OSDN Git Service

PR middle-end/46314
[pf3gnuchains/gcc-fork.git] / gcc / java / jcf-parse.c
index 947f76d..30f171c 100644 (file)
@@ -1,12 +1,12 @@
 /* Parser for Java(TM) .class files.
    Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007 Free Software Foundation, Inc.
+   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,
@@ -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
-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.
@@ -28,23 +27,23 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
 #include "tree.h"
-#include "real.h"
 #include "obstack.h"
 #include "flags.h"
 #include "java-except.h"
 #include "input.h"
 #include "javaop.h"
 #include "java-tree.h"
+#include "diagnostic-core.h"
 #include "toplev.h"
 #include "parse.h"
 #include "ggc.h"
 #include "debug.h"
 #include "assert.h"
-#include "tm_p.h"
 #include "cgraph.h"
 #include "vecprim.h"
+#include "bitmap.h"
+#include "target.h"
 
 #ifdef HAVE_LOCALE_H
 #include <locale.h>
@@ -74,7 +73,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 
 extern struct obstack temporary_obstack;
 
-static GTY(()) tree parse_roots[3];
+static GTY(()) tree parse_roots[2];
 
 /* The FIELD_DECL for the current field.  */
 #define current_field parse_roots[0]
@@ -82,16 +81,16 @@ static GTY(()) tree parse_roots[3];
 /* The METHOD_DECL for the current method.  */
 #define current_method parse_roots[1]
 
-/* A list of TRANSLATION_UNIT_DECLs for the files to be compiled.  */
-#define current_file_list parse_roots[2]
-
 /* Line 0 in current file, if compiling from bytecode. */
 static location_t file_start_location;
 
 /* The Java archive that provides main_class;  the main input file. */
 static GTY(()) struct JCF * main_jcf;
 
-/* The number of source files passd to us by -fsource-filename and an
+/* A list of all the class DECLs seen so far.  */
+static GTY(()) VEC(tree,gc) *all_class_list;
+
+/* The number of source files passed to us by -fsource-filename and an
    array of pointers to each name.  Used by find_sourcefile().  */
 static int num_files = 0;
 static char **filenames;
@@ -146,7 +145,7 @@ reverse (const char *s)
   else
     {
       int len = strlen (s);
-      char *d = xmalloc (len + 1);
+      char *d = XNEWVAR (char, len + 1);
       const char *sp;
       char *dp;
       
@@ -166,7 +165,7 @@ cmpstringp (const void *p1, const void *p2)
      pointers to char", but strcmp() arguments are "pointers
      to char", hence the following cast plus dereference */
 
-  return strcmp(*(char **) p1, *(char **) p2);
+  return strcmp(*(const char *const*) p1, *(const char *const*) p2);
 }
 
 /* Create an array of strings, one for each source file that we've
@@ -214,11 +213,11 @@ java_read_sourcefilenames (const char *fsource_filename)
       /* Read the filenames.  Put a pointer to each filename into the
         array FILENAMES.  */
       {
-       char *linebuf = alloca (longest_line + 1);
+       char *linebuf = (char *) alloca (longest_line + 1);
        int i = 0;
        int charpos;
 
-       filenames = xmalloc (num_files * sizeof (char*));
+       filenames = XNEWVEC (char *, num_files);
 
        charpos = 0;
        for (;;)
@@ -250,7 +249,7 @@ java_read_sourcefilenames (const char *fsource_filename)
     }
   else
     {
-      filenames = xmalloc (sizeof (char*));      
+      filenames = XNEWVEC (char *, 1);      
       filenames[0] = reverse (fsource_filename);
       num_files = 1;
     }
@@ -259,7 +258,7 @@ java_read_sourcefilenames (const char *fsource_filename)
 /* Given a relative pathname such as foo/bar.java, attempt to find a
    longer pathname with the same suffix.  
 
-   This is a best guess heuristic; with some weird class hierarcies we
+   This is a best guess heuristic; with some weird class hierarchies we
    may fail to pick the correct source file.  For example, if we have
    the filenames foo/bar.java and also foo/foo/bar.java, we do not
    have enough information to know which one is the right match for
@@ -328,20 +327,13 @@ set_source_filename (JCF *jcf, int index)
          && strcmp (sfname, old_filename + old_len - new_len) == 0
          && (old_filename[old_len - new_len - 1] == '/'
              || old_filename[old_len - new_len - 1] == '\\'))
-       {
-#ifndef USE_MAPPED_LOCATION
-         input_filename = find_sourcefile (input_filename);
-         DECL_SOURCE_LOCATION (TYPE_NAME (current_class)) = input_location;
-         file_start_location = input_location;
-#endif
-         return;
-       }
+       return;
     }
   if (strchr (sfname, '/') == NULL && strchr (sfname, '\\') == NULL)
     {
       const char *class_name
        = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class)));
-      char *dot = strrchr (class_name, '.');
+      const char *dot = strrchr (class_name, '.');
       if (dot != NULL)
        {
          /* Length of prefix, not counting final dot. */
