OSDN Git Service

PR debug/43521
[pf3gnuchains/gcc-fork.git] / gcc / java / decl.c
index a74e518..e1c7fa4 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, 2009, 2010 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, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, 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,9 @@ 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"
+#include "cgraph.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. */
+
+#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.  */
 
-/* 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.  */
+/* 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)
@@ -343,7 +274,7 @@ find_local_variable (int index, tree type, int pc ATTRIBUTE_UNUSED)
       tree name;
       sprintf (buf, "#slot#%d#%d", index, uniq++);
       name = get_identifier (buf);
-      decl = build_decl (VAR_DECL, name, type);
+      decl = build_decl (input_location, VAR_DECL, name, type);
       DECL_IGNORED_P (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
       decl = push_jvm_slot (index, decl);
@@ -366,7 +297,7 @@ find_local_variable (int index, tree type, int pc ATTRIBUTE_UNUSED)
       name = get_identifier (buf);
       base_decl
        = TREE_VEC_ELT (base_decl_map, index)
-       = build_decl (VAR_DECL, name, ptr_type_node);
+       = build_decl (input_location, VAR_DECL, name, ptr_type_node);
       pushdecl_function_level (base_decl);
       DECL_IGNORED_P (base_decl) = 1;
       DECL_ARTIFICIAL (base_decl) = 1;
@@ -375,13 +306,13 @@ find_local_variable (int index, tree type, int pc ATTRIBUTE_UNUSED)
   return decl;
 }
 
-/* Called during gimplification for every variable.  If the variable
+/* Called during genericization for every variable.  If the variable
    is a temporary of pointer type, replace it with a common variable
    thath is used to hold all pointer types that are ever stored in
    that slot.  Set WANT_LVALUE if you want a variable that is to be
    written to.  */
 
-tree 
+static tree 
 java_replace_reference (tree var_decl, bool want_lvalue)
 {
   tree decl_type;
@@ -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);
 
@@ -412,6 +341,43 @@ java_replace_reference (tree var_decl, bool want_lvalue)
   return var_decl;
 }
 
+/* Helper for java_genericize.  */
+
+tree
+java_replace_references (tree *tp, int *walk_subtrees,
+                        void *data ATTRIBUTE_UNUSED)
+{
+  if (TREE_CODE (*tp) == MODIFY_EXPR)
+    {
+      source_location loc = EXPR_LOCATION (*tp);
+      tree lhs = TREE_OPERAND (*tp, 0);
+      /* This is specific to the bytecode compiler.  If a variable has
+        LOCAL_SLOT_P set, replace an assignment to it with an assignment
+        to the corresponding variable that holds all its aliases.  */
+      if (TREE_CODE (lhs) == VAR_DECL
+         && DECL_LANG_SPECIFIC (lhs)
+         && LOCAL_SLOT_P (lhs)
+         && TREE_CODE (TREE_TYPE (lhs)) == POINTER_TYPE)
+       {
+         tree new_lhs = java_replace_reference (lhs, /* want_lvalue */ true);
+         tree new_rhs = build1 (NOP_EXPR, TREE_TYPE (new_lhs),
+                                TREE_OPERAND (*tp, 1));
+         tree tem = build2 (MODIFY_EXPR, TREE_TYPE (new_lhs),
+                            new_lhs, new_rhs);
+         *tp = build1 (NOP_EXPR, TREE_TYPE (lhs), tem);
+         SET_EXPR_LOCATION (tem, loc);
+         SET_EXPR_LOCATION (new_rhs, loc);
+         SET_EXPR_LOCATION (*tp, loc);
+       }
+    }
+  if (TREE_CODE (*tp) == VAR_DECL)
+    {
+      *tp = java_replace_reference (*tp, /* want_lvalue */ false);
+      *walk_subtrees = 0;
+    }
+
+  return NULL_TREE;
+}
 
 /* Same as find_local_index, except that INDEX is a stack index. */
 
