/* Parser for Java(TM) .class files.
   Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002
   Free Software Foundation, Inc.

This file is part of GNU CC.

GNU CC 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)
any later version.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
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 GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.

Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
The Free Software Foundation is independent of Sun Microsystems, Inc.  */

/* Written by Per Bothner <bothner@cygnus.com> */

#include "config.h"
#include "system.h"
#include "tree.h"
#include "obstack.h"
#include "flags.h"
#include "java-except.h"
#include "input.h"
#include "java-tree.h"
#include "toplev.h"
#include "parse.h"
#include "ggc.h"
#include "debug.h"
#include "assert.h"

#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif

#ifdef HAVE_NL_LANGINFO
#include <langinfo.h>
#endif

/* A CONSTANT_Utf8 element is converted to an IDENTIFIER_NODE at parse time. */
#define JPOOL_UTF(JCF, INDEX) CPOOL_UTF(&(JCF)->cpool, INDEX)
#define JPOOL_UTF_LENGTH(JCF, INDEX) IDENTIFIER_LENGTH (JPOOL_UTF (JCF, INDEX))
#define JPOOL_UTF_DATA(JCF, INDEX) \
  ((const unsigned char *) IDENTIFIER_POINTER (JPOOL_UTF (JCF, INDEX)))
#define HANDLE_CONSTANT_Utf8(JCF, INDEX, LENGTH) \
  do { \
    unsigned char save;  unsigned char *text; \
    JCF_FILL (JCF, (LENGTH)+1); /* Make sure we read 1 byte beyond string. */ \
    text = (JCF)->read_ptr; \
    save = text[LENGTH]; \
    text[LENGTH] = 0; \
    (JCF)->cpool.data[INDEX] = (jword) get_identifier (text); \
    text[LENGTH] = save; \
    JCF_SKIP (JCF, LENGTH); } while (0)

#include "jcf.h"

extern struct obstack *saveable_obstack;
extern struct obstack temporary_obstack;
extern struct obstack permanent_obstack;

/* Set to non-zero value in order to emit class initilization code
   before static field references.  */
extern int always_initialize_class_p;

static tree parse_roots[3] = { NULL_TREE, NULL_TREE, NULL_TREE };

/* The FIELD_DECL for the current field.  */
#define current_field parse_roots[0]

/* The METHOD_DECL for the current method.  */
#define current_method parse_roots[1]

/* A list of file names.  */
#define current_file_list parse_roots[2]

/* The Java archive that provides main_class;  the main input file. */
static struct JCF main_jcf[1];

static struct ZipFile *localToFile;

/* Declarations of some functions used here.  */
static void handle_innerclass_attribute PARAMS ((int count, JCF *));
static tree give_name_to_class PARAMS ((JCF *jcf, int index));
static void parse_zip_file_entries PARAMS ((void));
static void process_zip_dir PARAMS ((FILE *));
static void parse_source_file_1 PARAMS ((tree, FILE *));
static void parse_source_file_2 PARAMS ((void));
static void parse_class_file PARAMS ((void));
static void set_source_filename PARAMS ((JCF *, int));
static void ggc_mark_jcf PARAMS ((void**));
static void jcf_parse PARAMS ((struct JCF*));
static void load_inner_classes PARAMS ((tree));

/* Mark (for garbage collection) all the tree nodes that are
   referenced from JCF's constant pool table. Do that only if the JCF
   hasn't been marked finished.  */

static void
ggc_mark_jcf (elt)
     void **elt;
{
  JCF *jcf = *(JCF**) elt;
  if (jcf != NULL && !jcf->finished)
    {
      CPool *cpool = &jcf->cpool;
      int size = CPOOL_COUNT(cpool);
      int index;
      for (index = 1; index < size;  index++)
	{
	  int tag = JPOOL_TAG (jcf, index);
	  if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
	    ggc_mark_tree ((tree) cpool->data[index]);
	}
    }
}

/* Handle "SourceFile" attribute. */

static void
set_source_filename (jcf, index)
     JCF *jcf;
     int index;
{
  tree sfname_id = get_name_constant (jcf, index);
  const char *sfname = IDENTIFIER_POINTER (sfname_id);
  if (input_filename != NULL)
    {
      int old_len = strlen (input_filename);
      int new_len = IDENTIFIER_LENGTH (sfname_id);
      /* Use the current input_filename (derived from the class name)
	 if it has a directory prefix, but otherwise matches sfname. */
      if (old_len > new_len
	  && strcmp (sfname, input_filename + old_len - new_len) == 0
	  && (input_filename[old_len - new_len - 1] == '/'
	      || input_filename[old_len - new_len - 1] == '\\'))
	return;
    }
  input_filename = sfname;
  DECL_SOURCE_FILE (TYPE_NAME (current_class)) = sfname;
  if (current_class == main_class) main_input_filename = input_filename;
}

#define HANDLE_SOURCEFILE(INDEX) set_source_filename (jcf, INDEX)

#define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \
{ tree super_class = SUPER==0 ? NULL_TREE : get_class_constant (jcf, SUPER); \
  current_class = give_name_to_class (jcf, THIS); \
  set_super_info (ACCESS_FLAGS, current_class, super_class, INTERFACES_COUNT);}

