FreeBSD/contrib/gcc/c-decl.c
/* 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.  */
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.
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 .
void
finish_function (void)
{
  tree fndecl = current_function_decl;
  label_context_stack_se = label_context_stack_se->next;
  label_context_stack_vm = label_context_stack_vm->next;
  if (TREE_CODE (fndecl) == FUNCTION_DECL
      && targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
    {
      tree args = DECL_ARGUMENTS (fndecl);
      for (; args; args = TREE_CHAIN (args))
	{
	  tree type = TREE_TYPE (args);
	  if (INTEGRAL_TYPE_P (type)
	      && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
	    DECL_ARG_TYPE (args) = integer_type_node;
	}
    }
  if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node)
    BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
  if (DECL_RESULT (fndecl) && DECL_RESULT (fndecl) != error_mark_node)
    DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
  if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted)
    {
      if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
	  != integer_type_node)
	{
	  if (!warn_main)
	    pedwarn ("return type of %q+D is not %<int%>", fndecl);
	}
      else
	{
	  if (flag_isoc99)
	    {
	      tree stmt = c_finish_return (integer_zero_node);
#ifdef USE_MAPPED_LOCATION
	      SET_EXPR_LOCATION (stmt, BUILTINS_LOCATION);
#else
	      annotate_with_file_line (stmt, input_filename, 0);
#endif
	    }
	}
    }
  DECL_SAVED_TREE (fndecl) = pop_stmt_list (DECL_SAVED_TREE (fndecl));
  finish_fname_decls ();
  if (warn_return_type
      && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
      && !current_function_returns_value && !current_function_returns_null
      && !current_function_returns_abnormally
      && !MAIN_NAME_P (DECL_NAME (fndecl))
      && !C_FUNCTION_IMPLICIT_INT (fndecl)
      && DECL_INLINE (fndecl))
    {
      warning (OPT_Wreturn_type,
	       "no return statement in function returning non-void");
      TREE_NO_WARNING (fndecl) = 1;
    }
  if (extra_warnings
      && current_function_returns_value
      && current_function_returns_null)
    warning (OPT_Wextra, "this function may return with or without a value");
  cfun->function_end_locus = input_location;
  if (DECL_STATIC_CONSTRUCTOR (fndecl)
      && !targetm.have_ctors_dtors)
    static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
  if (DECL_STATIC_DESTRUCTOR (fndecl)
      && !targetm.have_ctors_dtors)
    static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
  c_determine_visibility (fndecl);
  if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node
      && !undef_nested_function)
    {
      if (!decl_function_context (fndecl))
	{
	  c_genericize (fndecl);
	  c_gimple_diagnostics_recursively (fndecl);
	  if (cgraph_global_info_ready)
	    {
	      c_expand_body (fndecl);
	      return;
	    }
	  cgraph_finalize_function (fndecl, false);
	}
      else
	{
	  (void) cgraph_node (fndecl);
	}
    }
  if (!decl_function_context (fndecl))
    undef_nested_function = false;
  cfun = NULL;
  current_function_decl = NULL;
}
void finish_function ( void ) { tree fndecl = current_function_decl ; label_context_stack_se = label_context_stack_se -> next ; label_context_stack_vm = label_context_stack_vm -> next ; if ( TREE_CODE ( fndecl ) == FUNCTION_DECL && targetm . calls . promote_prototypes ( TREE_TYPE ( fndecl ) ) ) { tree args = DECL_ARGUMENTS ( fndecl ) ; for ( ; args ; args = TREE_CHAIN ( args ) ) { tree type = TREE_TYPE ( args ) ; if ( INTEGRAL_TYPE_P ( type ) && TYPE_PRECISION ( type ) < TYPE_PRECISION ( integer_type_node ) ) DECL_ARG_TYPE ( args ) = integer_type_node ; } } if ( DECL_INITIAL ( fndecl ) && DECL_INITIAL ( fndecl ) != error_mark_node ) BLOCK_SUPERCONTEXT ( DECL_INITIAL ( fndecl ) ) = fndecl ; if ( DECL_RESULT ( fndecl ) && DECL_RESULT ( fndecl ) != error_mark_node ) DECL_CONTEXT ( DECL_RESULT ( fndecl ) ) = fndecl ; if ( MAIN_NAME_P ( DECL_NAME ( fndecl ) ) && flag_hosted ) { if ( TYPE_MAIN_VARIANT ( TREE_TYPE ( TREE_TYPE ( fndecl ) ) ) != integer_type_node ) { if ( ! warn_main ) pedwarn ( " " , fndecl ) ; } else { if ( flag_isoc99 ) { tree stmt = c_finish_return ( integer_zero_node ) ; #ifdef USE_MAPPED_LOCATION SET_EXPR_LOCATION ( stmt , BUILTINS_LOCATION ) ; #else annotate_with_file_line ( stmt , input_filename , 0 ) ; #endif } } } DECL_SAVED_TREE ( fndecl ) = pop_stmt_list ( DECL_SAVED_TREE ( fndecl ) ) ; finish_fname_decls ( ) ; if ( warn_return_type && TREE_CODE ( TREE_TYPE ( TREE_TYPE ( fndecl ) ) ) != VOID_TYPE && ! current_function_returns_value && ! current_function_returns_null && ! current_function_returns_abnormally && ! MAIN_NAME_P ( DECL_NAME ( fndecl ) ) && ! C_FUNCTION_IMPLICIT_INT ( fndecl ) && DECL_INLINE ( fndecl ) ) { warning ( OPT_Wreturn_type , " " ) ; TREE_NO_WARNING ( fndecl ) = 1 ; } if ( extra_warnings && current_function_returns_value && current_function_returns_null ) warning ( OPT_Wextra , " " ) ; cfun -> function_end_locus = input_location ; if ( DECL_STATIC_CONSTRUCTOR ( fndecl ) && ! targetm . have_ctors_dtors ) static_ctors = tree_cons ( NULL_TREE , fndecl , static_ctors ) ; if ( DECL_STATIC_DESTRUCTOR ( fndecl ) && ! targetm . have_ctors_dtors ) static_dtors = tree_cons ( NULL_TREE , fndecl , static_dtors ) ; c_determine_visibility ( fndecl ) ; if ( DECL_INITIAL ( fndecl ) && DECL_INITIAL ( fndecl ) != error_mark_node && ! undef_nested_function ) { if ( ! decl_function_context ( fndecl ) ) { c_genericize ( fndecl ) ; c_gimple_diagnostics_recursively ( fndecl ) ; if ( cgraph_global_info_ready ) { c_expand_body ( fndecl ) ; return ; } cgraph_finalize_function ( fndecl , false ) ; } else { ( void ) cgraph_node ( fndecl ) ; } } if ( ! decl_function_context ( fndecl ) ) undef_nested_function = false ; cfun = NULL ; current_function_decl = NULL ; }
Finish up a function declaration and compile that function
all the way to assembler language output.
Finish up a function declaration and compile that function all the way to assembler language output .
/* Must mark the RESULT_DECL as being in this function.  */ /* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned.
	     If warn_main is -1 (-Wno-main) we don't want to be warned.  */ /* Hack.  We don't want the middle-end to warn that this return
		 is unreachable, so we mark its location as special.  Using
		 UNKNOWN_LOCATION has the problem that it gets clobbered in
		 annotate_one_with_locus.  A cleaner solution might be to
		 ensure ! should_carry_locus_p (stmt), but that needs a flag.
	      */ /* Hack.  We don't want the middle-end to warn that this
		 return is unreachable, so put the statement on the
		 special line 0.  */ /* Tie off the statement tree for this function.  */ /* Complain if there's just no return statement.  */ /* Don't complain if we are no-return.  */ /* Don't warn for main().  */ /* Or if they didn't actually specify a return type.  */ /* Normally, with -Wreturn-type, flow will complain.  Unless we're an
	 inline function, as we might never be compiled separately.  */ /* With just -Wextra, complain only if function returns both with
     and without a value.  */ /* Store the end of the function, so that we get good line number
     info for the epilogue.  */ /* If we don't have ctors/dtors sections, and this is a static
     constructor or destructor, it must be recorded now.  */ /* Finalize the ELF visibility for the function.  */ /* Genericize before inlining.  Delay genericizing nested functions
     until their parent function is genericized.  Since finalizing
     requires GENERIC, delay that as well.  */ /* ??? Objc emits functions after finalizing the compilation unit.
	     This should be cleaned up later and this conditional removed.  */ /* Register this function with cgraph just far enough to get it
	    added to our parent's nested function list.  Handy, since the
	    C front end doesn't have such a list.  */ /* 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.  */