aboutsummaryrefslogtreecommitdiff
path: root/gcc/java/expr.c
diff options
context:
space:
mode:
authorAnthony Green <green@cygnus.com>2000-02-26 05:12:27 +0000
committerAnthony Green <green@gcc.gnu.org>2000-02-26 05:12:27 +0000
commit3ff9925ce0be6f6e72f8da4d8ec96aad25e593f2 (patch)
treecfe8d050a2c658d4be3700810c5e25cbdfe9806d /gcc/java/expr.c
parent985dae7cdd18b543af8396c61c5332d685e47745 (diff)
downloadgcc-3ff9925ce0be6f6e72f8da4d8ec96aad25e593f2.zip
gcc-3ff9925ce0be6f6e72f8da4d8ec96aad25e593f2.tar.gz
gcc-3ff9925ce0be6f6e72f8da4d8ec96aad25e593f2.tar.bz2
expr.c (build_class_init): Mark the decl to be ignored by check_init.
2000-02-25 Anthony Green <green@cygnus.com> * expr.c (build_class_init): Mark the decl to be ignored by check_init. * java-tree.h (DECL_BIT_INDEX): Move definition from check-init.c * check-init.c: Move DECL_BIT_INDEX to java-tree.h * class.c (init_test_hash_newfunc): New function. (decl_hash): New function. (decl_compare): New function. * decl.c (emit_init_test_initialization): New function. (complete_start_java_method): Traverse the init test hashtable, calling emit_init_test_initialization. (always_initialize_class_p): Define. * expr.c (build_class_init): Use initialization tests when emitting class initialization code. (always_initialize_class_p): Declare. * jcf-parse.c (parse_class_file): Set always_initialize_class_p to 1. * java-tree.h: Include hash.h. (DECL_FUNCTION_INIT_TEST_TABLE): Define. (struct lang_decl): Add init_test_table field. (init_test_hash_entry): Define. From-SVN: r32166
Diffstat (limited to 'gcc/java/expr.c')
-rw-r--r--gcc/java/expr.c50
1 files changed, 44 insertions, 6 deletions
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index f25b194..41a1d3d 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -83,6 +83,10 @@ static tree case_identity PARAMS ((tree, tree));
static tree operand_type[59];
extern struct obstack permanent_obstack;
+/* Set to non-zero value in order to emit class initilization code
+ before static field references. */
+int always_initialize_class_p;
+
void
init_expr_processing()
{
@@ -1490,14 +1494,48 @@ tree
build_class_init (clas, expr)
tree clas, expr;
{
- tree init;
+ tree init, call;
+ struct init_test_hash_entry *ite;
if (inherits_from_p (current_class, clas))
return expr;
- init = build (CALL_EXPR, void_type_node,
- build_address_of (soft_initclass_node),
- build_tree_list (NULL_TREE, build_class_ref (clas)),
- NULL_TREE);
- TREE_SIDE_EFFECTS (init) = 1;
+
+ if (always_initialize_class_p)
+ {
+ init = build (CALL_EXPR, void_type_node,
+ build_address_of (soft_initclass_node),
+ build_tree_list (NULL_TREE, build_class_ref (clas)),
+ NULL_TREE);
+ TREE_SIDE_EFFECTS (init) = 1;
+ }
+ else
+ {
+ ite = (struct init_test_hash_entry *)
+ hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
+ (const hash_table_key) clas,
+ TRUE, NULL);
+
+ if (ite->init_test_decl == 0)
+ ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
+ boolean_type_node);
+ /* Tell the check-init code to ignore this decl. */
+ DECL_BIT_INDEX(ite->init_test_decl) = -1;
+
+ init = build (CALL_EXPR, void_type_node,
+ build_address_of (soft_initclass_node),
+ build_tree_list (NULL_TREE, build_class_ref (clas)),
+ NULL_TREE);
+ TREE_SIDE_EFFECTS (init) = 1;
+ call = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
+ build (MODIFY_EXPR, boolean_type_node,
+ ite->init_test_decl, boolean_true_node));
+ TREE_SIDE_EFFECTS (call) = 1;
+ init = build (COND_EXPR, void_type_node,
+ build (EQ_EXPR, boolean_type_node,
+ ite->init_test_decl, boolean_false_node),
+ call, integer_zero_node);
+ TREE_SIDE_EFFECTS (init) = 1;
+ }
+
if (expr != NULL_TREE)
{
expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);