diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/java/ChangeLog | 28 | ||||
-rw-r--r-- | gcc/java/class.c | 3 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 4 | ||||
-rw-r--r-- | gcc/java/jcf-parse.c | 6 | ||||
-rw-r--r-- | gcc/java/jcf-write.c | 13 | ||||
-rw-r--r-- | gcc/java/parse.h | 35 | ||||
-rw-r--r-- | gcc/java/parse.y | 82 |
7 files changed, 134 insertions, 37 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index f8c3803..0a9465f 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,31 @@ +2000-08-10 Alexandre Petit-Bianco <apbianco@cygnus.com> + + * class.c (maybe_layout_super_class): Fixed indentation. + * java-tree.h (CLASS_METHOD_CHECKED_P): New macro. + (java_check_methods): New function declaration. + * jcf-parse.c (get_constant): Let `char_len' go up to 3. Use `str' + instead of `str_ptr'. + * jcf-write.c (generate_bytecode_insns): Emit number the of args + of a `invokeinterface' at the right time. + * parse.h (WFL_STRIP_BRACKET): New macro. + (SET_TYPE_FOR_RESOLUTION): Use it. + * parse.y (build_unresolved_array_type): Reuse `type_or_wfl.' + (check_class_interface_creation): Don't check for cross package + innerclass name clashes. + (method_header): Behave properly if MDECL is `error_mark_node.' + (method_declarator): Return `error_mark_node' if bogus current + class. + (resolve_class): Apply WFL_STRIP_BRACKET on `cl' if necessary. + (resolve_and_layout): New local `decl_type', set and used. Call + java_check_methods. + (java_check_methods): New method. + (java_layout_classes): Use it. + (resolve_qualified_expression_name): No EH check necessary in + access$<n>. + (java_complete_lhs): Use VAR_DECL's DECL_INITIAL when evaluating + `case' statement. + (patch_assignment): Set DECL_INITIAL on integral final local. + 2000-08-07 Alexandre Petit-Bianco <apbianco@cygnus.com * parse.y (build_dot_class_method_invocation): Changed parameter diff --git a/gcc/java/class.c b/gcc/java/class.c index 7cd6e66..625d820 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -1748,8 +1748,7 @@ maybe_layout_super_class (super_class, this_class) { if (TREE_CODE (super_class) == RECORD_TYPE) { - if (!CLASS_LOADED_P (super_class) - && CLASS_FROM_SOURCE_P (super_class)) + if (!CLASS_LOADED_P (super_class) && CLASS_FROM_SOURCE_P (super_class)) safe_layout_class (super_class); if (!CLASS_LOADED_P (super_class)) load_class (super_class, 1); diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 07a5521..7d2d74f 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -52,6 +52,7 @@ struct JCF; QUALIFIED_P (in IDENTIFIER_NODE) PRIMARY_P (in EXPR_WITH_FILE_LOCATION) MODIFY_EXPR_FROM_INITIALIZATION_P (in MODIFY_EXPR) + CLASS_METHOD_CHECKED_P (in RECORD_TYPE) 3: IS_AN_IMPORT_ON_DEMAND_P (in IDENTIFIER_NODE) RESOLVE_PACKAGE_NAME_P (in EXPR_WITH_FILE_LOCATION) SWITCH_HAS_DEFAULT (in SWITCH_EXPR) @@ -788,6 +789,7 @@ extern tree get_boehm_type_descriptor PARAMS ((tree)); extern unsigned long java_hash_hash_tree_node PARAMS ((hash_table_key)); extern boolean java_hash_compare_tree_node PARAMS ((hash_table_key, hash_table_key)); +extern void java_check_methods PARAMS ((tree)); /* We use ARGS_SIZE_RTX to indicate that gcc/expr.h has been included to declare `enum expand_modifier'. */ @@ -999,6 +1001,8 @@ extern tree *type_map; initialization during its declaration */ #define MODIFY_EXPR_FROM_INITIALIZATION_P(EXPR) TREE_LANG_FLAG_2 (EXPR) +#define CLASS_METHOD_CHECKED_P(EXPR) TREE_LANG_FLAG_2 (EXPR) + /* True if EXPR (a WFL in that case) resolves into an expression name */ #define RESOLVE_EXPRESSION_NAME_P(WFL) TREE_LANG_FLAG_0 (WFL) diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index 78bf521..1962f80 100644 --- a/gcc/java/jcf-parse.c +++ b/gcc/java/jcf-parse.c @@ -341,8 +341,8 @@ get_constant (jcf, index) for (str_len = 0; i > 0; str_len++) { int char_len = UT8_CHAR_LENGTH (*str); - if (char_len < 0 || char_len > 2 || char_len > i) - fatal ("bad string constant"); + if (char_len < 0 || char_len > 3 || char_len > i) + fatal ("bad string constant"); str += char_len; i -= char_len; } @@ -368,7 +368,7 @@ get_constant (jcf, index) char_value = (char_value << 6) | (*str++ & 0x3F); break; case 3: - char_value = *str_ptr++ & 0x0F; + char_value = *str++ & 0x0F; char_value = (char_value << 6) | (*str++ & 0x3F); char_value = (char_value << 6) | (*str++ & 0x3F); break; diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c index 538c1a2..df50fff 100644 --- a/gcc/java/jcf-write.c +++ b/gcc/java/jcf-write.c @@ -2561,9 +2561,13 @@ generate_bytecode_insns (exp, target, state) TREE_TYPE (TREE_TYPE (TREE_VALUE (TREE_OPERAND (exp, 1)))); } index = find_methodref_index (&state->cpool, f); - if (interface) - DECL_CONTEXT (f) = saved_context; OP2 (index); + if (interface) + { + DECL_CONTEXT (f) = saved_context; + OP1 (nargs); + OP1 (0); + } f = TREE_TYPE (TREE_TYPE (f)); if (TREE_CODE (f) != VOID_TYPE) { @@ -2573,11 +2577,6 @@ generate_bytecode_insns (exp, target, state) else NOTE_PUSH (size); } - if (interface) - { - OP1 (nargs); - OP1 (0); - } break; } } diff --git a/gcc/java/parse.h b/gcc/java/parse.h index 50a9e3e..8071237 100644 --- a/gcc/java/parse.h +++ b/gcc/java/parse.h @@ -535,27 +535,50 @@ typedef struct _jdeplist { java.lang.Object. */ #define SET_TYPE_FOR_RESOLUTION(TYPE, SAVE, CHAIN) \ { \ - tree returned_type; \ + tree _returned_type; \ (CHAIN) = 0; \ if (TREE_TYPE (GET_CPC ()) == object_type_node \ - && TREE_CODE (TYPE) == EXPR_WITH_FILE_LOCATION \ + && TREE_CODE (TYPE) == EXPR_WITH_FILE_LOCATION \ && EXPR_WFL_NODE (TYPE) == unqualified_object_id_node) \ (TYPE) = object_type_node; \ else \ { \ - if (unresolved_type_p (type, &returned_type)) \ + if (unresolved_type_p (type, &_returned_type)) \ { \ - if (returned_type) \ - (TYPE) = returned_type; \ + if (_returned_type) \ + (TYPE) = _returned_type; \ else \ { \ - (SAVE) = (TYPE); \ + tree _type; \ + WFL_STRIP_BRACKET (_type, TYPE); \ + (SAVE) = (_type); \ (TYPE) = obtain_incomplete_type (TYPE); \ CHAIN = 1; \ } \ } \ } \ } + +#define WFL_STRIP_BRACKET(TARGET, TYPE) \ +{ \ + tree __type = (TYPE); \ + if (TYPE && TREE_CODE (TYPE) == EXPR_WITH_FILE_LOCATION) \ + { \ + tree _node = EXPR_WFL_NODE (TYPE); \ + const char *_ptr = IDENTIFIER_POINTER (_node); \ + const char *_ref = _ptr; \ + while (_ptr[0] == '[') \ + _ptr++; \ + if (_ref != _ptr) \ + { \ + tree _new = copy_node (TYPE); \ + EXPR_WFL_NODE (_new) = get_identifier (_ptr); \ + __type = _new; \ + } \ + } \ + (TARGET) = __type; \ +} + /* Promote a type if it won't be registered as a patch */ #define PROMOTE_RECORD_IF_COMPLETE(TYPE, IS_INCOMPLETE) \ { \ diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 6842979..56edc6c 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -3265,10 +3265,8 @@ build_unresolved_array_type (type_or_wfl) IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)), IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl))); ptr = obstack_finish (&temporary_obstack); - return build_expr_wfl (get_identifier (ptr), - EXPR_WFL_FILENAME (type_or_wfl), - EXPR_WFL_LINENO (type_or_wfl), - EXPR_WFL_COLNO (type_or_wfl)); + EXPR_WFL_NODE (type_or_wfl) = get_identifier (ptr); + return type_or_wfl; } static void @@ -3303,7 +3301,8 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d - Can't be imported by a single type import - Can't already exists in the package */ if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name) - && (node = find_name_in_single_imports (raw_name))) + && (node = find_name_in_single_imports (raw_name)) + && !CPC_INNER_P ()) { parse_error_context (cl, "%s name `%s' clashes with imported type `%s'", @@ -4260,14 +4259,18 @@ method_header (flags, type, mdecl, throws) int flags; tree type, mdecl, throws; { - tree meth = TREE_VALUE (mdecl); - tree id = TREE_PURPOSE (mdecl); tree type_wfl = NULL_TREE; tree meth_name = NULL_TREE; tree current, orig_arg, this_class = NULL; + tree id, meth; int saved_lineno; int constructor_ok = 0, must_chain; int count; + + if (mdecl == error_mark_node) + return error_mark_node; + meth = TREE_VALUE (mdecl); + id = TREE_PURPOSE (mdecl); check_modifiers_consistency (flags); @@ -4665,6 +4668,9 @@ method_declarator (id, list) patch_stage = JDEP_NO_PATCH; + if (GET_CPC () == error_mark_node) + return error_mark_node; + /* If we're dealing with an inner class constructor, we hide the this$<n> decl in the name field of its parameter declaration. We also might have to hide the outer context local alias @@ -5391,7 +5397,10 @@ resolve_class (enclosing, class_type, decl, cl) while (name[0] == '[') name++; if (base != name) - TYPE_NAME (class_type) = get_identifier (name); + { + TYPE_NAME (class_type) = get_identifier (name); + WFL_STRIP_BRACKET (cl, cl); + } /* 2- Resolve the bare type */ if (!(resolved_type_decl = do_resolve_class (enclosing, class_type, @@ -5562,7 +5571,7 @@ resolve_and_layout (something, cl) tree something; tree cl; { - tree decl; + tree decl, decl_type; /* Don't do that on the current class */ if (something == current_class) @@ -5605,13 +5614,14 @@ resolve_and_layout (something, cl) return NULL_TREE; /* Resolve and layout if necessary */ - layout_class_methods (TREE_TYPE (decl)); - /* Check methods, but only once */ - if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) - && !CLASS_LOADED_P (TREE_TYPE (decl))) - CHECK_METHODS (decl); - if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl))) - safe_layout_class (TREE_TYPE (decl)); + decl_type = TREE_TYPE (decl); + layout_class_methods (decl_type); + /* Check methods */ + if (CLASS_FROM_SOURCE_P (decl_type)) + java_check_methods (decl); + /* Layout the type if necessary */ + if (decl_type != current_class && !CLASS_LOADED_P (decl_type)) + safe_layout_class (decl_type); return decl; } @@ -5957,6 +5967,23 @@ check_method_types_complete (decl) return 1; } +/* Visible interface to check methods contained in CLASS_DECL */ + +void +java_check_methods (class_decl) + tree class_decl; +{ + if (CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl))) + return; + + if (CLASS_INTERFACE (class_decl)) + java_check_abstract_methods (class_decl); + else + java_check_regular_methods (class_decl); + + CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)) = 1; +} + /* Check all the methods of CLASS_DECL. Methods are first completed then checked according to regular method existance rules. If no constructor for CLASS_DECL were encountered, then build its @@ -7288,7 +7315,7 @@ java_layout_classes () /* Then check the methods of all parsed classes */ for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current)) if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current)))) - CHECK_METHODS (TREE_VALUE (current)); + java_check_methods (TREE_VALUE (current)); java_parse_abort_on_error (); for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current)) @@ -8951,8 +8978,10 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found) instantiation using a primary qualified by a `new' */ RESTORE_THIS_AND_CURRENT_CLASS; - /* EH check */ - if (location) + /* EH check. No check on access$<n> functions */ + if (location + && !OUTER_FIELD_ACCESS_IDENTIFIER_P + (DECL_NAME (current_function_decl))) check_thrown_exceptions (location, ret_decl); /* If the previous call was static and this one is too, @@ -10988,6 +11017,8 @@ java_complete_lhs (node) /* Multiple instance of a case label bearing the same value is checked during code generation. The case expression is allright so far. */ + if (TREE_CODE (cn) == VAR_DECL) + cn = DECL_INITIAL (cn); TREE_OPERAND (node, 0) = cn; TREE_TYPE (node) = void_type_node; CAN_COMPLETE_NORMALLY (node) = 1; @@ -12037,6 +12068,19 @@ patch_assignment (node, wfl_op1, wfl_op2) } } + /* Final locals can be used as case values in switch + statement. Prepare them for this eventuality. */ + if (TREE_CODE (lvalue) == VAR_DECL + && LOCAL_FINAL (lvalue) + && TREE_CONSTANT (new_rhs) + && IDENTIFIER_LOCAL_VALUE (DECL_NAME (lvalue)) + && JINTEGRAL_TYPE_P (TREE_TYPE (lvalue)) + ) + { + TREE_CONSTANT (lvalue) = 1; + DECL_INITIAL (lvalue) = new_rhs; + } + TREE_OPERAND (node, 0) = lvalue; TREE_OPERAND (node, 1) = new_rhs; TREE_TYPE (node) = lhs_type; |