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.
===================================================================
@@ -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))
===================================================================
@@ -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));
}
===================================================================
@@ -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);
===================================================================
@@ -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;
===================================================================
@@ -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);
===================================================================
@@ -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
===================================================================
@@ -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))
{