@@ -365,13 +357,7 @@ set_source_filename (JCF *jcf, int index)
     }
       
   sfname = find_sourcefile (sfname);
-#ifdef USE_MAPPED_LOCATION
-  line_table.maps[line_table.used-1].to_file = sfname;
-#else
-  input_filename = sfname;
-  DECL_SOURCE_LOCATION (TYPE_NAME (current_class)) = input_location;
-  file_start_location = input_location;
-#endif
+  line_table->maps[line_table->used-1].to_file = sfname;
   if (current_class == main_class) main_input_filename = sfname;
 }
 
@@ -381,15 +367,15 @@ set_source_filename (JCF *jcf, int index)
 /* Annotation handling.  
 
    The technique we use here is to copy the annotation data directly
-   from the input class file into the ouput file.  We don't decode the
+   from the input class file into the output file.  We don't decode the
    data at all, merely rewriting constant indexes whenever we come
-   across them: this is necessary becasue the constant pool in the
+   across them: this is necessary because the constant pool in the
    output file isn't the same as the constant pool in in the input.
 
    The main advantage of this technique is that the resulting
    annotation data is pointer-free, so it doesn't have to be relocated
    at startup time.  As a consequence of this, annotations have no
-   peformance impact unless they are used.  Also, this representation
+   performance impact unless they are used.  Also, this representation
    is very dense.  */
 
 
@@ -405,13 +391,13 @@ annotation_grow (int delta)
 
   if (*data == NULL)
     {
-      *data = xmalloc (delta);
+      *data = XNEWVAR (unsigned char, delta);
     }
   else
     {
       int newlen = *datasize + delta;
       if (floor_log2 (newlen) != floor_log2 (*datasize))
-       *data = xrealloc (*data,  2 << (floor_log2 (newlen)));
+       *data = XRESIZEVAR (unsigned char, *data,  2 << (floor_log2 (newlen)));
     }
   *datasize += delta;
   return *data + len;
