cp-tree.h: Update declarations.
authorRichard Henderson <rth@redhat.com>
Wed, 20 Dec 2000 18:16:47 +0000 (10:16 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 20 Dec 2000 18:16:47 +0000 (10:16 -0800)
        * cp-tree.h: Update declarations.
        * decl.c (finish_case_label): Return the new stmt node.
        * semantics.c (finish_goto_stmt): Likewise.
        (finish_expr_stmt, finish_return_stmt): Likewise.
        (finish_break_stmt, finish_continue_stmt): Likewise.
        (finish_asm_stmt): Likewise.
        * parse.y (already_scoped_stmt): Set STMT_LINENO.
        (compstmt, implicitly_scoped_stmt, stmt): Likewise.
        (simple_if, simple_stmt): Return the new stmt node.
        (save_lineno): New.

From-SVN: r38401

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/parse.y
gcc/cp/semantics.c

index 9804092..fc473fb 100644 (file)
@@ -1,3 +1,16 @@
+2000-12-20  Richard Henderson  <rth@redhat.com>
+
+       * cp-tree.h: Update declarations.
+       * decl.c (finish_case_label): Return the new stmt node.
+       * semantics.c (finish_goto_stmt): Likewise.
+       (finish_expr_stmt, finish_return_stmt): Likewise.
+       (finish_break_stmt, finish_continue_stmt): Likewise.
+       (finish_asm_stmt): Likewise.
+       * parse.y (already_scoped_stmt): Set STMT_LINENO.
+       (compstmt, implicitly_scoped_stmt, stmt): Likewise.
+       (simple_if, simple_stmt): Return the new stmt node.
+       (save_lineno): New.
+
 2000-12-18  Joseph S. Myers  <jsm28@cam.ac.uk>
 
        * cp-tree.h: Don't declare warn_long_long.
index d7ede4e..f6d0b82 100644 (file)
@@ -3200,7 +3200,6 @@ extern void check_function_format         PARAMS ((int *, tree, tree, tree));
    NOP_EXPR is used as a special case (see truthvalue_conversion).  */
 extern void binary_op_error                     PARAMS ((enum tree_code));
 extern tree canonical_type_variant              PARAMS ((tree));
-extern void c_expand_expr_stmt                  PARAMS ((tree));
 /* Validate the expression after `case' and apply default promotions.  */
 extern tree check_case_value                    PARAMS ((tree));
 /* Concatenate a list of STRING_CST nodes into one STRING_CST.  */
@@ -4291,7 +4290,7 @@ extern void fixup_all_virtual_upcast_offsets    PARAMS ((tree));
 
 /* in semantics.c */
 extern void init_cp_semantics                   PARAMS ((void));
-extern void finish_expr_stmt                    PARAMS ((tree));
+extern tree finish_expr_stmt                    PARAMS ((tree));
 extern tree begin_if_stmt                       PARAMS ((void));
 extern void finish_if_stmt_cond                 PARAMS ((tree, tree));
 extern tree finish_then_clause                  PARAMS ((tree));
@@ -4304,19 +4303,19 @@ extern void finish_while_stmt                   PARAMS ((tree));
 extern tree begin_do_stmt                       PARAMS ((void));
 extern void finish_do_body                      PARAMS ((tree));
 extern void finish_do_stmt                      PARAMS ((tree, tree));
-extern void finish_return_stmt                  PARAMS ((tree));
+extern tree finish_return_stmt                  PARAMS ((tree));
 extern tree begin_for_stmt                      PARAMS ((void));
 extern void finish_for_init_stmt                PARAMS ((tree));
 extern void finish_for_cond                     PARAMS ((tree, tree));
 extern void finish_for_expr                     PARAMS ((tree, tree));
 extern void finish_for_stmt                     PARAMS ((tree));
-extern void finish_break_stmt                   PARAMS ((void));
-extern void finish_continue_stmt                PARAMS ((void));
+extern tree finish_break_stmt                   PARAMS ((void));
+extern tree finish_continue_stmt                PARAMS ((void));
 extern tree begin_switch_stmt                   PARAMS ((void));
 extern void finish_switch_cond                  PARAMS ((tree, tree));
 extern void finish_switch_stmt                  PARAMS ((tree));
-extern void finish_case_label                   PARAMS ((tree, tree));
-extern void finish_goto_stmt                    PARAMS ((tree));
+extern tree finish_case_label                   PARAMS ((tree, tree));
+extern tree finish_goto_stmt                    PARAMS ((tree));
 extern tree begin_try_block                     PARAMS ((void));
 extern void finish_try_block                    PARAMS ((tree));
 extern void finish_handler_sequence             PARAMS ((tree));
@@ -4331,7 +4330,7 @@ extern void finish_handler                      PARAMS ((tree, tree));
 extern void finish_cleanup                      PARAMS ((tree, tree));
 extern tree begin_compound_stmt                 PARAMS ((int));
 extern tree finish_compound_stmt                PARAMS ((int, tree));
-extern void finish_asm_stmt                     PARAMS ((tree, tree, tree, tree, tree));
+extern tree finish_asm_stmt                     PARAMS ((tree, tree, tree, tree, tree));
 extern void finish_label_stmt                   PARAMS ((tree));
 extern void finish_label_decl                   PARAMS ((tree));
 extern void finish_subobject                    PARAMS ((tree));
index 924447f..ab05842 100644 (file)
@@ -5158,12 +5158,12 @@ pop_switch ()
 /* Note that we've seen a definition of a case label, and complain if this
    is a bad place for one.  */
 
-void
+tree
 finish_case_label (low_value, high_value)
      tree low_value;
      tree high_value;
 {
-  tree cond;
+  tree cond, r;
   register struct binding_level *p;
 
   if (! switch_stack)
@@ -5175,7 +5175,7 @@ finish_case_label (low_value, high_value)
                  low_value);
       else
        error ("`default' label not within a switch statement");
-      return;
+      return NULL_TREE;
     }
 
   if (processing_template_decl)