#define HANDLE_CLASS_INTERFACE(INDEX) \
  add_interface (current_class, get_class_constant (jcf, INDEX))

#define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
{ int sig_index = SIGNATURE; \
  current_field = add_field (current_class, get_name_constant (jcf, NAME), \
			     parse_signature (jcf, sig_index), ACCESS_FLAGS); \
 set_java_signature (TREE_TYPE (current_field), JPOOL_UTF (jcf, sig_index)); \
 if ((ACCESS_FLAGS) & ACC_FINAL) \
   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (current_field); \
}

#define HANDLE_END_FIELDS() \
  (current_field = NULL_TREE)

#define HANDLE_CONSTANTVALUE(INDEX) \
{ tree constant;  int index = INDEX; \
  if (! flag_emit_class_files && JPOOL_TAG (jcf, index) == CONSTANT_String) { \
    tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index)); \
    constant = build_utf8_ref (name); \
  } \
  else \
    constant = get_constant (jcf, index); \
  set_constant_value (current_field, constant); }

#define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
 (current_method = add_method (current_class, ACCESS_FLAGS, \
			       get_name_constant (jcf, NAME), \
			       get_name_constant (jcf, SIGNATURE)), \
  DECL_LOCALVARIABLES_OFFSET (current_method) = 0, \
  DECL_LINENUMBERS_OFFSET (current_method) = 0)

#define HANDLE_END_METHODS() \
{ tree handle_type = CLASS_TO_HANDLE_TYPE (current_class); \
  if (handle_type != current_class) layout_type (handle_type); \
  current_method = NULL_TREE; }

#define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
{ DECL_MAX_STACK (current_method) = (MAX_STACK); \
  DECL_MAX_LOCALS (current_method) = (MAX_LOCALS); \
  DECL_CODE_LENGTH (current_method) = (CODE_LENGTH); \
  DECL_CODE_OFFSET (current_method) = JCF_TELL (jcf); }

#define HANDLE_LOCALVARIABLETABLE_ATTRIBUTE(COUNT) \
{ int n = (COUNT); \
  DECL_LOCALVARIABLES_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
  JCF_SKIP (jcf, n * 10); }

#define HANDLE_LINENUMBERTABLE_ATTRIBUTE(COUNT) \
{ int n = (COUNT); \
  DECL_LINENUMBERS_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
  JCF_SKIP (jcf, n * 4); }

#define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
{ \
  int n = COUNT; \
  tree list = DECL_FUNCTION_THROWS (current_method); \
  while (--n >= 0) \
    { \
      tree thrown_class = get_class_constant (jcf, JCF_readu2 (jcf)); \
      list = tree_cons (NULL_TREE, thrown_class, list); \
    } \
  DECL_FUNCTION_THROWS (current_method) = nreverse (list); \
}

/* Link seen inner classes to their outer context and register the
   inner class to its outer context. They will be later loaded.  */
#define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
  handle_innerclass_attribute (COUNT, jcf)

#define HANDLE_SYNTHETIC_ATTRIBUTE()					\
{									\
  /* Irrelevant decls should have been nullified by the END macros.	\
     We only handle the `Synthetic' attribute on method DECLs.		\
     DECL_ARTIFICIAL on fields is used for something else (See		\
     PUSH_FIELD in java-tree.h) */					\
  if (current_method)							\
    DECL_ARTIFICIAL (current_method) = 1;				\
}

#define HANDLE_GCJCOMPILED_ATTRIBUTE()		\
{ 						\
  if (current_class == object_type_node)	\
    jcf->right_zip = 1;				\
}

#include "jcf-reader.c"

static int yydebug;

tree
parse_signature (jcf, sig_index)
     JCF *jcf;
     int sig_index;
{
  if (sig_index <= 0 || sig_index >= JPOOL_SIZE (jcf)
      || JPOOL_TAG (jcf, sig_index) != CONSTANT_Utf8)
    abort ();
  else
    return parse_signature_string (JPOOL_UTF_DATA (jcf, sig_index),
				   JPOOL_UTF_LENGTH (jcf, sig_index));
}

void
java_set_yydebug (value)
     int value;
{
  yydebug = value;
}

