summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/c-common.c54
-rw-r--r--gcc/c-common.h6
-rw-r--r--gcc/c-parse.in34
4 files changed, 93 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bbe28edbd41..765c1db5a9d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+Fri Jan 4 11:45:05 2002 Jeffrey A Law (law@redhat.com)
+
+ * c-common.c (c_expand_start_cond): Expect the IF_STMT node to
+ be passed in, do not build it.
+ (c_begin_if_stmt): New function.
+ (c_begin_while_stmt, c_finish_while_stmt_cond): Likewise.
+ * c-common.h (c_expand_start_cond): Update prototype.
+ (c_begin_if_stmt): Prototype new function.
+ (c_begin_while_stmt, c_finish_while_stmt_cond): Likewise.
+ * c-parse.in (if_prefix): Use c_begin_if_stmt,
+ c_begin_while_stmt and c_finish_while_stmt_cond.
+
2002-01-04 William Cohen <wcohen@redhat.com>
* config/pa/elf.h (ASM_FILE_START): Reverted to profile_flag.
diff --git a/gcc/c-common.c b/gcc/c-common.c
index f5f44877509..b08ef5b77a3 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -268,15 +268,20 @@ static int if_stack_space = 0;
static int if_stack_pointer = 0;
/* Record the start of an if-then, and record the start of it
- for ambiguous else detection. */
+ for ambiguous else detection.
+
+ COND is the condition for the if-then statement.
+
+ IF_STMT is the statement node that has already been created for
+ this if-then statement. It is created before parsing the
+ condition to keep line number information accurate. */
void
-c_expand_start_cond (cond, compstmt_count)
+c_expand_start_cond (cond, compstmt_count, if_stmt)
tree cond;
int compstmt_count;
+ tree if_stmt;
{
- tree if_stmt;
-
/* Make sure there is enough space on the stack. */
if (if_stack_space == 0)
{
@@ -289,7 +294,6 @@ c_expand_start_cond (cond, compstmt_count)
if_stack = (if_elt *) xrealloc (if_stack, if_stack_space * sizeof (if_elt));
}
- if_stmt = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
IF_COND (if_stmt) = cond;
add_stmt (if_stmt);
@@ -355,6 +359,46 @@ c_finish_else ()
RECHAIN_STMTS (if_stmt, ELSE_CLAUSE (if_stmt));
}
+/* Begin an if-statement. Returns a newly created IF_STMT if
+ appropriate.
+
+ Unlike the C++ front-end, we do not call add_stmt here; it is
+ probably safe to do so, but I am not very familiar with this
+ code so I am being extra careful not to change its behavior
+ beyond what is strictly necessary for correctness. */
+
+tree
+c_begin_if_stmt ()
+{
+ tree r;
+ r = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
+ return r;
+}
+
+/* Begin a while statement. Returns a newly created WHILE_STMT if
+ appropriate.
+
+ Unlike the C++ front-end, we do not call add_stmt here; it is
+ probably safe to do so, but I am not very familiar with this
+ code so I am being extra careful not to change its behavior
+ beyond what is strictly necessary for correctness. */
+
+tree
+c_begin_while_stmt ()
+{
+ tree r;
+ r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE);
+ return r;
+}
+
+void
+c_finish_while_stmt_cond (cond, while_stmt)
+ tree while_stmt;
+ tree cond;
+{
+ WHILE_COND (while_stmt) = cond;
+}
+
/* Push current bindings for the function name VAR_DECLS. */
void
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 4c49b9fcddf..296c9af3ac3 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -337,6 +337,10 @@ extern void expand_stmt PARAMS ((tree));
extern void mark_stmt_tree PARAMS ((void *));
extern void shadow_warning PARAMS ((const char *,
tree, tree));
+extern tree c_begin_if_stmt PARAMS ((void));
+extern tree c_begin_while_stmt PARAMS ((void));
+extern void c_finish_while_stmt_cond PARAMS ((tree, tree));
+
/* Extra information associated with a DECL. Other C dialects extend
this structure in various ways. The C front-end only uses this
@@ -505,7 +509,7 @@ extern tree c_alignof_expr PARAMS ((tree));
NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error PARAMS ((enum tree_code));
extern tree c_expand_expr_stmt PARAMS ((tree));
-extern void c_expand_start_cond PARAMS ((tree, int));
+extern void c_expand_start_cond PARAMS ((tree, int, tree));
extern void c_finish_then PARAMS ((void));
extern void c_expand_start_else PARAMS ((void));
extern void c_finish_else PARAMS ((void));
diff --git a/gcc/c-parse.in b/gcc/c-parse.in
index 889425e26c2..9434a2fa9ff 100644
--- a/gcc/c-parse.in
+++ b/gcc/c-parse.in
@@ -2186,13 +2186,23 @@ simple_if:
;
if_prefix:
- IF '(' expr ')'
- { c_expand_start_cond (truthvalue_conversion ($3),
- compstmt_count);
+ /* We must build the IF_STMT node before parsing its
+ condition so that STMT_LINENO refers to the line
+ containing the "if", and not the line containing
+ the close-parenthesis.
+
+ c_begin_if_stmt returns the IF_STMT node, which
+ we later pass to c_expand_start_cond to fill
+ in the condition and other tidbits. */
+ IF
+ { $<ttype>$ = c_begin_if_stmt (); }
+ '(' expr ')'
+ { c_expand_start_cond (truthvalue_conversion ($4),
+ compstmt_count,$<ttype>2);
$<itype>$ = stmt_count;
if_stmt_file = $<filename>-2;
if_stmt_line = $<lineno>-1; }
- ;
+ ;
/* This is a subroutine of stmt.
It is used twice, once for valid DO statements
@@ -2287,12 +2297,22 @@ select_or_iter_stmt:
Otherwise a crash is likely. */
| simple_if ELSE error
{ c_expand_end_cond (); }
+ /* We must build the WHILE_STMT node before parsing its
+ condition so that STMT_LINENO refers to the line
+ containing the "while", and not the line containing
+ the close-parenthesis.
+
+ c_begin_while_stmt returns the WHILE_STMT node, which
+ we later pass to c_finish_while_stmt_cond to fill
+ in the condition and other tidbits. */
| WHILE
- { stmt_count++; }
+ { stmt_count++;
+ $<ttype>$ = c_begin_while_stmt (); }
'(' expr ')'
{ $4 = truthvalue_conversion ($4);
- $<ttype>$
- = add_stmt (build_stmt (WHILE_STMT, $4, NULL_TREE)); }
+ c_finish_while_stmt_cond (truthvalue_conversion ($4),
+ $<ttype>2);
+ $<ttype>$ = add_stmt ($<ttype>2); }
c99_block_lineno_labeled_stmt
{ RECHAIN_STMTS ($<ttype>6, WHILE_BODY ($<ttype>6)); }
| do_stmt_start