diff mbox series

[C++] Kill DECL_SAVED_FUNCTION_DATA

Message ID 6fbcb00e-cbcc-3854-e81c-cce451f8ea17@acm.org
State New
Headers show
Series [C++] Kill DECL_SAVED_FUNCTION_DATA | expand

Commit Message

Nathan Sidwell May 8, 2019, 5:31 p.m. UTC
I discovered that DECL_SAVED_FUNCTION_DATA became obsolete during or 
after the gimple conversion.  But we continued to faithfully save and 
restore it in the C++ FE.  We then extended it to hold the auto return 
pattern a function might have been declared with.

This patch removes the saved function data, and stores the auto pattern 
in the decl's slot that used to point to the saved data.

nathan
diff mbox series

Patch

2019-05-08  Nathan Sidwell  <nathan@acm.org>

	Kill DECL_SAVED_FUNCTION_DATA .
	* cp-tree.h (language_function): Remove x_auto_return_pattern.
	(current_function_auto_return_pattern): Delete.
	(lang_decl_fn): Replace saved_language_function with
	saved_auto_return type.
	(DECL_SAVED_FUNCTION_DATA): Delete.
	(DECL_SAVED_AUTO_RETURN_TYPE): New.
	(FNDECL_USED_AUTO): Correct documentation.
	* decl.c (duplicate_decls): Adjust AUTO return handling.
	(start_preparsed_function): Replace
	current_function_auto_return_pattern with
	DECL_SAVED_AUTO_RETURN_TYPE.  Remove DECL_SAVED_FUNCTION_DATA
	zapping.
	(finish_function): Likewise.
	(save_function_data): Delete.
	(fndecl_declared_return_type): Reimplement.
	* mangle.c (write_unqualified_name): Use DECL_SAVED_AUTO_RETURN_TYPE.
	* method.c (make_thunk, make_alias_for): Likewise.
	* parser.c (cp_parser_jump_statement): Likewise.
	* pt.c (do_auto_deduction): Likewise.
	* typeck.c (check_return_expr): Likewise.

Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 271012)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -1813,7 +1813,6 @@  struct GTY(()) language_function {
   tree x_in_charge_parm;
   tree x_vtt_parm;
   tree x_return_value;
-  tree x_auto_return_pattern;
 
   BOOL_BITFIELD returns_value : 1;
   BOOL_BITFIELD returns_null : 1;
@@ -1909,11 +1908,6 @@  struct GTY(()) language_function {
 #define current_function_return_value \
   (cp_function_chain->x_return_value)
 
-/* A type involving 'auto' to be used for return type deduction.  */
-
-#define current_function_auto_return_pattern \
-  (cp_function_chain->x_auto_return_pattern)
-
 /* In parser.c.  */
 extern tree cp_literal_operator_id (const char *);
 
@@ -2654,8 +2648,7 @@  struct GTY(()) lang_decl_fn {
   union lang_decl_u3
   {
     struct cp_token_cache * GTY ((tag ("1"))) pending_inline_info;
-    struct language_function * GTY ((tag ("0")))
-      saved_language_function;
+    tree GTY ((tag ("0"))) saved_auto_return_type;
   } GTY ((desc ("%1.pending_inline_p"))) u;
 
 };
@@ -3700,10 +3693,10 @@  struct GTY(()) lang_decl {
 #define FOLD_EXPR_INIT(NODE) \
   TREE_OPERAND (BINARY_FOLD_EXPR_CHECK (NODE), 2)
 
-/* In a FUNCTION_DECL, the saved language-specific per-function data.  */
-#define DECL_SAVED_FUNCTION_DATA(NODE)			\
+/* In a FUNCTION_DECL, the saved auto-return pattern.  */
+#define DECL_SAVED_AUTO_RETURN_TYPE(NODE)		\
   (LANG_DECL_FN_CHECK (FUNCTION_DECL_CHECK (NODE))	\
-   ->u.saved_language_function)
+   ->u.saved_auto_return_type)
 
 /* True if NODE is an implicit INDIRECT_REF from convert_from_reference.  */
 #define REFERENCE_REF_P(NODE)				\
@@ -3934,7 +3927,7 @@  more_aggr_init_expr_args_p (const aggr_i
 /* True if NODE was declared with auto in its return type, but it has
    started compilation and so the return type might have been changed by
    return type deduction; its declared return type should be found in
-   DECL_STRUCT_FUNCTION(NODE)->language->x_auto_return_pattern.  */
+   DECL_SAVED_AUTO_RETURN_TYPE (NODE).   */
 #define FNDECL_USED_AUTO(NODE) \
   TREE_LANG_FLAG_2 (FUNCTION_DECL_CHECK (NODE))
 
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 271012)
+++ gcc/cp/decl.c	(working copy)
@@ -80,7 +80,6 @@  static void maybe_deduce_size_from_array
 static void layout_var_decl (tree);
 static tree check_initializer (tree, tree, int, vec<tree, va_gc> **);
 static void make_rtl_for_nonlocal_decl (tree, tree, const char *);
-static void save_function_data (tree);
 static void copy_type_enum (tree , tree);
 static void check_function_type (tree, tree);
 static void finish_constructor_body (void);
@@ -2480,9 +2479,9 @@  duplicate_decls (tree newdecl, tree oldd
 	    }
 	  else if (DECL_PENDING_INLINE_P (newdecl))
 	    ;
-	  else if (DECL_SAVED_FUNCTION_DATA (newdecl) == NULL)
-	    DECL_SAVED_FUNCTION_DATA (newdecl)
-	      = DECL_SAVED_FUNCTION_DATA (olddecl);
+	  else if (DECL_SAVED_AUTO_RETURN_TYPE (newdecl) == NULL)
+	    DECL_SAVED_AUTO_RETURN_TYPE (newdecl)
+	      = DECL_SAVED_AUTO_RETURN_TYPE (olddecl);
 
 	  DECL_DECLARED_INLINE_P (newdecl) |= DECL_DECLARED_INLINE_P (olddecl);
 
@@ -15449,20 +15448,21 @@  start_preparsed_function (tree decl1, tr
   current_stmt_tree ()->stmts_are_full_exprs_p = 1;
   current_binding_level = bl;
 
+  /* If we are (erroneously) defining a function that we have already
+     defined before, wipe out what we knew before.  */
+  gcc_checking_assert (!DECL_PENDING_INLINE_P (decl1));
+  FNDECL_USED_AUTO (decl1) = false;
+  DECL_SAVED_AUTO_RETURN_TYPE (decl1) = NULL;
+
   if (!processing_template_decl && type_uses_auto (restype))
     {
       FNDECL_USED_AUTO (decl1) = true;
-      current_function_auto_return_pattern = restype;
+      DECL_SAVED_AUTO_RETURN_TYPE (decl1) = restype;
     }
 
   /* Start the statement-tree, start the tree now.  */
   DECL_SAVED_TREE (decl1) = push_stmt_list ();
 
-  /* If we are (erroneously) defining a function that we have already
-     defined before, wipe out what we knew before.  */
-  if (!DECL_PENDING_INLINE_P (decl1))
-    DECL_SAVED_FUNCTION_DATA (decl1) = NULL;
-
   if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1))
     {
       /* We know that this was set up by `grokclassfn'.  We do not
@@ -15753,31 +15753,6 @@  store_parm_decls (tree current_function_
 }
 
 
-/* We have finished doing semantic analysis on DECL, but have not yet
-   generated RTL for its body.  Save away our current state, so that
-   when we want to generate RTL later we know what to do.  */
-
-static void
-save_function_data (tree decl)
-{
-  struct language_function *f;
-
-  /* Save the language-specific per-function data so that we can
-     get it back when we really expand this function.  */
-  gcc_assert (!DECL_PENDING_INLINE_P (decl));
-
-  /* Make a copy.  */
-  f = ggc_alloc<language_function> ();
-  memcpy (f, cp_function_chain, sizeof (struct language_function));
-  DECL_SAVED_FUNCTION_DATA (decl) = f;
-
-  /* Clear out the bits we don't need.  */
-  f->base.x_stmt_tree.x_cur_stmt_list = NULL;
-  f->bindings = NULL;
-  f->base.local_typedefs = NULL;
-}
-
-
 /* Set the return value of the constructor (if present).  */
 
 static void
@@ -16106,9 +16081,9 @@  finish_function (bool inline_p)
      the return type is void.  But if the declared type is something like
      auto*, this is an error.  */
   if (!processing_template_decl && FNDECL_USED_AUTO (fndecl)
-      && TREE_TYPE (fntype) == current_function_auto_return_pattern)
+      && TREE_TYPE (fntype) == DECL_SAVED_AUTO_RETURN_TYPE (fndecl))
     {
-      if (is_auto (current_function_auto_return_pattern))
+      if (is_auto (DECL_SAVED_AUTO_RETURN_TYPE (fndecl)))
 	{
 	  apply_deduced_return_type (fndecl, void_type_node);
 	  fntype = TREE_TYPE (fndecl);
@@ -16117,7 +16092,7 @@  finish_function (bool inline_p)
 	       && !current_function_returns_null)
 	{
 	  error ("no return statements in function returning %qT",
-		 current_function_auto_return_pattern);
+		 DECL_SAVED_AUTO_RETURN_TYPE (fndecl));
 	  inform (input_location, "only plain %<auto%> return type can be "
 		  "deduced to %<void%>");
 	}
@@ -16180,10 +16155,6 @@  finish_function (bool inline_p)
      to the FUNCTION_DECL node itself.  */
   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
 
-  /* Save away current state, if appropriate.  */
-  if (!processing_template_decl)
-    save_function_data (fndecl);
-
   /* Complain if there's just no return statement.  */
   if (warn_return_type
       && !VOID_TYPE_P (TREE_TYPE (fntype))
@@ -16265,20 +16236,7 @@  finish_function (bool inline_p)
 
   /* Genericize before inlining.  */
   if (!processing_template_decl)
-    {
-      struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl);
-      cp_genericize (fndecl);
-      /* Clear out the bits we don't need.  */
-      f->x_current_class_ptr = NULL;
-      f->x_current_class_ref = NULL;
-      f->x_eh_spec_block = NULL;
-      f->x_in_charge_parm = NULL;
-      f->x_vtt_parm = NULL;
-      f->x_return_value = NULL;
-      f->bindings = NULL;
-      f->extern_decl_map = NULL;
-      f->infinite_loops = NULL;
-    }
+    cp_genericize (fndecl);
 
   /* We're leaving the context of this function, so zap cfun.  It's still in
      DECL_STRUCT_FUNCTION, and we'll restore it in tree_rest_of_compilation.  */
@@ -16692,14 +16650,8 @@  fndecl_declared_return_type (tree fn)
 {
   fn = STRIP_TEMPLATE (fn);
   if (FNDECL_USED_AUTO (fn))
-    {
-      struct language_function *f = NULL;
-      if (DECL_STRUCT_FUNCTION (fn))
-	f = DECL_STRUCT_FUNCTION (fn)->language;
-      if (f == NULL)
-	f = DECL_SAVED_FUNCTION_DATA (fn);
-      return f->x_auto_return_pattern;
-    }
+    return DECL_SAVED_AUTO_RETURN_TYPE (fn);
+
   return TREE_TYPE (TREE_TYPE (fn));
 }
 
Index: gcc/cp/mangle.c
===================================================================
--- gcc/cp/mangle.c	(revision 271012)
+++ gcc/cp/mangle.c	(working copy)
@@ -1366,8 +1366,7 @@  write_unqualified_name (tree decl)
 	      type = TREE_TYPE (fn_type);
 	    }
 	  else if (FNDECL_USED_AUTO (decl))
