From 24965e7a8ac518b99a3bd7ef5b2d8d88f96bf514 Mon Sep 17 00:00:00 2001
From: Neil Booth <neil@daikokuya.demon.co.uk>
Date: Fri, 8 Mar 2002 19:21:04 +0000
Subject: [PATCH] expr.c (expand_expr): Use unsave lang hook.

	* expr.c (expand_expr): Use unsave lang hook.
	* langhooks-def.h (LANG_HOOKS_UNSAVE): New.
	(LANG_HOOKS_INITIALIZER): Update.
	* langhooks.h (struct lang_hooks): New hook unsave.
	* tree.c (lang_unsave, lang_unsave_expr_now): Remove.
	(unsave_expr_1): Remove unused lang_unsave_expr_now.
	(unsave_expr_now_r): Rename lhd_unsave.  Update. Return input.
	(unsave_expr_now): Remove.
	* tree.h (unsave_expr_now, lang_unsave,
	lang_unsave_expr_now): Remove.
	(lhd_unsave): New.
cp:
	* cp-lang.c (LANG_HOOKS_UNSAVE): Redefine.
	* cp-tree.h (cxx_unsave): New.
	* tree.c (cp_unsave): Rename cxx_unsave, update prototype.
	(init_tree): Update.

From-SVN: r50449
---
 gcc/ChangeLog       | 14 ++++++++++++++
 gcc/cp/ChangeLog    |  7 +++++++
 gcc/cp/cp-lang.c    |  2 ++
 gcc/cp/cp-tree.h    |  1 +
 gcc/cp/tree.c       | 17 ++++++++---------
 gcc/expr.c          |  3 ++-
 gcc/langhooks-def.h |  2 ++
 gcc/langhooks.h     |  5 +++++
 gcc/tree.c          | 39 +++++++--------------------------------
 gcc/tree.h          | 14 ++------------
 10 files changed, 50 insertions(+), 54 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 14d4cd34c265..0e63f6667e77 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2002-03-08  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+	* expr.c (expand_expr): Use unsave lang hook.
+	* langhooks-def.h (LANG_HOOKS_UNSAVE): New.
+	(LANG_HOOKS_INITIALIZER): Update.
+	* langhooks.h (struct lang_hooks): New hook unsave.
+	* tree.c (lang_unsave, lang_unsave_expr_now): Remove.
+	(unsave_expr_1): Remove unused lang_unsave_expr_now.
+	(unsave_expr_now_r): Rename lhd_unsave.  Update. Return input.
+	(unsave_expr_now): Remove.
+	* tree.h (unsave_expr_now, lang_unsave,
+	lang_unsave_expr_now): Remove.
+	(lhd_unsave): New.
+
 2002-03-08  Andreas Jaeger  <aj@suse.de>
 
 	* flow.c (propagate_block_delete_insn): Remove unused variable.
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 56136be9f0a7..c9166dce575a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2002-03-08  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+	* cp-lang.c (LANG_HOOKS_UNSAVE): Redefine.
+	* cp-tree.h (cxx_unsave): New.
+	* tree.c (cp_unsave): Rename cxx_unsave, update prototype.
+	(init_tree): Update.
+
 2002-03-03  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
 	* decl.c (cxx_init_decl_processing): Use ARRAY_SIZE in lieu of
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index 800a8701de2e..072550ad6785 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -52,6 +52,8 @@ static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
 #define LANG_HOOKS_SAFE_FROM_P c_safe_from_p
 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl
+#undef LANG_HOOKS_UNSAVE_EXPR_NOW
+#define LANG_HOOKS_UNSAVE_EXPR_NOW cxx_unsave_expr_now
 #undef LANG_HOOKS_PRINT_STATISTICS
 #define LANG_HOOKS_PRINT_STATISTICS cxx_print_statistics
 #undef LANG_HOOKS_PRINT_XNODE
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a8c62de39e52..efceb8c399e0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4222,6 +4222,7 @@ extern void replace_defarg			PARAMS ((tree, tree));
 extern void end_input				PARAMS ((void));
 
 /* in tree.c */
+extern tree cxx_unsave_expr_now		PARAMS ((tree));
 extern void init_tree			        PARAMS ((void));
 extern int pod_type_p				PARAMS ((tree));
 extern tree canonical_type_variant              PARAMS ((tree));
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a49a2dcc6646..5a8b902455bf 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -44,7 +44,6 @@ static tree no_linkage_helper PARAMS ((tree *, int *, void *));
 static tree build_srcloc PARAMS ((const char *, int));
 static tree mark_local_for_remap_r PARAMS ((tree *, int *, void *));
 static tree cp_unsave_r PARAMS ((tree *, int *, void *));