@@ -422,8 +388,8 @@ find_stack_slot (int index, tree type)
                              type, -1);
 }
 
-struct binding_level GTY(())
-  {
+struct GTY(())
+  binding_level {
     /* A chain of _DECL nodes for all variables, constants, functions,
      * and typedef types.  These are in the reverse of the order supplied.
      */
@@ -456,6 +422,9 @@ struct binding_level GTY(())
 
     /* Binding depth at which this level began.  Used only for debugging.  */
     unsigned binding_depth;
+
+    /* The location at which this level began.  */
+    source_location loc;
   };
 
 #define NULL_BINDING_LEVEL (struct binding_level *) NULL
@@ -496,22 +465,11 @@ static const struct binding_level clear_binding_level
     NULL, /* stmts */
     NULL, /* exception_range */
     0, /* binding_depth */
+    0, /* loc */
   };
 
-#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
    types shorter than int.  */
 
@@ -531,40 +489,13 @@ 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));
+  pushdecl (build_decl (input_location,
+                       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));
-  make_decl_rtl (decl);
-  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)
@@ -573,17 +504,12 @@ create_primitive_vtable (const char *name)
   char buf[50];
 
   sprintf (buf, "_Jv_%sVTable", name);
-  r = build_decl (VAR_DECL, get_identifier (buf), ptr_type_node);
+  r = build_decl (input_location,
+                 VAR_DECL, get_identifier (buf), ptr_type_node);
   DECL_EXTERNAL (r) = 1;
   return r;
 }
 
-static tree
-do_nothing (tree t)
-{
-  return t;
-}
-
 /* Parse the version string and compute the ABI version number.  */
 static void
 parse_version (void)
@@ -614,18 +540,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);
 }
@@ -651,28 +579,36 @@ java_init_decl_processing (void)
   TREE_TYPE (error_mark_node) = error_mark_node;
 
   /* Create sizetype first - needed for other types. */
-  initialize_sizetypes (false);
+  initialize_sizetypes ();
 
   byte_type_node = make_signed_type (8);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"), byte_type_node));
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("byte"), byte_type_node));
   short_type_node = make_signed_type (16);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("short"), short_type_node));
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("short"), short_type_node));
   int_type_node = make_signed_type (32);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("int"), int_type_node));
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("int"), int_type_node));
   long_type_node = make_signed_type (64);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("long"), long_type_node));
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("long"), long_type_node));
 
   unsigned_byte_type_node = make_unsigned_type (8);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("unsigned byte"),
                        unsigned_byte_type_node));
   unsigned_short_type_node = make_unsigned_type (16);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned short"),
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("unsigned short"),
                        unsigned_short_type_node));
   unsigned_int_type_node = make_unsigned_type (32);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("unsigned int"),
                        unsigned_int_type_node));
   unsigned_long_type_node = make_unsigned_type (64);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned long"),
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("unsigned long"),
                        unsigned_long_type_node));
 
   /* This is not a java type, however tree-dfa requires a definition for
@@ -709,7 +645,8 @@ java_init_decl_processing (void)
   long_zero_node = build_int_cst (long_type_node, 0);
 
   void_type_node = make_node (VOID_TYPE);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("void"), void_type_node));
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("void"), void_type_node));
   layout_type (void_type_node);        /* Uses size_zero_node */
 
   ptr_type_node = build_pointer_type (void_type_node);
@@ -722,23 +659,18 @@ 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));
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("char"), char_type_node));
 
   boolean_type_node = make_node (BOOLEAN_TYPE);
   TYPE_PRECISION (boolean_type_node) = 1;
   fixup_unsigned_type (boolean_type_node);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("boolean"),
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("boolean"),
                        boolean_type_node));
   boolean_false_node = TYPE_MIN_VALUE (boolean_type_node);
   boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
@@ -754,13 +686,15 @@ java_init_decl_processing (void)
 
   float_type_node = make_node (REAL_TYPE);
   TYPE_PRECISION (float_type_node) = 32;
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("float"),
                         float_type_node));
   layout_type (float_type_node);
 
   double_type_node = make_node (REAL_TYPE);
   TYPE_PRECISION (double_type_node) = 64;
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
+  pushdecl (build_decl (BUILTINS_LOCATION,
+                       TYPE_DECL, get_identifier ("double"),
                         double_type_node));
   layout_type (double_type_node);
 
@@ -779,8 +713,10 @@ java_init_decl_processing (void)
 
   one_elt_array_domain_type = build_index_type (integer_one_node);
   utf8const_type = make_node (RECORD_TYPE);
-  PUSH_FIELD (utf8const_type, field, "hash", unsigned_short_type_node);
-  PUSH_FIELD (utf8const_type, field, "length", unsigned_short_type_node);
+  PUSH_FIELD (input_location,
+             utf8const_type, field, "hash", unsigned_short_type_node);
+  PUSH_FIELD (input_location,
+             utf8const_type, field, "length", unsigned_short_type_node);
   FINISH_RECORD (utf8const_type);
   utf8const_ptr_type = build_pointer_type (utf8const_type);
 
@@ -795,9 +731,11 @@ java_init_decl_processing (void)
   itable_ptr_type = build_pointer_type (itable_type);
 
   symbol_type = make_node (RECORD_TYPE);
