OSDN Git Service

* java-tree.h (push_labeled_block, pop_labeled_block): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / java / decl.c
index 5b693cb..8822c9e 100644 (file)
@@ -1,7 +1,7 @@
 /* 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 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -17,8 +17,8 @@ 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, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.
 
 Java and all Java-based marks are trademarks or registered trademarks
 of Sun Microsystems, Inc. in the United States and other countries.
@@ -48,6 +48,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);
@@ -61,19 +63,31 @@ static tree create_primitive_vtable (const char *);
 static tree check_local_unnamed_variable (tree, tree, tree);
 static void parse_version (void);
 
-/* Used when computing the ABI version.  */
-#define GCJ_BINARYCOMPAT_ADDITION 5
 
-/* Used when defining a class that should be loaded by the bootstrap
-   loader.  */
-#define GCJ_BOOTSTRAP_LOADER_ADDITION 1
+/* The following ABI flags are used in the high-order bits of the version
+   ID field. The version ID number itself should never be larger than 
+   0xfffff, so it should be safe to use top 12 bits for these flags. */
 
-/* The version of the BC ABI that we generate.  At the moment we are
-   compatible with what shipped in GCC 4.0.  This must be kept in sync
-   with parse_version(), libgcj, and reality (if the BC format
-   changes, this must change.  */
+#define FLAG_BINARYCOMPAT_ABI (1<<31)  /* Class is built with the BC-ABI. */
+
+#define FLAG_BOOTSTRAP_LOADER (1<<30)  /* Used when defining a class that 
+                                         should be loaded by the bootstrap
+                                         loader.  */
+
+/* If an ABI change is made within a GCC release series, rendering current
+   binaries incompatible with the old runtimes, this number must be set to
+   enforce the compatibility rules. */
+#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 
+   matching for the ordinary (C++) ABI.  */
+
+/* The version ID of the BC ABI that we generate.  This must be kept in
+   sync with parse_version(), libgcj, and reality (if the BC format changes, 
+   this must change).  */
 #define GCJ_CURRENT_BC_ABI_VERSION \
-  (4 * 10000 + 0 * 10 + GCJ_BINARYCOMPAT_ADDITION)
+  (4 * 100000 + 0 * 1000 + MINOR_BINARYCOMPAT_ABI_VERSION)
 
 /* The ABI version number.  */
 tree gcj_abi_version;
@@ -111,6 +125,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;
@@ -141,48 +161,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)
 {
@@ -203,52 +181,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'.  */
 
@@ -257,8 +189,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)
@@ -399,9 +330,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);
 
@@ -498,18 +427,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
@@ -531,39 +448,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)
@@ -613,18 +503,20 @@ parse_version (void)
       ++p;
     }
 
-  /* Implicit in this computation is the idea that we won't break the
-     old-style binary ABI in a sub-minor release (e.g., from 4.0.0 to
-     4.0.1).  */
-  abi_version = 10000 * major + 10 * minor;
-  /* It is helpful to distinguish BC ABI from ordinary ABI at this
-     level, since at some point we will recognize a variety of BC ABIs
-     (objects generated by different version of gcj), but will
-     probably always require strict matching for ordinary ABI.  */
   if (flag_indirect_dispatch)
-    abi_version = GCJ_CURRENT_BC_ABI_VERSION;
+    {
+      abi_version = GCJ_CURRENT_BC_ABI_VERSION;
+      abi_version |= FLAG_BINARYCOMPAT_ABI;
+    }
+  else /* C++ ABI */
+    {
+      /* Implicit in this computation is the idea that we won't break the
+        old-style binary ABI in a sub-minor release (e.g., from 4.0.0 to
+        4.0.1).  */
+      abi_version = 100000 * major + 1000 * minor;
+    }
   if (flag_bootstrap_classes)
-    abi_version += GCJ_BOOTSTRAP_LOADER_ADDITION;
+    abi_version |= FLAG_BOOTSTRAP_LOADER;
 
   gcj_abi_version = build_int_cstu (ptr_type_node, abi_version);
 }
@@ -721,15 +613,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));
@@ -850,15 +735,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");
@@ -872,6 +751,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);
 
