/* 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;
	d = REAL_VALUE_FROM_TARGET_SINGLE (num);
	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;
	  }
	d = REAL_VALUE_FROM_TARGET_DOUBLE (num);
	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 *separator;

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

      /* We failed loading name. Now consider that we might be looking
	 for a 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;
	}
      /* 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, field;
  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 (field = TYPE_FIELDS (CLASS_TO_HANDLE_TYPE (current_class));
       field != NULL_TREE; field = TREE_CHAIN (field))
    if (FIELD_STATIC (field))
      DECL_EXTERNAL (field) = 0;

  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.  */
#if defined (HAVE_LOCALE_H) && defined (HAVE_ICONV) && defined (HAVE_NL_LANGINFO)
  setlocale (LC_CTYPE, "");
  if (current_encoding == NULL)
    current_encoding = nl_langinfo (CODESET);
#endif 
  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, ARRAY_SIZE (parse_roots));

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

  init_src_parse ();
}
