Commit fdec99c6 by Per Bothner

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
parent df1e6be5
......@@ -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))
{
......
......@@ -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));
......
......@@ -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)))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment