OSDN Git Service

contrib/
[pf3gnuchains/gcc-fork.git] / gcc / java / decl.c
index 21488ff..d249157 100644 (file)
@@ -1,13 +1,13 @@
 /* Process declarations and variables for the GNU compiler for the
    Java(TM) language.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007,
+   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -16,9 +16,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.
 
 Java and all Java-based marks are trademarks or registered trademarks
 of Sun Microsystems, Inc. in the United States and other countries.
@@ -48,6 +47,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "tree-inline.h"
 #include "target.h"
 #include "version.h"
+#include "tree-iterator.h"
+#include "langhooks.h"
 
 #if defined (DEBUG_JAVA_BINDING_LEVELS)
 extern void indent (void);
@@ -73,9 +74,9 @@ static void parse_version (void);
                                          loader.  */
 
 /* If an ABI change is made within a GCC release series, rendering current
-   binaries incompatible with the old runtimes, this number can be set to
+   binaries incompatible with the old runtimes, this number must be set to
    enforce the compatibility rules. */
-#define MINOR_BINARYCOMPAT_ABI_VERSION 0
+#define MINOR_BINARYCOMPAT_ABI_VERSION 1
 
 /* The runtime may recognize a variety of BC ABIs (objects generated by 
    different version of gcj), but will probably always require strict 
@@ -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);
 
@@ -510,18 +426,6 @@ static const struct binding_level clear_binding_level
     0, /* binding_depth */
   };
 
-#if 0
-/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
-   that have names.  Here so we can clear out their names' definitions
-   at the end of the function.  */
-
-static tree named_labels;
-
-/* A list of LABEL_DECLs from outer contexts that are currently shadowed.  */
-
-static tree shadowed_labels;
-#endif
-
 tree java_global_trees[JTI_MAX];
   
 /* Build (and pushdecl) a "promoted type" for all standard
@@ -543,39 +447,12 @@ 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;
 }
 
-/* Return a definition for a builtin function named NAME and whose data type
-   is TYPE.  TYPE should be a function type with argument types.
-   FUNCTION_CODE tells later passes how to compile calls to this function.
-   See tree.h for its possible values.
-
-   If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
-   the name to be called if we can't opencode the function.  If
-   ATTRS is nonzero, use that for the function's attribute list.  */
-
-tree
-builtin_function (const char *name,
-                 tree type,
-                 int function_code,
-                 enum built_in_class cl,
-                 const char *library_name,
-                 tree ARG_UNUSED (attrs))
-{
-  tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
-  DECL_EXTERNAL (decl) = 1;
-  TREE_PUBLIC (decl) = 1;
-  if (library_name)
-    SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
-  pushdecl (decl);
-  DECL_BUILT_IN_CLASS (decl) = cl;
-  DECL_FUNCTION_CODE (decl) = function_code;
-  return decl;
-}
-
 /* Return tree that represents a vtable for a primitive array.  */
 static tree
 create_primitive_vtable (const char *name)
@@ -735,15 +612,8 @@ java_init_decl_processing (void)
 
   null_pointer_node = build_int_cst (ptr_type_node, 0);
 
