This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Merge from LTO: eh_personality changes


This merges the eh_personality changes from the branch.  It moves us
to store the eh personality decl per function.  The entanglement
between the C and ObjC frontends makes a new langhook necessary to
initialize the personality decl - other frontends don't really need it.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk?

This is the last non-LTO specific bits after fld merge on the branch.

Thanks,
Richard.

2009-09-04  Richard Guenther  <rguenther@suse.de>
	Rafael Avila de Espindola  <espindola@google.com>

	* c-decl.c (c_maybe_initialize_eh): Init eh_personality_decl
        instead of eh_personality_libfunc.
        (finish_decl): Don't call c_maybe_initialize_eh.
        * c-parser.c (c_parse_file): Call lang_hooks.init_eh.
        * dwarf2out.c (output_call_frame_info, dwarf2out_do_cfi_startproc,
	dwarf2out_begin_prologue): Use personality from current_function_decl.
        * except.c (sjlj_emit_function_enter, output_function_exception_table):
        Use personality from current_function_decl.
        * expr.h (build_personality_function, get_personality_function): New.
        * libfuncs.h (libfunc_index): Remove LTI_eh_personality.
        (eh_personality_libfunc): Remove.
        * lto-function-in.c (lto_init_eh): Don't set eh_personality_libfunc.
        (input_function_decl): Read decl->function_decl.personality.
        * lto-function-out.c (output_function_decl): Write
        decl->function_decl.personality.
        * optabs.c (build_libfunc_function): New function split out from ...
	(init_one_libfunc): ... here.
        * toplev.c (eh_personality_decl): New.
        * tree.c (make_node_stat):  Set DECL_FUNCTION_PERSONALITY.
        * tree.h (DECL_FUNCTION_PERSONALITY): New.
        (tree_function_decl): Add personality.
        (eh_personality_decl): New.

	* langhooks-def.h (LANG_HOOKS_INIT_EH): Define.
	(LANG_HOOKS_INITIALIZER): Adjust.
	* langhooks.h (struct lang_hooks): Add init_eh.
	* c-lang.c (LANG_HOOKS_INIT_EH): Define.

	objc/
	* objc-act.c (objc_init_exceptions): Export.  Move warning code ...
	(objc_begin_try_stmt): ... here
	(objc_build_throw_stmt): ... and here.
	* objc-act.h (objc_init_exceptions): Declare.
	* objc-lang.c (LANG_HOOKS_INIT_EH): Define.

	cp/
	* except.c (init_exception_processing, choose_personality_routine):
	Init eh_personality_decl instead of eh_personality_libfunc.

	java/
	* decl.c (java_init_decl_processing): Init eh_personality_decl
	instead of eh_personality_libfunc.

	ada/
	* gcc-interface/misc.c (gnat_init_gcc_eh): Init eh_personality_decl
	instead of eh_personality_libfunc.

	fortran/
	* f95-lang.c (gfc_maybe_initialize_eh): Init eh_personality_decl
	instead of eh_personality_libfunc.

Index: gcc/java/decl.c
===================================================================
*** gcc/java/decl.c.orig	2009-09-03 16:53:25.000000000 +0200
--- gcc/java/decl.c	2009-09-03 17:04:07.000000000 +0200
*************** java_init_decl_processing (void)
*** 1195,1203 ****
  			    0, NOT_BUILT_IN, NULL, NULL_TREE);
  
    /* Initialize variables for except.c.  */
!   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
!                                              ? "__gcj_personality_sj0"
!                                              : "__gcj_personality_v0");
    if (targetm.arm_eabi_unwinder)
      unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
    else
--- 1195,1206 ----
  			    0, NOT_BUILT_IN, NULL, NULL_TREE);
  
    /* Initialize variables for except.c.  */
! 
!   eh_personality_decl
!     = build_personality_function (USING_SJLJ_EXCEPTIONS
! 				  ? "__gcj_personality_sj0"
! 				  : "__gcj_personality_v0");
! 
    if (targetm.arm_eabi_unwinder)
      unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
    else
Index: gcc/libfuncs.h
===================================================================
*** gcc/libfuncs.h.orig	2009-09-03 16:53:25.000000000 +0200
--- gcc/libfuncs.h	2009-09-03 17:04:07.000000000 +0200
*************** enum libfunc_index
*** 31,37 ****
    LTI_setbits,
  
    LTI_unwind_resume,
-   LTI_eh_personality,
    LTI_setjmp,
    LTI_longjmp,
    LTI_unwind_sjlj_register,
