OSDN Git Service

Update Copyright years for files modified in 2008 and/or 2009.
[pf3gnuchains/gcc-fork.git] / gcc / java / class.c
index 804c239..edd16f0 100644 (file)
@@ -1,12 +1,12 @@
 /* Functions related to building classes and their related objects.
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
 /* Functions related to building classes and their related objects.
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007 Free Software Foundation, Inc.
+   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 
 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,
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -15,9 +15,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
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.
 
 Java and all Java-based marks are trademarks or registered trademarks
 of Sun Microsystems, Inc. in the United States and other countries.
 
 Java and all Java-based marks are trademarks or registered trademarks
 of Sun Microsystems, Inc. in the United States and other countries.
@@ -39,6 +38,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "output.h"
 #include "parse.h"
 #include "function.h"
 #include "output.h"
 #include "parse.h"
 #include "function.h"
+#include "tm_p.h"
 #include "ggc.h"
 #include "stdio.h"
 #include "target.h"
 #include "ggc.h"
 #include "stdio.h"
 #include "target.h"
@@ -280,7 +280,7 @@ ident_subst (const char* old_name,
   int prefix_len = strlen (prefix);
   int suffix_len = strlen (suffix);
   int i = prefix_len + old_length + suffix_len + 1;
   int prefix_len = strlen (prefix);
   int suffix_len = strlen (suffix);
   int i = prefix_len + old_length + suffix_len + 1;
-  char *buffer = alloca (i);
+  char *buffer = (char *) alloca (i);
 
   strcpy (buffer, prefix);
   for (i = 0; i < old_length; i++)
 
   strcpy (buffer, prefix);
   for (i = 0; i < old_length; i++)
@@ -315,10 +315,63 @@ identifier_subst (const tree old_id,
 tree
 mangled_classname (const char *prefix, tree type)
 {
 tree
 mangled_classname (const char *prefix, tree type)
 {
+  tree result;
   tree ident = TYPE_NAME (type);
   if (TREE_CODE (ident) != IDENTIFIER_NODE)
     ident = DECL_NAME (ident);
   tree ident = TYPE_NAME (type);
   if (TREE_CODE (ident) != IDENTIFIER_NODE)
     ident = DECL_NAME (ident);
-  return identifier_subst (ident, prefix, '.', '_', "");
+  result = identifier_subst (ident, prefix, '.', '_', "");
+
+  /* Replace any characters that aren't in the set [0-9a-zA-Z_$] with
+     "_0xXX".  Class names containing such chracters are uncommon, but
+     they do sometimes occur in class files.  Without this check,
+     these names cause assembly errors.
+
+     There is a possibility that a real class name could conflict with
+     the identifier we generate, but it is unlikely and will
+     immediately be detected as an assembler error.  At some point we
+     should do something more elaborate (perhaps using the full
+     unicode mangling scheme) in order to prevent such a conflict.  */
+  {
+    int i;
+    const int len = IDENTIFIER_LENGTH (result);
+    const char *p = IDENTIFIER_POINTER (result);
+    int illegal_chars = 0;
+
+    /* Make two passes over the identifier.  The first pass is merely
+       to count illegal characters; we need to do this in order to
+       allocate a buffer.  */
+    for (i = 0; i < len; i++)
+      {
+       char c = p[i];
+       illegal_chars += (! ISALNUM (c) && c != '_' && c != '$');
+      }
+
+    /* And the second pass, which is rarely executed, does the
+       rewriting.  */
+    if (illegal_chars != 0)
+      {
+       char *buffer = (char *) alloca (illegal_chars * 4 + len + 1);
+       int j;
+
+       for (i = 0, j = 0; i < len; i++)
+         {
+           char c = p[i];
+           if (! ISALNUM (c) && c != '_' && c != '$')
+             {
+               buffer[j++] = '_';
+               sprintf (&buffer[j], "0x%02x", c);
+               j += 4;
+             }
+           else
+             buffer[j++] = c;
+         }
+
+       buffer[j] = 0;
+       result = get_identifier (buffer);
+      }
+  }
+
+  return result;
 }
 
 tree
 }
 
 tree