@@ -913,6 +793,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);
@@ -947,6 +828,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);
@@ -957,9 +839,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);
@@ -1008,50 +887,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);
+  soft_resolvepoolentry_node
+    = add_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);
+  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,
@@ -1059,9 +938,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
@@ -1069,121 +948,141 @@ 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
+    = 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);
+    = add_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;
   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);
+  soft_lookupinterfacemethod_node
+    = add_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;
   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
+    = 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 ();
 
   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 ();
 }
@@ -1207,7 +1106,7 @@ lookup_name (tree name)
 }
 
 /* Similar to `lookup_name' but look only at current binding level and
-   the previous one if its the parameter level.  */
+   the previous one if it's the parameter level.  */
 
 static tree
 lookup_name_current_level (tree name)
@@ -1227,41 +1126,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).
@@ -1286,7 +1150,7 @@ pushdecl (tree x)
        /* error_mark_node is 0 for a while during initialization!  */
        {
          t = 0;
-         error ("%J'%D' used prior to declaration", x, x);
+         error ("%q+D used prior to declaration", x);
        }
 
       /* If we're naming a hitherto-unnamed type, set its TYPE_NAME
@@ -1315,55 +1179,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)
@@ -1446,14 +1261,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)
@@ -1519,14 +1326,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.
@@ -1646,32 +1445,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 ("%Jlabel '%D' used but not defined", label, label);
-             /* Avoid crashing later.  */
-             define_label (input_location, DECL_NAME (label));
-           }
-         else if (warn_unused[UNUSED_LABEL] && !TREE_USED (label))
-           warning (0, "%Jlabel '%D' defined but not used", label, 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.  */
@@ -1740,8 +1513,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);
@@ -1753,10 +1528,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;
        }
     }      
 
@@ -1791,8 +1573,8 @@ force_poplevels (int start_pc)
   while (current_binding_level->start_pc > start_pc)
     {
       if (pedantic && current_binding_level->start_pc > start_pc)
-       warning (0, "%JIn %D: overlapped variable and exception ranges at %d",
-                 current_function_decl, current_function_decl,
+       warning (0, "In %+D: overlapped variable and exception ranges at %d",
+                 current_function_decl,
                 current_binding_level->start_pc);
       poplevel (1, 0, 0);
     }
@@ -1863,8 +1645,8 @@ give_name_to_locals (JCF *jcf)
          tree decl = build_decl (VAR_DECL, name, type);
          if (end_pc > DECL_CODE_LENGTH (current_function_decl))
            {
-             warning (0, "%Jbad PC range for debug info for local '%D'",
-                       decl, decl);
+             warning (0, "bad PC range for debug info for local %q+D",
+                       decl);
              end_pc = DECL_CODE_LENGTH (current_function_decl);
            }
 
@@ -1877,14 +1659,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
@@ -1971,8 +1745,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;
@@ -2033,7 +1806,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)
@@ -2069,22 +1841,6 @@ 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);
 
@@ -2133,6 +1889,30 @@ java_mark_decl_local (tree decl)
     make_decl_rtl (decl);
 }
 
+/* Given appropriate target support, G++ will emit hidden aliases for native
+   methods.  Using this hidden name is required for proper operation of
+   _Jv_Method::ncode, but it doesn't hurt to use it everywhere.  Look for
+   proper target support, then mark the method for aliasing.  */
+
+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;
+}
+
+/* Use the preceding two functions and mark all members of the class.  */
+
 void
 java_mark_class_local (tree class)
 {
@@ -2143,8 +1923,13 @@ java_mark_class_local (tree class)
       java_mark_decl_local (t);
 
   for (t = TYPE_METHODS (class); t ; t = TREE_CHAIN (t))
-    if (!METHOD_ABSTRACT (t) && (!METHOD_NATIVE (t) || flag_jni))
-      java_mark_decl_local (t);
+    if (!METHOD_ABSTRACT (t))
+      {
+       if (METHOD_NATIVE (t) && !flag_jni)
+         java_mark_cni_decl_local (t);
+        else
+         java_mark_decl_local (t);
+      }
 }
 
 /* Add a statement to a compound_expr.  */
@@ -2165,18 +1950,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.  */
@@ -2210,8 +2014,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;