@@ -512,7 +498,7 @@ handle_long_constant (JCF *jcf, CPool *cpool, enum cpool_tag kind,
 static uint16
 handle_constant (JCF *jcf, int index, enum cpool_tag purpose)
 {
-  enum cpool_tag kind;
+  unsigned int kind;
   CPool *cpool = cpool_for_class (output_class);
   
   if (index == 0)
@@ -569,13 +555,13 @@ handle_constant (JCF *jcf, int index, enum cpool_tag purpose)
       break;
 
     case CONSTANT_Long:
-      index = handle_long_constant (jcf, cpool, kind, index, 
-                                   WORDS_BIG_ENDIAN);
+      index = handle_long_constant (jcf, cpool, CONSTANT_Long, index,
+                                   targetm.words_big_endian ());
       break;
       
     case CONSTANT_Double:
-      index = handle_long_constant (jcf, cpool, kind, index, 
-                                   FLOAT_WORDS_BIG_ENDIAN);
+      index = handle_long_constant (jcf, cpool, CONSTANT_Double, index,
+                                   targetm.float_words_big_endian ());
       break;
 
     case CONSTANT_Float:
@@ -723,7 +709,7 @@ handle_annotation (JCF *jcf, int level)
 }
 
 /* Read an annotation count from JCF, and write the following
-   annotatons to the reflection_data field of the outgoing class.  */
+   annotations to the reflection_data field of the outgoing class.  */
 
 static void
 handle_annotations (JCF *jcf, int level)
@@ -760,7 +746,7 @@ rewrite_reflection_indexes (void *arg)
 {
   bitmap_iterator bi;
   unsigned int offset;
-  VEC(int, heap) *map = arg;
+  VEC(int, heap) *map = (VEC(int, heap) *) arg;
   unsigned char *data = TYPE_REFLECTION_DATA (current_class);
 
   if (map)
@@ -949,13 +935,14 @@ handle_signature_attribute (int member_index, JCF *jcf,
 #define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
 { \
   int n = COUNT; \
-  tree list = DECL_FUNCTION_THROWS (current_method); \
+  VEC (tree,gc) *v = VEC_alloc (tree, gc, n); \
+  gcc_assert (DECL_FUNCTION_THROWS (current_method) == NULL); \
   while (--n >= 0) \
     { \
       tree thrown_class = get_class_constant (jcf, JCF_readu2 (jcf)); \
-      list = tree_cons (NULL_TREE, thrown_class, list); \
+      VEC_quick_push (tree, v, thrown_class); \
     } \
-  DECL_FUNCTION_THROWS (current_method) = nreverse (list); \
+  DECL_FUNCTION_THROWS (current_method) = v; \
 }
 
 #define HANDLE_DEPRECATED_ATTRIBUTE()  handle_deprecated ()
@@ -975,7 +962,7 @@ handle_signature_attribute (int member_index, JCF *jcf,
   else if (current_field)                                              \
     FIELD_SYNTHETIC (current_field) = 1;                               \
   else                                                                 \
-    CLASS_SYNTHETIC (current_class) = 1;                               \
+    TYPE_SYNTHETIC (current_class) = 1;                                        \
 }
 
 #define HANDLE_GCJCOMPILED_ATTRIBUTE()         \
@@ -1054,14 +1041,15 @@ get_constant (JCF *jcf, int index)
       }
     case CONSTANT_Long:
       {
-       unsigned HOST_WIDE_INT num = JPOOL_UINT (jcf, index);
-       unsigned HOST_WIDE_INT lo;
-       HOST_WIDE_INT hi;
-       
-       lshift_double (num, 0, 32, 64, &lo, &hi, 0);
-       num = JPOOL_UINT (jcf, index+1);
-       add_double (lo, hi, num, 0, &lo, &hi);
-       value = build_int_cst_wide_type (long_type_node, lo, hi);
+       unsigned HOST_WIDE_INT num;
+       double_int val;
+
+       num = JPOOL_UINT (jcf, index);
+       val = double_int_lshift (uhwi_to_double_int (num), 32, 64, false);
+       num = JPOOL_UINT (jcf, index + 1);
+       val = double_int_ior (val, uhwi_to_double_int (num));
+
+       value = double_int_to_tree (long_type_node, val);
        break;
       }
 
@@ -1084,7 +1072,7 @@ get_constant (JCF *jcf, int index)
        hi = JPOOL_UINT (jcf, index);
        lo = JPOOL_UINT (jcf, index+1);
 
-       if (FLOAT_WORDS_BIG_ENDIAN)
+       if (targetm.float_words_big_endian ())
          buf[0] = hi, buf[1] = lo;
        else
          buf[0] = lo, buf[1] = hi;
@@ -1174,8 +1162,8 @@ handle_innerclass_attribute (int count, JCF *jcf, int attribute_length)
       /* If icii is 0, don't try to read the class. */
       if (icii >= 0)
        {
-         tree class = get_class_constant (jcf, icii);
-         tree decl = TYPE_NAME (class);
+         tree klass = get_class_constant (jcf, icii);
+         tree decl = TYPE_NAME (klass);
           /* Skip reading further if ocii is null */
           if (DECL_P (decl) && !CLASS_COMPLETE_P (decl) && ocii)
            {
@@ -1206,22 +1194,16 @@ give_name_to_class (JCF *jcf, int i)
       tree class_name = unmangle_classname ((const char *) JPOOL_UTF_DATA (jcf, j),
                                            JPOOL_UTF_LENGTH (jcf, j));
       this_class = lookup_class (class_name);
-#ifdef USE_MAPPED_LOCATION
       {
       tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
-      const char *sfname = IDENTIFIER_POINTER (source_name);
-      linemap_add (&line_table, LC_ENTER, false, sfname, 0);
-      input_location = linemap_line_start (&line_table, 0, 1);
+      const char *sfname = find_sourcefile (IDENTIFIER_POINTER (source_name));
+      linemap_add (line_table, LC_ENTER, false, sfname, 0);
+      input_location = linemap_line_start (line_table, 0, 1);
       file_start_location = input_location;
       DECL_SOURCE_LOCATION (TYPE_NAME (this_class)) = input_location;
       if (main_input_filename == NULL && jcf == main_jcf)
        main_input_filename = sfname;
       }
-#else
-      input_location = DECL_SOURCE_LOCATION (TYPE_NAME (this_class));
-      if (main_input_filename == NULL && jcf == main_jcf)
-       main_input_filename = input_filename;
-#endif
 
       jcf->cpool.data[i].t = this_class;
       JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
@@ -1273,7 +1255,7 @@ int
 read_class (tree name)
 {
   JCF this_jcf, *jcf;
-  tree icv, class = NULL_TREE;
+  tree icv, klass = NULL_TREE;
   tree save_current_class = current_class;
   tree save_output_class = output_class;
   location_t save_location = input_location;
@@ -1281,8 +1263,8 @@ read_class (tree name)
 
   if ((icv = IDENTIFIER_CLASS_VALUE (name)) != NULL_TREE)
     {
-      class = TREE_TYPE (icv);
-      jcf = TYPE_JCF (class);
+      klass = TREE_TYPE (icv);
+      jcf = TYPE_JCF (klass);
     }
   else
     jcf = NULL;
@@ -1295,81 +1277,30 @@ read_class (tree name)
       
       path_name = find_class (IDENTIFIER_POINTER (name),
                              IDENTIFIER_LENGTH (name),
-                             &this_jcf, 1);
+                             &this_jcf);
       if (path_name == 0)
        return 0;
       else
-       free((char *) path_name);
+       free(CONST_CAST (char *, path_name));
     }
 
   current_jcf = jcf;
 
-  if (current_jcf->java_source)
-    {
-      gcc_unreachable ();
-#if 0
-      const char *filename = current_jcf->filename;
-      char *real_path;
-      tree given_file, real_file;
-      FILE *finput;
-      int generate;
-
-      java_parser_context_save_global ();
-      java_push_parser_context ();
-
-      given_file = get_identifier (filename);
-      filename = IDENTIFIER_POINTER (given_file);
-      real_path = lrealpath (filename);
-      real_file = get_identifier (real_path);
-      free (real_path);
-
-      generate = IS_A_COMMAND_LINE_FILENAME_P (given_file);
-      output_class = current_class = NULL_TREE;
-      current_function_decl = NULL_TREE;
-
-      if (! HAS_BEEN_ALREADY_PARSED_P (real_file))
-       {
-         if (! (finput = fopen (filename, "r")))
-           fatal_error ("can't reopen %s: %m", filename);
-
-         parse_source_file_1 (real_file, filename, finput);
-         parse_source_file_2 ();
-         parse_source_file_3 ();
-
-         if (fclose (finput))
-           fatal_error ("can't close %s: %m", input_filename);
-#ifdef USE_MAPPED_LOCATION
-         linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
-#endif
-       }
-      JCF_FINISH (current_jcf);
-      java_pop_parser_context (generate);
-      java_parser_context_restore_global ();
-#endif
-    }
-  else
+  if (klass == NULL_TREE || ! CLASS_PARSED_P (klass))
     {
-      if (class == NULL_TREE || ! CLASS_PARSED_P (class))
-       {
-/*       java_parser_context_save_global (); */
-/*       java_push_parser_context (); */
-         output_class = current_class = class;
-/*       ctxp->save_location = input_location; */
-         if (JCF_SEEN_IN_ZIP (current_jcf))
-           read_zip_member(current_jcf,
-                           current_jcf->zipd, current_jcf->zipd->zipf);
-         jcf_parse (current_jcf);
-         /* Parsing might change the class, in which case we have to
-            put it back where we found it.  */
-         if (current_class != class && icv != NULL_TREE)
-           TREE_TYPE (icv) = current_class;
-         class = current_class;
-/*       java_pop_parser_context (0); */
-/*       java_parser_context_restore_global (); */
-       }
-      layout_class (class);
-      load_inner_classes (class);
+      output_class = current_class = klass;
+      if (JCF_SEEN_IN_ZIP (current_jcf))
+       read_zip_member(current_jcf,
+                       current_jcf->zipd, current_jcf->zipd->zipf);
+      jcf_parse (current_jcf);
+      /* Parsing might change the class, in which case we have to
+        put it back where we found it.  */
+      if (current_class != klass && icv != NULL_TREE)
+       TREE_TYPE (icv) = current_class;
+      klass = current_class;
     }
+  layout_class (klass);
+  load_inner_classes (klass);
 
   output_class = save_output_class;
   current_class = save_current_class;
@@ -1414,11 +1345,6 @@ load_class (tree class_or_name, int verbose)
           || CLASS_FROM_CURRENTLY_COMPILED_P (type));
     }
 
-  /* If the class is from source code, then it must already be loaded.  */
-  class_decl = IDENTIFIER_CLASS_VALUE (name);
-  if (class_decl && CLASS_FROM_SOURCE_P (TREE_TYPE (class_decl)))
-    return;
-
   saved = name;
   
   /* If flag_verify_invocations is unset, we don't try to load a class
@@ -1431,7 +1357,7 @@ load_class (tree class_or_name, int verbose)
     {
       while (1)
        {
-         char *separator;
+         const char *separator;
 
          /* We've already loaded it.  */
          if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE)