-  PUSH_FIELD (symbol_type, field, "clname", utf8const_ptr_type);
-  PUSH_FIELD (symbol_type, field, "name", utf8const_ptr_type);
-  PUSH_FIELD (symbol_type, field, "signature", utf8const_ptr_type);
+  PUSH_FIELD (input_location,
+             symbol_type, field, "clname", utf8const_ptr_type);
+  PUSH_FIELD (input_location, symbol_type, field, "name", utf8const_ptr_type);
+  PUSH_FIELD (input_location,
+             symbol_type, field, "signature", utf8const_ptr_type);
   FINISH_RECORD (symbol_type);
 
   symbols_array_type = build_array_type (symbol_type, 
@@ -805,9 +743,12 @@ java_init_decl_processing (void)
   symbols_array_ptr_type = build_pointer_type (symbols_array_type);
 
   assertion_entry_type = make_node (RECORD_TYPE);
-  PUSH_FIELD (assertion_entry_type, field, "assertion_code", integer_type_node);
-  PUSH_FIELD (assertion_entry_type, field, "op1", utf8const_ptr_type);
-  PUSH_FIELD (assertion_entry_type, field, "op2", utf8const_ptr_type);
+  PUSH_FIELD (input_location,
+             assertion_entry_type, field, "assertion_code", integer_type_node);
+  PUSH_FIELD (input_location,
+             assertion_entry_type, field, "op1", utf8const_ptr_type);
+  PUSH_FIELD (input_location,
+             assertion_entry_type, field, "op2", utf8const_ptr_type);
   FINISH_RECORD (assertion_entry_type);
   
   assertion_table_type = build_array_type (assertion_entry_type,
@@ -845,22 +786,16 @@ java_init_decl_processing (void)
 
   methodtable_type = make_node (RECORD_TYPE);
   layout_type (methodtable_type);
-  build_decl (TYPE_DECL, get_identifier ("methodtable"), methodtable_type);
+  build_decl (BUILTINS_LOCATION,
+             TYPE_DECL, get_identifier ("methodtable"), methodtable_type);
   methodtable_ptr_type = build_pointer_type (methodtable_type);
 
   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 =
@@ -870,11 +805,16 @@ java_init_decl_processing (void)
   init_expr_processing();
 
   constants_type_node = make_node (RECORD_TYPE);
-  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);
+  PUSH_FIELD (input_location,
+             constants_type_node, field, "size", unsigned_int_type_node);
+  PUSH_FIELD (input_location,
+             constants_type_node, field, "tags", ptr_type_node);
+  PUSH_FIELD (input_location,
+             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);
+  build_decl (BUILTINS_LOCATION,
+             TYPE_DECL, get_identifier ("constants"), constants_type_node);
 
   access_flags_type_node = unsigned_short_type_node;
 
@@ -886,7 +826,8 @@ java_init_decl_processing (void)
   TYPE_NONALIASED_COMPONENT (otable_type) = 1;
   otable_ptr_type = build_pointer_type (otable_type);
 
-  PUSH_FIELD (object_type_node, field, "vtable", dtable_ptr_type);
+  PUSH_FIELD (input_location,
+             object_type_node, field, "vtable", dtable_ptr_type);
   DECL_FCONTEXT (field) = object_type_node;
   TYPE_VFIELD (object_type_node) = field;
 
@@ -894,7 +835,7 @@ java_init_decl_processing (void)
      There is an unresolved issue here, which is whether the vtable
      should be marked by the GC.  */
   if (! flag_hash_synchronization)
-    PUSH_FIELD (object_type_node, field, "sync_info",
+    PUSH_FIELD (input_location, object_type_node, field, "sync_info",
                build_pointer_type (object_type_node));
   for (t = TYPE_FIELDS (object_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
     FIELD_PRIVATE (t) = 1;
@@ -909,150 +850,202 @@ java_init_decl_processing (void)
   set_super_info (0, string_type_node, object_type_node, 0);
   class_ptr_type = build_pointer_type (class_type_node);
 
-  PUSH_FIELD (class_type_node, field, "next_or_version", class_ptr_type);
-  PUSH_FIELD (class_type_node, field, "name", utf8const_ptr_type);
-  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);
-  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);
-  PUSH_FIELD (class_type_node, field, "fields", field_ptr_type_node);
-  PUSH_FIELD (class_type_node, field, "size_in_bytes", int_type_node);
-  PUSH_FIELD (class_type_node, field, "field_count", short_type_node);
-  PUSH_FIELD (class_type_node, field, "static_field_count", short_type_node);
-  PUSH_FIELD (class_type_node, field, "vtable", dtable_ptr_type);
-  PUSH_FIELD (class_type_node, field, "otable", otable_ptr_type);
-  PUSH_FIELD (class_type_node, field, "otable_syms", 
+  PUSH_FIELD (input_location,
+             class_type_node, field, "next_or_version", class_ptr_type);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "name", utf8const_ptr_type);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "accflags", access_flags_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "superclass", class_ptr_type);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "constants", constants_type_node);
+  constants_field_decl_node = field;
+  PUSH_FIELD (input_location,
+             class_type_node, field, "methods", method_ptr_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "method_count", short_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "vtable_method_count", short_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "fields", field_ptr_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "size_in_bytes", int_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "field_count", short_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "static_field_count", short_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "vtable", dtable_ptr_type);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "otable", otable_ptr_type);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "otable_syms", 
              symbols_array_ptr_type);
-  PUSH_FIELD (class_type_node, field, "atable", atable_ptr_type);
-  PUSH_FIELD (class_type_node, field, "atable_syms", 
+  PUSH_FIELD (input_location,
+             class_type_node, field, "atable", atable_ptr_type);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "atable_syms", 
              symbols_array_ptr_type);