-#if 0
-  /* Make a type to be the domain of a few array types
-     whose domains don't really matter.
-     200 is small enough that it always fits in size_t
-     and large enough that it can hold most function names for the
-     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));
@@ -864,16 +734,9 @@ java_init_decl_processing (void)
   TYPE_identifier_node = get_identifier ("TYPE");
   init_identifier_node = get_identifier ("<init>");
   clinit_identifier_node = get_identifier ("<clinit>");
-  finit_identifier_node = get_identifier ("finit$");
-  instinit_identifier_node = get_identifier ("instinit$");
   void_signature_node = get_identifier ("()V");
-  length_identifier_node = get_identifier ("length");
   finalize_identifier_node = get_identifier ("finalize");
   this_identifier_node = get_identifier ("this");
-  super_identifier_node = get_identifier ("super");
-  continue_identifier_node = get_identifier ("continue");
-  access0_identifier_node = get_identifier ("access$0");
-  classdollar_identifier_node = get_identifier ("class$");
 
   java_lang_cloneable_identifier_node = get_identifier ("java.lang.Cloneable");
   java_io_serializable_identifier_node =
@@ -886,6 +749,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 +791,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);
@@ -961,6 +826,7 @@ java_init_decl_processing (void)
   PUSH_FIELD (class_type_node, field, "chain", ptr_type_node);
   PUSH_FIELD (class_type_node, field, "aux_info", ptr_type_node);
   PUSH_FIELD (class_type_node, field, "engine", ptr_type_node);
+  PUSH_FIELD (class_type_node, field, "reflection_data", ptr_type_node);
   for (t = TYPE_FIELDS (class_type_node);  t != NULL_TREE;  t = TREE_CHAIN (t))
     FIELD_PRIVATE (t) = 1;
   push_super_field (class_type_node, object_type_node);
@@ -971,9 +837,6 @@ java_init_decl_processing (void)
   field_info_union_node = make_node (UNION_TYPE);
   PUSH_FIELD (field_info_union_node, field, "boffset", int_type_node);
   PUSH_FIELD (field_info_union_node, field, "addr", ptr_type_node);
-#if 0
-  PUSH_FIELD (field_info_union_node, field, "idx", unsigned_short_type_node);
-#endif
   layout_type (field_info_union_node);
 
   PUSH_FIELD (field_type_node, field, "name", utf8const_ptr_type);
@@ -1022,50 +885,50 @@ java_init_decl_processing (void)
   endlink = end_params_node = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
 
   t = tree_cons (NULL_TREE, class_ptr_type, endlink);
-  alloc_object_node = builtin_function ("_Jv_AllocObject",
-                                       build_function_type (ptr_type_node, t),
-                                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+  alloc_object_node = add_builtin_function ("_Jv_AllocObject",
+                                           build_function_type (ptr_type_node, t),
+                                           0, NOT_BUILT_IN, NULL, NULL_TREE);
   DECL_IS_MALLOC (alloc_object_node) = 1;
-  alloc_no_finalizer_node = 
-    builtin_function ("_Jv_AllocObjectNoFinalizer",
-                     build_function_type (ptr_type_node, t),
-                     0, NOT_BUILT_IN, NULL, NULL_TREE);
+  alloc_no_finalizer_node =
+    add_builtin_function ("_Jv_AllocObjectNoFinalizer",
+                         build_function_type (ptr_type_node, t),
+                         0, NOT_BUILT_IN, NULL, NULL_TREE);
   DECL_IS_MALLOC (alloc_no_finalizer_node) = 1;
 
   t = tree_cons (NULL_TREE, ptr_type_node, endlink);
-  soft_initclass_node = builtin_function ("_Jv_InitClass",
-                                         build_function_type (void_type_node,
-                                                              t),
-                                         0, NOT_BUILT_IN, NULL, NULL_TREE);
+  soft_initclass_node = add_builtin_function ("_Jv_InitClass",
+                                             build_function_type (void_type_node,
+                                                                  t),
+                                             0, NOT_BUILT_IN, NULL, NULL_TREE);
   t = tree_cons (NULL_TREE, class_ptr_type,
                 tree_cons (NULL_TREE, int_type_node, endlink));
-  soft_resolvepoolentry_node 
-    = builtin_function ("_Jv_ResolvePoolEntry", 
-                       build_function_type (ptr_type_node, t),
-                       0,NOT_BUILT_IN, NULL, NULL_TREE);
-  DECL_IS_PURE (soft_resolvepoolentry_node) = 1;
-  throw_node = builtin_function ("_Jv_Throw",
-                                build_function_type (void_type_node, t),
-                                0, NOT_BUILT_IN, NULL, NULL_TREE);
+  soft_resolvepoolentry_node
+    = add_builtin_function ("_Jv_ResolvePoolEntry",
+                           build_function_type (ptr_type_node, t),
+                           0,NOT_BUILT_IN, NULL, NULL_TREE);
+  DECL_PURE_P (soft_resolvepoolentry_node) = 1;
+  throw_node = add_builtin_function ("_Jv_Throw",
+                                    build_function_type (void_type_node, t),
+                                    0, NOT_BUILT_IN, NULL, NULL_TREE);
   /* Mark throw_nodes as `noreturn' functions with side effects.  */
   TREE_THIS_VOLATILE (throw_node) = 1;
   TREE_SIDE_EFFECTS (throw_node) = 1;
 
   t = build_function_type (void_type_node, tree_cons (NULL_TREE, ptr_type_node,
                                                      endlink));
