X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fjava%2Fdecl.c;h=8497fbf787bc903dcefa0e0a1e01b011e263c9f7;hp=b8690160756689ac112698170cb943be2c2c9232;hb=208ca064ed26d6cd3bb8ca6fb13743668435b315;hpb=85b2164b6480724482a981c3beeef09520b1c9af diff --git a/gcc/java/decl.c b/gcc/java/decl.c index b8690160756..8497fbf787b 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -48,6 +48,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "tree-inline.h" #include "target.h" #include "version.h" +#include "tree-iterator.h" #if defined (DEBUG_JAVA_BINDING_LEVELS) extern void indent (void); @@ -123,6 +124,12 @@ static GTY(()) tree pending_local_decls; /* The decl for "_Jv_ResolvePoolEntry". */ tree soft_resolvepoolentry_node; +/* The decl for the .constants field of an instance of Class. */ +tree constants_field_decl_node; + +/* The decl for the .data field of an instance of Class. */ +tree constants_data_field_decl_node; + #if defined(DEBUG_JAVA_BINDING_LEVELS) int binding_depth = 0; int is_class_level = 0; @@ -153,48 +160,6 @@ debug_variable_p (tree decl) return true; } -/* Copy the value in decl into every live alias in the same local - variable slot. Some of these will be dead stores removed by the - optimizer. */ - -void -update_aliases (tree decl, int index, int pc) -{ - tree decl_type = TREE_TYPE (decl); - tree tmp; - - if (debug_variable_p (decl)) - abort (); - - for (tmp = TREE_VEC_ELT (decl_map, index); - tmp != NULL_TREE; - tmp = DECL_LOCAL_SLOT_CHAIN (tmp)) - { - tree tmp_type = TREE_TYPE (tmp); - if (tmp != decl - && LOCAL_SLOT_P (tmp) == 0 - && (pc == -1 - || (pc >= DECL_LOCAL_START_PC (tmp) - && pc < DECL_LOCAL_END_PC (tmp))) - /* This test is < (rather than <=) because there's no point - updating an alias that's about to die at the end of this - instruction. */ - && (tmp_type == decl_type - || (INTEGRAL_TYPE_P (tmp_type) - && INTEGRAL_TYPE_P (decl_type) - && TYPE_PRECISION (decl_type) <= 32 - && TYPE_PRECISION (tmp_type) <= 32) - || (TREE_CODE (tmp_type) == POINTER_TYPE - && TREE_CODE (decl_type) == POINTER_TYPE))) - { - tree src = build1 (NOP_EXPR, tmp_type, decl); - if (LOCAL_VAR_OUT_OF_SCOPE_P (tmp)) - abort (); - java_add_stmt (build2 (MODIFY_EXPR, tmp_type, tmp, src)); - } - } -} - static tree push_jvm_slot (int index, tree decl) { @@ -215,52 +180,6 @@ push_jvm_slot (int index, tree decl) return decl; } -/* At the point of its creation a local variable decl inherits - whatever is already in the same slot. In the case of a local - variable that is declared but unused, we won't find anything. */ - -static void -initialize_local_variable (tree decl, int index) -{ - tree decl_type = TREE_TYPE (decl); - if (TREE_CODE (decl_type) == POINTER_TYPE) - { - tree tmp = TREE_VEC_ELT (base_decl_map, index); - - if (tmp) - { - /* At the point of its creation this decl inherits whatever - is in the slot. */ - tree src = build1 (NOP_EXPR, decl_type, tmp); - java_add_stmt (build2 (MODIFY_EXPR, decl_type, decl, src)); - } - } - else - { - tree tmp; - - for (tmp = TREE_VEC_ELT (decl_map, index); - tmp != NULL_TREE; - tmp = DECL_LOCAL_SLOT_CHAIN (tmp)) - { - tree tmp_type = TREE_TYPE (tmp); - if (tmp != decl - && ! debug_variable_p (tmp) - && (tmp_type == decl_type - || (INTEGRAL_TYPE_P (tmp_type) - && INTEGRAL_TYPE_P (decl_type) - && TYPE_PRECISION (decl_type) <= 32 - && TYPE_PRECISION (tmp_type) <= 32 - && TYPE_PRECISION (tmp_type) - >= TYPE_PRECISION (decl_type)))) - { - java_add_stmt (build2 (MODIFY_EXPR, decl_type, decl, tmp)); - return; - } - } - } -} - /* Find the best declaration based upon type. If 'decl' fits 'type' better than 'best', return 'decl'. Otherwise return 'best'. */ @@ -269,8 +188,7 @@ check_local_unnamed_variable (tree best, tree decl, tree type) { tree decl_type = TREE_TYPE (decl); - if (LOCAL_VAR_OUT_OF_SCOPE_P (decl)) - abort (); + gcc_assert (! LOCAL_VAR_OUT_OF_SCOPE_P (decl)); /* Use the same decl for all integer types <= 32 bits. This is necessary because sometimes a value is stored as (for example) @@ -411,9 +329,7 @@ java_replace_reference (tree var_decl, bool want_lvalue) int index = DECL_LOCAL_SLOT_NUMBER (var_decl); tree base_decl = TREE_VEC_ELT (base_decl_map, index); - if (! base_decl) - abort (); - + gcc_assert (base_decl); if (! want_lvalue) base_decl = build1 (NOP_EXPR, decl_type, base_decl); @@ -543,6 +459,7 @@ push_promoted_type (const char *name, tree actual_type) TYPE_MAX_VALUE (type) = copy_node (in_max); TREE_TYPE (TYPE_MAX_VALUE (type)) = type; TYPE_PRECISION (type) = TYPE_PRECISION (int_type_node); + TYPE_STRING_FLAG (type) = TYPE_STRING_FLAG (actual_type); layout_type (type); pushdecl (build_decl (TYPE_DECL, get_identifier (name), type)); return type; @@ -743,7 +660,8 @@ java_init_decl_processing (void) initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */ short_array_type_node = build_prim_array_type (short_type_node, 200); #endif - char_type_node = make_node (CHAR_TYPE); + char_type_node = make_node (INTEGER_TYPE); + TYPE_STRING_FLAG (char_type_node) = 1; TYPE_PRECISION (char_type_node) = 16; fixup_unsigned_type (char_type_node); pushdecl (build_decl (TYPE_DECL, get_identifier ("char"), char_type_node)); @@ -886,6 +804,7 @@ java_init_decl_processing (void) PUSH_FIELD (constants_type_node, field, "size", unsigned_int_type_node); PUSH_FIELD (constants_type_node, field, "tags", ptr_type_node); PUSH_FIELD (constants_type_node, field, "data", ptr_type_node); + constants_data_field_decl_node = field; FINISH_RECORD (constants_type_node); build_decl (TYPE_DECL, get_identifier ("constants"), constants_type_node); @@ -927,6 +846,7 @@ java_init_decl_processing (void) PUSH_FIELD (class_type_node, field, "accflags", access_flags_type_node); PUSH_FIELD (class_type_node, field, "superclass", class_ptr_type); PUSH_FIELD (class_type_node, field, "constants", constants_type_node); + constants_field_decl_node = field; PUSH_FIELD (class_type_node, field, "methods", method_ptr_type_node); PUSH_FIELD (class_type_node, field, "method_count", short_type_node); PUSH_FIELD (class_type_node, field, "vtable_method_count", short_type_node); @@ -1116,6 +1036,15 @@ java_init_decl_processing (void) TREE_THIS_VOLATILE (soft_abstractmethod_node) = 1; TREE_SIDE_EFFECTS (soft_abstractmethod_node) = 1; + soft_nosuchfield_node + = builtin_function ("_Jv_ThrowNoSuchFieldError", + build_function_type (void_type_node, endlink), + 0, NOT_BUILT_IN, NULL, NULL_TREE); + /* Mark soft_nosuchfield_node as a `noreturn' function with side + effects. */ + TREE_THIS_VOLATILE (soft_nosuchfield_node) = 1; + TREE_SIDE_EFFECTS (soft_nosuchfield_node) = 1; + t = tree_cons (NULL_TREE, class_ptr_type, tree_cons (NULL_TREE, object_ptr_type_node, endlink)); soft_checkcast_node @@ -1169,6 +1098,12 @@ java_init_decl_processing (void) build_function_type (void_type_node, t), 0, NOT_BUILT_IN, NULL, NULL_TREE); + t = tree_cons (NULL_TREE, object_ptr_type_node, endlink); + soft_unwrapjni_node + = builtin_function ("_Jv_UnwrapJNIweakReference", + build_function_type (object_ptr_type_node, t), + 0, NOT_BUILT_IN, NULL, NULL_TREE); + t = tree_cons (NULL_TREE, int_type_node, tree_cons (NULL_TREE, int_type_node, endlink)); soft_idiv_node @@ -1197,6 +1132,7 @@ java_init_decl_processing (void) eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS ? "__gcj_personality_sj0" : "__gcj_personality_v0"); + default_init_unwind_resume_libfunc (); lang_eh_runtime_type = do_nothing; @@ -1230,7 +1166,7 @@ lookup_name (tree name) } /* Similar to `lookup_name' but look only at current binding level and - the previous one if its the parameter level. */ + the previous one if it's the parameter level. */ static tree lookup_name_current_level (tree name) @@ -1309,7 +1245,7 @@ pushdecl (tree x) /* error_mark_node is 0 for a while during initialization! */ { t = 0; - error ("%J'%D' used prior to declaration", x, x); + error ("%q+D used prior to declaration", x); } /* If we're naming a hitherto-unnamed type, set its TYPE_NAME @@ -1681,12 +1617,12 @@ poplevel (int keep, int reverse, int functionbody) if (DECL_INITIAL (label) == 0) { - error ("%Jlabel '%D' used but not defined", label, label); + error ("label %q+D used but not defined", label); /* Avoid crashing later. */ define_label (input_location, DECL_NAME (label)); } else if (warn_unused[UNUSED_LABEL] && !TREE_USED (label)) - warning (0, "%Jlabel '%D' defined but not used", label, label); + warning (0, "label %q+D defined but not used", label); IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0; /* Put the labels into the "variables" of the @@ -1763,8 +1699,10 @@ maybe_pushlevels (int pc) truncating variable lifetimes. */ if (end_pc > current_binding_level->end_pc) { + tree t; end_pc = current_binding_level->end_pc; - DECL_LOCAL_END_PC (decl) = end_pc; + for (t = decl; t != NULL_TREE; t = TREE_CHAIN (t)) + DECL_LOCAL_END_PC (t) = end_pc; } maybe_start_try (pc, end_pc); @@ -1776,10 +1714,17 @@ maybe_pushlevels (int pc) current_binding_level->names = NULL; for ( ; decl != NULL_TREE; decl = next) { + int index = DECL_LOCAL_SLOT_NUMBER (decl); + tree base_decl; next = TREE_CHAIN (decl); - push_jvm_slot (DECL_LOCAL_SLOT_NUMBER (decl), decl); + push_jvm_slot (index, decl); pushdecl (decl); - initialize_local_variable (decl, DECL_LOCAL_SLOT_NUMBER (decl)); + base_decl + = find_local_variable (index, TREE_TYPE (decl), pc); + if (TREE_CODE (TREE_TYPE (base_decl)) == POINTER_TYPE) + base_decl = TREE_VEC_ELT (base_decl_map, index); + SET_DECL_VALUE_EXPR (decl, base_decl); + DECL_HAS_VALUE_EXPR_P (decl) = 1; } } @@ -1814,8 +1759,8 @@ force_poplevels (int start_pc) while (current_binding_level->start_pc > start_pc) { if (pedantic && current_binding_level->start_pc > start_pc) - warning (0, "%JIn %D: overlapped variable and exception ranges at %d", - current_function_decl, current_function_decl, + warning (0, "In %+D: overlapped variable and exception ranges at %d", + current_function_decl, current_binding_level->start_pc); poplevel (1, 0, 0); } @@ -1886,8 +1831,8 @@ give_name_to_locals (JCF *jcf) tree decl = build_decl (VAR_DECL, name, type); if (end_pc > DECL_CODE_LENGTH (current_function_decl)) { - warning (0, "%Jbad PC range for debug info for local '%D'", - decl, decl); + warning (0, "bad PC range for debug info for local %q+D", + decl); end_pc = DECL_CODE_LENGTH (current_function_decl); } @@ -1994,8 +1939,7 @@ start_java_method (tree fndecl) { tree parm_name = NULL_TREE, parm_decl; tree parm_type = TREE_VALUE (tem); - if (i >= DECL_MAX_LOCALS (fndecl)) - abort (); + gcc_assert (i < DECL_MAX_LOCALS (fndecl)); parm_decl = build_decl (PARM_DECL, parm_name, parm_type); DECL_CONTEXT (parm_decl) = fndecl; @@ -2056,7 +2000,6 @@ end_java_method (void) attach_init_test_initialization_flags, block_body); } - flag_unit_at_a_time = 0; finish_method (fndecl); if (! flag_unit_at_a_time) @@ -2164,7 +2107,7 @@ java_mark_decl_local (tree decl) static void java_mark_cni_decl_local (tree decl) { - /* Setting DECL_LOCAL_CNI_METHOD_P changes the behaviour of the mangler. + /* Setting DECL_LOCAL_CNI_METHOD_P changes the behavior of the mangler. We expect that we should not yet have referenced this decl in a context that requires it. Check this invariant even if we don't have support for hidden aliases. */ @@ -2178,7 +2121,7 @@ java_mark_cni_decl_local (tree decl) DECL_LOCAL_CNI_METHOD_P (decl) = 1; } -/* Use the preceeding two functions and mark all members of the class. */ +/* Use the preceding two functions and mark all members of the class. */ void java_mark_class_local (tree class) @@ -2217,18 +2160,36 @@ add_stmt_to_compound (tree existing, tree type, tree stmt) return stmt; } -/* Add a statement to the compound_expr currently being - constructed. */ +/* Add a statement to the statement_list currently being constructed. + If the statement_list is null, we don't create a singleton list. + This is necessary because poplevel() assumes that adding a + statement to a null statement_list returns the statement. */ tree -java_add_stmt (tree stmt) +java_add_stmt (tree new_stmt) { + tree stmts = current_binding_level->stmts; + tree_stmt_iterator i; + if (input_filename) - SET_EXPR_LOCATION (stmt, input_location); + SET_EXPR_LOCATION (new_stmt, input_location); - return current_binding_level->stmts - = add_stmt_to_compound (current_binding_level->stmts, - TREE_TYPE (stmt), stmt); + if (stmts == NULL) + return current_binding_level->stmts = new_stmt; + + /* Force STMTS to be a statement_list. */ + if (TREE_CODE (stmts) != STATEMENT_LIST) + { + tree t = make_node (STATEMENT_LIST); + i = tsi_last (t); + tsi_link_after (&i, stmts, TSI_CONTINUE_LINKING); + stmts = t; + } + + i = tsi_last (stmts); + tsi_link_after (&i, new_stmt, TSI_CONTINUE_LINKING); + + return current_binding_level->stmts = stmts; } /* Add a variable to the current scope. */ @@ -2262,8 +2223,7 @@ get_stmts (void) void register_exception_range (struct eh_range *range, int pc, int end_pc) { - if (current_binding_level->exception_range) - abort (); + gcc_assert (! current_binding_level->exception_range); current_binding_level->exception_range = range; current_binding_level->end_pc = end_pc; current_binding_level->start_pc = pc;