cp-tree.h (EXPR_STMT_ASSIGNS_THIS): New macro.
authorMark Mitchell <mark@codesourcery.com>
Thu, 9 Sep 1999 23:24:34 +0000 (23:24 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 9 Sep 1999 23:24:34 +0000 (23:24 +0000)
* cp-tree.h (EXPR_STMT_ASSIGNS_THIS): New macro.
(STMT_IS_FULL_EXPR_P): Likewise.
(STMT_LINENO_FOR_FN_P): Likewise.
(prep_stmt): New function.
(building_stmt_tree): Tweak for safety.
* pt.c (tsubst_expr): Use prep_stmt throughout.
(add_tree): Move it to semantics.c
* semantics.c (add_tree): Move it here.
(finish_expr_stmt_real): New function.
(finish_expr_stmt): Use it.
(finish_if_stmt_cond): Use FINISH_COND.
(finish_while_stmt_cond): Likewise.
(finish_for_cond): Likewise.
(finish_stmt_tree): Tweak line-number handling.
(prep_stmt): New function.
(expand_stmt): Use it.

From-SVN: r29249

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/semantics.c

index 49c585d..f90f804 100644 (file)
@@ -1,5 +1,22 @@
 1999-09-09  Mark Mitchell  <mark@codesourcery.com>
 
+       * cp-tree.h (EXPR_STMT_ASSIGNS_THIS): New macro.
+       (STMT_IS_FULL_EXPR_P): Likewise.
+       (STMT_LINENO_FOR_FN_P): Likewise.
+       (prep_stmt): New function.
+       (building_stmt_tree): Tweak for safety.
+       * pt.c (tsubst_expr): Use prep_stmt throughout.
+       (add_tree): Move it to semantics.c
+       * semantics.c (add_tree): Move it here.
+       (finish_expr_stmt_real): New function.
+       (finish_expr_stmt): Use it.
+       (finish_if_stmt_cond): Use FINISH_COND.
+       (finish_while_stmt_cond): Likewise.
+       (finish_for_cond): Likewise.
+       (finish_stmt_tree): Tweak line-number handling.
+       (prep_stmt): New function.
+       (expand_stmt): Use it.
+       
        * cp-tree.h (begin_switch_stmt): Adjust prototype.
        (finish_switch_cond): Likewise.
        * parse.y (simple_stmt): Adjust accordingly.
index c8fc430..bb47e9b 100644 (file)
@@ -29,6 +29,7 @@ Boston, MA 02111-1307, USA.  */
 /* Usage of TREE_LANG_FLAG_?:
    0: BINFO_MARKED (BINFO nodes).
       COMPOUND_STMT_NO_SCOPE (in COMPOUND_STMT).
+      EXPR_STMT_ASSIGNS_THIS (in EXPR_STMT).
       NEW_EXPR_USE_GLOBAL (in NEW_EXPR).
       DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR).
       LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR).
@@ -49,12 +50,14 @@ Boston, MA 02111-1307, USA.  */
       INHERITED_VALUE_BINDING_P (in CPLUS_BINDING)
       BASELINK_P (in TREE_LIST)
       ICS_ELLIPSIS_FLAG (in _CONV)
+      STMT_IS_FULL_EXPR_P (in _STMT)
    2: IDENTIFIER_OPNAME_P.
       BINFO_VBASE_MARKED.
       BINFO_FIELDS_MARKED.
       TYPE_VIRTUAL_P.
       ICS_THIS_FLAG (in _CONV)
-      BINDING_HAS_LEVEL_P (In CPLUS_BINDING)
+      STMT_LINENO_FOR_FN_P (in _STMT)
+      BINDING_HAS_LEVEL_P (in CPLUS_BINDING)
    3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE).
       BINFO_VTABLE_PATH_MARKED.
       BINFO_PUSHDECLS_MARKED.