tree
get_constant (jcf, index)
  JCF *jcf;
  int index;
{
  tree value;
  int tag;
  if (index <= 0 || index >= JPOOL_SIZE(jcf))
    goto bad;
  tag = JPOOL_TAG (jcf, index);
  if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
    return (tree) jcf->cpool.data[index];
  switch (tag)
    {
    case CONSTANT_Integer:
      {
	jint num = JPOOL_INT(jcf, index);
	value = build_int_2 (num, num < 0 ? -1 : 0);
	TREE_TYPE (value) = int_type_node;
	break;
      }
    case CONSTANT_Long:
      {
	jint num = JPOOL_INT (jcf, index);
	HOST_WIDE_INT lo, hi;
	lshift_double (num, 0, 32, 64, &lo, &hi, 0);
	num = JPOOL_INT (jcf, index+1) & 0xffffffff;
	add_double (lo, hi, num, 0, &lo, &hi);
	value = build_int_2 (lo, hi);
	TREE_TYPE (value) = long_type_node;
	force_fit_type (value, 0);
	break;
      }
#if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
    case CONSTANT_Float:
      {
	jint num = JPOOL_INT(jcf, index);
	REAL_VALUE_TYPE d;
#ifdef REAL_ARITHMETIC
	d = REAL_VALUE_FROM_TARGET_SINGLE (num);
#else
	union { float f;  jint i; } u;
	u.i = num;
	d = u.f;
#endif
	value = build_real (float_type_node, d);
	break;
      }
    case CONSTANT_Double:
      {
	HOST_WIDE_INT num[2];
	REAL_VALUE_TYPE d;
	HOST_WIDE_INT lo, hi;
	num[0] = JPOOL_INT (jcf, index);
	lshift_double (num[0], 0, 32, 64, &lo, &hi, 0);
	num[0] = JPOOL_INT (jcf, index+1);
	add_double (lo, hi, num[0], 0, &lo, &hi);

	/* Since ereal_from_double expects an array of HOST_WIDE_INT
	   in the target's format, we swap the elements for big endian
	   targets, unless HOST_WIDE_INT is sufficiently large to
	   contain a target double, in which case the 2nd element
	   is ignored.

	   FIXME: Is this always right for cross targets? */
	if (FLOAT_WORDS_BIG_ENDIAN && sizeof(num[0]) < 8)
	  {
	    num[0] = hi;
	    num[1] = lo;
	  }
	else
	  {
	    num[0] = lo;
	    num[1] = hi;
	  }
#ifdef REAL_ARITHMETIC
	d = REAL_VALUE_FROM_TARGET_DOUBLE (num);
#else
	{
	  union { double d;  jint i[2]; } u;
	  u.i[0] = (jint) num[0];
	  u.i[1] = (jint) num[1];
	  d = u.d;
	}
#endif
	value = build_real (double_type_node, d);
	break;
      }
#endif /* TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT */
    case CONSTANT_String:
      {
	tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
	const char *utf8_ptr = IDENTIFIER_POINTER (name);
	int utf8_len = IDENTIFIER_LENGTH (name);
	unsigned char *str_ptr;
	unsigned char *str;
	const unsigned char *utf8;
	int i, str_len;

	/* Count the number of Unicode characters in the string,
	   while checking for a malformed Utf8 string. */
	utf8 = (const unsigned char *) utf8_ptr;
	i = utf8_len;
	str_len = 0;
	while (i > 0)
	  {
	    int char_len = UT8_CHAR_LENGTH (*utf8);
	    if (char_len < 0 || char_len > 3 || char_len > i)
 	      fatal_error ("bad string constant");

	    utf8 += char_len;
	    i -= char_len;
	    str_len++;
	  }

	/* Allocate a scratch buffer, convert the string to UCS2, and copy it
	   into the new space.  */
	str_ptr = (unsigned char *) alloca (2 * str_len);
	str = str_ptr;
	utf8 = (const unsigned char *)utf8_ptr;

	for (i = 0; i < str_len; i++)
	  {
	    int char_value;
	    int char_len = UT8_CHAR_LENGTH (*utf8);
	    switch (char_len)
	      {
	      case 1:
		char_value = *utf8++;
		break;
	      case 2:
		char_value = *utf8++ & 0x1F;
		char_value = (char_value << 6) | (*utf8++ & 0x3F);
		break;
	      case 3:
		char_value = *utf8++ & 0x0F;
		char_value = (char_value << 6) | (*utf8++ & 0x3F);
		char_value = (char_value << 6) | (*utf8++ & 0x3F);
		break;
	      default:
		goto bad;
	      }
	    if (BYTES_BIG_ENDIAN)
	      {
		*str++ = char_value >> 8;
		*str++ = char_value & 0xFF;
	      }
	    else
	      {
		*str++ = char_value & 0xFF;
		*str++ = char_value >> 8;
	      }
	  }
	value = build_string (str - str_ptr, str_ptr);
	TREE_TYPE (value) = build_pointer_type (string_type_node);
      }
      break;
    default:
      goto bad;
    }
  JPOOL_TAG (jcf, index) = tag | CONSTANT_ResolvedFlag;
  jcf->cpool.data [index] = (jword) value;
  return value;
 bad:
  internal_error ("bad value constant type %d, index %d", 
		  JPOOL_TAG (jcf, index), index);
}

tree
get_name_constant (jcf, index)
  JCF *jcf;
  int index;
{
  tree name = get_constant (jcf, index);

  if (TREE_CODE (name) != IDENTIFIER_NODE)
    abort ();

  return name;
}

/* Handle reading innerclass attributes. If a non zero entry (denoting
   a non anonymous entry) is found, We augment the inner class list of
   the outer context with the newly resolved innerclass.  */