@@ -1448,12 +1374,9 @@ load_class (tree class_or_name, int verbose)
             for an inner class.  */
          if ((separator = strrchr (IDENTIFIER_POINTER (name), '$'))
              || (separator = strrchr (IDENTIFIER_POINTER (name), '.')))
-           {
-             int c = *separator;
-             *separator = '\0';
-             name = get_identifier (IDENTIFIER_POINTER (name));
-             *separator = c;
-           }
+           name = get_identifier_with_length (IDENTIFIER_POINTER (name),
+                                              (separator
+                                               - IDENTIFIER_POINTER (name)));
          /* Otherwise, we failed, we bail. */
          else
            break;
@@ -1500,6 +1423,8 @@ jcf_parse (JCF* jcf)
 {
   int i, code;
 
+  bitmap_clear (field_offsets);
+
   if (jcf_parse_preamble (jcf) != 0)
     fatal_error ("not a valid Java .class file");
   code = jcf_parse_constant_pool (jcf);
@@ -1548,30 +1473,16 @@ jcf_parse (JCF* jcf)
   if (TYPE_REFLECTION_DATA (current_class))
     annotation_write_byte (JV_DONE_ATTR);
 
-#ifdef USE_MAPPED_LOCATION
-  linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
-#endif
+  linemap_add (line_table, LC_LEAVE, false, NULL, 0);
 
   /* The fields of class_type_node are already in correct order. */
   if (current_class != class_type_node && current_class != object_type_node)
     TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class));
 
   if (current_class == object_type_node)