-  PUSH_FIELD (class_type_node, field, "itable", itable_ptr_type);
-  PUSH_FIELD (class_type_node, field, "itable_syms", 
+  PUSH_FIELD (input_location,
+             class_type_node, field, "itable", itable_ptr_type);
+  PUSH_FIELD (input_location, class_type_node, field, "itable_syms", 
              symbols_array_ptr_type);
-  PUSH_FIELD (class_type_node, field, "catch_classes", ptr_type_node);
-  PUSH_FIELD (class_type_node, field, "interfaces",
+  PUSH_FIELD (input_location,
+             class_type_node, field, "catch_classes", ptr_type_node);
+  PUSH_FIELD (input_location, class_type_node, field, "interfaces",
              build_pointer_type (class_ptr_type));
-  PUSH_FIELD (class_type_node, field, "loader", ptr_type_node);
-  PUSH_FIELD (class_type_node, field, "interface_count", short_type_node);
-  PUSH_FIELD (class_type_node, field, "state", byte_type_node);
-  PUSH_FIELD (class_type_node, field, "thread", ptr_type_node);
-  PUSH_FIELD (class_type_node, field, "depth", short_type_node);
-  PUSH_FIELD (class_type_node, field, "ancestors", ptr_type_node);
-  PUSH_FIELD (class_type_node, field, "idt", ptr_type_node);  
-  PUSH_FIELD (class_type_node, field, "arrayclass", ptr_type_node);  
-  PUSH_FIELD (class_type_node, field, "protectionDomain", ptr_type_node);
-  PUSH_FIELD (class_type_node, field, "assertion_table", ptr_type_node);
-  PUSH_FIELD (class_type_node, field, "hack_signers", ptr_type_node);
-  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 (input_location, class_type_node, field, "loader", ptr_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "interface_count", short_type_node);
+  PUSH_FIELD (input_location, class_type_node, field, "state", byte_type_node);
+  PUSH_FIELD (input_location, class_type_node, field, "thread", ptr_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "depth", short_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "ancestors", ptr_type_node);
+  PUSH_FIELD (input_location, class_type_node, field, "idt", ptr_type_node);  
+  PUSH_FIELD (input_location,
+             class_type_node, field, "arrayclass", ptr_type_node);  
+  PUSH_FIELD (input_location,
+             class_type_node, field, "protectionDomain", ptr_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "assertion_table", ptr_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "hack_signers", ptr_type_node);
+  PUSH_FIELD (input_location, class_type_node, field, "chain", ptr_type_node);
+  PUSH_FIELD (input_location,
+             class_type_node, field, "aux_info", ptr_type_node);
+  PUSH_FIELD (input_location, class_type_node, field, "engine", ptr_type_node);
+  PUSH_FIELD (input_location,
+             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);
 
   FINISH_RECORD (class_type_node);
-  build_decl (TYPE_DECL, get_identifier ("Class"), class_type_node);
+  build_decl (BUILTINS_LOCATION,
+             TYPE_DECL, get_identifier ("Class"), class_type_node);
 
   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
+  PUSH_FIELD (input_location,
+             field_info_union_node, field, "boffset", int_type_node);
+  PUSH_FIELD (input_location,
+             field_info_union_node, field, "addr", ptr_type_node);
   layout_type (field_info_union_node);
 
-  PUSH_FIELD (field_type_node, field, "name", utf8const_ptr_type);
-  PUSH_FIELD (field_type_node, field, "type", class_ptr_type);
-  PUSH_FIELD (field_type_node, field, "accflags", access_flags_type_node);
-  PUSH_FIELD (field_type_node, field, "bsize", unsigned_short_type_node);
-  PUSH_FIELD (field_type_node, field, "info", field_info_union_node);
+  PUSH_FIELD (input_location,
+             field_type_node, field, "name", utf8const_ptr_type);
+  PUSH_FIELD (input_location, field_type_node, field, "type", class_ptr_type);
+  PUSH_FIELD (input_location,
+             field_type_node, field, "accflags", access_flags_type_node);
+  PUSH_FIELD (input_location,
+             field_type_node, field, "bsize", unsigned_short_type_node);
+  PUSH_FIELD (input_location,
+             field_type_node, field, "info", field_info_union_node);
   FINISH_RECORD (field_type_node);
-  build_decl (TYPE_DECL, get_identifier ("Field"), field_type_node);
+  build_decl (BUILTINS_LOCATION,
+             TYPE_DECL, get_identifier ("Field"), field_type_node);
 
   nativecode_ptr_array_type_node
     = build_array_type (nativecode_ptr_type_node, one_elt_array_domain_type);
 
-  PUSH_FIELD (dtable_type, field, "class", class_ptr_type);
-  PUSH_FIELD (dtable_type, field, "methods", nativecode_ptr_array_type_node);
+  PUSH_FIELD (input_location,
+             dtable_type, field, "class", class_ptr_type);
+  PUSH_FIELD (input_location,
+             dtable_type, field, "methods", nativecode_ptr_array_type_node);
   FINISH_RECORD (dtable_type);
-  build_decl (TYPE_DECL, get_identifier ("dispatchTable"), dtable_type);
+  build_decl (BUILTINS_LOCATION,
+             TYPE_DECL, get_identifier ("dispatchTable"), dtable_type);
 
   jexception_type = make_node (RECORD_TYPE);
-  PUSH_FIELD (jexception_type, field, "start_pc", ptr_type_node);
-  PUSH_FIELD (jexception_type, field, "end_pc", ptr_type_node);
-  PUSH_FIELD (jexception_type, field, "handler_pc", ptr_type_node);
-  PUSH_FIELD (jexception_type, field, "catch_type", class_ptr_type);
+  PUSH_FIELD (input_location,
+             jexception_type, field, "start_pc", ptr_type_node);
+  PUSH_FIELD (input_location, jexception_type, field, "end_pc", ptr_type_node);
+  PUSH_FIELD (input_location,
+             jexception_type, field, "handler_pc", ptr_type_node);
+  PUSH_FIELD (input_location,
+             jexception_type, field, "catch_type", class_ptr_type);
   FINISH_RECORD (jexception_type);
-  build_decl (TYPE_DECL, get_identifier ("jexception"), field_type_node);
+  build_decl (BUILTINS_LOCATION,
+             TYPE_DECL, get_identifier ("jexception"), field_type_node);
   jexception_ptr_type = build_pointer_type (jexception_type);
 
   lineNumberEntry_type = make_node (RECORD_TYPE);
-  PUSH_FIELD (lineNumberEntry_type, field, "line_nr", unsigned_short_type_node);
-  PUSH_FIELD (lineNumberEntry_type, field, "start_pc", ptr_type_node);
+  PUSH_FIELD (input_location,
+             lineNumberEntry_type, field, "line_nr", unsigned_short_type_node);
+  PUSH_FIELD (input_location,
+             lineNumberEntry_type, field, "start_pc", ptr_type_node);
   FINISH_RECORD (lineNumberEntry_type);
 
   lineNumbers_type = make_node (RECORD_TYPE);
-  PUSH_FIELD (lineNumbers_type, field, "length", unsigned_int_type_node);
+  PUSH_FIELD (input_location,
+             lineNumbers_type, field, "length", unsigned_int_type_node);
   FINISH_RECORD (lineNumbers_type);
 
-  PUSH_FIELD (method_type_node, field, "name", utf8const_ptr_type);
-  PUSH_FIELD (method_type_node, field, "signature", utf8const_ptr_type);
-  PUSH_FIELD (method_type_node, field, "accflags", access_flags_type_node);
-  PUSH_FIELD (method_type_node, field, "index", unsigned_short_type_node);
-  PUSH_FIELD (method_type_node, field, "ncode", nativecode_ptr_type_node);
-  PUSH_FIELD (method_type_node, field, "throws", ptr_type_node);
+  PUSH_FIELD (input_location,
+             method_type_node, field, "name", utf8const_ptr_type);
+  PUSH_FIELD (input_location,
+             method_type_node, field, "signature", utf8const_ptr_type);
+  PUSH_FIELD (input_location,
+             method_type_node, field, "accflags", access_flags_type_node);
+  PUSH_FIELD (input_location,
+             method_type_node, field, "index", unsigned_short_type_node);
+  PUSH_FIELD (input_location,
+             method_type_node, field, "ncode", nativecode_ptr_type_node);
+  PUSH_FIELD (input_location,
+             method_type_node, field, "throws", ptr_type_node);
   FINISH_RECORD (method_type_node);
-  build_decl (TYPE_DECL, get_identifier ("Method"), method_type_node);
+  build_decl (BUILTINS_LOCATION,
+             TYPE_DECL, get_identifier ("Method"), method_type_node);
 
   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,
@@ -1060,9 +1053,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
@@ -1070,121 +1063,134 @@ 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);
-  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
+    = 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);
-
-  /* Initialize variables for except.c.  */
-  eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
-                                             ? "__gcj_personality_sj0"
-                                             : "__gcj_personality_v0");
+    = add_builtin_function ("_Jv_remJ",
+                           build_function_type (long_type_node, t),
+                           0, NOT_BUILT_IN, NULL, NULL_TREE);
 