static void
handle_innerclass_attribute (count, jcf)
     int count;
     JCF *jcf;
{
  int c = (count);
  while (c--)
    {
      /* Read inner_class_info_index. This may be 0 */
      int icii = JCF_readu2 (jcf);
      /* Read outer_class_info_index. If the innerclasses attribute
	 entry isn't a member (like an inner class) the value is 0. */
      int ocii = JCF_readu2 (jcf);
      /* Read inner_name_index. If the class we're dealing with is
	 an annonymous class, it must be 0. */
      int ini = JCF_readu2 (jcf);
      /* Read the access flag. */
      int acc = JCF_readu2 (jcf);
      /* 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);
          /* Skip reading further if ocii is null */
          if (DECL_P (decl) && !CLASS_COMPLETE_P (decl) && ocii)
	    {
	      tree outer = TYPE_NAME (get_class_constant (jcf, ocii));
	      tree alias = (ini ? get_name_constant (jcf, ini) : NULL_TREE);
	      set_class_decl_access_flags (acc, decl);
	      DECL_CONTEXT (decl) = outer;
	      DECL_INNER_CLASS_LIST (outer) =
		tree_cons (decl, alias, DECL_INNER_CLASS_LIST (outer));
	      CLASS_COMPLETE_P (decl) = 1;
            }
	}
    }
}

static tree
give_name_to_class (jcf, i)
     JCF *jcf;
     int i;
{
  if (i <= 0 || i >= JPOOL_SIZE (jcf)
      || JPOOL_TAG (jcf, i) != CONSTANT_Class)
    abort ();
  else
    {
      tree this_class;
      int j = JPOOL_USHORT1 (jcf, i);
      /* verify_constant_pool confirmed that j is a CONSTANT_Utf8. */
      tree class_name = unmangle_classname (JPOOL_UTF_DATA (jcf, j),
					    JPOOL_UTF_LENGTH (jcf, j));
      this_class = lookup_class (class_name);
      input_filename = DECL_SOURCE_FILE (TYPE_NAME (this_class));
      lineno = 0;
      if (main_input_filename == NULL && jcf == main_jcf)
	main_input_filename = input_filename;

      jcf->cpool.data[i] = (jword) this_class;
      JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
      return this_class;
    }
}

/* Get the class of the CONSTANT_Class whose constant pool index is I. */

tree
get_class_constant (JCF *jcf , int i)
{
  tree type;
  if (i <= 0 || i >= JPOOL_SIZE (jcf)
      || (JPOOL_TAG (jcf, i) & ~CONSTANT_ResolvedFlag) != CONSTANT_Class)
    abort ();

  if (JPOOL_TAG (jcf, i) != CONSTANT_ResolvedClass)
    {
      int name_index = JPOOL_USHORT1 (jcf, i);
      /* verify_constant_pool confirmed that name_index is a CONSTANT_Utf8. */
      const char *name = JPOOL_UTF_DATA (jcf, name_index);
      int nlength = JPOOL_UTF_LENGTH (jcf, name_index);

      if (name[0] == '[')  /* Handle array "classes". */
	  type = TREE_TYPE (parse_signature_string (name, nlength));
      else
        { 
          tree cname = unmangle_classname (name, nlength);
          type = lookup_class (cname);
	}
      jcf->cpool.data[i] = (jword) type;
      JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
    }
  else
    type = (tree) jcf->cpool.data[i];
  return type;
}

/* Read a class with the fully qualified-name NAME.
   Return 1 iff we read the requested file.
   (It is still possible we failed if the file did not
   define the class it is supposed to.) */

int
read_class (name)
     tree name;
{
  JCF this_jcf, *jcf;
  tree icv, class = NULL_TREE;
  tree save_current_class = current_class;
  const char *save_input_filename = input_filename;
  JCF *save_current_jcf = current_jcf;

  if ((icv = IDENTIFIER_CLASS_VALUE (name)) != NULL_TREE)
    {
      class = TREE_TYPE (icv);
      jcf = TYPE_JCF (class);
    }
  else
    jcf = NULL;

  if (jcf == NULL)
    {
      this_jcf.zipd = NULL;
      jcf = &this_jcf;
      if (find_class (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name),
		      &this_jcf, 1) == 0)
	return 0;
    }

  current_jcf = jcf;

  if (current_jcf->java_source)
    {
      const char *filename = current_jcf->filename;
      tree file;
      FILE *finput;
      int generate;

      java_parser_context_save_global ();
      java_push_parser_context ();
      BUILD_FILENAME_IDENTIFIER_NODE (file, filename);
      generate = IS_A_COMMAND_LINE_FILENAME_P (file);
      if (wfl_operator == NULL_TREE)
	wfl_operator = build_expr_wfl (NULL_TREE, NULL, 0, 0);
      EXPR_WFL_FILENAME_NODE (wfl_operator) = file;
      input_filename = ggc_strdup (filename);
      current_class = NULL_TREE;
      current_function_decl = NULL_TREE;
      if (!HAS_BEEN_ALREADY_PARSED_P (file))
	{
	  if (!(finput = fopen (input_filename, "r")))
	    fatal_io_error ("can't reopen %s", input_filename);
	  parse_source_file_1 (file, finput);
	  parse_source_file_2 ();
	  if (fclose (finput))
	    fatal_io_error ("can't close %s", input_filename);
	}
      JCF_FINISH (current_jcf);
      java_pop_parser_context (generate);
      java_parser_context_restore_global ();
    }
  else
    {
      if (class == NULL_TREE || ! CLASS_PARSED_P (class))
	{
	  java_parser_context_save_global ();
	  java_push_parser_context ();
	  current_class = class;
	  input_filename = current_jcf->filename;
	  if (JCF_SEEN_IN_ZIP (current_jcf))
	    read_zip_member(current_jcf,
			    current_jcf->zipd, current_jcf->zipd->zipf);
	  jcf_parse (current_jcf);
	  class = current_class;
	  java_pop_parser_context (0);
	  java_parser_context_restore_global ();
	}
      layout_class (class);
      load_inner_classes (class);
    }

  current_class = save_current_class;
  input_filename = save_input_filename;
  current_jcf = save_current_jcf;
  return 1;
}

/* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
   called from the parser, otherwise it's a RECORD_TYPE node. If
   VERBOSE is 1, print error message on failure to load a class. */

/* Replace calls to load_class by having callers call read_class directly
   - and then perhaps rename read_class to load_class.  FIXME */

void
load_class (class_or_name, verbose)
     tree class_or_name;
     int verbose;
{
  tree name, saved;
  int class_loaded;

  /* class_or_name can be the name of the class we want to load */
  if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
    name = class_or_name;
  /* In some cases, it's a dependency that we process earlier that
     we though */
  else if (TREE_CODE (class_or_name) == TREE_LIST)
    name = TYPE_NAME (TREE_PURPOSE (class_or_name));
  /* Or it's a type in the making */
  else
    name = DECL_NAME (TYPE_NAME (class_or_name));

  saved = name;
  while (1)
    {
      char *dollar;

      if ((class_loaded = read_class (name)))
	break;

      /* We failed loading name. Now consider that we might be looking
	 for a inner class but it's only available in source for in
	 its enclosing context. */
      if ((dollar = strrchr (IDENTIFIER_POINTER (name), '$')))
	{
	  int c = *dollar;
	  *dollar = '\0';
	  name = get_identifier (IDENTIFIER_POINTER (name));
	  *dollar = c;
	}
      /* Otherwise, we failed, we bail. */
      else
	break;
    }

  if (!class_loaded && verbose)
    error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
}

/* Parse the .class file JCF. */

void
jcf_parse (jcf)
     JCF* jcf;
{
  int i, code;

  if (jcf_parse_preamble (jcf) != 0)
    fatal_error ("not a valid Java .class file");
  code = jcf_parse_constant_pool (jcf);
  if (code != 0)
    fatal_error ("error while parsing constant pool");
  code = verify_constant_pool (jcf);
  if (code > 0)
    fatal_error ("error in constant pool entry #%d\n", code);

  jcf_parse_class (jcf);
  if (main_class == NULL_TREE)
    main_class = current_class;
  if (! quiet_flag && TYPE_NAME (current_class))
    fprintf (stderr, " %s %s",
	     (jcf->access_flags & ACC_INTERFACE) ? "interface" : "class", 
	     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
  if (CLASS_PARSED_P (current_class))
    {
      /* FIXME - where was first time */
      fatal_error ("reading class %s for the second time from %s",
		   IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))),
		   jcf->filename);
    }
  CLASS_PARSED_P (current_class) = 1;

  for (i = 1; i < JPOOL_SIZE(jcf); i++)
    {
      switch (JPOOL_TAG (jcf, i))
	{
	case CONSTANT_Class:
	  get_class_constant (jcf, i);
	  break;
	}
    }
  
  code = jcf_parse_fields (jcf);
  if (code != 0)
    fatal_error ("error while parsing fields");
  code = jcf_parse_methods (jcf);
  if (code != 0)
    fatal_error ("error while parsing methods");
  code = jcf_parse_final_attributes (jcf);
  if (code != 0)
    fatal_error ("error while parsing final attributes");

  /* 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 (!jcf->right_zip
	  && (!flag_emit_class_files || flag_force_classes_archive_check))
	fatal_error ("the `java.lang.Object' that was found in `%s' 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);
    }
  else
    all_class_list = tree_cons (NULL_TREE,
				TYPE_NAME (current_class), all_class_list );
}

/* If we came across inner classes, load them now. */
static void
load_inner_classes (cur_class)
     tree cur_class;
{
  tree current;
  for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (cur_class)); current;
       current = TREE_CHAIN (current))
    {
      tree name = DECL_NAME (TREE_PURPOSE (current));
      tree decl = IDENTIFIER_GLOBAL_VALUE (name);
      if (decl && ! CLASS_LOADED_P (TREE_TYPE (decl))
	  && !CLASS_BEING_LAIDOUT (TREE_TYPE (decl)))
	load_class (name, 1);
    }
}

void
init_outgoing_cpool ()
{
  current_constant_pool_data_ref = NULL_TREE;
  outgoing_cpool = (struct CPool *)xmalloc (sizeof (struct CPool));
  memset (outgoing_cpool, 0, sizeof (struct CPool));
}