-    {
-      layout_class_methods (object_type_node);
-      /* If we don't have the right archive, emit a verbose warning.
-        If we're generating bytecode, emit the warning only if
-        -fforce-classes-archive-check was specified. */
-#if 0
-      /* ECJ HACK: ignore this.  */
-      if (!jcf->right_zip
-         && (!flag_emit_class_files || flag_force_classes_archive_check))
-       fatal_error ("the %<java.lang.Object%> that was found in %qs didn't have the special zero-length %<gnu.gcj.gcj-compiled%> attribute.  This generally means that your classpath is incorrectly set.  Use %<info gcj \"Input Options\"%> to see the info page describing how to set the classpath", jcf->filename);
-#endif
-    }
+    layout_class_methods (object_type_node);
   else
-    all_class_list = tree_cons (NULL_TREE,
-                               TYPE_NAME (current_class), all_class_list );
+    VEC_safe_push (tree, gc, all_class_list, TYPE_NAME (current_class));
 }
 
 /* If we came across inner classes, load them now. */
@@ -1594,29 +1505,25 @@ static void
 duplicate_class_warning (const char *filename)
 {
   location_t warn_loc;
-#ifdef USE_MAPPED_LOCATION
-  linemap_add (&line_table, LC_RENAME, 0, filename, 0);
-  warn_loc = linemap_line_start (&line_table, 0, 1);
-#else
-  warn_loc.file = filename;
-  warn_loc.line = 0;
-#endif
-  warning (0, "%Hduplicate class will only be compiled once", &warn_loc);
+  linemap_add (line_table, LC_RENAME, 0, filename, 0);
+  warn_loc = linemap_line_start (line_table, 0, 1);
+  warning_at (warn_loc, 0, "duplicate class will only be compiled once");
 }
 
 static void
 java_layout_seen_class_methods (void)
 {
-  tree previous_list = all_class_list;
-  tree end = NULL_TREE;
-  tree current;
+  unsigned start = 0;
+  unsigned end = VEC_length (tree, all_class_list);
 
   while (1)
     {
-      for (current = previous_list;
-          current != end; current = TREE_CHAIN (current))
+      unsigned ix;
+      unsigned new_length;
+
+      for (ix = start; ix != end; ix++)
         {
-         tree decl = TREE_VALUE (current);
+         tree decl = VEC_index (tree, all_class_list, ix);
           tree cls = TREE_TYPE (decl);
 
          input_location = DECL_SOURCE_LOCATION (decl);
@@ -1629,11 +1536,11 @@ java_layout_seen_class_methods (void)
 
       /* Note that new classes might have been added while laying out
          methods, changing the value of all_class_list.  */
-
-      if (previous_list != all_class_list)
+      new_length = VEC_length (tree, all_class_list);
+      if (end != new_length)
        {
-         end = previous_list;
-         previous_list = all_class_list;
+         start = end;
+         end = new_length;
        }
       else
        break;
@@ -1649,13 +1556,20 @@ parse_class_file (void)
   java_layout_seen_class_methods ();
 
   input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class));
+  {
+    /* Re-enter the current file.  */
+    expanded_location loc = expand_location (input_location);
+    linemap_add (line_table, LC_ENTER, 0, loc.file, loc.line);
+  }
   file_start_location = input_location;
   (*debug_hooks->start_source_file) (input_line, input_filename);
 
+  java_mark_class_local (current_class);
+
   gen_indirect_dispatch_tables (current_class);
 
   for (method = TYPE_METHODS (current_class);
-       method != NULL_TREE; method = TREE_CHAIN (method))
+       method != NULL_TREE; method = DECL_CHAIN (method))
     {
       JCF *jcf = current_jcf;
 
@@ -1711,13 +1625,8 @@ parse_class_file (void)
              if (min_line == 0 || line < min_line)
                min_line = line;
            }
