+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.
+
2019-05-06 Jason Merrill <jason@redhat.com>
PR c++/90171 - reorganize usual_deallocation_fn_p
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;
#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 *);
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;
};
#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) \
/* 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))
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);
}
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);
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
}
\f
-/* 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
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);
&& !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%>");
}
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))
/* 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. */
{
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));
}
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);
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;
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;
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);
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
/* 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)))))
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;
{
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))
{