static void
parse_class_file ()
{
  tree method;
  const char *save_input_filename = input_filename;
  int save_lineno = lineno;

  java_layout_seen_class_methods ();

  input_filename = DECL_SOURCE_FILE (TYPE_NAME (current_class));
  lineno = 0;
  (*debug_hooks->start_source_file) (lineno, input_filename);
  init_outgoing_cpool ();

  /* Currently we always have to emit calls to _Jv_InitClass when
     compiling from class files.  */
  always_initialize_class_p = 1;

  for ( method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (current_class));
	method != NULL_TREE; method = TREE_CHAIN (method))
    {
      JCF *jcf = current_jcf;

      if (METHOD_ABSTRACT (method))
	continue;

      if (METHOD_NATIVE (method))
	{
	  tree arg;
	  int  decl_max_locals;

	  if (! flag_jni)
	    continue;
	  /* We need to compute the DECL_MAX_LOCALS. We need to take
             the wide types into account too. */
	  for (arg = TYPE_ARG_TYPES (TREE_TYPE (method)), decl_max_locals = 0; 
	       arg != end_params_node;
	       arg = TREE_CHAIN (arg), decl_max_locals += 1)
	    {
	      if (TREE_VALUE (arg) && TYPE_IS_WIDE (TREE_VALUE (arg)))
		decl_max_locals += 1;
	    }
	  DECL_MAX_LOCALS (method) = decl_max_locals;
	  start_java_method (method);
	  give_name_to_locals (jcf);
	  expand_expr_stmt (build_jni_stub (method));
	  end_java_method ();
	  continue;
	}

      if (DECL_CODE_OFFSET (method) == 0)
	{
	  current_function_decl = method;
	  error ("missing Code attribute");
	  continue;
	}

      lineno = 0;
      if (DECL_LINENUMBERS_OFFSET (method))
	{
	  register int i;
	  register unsigned char *ptr;
	  JCF_SEEK (jcf, DECL_LINENUMBERS_OFFSET (method));
	  linenumber_count = i = JCF_readu2 (jcf);
	  linenumber_table = ptr = jcf->read_ptr;

	  for (ptr += 2; --i >= 0; ptr += 4)
	    {
	      int line = GET_u2 (ptr);
	      /* Set initial lineno lineno to smallest linenumber.
	       * Needs to be set before init_function_start. */
	      if (lineno == 0 || line < lineno)
		lineno = line;
	    }  
	}
      else
	{
	  linenumber_table = NULL;
	  linenumber_count = 0;
	}

      start_java_method (method);

      note_instructions (jcf, method);

      give_name_to_locals (jcf);

      /* Actually generate code. */
      expand_byte_code (jcf, method);

      end_java_method ();
    }

  if (flag_emit_class_files)
    write_classfile (current_class);

  finish_class ();

  (*debug_hooks->end_source_file) (save_lineno);
  input_filename = save_input_filename;
  lineno = save_lineno;
}

/* Parse a source file, as pointed by the current value of INPUT_FILENAME. */

static void
parse_source_file_1 (file, finput)
     tree file;
     FILE *finput;
{
  int save_error_count = java_error_count;
  /* Mark the file as parsed */
  HAS_BEEN_ALREADY_PARSED_P (file) = 1;

  jcf_dependency_add_file (input_filename, 0);

  lang_init_source (1);		    /* Error msgs have no method prototypes */

  /* There's no point in trying to find the current encoding unless we
     are going to do something intelligent with it -- hence the test
     for iconv.  */
#ifdef HAVE_ICONV
#ifdef HAVE_NL_LANGINFO
  setlocale (LC_CTYPE, "");
  if (current_encoding == NULL)
    current_encoding = nl_langinfo (CODESET);
#endif /* HAVE_NL_LANGINFO */
#endif /* HAVE_ICONV */
  if (current_encoding == NULL || *current_encoding == '\0')
    current_encoding = DEFAULT_ENCODING;

  /* Initialize the parser */
  java_init_lex (finput, current_encoding);
  java_parse_abort_on_error ();

  java_parse ();		    /* Parse and build partial tree nodes. */
  java_parse_abort_on_error ();
}

/* Process a parsed source file, resolving names etc. */

static void
parse_source_file_2 ()
{
  int save_error_count = java_error_count;
  java_complete_class ();	    /* Parse unsatisfied class decl. */
  java_parse_abort_on_error ();
  java_check_circular_reference (); /* Check on circular references */
  java_parse_abort_on_error ();
  java_fix_constructors ();	    /* Fix the constructors */
  java_parse_abort_on_error ();
  java_reorder_fields ();	    /* Reorder the fields */
}

void
add_predefined_file (name)
     tree name;
{
  predef_filenames = tree_cons (NULL_TREE, name, predef_filenames);
}

int
predefined_filename_p (node)
     tree node;
{
  tree iter;

  for (iter = predef_filenames; iter != NULL_TREE; iter = TREE_CHAIN (iter))
    {
      if (TREE_VALUE (iter) == node)
	return 1;
    }
  return 0;
}