@@ -1816,6 +1819,15 @@ struct lang_decl
    constructor call, rather than an ordinary function call.  */
 #define AGGR_INIT_VIA_CTOR_P(NODE) TREE_LANG_FLAG_0 (NODE)
 
+/* Nonzero if this statement contained the first assigned to `this' in
+   the current function.  (Of course, one cannot assign to `this' in
+   ANSI/ISO C++, but we still support assignments to this with
+   -fthis-is-variable.)  */
+#define EXPR_STMT_ASSIGNS_THIS(NODE) TREE_LANG_FLAG_0 ((NODE))
+
+/* Nonzero if this statement should be considered a full-expression.  */
+#define STMT_IS_FULL_EXPR_P(NODE) TREE_LANG_FLAG_1 ((NODE))
+
 /* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a
    TEMPLATE_DECL.  This macro determines whether or not a given class
    type is really a template type, as opposed to an instantiation or
@@ -2430,10 +2442,17 @@ extern int flag_new_for_scope;
 #define ASM_VOLATILE_P(NODE)                   \
   (ASM_CV_QUAL ((NODE)) != NULL_TREE)
 
-/* The line-number at which a statement began.  */
+/* The line-number at which a statement began.  But if
+   STMT_LINENO_FOR_FN_P does holds, then this macro gives the
+   line number for the end of the current function instead.  */
 #define STMT_LINENO(NODE)                      \
   (TREE_COMPLEXITY ((NODE)))
 
+/* If non-zero, the STMT_LINENO for NODE is the line at which the
+   function ended.  */
+#define STMT_LINENO_FOR_FN_P(NODE)             \
+  (TREE_LANG_FLAG_2 ((NODE)))
+
 /* The parameters for a call-declarator.  */
 #define CALL_DECLARATOR_PARMS(NODE) \
   (TREE_PURPOSE (TREE_OPERAND ((NODE), 1)))
@@ -3635,10 +3654,11 @@ extern tree expand_stmt                         PROTO((tree));
 extern void expand_body                         PROTO((tree));
 extern void begin_stmt_tree                     PROTO((tree));
 extern void finish_stmt_tree                    PROTO((tree));
+extern void prep_stmt                           PROTO((tree));
 /* Non-zero if we are presently building a statement tree, rather
    than expanding each statement as we encounter it.  */
-#define building_stmt_tree() \
-  (processing_template_decl || !expanding_p)
+#define building_stmt_tree()                                     \
+  (current_function && (processing_template_decl || !expanding_p))
 
 /* in spew.c */
 extern void init_spew                          PROTO((void));
