public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* gas: parsing source lines containing macro args
@ 1999-11-08  8:51 Andrew Haley
  1999-11-08  9:07 ` Ian Lance Taylor
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew Haley @ 1999-11-08  8:51 UTC (permalink / raw)
  To: binutils

Consider a source file that looks like this:

-----------------------------------------------------------------------
        .macro  foo_macro arg0, arg1
        foo \arg0,\arg1,0
        .endm

        .vu
n1:     foo_macro %r01,%r00
n2:	foo %r01,%r00,0
-----------------------------------------------------------------------

Line n1 expands to "foo %r01,%r00,0", which is the same as line n2.

However, if there is another token on the line inside the macro, bad
things happen:

-----------------------------------------------------------------------
        .macro  foo_macro arg0, arg1
        bar foo \arg0,\arg1,0
        .endm

        .vu
n1:     foo_macro %r01,%r00
n2:	bar foo %r01,%r00,0
-----------------------------------------------------------------------

Instead of being expanded to "bar foo %r01,%r00,0", line n1 is
expanded to "bar foo%r01,%r00,0": a space has disappeared.  This
happens becase when gas is scanning Line n1, any spaces after the
second operand are ignored *unless* they occur immediately before an
operand character.  Unfortunately, in this case the space in question
is immediately before a backslash, which is not an operand character,
so the space is dropped.

My patch fixes this by outputting a space when going from State 10
(after seeing whitespace in state 9) to State 3 (after second white on
line) iff the non-whitepsace character which caused the transition was
a backslash.

I thin that this genuinely is a special case, because a backslash
should only be treated as an operand char when the backslash appears
as the first character of an operand.

Andrew.


1999-11-08  Andrew Haley  <aph@cygnus.com>

	* app.c (do_scrub_chars): When in State 10, treat backslash
	characters in the same way as as symbol characters.

Index: app.c
===================================================================
RCS file: /cvs/binutils/binutils/gas/app.c,v
retrieving revision 1.3
diff -p -r1.3 app.c
*** app.c	1999/07/11 20:19:53	1.3
--- app.c	1999/11/08 16:48:03
*************** do_scrub_chars (get, tostart, tolen)
*** 1227,1232 ****
--- 1227,1242 ----
  	    }
  	  else if (state == 10)
  	    {
+ 	      if (ch == '\\')
+ 		{
+ 		  /* Special handling for backslash: a backslash may
+ 		     be the beginning of a formal parameter (of a
+ 		     macro) following another symbol character, with
+ 		     whitespace in between.  We skipped the whitespace
+ 		     earlier, so output it now.  */
+ 		  PUT (' ');
+ 		}
+ 
  	      state = 3;
  	    }
  	  PUT (ch);

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: gas: parsing source lines containing macro args
  1999-11-08  8:51 gas: parsing source lines containing macro args Andrew Haley
@ 1999-11-08  9:07 ` Ian Lance Taylor
  1999-11-09  9:18   ` Andrew Haley
  0 siblings, 1 reply; 3+ messages in thread
From: Ian Lance Taylor @ 1999-11-08  9:07 UTC (permalink / raw)
  To: aph; +Cc: binutils

   Date: 8 Nov 1999 16:51:20 -0000
   From: Andrew Haley <aph@pasanda.cygnus.co.uk>

   Consider a source file that looks like this:

   -----------------------------------------------------------------------
	   .macro  foo_macro arg0, arg1
	   foo \arg0,\arg1,0
	   .endm

	   .vu
   n1:     foo_macro %r01,%r00
   n2:	foo %r01,%r00,0
   -----------------------------------------------------------------------

   Line n1 expands to "foo %r01,%r00,0", which is the same as line n2.

   However, if there is another token on the line inside the macro, bad
   things happen:

   -----------------------------------------------------------------------
	   .macro  foo_macro arg0, arg1
	   bar foo \arg0,\arg1,0
	   .endm

	   .vu
   n1:     foo_macro %r01,%r00
   n2:	bar foo %r01,%r00,0
   -----------------------------------------------------------------------

   Instead of being expanded to "bar foo %r01,%r00,0", line n1 is
   expanded to "bar foo%r01,%r00,0": a space has disappeared.  This
   happens becase when gas is scanning Line n1, any spaces after the
   second operand are ignored *unless* they occur immediately before an
   operand character.  Unfortunately, in this case the space in question
   is immediately before a backslash, which is not an operand character,
   so the space is dropped.

   My patch fixes this by outputting a space when going from State 10
   (after seeing whitespace in state 9) to State 3 (after second white on
   line) iff the non-whitepsace character which caused the transition was
   a backslash.

It seems to me that correct handling really depends upon what the
macro parameter expands into.  If the parameter expands into something
which does not start with an operand character, then we do not want to
keep the space.  In your example, it expands into something which is
an operand character (at least, I guess it is, since otherwise the
space would have been dropped anyhow; on most platforms '%' is not an
operand char; on the i386 it is).

In other words, the problem seems to be that the scrubbing is being
done at the wrong level.  We can't scrub correctly until after we have
expanded the macro.

However, that would be a real pain to fix.

I think your patch is OK, provided the current testsuite passes.  But
I think your comment should be changed to indicate that we don't
actually have enough information to make the right choice, and that we
are making the choice which is more likely to be correct.

Ian

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: gas: parsing source lines containing macro args
  1999-11-08  9:07 ` Ian Lance Taylor
@ 1999-11-09  9:18   ` Andrew Haley
  0 siblings, 0 replies; 3+ messages in thread
From: Andrew Haley @ 1999-11-09  9:18 UTC (permalink / raw)
  To: ian; +Cc: binutils

> Date: 8 Nov 1999 12:06:37 -0500
> From: Ian Lance Taylor <ian@zembu.com>
>
> I think your patch is OK, provided the current testsuite passes.  But
> I think your comment should be changed to indicate that we don't
> actually have enough information to make the right choice, and that we
> are making the choice which is more likely to be correct.

Checked in like this.

Andrew.

1999-11-08  Andrew Haley  <aph@cygnus.com>

	* app.c (do_scrub_chars): When in State 10, treat backslash
	characters in the same way as as symbol characters.

Index: app.c
===================================================================
RCS file: /cvs/binutils/binutils/gas/app.c,v
retrieving revision 1.3
diff -p -r1.3 app.c
*** app.c	1999/07/11 20:19:53	1.3
--- app.c	1999/11/09 17:14:20
*************** do_scrub_chars (get, tostart, tolen)
*** 1227,1232 ****
--- 1227,1249 ----
  	    }
  	  else if (state == 10)
  	    {
+ 	      if (ch == '\\')
+ 		{
+ 		  /* Special handling for backslash: a backslash may
+ 		     be the beginning of a formal parameter (of a
+ 		     macro) following another symbol character, with
+ 		     whitespace in between.  If that is the case, we
+ 		     output a space before the parameter.  Strictly
+ 		     speaking, correct handling depends upon what the
+ 		     macro parameter expands into; if the parameter
+ 		     expands into something which does not start with
+ 		     an operand character, then we don't want to keep
+ 		     the space.  We don't have enough information to
+ 		     make the right choice, so here we are making the
+ 		     choice which is more likely to be correct.  */
+ 		  PUT (' ');
+ 		}
+ 
  	      state = 3;
  	    }
  	  PUT (ch);

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~1999-11-09  9:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-11-08  8:51 gas: parsing source lines containing macro args Andrew Haley
1999-11-08  9:07 ` Ian Lance Taylor
1999-11-09  9:18   ` Andrew Haley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).