diff options
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/c-common.c | 54 | ||||
-rw-r--r-- | gcc/c-common.h | 6 | ||||
-rw-r--r-- | gcc/c-parse.in | 34 |
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 |