@@ -5185,8 +5185,7 @@ finish_case_label (low_value, high_value)
       /* For templates, just add the case label; we'll do semantic
         analysis at instantiation-time.  */
       label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
-      add_stmt (build_case_label (low_value, high_value, label));
-      return;
+      return add_stmt (build_case_label (low_value, high_value, label));
     }
 
   /* Find the condition on which this switch statement depends.  */
@@ -5194,7 +5193,9 @@ finish_case_label (low_value, high_value)
   if (cond && TREE_CODE (cond) == TREE_LIST)
     cond = TREE_VALUE (cond);
 
-  c_add_case_label (switch_stack->cases, cond, low_value, high_value);
+  r = c_add_case_label (switch_stack->cases, cond, low_value, high_value);
+  if (r == error_mark_node)
+    r = NULL_TREE;
 
   check_switch_goto (switch_stack->level);
 
@@ -5203,6 +5204,8 @@ finish_case_label (low_value, high_value)
   for (p = current_binding_level; !(p->parm_flag); p = p->level_chain)
     p->more_cleanups_ok = 0;
   current_function_return_value = NULL_TREE;
+
+  return r;
 }
 \f
 /* Return the list of declarations of the current level.
index 4c03dc7..15cf725 100644 (file)
@@ -338,7 +338,8 @@ cp_parse_init ()
 %type <ttype> maybe_attribute attributes attribute attribute_list attrib
 %type <ttype> any_word
 
-%type <ttype> compstmt implicitly_scoped_stmt
+%type <itype> save_lineno
+%type <ttype> simple_stmt simple_if
 
 %type <ttype> declarator notype_declarator after_type_declarator
 %type <ttype> notype_declarator_intern absdcl_intern
@@ -1151,14 +1152,15 @@ compstmtend:
        ;
 
 already_scoped_stmt:
-         '{'
-                { $<ttype>$ = begin_compound_stmt (1); }
+         save_lineno '{'
+               { $<ttype>$ =  begin_compound_stmt (1); }
          compstmtend
-                { finish_compound_stmt (1, $<ttype>2); }
-       | simple_stmt
+               { STMT_LINENO ($<ttype>3) = $1;
+                 finish_compound_stmt (1, $<ttype>3); }
+       | save_lineno simple_stmt
+               { if ($2) STMT_LINENO ($2) = $1; }
        ;
 
-
 nontrivial_exprlist:
          expr_no_commas ',' expr_no_commas
                { $$ = tree_cons (NULL_TREE, $$, 
@@ -3277,56 +3279,61 @@ label_decl:
    It causes syntax errors to ignore to the next openbrace.  */
 compstmt_or_error:
          compstmt
-               {}
        | error compstmt
        ;
 
 compstmt:
-         '{'
+         save_lineno '{'
                 { $<ttype>$ = begin_compound_stmt (0); }
          compstmtend 
-                { $$ = finish_compound_stmt (0, $<ttype>2); }
+                { STMT_LINENO ($<ttype>3) = $1;
+                 finish_compound_stmt (0, $<ttype>3); }
        ;
 
 simple_if:
          IF
-               {
-                 $<ttype>$ = begin_if_stmt ();
-                 cond_stmt_keyword = "if";
-               }
+               { $<ttype>$ = begin_if_stmt ();
+                 cond_stmt_keyword = "if"; }
             paren_cond_or_null
                 { finish_if_stmt_cond ($3, $<ttype>2); }
            implicitly_scoped_stmt
-                { $<ttype>$ = finish_then_clause ($<ttype>2); }
+                { $$ = $<ttype>2;
+                 finish_then_clause ($<ttype>2); }
        ;
 
 implicitly_scoped_stmt:
          compstmt
-       |       { $<ttype>$ = begin_compound_stmt (0); }
-         simple_stmt 
-                { $$ = finish_compound_stmt (0, $<ttype>1); }
+       | 
+               { $<ttype>$ = begin_compound_stmt (0); }
+         save_lineno simple_stmt 
+               { STMT_LINENO ($<ttype>1) = $2;
+                 if ($3) STMT_LINENO ($3) = $2;
+                 finish_compound_stmt (0, $<ttype>1); }
        ;
 
 stmt:
          compstmt
-                {}
-       | simple_stmt
+       | save_lineno simple_stmt
+               { if ($2) STMT_LINENO ($2) = $1; }
        ;
 
 simple_stmt:
          decl
-               { finish_stmt (); }
+               { finish_stmt ();
+                 $$ = NULL_TREE; }
        | expr ';'
-                { finish_expr_stmt ($1); }
+                { $$ = finish_expr_stmt ($1); }
        | simple_if ELSE
                 { begin_else_clause (); }
          implicitly_scoped_stmt
                 { 
-                 finish_else_clause ($<ttype>1); 
+                 $$ = $1;
+                 finish_else_clause ($1); 
                  finish_if_stmt ();
                }
        | simple_if  %prec IF
-                { finish_if_stmt (); }
+                { $$ = $1;
+                 finish_if_stmt (); }
        | WHILE
                {
                  $<ttype>$ = begin_while_stmt ();
@@ -3335,7 +3342,8 @@ simple_stmt:
          paren_cond_or_null
                 { finish_while_stmt_cond ($3, $<ttype>2); }
          already_scoped_stmt
-                { finish_while_stmt ($<ttype>2); }
+                { $$ = $<ttype>2;
+                 finish_while_stmt ($<ttype>2); }
        | DO
                 { $<ttype>$ = begin_do_stmt (); }
          implicitly_scoped_stmt WHILE
@@ -3344,7 +3352,8 @@ simple_stmt:
                  cond_stmt_keyword = "do";
                }
          paren_expr_or_null ';'
-                { finish_do_stmt ($6, $<ttype>2); }
+                { $$ = $<ttype>2;
+                 finish_do_stmt ($6, $<ttype>2); }
        | FOR
                 { $<ttype>$ = begin_for_stmt (); }
          '(' for.init.statement
@@ -3354,75 +3363,83 @@ simple_stmt:
          xexpr ')'
                 { finish_for_expr ($9, $<ttype>2); }
          already_scoped_stmt
-                { finish_for_stmt ($<ttype>2); }
+                { $$ = $<ttype>2;
+                 finish_for_stmt ($<ttype>2); }
        | SWITCH 
                 { $<ttype>$ = begin_switch_stmt (); }
            '(' condition ')'
                 { finish_switch_cond ($4, $<ttype>2); }
          implicitly_scoped_stmt
-                { finish_switch_stmt ($<ttype>2); }
+                { $$ = $<ttype>2;
+                 finish_switch_stmt ($<ttype>2); }
        | CASE expr_no_commas ':'
-                { finish_case_label ($2, NULL_TREE); }
+                { $<ttype>$ = finish_case_label ($2, NULL_TREE); }
          stmt
+               { $$ = $<ttype>4; }
        | CASE expr_no_commas ELLIPSIS expr_no_commas ':'
-                { finish_case_label ($2, $4); }
+                { $<ttype>$ = finish_case_label ($2, $4); }
          stmt
