expr.c (encode_newarray_type, [...]): New functions.
authorPer Bothner <bothner@gcc.gnu.org>
Sat, 12 Dec 1998 19:25:01 +0000 (11:25 -0800)
committerPer Bothner <bothner@gcc.gnu.org>
Sat, 12 Dec 1998 19:25:01 +0000 (11:25 -0800)
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

gcc/java/expr.c
gcc/java/java-tree.h
gcc/java/parse.y

index 8e4c46870fe6c3324d840b5c7f4f3bc59d2639df..aa1b652341c4005701817f54ec4f3ad4f0a8d0b8 100644 (file)
@@ -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))
        {
index a81295eb682fe3ada9736986ec474862e7a59fa4..f220a465fa2c6f57c1a7e8da8c9cb5ac151f7fb7 100644 (file)
@@ -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));
index 622aee1489ef93efdb291aea4be55bf33ad8ac1e..1e0f0f4d938ea9de79f5e8e0d857c7a34204269e 100644 (file)
@@ -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 */
@@ -9755,59 +9728,43 @@ build_new_array_init (location, values)
 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)))