diff options
author | Per Bothner <bothner@gcc.gnu.org> | 1998-12-12 11:25:01 -0800 |
---|---|---|
committer | Per Bothner <bothner@gcc.gnu.org> | 1998-12-12 11:25:01 -0800 |
commit | fdec99c620f7f3eed47df81498b303cfc2e58f49 (patch) | |
tree | dfc11d7c104023d713f597a70153320b359eaed2 /gcc | |
parent | df1e6be5cc6dd6f008825fcf3076c7a84f7cb3d4 (diff) | |
download | gcc-fdec99c620f7f3eed47df81498b303cfc2e58f49.zip gcc-fdec99c620f7f3eed47df81498b303cfc2e58f49.tar.gz gcc-fdec99c620f7f3eed47df81498b303cfc2e58f49.tar.bz2 |
expr.c (encode_newarray_type, [...]): New functions.
d
* expr.c (encode_newarray_type, build_new_array): New functions.
* java-tree.h: Declare build_new_array.
* jcf-write.c (patch_newarray): Use build_new_array.
* expr.c (java_lang_expand_exp): Support NEW_ARRAY_INIT.
* jcf-write.c (generate_bytecode_insns): Support NEW_ARRAY_INIT.
* parse.y (patch_new_array_init): Re-organize.
Now is passed the actual array (pointer) type of the value.
Set the type of the CONSTRUCTOR to be an ARRAY_TYPE.
(patch_array_constructor): Removed - merged into patch_new_array_init.
(java_complete_tree): Update patch_new_array_init.
* jcf-write.c (find_constant_index): New function.
(generate_bytecode_insns): Use find_constant_index.
(generate_classfile): Use find_constant_index for ConstantValue.
From-SVN: r24273
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/java/expr.c | 74 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 1 | ||||
-rw-r--r-- | gcc/java/parse.y | 121 |
3 files changed, 109 insertions, 87 deletions
diff --git a/gcc/java/expr.c b/gcc/java/expr.c index 8e4c468..aa1b652 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -532,6 +532,32 @@ decode_newarray_type (int atype) } } +/* Map primitive type to the code used by OPCODE_newarray. */ + +int +encode_newarray_type (type) + tree type; +{ + if (type == boolean_type_node) + return 4; + else if (type == char_type_node) + return 5; + else if (type == float_type_node) + return 6; + else if (type == double_type_node) + return 7; + else if (type == byte_type_node) + return 8; + else if (type == short_type_node) + return 9; + else if (type == int_type_node) + return 10; + else if (type == long_type_node) + return 11; + else + fatal ("Can't compute type code - patch_newarray"); +} + /* Build a call to _Jv_ThrowBadArrayIndex(), the ArrayIndexOfBoundsException exception handler. */ @@ -707,7 +733,7 @@ build_newarray (atype_value, length) /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size of the dimension. */ -/* Merge with build_newarray. FIXME. */ + tree build_anewarray (class_type, length) tree class_type; @@ -726,6 +752,19 @@ build_anewarray (class_type, length) NULL_TREE); } +/* Return a node the evaluates 'new TYPE[LENGTH]'. */ + +tree +build_new_array (type, length) + tree type; + tree length; +{ + if (JPRIMITIVE_TYPE_P (type)) + return build_newarray (encode_newarray_type (type), length); + else + return build_anewarray (TREE_TYPE (type), length); +} + /* Generates a call to _Jv_NewMultiArray. multianewarray expects a class pointer, a number of dimensions and the matching number of dimensions. The argument list is NULL terminated. */ @@ -1717,6 +1756,39 @@ java_lang_expand_expr (exp, target, tmode, modifier) switch (TREE_CODE (exp)) { + case NEW_ARRAY_INIT: + { + rtx tmp, elements; + tree array_type = TREE_TYPE (TREE_TYPE (exp)); + tree element_type = TYPE_ARRAY_ELEMENT (array_type); + tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type))); + HOST_WIDE_INT ilength = java_array_type_length (array_type); + tree length = build_int_2 (ilength, 0); + tree init = TREE_OPERAND (exp, 0); + tree array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp)); + expand_decl (array_decl); + tmp = expand_assignment (array_decl, + build_new_array (element_type, length), + 1, 0); + if (TREE_CONSTANT (init) + && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type)) + { + tree init_decl = build_decl (VAR_DECL, generate_name (), + TREE_TYPE (init)); + pushdecl_top_level (init_decl); + TREE_STATIC (init_decl) = 1; + DECL_INITIAL (init_decl) = init; + DECL_IGNORED_P (init_decl) = 1; + TREE_READONLY (init_decl) = 1; + make_decl_rtl (init_decl, NULL, 1); + init = init_decl; + } + expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld), + build1 (INDIRECT_REF, array_type, array_decl), + data_fld), + init, 0, 0); + return tmp; + } case BLOCK: if (BLOCK_EXPR_BODY (exp)) { diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index a81295e..f220a46 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -538,6 +538,7 @@ extern tree binary_numeric_promotion PROTO ((tree, tree, tree *, tree *)); extern tree build_java_arrayaccess PROTO ((tree, tree, tree)); extern tree build_newarray PROTO ((int, tree)); extern tree build_anewarray PROTO ((tree, tree)); +extern tree build_new_array PROTO ((tree, tree)); extern tree build_java_array_length_access PROTO ((tree)); extern tree build_java_arraynull_check PROTO ((tree, tree, tree)); extern tree create_label_decl PROTO ((tree)); diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 622aee1..1e0f0f4 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -234,7 +234,6 @@ static tree find_expr_with_wfl PROTO ((tree)); static void missing_return_error PROTO ((tree)); static tree build_new_array_init PROTO ((int, tree)); static tree patch_new_array_init PROTO ((tree, tree)); -static tree patch_array_constructor PROTO ((tree, tree)); static tree maybe_build_array_element_wfl PROTO ((tree)); static int array_constructor_check_entry PROTO ((tree, tree)); static char *purify_type_name PROTO ((char *)); @@ -7733,7 +7732,7 @@ java_complete_tree (node) /* If we're about to patch a NEW_ARRAY_INIT, we call a special function to complete this RHS */ if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT) - nn = patch_new_array_init (GET_SKIP_TYPE (TREE_OPERAND (node, 0)), + nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)), TREE_OPERAND (node, 1)); else nn = java_complete_tree (TREE_OPERAND (node, 1)); @@ -9679,33 +9678,7 @@ patch_newarray (node) of dimension is equal to 1, then the nature of the base type (primitive or not) matters. */ if (ndims == 1) - { - if (JPRIMITIVE_TYPE_P (type)) - { - int type_code; - if (type == boolean_type_node) - type_code = 4; - else if (type == char_type_node) - type_code = 5; - else if (type == float_type_node) - type_code = 6; - else if (type == double_type_node) - type_code = 7; - else if (type == byte_type_node) - type_code = 8; - else if (type == short_type_node) - type_code = 9; - else if (type == int_type_node) - type_code = 10; - else if (type == long_type_node) - type_code = 11; - else - fatal ("Can't compute type code - patch_newarray"); - return build_newarray (type_code, TREE_VALUE (dims)); - } - else - return build_anewarray (TREE_TYPE (type), TREE_VALUE (dims)); - } + return build_new_array (type, TREE_VALUE (dims)); /* Can't reuse what's already written in expr.c because it uses the JVM stack representation. Provide a build_multianewarray. FIXME */ @@ -9756,58 +9729,42 @@ static tree patch_new_array_init (type, node) tree type, node; { - TREE_OPERAND (node, 0) = - patch_array_constructor (type, TREE_OPERAND (node, 0)); - - if (TREE_OPERAND (node, 0) == error_mark_node) - return error_mark_node; - - TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0)); - return node; -} - -/* Choose to walk further NEW_ARRAY_INIT or check array assignment - when reaching the leaves of the initializing expression. Report - error_mark_node if errors were encountered, otherwise return NODE - after having set it type. */ - -static tree -patch_array_constructor (type, node) - tree type, node; -{ int error_seen = 0; - tree current, lhs_type; + tree current, element_type; HOST_WIDE_INT length; + int all_constant = 1; + tree init = TREE_OPERAND (node, 0); - CONSTRUCTOR_ELTS (node) = nreverse (CONSTRUCTOR_ELTS (node)); - lhs_type = GET_SKIP_TYPE (type); + if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type))) + { + parse_error_context (node, + "Invalid array initializer for non-array type `%s'", + lang_printable_name (type, 1)); + return error_mark_node; + } + type = TREE_TYPE (type); + element_type = TYPE_ARRAY_ELEMENT (type); - if (TYPE_ARRAY_P (lhs_type)) + CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init)); + + for (length = 0, current = CONSTRUCTOR_ELTS (init); + current; length++, current = TREE_CHAIN (current)) { - /* Verify that we have what we expect here. This points a - discrepancy between the annouced type and the specified - one. */ - for (length = 0, current = CONSTRUCTOR_ELTS (node); - current; length++, current = TREE_CHAIN (current)) + tree elt = TREE_VALUE (current); + if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT) { - tree elt = TREE_VALUE (current); - if (elt && TREE_CODE (elt) == NEW_ARRAY_INIT) - TREE_VALUE (current) = patch_new_array_init (lhs_type, elt); - /* We're under dimensioned: we want to have elements - examined. */ - else - error_seen |= array_constructor_check_entry (lhs_type, current); - if ((elt && TREE_VALUE (elt) == error_mark_node) || error_seen) - error_seen = 1; + error_seen |= array_constructor_check_entry (element_type, current); + if (! TREE_CONSTANT (TREE_VALUE (current))) + all_constant = 0; } - } - else - { - /* This is the list of the values that need to be affected. We - browse the list and check for a valid assignment */ - for (length = 0, current = CONSTRUCTOR_ELTS (node); - current; length++, current = TREE_CHAIN (current)) - error_seen |= array_constructor_check_entry (lhs_type, current); + else + { + TREE_VALUE (current) = patch_new_array_init (element_type, elt); + TREE_PURPOSE (current) = NULL_TREE; + all_constant = 0; + } + if (elt && TREE_VALUE (elt) == error_mark_node) + error_seen = 1; } if (error_seen) @@ -9816,7 +9773,10 @@ patch_array_constructor (type, node) /* Create a new type. We can't reuse the one we have here by patching its dimension because it originally is of dimension -1 hence reused by gcc. This would prevent triangular arrays. */ - TREE_TYPE (node) = promote_type (build_java_array_type (lhs_type, length)); + type = build_java_array_type (element_type, length); + TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type)))); + TREE_TYPE (node) = promote_type (type); + TREE_CONSTANT (init) = all_constant; return node; } @@ -9835,17 +9795,6 @@ array_constructor_check_entry (type, entry) new_value = NULL_TREE; wfl_value = TREE_VALUE (entry); - /* If we have a TREE_LIST here, it means that we're specifying more - dimensions that we should. Report errors within the list. */ - if (TREE_CODE (wfl_value) == NEW_ARRAY_INIT) - { - if (TREE_CODE (wfl_value) == NEW_ARRAY_INIT) - EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (wfl_value); - parse_error_context (wfl_operator, "Invalid initializer for type `%s'", - lang_printable_name (type, 1)); - return 1; - } - value = java_complete_tree (TREE_VALUE (entry)); /* patch_string return error_mark_node if arg is error_mark_node */ if ((patched = patch_string (value))) |