summaryrefslogtreecommitdiff
path: root/gcc/java
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/java')
-rw-r--r--gcc/java/ChangeLog13
-rw-r--r--gcc/java/builtins.c2
-rw-r--r--gcc/java/decl.c10
-rw-r--r--gcc/java/except.c86
-rw-r--r--gcc/java/java-tree.h3
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;