-#ifdef USE_MAPPED_LOCATION
          if (min_line != 0)
-           input_location = linemap_line_start (&line_table, min_line, 1);
-#else
-         if (min_line != 0)
-           input_line = min_line;
-#endif
+           input_location = linemap_line_start (line_table, min_line, 1);
        }
       else
        {
@@ -1758,22 +1667,24 @@ parse_class_file (void)
   input_location = save_location;
 }
 
+static VEC(tree,gc) *predefined_filenames;
+
 void
 add_predefined_file (tree name)
 {
-  predef_filenames = tree_cons (NULL_TREE, name, predef_filenames);
+  VEC_safe_push (tree, gc, predefined_filenames, name);
 }
 
 int
 predefined_filename_p (tree node)
 {
-  tree iter;
+  unsigned ix;
+  tree f;
+
+  FOR_EACH_VEC_ELT (tree, predefined_filenames, ix, f)
+    if (f == node)
+      return 1;
 
-  for (iter = predef_filenames; iter != NULL_TREE; iter = TREE_CHAIN (iter))
-    {
-      if (TREE_VALUE (iter) == node)
-       return 1;
-    }
   return 0;
 }
 
@@ -1789,9 +1700,37 @@ java_emit_static_constructor (void)
   write_resource_constructor (&body);
 
   if (body)
-    cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY);
+    {
+      tree name = get_identifier ("_Jv_global_static_constructor");
+
+      tree decl 
+       = build_decl (input_location, FUNCTION_DECL, name,
+                     build_function_type_list (void_type_node, NULL_TREE));
+
+      tree resdecl = build_decl (input_location,
+                                RESULT_DECL, NULL_TREE, void_type_node);
+      DECL_ARTIFICIAL (resdecl) = 1;
+      DECL_RESULT (decl) = resdecl;
+      current_function_decl = decl;
+      allocate_struct_function (decl, false);
+
+      TREE_STATIC (decl) = 1;
+      TREE_USED (decl) = 1;
+      DECL_ARTIFICIAL (decl) = 1;
+      DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
+      DECL_SAVED_TREE (decl) = body;
+      DECL_UNINLINABLE (decl) = 1;
+
+      DECL_INITIAL (decl) = make_node (BLOCK);
+      TREE_USED (DECL_INITIAL (decl)) = 1;
+
+      DECL_STATIC_CONSTRUCTOR (decl) = 1;
+      java_genericize (decl);
+      cgraph_finalize_function (decl, false);
+    }
 }
 
+
 void
 java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
 {
@@ -1801,6 +1740,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
   tree node;
   FILE *finput = NULL;
   int in_quotes = 0;
+  unsigned ix;
  
   bitmap_obstack_initialize (&bit_obstack);
   field_offsets = BITMAP_ALLOC (&bit_obstack);
@@ -1820,7 +1760,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
            {
              count = next - list;
              avail = 2 * (count + avail);
-             list = xrealloc (list, avail);
+             list = XRESIZEVEC (char, list, avail);
              next = list + count;
              avail = avail - count;
            }
@@ -1841,7 +1781,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
       file_list = list;
     }
   else
-    list = (char *) main_input_filename;
+    list = CONST_CAST (char *, main_input_filename);
 
   while (list)
     {
@@ -1898,9 +1838,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
            duplicate_class_warning (IDENTIFIER_POINTER (node));
          else
            {
-             tree file_decl = build_decl (TRANSLATION_UNIT_DECL, node, NULL);
-             TREE_CHAIN (file_decl) = current_file_list;
-             current_file_list = file_decl;
+             build_translation_unit_decl (node);
              IS_A_COMMAND_LINE_FILENAME_P (node) = 1;
            }
        }
@@ -1918,17 +1856,18 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
       const char *resource_filename;
       
       /* Only one resource file may be compiled at a time.  */