+               { $$ = $<ttype>6; }
        | DEFAULT ':'
-               { finish_case_label (NULL_TREE, NULL_TREE); }
+               { $<ttype>$ = finish_case_label (NULL_TREE, NULL_TREE); }
          stmt
+               { $$ = $<ttype>3; }
        | BREAK ';'
-                { finish_break_stmt (); }
+                { $$ = finish_break_stmt (); }
        | CONTINUE ';'
-                { finish_continue_stmt (); }
+                { $$ = finish_continue_stmt (); }
        | RETURN_KEYWORD ';'
-                { finish_return_stmt (NULL_TREE); }
+                { $$ = finish_return_stmt (NULL_TREE); }
        | RETURN_KEYWORD expr ';'
-                { finish_return_stmt ($2); }
+                { $$ = finish_return_stmt ($2); }
        | asm_keyword maybe_cv_qualifier '(' string ')' ';'
-               { 
-                 finish_asm_stmt ($2, $4, NULL_TREE, NULL_TREE,
-                                  NULL_TREE); 
-               }
+               { $$ = finish_asm_stmt ($2, $4, NULL_TREE, NULL_TREE,
+                                       NULL_TREE); }
        /* This is the case with just output operands.  */
        | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ')' ';'
-               { 
-                 finish_asm_stmt ($2, $4, $6, NULL_TREE,
-                                  NULL_TREE); 
-               }
+               { $$ = finish_asm_stmt ($2, $4, $6, NULL_TREE, NULL_TREE); }
        /* This is the case with input operands as well.  */
-       | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':' asm_operands ')' ';'
-               { finish_asm_stmt ($2, $4, $6, $8, NULL_TREE); }
+       | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':'
+         asm_operands ')' ';'
+               { $$ = finish_asm_stmt ($2, $4, $6, $8, NULL_TREE); }
        | asm_keyword maybe_cv_qualifier '(' string SCOPE asm_operands ')' ';'
-               { finish_asm_stmt ($2, $4, NULL_TREE, $6, NULL_TREE); }
+               { $$ = finish_asm_stmt ($2, $4, NULL_TREE, $6, NULL_TREE); }
        /* This is the case with clobbered registers as well.  */
        | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':'
          asm_operands ':' asm_clobbers ')' ';'
-               { finish_asm_stmt ($2, $4, $6, $8, $10); }
+               { $$ = finish_asm_stmt ($2, $4, $6, $8, $10); }
        | asm_keyword maybe_cv_qualifier '(' string SCOPE asm_operands ':'
          asm_clobbers ')' ';'
-               { finish_asm_stmt ($2, $4, NULL_TREE, $6, $8); }
+               { $$ = finish_asm_stmt ($2, $4, NULL_TREE, $6, $8); }
        | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands SCOPE
          asm_clobbers ')' ';'
-               { finish_asm_stmt ($2, $4, $6, NULL_TREE, $8); }
+               { $$ = finish_asm_stmt ($2, $4, $6, NULL_TREE, $8); }
        | GOTO '*' expr ';'
                 { 
                  if (pedantic)
                    pedwarn ("ISO C++ forbids computed gotos");
-                 finish_goto_stmt ($3);
+                 $$ = finish_goto_stmt ($3);
                }
        | GOTO identifier ';'
-                { finish_goto_stmt ($2); }
+                { $$ = finish_goto_stmt ($2); }
        | label_colon stmt
+               { $$ = NULL_TREE; }
        | label_colon '}'
                { error ("label must be followed by statement");
-                 yyungetc ('}', 0); }
+                 yyungetc ('}', 0);
+                 $$ = NULL_TREE; }
        | ';'
-               { finish_stmt (); }
+               { finish_stmt ();
+                 $$ = NULL_TREE; }
        | try_block
+               { $$ = NULL_TREE; }
        | using_directive
+               { $$ = NULL_TREE; }
        | namespace_using_decl
-               { do_local_using_decl ($1); }
+               { do_local_using_decl ($1);
+                 $$ = NULL_TREE; }
        | namespace_alias
+               { $$ = NULL_TREE; }
        ;
 
 function_try_block:
@@ -3842,6 +3859,14 @@ operator_name:
                { $$ = frob_opname (ansi_opname (ERROR_MARK)); }
        ;
 
