compiler tweak offered

der Mouse mouse@Rodents.Montreal.QC.CA
Sun Aug 25 06:16:00 GMT 2002


-----BEGIN PGP SIGNED MESSAGE-----

I've finally gotten around to doing a hack to gcc I've been meaning to
for a while, and I'm writing to offer it back to you people if you're
interested.  It permits labeled control structure, as in

	for "outer" (elt=root; elt; elt=elt->link)
	 { while (...)
	    { ...
	      switch (...)
	       { ....
		 if (...) continue "outer";

This affects do, for, while, switch, break, and continue statements.
Unfortunately it does cause a reinterpretation of certain very unusual
legal C code, namely, any do-loop whose body is a non-brace-bracketed
statement beginning with a string literal, such as

	do "squeamishossifrage"[i++]; while (i < 10);

This is legal, if pointless, C, but my patches turn it into a syntax
error.  I haven't seen any good way around this.  One person suggested
putting the label after the while, so it's dismbiguated by the parens,
the same way it is for for and while loops - but the label has to be at
the beginning, so it is seen before the body of the loop (and any break
or continue statements therein).  Thoughts on addressing this would be
welcomed.  Putting () around the label string doesn't help.  Using []
has problems with Objective-C.  <>, maybe?  Can C or Obj-C statements
begin with a <?

In any case, for your consideration, amusement, edification, whatever,
here are the changes I'm using; personally, I don't care about the
do-loop issue, so these don't contain any addressing of it.

Unfortunately I don't see version numbers in any of the affected files,
which makes it harder to identify exactly what versions these are based
on.  If the current development sources have drifted far enough that
it's not obvious how to adapt these, you can always ignore them, or
write back to me about it.

Legalisms: As the sole author of the changes embodied in these patches,
I hereby place any intellectual property rights I may have in them in
the public domain, in witness whereof I am pgp-signing this message.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       mouse@rodents.montreal.qc.ca
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B

#! /bin/sh
#
# Shar: Shell Archiver
#
# This archive created Sun Aug 25 08:36:43 2002
# Run this through sh to create:
#	c-parse.in
#	c-parse.y
#	cp/
#	cp/semantics.c
#	f/
#	f/ste.c
#	objc/
#	objc/objc-parse.y
#	stmt.c
#	tree.h
echo x - c-parse.in \(7011 characters\)
sed 's/^X//' > c-parse.in << \EOF
X--- OLD/gnu/dist/gcc/c-parse.in	Thu Jan  1 00:00:00 1970
X+++ NEW/gnu/dist/gcc/c-parse.in	Thu Jan  1 00:00:00 1970
X@@ -189,6 +189,7 @@
X %type <ttype> any_word
X 
X %type <ttype> compstmt
X+%type <ttype> label_construct
X 
X %type <ttype> declarator
X %type <ttype> notype_declarator after_type_declarator
X@@ -1815,10 +1816,22 @@
X 		  emit_nop ();
X 		  expand_start_loop_continue_elsewhere (1);
X 		  position_after_white_space (); }
X+	  label_construct
X+		{ set_nesting_name ($3); }
X 	  lineno_labeled_stmt WHILE
X 		{ expand_loop_continue_here (); }
X 	;
X 
X+label_construct:
X+	  /* empty */
X+		{ $$ = NULL_TREE; }
X+	| STRING
X+		{ if (pedantic)
X+		    pedwarn ("ANSI C forbids labeled control structure");
X+		  $$ = $1;
X+		}
X+	;
X+
X save_filename:
X 		{ $$ = input_filename; }
X 	;
X@@ -1903,14 +1916,15 @@
X 		     I think it ought to work to put the nop after the line number.
X 		     We will see.  --rms, July 15, 1991.  */
X 		  emit_nop (); }
X-	  '(' expr ')'
X+	  label_construct '(' expr ')'
X 		{ /* Don't start the loop till we have succeeded
X 		     in parsing the end test.  This is to make sure
X 		     that we end every loop we start.  */
X 		  expand_start_loop (1);
X+		  set_nesting_name ($3);
X 		  emit_line_note (input_filename, lineno);
X 		  expand_exit_loop_if_false (NULL_PTR,
X-					     truthvalue_conversion ($4));
X+					     truthvalue_conversion ($5));
X 		  position_after_white_space (); }
X 	  lineno_labeled_stmt
X 		{ expand_end_loop (); }
X@@ -1925,13 +1939,12 @@
X 	| do_stmt_start error
X 		{ expand_end_loop ();
X 		  clear_momentary (); }
X-	| FOR
X-	  '(' xexpr ';'
X+	| FOR label_construct '(' xexpr ';'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X 		  /* See comment in `while' alternative, above.  */
X 		  emit_nop ();
X-		  if ($3) c_expand_expr_stmt ($3);
X+		  if ($4) c_expand_expr_stmt ($4);
X 		  /* Next step is to call expand_start_loop_continue_elsewhere,
X 		     but wait till after we parse the entire for (...).
X 		     Otherwise, invalid input might cause us to call that
X@@ -1939,59 +1952,71 @@
X 		}
X 	  xexpr ';'
X 		/* Can't emit now; wait till after expand_start_loop...  */
X-		{ $<lineno>7 = lineno;
X+		{ $<lineno>8 = lineno;
X 		  $<filename>$ = input_filename; }
X 	  xexpr ')'
X 		{ 
X 		  /* Start the loop.  Doing this after parsing
X 		     all the expressions ensures we will end the loop.  */
X 		  expand_start_loop_continue_elsewhere (1);
X+		  set_nesting_name ($2);
X 		  /* Emit the end-test, with a line number.  */
X-		  emit_line_note ($<filename>8, $<lineno>7);
X-		  if ($6)
X+		  emit_line_note ($<filename>9, $<lineno>8);
X+		  if ($7)
X 		    expand_exit_loop_if_false (NULL_PTR,
X-					       truthvalue_conversion ($6));
X-		  /* Don't let the tree nodes for $9 be discarded by
X+					       truthvalue_conversion ($7));
X+		  /* Don't let the tree nodes for $10 be discarded by
X 		     clear_momentary during the parsing of the next stmt.  */
X 		  push_momentary ();
X-		  $<lineno>7 = lineno;
X-		  $<filename>8 = input_filename;
X+		  $<lineno>8 = lineno;
X+		  $<filename>9 = input_filename;
X 		  position_after_white_space (); }
X 	  lineno_labeled_stmt
X 		{ /* Emit the increment expression, with a line number.  */
X-		  emit_line_note ($<filename>8, $<lineno>7);
X+		  emit_line_note ($<filename>9, $<lineno>8);
X 		  expand_loop_continue_here ();
X-		  if ($9)
X-		    c_expand_expr_stmt ($9);
X+		  if ($10)
X+		    c_expand_expr_stmt ($10);
X 		  if (yychar == CONSTANT || yychar == STRING)
X 		    pop_momentary_nofree ();
X 		  else
X 		    pop_momentary ();
X 		  expand_end_loop (); }
X-	| SWITCH '(' expr ')'
X+	| SWITCH label_construct '(' expr ')'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X-		  c_expand_start_case ($3);
X-		  /* Don't let the tree nodes for $3 be discarded by
X+		  c_expand_start_case ($4);
X+		  set_nesting_name ($2);
X+		  /* Don't let the tree nodes for $4 be discarded by
X 		     clear_momentary during the parsing of the next stmt.  */
X 		  push_momentary ();
X 		  position_after_white_space (); }
X 	  lineno_labeled_stmt
X-		{ expand_end_case ($3);
X+		{ expand_end_case ($4);
X 		  if (yychar == CONSTANT || yychar == STRING)
X 		    pop_momentary_nofree ();
X 		  else
X 		    pop_momentary (); }
X-	| BREAK ';'
X+	| BREAK label_construct ';'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X-		  if ( ! expand_exit_something ())
X-		    error ("break statement not within loop or switch"); }
X-	| CONTINUE ';'
X+		  if ( ! expand_exit_something ($2))
X+		    { if ($2 == NULL_TREE)
X+			error ("break statement not within loop or switch");
X+		      else
X+			error ("break label not found");
X+		    }
X+		}
X+	| CONTINUE label_construct ';'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X-		  if (! expand_continue_loop (NULL_PTR))
X-		    error ("continue statement not within a loop"); }
X+		  if (! expand_continue_loop (find_labeled_loop ($2)))
X+		    { if ($2 == NULL_TREE)
X+			error ("continue statement not within a loop");
X+		      else
X+			error ("continue label not found");
X+		    }
X+		}
X 	| RETURN ';'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X@@ -2058,48 +2083,49 @@
X 	;
X 
X all_iter_stmt_simple:
X-	  FOR '(' primary ')' 
X+	  FOR label_construct '(' primary ')' 
X 	  {
X 	    /* The value returned by this action is  */
X 	    /*      1 if everything is OK */ 
X 	    /*      0 in case of error or already bound iterator */
X 
X 	    $<itype>$ = 0;
X-	    if (TREE_CODE ($3) != VAR_DECL)
X+	    if (TREE_CODE ($4) != VAR_DECL)
X 	      error ("invalid `for (ITERATOR)' syntax");
X-	    else if (! ITERATOR_P ($3))
X+	    else if (! ITERATOR_P ($4))
X 	      error ("`%s' is not an iterator",
X-		     IDENTIFIER_POINTER (DECL_NAME ($3)));
X-	    else if (ITERATOR_BOUND_P ($3))
X+		     IDENTIFIER_POINTER (DECL_NAME ($4)));
X+	    else if (ITERATOR_BOUND_P ($4))
X 	      error ("`for (%s)' inside expansion of same iterator",
X-		     IDENTIFIER_POINTER (DECL_NAME ($3)));
X+		     IDENTIFIER_POINTER (DECL_NAME ($4)));
X 	    else
X 	      {
X 		$<itype>$ = 1;
X-		iterator_for_loop_start ($3);
X+		iterator_for_loop_start ($4);
X+		set_nesting_name ($2);
X 	      }
X 	  }
X 	  lineno_labeled_stmt
X 	  {
X-	    if ($<itype>5)
X-	      iterator_for_loop_end ($3);
X+	    if ($<itype>6)
X+	      iterator_for_loop_end ($4);
X 	  }
X 
X /*  This really should allow any kind of declaration,
X     for generality.  Fix it before turning it back on.
X 
X all_iter_stmt_with_decl:
X-	  FOR '(' ITERATOR pushlevel setspecs iterator_spec ')' 
X+	  FOR label_construct '(' ITERATOR pushlevel setspecs iterator_spec ')' 
X 	  {
X */	    /* The value returned by this action is  */
X 	    /*      1 if everything is OK */ 
X 	    /*      0 in case of error or already bound iterator */
X /*
X-	    iterator_for_loop_start ($6);
X+	    iterator_for_loop_start ($7);
X 	  }
X 	  lineno_labeled_stmt
X 	  {
X-	    iterator_for_loop_end ($6);
X+	    iterator_for_loop_end ($7);
X 	    emit_line_note (input_filename, lineno);
X 	    expand_end_bindings (getdecls (), 1, 0);
X 	    $<ttype>$ = poplevel (1, 1, 0);
EOF
if test 7011 -ne "`wc -c < c-parse.in`"
then
echo shar: error transmitting c-parse.in \(should have been 7011 characters\)
fi
echo x - c-parse.y \(7009 characters\)
sed 's/^X//' > c-parse.y << \EOF
X--- OLD/gnu/dist/gcc/c-parse.y	Thu Jan  1 00:00:00 1970
X+++ NEW/gnu/dist/gcc/c-parse.y	Thu Jan  1 00:00:00 1970
X@@ -177,6 +177,7 @@
X %type <ttype> any_word
X 
X %type <ttype> compstmt
X+%type <ttype> label_construct
X 
X %type <ttype> declarator
X %type <ttype> notype_declarator after_type_declarator
X@@ -1624,10 +1625,22 @@
X 		  emit_nop ();
X 		  expand_start_loop_continue_elsewhere (1);
X 		  position_after_white_space (); }
X+	  label_construct
X+		{ set_nesting_name ($3); }
X 	  lineno_labeled_stmt WHILE
X 		{ expand_loop_continue_here (); }
X 	;
X 
X+label_construct:
X+	  /* empty */
X+		{ $$ = NULL_TREE; }
X+	| STRING
X+		{ if (pedantic)
X+		    pedwarn ("ANSI C forbids labeled control structure");
X+		  $$ = $1;
X+		}
X+	;
X+
X save_filename:
X 		{ $$ = input_filename; }
X 	;
X@@ -1712,14 +1725,15 @@
X 		     I think it ought to work to put the nop after the line number.
X 		     We will see.  --rms, July 15, 1991.  */
X 		  emit_nop (); }
X-	  '(' expr ')'
X+	  label_construct '(' expr ')'
X 		{ /* Don't start the loop till we have succeeded
X 		     in parsing the end test.  This is to make sure
X 		     that we end every loop we start.  */
X 		  expand_start_loop (1);
X+		  set_nesting_name ($3);
X 		  emit_line_note (input_filename, lineno);
X 		  expand_exit_loop_if_false (NULL_PTR,
X-					     truthvalue_conversion ($4));
X+					     truthvalue_conversion ($5));
X 		  position_after_white_space (); }
X 	  lineno_labeled_stmt
X 		{ expand_end_loop (); }
X@@ -1734,13 +1748,12 @@
X 	| do_stmt_start error
X 		{ expand_end_loop ();
X 		  clear_momentary (); }
X-	| FOR
X-	  '(' xexpr ';'
X+	| FOR label_construct '(' xexpr ';'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X 		  /* See comment in `while' alternative, above.  */
X 		  emit_nop ();
X-		  if ($3) c_expand_expr_stmt ($3);
X+		  if ($4) c_expand_expr_stmt ($4);
X 		  /* Next step is to call expand_start_loop_continue_elsewhere,
X 		     but wait till after we parse the entire for (...).
X 		     Otherwise, invalid input might cause us to call that
X@@ -1748,59 +1761,71 @@
X 		}
X 	  xexpr ';'
X 		/* Can't emit now; wait till after expand_start_loop...  */
X-		{ $<lineno>7 = lineno;
X+		{ $<lineno>8 = lineno;
X 		  $<filename>$ = input_filename; }
X 	  xexpr ')'
X 		{ 
X 		  /* Start the loop.  Doing this after parsing
X 		     all the expressions ensures we will end the loop.  */
X 		  expand_start_loop_continue_elsewhere (1);
X+		  set_nesting_name ($2);
X 		  /* Emit the end-test, with a line number.  */
X-		  emit_line_note ($<filename>8, $<lineno>7);
X-		  if ($6)
X+		  emit_line_note ($<filename>9, $<lineno>8);
X+		  if ($7)
X 		    expand_exit_loop_if_false (NULL_PTR,
X-					       truthvalue_conversion ($6));
X-		  /* Don't let the tree nodes for $9 be discarded by
X+					       truthvalue_conversion ($7));
X+		  /* Don't let the tree nodes for $10 be discarded by
X 		     clear_momentary during the parsing of the next stmt.  */
X 		  push_momentary ();
X-		  $<lineno>7 = lineno;
X-		  $<filename>8 = input_filename;
X+		  $<lineno>8 = lineno;
X+		  $<filename>9 = input_filename;
X 		  position_after_white_space (); }
X 	  lineno_labeled_stmt
X 		{ /* Emit the increment expression, with a line number.  */
X-		  emit_line_note ($<filename>8, $<lineno>7);
X+		  emit_line_note ($<filename>9, $<lineno>8);
X 		  expand_loop_continue_here ();
X-		  if ($9)
X-		    c_expand_expr_stmt ($9);
X+		  if ($10)
X+		    c_expand_expr_stmt ($10);
X 		  if (yychar == CONSTANT || yychar == STRING)
X 		    pop_momentary_nofree ();
X 		  else
X 		    pop_momentary ();
X 		  expand_end_loop (); }
X-	| SWITCH '(' expr ')'
X+	| SWITCH label_construct '(' expr ')'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X-		  c_expand_start_case ($3);
X-		  /* Don't let the tree nodes for $3 be discarded by
X+		  c_expand_start_case ($4);
X+		  set_nesting_name ($2);
X+		  /* Don't let the tree nodes for $4 be discarded by
X 		     clear_momentary during the parsing of the next stmt.  */
X 		  push_momentary ();
X 		  position_after_white_space (); }
X 	  lineno_labeled_stmt
X-		{ expand_end_case ($3);
X+		{ expand_end_case ($4);
X 		  if (yychar == CONSTANT || yychar == STRING)
X 		    pop_momentary_nofree ();
X 		  else
X 		    pop_momentary (); }
X-	| BREAK ';'
X+	| BREAK label_construct ';'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X-		  if ( ! expand_exit_something ())
X-		    error ("break statement not within loop or switch"); }
X-	| CONTINUE ';'
X+		  if ( ! expand_exit_something ($2))
X+		    { if ($2 == NULL_TREE)
X+			error ("break statement not within loop or switch");
X+		      else
X+			error ("break label not found");
X+		    }
X+		}
X+	| CONTINUE label_construct ';'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X-		  if (! expand_continue_loop (NULL_PTR))
X-		    error ("continue statement not within a loop"); }
X+		  if (! expand_continue_loop (find_labeled_loop ($2)))
X+		    { if ($2 == NULL_TREE)
X+			error ("continue statement not within a loop");
X+		      else
X+			error ("continue label not found");
X+		    }
X+		}
X 	| RETURN ';'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X@@ -1867,48 +1892,49 @@
X 	;
X 
X all_iter_stmt_simple:
X-	  FOR '(' primary ')' 
X+	  FOR label_construct '(' primary ')' 
X 	  {
X 	    /* The value returned by this action is  */
X 	    /*      1 if everything is OK */ 
X 	    /*      0 in case of error or already bound iterator */
X 
X 	    $<itype>$ = 0;
X-	    if (TREE_CODE ($3) != VAR_DECL)
X+	    if (TREE_CODE ($4) != VAR_DECL)
X 	      error ("invalid `for (ITERATOR)' syntax");
X-	    else if (! ITERATOR_P ($3))
X+	    else if (! ITERATOR_P ($4))
X 	      error ("`%s' is not an iterator",
X-		     IDENTIFIER_POINTER (DECL_NAME ($3)));
X-	    else if (ITERATOR_BOUND_P ($3))
X+		     IDENTIFIER_POINTER (DECL_NAME ($4)));
X+	    else if (ITERATOR_BOUND_P ($4))
X 	      error ("`for (%s)' inside expansion of same iterator",
X-		     IDENTIFIER_POINTER (DECL_NAME ($3)));
X+		     IDENTIFIER_POINTER (DECL_NAME ($4)));
X 	    else
X 	      {
X 		$<itype>$ = 1;
X-		iterator_for_loop_start ($3);
X+		iterator_for_loop_start ($4);
X+		set_nesting_name ($2);
X 	      }
X 	  }
X 	  lineno_labeled_stmt
X 	  {
X-	    if ($<itype>5)
X-	      iterator_for_loop_end ($3);
X+	    if ($<itype>6)
X+	      iterator_for_loop_end ($4);
X 	  }
X 
X /*  This really should allow any kind of declaration,
X     for generality.  Fix it before turning it back on.
X 
X all_iter_stmt_with_decl:
X-	  FOR '(' ITERATOR pushlevel setspecs iterator_spec ')' 
X+	  FOR label_construct '(' ITERATOR pushlevel setspecs iterator_spec ')' 
X 	  {
X */	    /* The value returned by this action is  */
X 	    /*      1 if everything is OK */ 
X 	    /*      0 in case of error or already bound iterator */
X /*
X-	    iterator_for_loop_start ($6);
X+	    iterator_for_loop_start ($7);
X 	  }
X 	  lineno_labeled_stmt
X 	  {
X-	    iterator_for_loop_end ($6);
X+	    iterator_for_loop_end ($7);
X 	    emit_line_note (input_filename, lineno);
X 	    expand_end_bindings (getdecls (), 1, 0);
X 	    $<ttype>$ = poplevel (1, 1, 0);
EOF
if test 7009 -ne "`wc -c < c-parse.y`"
then
echo shar: error transmitting c-parse.y \(should have been 7009 characters\)
fi
mkdir cp>/dev/null 2>&1
echo x - cp/semantics.c \(419 characters\)
sed 's/^X//' > cp/semantics.c << \EOF
X--- OLD/gnu/dist/gcc/cp/semantics.c	Thu Jan  1 00:00:00 1970
X+++ NEW/gnu/dist/gcc/cp/semantics.c	Thu Jan  1 00:00:00 1970
X@@ -452,7 +452,7 @@
X   emit_line_note (input_filename, lineno);
X   if (processing_template_decl)
X     add_tree (build_min_nt (BREAK_STMT));
X-  else if ( ! expand_exit_something ())
X+  else if ( ! expand_exit_something (NULL_TREE))
X     cp_error ("break statement not within loop or switch");
X }
X 
EOF
if test 419 -ne "`wc -c < cp/semantics.c`"
then
echo shar: error transmitting cp/semantics.c \(should have been 419 characters\)
fi
mkdir f>/dev/null 2>&1
echo x - f/ste.c \(312 characters\)
sed 's/^X//' > f/ste.c << \EOF
X--- OLD/gnu/dist/gcc/f/ste.c	Thu Jan  1 00:00:00 1970
X+++ NEW/gnu/dist/gcc/f/ste.c	Thu Jan  1 00:00:00 1970
X@@ -2453,7 +2453,7 @@
X       }
X 
X     if (ffestw_select_break (block))
X-      expand_exit_something ();
X+      expand_exit_something (NULL_TREE);
X     else
X       ffestw_set_select_break (block, TRUE);
X 
EOF
if test 312 -ne "`wc -c < f/ste.c`"
then
echo shar: error transmitting f/ste.c \(should have been 312 characters\)
fi
mkdir objc>/dev/null 2>&1
echo x - objc/objc-parse.y \(7025 characters\)
sed 's/^X//' > objc/objc-parse.y << \EOF
X--- OLD/gnu/dist/gcc/objc/objc-parse.y	Thu Jan  1 00:00:00 1970
X+++ NEW/gnu/dist/gcc/objc/objc-parse.y	Thu Jan  1 00:00:00 1970
X@@ -155,6 +155,7 @@
X %type <ttype> any_word
X 
X %type <ttype> compstmt
X+%type <ttype> label_construct
X 
X %type <ttype> declarator
X %type <ttype> notype_declarator after_type_declarator
X@@ -1738,10 +1739,22 @@
X 		  emit_nop ();
X 		  expand_start_loop_continue_elsewhere (1);
X 		  position_after_white_space (); }
X+	  label_construct
X+		{ set_nesting_name ($3); }
X 	  lineno_labeled_stmt WHILE
X 		{ expand_loop_continue_here (); }
X 	;
X 
X+label_construct:
X+	  /* empty */
X+		{ $$ = NULL_TREE; }
X+	| STRING
X+		{ if (pedantic)
X+		    pedwarn ("ANSI C forbids labeled control structure");
X+		  $$ = $1;
X+		}
X+	;
X+
X save_filename:
X 		{ $$ = input_filename; }
X 	;
X@@ -1826,14 +1839,15 @@
X 		     I think it ought to work to put the nop after the line number.
X 		     We will see.  --rms, July 15, 1991.  */
X 		  emit_nop (); }
X-	  '(' expr ')'
X+	  label_construct '(' expr ')'
X 		{ /* Don't start the loop till we have succeeded
X 		     in parsing the end test.  This is to make sure
X 		     that we end every loop we start.  */
X 		  expand_start_loop (1);
X+		  set_nesting_name ($3);
X 		  emit_line_note (input_filename, lineno);
X 		  expand_exit_loop_if_false (NULL_PTR,
X-					     truthvalue_conversion ($4));
X+					     truthvalue_conversion ($5));
X 		  position_after_white_space (); }
X 	  lineno_labeled_stmt
X 		{ expand_end_loop (); }
X@@ -1848,13 +1862,12 @@
X 	| do_stmt_start error
X 		{ expand_end_loop ();
X 		  clear_momentary (); }
X-	| FOR
X-	  '(' xexpr ';'
X+	| FOR label_construct '(' xexpr ';'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X 		  /* See comment in `while' alternative, above.  */
X 		  emit_nop ();
X-		  if ($3) c_expand_expr_stmt ($3);
X+		  if ($4) c_expand_expr_stmt ($4);
X 		  /* Next step is to call expand_start_loop_continue_elsewhere,
X 		     but wait till after we parse the entire for (...).
X 		     Otherwise, invalid input might cause us to call that
X@@ -1862,59 +1875,71 @@
X 		}
X 	  xexpr ';'
X 		/* Can't emit now; wait till after expand_start_loop...  */
X-		{ $<lineno>7 = lineno;
X+		{ $<lineno>8 = lineno;
X 		  $<filename>$ = input_filename; }
X 	  xexpr ')'
X 		{ 
X 		  /* Start the loop.  Doing this after parsing
X 		     all the expressions ensures we will end the loop.  */
X 		  expand_start_loop_continue_elsewhere (1);
X+		  set_nesting_name ($2);
X 		  /* Emit the end-test, with a line number.  */
X-		  emit_line_note ($<filename>8, $<lineno>7);
X-		  if ($6)
X+		  emit_line_note ($<filename>9, $<lineno>8);
X+		  if ($7)
X 		    expand_exit_loop_if_false (NULL_PTR,
X-					       truthvalue_conversion ($6));
X-		  /* Don't let the tree nodes for $9 be discarded by
X+					       truthvalue_conversion ($7));
X+		  /* Don't let the tree nodes for $10 be discarded by
X 		     clear_momentary during the parsing of the next stmt.  */
X 		  push_momentary ();
X-		  $<lineno>7 = lineno;
X-		  $<filename>8 = input_filename;
X+		  $<lineno>8 = lineno;
X+		  $<filename>9 = input_filename;
X 		  position_after_white_space (); }
X 	  lineno_labeled_stmt
X 		{ /* Emit the increment expression, with a line number.  */
X-		  emit_line_note ($<filename>8, $<lineno>7);
X+		  emit_line_note ($<filename>9, $<lineno>8);
X 		  expand_loop_continue_here ();
X-		  if ($9)
X-		    c_expand_expr_stmt ($9);
X+		  if ($10)
X+		    c_expand_expr_stmt ($10);
X 		  if (yychar == CONSTANT || yychar == STRING)
X 		    pop_momentary_nofree ();
X 		  else
X 		    pop_momentary ();
X 		  expand_end_loop (); }
X-	| SWITCH '(' expr ')'
X+	| SWITCH label_construct '(' expr ')'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X-		  c_expand_start_case ($3);
X-		  /* Don't let the tree nodes for $3 be discarded by
X+		  c_expand_start_case ($4);
X+		  set_nesting_name ($2);
X+		  /* Don't let the tree nodes for $4 be discarded by
X 		     clear_momentary during the parsing of the next stmt.  */
X 		  push_momentary ();
X 		  position_after_white_space (); }
X 	  lineno_labeled_stmt
X-		{ expand_end_case ($3);
X+		{ expand_end_case ($4);
X 		  if (yychar == CONSTANT || yychar == STRING)
X 		    pop_momentary_nofree ();
X 		  else
X 		    pop_momentary (); }
X-	| BREAK ';'
X+	| BREAK label_construct ';'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X-		  if ( ! expand_exit_something ())
X-		    error ("break statement not within loop or switch"); }
X-	| CONTINUE ';'
X+		  if ( ! expand_exit_something ($2))
X+		    { if ($2 == NULL_TREE)
X+			error ("break statement not within loop or switch");
X+		      else
X+			error ("break label not found");
X+		    }
X+		}
X+	| CONTINUE label_construct ';'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X-		  if (! expand_continue_loop (NULL_PTR))
X-		    error ("continue statement not within a loop"); }
X+		  if (! expand_continue_loop (find_labeled_loop ($2)))
X+		    { if ($2 == NULL_TREE)
X+			error ("continue statement not within a loop");
X+		      else
X+			error ("continue label not found");
X+		    }
X+		}
X 	| RETURN ';'
X 		{ stmt_count++;
X 		  emit_line_note ($<filename>-1, $<lineno>0);
X@@ -1981,48 +2006,49 @@
X 	;
X 
X all_iter_stmt_simple:
X-	  FOR '(' primary ')' 
X+	  FOR label_construct '(' primary ')' 
X 	  {
X 	    /* The value returned by this action is  */
X 	    /*      1 if everything is OK */ 
X 	    /*      0 in case of error or already bound iterator */
X 
X 	    $<itype>$ = 0;
X-	    if (TREE_CODE ($3) != VAR_DECL)
X+	    if (TREE_CODE ($4) != VAR_DECL)
X 	      error ("invalid `for (ITERATOR)' syntax");
X-	    else if (! ITERATOR_P ($3))
X+	    else if (! ITERATOR_P ($4))
X 	      error ("`%s' is not an iterator",
X-		     IDENTIFIER_POINTER (DECL_NAME ($3)));
X-	    else if (ITERATOR_BOUND_P ($3))
X+		     IDENTIFIER_POINTER (DECL_NAME ($4)));
X+	    else if (ITERATOR_BOUND_P ($4))
X 	      error ("`for (%s)' inside expansion of same iterator",
X-		     IDENTIFIER_POINTER (DECL_NAME ($3)));
X+		     IDENTIFIER_POINTER (DECL_NAME ($4)));
X 	    else
X 	      {
X 		$<itype>$ = 1;
X-		iterator_for_loop_start ($3);
X+		iterator_for_loop_start ($4);
X+		set_nesting_name ($2);
X 	      }
X 	  }
X 	  lineno_labeled_stmt
X 	  {
X-	    if ($<itype>5)
X-	      iterator_for_loop_end ($3);
X+	    if ($<itype>6)
X+	      iterator_for_loop_end ($4);
X 	  }
X 
X /*  This really should allow any kind of declaration,
X     for generality.  Fix it before turning it back on.
X 
X all_iter_stmt_with_decl:
X-	  FOR '(' ITERATOR pushlevel setspecs iterator_spec ')' 
X+	  FOR label_construct '(' ITERATOR pushlevel setspecs iterator_spec ')' 
X 	  {
X */	    /* The value returned by this action is  */
X 	    /*      1 if everything is OK */ 
X 	    /*      0 in case of error or already bound iterator */
X /*
X-	    iterator_for_loop_start ($6);
X+	    iterator_for_loop_start ($7);
X 	  }
X 	  lineno_labeled_stmt
X 	  {
X-	    iterator_for_loop_end ($6);
X+	    iterator_for_loop_end ($7);
X 	    emit_line_note (input_filename, lineno);
X 	    expand_end_bindings (getdecls (), 1, 0);
X 	    $<ttype>$ = poplevel (1, 1, 0);
EOF
if test 7025 -ne "`wc -c < objc/objc-parse.y`"
then
echo shar: error transmitting objc/objc-parse.y \(should have been 7025 characters\)
fi
echo x - stmt.c \(3774 characters\)
sed 's/^X//' > stmt.c << \EOF
X--- OLD/gnu/dist/gcc/stmt.c	Thu Jan  1 00:00:00 1970
X+++ NEW/gnu/dist/gcc/stmt.c	Thu Jan  1 00:00:00 1970
X@@ -201,6 +201,8 @@
X {
X   struct nesting *all;
X   struct nesting *next;
X+  /* For labeled break and continue.  See set_nesting_name. */
X+  tree name;
X   int depth;
X   rtx exit_label;
X   union
X@@ -1779,6 +1781,7 @@
X 
X   thiscond->next = cond_stack;
X   thiscond->all = nesting_stack;
X+  thiscond->name = NULL_TREE;
X   thiscond->depth = ++nesting_depth;
X   thiscond->data.cond.next_label = gen_label_rtx ();
X   /* Before we encounter an `else', we don't need a separate exit label
X@@ -1869,6 +1872,7 @@
X 
X   thisloop->next = loop_stack;
X   thisloop->all = nesting_stack;
X+  thisloop->name = NULL_TREE;
X   thisloop->depth = ++nesting_depth;
X   thisloop->data.loop.start_label = gen_label_rtx ();
X   thisloop->data.loop.end_label = gen_label_rtx ();
X@@ -1886,6 +1890,15 @@
X   return thisloop;
X }
X 
X+/* Set the current nesting's name. */
X+
X+void
X+set_nesting_name (name)
X+     tree name;
X+{
X+  nesting_stack->name = name;
X+}
X+
X /* Like expand_start_loop but for a loop where the continuation point
X    (for expand_continue_loop) will be specified explicitly.  */
X 
X@@ -2023,7 +2036,7 @@
X 				}
X 			      } catch (...) { 
X 				1;
X-			      } )) {
X+			      } } )) {
X 		     body;
X 		  } 
X 
X@@ -2134,6 +2147,46 @@
X   last_expr_type = 0;
X }
X 
X+/* Check whether nestname, a nesting name from set_nesting_name, matches
X+   arg, the thing passed to expand_exit_something or find_labeled_loop.
X+
X+   NULL_TREE arg matches anything.
X+   String constants with equal contents match.
X+   Nothing else does. */
X+
X+int
X+nesting_name_match (nestname, arg)
X+     tree nestname;
X+     tree arg;
X+{
X+  return( (arg == NULL_TREE) ||
X+	  ( (nestname != NULL_TREE) &&
X+	    (TREE_CODE (nestname) == STRING_CST) &&
X+	    (TREE_CODE (arg) == STRING_CST) &&
X+	    (TREE_STRING_LENGTH (nestname) == TREE_STRING_LENGTH (arg)) &&
X+	    !bcmp (TREE_STRING_POINTER (nestname),
X+		   TREE_STRING_POINTER (arg),
X+		   TREE_STRING_LENGTH (nestname)) ) );
X+}
X+
X+/* Find the enclosing loop with the specified name.  Matches only loops. */
X+
X+struct nesting *
X+find_labeled_loop (lab)
X+     tree lab;
X+{
X+  struct nesting *n;
X+
X+  if (lab == NULL_TREE)
X+    return (0);
X+
X+  for (n = loop_stack; n; n = n->next)
X+    if (nesting_name_match (n->name, lab))
X+      return n;
X+
X+  error ("no enclosing loop tagged `%s'", TREE_STRING_POINTER (lab));
X+}
X+
X /* Generate a jump to the current loop's continue-point.
X    This is usually the top of the loop, but may be specified
X    explicitly elsewhere.  If not currently inside a loop,
X@@ -2238,12 +2291,13 @@
X    return 0 and do nothing; caller will print an error message.  */
X 
X int
X-expand_exit_something ()
X+expand_exit_something (lab)
X+     tree lab;
X {
X   struct nesting *n;
X   last_expr_type = 0;
X   for (n = nesting_stack; n; n = n->all)
X-    if (n->exit_label != 0)
X+    if ((n->exit_label != 0) && nesting_name_match (n->name, lab))
X       {
X 	expand_goto_internal (NULL_TREE, n->exit_label, NULL_RTX);
X 	return 1;
X@@ -2772,6 +2826,7 @@
X 
X   thisblock->next = block_stack;
X   thisblock->all = nesting_stack;
X+  thisblock->name = NULL_TREE;
X   thisblock->depth = ++nesting_depth;
X   thisblock->data.block.stack_level = 0;
X   thisblock->data.block.cleanups = 0;
X@@ -3865,6 +3920,7 @@
X 
X   thiscase->next = case_stack;
X   thiscase->all = nesting_stack;
X+  thiscase->name = NULL_TREE;
X   thiscase->depth = ++nesting_depth;
X   thiscase->exit_label = exit_flag ? gen_label_rtx () : 0;
X   thiscase->data.case_stmt.case_list = 0;
X@@ -3904,6 +3960,7 @@
X 
X   thiscase->next = case_stack;
X   thiscase->all = nesting_stack;
X+  thiscase->name = NULL_TREE;
X   thiscase->depth = ++nesting_depth;
X   thiscase->exit_label = 0;
X   thiscase->data.case_stmt.case_list = 0;
EOF
if test 3774 -ne "`wc -c < stmt.c`"
then
echo shar: error transmitting stmt.c \(should have been 3774 characters\)
fi
echo x - tree.h \(812 characters\)
sed 's/^X//' > tree.h << \EOF
X--- OLD/gnu/dist/gcc/tree.h	Thu Jan  1 00:00:00 1970
X+++ NEW/gnu/dist/gcc/tree.h	Thu Jan  1 00:00:00 1970
X@@ -1863,11 +1863,13 @@
X extern struct nesting *expand_start_loop_continue_elsewhere 	PROTO((int));
X extern void expand_loop_continue_here		PROTO((void));
X extern void expand_end_loop			PROTO((void));
X+extern void set_nesting_name			PROTO((tree));
X extern int expand_continue_loop			PROTO((struct nesting *));
X extern int expand_exit_loop			PROTO((struct nesting *));
X extern int expand_exit_loop_if_false		PROTO((struct nesting *,
X 						       tree));
X-extern int expand_exit_something		PROTO((void));
X+extern int expand_exit_something		PROTO((tree));
X+extern struct nesting *find_labeled_loop	PROTO((tree));
X 
X extern void expand_null_return			PROTO((void));
X extern void expand_return			PROTO((tree));
EOF
if test 812 -ne "`wc -c < tree.h`"
then
echo shar: error transmitting tree.h \(should have been 812 characters\)
fi
exit 0
# end of shell archive

-----BEGIN PGP SIGNATURE-----
Version: 2.6.3ia
Charset: latin1

iQCVAwUBPWiBrtiXPKPXYL91AQEFzwP5Ady/nXdZO1pFgTGqzeWoMewYZdq9lRq3
GJ7T7UFZJrwxqaz8Z/JIcsTMpa8fN1jXGzjtsCmOGc6jIZHhsQ7bRSFYb28AUfNT
xWAamMUDtC6eO5OJTm2HZb3AgdjiQ6uRjIYIZ27znGkEANjq6gI1X6k8VRThtbo+
Mw4Jc345LpY=
=FcjG
-----END PGP SIGNATURE-----



More information about the Gcc-patches mailing list