-      assert (TREE_CHAIN (current_file_list) == NULL);
+      assert (VEC_length (tree, all_translation_units) == 1);
 
-      resource_filename = IDENTIFIER_POINTER (DECL_NAME (current_file_list));
+      resource_filename
+       = IDENTIFIER_POINTER
+           (DECL_NAME (VEC_index (tree, all_translation_units, 0)));
       compile_resource_file (resource_name, resource_filename);
 
       goto finish;
     }
 
   current_jcf = main_jcf;
-  current_file_list = nreverse (current_file_list);
-  for (node = current_file_list; node; node = TREE_CHAIN (node))
+  FOR_EACH_VEC_ELT (tree, all_translation_units, ix, node)
     {
       unsigned char magic_string[4];
       char *real_path;
@@ -1966,8 +1905,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
       if (magic == 0xcafebabe)
        {
          CLASS_FILE_P (node) = 1;
-         current_jcf = ggc_alloc (sizeof (JCF));
-         JCF_ZERO (current_jcf);
+         current_jcf = ggc_alloc_cleared_JCF ();
          current_jcf->read_state = finput;
          current_jcf->filbuf = jcf_filbuf_from_stdio;
          jcf_parse (current_jcf);
@@ -1984,24 +1922,23 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
        }
       else if (magic == (JCF_u4)ZIPMAGIC)
        {
-         main_jcf = ggc_alloc (sizeof (JCF));
-         JCF_ZERO (main_jcf);
+         main_jcf = ggc_alloc_cleared_JCF ();
          main_jcf->read_state = finput;
          main_jcf->filbuf = jcf_filbuf_from_stdio;
-#ifdef USE_MAPPED_LOCATION
-         linemap_add (&line_table, LC_ENTER, false, filename, 0);
-         input_location = linemap_line_start (&line_table, 0, 1);
-#endif
+         linemap_add (line_table, LC_ENTER, false, filename, 0);
+         input_location = linemap_line_start (line_table, 0, 1);
          if (open_in_zip (main_jcf, filename, NULL, 0) <  0)
            fatal_error ("bad zip/jar file %s", filename);
          localToFile = SeenZipFiles;
          /* Register all the classes defined there.  */
-         process_zip_dir (main_jcf->read_state);
-#ifdef USE_MAPPED_LOCATION
-         linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
-#endif
+         process_zip_dir ((FILE *) main_jcf->read_state);
+         linemap_add (line_table, LC_LEAVE, false, NULL, 0);
          parse_zip_file_entries ();
        }
+      else if (magic == (JCF_u4) ZIPEMPTYMAGIC)
+       {
+         /* Ignore an empty input jar.  */
+       }
       else
        {
          gcc_unreachable ();
@@ -2012,21 +1949,12 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
          parse_source_file_1 (real_file, filename, finput);
          java_parser_context_restore_global ();
          java_pop_parser_context (1);
-#ifdef USE_MAPPED_LOCATION
-         linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
-#endif
+         linemap_add (line_table, LC_LEAVE, false, NULL, 0);
 #endif
        }
     }
 
-  /* Do this before lowering any code.  */
-  for (node = current_file_list; node; node = TREE_CHAIN (node))
-    {
-      if (CLASS_FILE_P (node))
-       java_mark_class_local (TREE_TYPE (node));
-    }
-
-  for (node = current_file_list; node; node = TREE_CHAIN (node))
+  FOR_EACH_VEC_ELT (tree, all_translation_units, ix, node)
     {
       input_location = DECL_SOURCE_LOCATION (node);
       if (CLASS_FILE_P (node))
@@ -2048,21 +1976,10 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
 
   bitmap_obstack_release (&bit_obstack);
 
-/*   java_expand_classes (); */
-/*   if (java_report_errors () || flag_syntax_only) */
-/*     return; */
-    
-  /* Expand all classes compiled from source.  */
-/*   java_finish_classes (); */
-
  finish:
   /* Arrange for any necessary initialization to happen.  */
   java_emit_static_constructor ();
-
-  /* Only finalize the compilation unit after we've told cgraph which
-     functions have their addresses stored.  */
-  cgraph_finalize_compilation_unit ();
-  cgraph_optimize ();
+  gcc_assert (global_bindings_p ());
 }
 
 