@@ -360,11 +413,12 @@ unmangle_classname (const char *name, int name_length)
 #define GEN_TABLE(TABLE, NAME, TABLE_TYPE, TYPE)                       \
 do                                                                     \
 {                                                                      \
 #define GEN_TABLE(TABLE, NAME, TABLE_TYPE, TYPE)                       \
 do                                                                     \
 {                                                                      \
-  const char *typename = IDENTIFIER_POINTER (mangled_classname ("", TYPE)); \
-  char *buf = alloca (strlen (typename) + strlen (#NAME "_syms_") + 1);        \
+  const char *type_name = IDENTIFIER_POINTER (mangled_classname ("", TYPE)); \
+  char *buf = (char *) alloca (strlen (type_name)                      \
+                               + strlen (#NAME "_syms_") + 1);         \
   tree decl;                                                           \
                                                                        \
   tree decl;                                                           \
                                                                        \
-  sprintf (buf, #NAME "_%s", typename);                                        \
+  sprintf (buf, #NAME "_%s", type_name);                               \
   TYPE_## TABLE ##_DECL (type) = decl =                                        \
     build_decl (VAR_DECL, get_identifier (buf), TABLE_TYPE);           \
   DECL_EXTERNAL (decl) = 1;                                            \
   TYPE_## TABLE ##_DECL (type) = decl =                                        \
     build_decl (VAR_DECL, get_identifier (buf), TABLE_TYPE);           \
   DECL_EXTERNAL (decl) = 1;                                            \
@@ -376,7 +430,7 @@ do                                                                  \
   pushdecl (decl);                                                     \
   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);                          \
   DECL_OWNER (decl) = TYPE;                                            \
   pushdecl (decl);                                                     \
   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);                          \
   DECL_OWNER (decl) = TYPE;                                            \
-  sprintf (buf, #NAME "_syms_%s", typename);                           \
+  sprintf (buf, #NAME "_syms_%s", type_name);                          \
   TYPE_## TABLE ##_SYMS_DECL (TYPE) =                                  \
     build_decl (VAR_DECL, get_identifier (buf), symbols_array_type);   \
   TREE_STATIC (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1;                 \
   TYPE_## TABLE ##_SYMS_DECL (TYPE) =                                  \
     build_decl (VAR_DECL, get_identifier (buf), symbols_array_type);   \
   TREE_STATIC (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1;                 \
@@ -390,13 +444,14 @@ while (0)
 void
 gen_indirect_dispatch_tables (tree type)
 {
 void
 gen_indirect_dispatch_tables (tree type)
 {
-  const char *typename = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+  const char *type_name = IDENTIFIER_POINTER (mangled_classname ("", type));
   {  
     tree field = NULL;
   {  
     tree field = NULL;
-    char *buf = alloca (strlen (typename) + strlen ("_catch_classes_") + 1);
+    char *buf = (char *) alloca (strlen (type_name)
+                                + strlen ("_catch_classes_") + 1);
     tree catch_class_type = make_node (RECORD_TYPE);
 
     tree catch_class_type = make_node (RECORD_TYPE);
 
-    sprintf (buf, "_catch_classes_%s", typename);
+    sprintf (buf, "_catch_classes_%s", type_name);
     PUSH_FIELD (catch_class_type, field, "address", utf8const_ptr_type);
     PUSH_FIELD (catch_class_type, field, "classname", ptr_type_node);
     FINISH_RECORD (catch_class_type);
     PUSH_FIELD (catch_class_type, field, "address", utf8const_ptr_type);
     PUSH_FIELD (catch_class_type, field, "classname", ptr_type_node);
     FINISH_RECORD (catch_class_type);
@@ -427,11 +482,6 @@ push_class (tree class_type, tree class_name)
 {
   tree decl, signature;
   location_t saved_loc = input_location;
 {
   tree decl, signature;
   location_t saved_loc = input_location;
-#ifndef USE_MAPPED_LOCATION
-  tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
-  input_filename = IDENTIFIER_POINTER (source_name);
-  input_line = 0;
-#endif
   CLASS_P (class_type) = 1;
   decl = build_decl (TYPE_DECL, class_name, class_type);
   TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
   CLASS_P (class_type) = 1;
   decl = build_decl (TYPE_DECL, class_name, class_type);
   TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
@@ -691,6 +741,15 @@ build_java_method_type (tree fntype, tree this_class, int access_flags)
   return fntype;
 }
 
   return fntype;
 }
 
+void
+java_hide_decl (tree decl ATTRIBUTE_UNUSED)
+{
+#ifdef HAVE_GAS_HIDDEN
+  DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+  DECL_VISIBILITY_SPECIFIED (decl) = 1;
+#endif
+}
+
 tree
 add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
 {
 tree
 add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
 {
@@ -703,7 +762,7 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
   DECL_CONTEXT (fndecl) = this_class;
 
   DECL_LANG_SPECIFIC (fndecl)
   DECL_CONTEXT (fndecl) = this_class;
 
   DECL_LANG_SPECIFIC (fndecl)
-    = ggc_alloc_cleared (sizeof (struct lang_decl));
+    = GGC_CNEW (struct lang_decl);
   DECL_LANG_SPECIFIC (fndecl)->desc = LANG_DECL_FUNC;
 
   /* Initialize the static initializer test table.  */
   DECL_LANG_SPECIFIC (fndecl)->desc = LANG_DECL_FUNC;
 
   /* Initialize the static initializer test table.  */
@@ -719,6 +778,14 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
   TREE_CHAIN (fndecl) = TYPE_METHODS (this_class);
   TYPE_METHODS (this_class) = fndecl;
 
   TREE_CHAIN (fndecl) = TYPE_METHODS (this_class);
   TYPE_METHODS (this_class) = fndecl;
 
+  /* If pointers to member functions use the least significant bit to
+     indicate whether a function is virtual, ensure a pointer
+     to this function will have that bit clear.  */
+  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+      && !(access_flags & ACC_STATIC)
+      && DECL_ALIGN (fndecl) < 2 * BITS_PER_UNIT)
+    DECL_ALIGN (fndecl) = 2 * BITS_PER_UNIT;
+
   /* Notice that this is a finalizer and update the class type
      accordingly. This is used to optimize instance allocation. */
   if (name == finalize_identifier_node
   /* Notice that this is a finalizer and update the class type
      accordingly. This is used to optimize instance allocation. */
   if (name == finalize_identifier_node
@@ -729,7 +796,7 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
   if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
   if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
   if (access_flags & ACC_PRIVATE)
   if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
   if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
   if (access_flags & ACC_PRIVATE)
-    METHOD_PRIVATE (fndecl) = DECL_INLINE (fndecl) = 1;
+    METHOD_PRIVATE (fndecl) = 1;
   if (access_flags & ACC_NATIVE)
     {
       METHOD_NATIVE (fndecl) = 1;
   if (access_flags & ACC_NATIVE)
     {
       METHOD_NATIVE (fndecl) = 1;
@@ -740,9 +807,9 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
        file.  */
     DECL_EXTERNAL (fndecl) = CLASS_FROM_CURRENTLY_COMPILED_P (this_class) == 0;
   if (access_flags & ACC_STATIC) 
        file.  */
     DECL_EXTERNAL (fndecl) = CLASS_FROM_CURRENTLY_COMPILED_P (this_class) == 0;
   if (access_flags & ACC_STATIC) 
-    METHOD_STATIC (fndecl) = DECL_INLINE (fndecl) = 1;
+    METHOD_STATIC (fndecl) = 1;
   if (access_flags & ACC_FINAL) 
   if (access_flags & ACC_FINAL) 
-    METHOD_FINAL (fndecl) = DECL_INLINE (fndecl) = 1;
+    METHOD_FINAL (fndecl) = 1;
   if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;
   if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;
   if (access_flags & ACC_STRICT) METHOD_STRICTFP (fndecl) = 1;
   if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;
   if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;
   if (access_flags & ACC_STRICT) METHOD_STRICTFP (fndecl) = 1;
@@ -773,14 +840,14 @@ add_method (tree this_class, int access_flags, tree name, tree method_sig)
 }
 
 tree
 }
 
 tree
-add_field (tree class, tree name, tree field_type, int flags)
+add_field (tree klass, tree name, tree field_type, int flags)
 {
   int is_static = (flags & ACC_STATIC) != 0;
   tree field;
   field = build_decl (is_static ? VAR_DECL : FIELD_DECL, name, field_type);
 {
   int is_static = (flags & ACC_STATIC) != 0;
   tree field;
   field = build_decl (is_static ? VAR_DECL : FIELD_DECL, name, field_type);
-  TREE_CHAIN (field) = TYPE_FIELDS (class);
-  TYPE_FIELDS (class) = field;
-  DECL_CONTEXT (field) = class;
+  TREE_CHAIN (field) = TYPE_FIELDS (klass);
+  TYPE_FIELDS (klass) = field;
+  DECL_CONTEXT (field) = klass;
   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field);
 
   if (flags & ACC_PUBLIC) FIELD_PUBLIC (field) = 1;
   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field);
 
   if (flags & ACC_PUBLIC) FIELD_PUBLIC (field) = 1;
@@ -801,9 +868,13 @@ add_field (tree class, tree name, tree field_type, int flags)
       /* Always make field externally visible.  This is required so
         that native methods can always access the field.  */
       TREE_PUBLIC (field) = 1;
       /* Always make field externally visible.  This is required so
         that native methods can always access the field.  */
       TREE_PUBLIC (field) = 1;
+      /* Hide everything that shouldn't be visible outside a DSO.  */
+      if (flag_indirect_classes
+         || (FIELD_PRIVATE (field)))
+       java_hide_decl (field);
       /* Considered external unless we are compiling it into this
         object file.  */
       /* Considered external unless we are compiling it into this
         object file.  */
-      DECL_EXTERNAL (field) = (is_compiled_class (class) != 2);
+      DECL_EXTERNAL (field) = (is_compiled_class (klass) != 2);
     }
 
   return field;
     }
 
   return field;
@@ -832,8 +903,6 @@ set_constant_value (tree field, tree constant)
                && TREE_TYPE (field) == string_ptr_type_node))
        error ("ConstantValue attribute of field '%s' has wrong type",
               IDENTIFIER_POINTER (DECL_NAME (field)));
                && TREE_TYPE (field) == string_ptr_type_node))
        error ("ConstantValue attribute of field '%s' has wrong type",
               IDENTIFIER_POINTER (DECL_NAME (field)));
-      if (FIELD_FINAL (field))
-       DECL_FIELD_FINAL_IUD (field) = 1;
     }
 }
 
     }
 }
 
@@ -862,8 +931,8 @@ static GTY(()) tree utf8_decl_list = NULL_TREE;
 tree
 build_utf8_ref (tree name)
 {
 tree
 build_utf8_ref (tree name)
 {
-  const char * name_ptr = IDENTIFIER_POINTER(name);
-  int name_len = IDENTIFIER_LENGTH(name);
+  const char * name_ptr = IDENTIFIER_POINTER (name);
+  int name_len = IDENTIFIER_LENGTH (name), name_pad;
   char buf[60];
   tree ctype, field = NULL_TREE, str_type, cinit, string;
   static int utf8_count = 0;
   char buf[60];
   tree ctype, field = NULL_TREE, str_type, cinit, string;
   static int utf8_count = 0;
@@ -874,8 +943,11 @@ build_utf8_ref (tree name)
     return ref;
 
   ctype = make_node (RECORD_TYPE);
     return ref;
 
   ctype = make_node (RECORD_TYPE);
+  /* '\0' byte plus padding to utf8const_type's alignment.  */
+  name_pad = TYPE_ALIGN_UNIT (utf8const_type)
+            - (name_len & (TYPE_ALIGN_UNIT (utf8const_type) - 1));
   str_type = build_prim_array_type (unsigned_byte_type_node,
   str_type = build_prim_array_type (unsigned_byte_type_node,
-                                   name_len + 1); /* Allow for final '\0'. */
+                                   name_len + name_pad);
   PUSH_FIELD (ctype, field, "hash", unsigned_short_type_node);
   PUSH_FIELD (ctype, field, "length", unsigned_short_type_node);
   PUSH_FIELD (ctype, field, "data", str_type);
   PUSH_FIELD (ctype, field, "hash", unsigned_short_type_node);
   PUSH_FIELD (ctype, field, "length", unsigned_short_type_node);
   PUSH_FIELD (ctype, field, "data", str_type);
@@ -889,7 +961,6 @@ build_utf8_ref (tree name)
   PUSH_FIELD_VALUE (cinit, "data", string);
   FINISH_RECORD_CONSTRUCTOR (cinit);
   TREE_CONSTANT (cinit) = 1;
   PUSH_FIELD_VALUE (cinit, "data", string);
   FINISH_RECORD_CONSTRUCTOR (cinit);
   TREE_CONSTANT (cinit) = 1;
-  TREE_INVARIANT (cinit) = 1;
 
   /* Generate a unique-enough identifier.  */
   sprintf(buf, "_Utf%d", ++utf8_count);
 
   /* Generate a unique-enough identifier.  */
   sprintf(buf, "_Utf%d", ++utf8_count);
@@ -906,8 +977,7 @@ build_utf8_ref (tree name)
     {
       int decl_size;
       /* Ensure decl_size is a multiple of utf8const_type's alignment. */
     {
       int decl_size;
       /* Ensure decl_size is a multiple of utf8const_type's alignment. */
-      decl_size = (name_len + 5 + TYPE_ALIGN_UNIT (utf8const_type) - 1)
-       & ~(TYPE_ALIGN_UNIT (utf8const_type) - 1);
+      decl_size = name_len + 4 + name_pad;
       if (flag_merge_constants && decl_size < 256)
        {
          char buf[32];
       if (flag_merge_constants && decl_size < 256)
        {
          char buf[32];
@@ -921,6 +991,8 @@ build_utf8_ref (tree name)
 
   TREE_CHAIN (decl) = utf8_decl_list;
   layout_decl (decl, 0);
 
   TREE_CHAIN (decl) = utf8_decl_list;
   layout_decl (decl, 0);
+  DECL_SIZE (decl) = TYPE_SIZE (ctype);
+  DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (ctype);
   pushdecl (decl);
   rest_of_decl_compilation (decl, global_bindings_p (), 0);
   varpool_mark_needed_node (varpool_node (decl));
   pushdecl (decl);
   rest_of_decl_compilation (decl, global_bindings_p (), 0);
   varpool_mark_needed_node (varpool_node (decl));
@@ -958,7 +1030,11 @@ build_static_class_ref (tree type)
       decl = build_decl (VAR_DECL, decl_name, class_type_node);
       TREE_STATIC (decl) = 1;
       if (! flag_indirect_classes)
       decl = build_decl (VAR_DECL, decl_name, class_type_node);
       TREE_STATIC (decl) = 1;
       if (! flag_indirect_classes)
-       TREE_PUBLIC (decl) = 1;
+       {
+         TREE_PUBLIC (decl) = 1;
+         if (CLASS_PRIVATE (TYPE_NAME (type)))
+           java_hide_decl (decl);
+       }
       DECL_IGNORED_P (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
       if (is_compiled_class (type) == 1)
       DECL_IGNORED_P (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
       if (is_compiled_class (type) == 1)
@@ -993,10 +1069,10 @@ build_classdollar_field (tree type)
                                             /* const */ 1, 0)),
                        /* const */ 1, 0)));
       TREE_STATIC (decl) = 1;
                                             /* const */ 1, 0)),
                        /* const */ 1, 0)));
       TREE_STATIC (decl) = 1;
-      TREE_INVARIANT (decl) = 1;
       TREE_CONSTANT (decl) = 1;
       TREE_READONLY (decl) = 1;
       TREE_PUBLIC (decl) = 1;
       TREE_CONSTANT (decl) = 1;
       TREE_READONLY (decl) = 1;
       TREE_PUBLIC (decl) = 1;
+      java_hide_decl (decl);
       DECL_IGNORED_P (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
       DECL_IGNORED_P (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
@@ -1008,7 +1084,7 @@ build_classdollar_field (tree type)
   return decl;
 }
 
   return decl;
 }
 
-/* Create a local variable that holds the the current class$.  */
+/* Create a local variable that holds the current class$.  */
 
 void
 cache_this_class_ref (tree fndecl)
 
 void
 cache_this_class_ref (tree fndecl)
@@ -1039,10 +1115,8 @@ cache_this_class_ref (tree fndecl)
       && ! DECL_CLINIT_P (fndecl)
       && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl))))
     {
       && ! DECL_CLINIT_P (fndecl)
       && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl))))
     {
-      tree init = build3 (CALL_EXPR, void_type_node,
-                         build_address_of (soft_initclass_node),
-                         build_tree_list (NULL_TREE, this_classdollar),
-                         NULL_TREE);
+      tree init = build_call_expr (soft_initclass_node, 1,
+                                  this_classdollar);
       java_add_stmt (init);
     }
 }
       java_add_stmt (init);
     }
 }
@@ -1075,7 +1149,13 @@ build_class_ref (tree type)
        return build_indirect_class_ref (type);
 
       if (type == output_class && flag_indirect_classes)
        return build_indirect_class_ref (type);
 
       if (type == output_class && flag_indirect_classes)
-       return this_classdollar;
+       {
+         /* This can be NULL if we see a JNI stub before we see any
+            other method.  */
+         if (! this_classdollar)
+           this_classdollar = build_classdollar_field (output_class);
+         return this_classdollar;
+       }
       
       if (TREE_CODE (type) == RECORD_TYPE)
        return build_static_class_ref (type);
       
       if (TREE_CODE (type) == RECORD_TYPE)
        return build_static_class_ref (type);
@@ -1119,7 +1199,7 @@ build_fieldref_cache_entry (int index, tree fdecl ATTRIBUTE_UNUSED)
 {
   tree decl, decl_name;
   const char *name = IDENTIFIER_POINTER (mangled_classname ("_cpool_", output_class));
 {
   tree decl, decl_name;
   const char *name = IDENTIFIER_POINTER (mangled_classname ("_cpool_", output_class));
-  char *buf = alloca (strlen (name) + 20);
+  char *buf = (char *) alloca (strlen (name) + 20);
   sprintf (buf, "%s_%d_ref", name, index);
   decl_name = get_identifier (buf);
   decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
   sprintf (buf, "%s_%d_ref", name, index);
   decl_name = get_identifier (buf);
   decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
@@ -1141,13 +1221,12 @@ build_static_field_ref (tree fdecl)
 {
   tree fclass = DECL_CONTEXT (fdecl);
   int is_compiled = is_compiled_class (fclass);
 {
   tree fclass = DECL_CONTEXT (fdecl);
   int is_compiled = is_compiled_class (fclass);
-  int from_class = ! CLASS_FROM_SOURCE_P (current_class);
 
   /* Allow static final fields to fold to a constant.  When using
      -findirect-dispatch, we simply never do this folding if compiling
      from .class; in the .class file constants will be referred to via
      the constant pool.  */
 
   /* Allow static final fields to fold to a constant.  When using
      -findirect-dispatch, we simply never do this folding if compiling
      from .class; in the .class file constants will be referred to via
      the constant pool.  */
-  if ((!flag_indirect_dispatch || !from_class)
+  if (!flag_indirect_dispatch
       && (is_compiled
          || (FIELD_FINAL (fdecl) && DECL_INITIAL (fdecl) != NULL_TREE
              && (JSTRING_TYPE_P (TREE_TYPE (fdecl))
       && (is_compiled
          || (FIELD_FINAL (fdecl) && DECL_INITIAL (fdecl) != NULL_TREE
              && (JSTRING_TYPE_P (TREE_TYPE (fdecl))
@@ -1177,20 +1256,16 @@ build_static_field_ref (tree fdecl)
 
       int cpool_index = alloc_constant_fieldref (output_class, fdecl);
       tree cache_entry = build_fieldref_cache_entry (cpool_index, fdecl);
 
       int cpool_index = alloc_constant_fieldref (output_class, fdecl);
       tree cache_entry = build_fieldref_cache_entry (cpool_index, fdecl);
-      tree test 
-       = build3 (CALL_EXPR, boolean_type_node, 
-                 build_address_of (built_in_decls[BUILT_IN_EXPECT]),
-                 tree_cons (NULL_TREE, build2 (EQ_EXPR, boolean_type_node,
-                                               cache_entry, null_pointer_node),
-                            build_tree_list (NULL_TREE, boolean_false_node)),
-                 NULL_TREE);
+      tree test
+        = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2,
+                          build2 (EQ_EXPR, boolean_type_node,
+                                  cache_entry, null_pointer_node),
+                          boolean_false_node);
       tree cpool_index_cst = build_int_cst (NULL_TREE, cpool_index);
       tree init
       tree cpool_index_cst = build_int_cst (NULL_TREE, cpool_index);
       tree init
-       = build3 (CALL_EXPR, ptr_type_node,
-                 build_address_of (soft_resolvepoolentry_node),
-                 tree_cons (NULL_TREE, build_class_ref (output_class),
-                            build_tree_list (NULL_TREE, cpool_index_cst)),
-                 NULL_TREE);
+       = build_call_expr (soft_resolvepoolentry_node, 2,
+                          build_class_ref (output_class),
+                          cpool_index_cst);
       init = build2 (MODIFY_EXPR, ptr_type_node, cache_entry, init);
       init = build3 (COND_EXPR, ptr_type_node, test, init, cache_entry);
       init = fold_convert (build_pointer_type (TREE_TYPE (fdecl)), init);
       init = build2 (MODIFY_EXPR, ptr_type_node, cache_entry, init);
       init = build3 (COND_EXPR, ptr_type_node, test, init, cache_entry);
       init = fold_convert (build_pointer_type (TREE_TYPE (fdecl)), init);
@@ -1299,8 +1374,8 @@ make_local_function_alias (tree method)
   tree alias;
   
   const char *method_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (method));
   tree alias;
   
   const char *method_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (method));
-  char *name = alloca (strlen (method_name) + 2);
-  char *buf = alloca (strlen (method_name) + 128);
+  char *name = (char *) alloca (strlen (method_name) + 2);
+  char *buf = (char *) alloca (strlen (method_name) + 128);
 
   /* Only create aliases for local functions.  */
   if (DECL_EXTERNAL (method))
 
   /* Only create aliases for local functions.  */
   if (DECL_EXTERNAL (method))
@@ -1319,7 +1394,6 @@ make_local_function_alias (tree method)
   TREE_PUBLIC (alias) = 0;
   DECL_EXTERNAL (alias) = 0;
   DECL_ARTIFICIAL (alias) = 1;
   TREE_PUBLIC (alias) = 0;
   DECL_EXTERNAL (alias) = 0;
   DECL_ARTIFICIAL (alias) = 1;
-  DECL_INLINE (alias) = 0;
   DECL_INITIAL (alias) = error_mark_node;
   TREE_ADDRESSABLE (alias) = 1;
   TREE_USED (alias) = 1;
   DECL_INITIAL (alias) = error_mark_node;
   TREE_ADDRESSABLE (alias) = 1;
   TREE_USED (alias) = 1;
@@ -1540,7 +1614,6 @@ get_dispatch_table (tree type, tree this_class_addr)
                tree fdesc = build2 (FDESC_EXPR, nativecode_ptr_type_node, 
                                     method, build_int_cst (NULL_TREE, j));
                TREE_CONSTANT (fdesc) = 1;
                tree fdesc = build2 (FDESC_EXPR, nativecode_ptr_type_node, 
                                     method, build_int_cst (NULL_TREE, j));
                TREE_CONSTANT (fdesc) = 1;
-               TREE_INVARIANT (fdesc) = 1;
                list = tree_cons (NULL_TREE, fdesc, list);
              }
          else
                list = tree_cons (NULL_TREE, fdesc, list);
              }
          else
@@ -1660,8 +1733,7 @@ make_class_data (tree type)
   tree id_class = get_identifier("java.lang.Class");
   /** Offset from start of virtual function table declaration
       to where objects actually point at, following new g++ ABI. */
   tree id_class = get_identifier("java.lang.Class");
   /** Offset from start of virtual function table declaration
       to where objects actually point at, following new g++ ABI. */
-  tree dtable_start_offset = build_int_cst (NULL_TREE,
-                                           2 * POINTER_SIZE / BITS_PER_UNIT);
+  tree dtable_start_offset = size_int (2 * POINTER_SIZE / BITS_PER_UNIT);
   VEC(int, heap) *field_indexes;
   tree first_real_field;
 
   VEC(int, heap) *field_indexes;
   tree first_real_field;
 
@@ -1690,6 +1762,10 @@ make_class_data (tree type)
 
       TREE_PUBLIC (dtable_decl) = 1;
       DECL_INITIAL (dtable_decl) = dtable;
 
       TREE_PUBLIC (dtable_decl) = 1;
       DECL_INITIAL (dtable_decl) = dtable;
+      /* The only dispatch table exported from a DSO is the dispatch
+        table for java.lang.Class.  */
+      if (DECL_NAME (type_decl) != id_class)
+       java_hide_decl (dtable_decl);
       if (! flag_indirect_classes)
        rest_of_decl_compilation (dtable_decl, 1, 0);
       /* Maybe we're compiling Class as the first class.  If so, set
       if (! flag_indirect_classes)
        rest_of_decl_compilation (dtable_decl, 1, 0);
       /* Maybe we're compiling Class as the first class.  If so, set
@@ -1745,6 +1821,8 @@ make_class_data (tree type)
            field_index = static_count++;
          else if (uses_jv_markobj || !flag_reduced_reflection)
            field_index = instance_count++;
            field_index = static_count++;
          else if (uses_jv_markobj || !flag_reduced_reflection)
            field_index = instance_count++;
+         else
+           continue;
          VEC_quick_push (int, field_indexes, field_index);
        }
     }
          VEC_quick_push (int, field_indexes, field_index);
        }
     }
@@ -1832,8 +1910,7 @@ make_class_data (tree type)
           || DECL_CLINIT_P (method)
           || DECL_NAME (type_decl) == id_class
           || DECL_NAME (method) == id_main
           || DECL_CLINIT_P (method)
           || DECL_NAME (type_decl) == id_class
           || DECL_NAME (method) == id_main
-          || (METHOD_PUBLIC (method) && !METHOD_STATIC (method))
-          || TYPE_DOT_CLASS (type) == method)
+          || (METHOD_PUBLIC (method) && !METHOD_STATIC (method)))
         {
           init = make_method_value (method);
           method_count++;
         {
           init = make_method_value (method);
           method_count++;
@@ -1944,7 +2021,7 @@ make_class_data (tree type)
   PUSH_FIELD_VALUE (temp, "vtable",
                    (flag_indirect_classes 
                     ? null_pointer_node
   PUSH_FIELD_VALUE (temp, "vtable",
                    (flag_indirect_classes 
                     ? null_pointer_node
-                    : build2 (PLUS_EXPR, dtable_ptr_type,
+                    : build2 (POINTER_PLUS_EXPR, dtable_ptr_type,
                               build1 (ADDR_EXPR, dtable_ptr_type,
                                       class_dtable_decl),
                               dtable_start_offset)));
                               build1 (ADDR_EXPR, dtable_ptr_type,
                                       class_dtable_decl),
                               dtable_start_offset)));
@@ -1992,7 +2069,7 @@ make_class_data (tree type)
   else
     PUSH_FIELD_VALUE (cons, "vtable",
                      dtable_decl == NULL_TREE ? null_pointer_node
   else
     PUSH_FIELD_VALUE (cons, "vtable",
                      dtable_decl == NULL_TREE ? null_pointer_node
-                     : build2 (PLUS_EXPR, dtable_ptr_type,
+                     : build2 (POINTER_PLUS_EXPR, dtable_ptr_type,
                                build1 (ADDR_EXPR, dtable_ptr_type,
                                        dtable_decl),
                                dtable_start_offset));
                                build1 (ADDR_EXPR, dtable_ptr_type,
                                        dtable_decl),
                                dtable_start_offset));
@@ -2010,7 +2087,6 @@ make_class_data (tree type)
                        build1 (ADDR_EXPR, symbols_array_ptr_type,
                                TYPE_OTABLE_SYMS_DECL (type)));
       TREE_CONSTANT (TYPE_OTABLE_DECL (type)) = 1;
                        build1 (ADDR_EXPR, symbols_array_ptr_type,
                                TYPE_OTABLE_SYMS_DECL (type)));
       TREE_CONSTANT (TYPE_OTABLE_DECL (type)) = 1;
-      TREE_INVARIANT (TYPE_OTABLE_DECL (type)) = 1;
     }
   if (TYPE_ATABLE_METHODS(type) == NULL_TREE)
     {
     }
   if (TYPE_ATABLE_METHODS(type) == NULL_TREE)
     {
@@ -2026,7 +2102,6 @@ make_class_data (tree type)
                        build1 (ADDR_EXPR, symbols_array_ptr_type,
                                TYPE_ATABLE_SYMS_DECL (type)));
       TREE_CONSTANT (TYPE_ATABLE_DECL (type)) = 1;
                        build1 (ADDR_EXPR, symbols_array_ptr_type,
                                TYPE_ATABLE_SYMS_DECL (type)));
       TREE_CONSTANT (TYPE_ATABLE_DECL (type)) = 1;
-      TREE_INVARIANT (TYPE_ATABLE_DECL (type)) = 1;
     }
    if (TYPE_ITABLE_METHODS(type) == NULL_TREE)
     {
     }
    if (TYPE_ITABLE_METHODS(type) == NULL_TREE)
     {
@@ -2042,7 +2117,6 @@ make_class_data (tree type)
                        build1 (ADDR_EXPR, symbols_array_ptr_type,
                                TYPE_ITABLE_SYMS_DECL (type)));
       TREE_CONSTANT (TYPE_ITABLE_DECL (type)) = 1;
                        build1 (ADDR_EXPR, symbols_array_ptr_type,
                                TYPE_ITABLE_SYMS_DECL (type)));
       TREE_CONSTANT (TYPE_ITABLE_DECL (type)) = 1;
-      TREE_INVARIANT (TYPE_ITABLE_DECL (type)) = 1;
     }
  
   PUSH_FIELD_VALUE (cons, "catch_classes",
     }
  
   PUSH_FIELD_VALUE (cons, "catch_classes",
@@ -2152,17 +2226,6 @@ make_class_data (tree type)
 void
 finish_class (void)
 {
 void
 finish_class (void)
 {
-  if (TYPE_VERIFY_METHOD (output_class))
-    {
-      tree verify_method = TYPE_VERIFY_METHOD (output_class);
-      DECL_SAVED_TREE (verify_method) 
-       = add_stmt_to_compound (DECL_SAVED_TREE (verify_method), void_type_node,
-                               build1 (RETURN_EXPR, void_type_node, NULL));
-      java_genericize (verify_method);
-      cgraph_finalize_function (verify_method, false);
-      TYPE_ASSERTIONS (current_class) = NULL;
-    }
-
   java_expand_catch_classes (current_class);
 
   current_function_decl = NULL_TREE;
   java_expand_catch_classes (current_class);
 
   current_function_decl = NULL_TREE;
@@ -2172,45 +2235,43 @@ finish_class (void)
   rest_of_decl_compilation (TYPE_NAME (current_class), 1, 0);
 }
 
   rest_of_decl_compilation (TYPE_NAME (current_class), 1, 0);
 }
 
-/* Return 2 if CLASS is compiled by this compilation job;
-   return 1 if CLASS can otherwise be assumed to be compiled;
-   return 0 if we cannot assume that CLASS is compiled.
+/* Return 2 if KLASS is compiled by this compilation job;
+   return 1 if KLASS can otherwise be assumed to be compiled;
+   return 0 if we cannot assume that KLASS is compiled.
    Returns 1 for primitive and 0 for array types.  */
 int
    Returns 1 for primitive and 0 for array types.  */
 int
-is_compiled_class (tree class)
+is_compiled_class (tree klass)
 {
   int seen_in_zip;
 {
   int seen_in_zip;
-  if (TREE_CODE (class) == POINTER_TYPE)
-    class = TREE_TYPE (class);
-  if (TREE_CODE (class) != RECORD_TYPE)  /* Primitive types are static. */
+  if (TREE_CODE (klass) == POINTER_TYPE)
+    klass = TREE_TYPE (klass);
+  if (TREE_CODE (klass) != RECORD_TYPE)  /* Primitive types are static. */
     return 1;
     return 1;
-  if (TYPE_ARRAY_P (class))
+  if (TYPE_ARRAY_P (klass))
     return 0;
 
     return 0;
 
-  seen_in_zip = (TYPE_JCF (class) && JCF_SEEN_IN_ZIP (TYPE_JCF (class)));
-  if (CLASS_FROM_CURRENTLY_COMPILED_P (class))
+  seen_in_zip = (TYPE_JCF (klass) && JCF_SEEN_IN_ZIP (TYPE_JCF (klass)));
+  if (CLASS_FROM_CURRENTLY_COMPILED_P (klass))
     {
       /* The class was seen in the current ZIP file and will be
         available as a compiled class in the future but may not have
         been loaded already. Load it if necessary. This prevent
         build_class_ref () from crashing. */
 
     {
       /* The class was seen in the current ZIP file and will be
         available as a compiled class in the future but may not have
         been loaded already. Load it if necessary. This prevent
         build_class_ref () from crashing. */
 
-      if (seen_in_zip && !CLASS_LOADED_P (class) && (class != current_class))
-        load_class (class, 1);
+      if (seen_in_zip && !CLASS_LOADED_P (klass) && (klass != current_class))
+        load_class (klass, 1);
 
       /* We return 2 for class seen in ZIP and class from files
          belonging to the same compilation unit */
       return 2;
     }
 
 
       /* We return 2 for class seen in ZIP and class from files
          belonging to the same compilation unit */
       return 2;
     }
 
-  if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class)))))
+  if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (klass)))))
     {
     {
-      if (!CLASS_LOADED_P (class))
+      if (!CLASS_LOADED_P (klass))
        {
        {
-         if (CLASS_FROM_SOURCE_P (class))
-           safe_layout_class (class);
-         else if (class != current_class)
-           load_class (class, 1);
+         if (klass != current_class)
+           load_class (klass, 1);
        }
       return 1;
     }
        }
       return 1;
     }
@@ -2306,8 +2367,6 @@ maybe_layout_super_class (tree super_class, tree this_class ATTRIBUTE_UNUSED)
     return NULL_TREE;
   else if (TREE_CODE (super_class) == RECORD_TYPE)
     {
     return NULL_TREE;
   else if (TREE_CODE (super_class) == RECORD_TYPE)
     {
-      if (!CLASS_LOADED_P (super_class) && CLASS_FROM_SOURCE_P (super_class))
-       safe_layout_class (super_class);
       if (!CLASS_LOADED_P (super_class))
        load_class (super_class, 1);
     }
       if (!CLASS_LOADED_P (super_class))
        load_class (super_class, 1);
     }
@@ -2331,12 +2390,12 @@ maybe_layout_super_class (tree super_class, tree this_class ATTRIBUTE_UNUSED)
    about the class processed currently.  */
 
 void
    about the class processed currently.  */
 
 void
-safe_layout_class (tree class)
+safe_layout_class (tree klass)
 {
   tree save_current_class = current_class;
   location_t save_location = input_location;
 
 {
   tree save_current_class = current_class;
   location_t save_location = input_location;
 
-  layout_class (class);
+  layout_class (klass);
 
   current_class = save_current_class;
   input_location = save_location;
 
   current_class = save_current_class;
   input_location = save_location;
@@ -2345,6 +2404,7 @@ safe_layout_class (tree class)
 void
 layout_class (tree this_class)
 {
 void
 layout_class (tree this_class)
 {
+  int i;
   tree super_class = CLASSTYPE_SUPER (this_class);
 
   class_list = tree_cons (this_class, NULL_TREE, class_list);
   tree super_class = CLASSTYPE_SUPER (this_class);
 
   class_list = tree_cons (this_class, NULL_TREE, class_list);
@@ -2369,7 +2429,7 @@ layout_class (tree this_class)
          obstack_grow (&temporary_obstack, buffer, strlen (buffer));
        }
       obstack_1grow (&temporary_obstack, '\0');
          obstack_grow (&temporary_obstack, buffer, strlen (buffer));
        }
       obstack_1grow (&temporary_obstack, '\0');
-      report = obstack_finish (&temporary_obstack);
+      report = XOBFINISH (&temporary_obstack, char *);
       cyclic_inheritance_report = ggc_strdup (report);
       obstack_free (&temporary_obstack, report);
       TYPE_SIZE (this_class) = error_mark_node;
       cyclic_inheritance_report = ggc_strdup (report);
       obstack_free (&temporary_obstack, report);
       TYPE_SIZE (this_class) = error_mark_node;
@@ -2395,28 +2455,22 @@ layout_class (tree this_class)
 
   layout_type (this_class);
 
 
   layout_type (this_class);
 
-  /* Also recursively load/layout any superinterfaces, but only if
-     class was loaded from bytecode.  The source parser will take care
-     of this itself.  */
-  if (!CLASS_FROM_SOURCE_P (this_class))
+  /* Also recursively load/layout any superinterfaces.  */
+  if (TYPE_BINFO (this_class))
     {
     {
-      int i;
-            if (TYPE_BINFO (this_class))
+      for (i = BINFO_N_BASE_BINFOS (TYPE_BINFO (this_class)) - 1; i > 0; i--)
        {
        {
-         for (i = BINFO_N_BASE_BINFOS (TYPE_BINFO (this_class)) - 1; i > 0; i--)
+         tree binfo = BINFO_BASE_BINFO (TYPE_BINFO (this_class), i);
+         tree super_interface = BINFO_TYPE (binfo);
+         tree maybe_super_interface 
+           = maybe_layout_super_class (super_interface, NULL_TREE);
+         if (maybe_super_interface == NULL
+             || TREE_CODE (TYPE_SIZE (maybe_super_interface)) == ERROR_MARK)
            {
            {
-             tree binfo = BINFO_BASE_BINFO (TYPE_BINFO (this_class), i);
-             tree super_interface = BINFO_TYPE (binfo);
-             tree maybe_super_interface 
-               = maybe_layout_super_class (super_interface, NULL_TREE);
-             if (maybe_super_interface == NULL
-                 || TREE_CODE (TYPE_SIZE (maybe_super_interface)) == ERROR_MARK)
-               {
-                 TYPE_SIZE (this_class) = error_mark_node;
-                 CLASS_BEING_LAIDOUT (this_class) = 0;
-                 class_list = TREE_CHAIN (class_list);
-                 return;
-               }
+             TYPE_SIZE (this_class) = error_mark_node;
+             CLASS_BEING_LAIDOUT (this_class) = 0;
+             class_list = TREE_CHAIN (class_list);
+             return;
            }
        }
     }
            }
        }
     }
@@ -2559,6 +2613,12 @@ layout_class_method (tree this_class, tree super_class,
 
   TREE_PUBLIC (method_decl) = 1;
 
 
   TREE_PUBLIC (method_decl) = 1;
 
+  if (flag_indirect_classes
+      || (METHOD_PRIVATE (method_decl) && METHOD_STATIC (method_decl)
+         && ! METHOD_NATIVE (method_decl)
+         && ! special_method_p (method_decl)))
+    java_hide_decl (method_decl);
+
   /* Considered external unless it is being compiled into this object
      file, or it was already flagged as external.  */
   if (!DECL_EXTERNAL (method_decl))
   /* Considered external unless it is being compiled into this object
      file, or it was already flagged as external.  */
   if (!DECL_EXTERNAL (method_decl))
@@ -2605,7 +2665,6 @@ layout_class_method (tree this_class, tree super_class,
          set_method_index (method_decl, method_index);
          if (method_index == NULL_TREE 
              && ! flag_indirect_dispatch
          set_method_index (method_decl, method_index);
          if (method_index == NULL_TREE 
              && ! flag_indirect_dispatch
-             && !CLASS_FROM_SOURCE_P (this_class)
              && ! DECL_ARTIFICIAL (super_method))
            error ("non-static method %q+D overrides static method",
                    method_decl);
              && ! DECL_ARTIFICIAL (super_method))
            error ("non-static method %q+D overrides static method",
                    method_decl);
@@ -2693,8 +2752,7 @@ emit_indirect_register_classes (tree *list_p)
   TREE_PUBLIC (t) = 1;
   DECL_EXTERNAL (t) = 1;
   register_class_fn = t;
   TREE_PUBLIC (t) = 1;
   DECL_EXTERNAL (t) = 1;
   register_class_fn = t;
-  t = tree_cons (NULL, reg_class_list, NULL);
-  t = build_function_call_expr (register_class_fn, t);
+  t = build_call_expr (register_class_fn, 1, reg_class_list);
   append_to_statement_list (t, list_p);
 }
 
   append_to_statement_list (t, list_p);
 }
 
@@ -2759,8 +2817,7 @@ emit_register_classes (tree *list_p)
       for (i = 0; VEC_iterate (tree, registered_class, i, klass); ++i)
        {
          t = build_fold_addr_expr (klass);
       for (i = 0; VEC_iterate (tree, registered_class, i, klass); ++i)
        {
          t = build_fold_addr_expr (klass);
-         t = tree_cons (NULL, t, NULL);
-         t = build_function_call_expr (register_class_fn, t);
+         t = build_call_expr (register_class_fn, 1, t);
          append_to_statement_list (t, list_p);
        }
     }
          append_to_statement_list (t, list_p);
        }
     }
@@ -2790,7 +2847,8 @@ build_symbol_entry (tree decl, tree special)
      system that this is a "special" symbol, i.e. one that should
      bypass access controls.  */
   if (special != NULL_TREE)
      system that this is a "special" symbol, i.e. one that should
      bypass access controls.  */
   if (special != NULL_TREE)
-    signature = build2 (PLUS_EXPR, TREE_TYPE (signature), signature, special);
+    signature = build2 (POINTER_PLUS_EXPR, TREE_TYPE (signature), signature,
+                       fold_convert (sizetype, special));
       
   START_RECORD_CONSTRUCTOR (sym, symbol_type);
   PUSH_FIELD_VALUE (sym, "clname", clname);
       
   START_RECORD_CONSTRUCTOR (sym, symbol_type);
   PUSH_FIELD_VALUE (sym, "clname", clname);
@@ -2798,7 +2856,6 @@ build_symbol_entry (tree decl, tree special)
   PUSH_FIELD_VALUE (sym, "signature", signature);
   FINISH_RECORD_CONSTRUCTOR (sym);
   TREE_CONSTANT (sym) = 1;
   PUSH_FIELD_VALUE (sym, "signature", signature);
   FINISH_RECORD_CONSTRUCTOR (sym);
   TREE_CONSTANT (sym) = 1;
-  TREE_INVARIANT (sym) = 1;
 
   return sym;
 } 
 
   return sym;
 } 
@@ -2839,7 +2896,6 @@ emit_symbol_table (tree name, tree the_table, tree decl_list,
   PUSH_FIELD_VALUE (null_symbol, "signature", null_pointer_node);
   FINISH_RECORD_CONSTRUCTOR (null_symbol);
   TREE_CONSTANT (null_symbol) = 1;  
   PUSH_FIELD_VALUE (null_symbol, "signature", null_pointer_node);
   FINISH_RECORD_CONSTRUCTOR (null_symbol);
   TREE_CONSTANT (null_symbol) = 1;  
-  TREE_INVARIANT (null_symbol) = 1;  
   list = tree_cons (NULL_TREE, null_symbol, list);
 
   /* Put the list in the right order and make it a constructor. */
   list = tree_cons (NULL_TREE, null_symbol, list);
 
   /* Put the list in the right order and make it a constructor. */
@@ -2962,14 +3018,14 @@ add_assertion_table_entry (void **htab_entry, void *ptr)
   return true;
 }
 
   return true;
 }
 
-/* Generate the type assertion table for CLASS, and return its DECL.  */
+/* Generate the type assertion table for KLASS, and return its DECL.  */
 
 static tree
 
 static tree
-emit_assertion_table (tree class)
+emit_assertion_table (tree klass)
 {
   tree null_entry, ctor, table_decl;
   tree list = NULL_TREE;
 {
   tree null_entry, ctor, table_decl;
   tree list = NULL_TREE;
-  htab_t assertions_htab = TYPE_ASSERTIONS (class);
+  htab_t assertions_htab = TYPE_ASSERTIONS (klass);
 
   /* Iterate through the hash table.  */
   htab_traverse (assertions_htab, add_assertion_table_entry, &list);
 
   /* Iterate through the hash table.  */
   htab_traverse (assertions_htab, add_assertion_table_entry, &list);
@@ -2987,7 +3043,7 @@ emit_assertion_table (tree class)
   list = nreverse (list);
   ctor = build_constructor_from_list (assertion_table_type, list);
 
   list = nreverse (list);
   ctor = build_constructor_from_list (assertion_table_type, list);
 
-  table_decl = build_decl (VAR_DECL, mangled_classname ("_type_assert_", class),
+  table_decl = build_decl (VAR_DECL, mangled_classname ("_type_assert_", klass),
                           assertion_table_type);
 
   TREE_STATIC (table_decl) = 1;
                           assertion_table_type);
 
   TREE_STATIC (table_decl) = 1;
@@ -3016,20 +3072,22 @@ static int java_treetreehash_compare (const void *, const void *);
 
 /* A hash table mapping trees to trees.  Used generally.  */
 
 
 /* A hash table mapping trees to trees.  Used generally.  */
 
-#define JAVA_TREEHASHHASH_H(t) (htab_hash_pointer (t))
+#define JAVA_TREEHASHHASH_H(t) ((hashval_t)TYPE_UID (t))
 
 static hashval_t
 java_treetreehash_hash (const void *k_p)
 {
 
 static hashval_t
 java_treetreehash_hash (const void *k_p)
 {
-  struct treetreehash_entry *k = (struct treetreehash_entry *) k_p;
+  const struct treetreehash_entry *const k
+    = (const struct treetreehash_entry *) k_p;
   return JAVA_TREEHASHHASH_H (k->key);
 }
 
 static int
 java_treetreehash_compare (const void * k1_p, const void * k2_p)
 {
   return JAVA_TREEHASHHASH_H (k->key);
 }
 
 static int
 java_treetreehash_compare (const void * k1_p, const void * k2_p)
 {
-  struct treetreehash_entry * k1 = (struct treetreehash_entry *) k1_p;
-  tree k2 = (tree) k2_p;
+  const struct treetreehash_entry *const k1
+    = (const struct treetreehash_entry *) k1_p;
+  const_tree const k2 = (const_tree) k2_p;
   return (k1->key == k2);
 }
 
   return (k1->key == k2);
 }
 
@@ -3038,7 +3096,7 @@ java_treetreehash_find (htab_t ht, tree t)
 {
   struct treetreehash_entry *e;
   hashval_t hv = JAVA_TREEHASHHASH_H (t);
 {
   struct treetreehash_entry *e;
   hashval_t hv = JAVA_TREEHASHHASH_H (t);
-  e = htab_find_with_hash (ht, t, hv);
+  e = (struct treetreehash_entry *) htab_find_with_hash (ht, t, hv);
   if (e == NULL)
     return NULL;
   else
   if (e == NULL)
     return NULL;
   else
@@ -3055,7 +3113,7 @@ java_treetreehash_new (htab_t ht, tree t)
   e = htab_find_slot_with_hash (ht, t, hv, INSERT);
   if (*e == NULL)
     {
   e = htab_find_slot_with_hash (ht, t, hv, INSERT);
   if (*e == NULL)
     {
-      tthe = (*ht->alloc_f) (1, sizeof (*tthe));
+      tthe = (struct treetreehash_entry *) (*ht->alloc_f) (1, sizeof (*tthe));
       tthe->key = t;
       *e = tthe;
     }
       tthe->key = t;
       *e = tthe;
     }
@@ -3085,7 +3143,7 @@ split_qualified_name (tree *left, tree *right, tree source)
   char *p, *base;
   int l = IDENTIFIER_LENGTH (source);
 
   char *p, *base;
   int l = IDENTIFIER_LENGTH (source);
 
-  base = alloca (l + 1);
+  base = (char *) alloca (l + 1);
   memcpy (base, IDENTIFIER_POINTER (source), l + 1);
 
   /* Breakdown NAME into REMAINDER . IDENTIFIER.  */
   memcpy (base, IDENTIFIER_POINTER (source), l + 1);
 
   /* Breakdown NAME into REMAINDER . IDENTIFIER.  */