-static void cp_unsave PARAMS ((tree *));
 static tree build_target_expr PARAMS ((tree, tree));
 static tree count_trees_r PARAMS ((tree *, int *, void *));
 static tree verify_stmt_tree_r PARAMS ((tree *, int *, void *));
@@ -2297,7 +2296,6 @@ void
 init_tree ()
 {
   make_lang_type_fn = cp_make_lang_type;
-  lang_unsave = cp_unsave;
   lang_statement_code_p = cp_statement_code_p;
   lang_set_decl_assembler_name = mangle_decl;
   list_hash_table = htab_create (31, list_hash, list_hash_eq, NULL);
@@ -2389,12 +2387,11 @@ cp_unsave_r (tp, walk_subtrees, data)
   return NULL_TREE;
 }
 
-/* Called by unsave_expr_now whenever an expression (*TP) needs to be
-   unsaved.  */
+/* Called whenever an expression needs to be unsaved.  */
 
-static void
-cp_unsave (tp)
-     tree *tp;
+tree
+cxx_unsave_expr_now (tp)
+     tree tp;
 {
   splay_tree st;
 
@@ -2403,13 +2400,15 @@ cp_unsave (tp)
   st = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
 
   /* Walk the tree once figuring out what needs to be remapped.  */
-  walk_tree (tp, mark_local_for_remap_r, st, NULL);
+  walk_tree (&tp, mark_local_for_remap_r, st, NULL);
 
   /* Walk the tree again, copying, remapping, and unsaving.  */
-  walk_tree (tp, cp_unsave_r, st, NULL);
+  walk_tree (&tp, cp_unsave_r, st, NULL);
 
   /* Clean up.  */
   splay_tree_delete (st);
+
+  return tp;
 }
 
 /* Returns the kind of special function that DECL (a FUNCTION_DECL)
diff --git a/gcc/expr.c b/gcc/expr.c
index 1cc1d161d224..caf5a75f8ea2 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6441,7 +6441,8 @@ expand_expr (exp, target, tmode, modifier)
       {
 	rtx temp;
 	temp = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
-	TREE_OPERAND (exp, 0) = unsave_expr_now (TREE_OPERAND (exp, 0));
+	TREE_OPERAND (exp, 0)
+	  = (*lang_hooks.unsave_expr_now) (TREE_OPERAND (exp, 0));
 	return temp;
       }
 
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 89002aa07968..06ca4f388e88 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -77,6 +77,7 @@ void lhd_tree_inlining_end_inlining		PARAMS ((tree));
 #define LANG_HOOKS_SAFE_FROM_P		lhd_safe_from_p
 #define LANG_HOOKS_STATICP		lhd_staticp
 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL lhd_do_nothing_t
+#define LANG_HOOKS_UNSAVE_EXPR_NOW	lhd_unsave_expr_now
 #define LANG_HOOKS_HONOR_READONLY	false
 #define LANG_HOOKS_PRINT_STATISTICS	lhd_do_nothing
 #define LANG_HOOKS_PRINT_XNODE		lhd_print_tree_nothing
@@ -146,6 +147,7 @@ int lhd_tree_dump_type_quals			PARAMS ((tree));
   LANG_HOOKS_SAFE_FROM_P, \
   LANG_HOOKS_STATICP, \
   LANG_HOOKS_DUP_LANG_SPECIFIC_DECL, \
+  LANG_HOOKS_UNSAVE_EXPR_NOW, \
   LANG_HOOKS_HONOR_READONLY, \
   LANG_HOOKS_PRINT_STATISTICS, \
   LANG_HOOKS_PRINT_XNODE, \
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 8203fd192142..14eb999d9c06 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -132,6 +132,11 @@ struct lang_hooks
      DECL_NODE with a newly GC-allocated copy.  */
   void (*dup_lang_specific_decl) PARAMS ((tree));
 
+  /* Called before its argument, an UNSAVE_EXPR, is to be
+     unsaved.  Modify it in-place so that all the evaluate only once
+     things are cleared out.  */
+  tree (*unsave_expr_now) PARAMS ((tree));
+
   /* Nonzero if TYPE_READONLY and TREE_READONLY should always be honored.  */
   bool honor_readonly;
 
diff --git a/gcc/tree.c b/gcc/tree.c
index a54b50641cb1..4f19508688fb 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -52,8 +52,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 /* obstack.[ch] explicitly declined to prototype this.  */
 extern int _obstack_allocated_p PARAMS ((struct obstack *h, PTR obj));
 