-  soft_monitorenter_node 
-    = builtin_function ("_Jv_MonitorEnter", t, 0, NOT_BUILT_IN,
-                       NULL, NULL_TREE);
-  soft_monitorexit_node 
-    = builtin_function ("_Jv_MonitorExit", t, 0, NOT_BUILT_IN,
-                       NULL, NULL_TREE);
-
-  t = tree_cons (NULL_TREE, ptr_type_node, 
+  soft_monitorenter_node
+    = add_builtin_function ("_Jv_MonitorEnter", t, 0, NOT_BUILT_IN,
+                           NULL, NULL_TREE);
+  soft_monitorexit_node
+    = add_builtin_function ("_Jv_MonitorExit", t, 0, NOT_BUILT_IN,
+                           NULL, NULL_TREE);
+
+  t = tree_cons (NULL_TREE, ptr_type_node,
                 tree_cons (NULL_TREE, int_type_node, endlink));
   soft_newarray_node
-      = builtin_function ("_Jv_NewPrimArray",
-                         build_function_type (ptr_type_node, t),
-                         0, NOT_BUILT_IN, NULL, NULL_TREE);
+      = add_builtin_function ("_Jv_NewPrimArray",
+                             build_function_type (ptr_type_node, t),
+                             0, NOT_BUILT_IN, NULL, NULL_TREE);
   DECL_IS_MALLOC (soft_newarray_node) = 1;
 
   t = tree_cons (NULL_TREE, int_type_node,
@@ -1073,9 +936,9 @@ java_init_decl_processing (void)
                            tree_cons (NULL_TREE, object_ptr_type_node,
                                       endlink)));
   soft_anewarray_node
-      = builtin_function ("_Jv_NewObjectArray",
-                         build_function_type (ptr_type_node, t),
-                         0, NOT_BUILT_IN, NULL, NULL_TREE);
+      = add_builtin_function ("_Jv_NewObjectArray",
+                             build_function_type (ptr_type_node, t),
+                             0, NOT_BUILT_IN, NULL, NULL_TREE);
   DECL_IS_MALLOC (soft_anewarray_node) = 1;
 
   /* There is no endlink here because _Jv_NewMultiArray is a varargs
@@ -1083,137 +946,144 @@ java_init_decl_processing (void)
   t = tree_cons (NULL_TREE, ptr_type_node,
                 tree_cons (NULL_TREE, int_type_node, NULL_TREE));
   soft_multianewarray_node
-      = builtin_function ("_Jv_NewMultiArray",
-                         build_function_type (ptr_type_node, t),
-                         0, NOT_BUILT_IN, NULL, NULL_TREE);
+      = add_builtin_function ("_Jv_NewMultiArray",
+                             build_function_type (ptr_type_node, t),
+                             0, NOT_BUILT_IN, NULL, NULL_TREE);
   DECL_IS_MALLOC (soft_multianewarray_node) = 1;
 
   t = build_function_type (void_type_node, 
                           tree_cons (NULL_TREE, int_type_node, endlink));
   soft_badarrayindex_node
-      = builtin_function ("_Jv_ThrowBadArrayIndex", t, 
-                         0, NOT_BUILT_IN, NULL, NULL_TREE);
+      = add_builtin_function ("_Jv_ThrowBadArrayIndex", t,
+                             0, NOT_BUILT_IN, NULL, NULL_TREE);
   /* Mark soft_badarrayindex_node as a `noreturn' function with side
      effects.  */
   TREE_THIS_VOLATILE (soft_badarrayindex_node) = 1;
   TREE_SIDE_EFFECTS (soft_badarrayindex_node) = 1;
 
   soft_nullpointer_node
