typed_declspecs setspecs declarator
{ if (! start_function ($1, $3))
YYFAIL;
reinit_parse_for_function (); }
xdecls
{ store_parm_decls (); }
compstmt_or_error
{ finish_function (lineno); }
/* Finish up a function declaration and compile that function
all the way to assembler language output. The free the storage
for the function definition.
This is called after parsing the body of the function definition.
LINENO is the current line number. */
void
finish_function (lineno)
int lineno;
{
register tree fndecl = current_function_decl;
/* TREE_READONLY (fndecl) = 1;
This caused &foo to be of type ptr-to-const-function
which then got a warning when stored in a ptr-to-function variable. */
poplevel (1, 0, 1);
/* Must mark the RESULT_DECL as being in this function. */
DECL_CONTEXT (DECL_RESULT (fndecl)) = DECL_INITIAL (fndecl);
/* Obey `register‘ declarations if `setjmp‘ is called in this fn. */
if (flag_traditional && current_function_calls_setjmp)
setjmp_protect (DECL_INITIAL (fndecl));
/* Generate rtl for function exit. */
expand_function_end (input_filename, lineno);
/* So we can tell if jump_optimize sets it to 1. */
current_function_returns_null = 0;
/* Run the optimizers and output the assembler code for this function. */
rest_of_compilation (fndecl);
if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null)
warning ("`volatile‘ function does return");
else if (warn_return_type && current_function_returns_null
&& TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node)
/* If this function returns non-void and control can drop through,
complain. */
warning ("control reaches end of non-void function");
/* With just -W, complain only if function returns both with
and without a value. */
else if (extra_warnings
&& current_function_returns_value && current_function_returns_null)
warning ("this function may return with or without a value");
/* Free all the tree nodes making up this function. */
/* Switch back to allocating nodes permanently
until we start another function. */
permanent_allocation ();
if (DECL_SAVED_INSNS (fndecl) == 0)
{
/* Stop pointing to the local nodes about to be freed. */
/* But DECL_INITIAL must remain nonzero so we know this
was an actual function definition. */
DECL_INITIAL (fndecl) = error_mark_node;
DECL_ARGUMENTS (fndecl) = 0;
}
/* Let the error reporting routines know that we‘re outside a function. */
current_function_decl = NULL;
}