summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-29 16:18:46 +0000
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-29 16:18:46 +0000
commit310b39066f979f2fac48d2ae2d6b504e0abd0aaf (patch)
tree406cc493b14a7dbe0721aae139686fc7c954a0cc
parent33d464a0d78f78bd3702b35b1122e68eb60d2d18 (diff)
downloadgcc-310b39066f979f2fac48d2ae2d6b504e0abd0aaf.tar.gz
2004-06-29 Andrew Haley <aph@redhat.com>
* except.c (expand_start_java_handler): Push a new binding level. Don't build a TRY_CATCH_EXPR now, we'll do it later. Call register_exception_range() to register where we'll do it. (expand_end_java_handler): Remove old bogus code. Replace with new logic that simply builds TRY_CATCH_EXPRs and inserts them at the top of the expression we're curently building. (maybe_end_try): Delete. * decl.c (binding_level.exception_range): New field. (clear_binding_level): Add field exception_range. Reformat. (poplevel): Call expand_end_java_handler(). (poplevel): Call java_add_stmt only if functionbody is false. (maybe_poplevels): Don't call maybe_end_try() from here. (end_java_method): Clear no longer used trees in function decl. (register_exception_range): New function. * java-tree.h (register_exception_range, struct eh_range): Declare. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83857 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/java/ChangeLog18
-rw-r--r--gcc/java/decl.c84
-rw-r--r--gcc/java/except.c83
-rw-r--r--gcc/java/java-except.h1
-rw-r--r--gcc/java/java-tree.h4
5 files changed, 94 insertions, 96 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index f6ad5ef0e17..51a2b359bce 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,21 @@
+2004-06-29 Andrew Haley <aph@redhat.com>
+
+ * except.c (expand_start_java_handler): Push a new binding level.
+ Don't build a TRY_CATCH_EXPR now, we'll do it later. Call
+ register_exception_range() to register where we'll do it.
+ (expand_end_java_handler): Remove old bogus code. Replace with
+ new logic that simply builds TRY_CATCH_EXPRs and inserts them at
+ the top of the expression we're curently building.
+ (maybe_end_try): Delete.
+ * decl.c (binding_level.exception_range): New field.
+ (clear_binding_level): Add field exception_range. Reformat.
+ (poplevel): Call expand_end_java_handler().
+ (poplevel): Call java_add_stmt only if functionbody is false.
+ (maybe_poplevels): Don't call maybe_end_try() from here.
+ (end_java_method): Clear no longer used trees in function decl.
+ (register_exception_range): New function.
+ * java-tree.h (register_exception_range, struct eh_range): Declare.
+
2004-06-28 Bryce McKinlay <mckinlay@redhat.com>
* jcf-write.c (get_classfile_modifiers): Formatting fixes.
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 682c8b3e3fd..508727a888a 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -314,6 +314,9 @@ struct binding_level GTY(())
/* The statements in this binding level. */
tree stmts;
+ /* An exception range associated with this binding level. */
+ struct eh_range * GTY((skip (""))) exception_range;
+
/* Binding depth at which this level began. Used only for debugging. */
unsigned binding_depth;
};
@@ -341,8 +344,18 @@ static GTY(()) struct binding_level *global_binding_level;
/* Binding level structures are initialized by copying this one. */
static const struct binding_level clear_binding_level
- = {NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE,
- NULL_BINDING_LEVEL, LARGEST_PC, 0, NULL_TREE, 0};
+= {
+ NULL_TREE, /* names */
+ NULL_TREE, /* shadowed */
+ NULL_TREE, /* blocks */
+ NULL_TREE, /* this_lock */
+ NULL_BINDING_LEVEL, /* level_chain */
+ LARGEST_PC, /* end_pc */
+ 0, /* start_pc */
+ NULL, /* stmts */
+ NULL, /* exception_range */
+ 0, /* binding_depth */
+ };
#if 0
/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
@@ -1316,6 +1329,9 @@ poplevel (int keep, int reverse, int functionbody)
TREE_TYPE (block) = void_type_node;
}
+ if (current_binding_level->exception_range)
+ expand_end_java_handler (current_binding_level->exception_range);
+
if (block != 0)
{
/* If any statements have been generated at this level, create a
@@ -1341,7 +1357,6 @@ poplevel (int keep, int reverse, int functionbody)
bind = build (BIND_EXPR, TREE_TYPE (block), BLOCK_VARS (block),
BLOCK_EXPR_BODY (block), block);
-
BIND_EXPR_BODY (bind) = current_binding_level->stmts;
if (BIND_EXPR_BODY (bind)
@@ -1448,24 +1463,27 @@ poplevel (int keep, int reverse, int functionbody)
DECL_INITIAL (current_function_decl) = block;
DECL_SAVED_TREE (current_function_decl) = bind;
}
- else if (block)
+ else
{
- if (!block_previously_created)
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, block);
+ if (block)
+ {
+ if (!block_previously_created)
+ current_binding_level->blocks
+ = chainon (current_binding_level->blocks, block);
+ }
+ /* If we did not make a block for the level just exited,
+ any blocks made for inner levels
+ (since they cannot be recorded as subblocks in that level)
+ must be carried forward so they will later become subblocks
+ of something else. */
+ else if (subblocks)
+ current_binding_level->blocks
+ = chainon (current_binding_level->blocks, subblocks);
+
+ if (bind)
+ java_add_stmt (bind);
}
- /* If we did not make a block for the level just exited,
- any blocks made for inner levels
- (since they cannot be recorded as subblocks in that level)
- must be carried forward so they will later become subblocks
- of something else. */
- else if (subblocks)
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, subblocks);
-
- if (bind)
- java_add_stmt (bind);
-
+
if (block)
TREE_USED (block) = 1;
return block;
@@ -1521,11 +1539,7 @@ maybe_poplevels (int pc)
#endif
while (current_binding_level->end_pc <= pc)
- {
- maybe_end_try (current_binding_level->start_pc, pc);
- poplevel (1, 0, 0);
- }
- maybe_end_try (0, pc);
+ poplevel (1, 0, 0);
}
/* Terminate any binding which began during the range beginning at
@@ -1781,6 +1795,14 @@ end_java_method (void)
flag_unit_at_a_time = 0;
finish_method (fndecl);
+ if (! flag_unit_at_a_time)
+ {
+ /* Nulling these fields when we no longer need them saves
+ memory. */
+ DECL_SAVED_TREE (fndecl) = NULL;
+ DECL_STRUCT_FUNCTION (fndecl) = NULL;
+ DECL_INITIAL (fndecl) = NULL_TREE;
+ }
current_function_decl = NULL_TREE;
}
@@ -1929,5 +1951,19 @@ get_stmts (void)
return &current_binding_level->stmts;
}
+/* Register an exception range as belonging to the current binding
+ level. There may only be one: if there are more, we'll create more
+ binding levels. However, each range can have multiple handlers,
+ and these are expanded when we call expand_end_java_handler(). */
+
+void
+register_exception_range (struct eh_range *range, int pc, int end_pc)
+{
+ if (current_binding_level->exception_range)
+ abort ();
+ current_binding_level->exception_range = range;
+ current_binding_level->end_pc = end_pc;
+ current_binding_level->start_pc = pc;
+}
#include "gt-java-decl.h"
diff --git a/gcc/java/except.c b/gcc/java/except.c
index b77842e8a66..91f741f63d0 100644
--- a/gcc/java/except.c
+++ b/gcc/java/except.c
@@ -40,7 +40,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "toplev.h"
static void expand_start_java_handler (struct eh_range *);
-static void expand_end_java_handler (struct eh_range *);
static struct eh_range *find_handler_in_range (int, struct eh_range *,
struct eh_range *);
static void link_handler (struct eh_range *, struct eh_range *);
@@ -305,13 +304,8 @@ expand_start_java_handler (struct eh_range *range)
fprintf (stderr, "expand start handler pc %d --> %d\n",
current_pc, range->end_pc);
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
- {
- tree new = build (TRY_CATCH_EXPR, void_type_node, NULL, NULL);
- TREE_SIDE_EFFECTS (new) = 1;
- java_add_stmt (build_java_empty_stmt ());
- range->stmt = java_add_stmt (new);
- }
-
+ pushlevel (0);
+ register_exception_range (range, range->start_pc, range->end_pc);
range->expanded = 1;
}
@@ -428,13 +422,11 @@ build_exception_object_ref (tree type)
/* If there are any handlers for this range, isssue end of range,
and then all handler blocks */
-static void
+void
expand_end_java_handler (struct eh_range *range)
{
tree handler = range->handlers;
- tree compound = NULL;
- force_poplevels (range->start_pc);
for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler))
{
/* For bytecode we treat exceptions a little unusually. A
@@ -444,55 +436,18 @@ expand_end_java_handler (struct eh_range *range)
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);
- if (compound)
- {
- /* If we already have a COMPOUND there is more than one
- catch handler for this try block. Wrap the
- TRY_CATCH_EXPR in operand 1 of COMPOUND with another
- TRY_CATCH_EXPR. */
- tree inner_try_expr = TREE_OPERAND (compound, 1);
- tree catch_expr
- = build (CATCH_EXPR, void_type_node, type,
- build (GOTO_EXPR, void_type_node, TREE_VALUE (handler)));
- tree try_expr
- = build (TRY_CATCH_EXPR, void_type_node,
- inner_try_expr, catch_expr);
- TREE_OPERAND (compound, 1) = try_expr;
- }
- else
- {
- tree *stmts = get_stmts ();
- tree outer;
- tree try_expr;
- compound = range->stmt;
- outer = TREE_OPERAND (compound, 0);
- try_expr = TREE_OPERAND (compound, 1);
- /* On the left of COMPOUND is the expresion to be evaluated
- before the try handler is entered; on the right is a
- TRY_FINALLY_EXPR with no operands as yet. In the current
- statement list is an expression that we're going to move
- inside the try handler. We'll create a new COMPOUND_EXPR
- with the outer context on the left and the TRY_FINALLY_EXPR
- on the right, then nullify both operands of COMPOUND, which
- becomes the final expression in OUTER. This new compound
- expression replaces the current statement list. */
- TREE_OPERAND (try_expr, 0) = *stmts;
- TREE_OPERAND (try_expr, 1)
- = build (CATCH_EXPR, void_type_node, type,
- build (GOTO_EXPR, void_type_node, TREE_VALUE (handler)));
- TREE_SIDE_EFFECTS (try_expr) = 1;
- TREE_OPERAND (compound, 0) = build_java_empty_stmt ();
- TREE_OPERAND (compound, 1) = build_java_empty_stmt ();
- compound
- = build (COMPOUND_EXPR, TREE_TYPE (try_expr), outer, try_expr);
- *stmts = compound;
- }
+ {
+ tree catch_expr
+ = build (CATCH_EXPR, void_type_node, type,
+ build (GOTO_EXPR, void_type_node, TREE_VALUE (handler)));
+ tree try_catch_expr = build (TRY_CATCH_EXPR, void_type_node,
+ *get_stmts (), catch_expr);
+ *get_stmts () = try_catch_expr;
+ }
}
#if defined(DEBUG_JAVA_BINDING_LEVELS)
indent ();
@@ -536,19 +491,3 @@ maybe_start_try (int start_pc, int end_pc)
check_start_handlers (range, start_pc);
}
-/* Emit any end-of-try-range ending at end_pc and starting before
- start_pc. */
-
-void
-maybe_end_try (int start_pc, int end_pc)
-{
- if (! doing_eh (1))
- return;
-
- while (current_range != NULL_EH_RANGE && current_range->end_pc <= end_pc
- && current_range->start_pc >= start_pc)
- {
- expand_end_java_handler (current_range);
- current_range = current_range->outer;
- }
-}
diff --git a/gcc/java/java-except.h b/gcc/java/java-except.h
index 0646d61b591..960a9155023 100644
--- a/gcc/java/java-except.h
+++ b/gcc/java/java-except.h
@@ -68,3 +68,4 @@ extern void maybe_end_try (int, int);
extern void add_handler (int, int, tree, tree);
extern void handle_nested_ranges (void);
extern void expand_resume_after_catch (void);
+extern void expand_end_java_handler (struct eh_range *);
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 64c07784d23..1089e595083 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -1117,6 +1117,9 @@ struct lang_type GTY(())
#define SEARCH_SUPER 2
#define SEARCH_VISIBLE 4
+/* Defined in java-except.h */
+struct eh_range;
+
extern void java_parse_file (int);
extern bool java_mark_addressable (tree);
extern tree java_type_for_mode (enum machine_mode, int);
@@ -1345,6 +1348,7 @@ extern tree add_stmt_to_compound (tree, tree, tree);
extern tree java_add_stmt (tree);
extern tree java_add_local_var (tree decl);
extern tree *get_stmts (void);
+extern void register_exception_range(struct eh_range *, int, int);
extern void finish_method (tree);
extern void java_expand_body (tree);