mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-08 20:52:05 +08:00
langhooks-def.h (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
2009-09-13 Richard Guenther <rguenther@suse.de> Rafael Avila de Espindola <espindola@google.com> * langhooks-def.h (LANG_HOOKS_EH_RUNTIME_TYPE): Define. (LANG_HOOKS_EH_PERSONALITY): Likewise. (LANG_HOOKS_INITIALIZER): Adjust. (lhd_pass_through_t): Declare. * langhooks.h (struct lang_hooks): Add eh_runtime_type and eh_personality. * langhooks.c (lhd_pass_through_t): New function. * dwarf2out.c (output_call_frame_info, dwarf2out_do_cfi_startproc, dwarf2out_begin_prologue): Use personality from current_function_decl. * expr.h (get_personality_function): Declare. * expr.c (get_personality_function): New function. (build_personality_function): Likewise. * libfuncs.h (libfunc_index): Remove LTI_eh_personality. (eh_personality_libfunc): Remove. * optabs.c (build_libfunc_function): New function split out from ... (init_one_libfunc): ... here. * tree.h (DECL_FUNCTION_PERSONALITY): New. (tree_function_decl): Add personality. (lhd_gcc_personality): Declare. (build_personality_function): Likewise. * tree.c (gcc_eh_personality_decl): New. (lhd_gcc_personality): New function. * except.h (lang_eh_runtime_type): Remove. (enum eh_personality_kind): New. (build_personality_function): Declare. (function_needs_eh_personality): Declare. * except.c (lang_eh_runtime_type): Remove. (function_needs_eh_personality): New function. (add_type_for_runtime): Call lang_hooks.type_for_runtime instead. (sjlj_emit_function_enter, output_function_exception_table): Use personality from current_function_decl. * tree-eh.c (lower_eh_constructs): Set DECL_FUNCTION_PERSONALITY. * tree-inline.c (tree_can_inline_p): Do not inline across different EH personalities. (expand_call_inline): Likewise. Adjust the callers EH personality. (tree_function_versioning): Copy DECL_FUNCTION_PERSONALITY. * cgraph.c (cgraph_add_new_function): Set DECL_FUNCTION_PERSONALITY. * Makefile.in (cgraph.o): Add $(EXCEPT_H) dependency. (c-parser.o): Likewise * c-tree.h (c_eh_initialized_p): Remove. (c_maybe_initialize_eh): Likewise. * c-decl.c (finish_decl): Don't call c_maybe_initialize_eh. (finish_decl): Don't call c_maybe_initialize_eh. (c_eh_initialized_p): Remove. (c_maybe_initialize_eh): Likewise. * c-parser.c (c_parser_omp_construct): Likewise. (c_parse_file): Initialize exception handling. objc/ * objc-act.c (objc_eh_runtime_type): Export. (objc_init_exceptions): Remove. Move warning code ... (objc_begin_try_stmt): ... here (objc_build_throw_stmt): ... and here. (objc_eh_personality_decl): New. (objc_eh_personality): New function. * objc-act.h (objc_eh_runtime_type): Declare. (objc_eh_personality): Likewise. * objc-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define. (LANG_HOOKS_EH_PERSONALITY): Likewise. cp/ * except.c (init_exception_processing): Do not set lang_eh_runtime_type. (choose_personality_routine): Do not set eh_personality_decl, set pragma_java_exceptions. * cp-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define. (LANG_HOOKS_EH_PERSONALITY): Likewise. (cp_eh_personality_decl): New. (cp_eh_personality): Likewise. * Make-lang.in (cp-lang.o): Add $(EXPR_H) and $(EXCEPT_H) dependencies. java/ * decl.c (do_nothing): Remove. (java_init_decl_processing): Do not set lang_eh_runtime_type. * Make-lang.in (lang.o): Add $(EXCEPT_H) dependency. * lang.c (java_eh_personality): New. (java_eh_personality_decl): Likewise. (LANG_HOOKS_EH_PERSONALITY): Define. ada/ * gcc-interface/misc.c (gnat_init_gcc_eh): Do not set lang_eh_runtime_type. (LANG_HOOKS_EH_PERSONALITY): Define. (gnat_eh_personality_decl): New. (gnat_eh_personality): Likewise. * Make-lang.in (misc.o): Add gt-ada-misc.h dependency. * config-lang.in (gtfiles): Add misc.c. fortran/ * f95-lang.c (gfc_maybe_initialize_eh): Do not init eh_personality_libfunc. Co-Authored-By: Rafael Avila de Espindola <espindola@google.com> From-SVN: r151676
This commit is contained in:
parent
22f3450401
commit
f9417da1a2
@ -1,3 +1,54 @@
|
||||
2009-09-13 Richard Guenther <rguenther@suse.de>
|
||||
Rafael Avila de Espindola <espindola@google.com>
|
||||
|
||||
* langhooks-def.h (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
|
||||
(LANG_HOOKS_EH_PERSONALITY): Likewise.
|
||||
(LANG_HOOKS_INITIALIZER): Adjust.
|
||||
(lhd_pass_through_t): Declare.
|
||||
* langhooks.h (struct lang_hooks): Add eh_runtime_type and
|
||||
eh_personality.
|
||||
* langhooks.c (lhd_pass_through_t): New function.
|
||||
* dwarf2out.c (output_call_frame_info, dwarf2out_do_cfi_startproc,
|
||||
dwarf2out_begin_prologue): Use personality from current_function_decl.
|
||||
* expr.h (get_personality_function): Declare.
|
||||
* expr.c (get_personality_function): New function.
|
||||
(build_personality_function): Likewise.
|
||||
* libfuncs.h (libfunc_index): Remove LTI_eh_personality.
|
||||
(eh_personality_libfunc): Remove.
|
||||
* optabs.c (build_libfunc_function): New function split out from ...
|
||||
(init_one_libfunc): ... here.
|
||||
* tree.h (DECL_FUNCTION_PERSONALITY): New.
|
||||
(tree_function_decl): Add personality.
|
||||
(lhd_gcc_personality): Declare.
|
||||
(build_personality_function): Likewise.
|
||||
* tree.c (gcc_eh_personality_decl): New.
|
||||
(lhd_gcc_personality): New function.
|
||||
* except.h (lang_eh_runtime_type): Remove.
|
||||
(enum eh_personality_kind): New.
|
||||
(build_personality_function): Declare.
|
||||
(function_needs_eh_personality): Declare.
|
||||
* except.c (lang_eh_runtime_type): Remove.
|
||||
(function_needs_eh_personality): New function.
|
||||
(add_type_for_runtime): Call lang_hooks.type_for_runtime instead.
|
||||
(sjlj_emit_function_enter, output_function_exception_table):
|
||||
Use personality from current_function_decl.
|
||||
* tree-eh.c (lower_eh_constructs): Set DECL_FUNCTION_PERSONALITY.
|
||||
* tree-inline.c (tree_can_inline_p): Do not inline across different
|
||||
EH personalities.
|
||||
(expand_call_inline): Likewise. Adjust the callers EH personality.
|
||||
(tree_function_versioning): Copy DECL_FUNCTION_PERSONALITY.
|
||||
* cgraph.c (cgraph_add_new_function): Set DECL_FUNCTION_PERSONALITY.
|
||||
* Makefile.in (cgraph.o): Add $(EXCEPT_H) dependency.
|
||||
(c-parser.o): Likewise
|
||||
* c-tree.h (c_eh_initialized_p): Remove.
|
||||
(c_maybe_initialize_eh): Likewise.
|
||||
* c-decl.c (finish_decl): Don't call c_maybe_initialize_eh.
|
||||
(finish_decl): Don't call c_maybe_initialize_eh.
|
||||
(c_eh_initialized_p): Remove.
|
||||
(c_maybe_initialize_eh): Likewise.
|
||||
* c-parser.c (c_parser_omp_construct): Likewise.
|
||||
(c_parse_file): Initialize exception handling.
|
||||
|
||||
2009-09-13 Kai Tietz <kai.tietz@onevision.com>
|
||||
|
||||
* config.gcc (tm_file): Remove i386/biarch32.h
|
||||
|
@ -1909,7 +1909,7 @@ c-errors.o: c-errors.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
c-parser.o : c-parser.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(GGC_H) $(TIMEVAR_H) $(C_TREE_H) $(INPUT_H) $(FLAGS_H) $(TOPLEV_H) output.h \
|
||||
$(CPPLIB_H) gt-c-parser.h $(RTL_H) langhooks.h $(C_COMMON_H) $(C_PRAGMA_H) \
|
||||
vec.h $(TARGET_H) $(CGRAPH_H) $(PLUGIN_H)
|
||||
vec.h $(TARGET_H) $(CGRAPH_H) $(PLUGIN_H) $(EXCEPT_H)
|
||||
|
||||
srcextra: gcc.srcextra lang.srcextra
|
||||
|
||||
@ -2767,7 +2767,7 @@ simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
langhooks.h $(TOPLEV_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
|
||||
gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
|
||||
$(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) value-prof.h
|
||||
$(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) value-prof.h $(EXCEPT_H)
|
||||
cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) langhooks.h $(TREE_INLINE_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \
|
||||
$(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
|
||||
|
@ -1,3 +1,14 @@
|
||||
2009-09-13 Richard Guenther <rguenther@suse.de>
|
||||
Rafael Avila de Espindola <espindola@google.com>
|
||||
|
||||
* gcc-interface/misc.c (gnat_init_gcc_eh): Do not set
|
||||
lang_eh_runtime_type.
|
||||
(LANG_HOOKS_EH_PERSONALITY): Define.
|
||||
(gnat_eh_personality_decl): New.
|
||||
(gnat_eh_personality): Likewise.
|
||||
* Make-lang.in (misc.o): Add gt-ada-misc.h dependency.
|
||||
* config-lang.in (gtfiles): Add misc.c.
|
||||
|
||||
2009-09-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
PR ada/18302
|
||||
|
@ -1072,7 +1072,8 @@ ada/misc.o : ada/gcc-interface/misc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(LANGHOOKS_DEF_H) opts.h options.h $(TREE_INLINE_H) \
|
||||
ada/gcc-interface/ada.h ada/adadecode.h ada/types.h ada/atree.h \
|
||||
ada/elists.h ada/namet.h ada/nlists.h ada/stringt.h ada/uintp.h ada/fe.h \
|
||||
ada/sinfo.h ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h
|
||||
ada/sinfo.h ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h \
|
||||
gt-ada-misc.h
|
||||
$(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
|
||||
|
||||
ada/targtyps.o : ada/gcc-interface/targtyps.c $(CONFIG_H) $(SYSTEM_H) \
|
||||
|
@ -32,7 +32,7 @@ boot_language_boot_flags='ADAFLAGS="$(BOOT_ADAFLAGS)"'
|
||||
|
||||
compilers="gnat1\$(exeext)"
|
||||
|
||||
gtfiles="\$(srcdir)/ada/gcc-interface/ada-tree.h \$(srcdir)/ada/gcc-interface/gigi.h \$(srcdir)/ada/gcc-interface/decl.c \$(srcdir)/ada/gcc-interface/trans.c \$(srcdir)/ada/gcc-interface/utils.c"
|
||||
gtfiles="\$(srcdir)/ada/gcc-interface/ada-tree.h \$(srcdir)/ada/gcc-interface/gigi.h \$(srcdir)/ada/gcc-interface/decl.c \$(srcdir)/ada/gcc-interface/trans.c \$(srcdir)/ada/gcc-interface/utils.c \$(srcdir)/ada/gcc-interface/misc.c"
|
||||
|
||||
outputs="ada/gcc-interface/Makefile ada/Makefile"
|
||||
|
||||
|
@ -79,6 +79,7 @@ static void gnat_parse_file (int);
|
||||
static void internal_error_function (const char *, va_list *);
|
||||
static tree gnat_type_max_size (const_tree);
|
||||
static void gnat_get_subrange_bounds (const_tree, tree *, tree *);
|
||||
static tree gnat_eh_personality (void);
|
||||
|
||||
/* Definitions for our language-specific hooks. */
|
||||
|
||||
@ -129,7 +130,9 @@ static void gnat_get_subrange_bounds (const_tree, tree *, tree *);
|
||||
#undef LANG_HOOKS_ATTRIBUTE_TABLE
|
||||
#define LANG_HOOKS_ATTRIBUTE_TABLE gnat_internal_attribute_table
|
||||
#undef LANG_HOOKS_BUILTIN_FUNCTION
|
||||
#define LANG_HOOKS_BUILTIN_FUNCTION gnat_builtin_function
|
||||
#define LANG_HOOKS_BUILTIN_FUNCTION gnat_builtin_function
|
||||
#undef LANG_HOOKS_EH_PERSONALITY
|
||||
#define LANG_HOOKS_EH_PERSONALITY gnat_eh_personality
|
||||
|
||||
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
||||
|
||||
@ -431,11 +434,7 @@ gnat_init_gcc_eh (void)
|
||||
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 ();
|
||||
|
||||
/* Turn on -fexceptions and -fnon-call-exceptions. The first one triggers
|
||||
@ -811,3 +810,19 @@ fp_size_to_prec (int size)
|
||||
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
static GTY(()) tree gnat_eh_personality_decl;
|
||||
|
||||
static tree
|
||||
gnat_eh_personality (void)
|
||||
{
|
||||
if (!gnat_eh_personality_decl)
|
||||
gnat_eh_personality_decl
|
||||
= build_personality_function (USING_SJLJ_EXCEPTIONS
|
||||
? "__gnat_eh_personality_sj"
|
||||
: "__gnat_eh_personality");
|
||||
|
||||
return gnat_eh_personality_decl;
|
||||
}
|
||||
|
||||
#include "gt-ada-misc.h"
|
||||
|
26
gcc/c-decl.c
26
gcc/c-decl.c
@ -92,9 +92,6 @@ tree pending_invalid_xref;
|
||||
/* File and line to appear in the eventual error message. */
|
||||
location_t pending_invalid_xref_location;
|
||||
|
||||
/* True means we've initialized exception handling. */
|
||||
bool c_eh_initialized_p;
|
||||
|
||||
/* The file and line that the prototype came from if this is an
|
||||
old-style definition; used for diagnostics in
|
||||
store_parm_decls_oldstyle. */
|
||||
@ -2365,7 +2362,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|
||||
TREE_USED (olddecl) = 1;
|
||||
|
||||
/* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
|
||||
But preserve OLDDECL's DECL_UID and DECL_CONTEXT. */
|
||||
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);
|
||||
@ -4043,23 +4041,6 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
|
||||
return tem;
|
||||
}
|
||||
|
||||
/* Initialize EH if not initialized yet and exceptions are enabled. */
|
||||
|
||||
void
|
||||
c_maybe_initialize_eh (void)
|
||||
{
|
||||
if (!flag_exceptions || c_eh_initialized_p)
|
||||
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 ();
|
||||
}
|
||||
|
||||
/* Finish processing of a declaration;
|
||||
install its initial value.
|
||||
If ORIGTYPE is not NULL_TREE, it is the original type of INIT.
|
||||
@ -4360,9 +4341,6 @@ finish_decl (tree decl, location_t init_loc, tree init,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "target.h"
|
||||
#include "cgraph.h"
|
||||
#include "plugin.h"
|
||||
#include "except.h"
|
||||
|
||||
|
||||
/* Initialization routine for this file. */
|
||||
@ -8489,12 +8490,6 @@ c_parser_omp_construct (c_parser *parser)
|
||||
p_kind = c_parser_peek_token (parser)->pragma_kind;
|
||||
c_parser_consume_pragma (parser);
|
||||
|
||||
/* For all constructs below except #pragma omp atomic
|
||||
MUST_NOT_THROW catch handlers are needed when exceptions
|
||||
are enabled. */
|
||||
if (p_kind != PRAGMA_OMP_ATOMIC)
|
||||
c_maybe_initialize_eh ();
|
||||
|
||||
switch (p_kind)
|
||||
{
|
||||
case PRAGMA_OMP_ATOMIC:
|
||||
@ -8607,6 +8602,13 @@ c_parse_file (void)
|
||||
the_parser = GGC_NEW (c_parser);
|
||||
*the_parser = tparser;
|
||||
|
||||
/* Initialize EH, if we've been told to do so. */
|
||||
if (flag_exceptions)
|
||||
{
|
||||
default_init_unwind_resume_libfunc ();
|
||||
using_eh_for_cleanups ();
|
||||
}
|
||||
|
||||
c_parser_translation_unit (the_parser);
|
||||
the_parser = NULL;
|
||||
}
|
||||
|
@ -427,7 +427,6 @@ extern struct c_spot_bindings *c_get_switch_bindings (void);
|
||||
extern void c_release_switch_bindings (struct c_spot_bindings *);
|
||||
extern bool c_check_switch_jump_warnings (struct c_spot_bindings *,
|
||||
location_t, location_t);
|
||||
extern void c_maybe_initialize_eh (void);
|
||||
extern void finish_decl (tree, location_t, tree, tree, tree);
|
||||
extern tree finish_enum (tree, tree, tree);
|
||||
extern void finish_function (void);
|
||||
@ -589,9 +588,6 @@ extern int system_header_p;
|
||||
|
||||
extern bool c_override_global_bindings_to_false;
|
||||
|
||||
/* True means we've initialized exception handling. */
|
||||
extern bool c_eh_initialized_p;
|
||||
|
||||
/* In c-decl.c */
|
||||
extern void c_finish_incomplete_decl (tree);
|
||||
extern void c_write_global_declarations (void);
|
||||
|
@ -84,6 +84,7 @@ The callgraph:
|
||||
#include "tree-dump.h"
|
||||
#include "tree-flow.h"
|
||||
#include "value-prof.h"
|
||||
#include "except.h"
|
||||
|
||||
static void cgraph_node_remove_callers (struct cgraph_node *node);
|
||||
static inline void cgraph_edge_remove_caller (struct cgraph_edge *e);
|
||||
@ -1953,6 +1954,12 @@ cgraph_add_new_function (tree fndecl, bool lowered)
|
||||
current_function_decl = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set a personality if required and we already passed EH lowering. */
|
||||
if (lowered
|
||||
&& (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
|
||||
== eh_personality_lang))
|
||||
DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
|
||||
}
|
||||
|
||||
/* Return true if NODE can be made local for API change.
|
||||
|
@ -1,3 +1,17 @@
|
||||
2009-09-13 Richard Guenther <rguenther@suse.de>
|
||||
Rafael Avila de Espindola <espindola@google.com>
|
||||
|
||||
* except.c (init_exception_processing): Do not set
|
||||
lang_eh_runtime_type.
|
||||
(choose_personality_routine): Do not set eh_personality_decl,
|
||||
set pragma_java_exceptions.
|
||||
* cp-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
|
||||
(LANG_HOOKS_EH_PERSONALITY): Likewise.
|
||||
(cp_eh_personality_decl): New.
|
||||
(cp_eh_personality): Likewise.
|
||||
* Make-lang.in (cp-lang.o): Add $(EXPR_H) and $(EXCEPT_H)
|
||||
dependencies.
|
||||
|
||||
2009-09-13 Wei Guozhi <carrot@google.com>
|
||||
|
||||
PR c++/3187
|
||||
|
@ -250,7 +250,7 @@ cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \
|
||||
$(C_PRAGMA_H) toplev.h output.h input.h cp/operators.def $(TM_P_H)
|
||||
cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h debug.h langhooks.h \
|
||||
$(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-cp.h \
|
||||
$(DIAGNOSTIC_H) cp/cp-objcp-common.h
|
||||
$(DIAGNOSTIC_H) cp/cp-objcp-common.h $(EXPR_H) $(EXCEPT_H)
|
||||
cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \
|
||||
output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \
|
||||
cp/operators.def $(TM_P_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(C_PRAGMA_H) \
|
||||
|
@ -32,11 +32,14 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "debug.h"
|
||||
#include "cp-objcp-common.h"
|
||||
#include "hashtab.h"
|
||||
#include "except.h"
|
||||
#include "expr.h"
|
||||
|
||||
enum c_language_kind c_language = clk_cxx;
|
||||
static void cp_init_ts (void);
|
||||
static const char * cxx_dwarf_name (tree t, int verbosity);
|
||||
static enum classify_record cp_classify_record (tree type);
|
||||
static tree cp_eh_personality (void);
|
||||
|
||||
/* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h;
|
||||
consequently, there should be very few hooks below. */
|
||||
@ -71,6 +74,10 @@ static enum classify_record cp_classify_record (tree type);
|
||||
#define LANG_HOOKS_FOLD_OBJ_TYPE_REF cp_fold_obj_type_ref
|
||||
#undef LANG_HOOKS_INIT_TS
|
||||
#define LANG_HOOKS_INIT_TS cp_init_ts
|
||||
#undef LANG_HOOKS_EH_PERSONALITY
|
||||
#define LANG_HOOKS_EH_PERSONALITY cp_eh_personality
|
||||
#undef LANG_HOOKS_EH_RUNTIME_TYPE
|
||||
#define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type
|
||||
|
||||
/* Each front end provides its own lang hook initializer. */
|
||||
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
||||
@ -145,4 +152,26 @@ finish_file (void)
|
||||
{
|
||||
}
|
||||
|
||||
static GTY(()) tree cp_eh_personality_decl;
|
||||
|
||||
static tree
|
||||
cp_eh_personality (void)
|
||||
{
|
||||
if (!cp_eh_personality_decl)
|
||||
{
|
||||
if (!pragma_java_exceptions)
|
||||
cp_eh_personality_decl
|
||||
= build_personality_function (USING_SJLJ_EXCEPTIONS
|
||||
? "__gxx_personality_sj0"
|
||||
: "__gxx_personality_v0");
|
||||
else
|
||||
cp_eh_personality_decl
|
||||
= build_personality_function (USING_SJLJ_EXCEPTIONS
|
||||
? "__gcj_personality_sj0"
|
||||
: "__gcj_personality_v0");
|
||||
}
|
||||
|
||||
return cp_eh_personality_decl;
|
||||
}
|
||||
|
||||
#include "gtype-cp.h"
|
||||
|
@ -4521,6 +4521,7 @@ extern void choose_personality_routine (enum languages);
|
||||
extern tree eh_type_info (tree);
|
||||
extern tree begin_eh_spec_block (void);
|
||||
extern void finish_eh_spec_block (tree, tree);
|
||||
extern tree build_eh_type_type (tree);
|
||||
|
||||
/* in expr.c */
|
||||
extern tree cplus_expand_constant (tree);
|
||||
|
@ -43,7 +43,6 @@ along with GCC; see the file COPYING3. If not see
|
||||
|
||||
static void push_eh_cleanup (tree);
|
||||
static tree prepare_eh_type (tree);
|
||||
static tree build_eh_type_type (tree);
|
||||
static tree do_begin_catch (void);
|
||||
static int dtor_nothrow (tree);
|
||||
static tree do_end_catch (tree);
|
||||
@ -78,15 +77,11 @@ init_exception_processing (void)
|
||||
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
|
||||
default_init_unwind_resume_libfunc ();
|
||||
|
||||
lang_eh_runtime_type = build_eh_type_type;
|
||||
lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
|
||||
}
|
||||
|
||||
@ -143,7 +138,7 @@ eh_type_info (tree type)
|
||||
/* Build the address of a typeinfo decl for use in the runtime
|
||||
matching field of the exception model. */
|
||||
|
||||
static tree
|
||||
tree
|
||||
build_eh_type_type (tree type)
|
||||
{
|
||||
tree exp = eh_type_info (type);
|
||||
@ -313,7 +308,7 @@ decl_is_java_type (tree decl, int err)
|
||||
/* 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
|
||||
??? At present eh_personality_decl is set to
|
||||
__gxx_personality_(sj|v)0 in init_exception_processing - should it
|
||||
be done here instead? */
|
||||
void
|
||||
@ -354,9 +349,7 @@ choose_personality_routine (enum languages lang)
|
||||
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");
|
||||
pragma_java_exceptions = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -216,6 +216,10 @@ static GTY(()) section *debug_str_section;
|
||||
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 ";#"
|
||||
@ -3599,6 +3603,7 @@ output_call_frame_info (int for_eh)
|
||||
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. */
|
||||
@ -3684,6 +3689,8 @@ output_call_frame_info (int for_eh)
|
||||
|
||||
augmentation[0] = 0;
|
||||
augmentation_size = 0;
|
||||
|
||||
personality = current_unit_personality;
|
||||
if (for_eh)
|
||||
{
|
||||
char *p;
|
||||
@ -3703,11 +3710,11 @@ output_call_frame_info (int for_eh)
|
||||
lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
|
||||
|
||||
p = augmentation + 1;
|
||||
if (eh_personality_libfunc)
|
||||
if (personality)
|
||||
{
|
||||
*p++ = 'P';
|
||||
augmentation_size += 1 + size_of_encoded_value (per_encoding);
|
||||
assemble_external_libcall (eh_personality_libfunc);
|
||||
assemble_external_libcall (personality);
|
||||
}
|
||||
if (any_lsda_needed)
|
||||
{
|
||||
@ -3726,7 +3733,7 @@ output_call_frame_info (int for_eh)
|
||||
}
|
||||
|
||||
/* Ug. Some platforms can't do unaligned dynamic relocations at all. */
|
||||
if (eh_personality_libfunc && per_encoding == DW_EH_PE_aligned)
|
||||
if (personality && per_encoding == DW_EH_PE_aligned)
|
||||
{
|
||||
int offset = ( 4 /* Length */
|
||||
+ 4 /* CIE Id */
|
||||
@ -3760,12 +3767,12 @@ output_call_frame_info (int for_eh)
|
||||
if (augmentation[0])
|
||||
{
|
||||
dw2_asm_output_data_uleb128 (augmentation_size, "Augmentation size");
|
||||
if (eh_personality_libfunc)
|
||||
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,
|
||||
eh_personality_libfunc,
|
||||
personality,
|
||||
true, NULL);
|
||||
}
|
||||
|
||||
@ -3824,13 +3831,14 @@ dwarf2out_do_cfi_startproc (bool second)
|
||||
{
|
||||
int enc;
|
||||
rtx ref;
|
||||
rtx personality = get_personality_function (current_function_decl);
|
||||
|
||||
fprintf (asm_out_file, "\t.cfi_startproc\n");
|
||||
|
||||
if (eh_personality_libfunc)
|
||||
if (personality)
|
||||
{
|
||||
enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
|
||||
ref = eh_personality_libfunc;
|
||||
ref = personality;
|
||||
|
||||
/* ??? The GAS support isn't entirely consistent. We have to
|
||||
handle indirect support ourselves, but PC-relative is done
|
||||
@ -3873,6 +3881,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
|
||||
char label[MAX_ARTIFICIAL_LABEL_BYTES];
|
||||
char * dup_label;
|
||||
dw_fde_ref fde;
|
||||
rtx personality;
|
||||
section *fnsec;
|
||||
|
||||
current_function_func_begin_label = NULL;
|
||||
@ -3967,8 +3976,17 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
|
||||
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
|
||||
|
88
gcc/except.c
88
gcc/except.c
@ -92,9 +92,6 @@ gimple (*lang_protect_cleanup_actions) (void);
|
||||
/* Return true if type A catches type B. */
|
||||
int (*lang_eh_type_covers) (tree a, tree b);
|
||||
|
||||
/* Map a type to a runtime object to match type. */
|
||||
tree (*lang_eh_runtime_type) (tree);
|
||||
|
||||
/* A hash table of label to region number. */
|
||||
|
||||
struct GTY(()) ehl_map_entry {
|
||||
@ -1696,7 +1693,7 @@ add_type_for_runtime (tree type)
|
||||
TREE_HASH (type), INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
tree runtime = (*lang_eh_runtime_type) (type);
|
||||
tree runtime = lang_hooks.eh_runtime_type (type);
|
||||
*slot = tree_cons (type, runtime, NULL_TREE);
|
||||
}
|
||||
}
|
||||
@ -2424,6 +2421,7 @@ sjlj_emit_function_enter (rtx dispatch_label)
|
||||
{
|
||||
rtx fn_begin, fc, mem, seq;
|
||||
bool fn_begin_outside_block;
|
||||
rtx personality = get_personality_function (current_function_decl);
|
||||
|
||||
fc = crtl->eh.sjlj_fc;
|
||||
|
||||
@ -2432,9 +2430,9 @@ sjlj_emit_function_enter (rtx dispatch_label)
|
||||
/* 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);
|
||||
assemble_external_libcall (personality);
|
||||
mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
|
||||
emit_move_insn (mem, eh_personality_libfunc);
|
||||
emit_move_insn (mem, personality);
|
||||
|
||||
mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
|
||||
if (crtl->uses_eh_lsda)
|
||||
@ -4394,7 +4392,7 @@ output_ttype (tree type, int tt_format, int tt_format_size)
|
||||
|
||||
static void
|
||||
output_one_function_exception_table (const char * ARG_UNUSED (fnname),
|
||||
int section)
|
||||
int section, rtx ARG_UNUSED (personality))
|
||||
{
|
||||
int tt_format, cs_format, lp_format, i, n;
|
||||
#ifdef HAVE_AS_LEB128
|
||||
@ -4410,7 +4408,7 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname),
|
||||
#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);
|
||||
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. */
|
||||
@ -4580,16 +4578,18 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname),
|
||||
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 (eh_personality_libfunc)
|
||||
assemble_external_libcall (eh_personality_libfunc);
|
||||
if (personality)
|
||||
assemble_external_libcall (personality);
|
||||
|
||||
output_one_function_exception_table (fnname, 0);
|
||||
output_one_function_exception_table (fnname, 0, personality);
|
||||
if (crtl->eh.call_site_record[1] != NULL)
|
||||
output_one_function_exception_table (fnname, 1);
|
||||
output_one_function_exception_table (fnname, 1, personality);
|
||||
|
||||
switch_to_section (current_function_section ());
|
||||
}
|
||||
@ -4606,6 +4606,70 @@ get_eh_throw_stmt_table (struct function *fun)
|
||||
return fun->eh->throw_stmt_table;
|
||||
}
|
||||
|
||||
/* Return true if the function deeds a EH personality function. */
|
||||
|
||||
enum eh_personality_kind
|
||||
function_needs_eh_personality (struct function *fn)
|
||||
{
|
||||
struct eh_region_d *i;
|
||||
int depth = 0;
|
||||
enum eh_personality_kind kind = eh_personality_none;
|
||||
|
||||
i = fn->eh->region_tree;
|
||||
if (!i)
|
||||
return eh_personality_none;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (i->type)
|
||||
{
|
||||
case ERT_TRY:
|
||||
case ERT_THROW:
|
||||
/* Do not need a EH personality function. */
|
||||
break;
|
||||
|
||||
case ERT_MUST_NOT_THROW:
|
||||
/* Always needs a EH personality function. */
|
||||
return eh_personality_lang;
|
||||
|
||||
case ERT_CLEANUP:
|
||||
/* Can do with any personality including the generic C one. */
|
||||
kind = eh_personality_any;
|
||||
break;
|
||||
|
||||
case ERT_CATCH:
|
||||
case ERT_ALLOWED_EXCEPTIONS:
|
||||
/* Always needs a EH personality function. The generic C
|
||||
personality doesn't handle these even for empty type lists. */
|
||||
return eh_personality_lang;
|
||||
|
||||
case ERT_UNKNOWN:
|
||||
return eh_personality_lang;
|
||||
}
|
||||
/* If there are sub-regions, process them. */
|
||||
if (i->inner)
|
||||
i = i->inner, depth++;
|
||||
/* If there are peers, process them. */
|
||||
else if (i->next_peer)
|
||||
i = i->next_peer;
|
||||
/* Otherwise, step back up the tree to the next peer. */
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
i = i->outer;
|
||||
depth--;
|
||||
if (i == NULL)
|
||||
return kind;
|
||||
}
|
||||
while (i->next_peer == NULL);
|
||||
i = i->next_peer;
|
||||
}
|
||||
}
|
||||
|
||||
return kind;
|
||||
}
|
||||
|
||||
/* Dump EH information to OUT. */
|
||||
|
||||
void
|
||||
|
12
gcc/except.h
12
gcc/except.h
@ -217,9 +217,6 @@ extern gimple (*lang_protect_cleanup_actions) (void);
|
||||
/* Return true if type A catches type B. */
|
||||
extern int (*lang_eh_type_covers) (tree a, tree b);
|
||||
|
||||
/* Map a type to a runtime object to match type. */
|
||||
extern tree (*lang_eh_runtime_type) (tree);
|
||||
|
||||
|
||||
/* Just because the user configured --with-sjlj-exceptions=no doesn't
|
||||
mean that we can use call frame exceptions. Detect that the target
|
||||
@ -277,3 +274,12 @@ extern int num_eh_regions (void);
|
||||
extern bitmap must_not_throw_labels (void);
|
||||
extern struct eh_region_d *redirect_eh_edge_to_label (struct edge_def *, tree, bool, bool, int);
|
||||
extern int get_next_region_sharing_label (int);
|
||||
|
||||
enum eh_personality_kind {
|
||||
eh_personality_none,
|
||||
eh_personality_any,
|
||||
eh_personality_lang
|
||||
};
|
||||
|
||||
extern enum eh_personality_kind
|
||||
function_needs_eh_personality (struct function *);
|
||||
|
48
gcc/expr.c
48
gcc/expr.c
@ -10214,4 +10214,52 @@ const_vector_from_tree (tree exp)
|
||||
|
||||
return gen_rtx_CONST_VECTOR (mode, v);
|
||||
}
|
||||
|
||||
|
||||
/* Build a decl for a EH personality function named NAME. */
|
||||
|
||||
tree
|
||||
build_personality_function (const char *name)
|
||||
{
|
||||
tree decl, type;
|
||||
|
||||
type = build_function_type_list (integer_type_node, integer_type_node,
|
||||
long_long_unsigned_type_node,
|
||||
ptr_type_node, ptr_type_node, NULL_TREE);
|
||||
decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
|
||||
get_identifier (name), type);
|
||||
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);
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
/* Extracts the personality function of DECL and returns the corresponding
|
||||
libfunc. */
|
||||
|
||||
rtx
|
||||
get_personality_function (tree decl)
|
||||
{
|
||||
tree personality = DECL_FUNCTION_PERSONALITY (decl);
|
||||
enum eh_personality_kind pk;
|
||||
|
||||
pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION (decl));
|
||||
if (pk == eh_personality_none)
|
||||
return NULL;
|
||||
|
||||
if (!personality
|
||||
&& pk == eh_personality_any)
|
||||
personality = lang_hooks.eh_personality ();
|
||||
|
||||
if (pk == eh_personality_lang)
|
||||
gcc_assert (personality != NULL_TREE);
|
||||
|
||||
return XEXP (DECL_RTL (personality), 0);
|
||||
}
|
||||
|
||||
#include "gt-expr.h"
|
||||
|
@ -814,6 +814,12 @@ extern void init_all_optabs (void);
|
||||
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 *);
|
||||
|
||||
/* Get the personality libfunc for a function decl. */
|
||||
rtx get_personality_function (tree);
|
||||
|
||||
extern int vector_mode_valid_p (enum machine_mode);
|
||||
|
||||
#endif /* GCC_EXPR_H */
|
||||
|
@ -1,3 +1,9 @@
|
||||
2009-09-13 Richard Guenther <rguenther@suse.de>
|
||||
Rafael Avila de Espindola <espindola@google.com>
|
||||
|
||||
* f95-lang.c (gfc_maybe_initialize_eh): Do not init
|
||||
eh_personality_libfunc.
|
||||
|
||||
2009-09-11 Janus Weil <janus@gcc.gnu.org>
|
||||
|
||||
PR fortran/41242
|
||||
|
@ -1155,10 +1155,6 @@ gfc_maybe_initialize_eh (void)
|
||||
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 ();
|
||||
}
|
||||
|
@ -1,3 +1,13 @@
|
||||
2009-09-13 Richard Guenther <rguenther@suse.de>
|
||||
Rafael Avila de Espindola <espindola@google.com>
|
||||
|
||||
* decl.c (do_nothing): Remove.
|
||||
(java_init_decl_processing): Do not set lang_eh_runtime_type.
|
||||
* Make-lang.in (lang.o): Add $(EXCEPT_H) dependency.
|
||||
* lang.c (java_eh_personality): New.
|
||||
(java_eh_personality_decl): Likewise.
|
||||
(LANG_HOOKS_EH_PERSONALITY): Define.
|
||||
|
||||
2009-09-03 Diego Novillo <dnovillo@google.com>
|
||||
|
||||
* lang.c (lang_hooks): Remove const qualifier.
|
||||
|
@ -284,7 +284,7 @@ java/jvgenmain.o: java/jvgenmain.c $(CONFIG_H) $(JAVA_TREE_H) $(SYSTEM_H) \
|
||||
coretypes.h $(TM_H) intl.h
|
||||
java/lang.o: java/lang.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h input.h \
|
||||
toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(EXPR_H) $(DIAGNOSTIC_H) \
|
||||
langhooks.h $(LANGHOOKS_DEF_H) gt-java-lang.h opts.h options.h
|
||||
langhooks.h $(LANGHOOKS_DEF_H) gt-java-lang.h opts.h options.h $(EXCEPT_H)
|
||||
java/mangle.o: java/mangle.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) $(SYSTEM_H) \
|
||||
coretypes.h $(TM_H) toplev.h $(GGC_H) gt-java-mangle.h $(LANGHOOKS_DEF_H)
|
||||
java/mangle_name.o: java/mangle_name.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) \
|
||||
|
@ -510,12 +510,6 @@ create_primitive_vtable (const char *name)
|
||||
return r;
|
||||
}
|
||||
|
||||
static tree
|
||||
do_nothing (tree t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Parse the version string and compute the ABI version number. */
|
||||
static void
|
||||
parse_version (void)
|
||||
@ -1195,16 +1189,12 @@ java_init_decl_processing (void)
|
||||
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
|
||||
default_init_unwind_resume_libfunc ();
|
||||
|
||||
lang_eh_runtime_type = do_nothing;
|
||||
|
||||
initialize_builtins ();
|
||||
soft_fmod_node = built_in_decls[BUILT_IN_FMOD];
|
||||
|
||||
|
@ -45,6 +45,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
||||
#include "tree-dump.h"
|
||||
#include "opts.h"
|
||||
#include "options.h"
|
||||
#include "except.h"
|
||||
|
||||
static bool java_init (void);
|
||||
static void java_finish (void);
|
||||
@ -64,6 +65,8 @@ static bool java_decl_ok_for_sibcall (const_tree);
|
||||
|
||||
static enum classify_record java_classify_record (tree type);
|
||||
|
||||
static tree java_eh_personality (void);
|
||||
|
||||
#ifndef TARGET_OBJECT_SUFFIX
|
||||
# define TARGET_OBJECT_SUFFIX ".o"
|
||||
#endif
|
||||
@ -158,6 +161,9 @@ struct GTY(()) language_function {
|
||||
#undef LANG_HOOKS_ATTRIBUTE_TABLE
|
||||
#define LANG_HOOKS_ATTRIBUTE_TABLE java_attribute_table
|
||||
|
||||
#undef LANG_HOOKS_EH_PERSONALITY
|
||||
#define LANG_HOOKS_EH_PERSONALITY java_eh_personality
|
||||
|
||||
/* Each front end provides its own. */
|
||||
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
||||
|
||||
@ -880,4 +886,18 @@ java_classify_record (tree type)
|
||||
return RECORD_IS_CLASS;
|
||||
}
|
||||
|
||||
static GTY(()) tree java_eh_personality_decl;
|
||||
|
||||
static tree
|
||||
java_eh_personality (void)
|
||||
{
|
||||
if (!java_eh_personality_decl)
|
||||
java_eh_personality_decl
|
||||
= build_personality_function (USING_SJLJ_EXCEPTIONS
|
||||
? "__gcj_personality_sj0"
|
||||
: "__gcj_personality_v0");
|
||||
|
||||
return java_eh_personality_decl;
|
||||
}
|
||||
|
||||
#include "gt-java-lang.h"
|
||||
|
@ -40,6 +40,7 @@ extern void lhd_do_nothing (void);
|
||||
extern void lhd_do_nothing_t (tree);
|
||||
extern void lhd_do_nothing_i (int);
|
||||
extern void lhd_do_nothing_f (struct function *);
|
||||
extern tree lhd_pass_through_t (tree);
|
||||
extern bool lhd_post_options (const char **);
|
||||
extern alias_set_type lhd_get_alias_set (tree);
|
||||
extern tree lhd_return_null_tree_v (void);
|
||||
@ -107,6 +108,8 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
|
||||
#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_EH_PERSONALITY lhd_gcc_personality
|
||||
#define LANG_HOOKS_EH_RUNTIME_TYPE lhd_pass_through_t
|
||||
|
||||
/* Attribute hooks. */
|
||||
#define LANG_HOOKS_ATTRIBUTE_TABLE NULL
|
||||
@ -271,6 +274,8 @@ extern tree lhd_make_node (enum tree_code);
|
||||
LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE, \
|
||||
LANG_HOOKS_INIT_TS, \
|
||||
LANG_HOOKS_EXPR_TO_DECL, \
|
||||
LANG_HOOKS_EH_PERSONALITY, \
|
||||
LANG_HOOKS_EH_RUNTIME_TYPE, \
|
||||
}
|
||||
|
||||
#endif /* GCC_LANG_HOOKS_DEF_H */
|
||||
|
@ -53,6 +53,13 @@ lhd_do_nothing_t (tree ARG_UNUSED (t))
|
||||
{
|
||||
}
|
||||
|
||||
/* Pass through (tree). */
|
||||
tree
|
||||
lhd_pass_through_t (tree t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Do nothing (int). */
|
||||
|
||||
void
|
||||
|
@ -414,6 +414,12 @@ struct lang_hooks
|
||||
if in the process TREE_CONSTANT or TREE_SIDE_EFFECTS need updating. */
|
||||
tree (*expr_to_decl) (tree expr, bool *tc, bool *se);
|
||||
|
||||
/* The EH personality function decl. */
|
||||
tree (*eh_personality) (void);
|
||||
|
||||
/* Map a type to a runtime object to match type. */
|
||||
tree (*eh_runtime_type) (tree);
|
||||
|
||||
/* Whenever you add entries here, make sure you adjust langhooks-def.h
|
||||
and langhooks.c accordingly. */
|
||||
};
|
||||
|
@ -31,7 +31,6 @@ enum libfunc_index
|
||||
LTI_setbits,
|
||||
|
||||
LTI_unwind_resume,
|
||||
LTI_eh_personality,
|
||||
LTI_setjmp,
|
||||
LTI_longjmp,
|
||||
LTI_unwind_sjlj_register,
|
||||
@ -61,7 +60,6 @@ extern GTY(()) rtx libfunc_table[LTI_MAX];
|
||||
#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])
|
||||
|
@ -1,3 +1,17 @@
|
||||
2009-09-13 Richard Guenther <rguenther@suse.de>
|
||||
Rafael Avila de Espindola <espindola@google.com>
|
||||
|
||||
* objc-act.c (objc_eh_runtime_type): Export.
|
||||
(objc_init_exceptions): Remove. Move warning code ...
|
||||
(objc_begin_try_stmt): ... here
|
||||
(objc_build_throw_stmt): ... and here.
|
||||
(objc_eh_personality_decl): New.
|
||||
(objc_eh_personality): New function.
|
||||
* objc-act.h (objc_eh_runtime_type): Declare.
|
||||
(objc_eh_personality): Likewise.
|
||||
* objc-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
|
||||
(LANG_HOOKS_EH_PERSONALITY): Likewise.
|
||||
|
||||
2009-09-03 Diego Novillo <dnovillo@google.com>
|
||||
|
||||
* objc-lang.c (lang_hooks): Remove const qualifier.
|
||||
|
@ -3483,50 +3483,32 @@ struct objc_try_context
|
||||
|
||||
static struct objc_try_context *cur_try_context;
|
||||
|
||||
static GTY(()) tree objc_eh_personality_decl;
|
||||
|
||||
/* This hook, called via lang_eh_runtime_type, generates a runtime object
|
||||
that represents TYPE. For Objective-C, this is just the class name. */
|
||||
/* ??? Isn't there a class object or some such? Is it easy to get? */
|
||||
|
||||
#ifndef OBJCPLUS
|
||||
static tree
|
||||
tree
|
||||
objc_eh_runtime_type (tree type)
|
||||
{
|
||||
return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize exception handling. */
|
||||
|
||||
static void
|
||||
objc_init_exceptions (void)
|
||||
tree
|
||||
objc_eh_personality (void)
|
||||
{
|
||||
static bool done = false;
|
||||
if (done)
|
||||
return;
|
||||
done = true;
|
||||
if (!flag_objc_sjlj_exceptions
|
||||
&& !objc_eh_personality_decl)
|
||||
objc_eh_personality_decl
|
||||
= build_personality_function (USING_SJLJ_EXCEPTIONS
|
||||
? "__gnu_objc_personality_sj0"
|
||||
: "__gnu_objc_personality_v0");
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
return objc_eh_personality_decl;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
|
||||
we'll arrange for it to be initialized (and associated with a binding)
|
||||
@ -3824,7 +3806,14 @@ objc_begin_try_stmt (location_t try_locus, tree body)
|
||||
c->end_try_locus = input_location;
|
||||
cur_try_context = c;
|
||||
|
||||
objc_init_exceptions ();
|
||||
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);
|
||||
@ -3973,7 +3962,14 @@ objc_build_throw_stmt (location_t loc, tree throw_expr)
|
||||
{
|
||||
tree args;
|
||||
|
||||
objc_init_exceptions ();
|
||||
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)
|
||||
{
|
||||
|
@ -32,6 +32,8 @@ const char *objc_printable_name (tree, int);
|
||||
void objc_finish_file (void);
|
||||
tree objc_fold_obj_type_ref (tree, tree);
|
||||
int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
|
||||
tree objc_eh_runtime_type (tree);
|
||||
tree objc_eh_personality (void);
|
||||
|
||||
/* NB: The remaining public functions are prototyped in c-common.h, for the
|
||||
benefit of stub-objc.c and objc-act.c. */
|
||||
|
@ -51,6 +51,13 @@ static void objc_init_ts (void);
|
||||
#undef LANG_HOOKS_INIT_TS
|
||||
#define LANG_HOOKS_INIT_TS objc_init_ts
|
||||
|
||||
#ifndef OBJCPLUS
|
||||
#undef LANG_HOOKS_EH_PERSONALITY
|
||||
#define LANG_HOOKS_EH_PERSONALITY objc_eh_personality
|
||||
#undef LANG_HOOKS_EH_RUNTIME_TYPE
|
||||
#define LANG_HOOKS_EH_RUNTIME_TYPE objc_eh_runtime_type
|
||||
#endif
|
||||
|
||||
/* Each front end provides its own lang hook initializer. */
|
||||
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
||||
|
||||
|
36
gcc/optabs.c
36
gcc/optabs.c
@ -6023,6 +6023,28 @@ libfunc_decl_eq (const void *entry1, const void *entry2)
|
||||
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)
|
||||
{
|
||||
@ -6043,19 +6065,7 @@ init_one_libfunc (const char *name)
|
||||
{
|
||||
/* 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);
|
||||
|
||||
decl = build_libfunc_function (name);
|
||||
*slot = decl;
|
||||
}
|
||||
return XEXP (DECL_RTL (decl), 0);
|
||||
|
@ -1939,6 +1939,14 @@ lower_eh_constructs (void)
|
||||
htab_delete (finally_tree);
|
||||
|
||||
collect_eh_region_array ();
|
||||
|
||||
/* If this function needs a language specific EH personality routine
|
||||
and the frontend didn't already set one do so now. */
|
||||
if (function_needs_eh_personality (cfun) == eh_personality_lang
|
||||
&& !DECL_FUNCTION_PERSONALITY (current_function_decl))
|
||||
DECL_FUNCTION_PERSONALITY (current_function_decl)
|
||||
= lang_hooks.eh_personality ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3505,6 +3505,13 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
|
||||
|
||||
cg_edge = cgraph_edge (id->dst_node, stmt);
|
||||
|
||||
/* Don't inline functions with different EH personalities. */
|
||||
if (DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
|
||||
&& DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl)
|
||||
&& (DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
|
||||
!= DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl)))
|
||||
goto egress;
|
||||
|
||||
/* Don't try to inline functions that are not well-suited to
|
||||
inlining. */
|
||||
if (!cgraph_inline_p (cg_edge, &reason))
|
||||
@ -3546,6 +3553,11 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
|
||||
/* We will be inlining this callee. */
|
||||
id->eh_region = lookup_stmt_eh_region (stmt);
|
||||
|
||||
/* Update the callers EH personality. */
|
||||
if (DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl))
|
||||
DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
|
||||
= DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl);
|
||||
|
||||
/* Split the block holding the GIMPLE_CALL. */
|
||||
e = split_block (bb, stmt);
|
||||
bb = e->src;
|
||||
@ -4730,6 +4742,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
|
||||
|
||||
DECL_ARTIFICIAL (new_decl) = 1;
|
||||
DECL_ABSTRACT_ORIGIN (new_decl) = DECL_ORIGIN (old_decl);
|
||||
DECL_FUNCTION_PERSONALITY (new_decl) = DECL_FUNCTION_PERSONALITY (old_decl);
|
||||
|
||||
/* Prepare the data structures for the tree copy. */
|
||||
memset (&id, 0, sizeof (id));
|
||||
@ -5000,6 +5013,18 @@ tree_can_inline_p (struct cgraph_edge *e)
|
||||
caller = e->caller->decl;
|
||||
callee = e->callee->decl;
|
||||
|
||||
/* We cannot inline a function that uses a different EH personality
|
||||
than the caller. */
|
||||
if (DECL_FUNCTION_PERSONALITY (caller)
|
||||
&& DECL_FUNCTION_PERSONALITY (callee)
|
||||
&& (DECL_FUNCTION_PERSONALITY (caller)
|
||||
!= DECL_FUNCTION_PERSONALITY (callee)))
|
||||
{
|
||||
e->inline_failed = CIF_UNSPECIFIED;
|
||||
gimple_call_set_cannot_inline (e->call_stmt, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Allow the backend to decide if inlining is ok. */
|
||||
if (!targetm.target_option.can_inline_p (caller, callee))
|
||||
{
|
||||
|
15
gcc/tree.c
15
gcc/tree.c
@ -10566,5 +10566,20 @@ tree_strip_sign_nop_conversions (tree exp)
|
||||
return exp;
|
||||
}
|
||||
|
||||
static GTY(()) tree gcc_eh_personality_decl;
|
||||
|
||||
/* Return the GCC personality function decl. */
|
||||
|
||||
tree
|
||||
lhd_gcc_personality (void)
|
||||
{
|
||||
if (!gcc_eh_personality_decl)
|
||||
gcc_eh_personality_decl
|
||||
= build_personality_function (USING_SJLJ_EXCEPTIONS
|
||||
? "__gcc_personality_sj0"
|
||||
: "__gcc_personality_v0");
|
||||
|
||||
return gcc_eh_personality_decl;
|
||||
}
|
||||
|
||||
#include "gt-tree.h"
|
||||
|
@ -2538,6 +2538,9 @@ struct GTY(()) tree_decl_minimal {
|
||||
#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. Moreover, for a FUNCTION_DECL,
|
||||
the body of the function should also be ignored. */
|
||||
@ -3191,6 +3194,9 @@ struct GTY(()) tree_function_decl {
|
||||
|
||||
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 */
|
||||
@ -4653,6 +4659,7 @@ extern bool auto_var_in_fn_p (const_tree, const_tree);
|
||||
extern tree build_low_bits_mask (tree, unsigned);
|
||||
extern tree tree_strip_nop_conversions (tree);
|
||||
extern tree tree_strip_sign_nop_conversions (tree);
|
||||
extern tree lhd_gcc_personality (void);
|
||||
|
||||
/* In cgraph.c */
|
||||
extern void change_decl_assembler_name (tree, tree);
|
||||
@ -5264,6 +5271,7 @@ extern unsigned HOST_WIDE_INT compute_builtin_object_size (tree, int);
|
||||
|
||||
/* In expr.c. */
|
||||
extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
|
||||
extern tree build_personality_function (const char *);
|
||||
|
||||
/* In tree-inline.c. */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user