int
yyparse ()
{
  int filename_count = 0;
  char *list, *next;
  tree node;
  FILE *finput = NULL;

  if (flag_filelist_file)
    {
      int avail = 2000;
      finput = fopen (input_filename, "r");
      if (finput == NULL)
	fatal_io_error ("can't open %s", input_filename);
      list = xmalloc(avail);
      next = list;
      for (;;)
	{
	  int count;
	  if (avail < 500)
	    {
	      count = next - list;
	      avail = 2 * (count + avail);
	      list = xrealloc (list, avail);
	      next = list + count;
	      avail = avail - count;
	    }
	  /* Subtract to to guarantee space for final '\0'. */
	  count = fread (next, 1, avail - 1, finput);
	  if (count == 0)
	    {
	      if (! feof (finput))
		fatal_io_error ("error closing %s", input_filename);
	      *next = '\0';
	      break;
	    }
	  avail -= count;
	  next += count;
	}
      fclose (finput);
      finput = NULL;
    }
  else
    list = xstrdup (input_filename);

  do 
    {
      for (next = list; ; )
	{
	  char ch = *next;
	  if (ch == '\n' || ch == '\r' || ch == '\t' || ch == ' '
	      || ch == '&' /* FIXME */)
	    {
	      if (next == list)
		{
		  next++;
		  list = next;
		  continue;
		}
	      else
		{
		  *next++ = '\0';
		  break;
		}
	    }
	  if (ch == '\0')
	    {
	      next = NULL;
	      break;
	    }
	  next++;
	}

      if (list[0]) 
	{
	  char *value;
	  tree id;
	  int twice = 0;

	  int len = strlen (list);

	  if (*list != '/' && filename_count > 0)
	    obstack_grow (&temporary_obstack, "./", 2);

	  obstack_grow0 (&temporary_obstack, list, len);
	  value = obstack_finish (&temporary_obstack);

	  filename_count++;

	  /* Exclude file that we see twice on the command line. For
	     all files except {Class,Error,Object,RuntimeException,String,
	     Throwable}.java we can rely on maybe_get_identifier. For
	     these files, we need to do a linear search of
	     current_file_list. This search happens only for these
	     files, presumably only when we're recompiling libgcj. */
	     
	  if ((id = maybe_get_identifier (value)))
	    {
	      if (predefined_filename_p (id))
		{
		  tree c;
		  for (c = current_file_list; c; c = TREE_CHAIN (c))
		    if (TREE_VALUE (c) == id)
		      twice = 1;
		}
	      else
		twice = 1;
	    }

	  if (twice)
	    {
	      const char *saved_input_filename = input_filename;
	      input_filename = value;
	      warning ("source file seen twice on command line and will be compiled only once");
	      input_filename = saved_input_filename;
	    }
	  else
	    {
	      BUILD_FILENAME_IDENTIFIER_NODE (node, value);
	      IS_A_COMMAND_LINE_FILENAME_P (node) = 1;
	      current_file_list = tree_cons (NULL_TREE, node, 
					     current_file_list);
	    }
	}
      list = next;
    }
  while (next);

  if (filename_count == 0)
    warning ("no input file specified");

  if (resource_name)
    {
      const char *resource_filename;
      
      /* Only one resource file may be compiled at a time.  */
      assert (TREE_CHAIN (current_file_list) == NULL);

      resource_filename = IDENTIFIER_POINTER (TREE_VALUE (current_file_list));
      compile_resource_file (resource_name, resource_filename);
      
      java_expand_classes ();
      if (!java_report_errors ())
	emit_register_classes ();
      return 0;
    }

  current_jcf = main_jcf;
  current_file_list = nreverse (current_file_list);
  for (node = current_file_list; node; node = TREE_CHAIN (node))
    {
      unsigned char magic_string[4];
      uint32 magic = 0;
      tree name = TREE_VALUE (node);

      /* Skip already parsed files */
      if (HAS_BEEN_ALREADY_PARSED_P (name))
	continue;
      
      /* Close previous descriptor, if any */
      if (finput && fclose (finput))
	fatal_io_error ("can't close input file %s", main_input_filename);
      
      finput = fopen (IDENTIFIER_POINTER (name), "rb");
      if (finput == NULL)
	fatal_io_error ("can't open %s", IDENTIFIER_POINTER (name));
      
#ifdef IO_BUFFER_SIZE
      setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE),
	       _IOFBF, IO_BUFFER_SIZE);