-  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 ();
 }
@@ -1208,7 +1214,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)
@@ -1228,41 +1234,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).
@@ -1287,7 +1258,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
@@ -1316,55 +1287,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)
@@ -1439,7 +1361,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
@@ -1447,14 +1369,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)
@@ -1472,7 +1386,8 @@ pushlevel (int unused ATTRIBUTE_UNUSED)
 
   *newlevel = clear_binding_level;
   newlevel->level_chain = current_binding_level;
-  current_binding_level = newlevel;
+  newlevel->loc = input_location;
+  current_binding_level = newlevel;  
 #if defined(DEBUG_JAVA_BINDING_LEVELS)
   newlevel->binding_depth = binding_depth;
   indent ();
@@ -1520,14 +1435,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.
@@ -1595,6 +1502,8 @@ poplevel (int keep, int reverse, int functionbody)
          if (BIND_EXPR_BODY (bind) == NULL)
            BIND_EXPR_BODY (bind) = build_java_empty_stmt ();
 
+         SET_EXPR_LOCATION (bind, current_binding_level->loc);
+
          current_binding_level->stmts = NULL;
        }
       else
@@ -1647,32 +1556,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.  */
@@ -1741,8 +1624,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);
@@ -1754,10 +1639,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;
        }
     }      
 