--- 31,36 ----
*************** extern GTY(()) rtx libfunc_table[LTI_MAX
*** 61,67 ****
  #define setbits_libfunc	(libfunc_table[LTI_setbits])
  
  #define unwind_resume_libfunc	(libfunc_table[LTI_unwind_resume])
- #define eh_personality_libfunc	(libfunc_table[LTI_eh_personality])
  #define setjmp_libfunc	(libfunc_table[LTI_setjmp])
  #define longjmp_libfunc	(libfunc_table[LTI_longjmp])
  #define unwind_sjlj_register_libfunc (libfunc_table[LTI_unwind_sjlj_register])
--- 60,65 ----
Index: gcc/optabs.c
===================================================================
*** gcc/optabs.c.orig	2009-09-03 16:53:25.000000000 +0200
--- gcc/optabs.c	2009-09-03 17:04:07.000000000 +0200
*************** libfunc_decl_eq (const void *entry1, con
*** 6023,6028 ****
--- 6023,6050 ----
    return DECL_NAME ((const_tree) entry1) == (const_tree) entry2;
  }
  
+ /* Build a decl for a libfunc named NAME. */
+ 
+ tree
+ build_libfunc_function (const char *name)
+ {
+   tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
+ 			  get_identifier (name),
+                           build_function_type (integer_type_node, NULL_TREE));
+   /* ??? We don't have any type information except for this is
+      a function.  Pretend this is "int foo()".  */
+   DECL_ARTIFICIAL (decl) = 1;
+   DECL_EXTERNAL (decl) = 1;
+   TREE_PUBLIC (decl) = 1;
+   gcc_assert (DECL_ASSEMBLER_NAME (decl));
+ 
+   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
+      are the flags assigned by targetm.encode_section_info.  */
+   SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
+ 
+   return decl;
+ }
+ 
  rtx
  init_one_libfunc (const char *name)
  {
*************** init_one_libfunc (const char *name)
*** 6043,6061 ****
      {
        /* Create a new decl, so that it can be passed to
  	 targetm.encode_section_info.  */
!       /* ??? We don't have any type information except for this is
! 	 a function.  Pretend this is "int foo()".  */
!       decl = build_decl (UNKNOWN_LOCATION,
! 			 FUNCTION_DECL, get_identifier (name),
! 			 build_function_type (integer_type_node, NULL_TREE));
!       DECL_ARTIFICIAL (decl) = 1;
!       DECL_EXTERNAL (decl) = 1;
!       TREE_PUBLIC (decl) = 1;
! 
!       /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
! 	 are the flags assigned by targetm.encode_section_info.  */
!       SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
! 
        *slot = decl;
      }
    return XEXP (DECL_RTL (decl), 0);
--- 6065,6071 ----
      {
        /* Create a new decl, so that it can be passed to
  	 targetm.encode_section_info.  */
!       decl = build_libfunc_function (name);
        *slot = decl;
      }
    return XEXP (DECL_RTL (decl), 0);
Index: gcc/tree.h
===================================================================
*** gcc/tree.h.orig	2009-09-03 16:53:26.000000000 +0200
--- gcc/tree.h	2009-09-03 17:04:07.000000000 +0200
*************** struct GTY(()) tree_decl_minimal {
*** 2533,2538 ****
--- 2533,2541 ----
  #define DECL_DEBUG_EXPR_IS_FROM(NODE) \
    (DECL_COMMON_CHECK (NODE)->decl_common.debug_expr_is_from)
  
+ #define DECL_FUNCTION_PERSONALITY(NODE) \
+   (FUNCTION_DECL_CHECK (NODE)->function_decl.personality)
+ 
  /* Nonzero for a given ..._DECL node means that the name of this node should
     be ignored for symbolic debug purposes.  */
  #define DECL_IGNORED_P(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.ignored_flag)
*************** struct GTY(()) tree_function_decl {
*** 3183,3188 ****
--- 3186,3194 ----
  
    struct function *f;
  
+   /* The personality function. Used for stack unwinding. */
+   tree personality;
+ 
    /* Function specific options that are used by this function.  */
    tree function_specific_target;	/* target options */
    tree function_specific_optimization;	/* optimization options */
*************** extern int pedantic_lvalues;
*** 4556,4561 ****
--- 4562,4570 ----
  
  extern GTY(()) tree current_function_decl;
  
+ /* The eh personally function that this FE wants to use. */
+ extern GTY(()) tree eh_personality_decl;
+ 
  /* Nonzero means a FUNC_BEGIN label was emitted.  */
  extern GTY(()) const char * current_function_func_begin_label;
  
Index: gcc/objc/objc-act.c
===================================================================
*** gcc/objc/objc-act.c.orig	2009-09-03 16:53:26.000000000 +0200
--- gcc/objc/objc-act.c	2009-09-03 18:57:23.000000000 +0200
*************** objc_eh_runtime_type (tree type)
*** 3497,3503 ****
  
  /* Initialize exception handling.  */
  
! static void
  objc_init_exceptions (void)
  {
    static bool done = false;
--- 3497,3503 ----
  
  /* Initialize exception handling.  */
  
! void
  objc_init_exceptions (void)
  {
    static bool done = false;
*************** objc_init_exceptions (void)
*** 3505,3526 ****
      return;
    done = true;
  
-   if (flag_objc_sjlj_exceptions)
-     {
-       /* On Darwin, ObjC exceptions require a sufficiently recent
- 	 version of the runtime, so the user must ask for them explicitly.  */
-       if (!flag_objc_exceptions)
- 	warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
- 		 "exception syntax");
-     }
  #ifndef OBJCPLUS
!   else
      {
        c_eh_initialized_p = true;
!       eh_personality_libfunc
! 	= init_one_libfunc (USING_SJLJ_EXCEPTIONS
! 			    ? "__gnu_objc_personality_sj0"
! 			    : "__gnu_objc_personality_v0");
        default_init_unwind_resume_libfunc ();
        using_eh_for_cleanups ();
        lang_eh_runtime_type = objc_eh_runtime_type;
--- 3505,3519 ----
      return;
    done = true;
  
  #ifndef OBJCPLUS
!   if (!flag_objc_sjlj_exceptions)
      {
        c_eh_initialized_p = true;
!       eh_personality_decl
! 	= build_personality_function (USING_SJLJ_EXCEPTIONS
! 				      ? "__gnu_objc_personality_sj0"
! 				      : "__gnu_objc_personality_v0");
! 
        default_init_unwind_resume_libfunc ();
        using_eh_for_cleanups ();
        lang_eh_runtime_type = objc_eh_runtime_type;
*************** objc_begin_try_stmt (location_t try_locu
*** 3824,3830 ****
    c->end_try_locus = input_location;
    cur_try_context = c;
  
!   objc_init_exceptions ();
  
    if (flag_objc_sjlj_exceptions)
      objc_mark_locals_volatile (NULL);
--- 3817,3830 ----
    c->end_try_locus = input_location;
    cur_try_context = c;
  
!   if (flag_objc_sjlj_exceptions)
!     {
!       /* On Darwin, ObjC exceptions require a sufficiently recent
! 	 version of the runtime, so the user must ask for them explicitly.  */
!       if (!flag_objc_exceptions)
! 	warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
! 		 "exception syntax");
!     }
  
    if (flag_objc_sjlj_exceptions)
      objc_mark_locals_volatile (NULL);
*************** objc_build_throw_stmt (location_t loc, t
*** 3973,3979 ****
  {
    tree args;
  
!   objc_init_exceptions ();
  
    if (throw_expr == NULL)
      {
--- 3973,3986 ----
  {
    tree args;
  
!   if (flag_objc_sjlj_exceptions)
!     {
!       /* On Darwin, ObjC exceptions require a sufficiently recent
! 	 version of the runtime, so the user must ask for them explicitly.  */
!       if (!flag_objc_exceptions)
! 	warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
! 		 "exception syntax");
!     }
  
    if (throw_expr == NULL)
      {
Index: gcc/toplev.c
===================================================================
*** gcc/toplev.c.orig	2009-09-03 16:53:26.000000000 +0200
--- gcc/toplev.c	2009-09-03 17:04:07.000000000 +0200
*************** int optimize_size = 0;
*** 202,207 ****
--- 202,210 ----
     or 0 if between functions.  */
  tree current_function_decl;
  
+ /* The EH personality function that this FE wants to use. */
+ tree eh_personality_decl;
+ 
  /* Set to the FUNC_BEGIN label of the current function, or NULL
     if none.  */
  const char * current_function_func_begin_label;
Index: gcc/cp/except.c
===================================================================
*** gcc/cp/except.c.orig	2009-09-03 16:53:26.000000000 +0200
--- gcc/cp/except.c	2009-09-03 17:04:07.000000000 +0200
*************** init_exception_processing (void)
*** 78,86 ****
    call_unexpected_node
      = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
  
!   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
! 					     ? "__gxx_personality_sj0"
! 					     : "__gxx_personality_v0");
    if (targetm.arm_eabi_unwinder)
      unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
    else
--- 78,88 ----
    call_unexpected_node
      = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
  
!   eh_personality_decl
!     = build_personality_function (USING_SJLJ_EXCEPTIONS
! 				  ? "__gxx_personality_sj0"
! 				  : "__gxx_personality_v0");
! 
    if (targetm.arm_eabi_unwinder)
      unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
    else
*************** decl_is_java_type (tree decl, int err)
*** 313,319 ****
  /* Select the personality routine to be used for exception handling,
     or issue an error if we need two different ones in the same
     translation unit.
!    ??? At present eh_personality_libfunc is set to
     __gxx_personality_(sj|v)0 in init_exception_processing - should it
     be done here instead?  */
  void
--- 315,321 ----
  /* Select the personality routine to be used for exception handling,
     or issue an error if we need two different ones in the same
     translation unit.
!    ??? At present eh_personality_decl is set to
     __gxx_personality_(sj|v)0 in init_exception_processing - should it
     be done here instead?  */
  void
*************** choose_personality_routine (enum languag
*** 354,362 ****
      case lang_java:
        state = chose_java;
        terminate_node = built_in_decls [BUILT_IN_ABORT];
!       eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
! 						 ? "__gcj_personality_sj0"
! 						 : "__gcj_personality_v0");
        break;
  
      default:
--- 356,365 ----
      case lang_java:
        state = chose_java;
        terminate_node = built_in_decls [BUILT_IN_ABORT];
!       eh_personality_decl
! 	= build_personality_function (USING_SJLJ_EXCEPTIONS
! 				      ? "__gcj_personality_sj0"
! 				      : "__gcj_personality_v0");
        break;
  
      default:
Index: gcc/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c.orig	2009-09-03 16:53:26.000000000 +0200
--- gcc/dwarf2out.c	2009-09-03 17:04:07.000000000 +0200
*************** static GTY(()) section *debug_str_sectio
*** 216,221 ****
--- 216,225 ----
  static GTY(()) section *debug_ranges_section;
  static GTY(()) section *debug_frame_section;
  
+ /* Personality decl of current unit.  Used only when assembler does not support
+    personality CFI.  */
+ static GTY(()) rtx current_unit_personality;
+ 
  /* How to start an assembler comment.  */
  #ifndef ASM_COMMENT_START
  #define ASM_COMMENT_START ";#"
*************** output_call_frame_info (int for_eh)
*** 3599,3604 ****
--- 3603,3609 ----
    int per_encoding = DW_EH_PE_absptr;
    int lsda_encoding = DW_EH_PE_absptr;
    int return_reg;
+   rtx personality = NULL;
    int dw_cie_version;
  
    /* Don't emit a CIE if there won't be any FDEs.  */
*************** output_call_frame_info (int for_eh)
*** 3684,3689 ****
--- 3689,3696 ----
  
    augmentation[0] = 0;
    augmentation_size = 0;
+ 
+   personality = current_unit_personality;
    if (for_eh)
      {
        char *p;
*************** output_call_frame_info (int for_eh)
*** 3703,3713 ****
        lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
  
        p = augmentation + 1;
!       if (eh_personality_libfunc)
  	{
  	  *p++ = 'P';
  	  augmentation_size += 1 + size_of_encoded_value (per_encoding);
! 	  assemble_external_libcall (eh_personality_libfunc);
  	}
        if (any_lsda_needed)
  	{
--- 3710,3720 ----
        lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
  
        p = augmentation + 1;
!       if (personality)
  	{
  	  *p++ = 'P';
  	  augmentation_size += 1 + size_of_encoded_value (per_encoding);
! 	  assemble_external_libcall (personality);
  	}
        if (any_lsda_needed)
  	{
*************** output_call_frame_info (int for_eh)
*** 3726,3732 ****
  	}
  
        /* Ug.  Some platforms can't do unaligned dynamic relocations at all.  */
!       if (eh_personality_libfunc && per_encoding == DW_EH_PE_aligned)
  	{
  	  int offset = (  4		/* Length */
  			+ 4		/* CIE Id */
--- 3733,3739 ----
  	}
  
        /* Ug.  Some platforms can't do unaligned dynamic relocations at all.  */
!       if (personality && per_encoding == DW_EH_PE_aligned)
  	{
  	  int offset = (  4		/* Length */
  			+ 4		/* CIE Id */
*************** output_call_frame_info (int for_eh)
*** 3760,3771 ****
    if (augmentation[0])
      {
        dw2_asm_output_data_uleb128 (augmentation_size, "Augmentation size");
!       if (eh_personality_libfunc)
  	{
  	  dw2_asm_output_data (1, per_encoding, "Personality (%s)",
  			       eh_data_format_name (per_encoding));
  	  dw2_asm_output_encoded_addr_rtx (per_encoding,
! 					   eh_personality_libfunc,
  					   true, NULL);
  	}
  
--- 3767,3778 ----
    if (augmentation[0])
      {
        dw2_asm_output_data_uleb128 (augmentation_size, "Augmentation size");
!       if (personality)
  	{
  	  dw2_asm_output_data (1, per_encoding, "Personality (%s)",
  			       eh_data_format_name (per_encoding));
  	  dw2_asm_output_encoded_addr_rtx (per_encoding,
! 					   personality,
  					   true, NULL);
  	}
  
*************** dwarf2out_do_cfi_startproc (bool second)
*** 3824,3836 ****
  {
    int enc;
    rtx ref;
  
    fprintf (asm_out_file, "\t.cfi_startproc\n");
  
!   if (eh_personality_libfunc)
      {
        enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
!       ref = eh_personality_libfunc;
  
        /* ??? The GAS support isn't entirely consistent.  We have to
  	 handle indirect support ourselves, but PC-relative is done
--- 3831,3844 ----
  {
    int enc;
    rtx ref;
+   rtx personality = get_personality_function (current_function_decl);
  
    fprintf (asm_out_file, "\t.cfi_startproc\n");
  
!   if (personality)
      {
        enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
!       ref = personality;
  
        /* ??? The GAS support isn't entirely consistent.  We have to
  	 handle indirect support ourselves, but PC-relative is done
*************** dwarf2out_begin_prologue (unsigned int l
*** 3873,3878 ****
--- 3881,3887 ----
    char label[MAX_ARTIFICIAL_LABEL_BYTES];
    char * dup_label;
    dw_fde_ref fde;
+   rtx personality;
    section *fnsec;
  
    current_function_func_begin_label = NULL;
*************** dwarf2out_begin_prologue (unsigned int l
*** 3967,3974 ****
--- 3976,3992 ----
      dwarf2out_source_line (line, file, 0, true);
  #endif
  
+   personality = get_personality_function (current_function_decl);
    if (dwarf2out_do_cfi_asm ())
      dwarf2out_do_cfi_startproc (false);
+   else
+     {
+       if (!current_unit_personality || current_unit_personality == personality)
+         current_unit_personality = personality;
+       else
+ 	sorry ("Multiple EH personalities are supported only with assemblers "
+ 	       "supporting .cfi.personality directive.");
+     }
  }
  
  /* Output a marker (i.e. a label) for the absolute end of the generated code
Index: gcc/expr.h
===================================================================
*** gcc/expr.h.orig	2009-09-03 16:53:26.000000000 +0200
--- gcc/expr.h	2009-09-03 17:04:07.000000000 +0200
*************** extern void init_all_optabs (void);
*** 814,819 ****
--- 814,845 ----
  extern rtx init_one_libfunc (const char *);
  extern rtx set_user_assembler_libfunc (const char *, const char *);
  
+ /* Build a decl for a libfunc named NAME. */
+ extern tree build_libfunc_function (const char *);
+ 
+ /* Build a decl for a personality function named NAME. */
+ static inline tree
+ build_personality_function (const char *name)
+ {
+   return build_libfunc_function (name);
+ }
+ 
+ /* Extracts the personality function of DECL and returns the corresponding
+    libfunc. */
+ 
+ static inline rtx
+ get_personality_function (tree decl)
+ {
+   tree personality = DECL_FUNCTION_PERSONALITY (decl);
+   tree name;
+   if (!personality)
+     return NULL;
+ 
+   name = DECL_ASSEMBLER_NAME (personality);
+ 
+   return init_one_libfunc (IDENTIFIER_POINTER (name));
+ }
+ 
  extern int vector_mode_valid_p (enum machine_mode);
  
  #endif /* GCC_EXPR_H */
Index: gcc/ada/gcc-interface/misc.c
===================================================================
*** gcc/ada/gcc-interface/misc.c.orig	2009-09-03 16:53:26.000000000 +0200
--- gcc/ada/gcc-interface/misc.c	2009-09-03 17:04:07.000000000 +0200
*************** gnat_init_gcc_eh (void)
*** 431,439 ****
       right exception regions.  */
    using_eh_for_cleanups ();
  
!   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
! 					     ? "__gnat_eh_personality_sj"
! 					     : "__gnat_eh_personality");
    lang_eh_type_covers = gnat_eh_type_covers;
    lang_eh_runtime_type = gnat_return_tree;
    default_init_unwind_resume_libfunc ();
--- 431,441 ----
       right exception regions.  */
    using_eh_for_cleanups ();
  
!   eh_personality_decl
!     = build_personality_function (USING_SJLJ_EXCEPTIONS
! 				  ? "__gnat_eh_personality_sj"
! 				  : "__gnat_eh_personality");
! 
    lang_eh_type_covers = gnat_eh_type_covers;
    lang_eh_runtime_type = gnat_return_tree;
    default_init_unwind_resume_libfunc ();
Index: gcc/c-decl.c
===================================================================
*** gcc/c-decl.c.orig	2009-09-03 16:53:26.000000000 +0200
--- gcc/c-decl.c	2009-09-03 17:04:07.000000000 +0200
*************** merge_decls (tree newdecl, tree olddecl,
*** 2365,2371 ****
      TREE_USED (olddecl) = 1;
  
    /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
!      But preserve OLDDECL's DECL_UID and DECL_CONTEXT.  */
    {
      unsigned olddecl_uid = DECL_UID (olddecl);
      tree olddecl_context = DECL_CONTEXT (olddecl);
--- 2365,2372 ----
      TREE_USED (olddecl) = 1;
  
    /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
!      But preserve OLDDECL's DECL_UID, DECL_CONTEXT and
!      DECL_ARGUMENTS (if appropriate).  */
    {
      unsigned olddecl_uid = DECL_UID (olddecl);
      tree olddecl_context = DECL_CONTEXT (olddecl);
*************** c_maybe_initialize_eh (void)
*** 4052,4061 ****
      return;
  
    c_eh_initialized_p = true;
!   eh_personality_libfunc
!     = init_one_libfunc (USING_SJLJ_EXCEPTIONS
! 			? "__gcc_personality_sj0"
! 			: "__gcc_personality_v0");
    default_init_unwind_resume_libfunc ();
    using_eh_for_cleanups ();
  }
--- 4053,4063 ----
      return;
  
    c_eh_initialized_p = true;
!   eh_personality_decl
!     = build_personality_function (USING_SJLJ_EXCEPTIONS
! 				  ? "__gcc_personality_sj0"
! 				  : "__gcc_personality_v0");
! 
    default_init_unwind_resume_libfunc ();
    using_eh_for_cleanups ();
  }
*************** finish_decl (tree decl, location_t init_
*** 4360,4368 ****
  	  TREE_USED (decl) = 1;
  	  TREE_USED (cleanup_decl) = 1;
  
- 	  /* Initialize EH, if we've been told to do so.  */
- 	  c_maybe_initialize_eh ();
- 
  	  push_cleanup (decl, cleanup, false);
  	}
      }
--- 4362,4367 ----
Index: gcc/fortran/f95-lang.c
===================================================================
*** gcc/fortran/f95-lang.c.orig	2009-09-03 16:53:26.000000000 +0200
--- gcc/fortran/f95-lang.c	2009-09-03 17:04:07.000000000 +0200
*************** gfc_maybe_initialize_eh (void)
*** 1155,1164 ****
      return;
  
    gfc_eh_initialized_p = true;
!   eh_personality_libfunc
!     = init_one_libfunc (USING_SJLJ_EXCEPTIONS
!                        ? "__gcc_personality_sj0"
!                        : "__gcc_personality_v0");
    default_init_unwind_resume_libfunc ();
    using_eh_for_cleanups ();
  }
--- 1155,1164 ----
      return;
  
    gfc_eh_initialized_p = true;
!   eh_personality_decl
!     = build_personality_function (USING_SJLJ_EXCEPTIONS
! 				  ? "__gcc_personality_sj0"
! 				  : "__gcc_personality_v0");
    default_init_unwind_resume_libfunc ();
    using_eh_for_cleanups ();
  }
Index: gcc/except.c
===================================================================
*** gcc/except.c.orig	2009-09-03 16:53:26.000000000 +0200
--- gcc/except.c	2009-09-03 17:04:07.000000000 +0200
*************** sjlj_emit_function_enter (rtx dispatch_l
*** 2424,2429 ****
--- 2424,2430 ----
  {
    rtx fn_begin, fc, mem, seq;
    bool fn_begin_outside_block;
+   rtx personality = get_personality_function (current_function_decl);
  
    fc = crtl->eh.sjlj_fc;
  
*************** sjlj_emit_function_enter (rtx dispatch_l
*** 2432,2440 ****
    /* We're storing this libcall's address into memory instead of
       calling it directly.  Thus, we must call assemble_external_libcall
       here, as we can not depend on emit_library_call to do it for us.  */
!   assemble_external_libcall (eh_personality_libfunc);
    mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
!   emit_move_insn (mem, eh_personality_libfunc);
  
    mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
    if (crtl->uses_eh_lsda)
--- 2433,2441 ----
    /* We're storing this libcall's address into memory instead of
       calling it directly.  Thus, we must call assemble_external_libcall
       here, as we can not depend on emit_library_call to do it for us.  */
!   assemble_external_libcall (personality);
    mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
!   emit_move_insn (mem, personality);
  
    mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
    if (crtl->uses_eh_lsda)
*************** output_ttype (tree type, int tt_format, 
*** 4394,4400 ****
  
  static void
  output_one_function_exception_table (const char * ARG_UNUSED (fnname),
! 				     int section)
  {
    int tt_format, cs_format, lp_format, i, n;
  #ifdef HAVE_AS_LEB128
--- 4395,4401 ----
  
  static void
  output_one_function_exception_table (const char * ARG_UNUSED (fnname),
! 				     int section, rtx ARG_UNUSED (personality))
  {
    int tt_format, cs_format, lp_format, i, n;
  #ifdef HAVE_AS_LEB128
*************** output_one_function_exception_table (con
*** 4410,4416 ****
  #ifdef TARGET_UNWIND_INFO
    /* TODO: Move this into target file.  */
    fputs ("\t.personality\t", asm_out_file);
!   output_addr_const (asm_out_file, eh_personality_libfunc);
    fputs ("\n\t.handlerdata\n", asm_out_file);
    /* Note that varasm still thinks we're in the function's code section.
       The ".endp" directive that will immediately follow will take us back.  */
--- 4411,4417 ----
  #ifdef TARGET_UNWIND_INFO
    /* TODO: Move this into target file.  */
    fputs ("\t.personality\t", asm_out_file);
!   output_addr_const (asm_out_file, personality);
    fputs ("\n\t.handlerdata\n", asm_out_file);
    /* Note that varasm still thinks we're in the function's code section.
       The ".endp" directive that will immediately follow will take us back.  */
*************** output_one_function_exception_table (con
*** 4580,4595 ****
  void
  output_function_exception_table (const char * ARG_UNUSED (fnname))
  {
    /* Not all functions need anything.  */
    if (! crtl->uses_eh_lsda)
      return;
  
!   if (eh_personality_libfunc)
!     assemble_external_libcall (eh_personality_libfunc);
  
!   output_one_function_exception_table (fnname, 0);
    if (crtl->eh.call_site_record[1] != NULL)
!     output_one_function_exception_table (fnname, 1);
  
    switch_to_section (current_function_section ());
  }
--- 4581,4598 ----
  void
  output_function_exception_table (const char * ARG_UNUSED (fnname))
  {
+   rtx personality = get_personality_function (current_function_decl);
+ 
    /* Not all functions need anything.  */
    if (! crtl->uses_eh_lsda)
      return;
  
!   if (personality)
!     assemble_external_libcall (personality);
  
!   output_one_function_exception_table (fnname, 0, personality);
    if (crtl->eh.call_site_record[1] != NULL)
!     output_one_function_exception_table (fnname, 1, personality);
  
    switch_to_section (current_function_section ());
  }
Index: gcc/c-parser.c
===================================================================
*** gcc/c-parser.c.orig	2009-09-03 16:53:26.000000000 +0200
--- gcc/c-parser.c	2009-09-03 17:25:23.000000000 +0200
*************** c_parse_file (void)
*** 8607,8612 ****
--- 8607,8615 ----
    the_parser = GGC_NEW (c_parser);
    *the_parser = tparser;
  
+   /* Initialize EH, if we've been told to do so.  */
+   lang_hooks.init_eh ();
+ 
    c_parser_translation_unit (the_parser);
    the_parser = NULL;
  }
Index: gcc/tree.c
===================================================================
*** gcc/tree.c.orig	2009-09-03 16:53:26.000000000 +0200
--- gcc/tree.c	2009-09-03 17:04:07.000000000 +0200
*************** make_node_stat (enum tree_code code MEM_
*** 867,872 ****
--- 867,873 ----
  	    {
  	      DECL_ALIGN (t) = FUNCTION_BOUNDARY;
  	      DECL_MODE (t) = FUNCTION_MODE;
+ 	      DECL_FUNCTION_PERSONALITY (t) = eh_personality_decl;
  	    }
  	  else
  	    DECL_ALIGN (t) = 1;
Index: gcc/c-lang.c
===================================================================
*** gcc/c-lang.c.orig	2009-09-03 17:25:31.000000000 +0200
--- gcc/c-lang.c	2009-09-03 17:26:29.000000000 +0200
*************** enum c_language_kind c_language = clk_c;
*** 44,49 ****
--- 44,51 ----
  #define LANG_HOOKS_NAME "GNU C"
  #undef LANG_HOOKS_INIT
  #define LANG_HOOKS_INIT c_objc_common_init
+ #undef LANG_HOOKS_INIT_EH
+ #define LANG_HOOKS_INIT_EH c_maybe_initialize_eh
  
  /* Each front end provides its own lang hook initializer.  */
  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
Index: gcc/langhooks-def.h
===================================================================
*** gcc/langhooks-def.h.orig	2009-09-03 17:20:17.000000000 +0200
--- gcc/langhooks-def.h	2009-09-03 17:29:30.000000000 +0200
*************** extern void lhd_omp_firstprivatize_type_
*** 107,112 ****
--- 107,113 ----
  #define LANG_HOOKS_EXPR_TO_DECL		lhd_expr_to_decl
  #define LANG_HOOKS_TO_TARGET_CHARSET	lhd_to_target_charset
  #define LANG_HOOKS_INIT_TS		lhd_do_nothing
+ #define LANG_HOOKS_INIT_EH		NULL
  
  /* Attribute hooks.  */
  #define LANG_HOOKS_ATTRIBUTE_TABLE		NULL
*************** extern tree lhd_make_node (enum tree_cod
*** 271,276 ****
--- 272,278 ----
    LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE, \
    LANG_HOOKS_INIT_TS,          \
    LANG_HOOKS_EXPR_TO_DECL, \
+   LANG_HOOKS_INIT_EH, \
  }
  
  #endif /* GCC_LANG_HOOKS_DEF_H */
Index: gcc/langhooks.h
===================================================================
*** gcc/langhooks.h.orig	2009-09-03 17:20:17.000000000 +0200
--- gcc/langhooks.h	2009-09-03 17:22:05.000000000 +0200
*************** struct lang_hooks
*** 414,419 ****
--- 414,422 ----
       if in the process TREE_CONSTANT or TREE_SIDE_EFFECTS need updating.  */
    tree (*expr_to_decl) (tree expr, bool *tc, bool *se);
  
+   /* Called to initialize the exception handing personality.  */
+   void (*init_eh) (void);
+ 
    /* Whenever you add entries here, make sure you adjust langhooks-def.h
       and langhooks.c accordingly.  */
  };
Index: gcc/objc/objc-act.h
===================================================================
*** gcc/objc/objc-act.h.orig	2009-09-03 17:24:39.000000000 +0200
--- gcc/objc/objc-act.h	2009-09-03 17:28:37.000000000 +0200
*************** const char *objc_printable_name (tree, i
*** 32,37 ****
--- 32,38 ----
  void objc_finish_file (void);
  tree objc_fold_obj_type_ref (tree, tree);
  int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
+ void objc_init_exceptions (void);
  
  /* NB: The remaining public functions are prototyped in c-common.h, for the
     benefit of stub-objc.c and objc-act.c.  */
Index: gcc/objc/objc-lang.c
===================================================================
*** gcc/objc/objc-lang.c.orig	2009-09-03 17:23:12.000000000 +0200
--- gcc/objc/objc-lang.c	2009-09-03 17:24:19.000000000 +0200
*************** static void objc_init_ts (void);
*** 50,55 ****
--- 50,57 ----
  #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
  #undef LANG_HOOKS_INIT_TS
  #define LANG_HOOKS_INIT_TS objc_init_ts
+ #undef LANG_HOOKS_INIT_EH
+ #define LANG_HOOKS_INIT_EH objc_init_exceptions
  
  /* Each front end provides its own lang hook initializer.  */
  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]