@@ -2129,7 +2046,7 @@ parse_zip_file_entries (void)
   for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
        i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
     {
-      tree class;
+      tree klass;
 
       switch (classify_zip_file (zdir))
        {
@@ -2139,31 +2056,40 @@ parse_zip_file_entries (void)
        case 1:
          {
            char *class_name = compute_class_name (zdir);
-           class = lookup_class (get_identifier (class_name));
+           int previous_alias_set = -1;
+           klass = lookup_class (get_identifier (class_name));
            FREE (class_name);
-           current_jcf = TYPE_JCF (class);
-           output_class = current_class = class;
+           current_jcf = TYPE_JCF (klass);
+           output_class = current_class = klass;
 
            /* This is a dummy class, and now we're compiling it for
               real.  */
-           gcc_assert (! TYPE_DUMMY (class));
+           gcc_assert (! TYPE_DUMMY (klass));
 
            /* This is for a corner case where we have a superclass
-              but no superclass fields.  
+              but no superclass fields.
 
               This can happen if we earlier failed to lay out this
               class because its superclass was still in the process
               of being laid out; this occurs when we have recursive
-              class dependencies via inner classes.  Setting
-              TYPE_SIZE to null here causes CLASS_LOADED_P to return
-              false, so layout_class() will be called again.  */
-           if (TYPE_SIZE (class) && CLASSTYPE_SUPER (class)
-               && integer_zerop (TYPE_SIZE (class)))
-             TYPE_SIZE (class) = NULL_TREE;
-
-           if (! CLASS_LOADED_P (class))
+              class dependencies via inner classes.  We must record
+              the previous alias set and restore it after laying out
+              the class.
+
+              FIXME: this really is a kludge.  We should figure out a
+              way to lay out the class properly before this
+              happens.  */
+           if (TYPE_SIZE (klass) && CLASSTYPE_SUPER (klass)
+               && integer_zerop (TYPE_SIZE (klass)))
              {
-               if (! CLASS_PARSED_P (class))
+               TYPE_SIZE (klass) = NULL_TREE;
+               previous_alias_set = TYPE_ALIAS_SET (klass);
+               TYPE_ALIAS_SET (klass) = -1;
+             }
+
+           if (! CLASS_LOADED_P (klass))
+             {
+               if (! CLASS_PARSED_P (klass))
                  {
                    read_zip_member (current_jcf, zdir, localToFile);
                    jcf_parse (current_jcf);
@@ -2172,6 +2098,9 @@ parse_zip_file_entries (void)
                load_inner_classes (current_class);
              }
 
+           if (previous_alias_set != -1)
+             TYPE_ALIAS_SET (klass) = previous_alias_set;
+
            if (TYPE_SIZE (current_class) != error_mark_node)
              {
                parse_class_file ();
@@ -2196,7 +2125,6 @@ parse_zip_file_entries (void)
            JCF_ZERO (jcf);
            jcf->read_state  = finput;
            jcf->filbuf      = jcf_filbuf_from_stdio;
-           jcf->java_source = 0;
            jcf->classname   = NULL;
            jcf->filename    = file_name;
            jcf->zipd        = zdir;
@@ -2239,7 +2167,7 @@ process_zip_dir (FILE *finput)
        i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
     {
       char *class_name, *file_name, *class_name_in_zip_dir;
-      tree class;
+      tree klass;
       JCF  *jcf;
 
       class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
@@ -2250,15 +2178,14 @@ process_zip_dir (FILE *finput)
 
       class_name = compute_class_name (zdir);
       file_name  = XNEWVEC (char, zdir->filename_length+1);
-      jcf = ggc_alloc (sizeof (JCF));
-      JCF_ZERO (jcf);
+      jcf = ggc_alloc_cleared_JCF ();
 
       strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
       file_name [zdir->filename_length] = '\0';
 
-      class = lookup_class (get_identifier (class_name));
+      klass = lookup_class (get_identifier (class_name));
 
-      if (CLASS_FROM_CURRENTLY_COMPILED_P (class))
+      if (CLASS_FROM_CURRENTLY_COMPILED_P (klass))
        {
          /* We've already compiled this class.  */
          duplicate_class_warning (file_name);
@@ -2266,16 +2193,15 @@ process_zip_dir (FILE *finput)
        }
       /* This function is only called when processing a zip file seen
         on the command line.  */
-      CLASS_FROM_CURRENTLY_COMPILED_P (class) = 1;
+      CLASS_FROM_CURRENTLY_COMPILED_P (klass) = 1;
 
       jcf->read_state  = finput;
       jcf->filbuf      = jcf_filbuf_from_stdio;
-      jcf->java_source = 0;
       jcf->classname   = class_name;
       jcf->filename    = file_name;
       jcf->zipd        = zdir;
 
-      TYPE_JCF (class) = jcf;
+      TYPE_JCF (klass) = jcf;
     }
 }