index 0795a19..9fd1f2f 100644 (file)
@@ -7235,6 +7235,7 @@ tsubst_expr (t, args, complain, in_decl)
   switch (TREE_CODE (t))
     {
     case RETURN_INIT:
+      prep_stmt (t);
       finish_named_return_value
        (TREE_OPERAND (t, 0),
         tsubst_expr (TREE_OPERAND (t, 1), args, /*complain=*/1, in_decl));
@@ -7242,6 +7243,7 @@ tsubst_expr (t, args, complain, in_decl)
       break;
 
     case CTOR_INITIALIZER:
+      prep_stmt (t);
       current_member_init_list
        = tsubst_expr_values (TREE_OPERAND (t, 0), args);
       current_base_init_list
@@ -7251,13 +7253,18 @@ tsubst_expr (t, args, complain, in_decl)
       break;
 
     case RETURN_STMT:
-      lineno = STMT_LINENO (t);
+      prep_stmt (t);
       finish_return_stmt (tsubst_expr (RETURN_EXPR (t),
                                       args, complain, in_decl));
       break;
 
     case EXPR_STMT:
-      lineno = STMT_LINENO (t);
+      prep_stmt (t);
+      /* If we're doing tsubst'ing, then we should not yet have done
+        semantic analysisy, so we should not know that this statement
+        assigns to the `this' pointer.  */
+      my_friendly_assert (EXPR_STMT_ASSIGNS_THIS (t) == 0,
+                         19990831);
       finish_expr_stmt (tsubst_expr (EXPR_STMT_EXPR (t),
                                     args, complain, in_decl));
       break;
@@ -7268,7 +7275,7 @@ tsubst_expr (t, args, complain, in_decl)
        tree decl;
        tree init;
 
-       lineno = STMT_LINENO (t);
+       prep_stmt (t);
        decl = DECL_STMT_DECL (t);
        if (TREE_CODE (decl) == LABEL_DECL)
          finish_label_decl (DECL_NAME (decl));
@@ -7296,7 +7303,7 @@ tsubst_expr (t, args, complain, in_decl)
     case FOR_STMT:
       {
        tree tmp;
-       lineno = STMT_LINENO (t);
+       prep_stmt (t);
 
        stmt = begin_for_stmt ();
        for (tmp = FOR_INIT_STMT (t); tmp; tmp = TREE_CHAIN (tmp))
@@ -7314,7 +7321,7 @@ tsubst_expr (t, args, complain, in_decl)
 
     case WHILE_STMT:
       {
-       lineno = STMT_LINENO (t);
+       prep_stmt (t);
        stmt = begin_while_stmt ();
        finish_while_stmt_cond (tsubst_expr (WHILE_COND (t),
                                             args, complain, in_decl),
@@ -7326,7 +7333,7 @@ tsubst_expr (t, args, complain, in_decl)
 
     case DO_STMT:
       {
-       lineno = STMT_LINENO (t);
+       prep_stmt (t);
        stmt = begin_do_stmt ();
        tsubst_expr (DO_BODY (t), args, complain, in_decl);
        finish_do_body (stmt);
@@ -7340,7 +7347,7 @@ tsubst_expr (t, args, complain, in_decl)
       {
        tree tmp;
 
-       lineno = STMT_LINENO (t);
+       prep_stmt (t);
        stmt = begin_if_stmt ();
        finish_if_stmt_cond (tsubst_expr (IF_COND (t),
                                          args, complain, in_decl),
@@ -7367,7 +7374,7 @@ tsubst_expr (t, args, complain, in_decl)
       {
        tree substmt;
 
-       lineno = STMT_LINENO (t);
+       prep_stmt (t);
        stmt = begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
        for (substmt = COMPOUND_BODY (t); 
             substmt != NULL_TREE;
@@ -7378,12 +7385,12 @@ tsubst_expr (t, args, complain, in_decl)
       break;
 
     case BREAK_STMT:
-      lineno = STMT_LINENO (t);
+      prep_stmt (t);
       finish_break_stmt ();
       break;
 
     case CONTINUE_STMT:
-      lineno = STMT_LINENO (t);
+      prep_stmt (t);
       finish_continue_stmt ();
       break;
 
@@ -7391,7 +7398,7 @@ tsubst_expr (t, args, complain, in_decl)
       {
        tree val;
 
-       lineno = STMT_LINENO (t);
+       prep_stmt (t);
        stmt = begin_switch_stmt ();
        val = tsubst_expr (SWITCH_COND (t), args, complain, in_decl);
        finish_switch_cond (val, stmt);
@@ -7401,6 +7408,7 @@ tsubst_expr (t, args, complain, in_decl)
       break;
 
     case CASE_LABEL:
+      prep_stmt (t);
       finish_case_label (tsubst_expr (CASE_LOW (t), args, complain, in_decl),
                         tsubst_expr (CASE_HIGH (t), args, complain, in_decl));
       break;
@@ -7411,7 +7419,7 @@ tsubst_expr (t, args, complain, in_decl)
       break;
 
     case GOTO_STMT:
-      lineno = STMT_LINENO (t);
+      prep_stmt (t);
       t = GOTO_DESTINATION (t);
       if (TREE_CODE (t) != LABEL_DECL)
        /* Computed goto's must be tsubst'd into.  On the other hand,
@@ -7424,7 +7432,7 @@ tsubst_expr (t, args, complain, in_decl)
       break;
 
     case ASM_STMT:
-      lineno = STMT_LINENO (t);
+      prep_stmt (t);
       finish_asm_stmt (ASM_CV_QUAL (t),
                       tsubst_expr (ASM_STRING (t), args, complain, in_decl),
                       tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
@@ -7434,7 +7442,7 @@ tsubst_expr (t, args, complain, in_decl)
       break;
 
     case TRY_BLOCK:
-      lineno = STMT_LINENO (t);
+      prep_stmt (t);
       stmt = begin_try_block ();
       tsubst_expr (TRY_STMTS (t), args, complain, in_decl);
       finish_try_block (stmt);
@@ -7452,7 +7460,7 @@ tsubst_expr (t, args, complain, in_decl)
       break;
 
     case HANDLER:
-      lineno = STMT_LINENO (t);
+      prep_stmt (t);
       stmt = begin_handler ();
       if (HANDLER_PARMS (t))
        expand_start_catch_block
@@ -7466,7 +7474,7 @@ tsubst_expr (t, args, complain, in_decl)
       break;
 
     case TAG_DEFN:
-      lineno = STMT_LINENO (t);
+      prep_stmt (t);
       t = TREE_TYPE (t);
       if (TREE_CODE (t) == ENUMERAL_TYPE)
        tsubst (t, args, complain, NULL_TREE);
@@ -9854,14 +9862,6 @@ tsubst_expr_values (t, argvec)
 }
 
 void
-add_tree (t)
-     tree t;
-{
-  last_tree = TREE_CHAIN (last_tree) = t;
-}
-
-
-void
 begin_tree ()
 {
   if (current_function)
index 4d6a234..0b65dee 100644 (file)
@@ -44,6 +44,7 @@
 static void expand_stmts PROTO((tree));
 static void do_pushlevel PROTO((void));
 static tree do_poplevel PROTO((void));
+static void finish_expr_stmt_real PROTO((tree, int));
 static tree expand_cond PROTO((tree));
 
 /* When parsing a template, LAST_TREE contains the last statement
@@ -75,11 +76,29 @@ static tree expand_cond PROTO((tree));
       substmt = cond;                          \
   } while (0)
   
-/* Finish an expression-statement, whose EXPRESSION is as indicated.  */
+/* T is a statement.  Add it to the statement-tree.  */
 
-void 
-finish_expr_stmt (expr)
+void
+add_tree (t)
+     tree t;
+{
+  /* Add T to the statement-tree.  */
+  last_tree = TREE_CHAIN (last_tree) = t;
+
+  /* When we expand a statement-tree, we must know whether or not the
+     statements are full-expresions.  We record that fact here.  */
+  if (building_stmt_tree ())
+    STMT_IS_FULL_EXPR_P (last_tree) = stmts_are_full_exprs_p;
+}
+
+/* Finish an expression-statement, whose EXPRESSION is as indicated.
+   If ASSIGNED_THIS is non-zero, then this statement just assigned to
+   the `this' pointer.  */
+
+static void 
+finish_expr_stmt_real (expr, assigned_this)
      tree expr;
+     int assigned_this;
 {
   if (expr != NULL_TREE)
     {
@@ -109,6 +128,11 @@ finish_expr_stmt (expr)
        }
     }
 
+  /* If this statement assigned to the `this' pointer, record that
+     fact for finish_stmt.  */
+  if (assigned_this)
+    current_function_just_assigned_this = 1;
+
   finish_stmt ();
 
   /* This was an expression-statement, so we save the type of the
@@ -116,6 +140,15 @@ finish_expr_stmt (expr)
   last_expr_type = expr ? TREE_TYPE (expr) : NULL_TREE;
 }
 
+/* Like finish_expr_stmt_real, but ASSIGNS_THIS is always zero.  */
+
+void
+finish_expr_stmt (expr)
+     tree expr;
+{
+  finish_expr_stmt_real (expr, /*assigns_this=*/0);
+}
+
 /* Begin an if-statement.  Returns a newly created IF_STMT if
    appropriate.  */
 
@@ -146,12 +179,7 @@ finish_if_stmt_cond (cond, if_stmt)
      tree if_stmt;
 {
   if (building_stmt_tree ())
-    {
-      if (last_tree != if_stmt)
-       RECHAIN_STMTS_FROM_LAST (if_stmt, IF_COND (if_stmt));
-      else
-       IF_COND (if_stmt) = cond;
-    }
+    FINISH_COND (cond, if_stmt, IF_COND (if_stmt));
   else
     {
       emit_line_note (input_filename, lineno);
@@ -244,12 +272,7 @@ finish_while_stmt_cond (cond, while_stmt)
      tree while_stmt;
 {
   if (building_stmt_tree ())
-    {
-      if (last_tree != while_stmt)
-       RECHAIN_STMTS_FROM_LAST (while_stmt, WHILE_COND (while_stmt)); 
-      else
-       TREE_OPERAND (while_stmt, 0) = cond;
-    }
+    FINISH_COND (cond, while_stmt, WHILE_COND (while_stmt));
   else
     {
       emit_line_note (input_filename, lineno);
@@ -409,12 +432,7 @@ finish_for_cond (cond, for_stmt)
      tree for_stmt;
 {
   if (building_stmt_tree ())
-    {
-      if (last_tree != for_stmt)
-       RECHAIN_STMTS_FROM_LAST (for_stmt, FOR_COND (for_stmt));
-      else
-       FOR_COND (for_stmt) = cond;
-    }
+    FINISH_COND (cond, for_stmt, FOR_COND (for_stmt));
   else
     {
       emit_line_note (input_filename, lineno);
@@ -1973,7 +1991,28 @@ void
 finish_stmt_tree (fn)
      tree fn;
 {
-  DECL_SAVED_TREE (fn) = TREE_CHAIN (DECL_SAVED_TREE (fn));
+  tree stmt;
+  
+  /* Remove the fake extra statement added in begin_stmt_tree.  */
+  stmt = TREE_CHAIN (DECL_SAVED_TREE (fn));
+  DECL_SAVED_TREE (fn) = stmt;
+
+  /* The line-number recorded in the outermost statement in a function
+     is the line number of the end of the function.  */
+  STMT_LINENO (stmt) = lineno;
+  STMT_LINENO_FOR_FN_P (stmt) = 1;
+}
+
+/* We're about to expand T, a statement.  Set up appropriate context
+   for the substitution.  */
+
+void
+prep_stmt (t)
+     tree t;
+{
+  if (!STMT_LINENO_FOR_FN_P (t))
+    lineno = STMT_LINENO (t);
+  stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t);
 }
 
 /* Some statements, like for-statements or if-statements, require a
@@ -2013,19 +2052,28 @@ tree
 expand_stmt (t)
      tree t;
 {
+  int saved_stmts_are_full_exprs_p;
+  tree rval;
+
   if (t == NULL_TREE || t == error_mark_node)
     return NULL_TREE;
 
+  /* Assume we'll have nothing to return.  */
+  rval = NULL_TREE;
+
+  /* Set up context appropriately for handling this statement.  */
+  saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p;
+  prep_stmt (t);
+
   switch (TREE_CODE (t))
     {
     case RETURN_STMT:
-      lineno = STMT_LINENO (t);
       finish_return_stmt (RETURN_EXPR (t));
       break;
 
     case EXPR_STMT:
-      lineno = STMT_LINENO (t);
-      finish_expr_stmt (EXPR_STMT_EXPR (t));
+      finish_expr_stmt_real (EXPR_STMT_EXPR (t),
+                            EXPR_STMT_ASSIGNS_THIS (t));
       break;
 
     case DECL_STMT:
@@ -2064,7 +2112,6 @@ expand_stmt (t)
       {
        tree tmp;
 
-       lineno = STMT_LINENO (t);
        begin_for_stmt ();
        for (tmp = FOR_INIT_STMT (t); tmp; tmp = TREE_CHAIN (tmp))
          expand_stmt (tmp);
@@ -2079,7 +2126,6 @@ expand_stmt (t)
 
     case WHILE_STMT:
       {
-       lineno = STMT_LINENO (t);
        begin_while_stmt ();
        finish_while_stmt_cond (expand_cond (WHILE_COND (t)), NULL_TREE);
        expand_stmt (WHILE_BODY (t));
@@ -2089,7 +2135,6 @@ expand_stmt (t)
 
     case DO_STMT:
       {
-       lineno = STMT_LINENO (t);
        begin_do_stmt ();
        expand_stmt (DO_BODY (t));
        finish_do_body (NULL_TREE);
@@ -2098,7 +2143,6 @@ expand_stmt (t)
       break;
 
     case IF_STMT:
-      lineno = STMT_LINENO (t);
       begin_if_stmt ();
       finish_if_stmt_cond (expand_cond (IF_COND (t)), NULL_TREE);
       if (THEN_CLAUSE (t))
@@ -2116,19 +2160,17 @@ expand_stmt (t)
       break;
 
     case COMPOUND_STMT:
-      lineno = STMT_LINENO (t);
       begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
       expand_stmts (COMPOUND_BODY (t));
-      return finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), 
+      rval = finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), 
                                   NULL_TREE);
+      break;
 
     case BREAK_STMT:
-      lineno = STMT_LINENO (t);
       finish_break_stmt ();
       break;
 
     case CONTINUE_STMT:
-      lineno = STMT_LINENO (t);
       finish_continue_stmt ();
       break;
 
@@ -2136,7 +2178,6 @@ expand_stmt (t)
       {
        tree cond;
 
-       lineno = STMT_LINENO (t);
        begin_switch_stmt ();
        cond = expand_cond (SWITCH_COND (t));
        finish_switch_cond (cond, NULL_TREE);
@@ -2150,12 +2191,10 @@ expand_stmt (t)
       break;
 
     case LABEL_STMT:
-      lineno = STMT_LINENO (t);
       finish_label_stmt (DECL_NAME (LABEL_STMT_LABEL (t)));
       break;
 
     case GOTO_STMT:
-      lineno = STMT_LINENO (t);
       if (TREE_CODE (GOTO_DESTINATION (t)) == LABEL_DECL)
        finish_goto_stmt (DECL_NAME (GOTO_DESTINATION (t)));
       else
@@ -2163,13 +2202,11 @@ expand_stmt (t)
       break;
 
     case ASM_STMT:
-      lineno = STMT_LINENO (t);
       finish_asm_stmt (ASM_CV_QUAL (t), ASM_STRING (t), ASM_OUTPUTS
                       (t), ASM_INPUTS (t), ASM_CLOBBERS (t));
       break;
 
     case TRY_BLOCK:
-      lineno = STMT_LINENO (t);
       if (CLEANUP_P (t))
        {
          expand_eh_region_start ();
@@ -2187,7 +2224,6 @@ expand_stmt (t)
       break;
 
     case HANDLER:
-      lineno = STMT_LINENO (t);
       begin_handler ();
       if (HANDLER_PARMS (t))
        expand_start_catch_block (DECL_STMT_DECL (HANDLER_PARMS (t)));
@@ -2199,7 +2235,6 @@ expand_stmt (t)
       break;
 
     case SUBOBJECT:
-      lineno = STMT_LINENO (t);
       finish_subobject (SUBOBJECT_CLEANUP (t));
       break;
 
@@ -2208,7 +2243,10 @@ expand_stmt (t)
       break;
     }
 
-  return NULL_TREE;
+  /* Restore saved state.  */
+  stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p;
+
+  return rval;
 }
 
 /* Generate RTL for FN.  */