@@ -1792,25 +1684,13 @@ 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);
     }
 }
 
-/* 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
@@ -1823,7 +1703,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;
 }
@@ -1854,7 +1734,6 @@ give_name_to_locals (JCF *jcf)
        {
          tree decl = TREE_VEC_ELT (decl_map, slot);
          DECL_NAME (decl) = name;
-         SET_DECL_ASSEMBLER_NAME (decl, name);
          if (TREE_CODE (decl) != PARM_DECL || TREE_TYPE (decl) != type)
            warning (0, "bad type in parameter debug info");
        }
@@ -1862,11 +1741,11 @@ give_name_to_locals (JCF *jcf)
        {
          tree *ptr;
          int end_pc = start_pc + length;
-         tree decl = build_decl (VAR_DECL, name, type);
+         tree decl = build_decl (input_location, 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);
            }
 
@@ -1879,14 +1758,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
@@ -1921,7 +1792,6 @@ give_name_to_locals (JCF *jcf)
              sprintf (buffer, "ARG_%d", arg_i);
              DECL_NAME (parm) = get_identifier (buffer);
            }
-         SET_DECL_ASSEMBLER_NAME (parm, DECL_NAME (parm));
        }
     }
 }
@@ -1933,11 +1803,8 @@ build_result_decl (tree fndecl)
   tree result = DECL_RESULT (fndecl);
   if (! result)
     {
-      /* To be compatible with C_PROMOTING_INTEGER_TYPE_P in cc1/cc1plus. */
-      if (INTEGRAL_TYPE_P (restype)
-         && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
-       restype = integer_type_node;
-      result = build_decl (RESULT_DECL, NULL_TREE, restype);
+      result = build_decl (DECL_SOURCE_LOCATION (fndecl),
+                          RESULT_DECL, NULL_TREE, restype);
       DECL_ARTIFICIAL (result) = 1;
       DECL_IGNORED_P (result) = 1;
       DECL_CONTEXT (result) = fndecl;
@@ -1960,7 +1827,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));
@@ -1974,10 +1841,9 @@ 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);
+      parm_decl = build_decl (input_location, PARM_DECL, parm_name, parm_type);
       DECL_CONTEXT (parm_decl) = fndecl;
       if (targetm.calls.promote_prototypes (parm_type)
          && TYPE_PRECISION (parm_type) < TYPE_PRECISION (integer_type_node)
@@ -1991,6 +1857,10 @@ start_java_method (tree fndecl)
       /* Add parm_decl to the decl_map. */
       push_jvm_slot (i, parm_decl);
 
+      /* The this parameter of methods is artificial.  */
+      if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE && i == 0)
+       DECL_ARTIFICIAL (parm_decl) = 1;
+
       type_map[i] = TREE_TYPE (parm_decl);
       if (TYPE_IS_WIDE (TREE_TYPE (parm_decl)))
        {
@@ -2005,6 +1875,7 @@ start_java_method (tree fndecl)
     type_map[i++] = NULL_TREE;
 
   build_result_decl (fndecl);
+  DECL_SOURCE_LOCATION (fndecl) = input_location;
 
   /* Push local variables.  */
   pushlevel (2);
@@ -2036,18 +1907,10 @@ 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)
-    {
-      /* Nulling these fields when we no longer need them saves
-        memory.  */
-      DECL_SAVED_TREE (fndecl) = NULL;
-      DECL_STRUCT_FUNCTION (fndecl) = NULL;
-      DECL_INITIAL (fndecl) = NULL_TREE;
-    }
   current_function_decl = NULL_TREE;