#endif
      input_filename = IDENTIFIER_POINTER (name);

      /* Figure what kind of file we're dealing with */
      if (fread (magic_string, 1, 4, finput) == 4)
	{
	  fseek (finput, 0L, SEEK_SET);
	  magic = GET_u4 (magic_string);
	}
      if (magic == 0xcafebabe)
	{
	  CLASS_FILE_P (node) = 1;
	  current_jcf = ALLOC (sizeof (JCF));
	  JCF_ZERO (current_jcf);
	  current_jcf->read_state = finput;
	  current_jcf->filbuf = jcf_filbuf_from_stdio;
	  jcf_parse (current_jcf);
	  TYPE_JCF (current_class) = current_jcf;
	  CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
	  TREE_PURPOSE (node) = current_class;
	}
      else if (magic == (JCF_u4)ZIPMAGIC)
	{
	  ZIP_FILE_P (node) = 1;
	  JCF_ZERO (main_jcf);
	  main_jcf->read_state = finput;
	  main_jcf->filbuf = jcf_filbuf_from_stdio;
	  if (open_in_zip (main_jcf, input_filename, NULL, 0) <  0)
	    fatal_error ("bad zip/jar file %s", IDENTIFIER_POINTER (name));
	  localToFile = SeenZipFiles;
	  /* Register all the class defined there.  */
	  process_zip_dir (main_jcf->read_state);
	  parse_zip_file_entries ();
	  /*
	  for (each entry)
	    CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
	  */
	}
      else
	{
	  JAVA_FILE_P (node) = 1;
	  java_push_parser_context ();
	  java_parser_context_save_global ();
	  parse_source_file_1 (name, finput);
	  java_parser_context_restore_global ();
	  java_pop_parser_context (1);
	}
    }

  for (ctxp = ctxp_for_generation;  ctxp;  ctxp = ctxp->next)
    {
      input_filename = ctxp->filename;
      parse_source_file_2 ();
    }
  for (node = current_file_list; node; node = TREE_CHAIN (node))
    {
      input_filename = IDENTIFIER_POINTER (TREE_VALUE (node));
      if (CLASS_FILE_P (node))
	{
	  current_class = TREE_PURPOSE (node);
	  current_jcf = TYPE_JCF (current_class);
	  layout_class (current_class);
	  load_inner_classes (current_class);
	  parse_class_file ();
	  JCF_FINISH (current_jcf);
	}
    }
  input_filename = main_input_filename;

  java_expand_classes ();
  if (!java_report_errors () && !flag_syntax_only)
    {
      emit_register_classes ();
      if (flag_indirect_dispatch)
	emit_offset_symbol_table ();
    }
  return 0;
}

/* Process all class entries found in the zip file.  */
static void
parse_zip_file_entries (void)
{
  struct ZipDirectory *zdir;
  int i;

  for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
       i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
    {
      tree class;
      
      /* We don't need to consider those files.  */
      if (!zdir->size || !zdir->filename_offset)
	continue;

      class = lookup_class (get_identifier (ZIPDIR_FILENAME (zdir)));
      current_jcf = TYPE_JCF (class);
      current_class = class;

      if ( !CLASS_LOADED_P (class))
	{
	  if (! CLASS_PARSED_P (class))
	    {
	      read_zip_member(current_jcf, zdir, localToFile);
	      jcf_parse (current_jcf);
	    }
	  layout_class (current_class);
	  load_inner_classes (current_class);
	}

      if (TYPE_SIZE (current_class) != error_mark_node)
	{
	  input_filename = current_jcf->filename;
	  parse_class_file ();
	  FREE (current_jcf->buffer); /* No longer necessary */
	  /* Note: there is a way to free this buffer right after a
	     class seen in a zip file has been parsed. The idea is the
	     set its jcf in such a way that buffer will be reallocated
	     the time the code for the class will be generated. FIXME. */
	}
    }
}

/* Read all the entries of the zip file, creates a class and a JCF. Sets the
   jcf up for further processing and link it to the created class.  */

static void
process_zip_dir (FILE *finput)
{
  int i;
  ZipDirectory *zdir;

  for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
       i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
    {
      char *class_name, *file_name, *class_name_in_zip_dir;
      tree class;
      JCF  *jcf;
      int   j;

      class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);

      /* We choose to not to process entries with a zero size or entries
	 not bearing the .class extension.  */
      if (!zdir->size || !zdir->filename_offset ||
	  strncmp (&class_name_in_zip_dir[zdir->filename_length-6], 
		   ".class", 6))
	{
	  /* So it will be skipped in parse_zip_file_entries  */
	  zdir->size = 0;  
	  continue;
	}

      class_name = ALLOC (zdir->filename_length+1-6);
      file_name  = ALLOC (zdir->filename_length+1);
      jcf = ALLOC (sizeof (JCF));
      JCF_ZERO (jcf);

      strncpy (class_name, class_name_in_zip_dir, zdir->filename_length-6);
      class_name [zdir->filename_length-6] = '\0';
      strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
      file_name [zdir->filename_length] = '\0';

      for (j=0; class_name[j]; j++)
        class_name [j] = (class_name [j] == '/' ? '.' : class_name [j]);

      /* Yes, we write back the true class name into the zip directory.  */
      strcpy (class_name_in_zip_dir, class_name);
      zdir->filename_length = j;
      class = lookup_class (get_identifier (class_name));

      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;
    }
}

/* Initialization.  */

void
init_jcf_parse ()
{
  /* Register roots with the garbage collector.  */
  ggc_add_tree_root (parse_roots, sizeof (parse_roots) / sizeof(tree));

  ggc_add_root (&current_jcf, 1, sizeof (JCF), (void (*)(void *))ggc_mark_jcf);

  init_src_parse ();
}