-    = builtin_function ("_Jv_ThrowNullPointerException",
-                       build_function_type (void_type_node, endlink),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+    = add_builtin_function ("_Jv_ThrowNullPointerException",
+                           build_function_type (void_type_node, endlink),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
   /* Mark soft_nullpointer_node as a `noreturn' function with side
      effects.  */
   TREE_THIS_VOLATILE (soft_nullpointer_node) = 1;
   TREE_SIDE_EFFECTS (soft_nullpointer_node) = 1;
 
   soft_abstractmethod_node
-    = builtin_function ("_Jv_ThrowAbstractMethodError",
-                       build_function_type (void_type_node, endlink),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+    = add_builtin_function ("_Jv_ThrowAbstractMethodError",
+                           build_function_type (void_type_node, endlink),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
   /* Mark soft_abstractmethod_node as a `noreturn' function with side
      effects.  */
   TREE_THIS_VOLATILE (soft_abstractmethod_node) = 1;
   TREE_SIDE_EFFECTS (soft_abstractmethod_node) = 1;
 
+  soft_nosuchfield_node
+    = add_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
-    = builtin_function ("_Jv_CheckCast",
-                       build_function_type (ptr_type_node, t),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+    = add_builtin_function ("_Jv_CheckCast",
+                           build_function_type (ptr_type_node, t),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
   t = tree_cons (NULL_TREE, object_ptr_type_node,
                 tree_cons (NULL_TREE, class_ptr_type, endlink));
   soft_instanceof_node
-    = builtin_function ("_Jv_IsInstanceOf",
-                       build_function_type (boolean_type_node, t),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
-  DECL_IS_PURE (soft_instanceof_node) = 1;
+    = add_builtin_function ("_Jv_IsInstanceOf",
+                           build_function_type (boolean_type_node, t),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
+  DECL_PURE_P (soft_instanceof_node) = 1;
   t = tree_cons (NULL_TREE, object_ptr_type_node,
                 tree_cons (NULL_TREE, object_ptr_type_node, endlink));
   soft_checkarraystore_node
-    = builtin_function ("_Jv_CheckArrayStore",
-                       build_function_type (void_type_node, t),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+    = add_builtin_function ("_Jv_CheckArrayStore",
+                           build_function_type (void_type_node, t),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
   t = tree_cons (NULL_TREE, ptr_type_node,
                 tree_cons (NULL_TREE, ptr_type_node,
                            tree_cons (NULL_TREE, int_type_node, endlink)));
-  soft_lookupinterfacemethod_node 
-    = builtin_function ("_Jv_LookupInterfaceMethodIdx",
-                       build_function_type (ptr_type_node, t),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
-  DECL_IS_PURE (soft_lookupinterfacemethod_node) = 1;
+  soft_lookupinterfacemethod_node
+    = add_builtin_function ("_Jv_LookupInterfaceMethodIdx",
+                           build_function_type (ptr_type_node, t),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
+  DECL_PURE_P (soft_lookupinterfacemethod_node) = 1;
   t = tree_cons (NULL_TREE, ptr_type_node,
                 tree_cons (NULL_TREE, ptr_type_node,
                            tree_cons (NULL_TREE, ptr_type_node, endlink)));
-  soft_lookupinterfacemethodbyname_node 
-    = builtin_function ("_Jv_LookupInterfaceMethod",
-                       build_function_type (ptr_type_node, t),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+  soft_lookupinterfacemethodbyname_node
+    = add_builtin_function ("_Jv_LookupInterfaceMethod",
+                           build_function_type (ptr_type_node, t),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
   t = tree_cons (NULL_TREE, object_ptr_type_node,
                 tree_cons (NULL_TREE, ptr_type_node,
                            tree_cons (NULL_TREE, ptr_type_node, 
                                       tree_cons (NULL_TREE, int_type_node, 
                                                  endlink))));
   soft_lookupjnimethod_node
-    = builtin_function ("_Jv_LookupJNIMethod",
-                       build_function_type (ptr_type_node, t),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+    = add_builtin_function ("_Jv_LookupJNIMethod",
+                           build_function_type (ptr_type_node, t),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
   t = tree_cons (NULL_TREE, ptr_type_node, endlink);
   soft_getjnienvnewframe_node
-    = builtin_function ("_Jv_GetJNIEnvNewFrame",
-                       build_function_type (ptr_type_node, t),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+    = add_builtin_function ("_Jv_GetJNIEnvNewFrame",
+                           build_function_type (ptr_type_node, t),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
   soft_jnipopsystemframe_node
-    = builtin_function ("_Jv_JNI_PopSystemFrame",
-                       build_function_type (void_type_node, t),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+    = add_builtin_function ("_Jv_JNI_PopSystemFrame",
+                           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);
+    = add_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
-    = builtin_function ("_Jv_divI",
-                       build_function_type (int_type_node, t),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+    = add_builtin_function ("_Jv_divI",
+                           build_function_type (int_type_node, t),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
 
   soft_irem_node
-    = builtin_function ("_Jv_remI",
-                       build_function_type (int_type_node, t),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+    = add_builtin_function ("_Jv_remI",
+                           build_function_type (int_type_node, t),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
 
   t = tree_cons (NULL_TREE, long_type_node,
                 tree_cons (NULL_TREE, long_type_node, endlink));
   soft_ldiv_node
-    = builtin_function ("_Jv_divJ",
-                       build_function_type (long_type_node, t),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+    = add_builtin_function ("_Jv_divJ",
+                           build_function_type (long_type_node, t),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
 
   soft_lrem_node
-    = builtin_function ("_Jv_remJ",
-                       build_function_type (long_type_node, t),
-                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+    = add_builtin_function ("_Jv_remJ",
+                           build_function_type (long_type_node, t),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
 
   /* Initialize variables for except.c.  */
   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
                                              ? "__gcj_personality_sj0"
                                              : "__gcj_personality_v0");
-  default_init_unwind_resume_libfunc ();
+  if (targetm.arm_eabi_unwinder)
+    unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
+  else
+    default_init_unwind_resume_libfunc ();
 
   lang_eh_runtime_type = do_nothing;
 
-  init_jcf_parse ();
-    
   initialize_builtins ();
   soft_fmod_node = built_in_decls[BUILT_IN_FMOD];
-#if 0
-  soft_fmodf_node = built_in_decls[BUILT_IN_FMODF];
-#endif
 
   parse_version ();
 }
@@ -1257,41 +1127,6 @@ lookup_name_current_level (tree name)
   return t;
 }
 
-/* Use a binding level to record a labeled block declaration */
-
-void
-push_labeled_block (tree lb)
-{
-  tree name = DECL_NAME (LABELED_BLOCK_LABEL (lb));
-  struct binding_level *b = current_binding_level;
-  tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
-  if (oldlocal != 0)
-      b->shadowed = tree_cons (name, oldlocal, b->shadowed);
-  TREE_CHAIN (lb) = b->names;
-  b->names = lb;
-  IDENTIFIER_LOCAL_VALUE (name) = lb;
-}
-
-/* Pop the current binding level, reinstalling values for the previous
-   labeled block */
-
-void
-pop_labeled_block (void)
-{
-  struct binding_level *b = current_binding_level;
-  tree label =  b->names;
-  IDENTIFIER_LOCAL_VALUE (DECL_NAME (LABELED_BLOCK_LABEL (label))) = 
-    NULL_TREE;
-  if (b->shadowed)
-    IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (b->shadowed)) = 
-      TREE_VALUE (b->shadowed);
-
-  /* Pop the current level, and free the structure for reuse.  */
-  current_binding_level = current_binding_level->level_chain;
-  b->level_chain = free_binding_level;
-  free_binding_level = b;
-}
-
 /* Record a decl-node X as belonging to the current lexical scope.
    Check for errors (such as an incompatible declaration for the same
    name already seen in the same scope).
@@ -1345,55 +1180,6 @@ pushdecl (tree x)
          tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
          IDENTIFIER_LOCAL_VALUE (name) = x;
 
-#if 0
-         /* Warn if shadowing an argument at the top level of the body.  */
-         if (oldlocal != 0 && !DECL_EXTERNAL (x)
-             /* This warning doesn't apply to the parms of a nested fcn.  */
-             && ! current_binding_level->parm_flag
-             /* Check that this is one level down from the parms.  */
-             && current_binding_level->level_chain->parm_flag
-             /* Check that the decl being shadowed
-                comes from the parm level, one level up.  */
-             && chain_member (oldlocal, current_binding_level->level_chain->names))
-           {
-             if (TREE_CODE (oldlocal) == PARM_DECL)
-               pedwarn ("declaration of %qs shadows a parameter",
-                        IDENTIFIER_POINTER (name));
-             else
-               pedwarn ("declaration of %qs shadows a symbol from the parameter list",
-                        IDENTIFIER_POINTER (name));
-           }
-
-         /* Maybe warn if shadowing something else.  */
-         else if (warn_shadow && !DECL_EXTERNAL (x)
-                  /* No shadow warnings for internally generated vars.  */
-                  && DECL_SOURCE_LINE (x) != 0
-                  /* No shadow warnings for vars made for inlining.  */
-                  && ! DECL_FROM_INLINE (x))
-           {
-             const char *warnstring = 0;
-
-             if (TREE_CODE (x) == PARM_DECL
-                 && current_binding_level->level_chain->parm_flag)
-               /* Don't warn about the parm names in function declarator
-                  within a function declarator.
-                  It would be nice to avoid warning in any function
-                  declarator in a declaration, as opposed to a definition,
-                  but there is no way to tell it's not a definition.  */
-               ;
-             else if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL)
-               warnstring = "declaration of %qs shadows a parameter";
-             else if (oldlocal != 0)
-               warnstring = "declaration of %qs shadows previous local";
-             else if (IDENTIFIER_GLOBAL_VALUE (name) != 0
-                      && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node)
-               warnstring = "declaration of %qs shadows global declaration";
-
-             if (warnstring)
-               warning (0, warnstring, IDENTIFIER_POINTER (name));
-           }
-#endif
-
          /* If storing a local value, there may already be one (inherited).
             If so, record it for restoration when this binding level ends.  */
          if (oldlocal != 0)
@@ -1468,7 +1254,7 @@ static struct binding_level *
 make_binding_level (void)
 {
   /* NOSTRICT */
-  return ggc_alloc_cleared (sizeof (struct binding_level));
+  return GGC_CNEW (struct binding_level);
 }
 
 void
@@ -1476,14 +1262,6 @@ pushlevel (int unused ATTRIBUTE_UNUSED)
 {
   struct binding_level *newlevel = NULL_BINDING_LEVEL;
 
-#if 0
-  /* If this is the top level of a function,
-     just make sure that NAMED_LABELS is 0.  */
-
-  if (current_binding_level == global_binding_level)
-    named_labels = 0;
-#endif
-
   /* Reuse or create a struct for this binding level.  */
 
   if (free_binding_level)
@@ -1549,14 +1327,6 @@ poplevel (int keep, int reverse, int functionbody)
   else
     fprintf (stderr, "pop  %s level %p pc %d\n",
             (is_class_level) ? "class" : "block", current_binding_level, current_pc);
-#if 0
-  if (is_class_level != (current_binding_level == class_binding_level))
-    {
-      indent ();
-      fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n");
-    }
-  is_class_level = 0;
-#endif
 #endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
 
   /* Get the decls in the order they were written.
@@ -1676,32 +1446,6 @@ poplevel (int keep, int reverse, int functionbody)
         found in the FUNCTION_DECL instead.  */
 
       BLOCK_VARS (block) = 0;
-
-      /* Clear out the definitions of all label names,
-        since their scopes end here,
-        and add them to BLOCK_VARS.  */
-
-#if 0
-      for (link = named_labels; link; link = TREE_CHAIN (link))
-       {
-         tree label = TREE_VALUE (link);
-
-         if (DECL_INITIAL (label) == 0)
-           {
-             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, "label %q+D defined but not used", label);
-         IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0;
-
-         /* Put the labels into the "variables" of the
-            top-level block, so debugger can see them.  */
-         TREE_CHAIN (label) = BLOCK_VARS (block);
-         BLOCK_VARS (block) = label;
-       }
-#endif
     }
 
   /* Pop the current level, and free the structure for reuse.  */
@@ -1770,8 +1514,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);
@@ -1783,10 +1529,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;
        }
     }      
 
@@ -1828,18 +1581,6 @@ force_poplevels (int start_pc)
     }
 }
 
-/* Insert BLOCK at the end of the list of subblocks of the
-   current binding level.  This is used when a BIND_EXPR is expanded,
-   to handle the BLOCK node inside the BIND_EXPR.  */
-
-void
-insert_block (tree block)
-{
-  TREE_USED (block) = 1;
-  current_binding_level->blocks
-    = chainon (current_binding_level->blocks, block);
-}
-
 /* integrate_decl_tree calls this function. */
 
 void
@@ -1852,7 +1593,7 @@ java_dup_lang_specific_decl (tree node)
     return;
 
   lang_decl_size = sizeof (struct lang_decl);
-  x = ggc_alloc (lang_decl_size);
+  x = GGC_NEW (struct lang_decl);
   memcpy (x, DECL_LANG_SPECIFIC (node), lang_decl_size);
   DECL_LANG_SPECIFIC (node) = x;
 }
@@ -1907,14 +1648,6 @@ give_name_to_locals (JCF *jcf)
          MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
          DECL_LOCAL_SLOT_NUMBER (decl) = slot;
          DECL_LOCAL_START_PC (decl) = start_pc;
-#if 0
-         /* FIXME: The range used internally for exceptions and local
-            variable ranges, is a half-open interval: 
-            start_pc <= pc < end_pc.  However, the range used in the
-            Java VM spec is inclusive at both ends: 
-            start_pc <= pc <= end_pc. */
-         end_pc++;
-#endif
          DECL_LOCAL_END_PC (decl) = end_pc;
 
          /* Now insert the new decl in the proper place in
@@ -1987,7 +1720,7 @@ start_java_method (tree fndecl)
   i = DECL_MAX_LOCALS(fndecl) + DECL_MAX_STACK(fndecl);
   decl_map = make_tree_vec (i);
   base_decl_map = make_tree_vec (i);
-  type_map = xrealloc (type_map, i * sizeof (tree));
+  type_map = XRESIZEVEC (tree, type_map, i);
 
 #if defined(DEBUG_JAVA_BINDING_LEVELS)
   fprintf (stderr, "%s:\n", lang_printable_name (fndecl, 2));
@@ -2001,8 +1734,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;
@@ -2063,7 +1795,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)
@@ -2099,50 +1830,21 @@ finish_method (tree fndecl)
                    build2 (TRY_FINALLY_EXPR, void_type_node, *tp, exit));
     }
 
-  /* Prepend class initialization for static methods reachable from
-     other classes.  */
-  if (METHOD_STATIC (fndecl)
-      && (! METHOD_PRIVATE (fndecl)
-          || INNER_CLASS_P (DECL_CONTEXT (fndecl)))
-      && ! DECL_CLINIT_P (fndecl)
-      && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl))))
-    {
-      tree clas = DECL_CONTEXT (fndecl);
-      tree init = build3 (CALL_EXPR, void_type_node,
-                         build_address_of (soft_initclass_node),
-                         build_tree_list (NULL_TREE, build_class_ref (clas)),
-                         NULL_TREE);
-      *tp = build2 (COMPOUND_EXPR, TREE_TYPE (*tp), init, *tp);
-    }
-
   /* Convert function tree to GENERIC prior to inlining.  */
   java_genericize (fndecl);
 
   /* Store the end of the function, so that we get good line number
      info for the epilogue.  */
   if (DECL_STRUCT_FUNCTION (fndecl))
-    cfun = DECL_STRUCT_FUNCTION (fndecl);
+    set_cfun (DECL_STRUCT_FUNCTION (fndecl));
   else
-    allocate_struct_function (fndecl);
-#ifdef USE_MAPPED_LOCATION
+    allocate_struct_function (fndecl, false);
   cfun->function_end_locus = DECL_FUNCTION_LAST_LINE (fndecl);
-#else
-  cfun->function_end_locus.file = DECL_SOURCE_FILE (fndecl);
-  cfun->function_end_locus.line = DECL_FUNCTION_LAST_LINE (fndecl);
-#endif
 
   /* Defer inlining and expansion to the cgraph optimizers.  */
   cgraph_finalize_function (fndecl, false);
 }
 
-/* Optimize and expand a function's entire body.  */
-
-void
-java_expand_body (tree fndecl)
-{
-  tree_rest_of_compilation (fndecl);
-}
-
 /* We pessimistically marked all methods and fields external until we
    knew what set of classes we were planning to compile.  Now mark those
    associated with CLASS to be generated locally as not external.  */
@@ -2171,32 +1873,41 @@ java_mark_decl_local (tree decl)
 static void
 java_mark_cni_decl_local (tree decl)
 {
-  /* 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.  */
-  gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl));
-
 #if !defined(HAVE_GAS_HIDDEN) || !defined(ASM_OUTPUT_DEF)
   return;
 #endif
 
   DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
   DECL_LOCAL_CNI_METHOD_P (decl) = 1;
+
+  /* Setting DECL_LOCAL_CNI_METHOD_P changes the behavior of the
+     mangler.  We might have already referenced this native method and
+     therefore created its name, but even if we have it won't hurt.
+     We'll just go via its externally visible name, rather than its
+     hidden alias.  However, we must force things so that the correct
+     mangling is done.  */
+
+  if (DECL_ASSEMBLER_NAME_SET_P (decl))
+    java_mangle_decl (decl);
+  if (DECL_RTL_SET_P (decl))
+    {
+      SET_DECL_RTL (decl, 0);
+      make_decl_rtl (decl);
+    }
 }
 
 /* Use the preceding two functions and mark all members of the class.  */
 
 void
-java_mark_class_local (tree class)
+java_mark_class_local (tree klass)
 {
   tree t;
 
-  for (t = TYPE_FIELDS (class); t ; t = TREE_CHAIN (t))
+  for (t = TYPE_FIELDS (klass); t ; t = TREE_CHAIN (t))
     if (FIELD_STATIC (t))
       java_mark_decl_local (t);
 
-  for (t = TYPE_METHODS (class); t ; t = TREE_CHAIN (t))
+  for (t = TYPE_METHODS (klass); t ; t = TREE_CHAIN (t))
     if (!METHOD_ABSTRACT (t))
       {
        if (METHOD_NATIVE (t) && !flag_jni)
@@ -2224,18 +1935,37 @@ 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);
+  TREE_TYPE (stmts) = void_type_node;
+
+  return current_binding_level->stmts = stmts;
 }
 
 /* Add a variable to the current scope.  */
@@ -2269,8 +1999,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;