+/* The forced readahead in here is because we might be at the end of a
+   line, and lineno won't be bumped until yylex absorbs the first token
+   on the next line.  */
+save_lineno:
+               { if (yychar == YYEMPTY)
+                   yychar = YYLEX;
+                 $$ = lineno; }
+       ;
 %%
 
 #ifdef SPEW_DEBUG
index 8502eef..856f4ae 100644 (file)
@@ -150,7 +150,7 @@ do_pushlevel ()
 
 /* Finish a goto-statement.  */
 
-void
+tree
 finish_goto_stmt (destination)
      tree destination;
 {
@@ -171,7 +171,7 @@ finish_goto_stmt (destination)
   
   check_goto (destination);
 
-  add_stmt (build_stmt (GOTO_STMT, destination));
+  return add_stmt (build_stmt (GOTO_STMT, destination));
 }
 
 /* COND is the condition-expression for an if, while, etc.,
@@ -196,10 +196,12 @@ maybe_convert_cond (cond)
 
 /* Finish an expression-statement, whose EXPRESSION is as indicated.  */
 
-void 
+tree
 finish_expr_stmt (expr)
      tree expr;
 {
+  tree r = NULL_TREE;
+
   if (expr != NULL_TREE)
     {
       if (!processing_template_decl
@@ -215,7 +217,7 @@ finish_expr_stmt (expr)
       if (!processing_template_decl)
        expr = break_out_cleanups (expr);
       
-      add_stmt (build_stmt (EXPR_STMT, expr));
+      r = add_stmt (build_stmt (EXPR_STMT, expr));
     }
 
   finish_stmt ();
@@ -223,6 +225,8 @@ finish_expr_stmt (expr)
   /* This was an expression-statement, so we save the type of the
      expression.  */
   last_expr_type = expr ? TREE_TYPE (expr) : NULL_TREE;
+
+  return r;
 }
 
 
@@ -375,10 +379,12 @@ finish_do_stmt (cond, do_stmt)
 /* Finish a return-statement.  The EXPRESSION returned, if any, is as
    indicated.  */
 
-void
+tree
 finish_return_stmt (expr)
      tree expr;
 {
+  tree r;
+
   if (!processing_template_decl)
     expr = check_return_expr (expr);
   if (!processing_template_decl)
@@ -391,8 +397,7 @@ finish_return_stmt (expr)
             return a value there.  When we finally generate the real
             return statement, CTOR_LABEL is no longer set, and we fall
             through into the normal return-processing code below.  */
-         finish_goto_stmt (ctor_label);
-         return;
+         return finish_goto_stmt (ctor_label);
        }
       else if (DECL_DESTRUCTOR_P (current_function_decl))
        {
@@ -400,12 +405,13 @@ finish_return_stmt (expr)
             base-classes before returning.  So, all returns in a
             destructor get sent to the DTOR_LABEL; finsh_function emits
             code to return a value there.  */
-         finish_goto_stmt (dtor_label);
-         return;
+         return finish_goto_stmt (dtor_label);
        }
     }
-  add_stmt (build_stmt (RETURN_STMT, expr));
+  r = add_stmt (build_stmt (RETURN_STMT, expr));
   finish_stmt ();
+
+  return r;
 }
 
 /* Begin a for-statement.  Returns a new FOR_STMT if appropriate.  */
@@ -482,18 +488,18 @@ finish_for_stmt (for_stmt)
 
 /* Finish a break-statement.  */
 
-void
+tree
 finish_break_stmt ()
 {
-  add_stmt (build_break_stmt ());
+  return add_stmt (build_break_stmt ());
 }
 
 /* Finish a continue-statement.  */
 
-void
+tree
 finish_continue_stmt ()
 {
-  add_stmt (build_continue_stmt ());
+  return add_stmt (build_continue_stmt ());
 }
 
 /* Begin a switch-statement.  Returns a new SWITCH_STMT if
@@ -884,7 +890,7 @@ finish_compound_stmt (has_no_scope, compound_stmt)
    STRING, some OUTPUT_OPERANDS, some INPUT_OPERANDS, and some
    CLOBBERS.  */
 
-void
+tree
 finish_asm_stmt (cv_qualifier, string, output_operands,
                 input_operands, clobbers)
      tree cv_qualifier;
@@ -914,7 +920,7 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
   r = build_stmt (ASM_STMT, cv_qualifier, string,
                  output_operands, input_operands,
                  clobbers);
-  add_stmt (r);
+  return add_stmt (r);
 }
 
 /* Finish a label with the indicated NAME.  */