-static void unsave_expr_now_r PARAMS ((tree));
-
 /* Objects allocated on this obstack last forever.  */
 
 struct obstack permanent_obstack;
@@ -167,14 +165,6 @@ static int type_hash_marked_p PARAMS ((const void *));
 static void type_hash_mark PARAMS ((const void *));
 static int mark_tree_hashtable_entry PARAMS((void **, void *));
 
-/* If non-null, these are language-specific helper functions for
-   unsave_expr_now.  If present, LANG_UNSAVE is called before its
-   argument (an UNSAVE_EXPR) is to be unsaved, and all other
-   processing in unsave_expr_now is aborted.  LANG_UNSAVE_EXPR_NOW is
-   called from unsave_expr_1 for language-specific tree codes.  */
-void (*lang_unsave) PARAMS ((tree *));
-void (*lang_unsave_expr_now) PARAMS ((tree));
-
 /* If non-null, these are language-specific helper functions for
    unsafe_for_reeval.  Return negative to not handle some tree.  */
 int (*lang_unsafe_for_reeval) PARAMS ((tree));
@@ -1670,23 +1660,21 @@ unsave_expr_1 (expr)
       break;
 
     default:
-      if (lang_unsave_expr_now != 0)
-	(*lang_unsave_expr_now) (expr);
       break;
     }
 }
 
-/* Helper function for unsave_expr_now.  */
+/* Default lang hook for "unsave_expr_now".  */
 
-static void
-unsave_expr_now_r (expr)
+tree
+lhd_unsave_expr_now (expr)
      tree expr;
 {
   enum tree_code code;
 
   /* There's nothing to do for NULL_TREE.  */
   if (expr == 0)
-    return;
+    return expr;
 
   unsave_expr_1 (expr);
 
@@ -1702,8 +1690,8 @@ unsave_expr_now_r (expr)
     case 'x':  /* miscellaneous: e.g., identifier, TREE_LIST or ERROR_MARK.  */
       if (code == TREE_LIST)
 	{
-	  unsave_expr_now_r (TREE_VALUE (expr));
-	  unsave_expr_now_r (TREE_CHAIN (expr));
+	  lhd_unsave_expr_now (TREE_VALUE (expr));
+	  lhd_unsave_expr_now (TREE_CHAIN (expr));
 	}
       break;
 
@@ -1717,26 +1705,13 @@ unsave_expr_now_r (expr)
 	int i;
 
 	for (i = first_rtl_op (code) - 1; i >= 0; i--)
-	  unsave_expr_now_r (TREE_OPERAND (expr, i));
+	  lhd_unsave_expr_now (TREE_OPERAND (expr, i));
       }
       break;
 
     default:
       abort ();
     }
-}
-
-/* Modify a tree in place so that all the evaluate only once things
-   are cleared out.  Return the EXPR given.  */
-
-tree
-unsave_expr_now (expr)
-     tree expr;
-{
-  if (lang_unsave!= 0)
-    (*lang_unsave) (&expr);
-  else
-    unsave_expr_now_r (expr);
 
   return expr;
 }
diff --git a/gcc/tree.h b/gcc/tree.h
index 68b96e825877..cb67df88fe5c 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2550,18 +2550,6 @@ extern tree unsave_expr			PARAMS ((tree));
 
 extern void unsave_expr_1               PARAMS ((tree));
 
-/* Like unsave_expr_1, but recurses into all subtrees.  */
-
-extern tree unsave_expr_now		PARAMS ((tree));
-
-/* If non-null, these are language-specific helper functions for
-   unsave_expr_now.  If present, LANG_UNSAVE is called before its
-   argument (an UNSAVE_EXPR) is to be unsaved, and all other
-   processing in unsave_expr_now is aborted.  LANG_UNSAVE_EXPR_NOW is
-   called from unsave_expr_1 for language-specific tree codes.  */
-extern void (*lang_unsave)              PARAMS ((tree *));
-extern void (*lang_unsave_expr_now)     PARAMS ((tree));
-
 /* Return 0 if it is safe to evaluate EXPR multiple times,
    return 1 if it is safe if EXPR is unsaved afterward, or
    return 2 if it is completely unsafe.  */
@@ -2756,6 +2744,8 @@ extern tree get_set_constructor_bytes		PARAMS ((tree,
 extern tree get_callee_fndecl                   PARAMS ((tree));
 extern void set_decl_assembler_name             PARAMS ((tree));
 extern int type_num_arguments                   PARAMS ((tree));
+extern tree lhd_unsave_expr_now		PARAMS ((tree));
+
 
 /* In stmt.c */
 
-- 
GitLab