-	    type = (DECL_STRUCT_FUNCTION (decl)->language
-		    ->x_auto_return_pattern);
+	    type = DECL_SAVED_AUTO_RETURN_TYPE (decl);
 	  else
 	    type = DECL_CONV_FN_TYPE (decl);
 	  write_conversion_operator_name (type);
Index: gcc/cp/method.c
===================================================================
--- gcc/cp/method.c	(revision 271012)
+++ gcc/cp/method.c	(working copy)
@@ -118,7 +118,7 @@  make_thunk (tree function, bool this_adj
   DECL_INTERFACE_KNOWN (thunk) = 1;
   DECL_NOT_REALLY_EXTERN (thunk) = 1;
   DECL_COMDAT (thunk) = DECL_COMDAT (function);
-  DECL_SAVED_FUNCTION_DATA (thunk) = NULL;
+  DECL_SAVED_AUTO_RETURN_TYPE (thunk) = NULL;
   /* The thunk itself is not a constructor or destructor, even if
      the thing it is thunking to is.  */
   DECL_CXX_DESTRUCTOR_P (thunk) = 0;
@@ -206,7 +206,7 @@  make_alias_for (tree target, tree newid)
   DECL_TEMPLATE_INSTANTIATED (alias) = 0;
   if (TREE_CODE (alias) == FUNCTION_DECL)
     {
-      DECL_SAVED_FUNCTION_DATA (alias) = NULL;
+      DECL_SAVED_AUTO_RETURN_TYPE (alias) = NULL;
       DECL_CXX_DESTRUCTOR_P (alias) = 0;
       DECL_CXX_CONSTRUCTOR_P (alias) = 0;
       DECL_PENDING_INLINE_P (alias) = 0;
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 271012)
+++ gcc/cp/parser.c	(working copy)
@@ -12913,7 +12913,7 @@  cp_parser_jump_statement (cp_parser* par
 	     expression.  */
 	  expr = NULL_TREE;
 	/* Build the return-statement.  */
-	if (current_function_auto_return_pattern && in_discarded_stmt)
+	if (FNDECL_USED_AUTO (current_function_decl) && in_discarded_stmt)
 	  /* Don't deduce from a discarded return statement.  */;
 	else
 	  statement = finish_return_stmt (expr);
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 271012)
+++ gcc/cp/pt.c	(working copy)
@@ -27622,7 +27622,10 @@  do_auto_deduction (tree type, tree init,
 	       emitted by now.  Also, having a mention to '<type error>'
 	       in the diagnostic is not really useful to the user.  */
 	    {
-	      if (cfun && auto_node == current_function_auto_return_pattern
+	      if (cfun
+		  && FNDECL_USED_AUTO (current_function_decl)
+		  && (auto_node
+		      == DECL_SAVED_AUTO_RETURN_TYPE (current_function_decl))
 		  && LAMBDA_FUNCTION_P (current_function_decl))
 		error ("unable to deduce lambda return type from %qE", init);
 	      else
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 271012)
+++ gcc/cp/typeck.c	(working copy)
@@ -9551,7 +9551,7 @@  check_return_expr (tree retval, bool *no
       /* If one of the types might be void, we can't tell whether we're
 	 returning a value.  */
       if ((WILDCARD_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))
-	   && !current_function_auto_return_pattern)
+	   && !FNDECL_USED_AUTO (current_function_decl))
 	  || (retval != NULL_TREE
 	      && (TREE_TYPE (retval) == NULL_TREE
 		  || WILDCARD_TYPE_P (TREE_TYPE (retval)))))
@@ -9561,16 +9561,17 @@  check_return_expr (tree retval, bool *no
   functype = TREE_TYPE (TREE_TYPE (current_function_decl));
 
   /* Deduce auto return type from a return statement.  */
-  if (current_function_auto_return_pattern)
+  if (FNDECL_USED_AUTO (current_function_decl))
     {
+      tree pattern = DECL_SAVED_AUTO_RETURN_TYPE (current_function_decl);
       tree auto_node;
       tree type;
 
-      if (!retval && !is_auto (current_function_auto_return_pattern))
+      if (!retval && !is_auto (pattern))
 	{
 	  /* Give a helpful error message.  */
 	  error ("return-statement with no value, in function returning %qT",
-		 current_function_auto_return_pattern);
+		 pattern);
 	  inform (input_location, "only plain %<auto%> return type can be "
 		  "deduced to %<void%>");
 	  type = error_mark_node;
@@ -9584,14 +9585,13 @@  check_return_expr (tree retval, bool *no
 	{
 	  if (!retval)
 	    retval = void_node;
-	  auto_node = type_uses_auto (current_function_auto_return_pattern);
-	  type = do_auto_deduction (current_function_auto_return_pattern,
-				    retval, auto_node);
+	  auto_node = type_uses_auto (pattern);
+	  type = do_auto_deduction (pattern, retval, auto_node);
 	}
 
       if (type == error_mark_node)
 	/* Leave it.  */;
-      else if (functype == current_function_auto_return_pattern)
+      else if (functype == pattern)
 	apply_deduced_return_type (current_function_decl, type);
       else if (!same_type_p (type, functype))
 	{