diff options
Diffstat (limited to 'gcc/java')
-rw-r--r-- | gcc/java/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/java/builtins.c | 2 | ||||
-rw-r--r-- | gcc/java/decl.c | 10 | ||||
-rw-r--r-- | gcc/java/except.c | 86 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 3 |
5 files changed, 83 insertions, 31 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 6b7d930ba28..6c58a99b4c1 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,16 @@ +2009-09-14 Richard Henderson <rth@redhat.com> + + * builtins.c (initialize_builtins): Update call to + build_common_builtin_nodes. + * decl.c (java_init_decl_processing): Don't call + default_init_unwind_resume_libfunc. + * except.c: Include tree-iterator.h. + (build_exception_object_var): New. + (build_exception_object_ref): Use it. + (expand_end_java_handler): Initialize it from __builtin_eh_pointer. + Attach all CATCH_EXPRs to a single TRY_CATCH_EXPR. + * java-tree.h (DECL_FUNCTION_EXC_OBJ): New. + 2009-09-13 Richard Guenther <rguenther@suse.de> Rafael Avila de Espindola <espindola@google.com> diff --git a/gcc/java/builtins.c b/gcc/java/builtins.c index 6e4815beeab..a05ff53ceb9 100644 --- a/gcc/java/builtins.c +++ b/gcc/java/builtins.c @@ -584,7 +584,7 @@ initialize_builtins (void) build_function_type_list (ptr_type_node, int_type_node, NULL_TREE), "__builtin_return_address", BUILTIN_NOTHROW); - build_common_builtin_nodes (); + build_common_builtin_nodes (true); } /* If the call matches a builtin, return the diff --git a/gcc/java/decl.c b/gcc/java/decl.c index c9ccc9d8556..c593b53df5c 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -1,7 +1,7 @@ /* Process declarations and variables for the GNU compiler for the Java(TM) language. Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, - 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -1188,14 +1188,8 @@ java_init_decl_processing (void) build_function_type (long_type_node, t), 0, NOT_BUILT_IN, NULL, NULL_TREE); - /* Initialize variables for except.c. */ - - if (targetm.arm_eabi_unwinder) - unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup"); - else - default_init_unwind_resume_libfunc (); - initialize_builtins (); + soft_fmod_node = built_in_decls[BUILT_IN_FMOD]; parse_version (); diff --git a/gcc/java/except.c b/gcc/java/except.c index e97ed7755d9..4e4651421d4 100644 --- a/gcc/java/except.c +++ b/gcc/java/except.c @@ -1,6 +1,6 @@ /* Handle exceptions for GNU compiler for the Java(TM) language. Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, - 2007, 2008 Free Software Foundation, Inc. + 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -37,6 +37,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "except.h" #include "java-except.h" #include "toplev.h" +#include "tree-iterator.h" + static void expand_start_java_handler (struct eh_range *); static struct eh_range *find_handler_in_range (int, struct eh_range *, @@ -457,6 +459,26 @@ java_expand_catch_classes (tree this_class) expand_catch_class, NULL); } +/* Build and push the variable that will hold the exception object + within this function. */ + +static tree +build_exception_object_var (void) +{ + tree decl = DECL_FUNCTION_EXC_OBJ (current_function_decl); + if (decl == NULL) + { + decl = build_decl (DECL_SOURCE_LOCATION (current_function_decl), + VAR_DECL, get_identifier ("#exc_obj"), ptr_type_node); + DECL_IGNORED_P (decl) = 1; + DECL_ARTIFICIAL (decl) = 1; + + DECL_FUNCTION_EXC_OBJ (current_function_decl) = decl; + pushdecl_function_level (decl); + } + return decl; +} + /* Build a reference to the jthrowable object being carried in the exception header. */ @@ -467,7 +489,8 @@ build_exception_object_ref (tree type) /* Java only passes object via pointer and doesn't require adjusting. The java object is immediately before the generic exception header. */ - obj = build0 (EXC_PTR_EXPR, build_pointer_type (type)); + obj = build_exception_object_var (); + obj = fold_convert (build_pointer_type (type), obj); obj = build2 (POINTER_PLUS_EXPR, TREE_TYPE (obj), obj, fold_build1 (NEGATE_EXPR, sizetype, TYPE_SIZE_UNIT (TREE_TYPE (obj)))); @@ -482,29 +505,48 @@ void expand_end_java_handler (struct eh_range *range) { tree handler = range->handlers; - - for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler)) + if (handler) { - /* For bytecode we treat exceptions a little unusually. A - `finally' clause looks like an ordinary exception handler for - Throwable. The reason for this is that the bytecode has - already expanded the finally logic, and we would have to do - extra (and difficult) work to get this to look like a - gcc-style finally clause. */ - tree type = TREE_PURPOSE (handler); - if (type == NULL) - type = throwable_type_node; - type = prepare_eh_table_type (type); + tree exc_obj = build_exception_object_var (); + tree catches = make_node (STATEMENT_LIST); + tree_stmt_iterator catches_i = tsi_last (catches); + tree *body; - { - tree catch_expr = build2 (CATCH_EXPR, void_type_node, type, - build1 (GOTO_EXPR, void_type_node, - TREE_VALUE (handler))); - tree try_catch_expr = build2 (TRY_CATCH_EXPR, void_type_node, - *get_stmts (), catch_expr); - *get_stmts () = try_catch_expr; - } + for (; handler; handler = TREE_CHAIN (handler)) + { + tree type, eh_type, x; + tree stmts = make_node (STATEMENT_LIST); + tree_stmt_iterator stmts_i = tsi_last (stmts); + + type = TREE_PURPOSE (handler); + if (type == NULL) + type = throwable_type_node; + eh_type = prepare_eh_table_type (type); + + x = build_call_expr (built_in_decls[BUILT_IN_EH_POINTER], + 1, integer_zero_node); + x = build2 (MODIFY_EXPR, void_type_node, exc_obj, x); + tsi_link_after (&stmts_i, x, TSI_CONTINUE_LINKING); + + x = build1 (GOTO_EXPR, void_type_node, TREE_VALUE (handler)); + tsi_link_after (&stmts_i, x, TSI_CONTINUE_LINKING); + + x = build2 (CATCH_EXPR, void_type_node, eh_type, stmts); + tsi_link_after (&catches_i, x, TSI_CONTINUE_LINKING); + + /* Throwable can match anything in Java, and therefore + any subsequent handlers are unreachable. */ + /* ??? If we're assured of no foreign language exceptions, + we'd be better off using NULL as the exception type + for the catch. */ + if (type == throwable_type_node) + break; + } + + body = get_stmts (); + *body = build2 (TRY_CATCH_EXPR, void_type_node, *body, catches); } + #if defined(DEBUG_JAVA_BINDING_LEVELS) indent (); fprintf (stderr, "expand end handler pc %d <-- %d\n", diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 29027eb6463..8ffe2422967 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -714,6 +714,8 @@ union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"), /* List of checked thrown exceptions, as specified with the `throws' keyword */ #define DECL_FUNCTION_THROWS(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.throws_list) +/* VAR_DECL containing the caught exception object. */ +#define DECL_FUNCTION_EXC_OBJ(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.exc_obj) /* For each function decl, init_test_table contains a hash table whose entries are keyed on class names, and whose values are local boolean decls. The variables are intended to be TRUE when the @@ -785,6 +787,7 @@ struct GTY(()) lang_decl_func { int arg_slot_count; source_location last_line; /* End line number for a function decl */ tree throws_list; /* Exception specified by `throws' */ + tree exc_obj; /* Decl holding the exception object. */ /* Class initialization test variables */ htab_t GTY ((param_is (struct treetreehash_entry))) init_test_table; |