+  base_decl_map = NULL_TREE;
 }
 
 /* Prepare a method for expansion.  */
@@ -2072,50 +1935,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.  */
@@ -2125,24 +1959,64 @@ java_mark_decl_local (tree decl)
 {
   DECL_EXTERNAL (decl) = 0;
 
-  /* If we've already constructed DECL_RTL, give encode_section_info
-     a second chance, now that we've changed the flags.  */
+#ifdef ENABLE_CHECKING
+  /* Double check that we didn't pass the function to the callgraph early.  */
+  if (TREE_CODE (decl) == FUNCTION_DECL)
+    gcc_assert (!cgraph_node (decl)->local.finalized);
+#endif
+  gcc_assert (!DECL_RTL_SET_P (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)
+{
+#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))
-    make_decl_rtl (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))
-    if (!METHOD_ABSTRACT (t) && (!METHOD_NATIVE (t) || flag_jni))
-      java_mark_decl_local (t);
+  for (t = TYPE_METHODS (klass); t ; t = TREE_CHAIN (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.  */
@@ -2163,18 +2037,57 @@ add_stmt_to_compound (tree existing, tree type, tree stmt)
     return stmt;
 }
 
-/* Add a statement to the compound_expr currently being
-   constructed.  */
+/* If this node is an expr, mark its input location.  Called from
+   walk_tree().  */
+
+static tree
+set_input_location (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+                   void *data ATTRIBUTE_UNUSED)
+{
+  tree t = *tp;
+
+  if (CAN_HAVE_LOCATION_P (t))
+    {
+      if (EXPR_HAS_LOCATION(t))
+       return t;  /* Don't walk any further into this expr.   */
+      else
+       SET_EXPR_LOCATION (t, input_location);
+    }
+
+  return NULL_TREE;  /* Continue walking this expr.   */
+}
+
+/* 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);
-  
-  return current_binding_level->stmts 
-    = add_stmt_to_compound (current_binding_level->stmts, 
-                           TREE_TYPE (stmt), stmt);
+    walk_tree (&new_stmt, set_input_location, NULL, NULL);
+
+  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.  */
@@ -2208,8 +2121,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;