/* Functions related to building classes and their related objects.
   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
   2005, 2006, 2007, 2008, 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 3, or (at your option)
any later version.

GCC 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 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.
The Free Software Foundation is independent of Sun Microsystems, Inc.  */

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "flags.h"
#include "java-tree.h"
#include "jcf.h"
#include "obstack.h"
#include "diagnostic-core.h"
#include "toplev.h"
#include "output.h"
#include "parse.h"
#include "function.h"
#include "ggc.h"
#include "cgraph.h"
#include "tree-iterator.h"
#include "vecprim.h"
#include "tm.h"         /* FIXME: For gcc_obstack_init from defaults.h.  */
#include "target.h"

static tree make_method_value (tree);
static tree build_java_method_type (tree, tree, int);
static int32 hashUtf8String (const char *, int);
static tree make_field_value (tree);
static tree get_dispatch_vector (tree);
static tree get_dispatch_table (tree, tree);
static int supers_all_compiled (tree type);
static tree maybe_layout_super_class (tree, tree);
static void add_miranda_methods (tree, tree);
static int assume_compiled (const char *);
static tree build_symbol_entry (tree, tree);
static tree emit_assertion_table (tree);
static void register_class (void);

struct obstack temporary_obstack;

static const char *cyclic_inheritance_report;

/* The compiler generates different code depending on whether or not
   it can assume certain classes have been compiled down to native
   code or not.  The compiler options -fassume-compiled= and
   -fno-assume-compiled= are used to create a tree of
   class_flag_node objects.  This tree is queried to determine if
   a class is assume to be compiled or not.  Each node in the tree
   represents either a package or a specific class.  */

typedef struct class_flag_node_struct
{
  /* The class or package name.  */
  const char *ident;

  /* Nonzero if this represents an exclusion.  */
  int value;

  /* Pointers to other nodes in the tree.  */
  struct class_flag_node_struct *parent;
  struct class_flag_node_struct *sibling;
  struct class_flag_node_struct *child;
} class_flag_node;

static class_flag_node *find_class_flag_node (class_flag_node *, const char *);
static void add_class_flag (class_flag_node **, const char *, int);

/* This is the root of the include/exclude tree.  */

static class_flag_node *assume_compiled_tree;

static class_flag_node *enable_assert_tree;

static GTY(()) tree class_roots[4];
#define fields_ident class_roots[0]  /* get_identifier ("fields") */
#define info_ident class_roots[1]  /* get_identifier ("info") */
#define class_list class_roots[2]
#define class_dtable_decl class_roots[3]

static GTY(()) VEC(tree,gc) *registered_class;

/* A tree that returns the address of the class$ of the class
   currently being compiled.  */
static GTY(()) tree this_classdollar;

/* A list of static class fields.  This is to emit proper debug
   info for them.  */
VEC(tree,gc) *pending_static_fields;

/* Return the node that most closely represents the class whose name
   is IDENT.  Start the search from NODE (followed by its siblings).
   Return NULL if an appropriate node does not exist.  */

static class_flag_node *
find_class_flag_node (class_flag_node *node, const char *ident)
{
  while (node)
    {
      size_t node_ident_length = strlen (node->ident);

      /* node_ident_length is zero at the root of the tree.  If the
	 identifiers are the same length, then we have matching
	 classes.  Otherwise check if we've matched an enclosing
	 package name.  */

      if (node_ident_length == 0
	  || (strncmp (ident, node->ident, node_ident_length) == 0
	      && (ident[node_ident_length] == '\0'
		  || ident[node_ident_length] == '.')))
	{
	  /* We've found a match, however, there might be a more
             specific match.  */

	  class_flag_node *found = find_class_flag_node (node->child, ident);
	  if (found)
	    return found;
	  else
	    return node;
	}

      /* No match yet.  Continue through the sibling list.  */
      node = node->sibling;
    }

  /* No match at all in this tree.  */
  return NULL;
}

void
add_class_flag (class_flag_node **rootp, const char *ident, int value)
{
  class_flag_node *root = *rootp;
  class_flag_node *parent, *node;

  /* Create the root of the tree if it doesn't exist yet.  */

  if (NULL == root)
    {
      root = XNEW (class_flag_node);
      root->ident = "";
      root->value = 0;
      root->sibling = NULL;
      root->child = NULL;
      root->parent = NULL;
      *rootp = root;
    }

  /* Calling the function with the empty string means we're setting
     value for the root of the hierarchy.  */

  if (0 == ident[0])
    {
      root->value = value;
      return;
    }

  /* Find the parent node for this new node.  PARENT will either be a
     class or a package name.  Adjust PARENT accordingly.  */

  parent = find_class_flag_node (root, ident);
  if (strcmp (ident, parent->ident) == 0)
    parent->value = value;
  else
    {
      /* Insert new node into the tree.  */
      node = XNEW (class_flag_node);

      node->ident = xstrdup (ident);
      node->value = value;
      node->child = NULL;

      node->parent = parent;
      node->sibling = parent->child;
      parent->child = node;
    }
}

/* Add a new IDENT to the include/exclude tree.  It's an exclusion
   if EXCLUDEP is nonzero.  */

void
add_assume_compiled (const char *ident, int excludep)
{
  add_class_flag (&assume_compiled_tree, ident, excludep);
}

/* The default value returned by enable_assertions. */

#define DEFAULT_ENABLE_ASSERT (optimize == 0)

/* Enter IDENT (a class or package name) into the enable-assertions table.
   VALUE is true to enable and false to disable. */

void
add_enable_assert (const char *ident, int value)
{
  if (enable_assert_tree == NULL)
    add_class_flag (&enable_assert_tree, "", DEFAULT_ENABLE_ASSERT);
  add_class_flag (&enable_assert_tree, ident, value);
}

/* Returns nonzero if IDENT is the name of a class that the compiler
   should assume has been compiled to object code.  */

static int
assume_compiled (const char *ident)
{
  class_flag_node *i;
  int result;
  
  if (NULL == assume_compiled_tree)
    return 1;

  i = find_class_flag_node (assume_compiled_tree, ident);

  result = ! i->value;
  
  return (result);
}

/* Return true if we should generate code to check assertions within KLASS. */

bool
enable_assertions (tree klass)
{
  /* Check if command-line specifies whether we should check assertions. */

  if (klass != NULL_TREE && DECL_NAME (klass) && enable_assert_tree != NULL)
    {
      const char *ident = IDENTIFIER_POINTER (DECL_NAME (klass));
      class_flag_node *node
	= find_class_flag_node (enable_assert_tree, ident);
      return node->value;
    }

  /* The default is to enable assertions if generating class files,
     or not optimizing. */
  return DEFAULT_ENABLE_ASSERT;
}

/* Return an IDENTIFIER_NODE the same as (OLD_NAME, OLD_LENGTH).
   except that characters matching OLD_CHAR are substituted by NEW_CHAR.
   Also, PREFIX is prepended, and SUFFIX is appended. */

tree
ident_subst (const char* old_name,
	     int old_length,
	     const char *prefix,
	     int old_char,
	     int new_char,
	     const char *suffix)
{
  int prefix_len = strlen (prefix);
  int suffix_len = strlen (suffix);
  int i = prefix_len + old_length + suffix_len + 1;
  char *buffer = (char *) alloca (i);

  strcpy (buffer, prefix);
  for (i = 0; i < old_length; i++)
    {
      char ch = old_name[i];
      if (ch == old_char)
	ch = new_char;
      buffer[prefix_len + i] = ch;
    }
  strcpy (buffer + prefix_len + old_length, suffix);
  return get_identifier (buffer);
}

/* Return an IDENTIFIER_NODE the same as OLD_ID,
   except that characters matching OLD_CHAR are substituted by NEW_CHAR.
   Also, PREFIX is prepended, and SUFFIX is appended. */

tree
identifier_subst (const tree old_id,
		  const char *prefix,
		  int old_char,
		  int new_char,
		  const char *suffix)
{
  return ident_subst (IDENTIFIER_POINTER (old_id), IDENTIFIER_LENGTH (old_id),
		      prefix, old_char, new_char, suffix);
}

/* Generate a valid C identifier from the name of the class TYPE,
   prefixed by PREFIX. */

tree
mangled_classname (const char *prefix, tree type)
{
  tree result;
  tree ident = TYPE_NAME (type);
  if (TREE_CODE (ident) != IDENTIFIER_NODE)
    ident = DECL_NAME (ident);
  result = identifier_subst (ident, prefix, '.', '_', "");

  /* Replace any characters that aren't in the set [0-9a-zA-Z_$] with
     "_0xXX".  Class names containing such chracters are uncommon, but
     they do sometimes occur in class files.  Without this check,
     these names cause assembly errors.

     There is a possibility that a real class name could conflict with
     the identifier we generate, but it is unlikely and will
     immediately be detected as an assembler error.  At some point we
     should do something more elaborate (perhaps using the full
     unicode mangling scheme) in order to prevent such a conflict.  */
  {
    int i;
    const int len = IDENTIFIER_LENGTH (result);
    const char *p = IDENTIFIER_POINTER (result);
    int illegal_chars = 0;

    /* Make two passes over the identifier.  The first pass is merely
       to count illegal characters; we need to do this in order to
       allocate a buffer.  */
    for (i = 0; i < len; i++)
      {
	char c = p[i];
	illegal_chars += (! ISALNUM (c) && c != '_' && c != '$');
      }

    /* And the second pass, which is rarely executed, does the
       rewriting.  */
    if (illegal_chars != 0)
      {
	char *buffer = (char *) alloca (illegal_chars * 4 + len + 1);
	int j;

	for (i = 0, j = 0; i < len; i++)
	  {
	    char c = p[i];
	    if (! ISALNUM (c) && c != '_' && c != '$')
	      {
		buffer[j++] = '_';
		sprintf (&buffer[j], "0x%02x", c);
		j += 4;
	      }
	    else
	      buffer[j++] = c;
	  }

	buffer[j] = 0;
	result = get_identifier (buffer);
      }
  }

  return result;
}

tree
make_class (void)
{
  tree type;
  type = make_node (RECORD_TYPE);
  /* Unfortunately we must create the binfo here, so that class
     loading works.  */
  TYPE_BINFO (type) = make_tree_binfo (0);
  MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type);
  TYPE_CATCH_CLASSES (type) = NULL;
  /* Push a dummy entry; we can't call make_catch_class_record here
     because other infrastructure may not be set up yet.  We'll come
     back and fill it in later once said infrastructure is
     initialized.  */
  CONSTRUCTOR_APPEND_ELT (TYPE_CATCH_CLASSES (type), NULL_TREE, NULL_TREE);

  return type;
}

/* Given a fully-qualified classname in NAME (whose length is NAME_LENGTH),
   and where each of the constituents is separated by '/',
   return a corresponding IDENTIFIER_NODE, except using '.' as separator. */

tree
unmangle_classname (const char *name, int name_length)
{
  tree to_return = ident_subst (name, name_length, "", '/', '.', "");
  /* It's not sufficient to compare to_return and get_identifier
     (name) to determine whether to_return is qualified. There are
     cases in signature analysis where name will be stripped of a
     trailing ';'. */
  name = IDENTIFIER_POINTER (to_return);
  while (*name)
    if (*name++ == '.') 
      {
	QUALIFIED_P (to_return) = 1;
	break;
      }
  
  return to_return;
}

#define GEN_TABLE(TABLE, NAME, TABLE_TYPE, TYPE)			\
do									\
{									\
  const char *type_name = IDENTIFIER_POINTER (mangled_classname ("", TYPE)); \
  char *buf = (char *) alloca (strlen (type_name)			\
                               + strlen (#NAME "_syms_") + 1);		\
  tree decl;								\
									\
  sprintf (buf, #NAME "_%s", type_name);				\
  TYPE_## TABLE ##_DECL (type) = decl =					\
    build_decl (input_location, VAR_DECL, get_identifier (buf), TABLE_TYPE); \
  DECL_EXTERNAL (decl) = 1;						\
  TREE_STATIC (decl) = 1;						\
  TREE_READONLY (decl) = 1;						\
  TREE_CONSTANT (decl) = 1;						\
  DECL_IGNORED_P (decl) = 1;						\
  /* Mark the table as belonging to this class.  */			\
  pushdecl (decl);							\
  MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);				\
  DECL_OWNER (decl) = TYPE;						\
  sprintf (buf, #NAME "_syms_%s", type_name);				\
  TYPE_## TABLE ##_SYMS_DECL (TYPE) =					\
    build_decl (input_location, VAR_DECL, get_identifier (buf), symbols_array_type); \
  TREE_STATIC (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1;			\
  TREE_CONSTANT (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1;		\
  DECL_IGNORED_P (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1;		\
}									\
while (0)

/* Given a class, create the DECLs for all its associated indirect
   dispatch tables.  */
void
gen_indirect_dispatch_tables (tree type)
{
  const char *type_name = IDENTIFIER_POINTER (mangled_classname ("", type));
  {  
    tree field = NULL;
    char *buf = (char *) alloca (strlen (type_name)
				 + strlen ("_catch_classes_") + 1);
    tree catch_class_type = make_node (RECORD_TYPE);

    sprintf (buf, "_catch_classes_%s", type_name);
    PUSH_FIELD (input_location,
		catch_class_type, field, "address", utf8const_ptr_type);
    PUSH_FIELD (input_location,
		catch_class_type, field, "classname", ptr_type_node);
    FINISH_RECORD (catch_class_type);
    
    TYPE_CTABLE_DECL (type) 
      = build_decl (input_location, VAR_DECL, get_identifier (buf),
		    build_array_type (catch_class_type, 0));
    DECL_EXTERNAL (TYPE_CTABLE_DECL (type)) = 1;
    TREE_STATIC (TYPE_CTABLE_DECL (type)) = 1;
    TREE_READONLY (TYPE_CTABLE_DECL (type)) = 1;
    TREE_CONSTANT (TYPE_CTABLE_DECL (type)) = 1;
    DECL_IGNORED_P (TYPE_CTABLE_DECL (type)) = 1;
    pushdecl (TYPE_CTABLE_DECL (type));  
  }

  if (flag_indirect_dispatch)
    {
      GEN_TABLE (ATABLE, _atable, atable_type, type);
      GEN_TABLE (OTABLE, _otable, otable_type, type);
      GEN_TABLE (ITABLE, _itable, itable_type, type);
    }
}

#undef GEN_TABLE

tree
push_class (tree class_type, tree class_name)
{
  tree decl, signature;
  location_t saved_loc = input_location;
  CLASS_P (class_type) = 1;
  decl = build_decl (input_location, TYPE_DECL, class_name, class_type);
  TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;

  /* dbxout needs a DECL_SIZE if in gstabs mode */
  DECL_SIZE (decl) = integer_zero_node;

  input_location = saved_loc;
  signature = identifier_subst (class_name, "L", '.', '/', ";");
  IDENTIFIER_SIGNATURE_TYPE (signature) = build_pointer_type (class_type);

  /* Setting DECL_ARTIFICIAL forces dbxout.c to specific the type is
     both a typedef and in the struct name-space.  We may want to re-visit
     this later, but for now it reduces the changes needed for gdb. */
  DECL_ARTIFICIAL (decl) = 1;

  pushdecl_top_level (decl);

  return decl;
}

/* Finds the (global) class named NAME.  Creates the class if not found.
   Also creates associated TYPE_DECL.
   Does not check if the class actually exists, load the class,
   fill in field or methods, or do layout_type. */

tree
lookup_class (tree name)
{
  tree decl = IDENTIFIER_CLASS_VALUE (name);
  if (decl == NULL_TREE)
    decl = push_class (make_class (), name);
  return TREE_TYPE (decl);
}

void
set_super_info (int access_flags, tree this_class,
		tree super_class, int interfaces_count)
{
  int total_supers = interfaces_count;
  tree class_decl = TYPE_NAME (this_class);
  
  if (super_class)
    total_supers++;

  if (total_supers)
    TYPE_BINFO (this_class) = make_tree_binfo (total_supers);
  TYPE_VFIELD (this_class) = TYPE_VFIELD (object_type_node);
  if (super_class)
    {
      tree super_binfo = make_tree_binfo (0);
      BINFO_TYPE (super_binfo) = super_class;
      BINFO_OFFSET (super_binfo) = integer_zero_node;
      BINFO_BASE_APPEND (TYPE_BINFO (this_class), super_binfo);
      CLASS_HAS_SUPER_FLAG (TYPE_BINFO (this_class)) = 1;
    }

  set_class_decl_access_flags (access_flags, class_decl);
}

void
set_class_decl_access_flags (int access_flags, tree class_decl)
{
  if (access_flags & ACC_PUBLIC)    CLASS_PUBLIC (class_decl) = 1;
  if (access_flags & ACC_FINAL)     CLASS_FINAL (class_decl) = 1;
  if (access_flags & ACC_SUPER)     CLASS_SUPER (class_decl) = 1;
  if (access_flags & ACC_INTERFACE) CLASS_INTERFACE (class_decl) = 1;
  if (access_flags & ACC_ABSTRACT)  CLASS_ABSTRACT (class_decl) = 1;
  if (access_flags & ACC_STATIC)    CLASS_STATIC (class_decl) = 1;
  if (access_flags & ACC_PRIVATE)   CLASS_PRIVATE (class_decl) = 1;
  if (access_flags & ACC_PROTECTED) CLASS_PROTECTED (class_decl) = 1;
  if (access_flags & ACC_STRICT)    CLASS_STRICTFP (class_decl) = 1;
  if (access_flags & ACC_ENUM)      CLASS_ENUM (class_decl) = 1;
  if (access_flags & ACC_SYNTHETIC) CLASS_SYNTHETIC (class_decl) = 1;
  if (access_flags & ACC_ANNOTATION) CLASS_ANNOTATION (class_decl) = 1;
}

/* Return length of inheritance chain of CLAS, where java.lang.Object is 0,
   direct sub-classes of Object are 1, and so on. */

int
class_depth (tree clas)
{
  int depth = 0;
  if (! CLASS_LOADED_P (clas))
    load_class (clas, 1);
  if (TYPE_SIZE (clas) == error_mark_node)
    return -1;
  while (clas != object_type_node)
    {
      depth++;
      clas = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (clas), 0));
    }
  return depth;
}

/* Return true iff TYPE2 is an interface that extends interface TYPE1 */

int
interface_of_p (tree type1, tree type2)
{
  int i;
  tree binfo, base_binfo;

  if (! TYPE_BINFO (type2))
    return 0;

  for (binfo = TYPE_BINFO (type2), i = 0;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    if (BINFO_TYPE (base_binfo) == type1)
      return 1;
  
  for (binfo = TYPE_BINFO (type2), i = 0;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) /*  */
    if (BINFO_TYPE (base_binfo)
	&& interface_of_p (type1, BINFO_TYPE (base_binfo)))
      return 1;
  
  return 0;
}

/* Return true iff TYPE1 inherits from TYPE2. */

int
inherits_from_p (tree type1, tree type2)
{
  while (type1 != NULL_TREE && TREE_CODE (type1) == RECORD_TYPE)
    {
      if (type1 == type2)
	return 1;

      if (! CLASS_LOADED_P (type1))
	load_class (type1, 1);

      type1 = maybe_layout_super_class (CLASSTYPE_SUPER (type1), type1);
    }
  return 0;
}

/* Return a 1 iff TYPE1 is an enclosing context for TYPE2 */

int
enclosing_context_p (tree type1, tree type2)
{
  if (!INNER_CLASS_TYPE_P (type2))
    return 0;

  for (type2 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2)));
       type2; 
       type2 = (INNER_CLASS_TYPE_P (type2) ?
		TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2))) : NULL_TREE))
    {
      if (type2 == type1)
	return 1;
    }

  return 0;
}


/* Return 1 iff TYPE1 and TYPE2 share a common enclosing class, regardless of
   nesting level.  */

int
common_enclosing_context_p (tree type1, tree type2)
{
  while (type1)
    {
      tree current;
      for (current = type2; current;
	   current = (INNER_CLASS_TYPE_P (current) ?
		      TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current))) : 
		      NULL_TREE))
	if (type1 == current)
	  return 1;

      if (INNER_CLASS_TYPE_P (type1))
        type1 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1)));
      else
        break;
    }
  return 0;
}

/* Return 1 iff there exists a common enclosing "this" between TYPE1
   and TYPE2, without crossing any static context.  */

int
common_enclosing_instance_p (tree type1, tree type2)
{
  if (!PURE_INNER_CLASS_TYPE_P (type1) || !PURE_INNER_CLASS_TYPE_P (type2))
    return 0;
  
  for (type1 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1))); type1; 
       type1 = (PURE_INNER_CLASS_TYPE_P (type1) ?
		TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1))) : NULL_TREE))
    {
      tree current;
      for (current = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2))); current;
	   current = (PURE_INNER_CLASS_TYPE_P (current) ?
		      TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current))) : 
		      NULL_TREE))
	if (type1 == current)
	  return 1;
    }
  return 0;
}

/* Add INTERFACE_CLASS to THIS_CLASS iff INTERFACE_CLASS can't be
   found in THIS_CLASS. Returns NULL_TREE upon success, INTERFACE_CLASS
   if attempt is made to add it twice. */

tree
maybe_add_interface (tree this_class, tree interface_class)
{
  tree binfo, base_binfo;
  int i;

  for (binfo = TYPE_BINFO (this_class), i = 0;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    if (BINFO_TYPE (base_binfo) == interface_class)
      return interface_class;
  add_interface (this_class, interface_class);
  return NULL_TREE;
}

/* Add the INTERFACE_CLASS as one of the interfaces of THIS_CLASS. */

void
add_interface (tree this_class, tree interface_class)
{
  tree interface_binfo = make_tree_binfo (0);
  
  BINFO_TYPE (interface_binfo) = interface_class;
  BINFO_OFFSET (interface_binfo) = integer_zero_node;
  BINFO_VPTR_FIELD (interface_binfo) = integer_zero_node;
  BINFO_VIRTUAL_P (interface_binfo) = 1;
  
  BINFO_BASE_APPEND (TYPE_BINFO (this_class), interface_binfo);
}

static tree
build_java_method_type (tree fntype, tree this_class, int access_flags)
{
  if (access_flags & ACC_STATIC)
    return fntype;
  fntype = build_method_type (this_class, fntype);

  /* We know that arg 1 of every nonstatic method is non-null; tell
     the back-end so.  */
  TYPE_ATTRIBUTES (fntype) = (tree_cons 
			      (get_identifier ("nonnull"),
			       tree_cons (NULL_TREE, 
					  build_int_cst (NULL_TREE, 1),
					  NULL_TREE),
			       TYPE_ATTRIBUTES (fntype)));
  return fntype;
}

void
java_hide_decl (tree decl ATTRIBUTE_UNUSED)
{
#ifdef HAVE_GAS_HIDDEN
  DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
  DECL_VISIBILITY_SPECIFIED (decl) = 1;
#endif
}

tree
add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
{
  tree method_type, fndecl;

  method_type = build_java_method_type (function_type,
					this_class, access_flags);

  fndecl = build_decl (input_location, FUNCTION_DECL, name, method_type);
  DECL_CONTEXT (fndecl) = this_class;

  DECL_LANG_SPECIFIC (fndecl)
    = ggc_alloc_cleared_lang_decl(sizeof (struct lang_decl));
  DECL_LANG_SPECIFIC (fndecl)->desc = LANG_DECL_FUNC;

  /* Initialize the static initializer test table.  */

  DECL_FUNCTION_INIT_TEST_TABLE (fndecl) = java_treetreehash_create (10);

  /* Initialize the initialized (static) class table. */
  if (access_flags & ACC_STATIC)
    DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl) =
      htab_create_ggc (50, htab_hash_pointer, htab_eq_pointer, NULL);

  DECL_CHAIN (fndecl) = TYPE_METHODS (this_class);
  TYPE_METHODS (this_class) = fndecl;

  /* If pointers to member functions use the least significant bit to
     indicate whether a function is virtual, ensure a pointer
     to this function will have that bit clear.  */
  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
      && !(access_flags & ACC_STATIC)
      && DECL_ALIGN (fndecl) < 2 * BITS_PER_UNIT)
    DECL_ALIGN (fndecl) = 2 * BITS_PER_UNIT;

  /* Notice that this is a finalizer and update the class type
     accordingly. This is used to optimize instance allocation. */
  if (name == finalize_identifier_node
      && TREE_TYPE (function_type) == void_type_node
      && TREE_VALUE (TYPE_ARG_TYPES (function_type)) == void_type_node)
    HAS_FINALIZER_P (this_class) = 1;

  if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
  if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
  if (access_flags & ACC_PRIVATE)
    METHOD_PRIVATE (fndecl) = 1;
  if (access_flags & ACC_NATIVE)
    {
      METHOD_NATIVE (fndecl) = 1;
      DECL_EXTERNAL (fndecl) = 1;
    }
  else
    /* FNDECL is external unless we are compiling it into this object
       file.  */
    DECL_EXTERNAL (fndecl) = CLASS_FROM_CURRENTLY_COMPILED_P (this_class) == 0;
  if (access_flags & ACC_STATIC) 
    METHOD_STATIC (fndecl) = 1;
  if (access_flags & ACC_FINAL) 
    METHOD_FINAL (fndecl) = 1;
  if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;
  if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;
  if (access_flags & ACC_STRICT) METHOD_STRICTFP (fndecl) = 1;
  if (access_flags & ACC_SYNTHETIC) DECL_ARTIFICIAL (fndecl) = 1;
  if (access_flags & ACC_BRIDGE) METHOD_BRIDGE (fndecl) = 1;
  if (access_flags & ACC_VARARGS) METHOD_VARARGS (fndecl) = 1;
  return fndecl;
}

/* Add a method to THIS_CLASS.
   The method's name is NAME.
   Its signature (mangled type) is METHOD_SIG (an IDENTIFIER_NODE). */

tree
add_method (tree this_class, int access_flags, tree name, tree method_sig)
{
  tree function_type, fndecl;
  const unsigned char *sig
    = (const unsigned char *) IDENTIFIER_POINTER (method_sig);

  if (sig[0] != '(')
    fatal_error ("bad method signature");

  function_type = get_type_from_signature (method_sig);
  fndecl = add_method_1 (this_class, access_flags, name, function_type);
  set_java_signature (TREE_TYPE (fndecl), method_sig);
  return fndecl;
}

tree
add_field (tree klass, tree name, tree field_type, int flags)
{
  int is_static = (flags & ACC_STATIC) != 0;
  tree field;
  field = build_decl (input_location,
		      is_static ? VAR_DECL : FIELD_DECL, name, field_type);
  DECL_CHAIN (field) = TYPE_FIELDS (klass);
  TYPE_FIELDS (klass) = field;
  DECL_CONTEXT (field) = klass;
  MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field);

  if (flags & ACC_PUBLIC) FIELD_PUBLIC (field) = 1;
  if (flags & ACC_PROTECTED) FIELD_PROTECTED (field) = 1;
  if (flags & ACC_PRIVATE) FIELD_PRIVATE (field) = 1;
  if (flags & ACC_FINAL) FIELD_FINAL (field) = 1;
  if (flags & ACC_VOLATILE) 
    {
      FIELD_VOLATILE (field) = 1;
      TREE_THIS_VOLATILE (field) = 1;
    }
  if (flags & ACC_TRANSIENT) FIELD_TRANSIENT (field) = 1;
  if (flags & ACC_ENUM) FIELD_ENUM (field) = 1;
  if (flags & ACC_SYNTHETIC) FIELD_SYNTHETIC (field) = 1;
  if (is_static)
    {
      FIELD_STATIC (field) = 1;
      /* Always make field externally visible.  This is required so
	 that native methods can always access the field.  */
      TREE_PUBLIC (field) = 1;
      /* Hide everything that shouldn't be visible outside a DSO.  */
      if (flag_indirect_classes
	  || (FIELD_PRIVATE (field)))
	java_hide_decl (field);
      /* Considered external unless we are compiling it into this
	 object file.  */
      DECL_EXTERNAL (field) = (is_compiled_class (klass) != 2);
      if (!DECL_EXTERNAL (field))
	VEC_safe_push (tree, gc, pending_static_fields, field);
    }

  return field;
}

/* Associate a constant value CONSTANT with VAR_DECL FIELD. */

void
set_constant_value (tree field, tree constant)
{
  if (field == NULL_TREE)
    warning (OPT_Wattributes,
	     "misplaced ConstantValue attribute (not in any field)");
  else if (DECL_INITIAL (field) != NULL_TREE)
    warning (OPT_Wattributes,
	     "duplicate ConstantValue attribute for field '%s'",
	     IDENTIFIER_POINTER (DECL_NAME (field)));
  else
    {
      DECL_INITIAL (field) = constant;
      if (TREE_TYPE (constant) != TREE_TYPE (field)
	  && ! (TREE_TYPE (constant) == int_type_node
		&& INTEGRAL_TYPE_P (TREE_TYPE (field))
		&& TYPE_PRECISION (TREE_TYPE (field)) <= 32)
	  && ! (TREE_TYPE (constant) == utf8const_ptr_type
		&& TREE_TYPE (field) == string_ptr_type_node))
	error ("ConstantValue attribute of field '%s' has wrong type",
	       IDENTIFIER_POINTER (DECL_NAME (field)));
    }
}

/* Calculate a hash value for a string encoded in Utf8 format.
 * This returns the same hash value as specified for java.lang.String.hashCode.
 */

static int32
hashUtf8String (const char *str, int len)
{
  const unsigned char* ptr = (const unsigned char*) str;
  const unsigned char *limit = ptr + len;
  int32 hash = 0;
  for (; ptr < limit;)
    {
      int ch = UTF8_GET (ptr, limit);
      /* Updated specification from
	 http://www.javasoft.com/docs/books/jls/clarify.html. */
      hash = (31 * hash) + ch;
    }
  return hash;
}

tree
build_utf8_ref (tree name)
{
  const char * name_ptr = IDENTIFIER_POINTER (name);
  int name_len = IDENTIFIER_LENGTH (name), name_pad;
  char buf[60];
  tree ctype, field = NULL_TREE, str_type, cinit, string;
  static int utf8_count = 0;
  int name_hash;
  tree ref = IDENTIFIER_UTF8_REF (name);
  tree decl;
  VEC(constructor_elt,gc) *v = NULL;
  if (ref != NULL_TREE)
    return ref;

  ctype = make_node (RECORD_TYPE);
  /* '\0' byte plus padding to utf8const_type's alignment.  */
  name_pad = TYPE_ALIGN_UNIT (utf8const_type)
	     - (name_len & (TYPE_ALIGN_UNIT (utf8const_type) - 1));
  str_type = build_prim_array_type (unsigned_byte_type_node,
				    name_len + name_pad);
  PUSH_FIELD (input_location, ctype, field, "hash", unsigned_short_type_node);
  PUSH_FIELD (input_location,
	      ctype, field, "length", unsigned_short_type_node);
  PUSH_FIELD (input_location, ctype, field, "data", str_type);
  FINISH_RECORD (ctype);
  START_RECORD_CONSTRUCTOR (v, ctype);
  name_hash = hashUtf8String (name_ptr, name_len) & 0xFFFF;
  PUSH_FIELD_VALUE (v, "hash", build_int_cst (NULL_TREE, name_hash));
  PUSH_FIELD_VALUE (v, "length", build_int_cst (NULL_TREE, name_len));
  string = build_string (name_len, name_ptr);
  TREE_TYPE (string) = str_type;
  PUSH_FIELD_VALUE (v, "data", string);
  FINISH_RECORD_CONSTRUCTOR (cinit, v, ctype);
  TREE_CONSTANT (cinit) = 1;

  /* Generate a unique-enough identifier.  */
  sprintf(buf, "_Utf%d", ++utf8_count);

  decl = build_decl (input_location,
		     VAR_DECL, get_identifier (buf), utf8const_type);
  TREE_STATIC (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  TREE_READONLY (decl) = 1;
  TREE_THIS_VOLATILE (decl) = 0;
  DECL_INITIAL (decl) = cinit;
  DECL_USER_ALIGN (decl) = 1;

  if (HAVE_GAS_SHF_MERGE)
    {
      int decl_size;
      /* Ensure decl_size is a multiple of utf8const_type's alignment. */
      decl_size = name_len + 4 + name_pad;
      if (flag_merge_constants && decl_size < 256)
	{
	  char buf[32];
	  int flags = (SECTION_OVERRIDE
		       | SECTION_MERGE | (SECTION_ENTSIZE & decl_size));
	  sprintf (buf, ".rodata.jutf8.%d", decl_size);
	  switch_to_section (get_section (buf, flags, NULL));
	  DECL_SECTION_NAME (decl) = build_string (strlen (buf), buf);
	}
    }

  layout_decl (decl, 0);
  DECL_SIZE (decl) = TYPE_SIZE (ctype);
  DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (ctype);
  pushdecl (decl);
  rest_of_decl_compilation (decl, global_bindings_p (), 0);
  varpool_mark_needed_node (varpool_node (decl));
  ref = build1 (ADDR_EXPR, utf8const_ptr_type, decl);
  IDENTIFIER_UTF8_REF (name) = ref;
  return ref;
}

/* Like build_class_ref, but instead of a direct reference generate a
   pointer into the constant pool.  */

static tree
build_indirect_class_ref (tree type)
{
  int index;
  tree cl;
  index = alloc_class_constant (type);
  cl = build_ref_from_constant_pool (index); 
  return convert (promote_type (class_ptr_type), cl);
}

static tree
build_static_class_ref (tree type)
{
  tree decl_name, decl, ref;

  if (TYPE_SIZE (type) == error_mark_node)
    return null_pointer_node;
  decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)),
				"", '/', '/', ".class$$");
  decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
  if (decl == NULL_TREE)
    {
      decl = build_decl (input_location, VAR_DECL, decl_name, class_type_node);
      TREE_STATIC (decl) = 1;
      if (! flag_indirect_classes)
	{
	  TREE_PUBLIC (decl) = 1;
	  if (CLASS_PRIVATE (TYPE_NAME (type)))
	    java_hide_decl (decl);
	}
      DECL_IGNORED_P (decl) = 1;
      DECL_ARTIFICIAL (decl) = 1;
      if (is_compiled_class (type) == 1)
	DECL_EXTERNAL (decl) = 1;
      MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
      DECL_CLASS_FIELD_P (decl) = 1;
      DECL_CONTEXT (decl) = type;

      /* ??? We want to preserve the DECL_CONTEXT we set just above,
	 that that means not calling pushdecl_top_level.  */
      IDENTIFIER_GLOBAL_VALUE (decl_name) = decl;
    }

  ref = build1 (ADDR_EXPR, class_ptr_type, decl);
  return ref;
}

static tree
build_classdollar_field (tree type)
{
  tree decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)),
				     "", '/', '/', ".class$");
  tree decl = IDENTIFIER_GLOBAL_VALUE (decl_name);

  if (decl == NULL_TREE)
    {
      decl 
	= build_decl (input_location,
		      VAR_DECL, decl_name, 
		      (build_type_variant 
		       (build_pointer_type 
			(build_type_variant (class_type_node, 
					     /* const */ 1, 0)),
			/* const */ 1, 0)));
      TREE_STATIC (decl) = 1;
      TREE_CONSTANT (decl) = 1;
      TREE_READONLY (decl) = 1;
      TREE_PUBLIC (decl) = 1;
      java_hide_decl (decl);
      DECL_IGNORED_P (decl) = 1;
      DECL_ARTIFICIAL (decl) = 1;
      MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
      IDENTIFIER_GLOBAL_VALUE (decl_name) = decl;
      DECL_CLASS_FIELD_P (decl) = 1;
      DECL_CONTEXT (decl) = type;
    }

  return decl;
}

/* Create a local variable that holds the current class$.  */

void
cache_this_class_ref (tree fndecl)
{
  if (optimize)
    {
      tree classdollar_field;
      if (flag_indirect_classes)
	classdollar_field = build_classdollar_field (output_class);
      else
	classdollar_field = build_static_class_ref (output_class);

      this_classdollar = build_decl (input_location,
				     VAR_DECL, NULL_TREE, 
				     TREE_TYPE (classdollar_field));
      
      java_add_local_var (this_classdollar);
      java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (this_classdollar), 
			     this_classdollar, classdollar_field));
    }
  else
    this_classdollar = build_classdollar_field (output_class);

  /* Prepend class initialization for static methods reachable from
     other classes.  */
  if (METHOD_STATIC (fndecl)
      && (! METHOD_PRIVATE (fndecl)
          || INNER_CLASS_P (DECL_CONTEXT (fndecl)))
      && ! DECL_CLINIT_P (fndecl)
      && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl))))
    {
      tree init = build_call_expr (soft_initclass_node, 1,
				   this_classdollar);
      java_add_stmt (init);
    }
}

/* Remove the reference to the local variable that holds the current
   class$.  */

void
uncache_this_class_ref (tree fndecl ATTRIBUTE_UNUSED)
{
  this_classdollar = build_classdollar_field (output_class);
}

/* Build a reference to the class TYPE.
   Also handles primitive types and array types. */

tree
build_class_ref (tree type)
{
  int is_compiled = is_compiled_class (type);
  if (is_compiled)
    {
      tree ref, decl;
      if (TREE_CODE (type) == POINTER_TYPE)
	type = TREE_TYPE (type);

      if (flag_indirect_dispatch
	  && type != output_class
	  && TREE_CODE (type) == RECORD_TYPE)
	return build_indirect_class_ref (type);

      if (type == output_class && flag_indirect_classes)
	{
	  /* This can be NULL if we see a JNI stub before we see any
	     other method.  */
	  if (! this_classdollar)
	    this_classdollar = build_classdollar_field (output_class);
	  return this_classdollar;
	}
      
      if (TREE_CODE (type) == RECORD_TYPE)
	return build_static_class_ref (type);
      else
	{
	  const char *name;
	  tree decl_name;
	  char buffer[25];
	  decl_name = TYPE_NAME (type);
	  if (TREE_CODE (decl_name) == TYPE_DECL)
	    decl_name = DECL_NAME (decl_name);
	  name = IDENTIFIER_POINTER (decl_name);
	  if (strncmp (name, "promoted_", 9) == 0)
	    name += 9;
	  sprintf (buffer, "_Jv_%sClass", name);
	  decl_name = get_identifier (buffer);
	  decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
	  if (decl == NULL_TREE)
	    {
	      decl = build_decl (input_location,
				 VAR_DECL, decl_name, class_type_node);
	      TREE_STATIC (decl) = 1;
	      TREE_PUBLIC (decl) = 1;
	      DECL_EXTERNAL (decl) = 1;
	      DECL_ARTIFICIAL (decl) = 1;
	      pushdecl_top_level (decl);
	    }
	}

      ref = build1 (ADDR_EXPR, class_ptr_type, decl);
      return ref;
    }
  else
    return build_indirect_class_ref (type);
}

/* Create a local statically allocated variable that will hold a
   pointer to a static field.  */

static tree
build_fieldref_cache_entry (int index, tree fdecl ATTRIBUTE_UNUSED)
{
  tree decl, decl_name;
  const char *name = IDENTIFIER_POINTER (mangled_classname ("_cpool_", output_class));
  char *buf = (char *) alloca (strlen (name) + 20);
  sprintf (buf, "%s_%d_ref", name, index);
  decl_name = get_identifier (buf);
  decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
  if (decl == NULL_TREE)
    {
      decl = build_decl (input_location,
			 VAR_DECL, decl_name, ptr_type_node);
      TREE_STATIC (decl) = 1;
      TREE_PUBLIC (decl) = 0;
      DECL_EXTERNAL (decl) = 0;
      DECL_ARTIFICIAL (decl) = 1;
      DECL_IGNORED_P (decl) = 1;
      pushdecl_top_level (decl);
    }
  return decl;
}

tree
build_static_field_ref (tree fdecl)
{
  tree fclass = DECL_CONTEXT (fdecl);
  int is_compiled = is_compiled_class (fclass);

  /* Allow static final fields to fold to a constant.  When using
     -findirect-dispatch, we simply never do this folding if compiling
     from .class; in the .class file constants will be referred to via
     the constant pool.  */
  if (!flag_indirect_dispatch
      && (is_compiled
	  || (FIELD_FINAL (fdecl) && DECL_INITIAL (fdecl) != NULL_TREE
	      && (JSTRING_TYPE_P (TREE_TYPE (fdecl))
		  || JNUMERIC_TYPE_P (TREE_TYPE (fdecl)))
	      && TREE_CONSTANT (DECL_INITIAL (fdecl)))))
    {
      if (is_compiled == 1)
	DECL_EXTERNAL (fdecl) = 1;
    }
  else
    {
      /* Generate a CONSTANT_FieldRef for FDECL in the constant pool
	 and a class local static variable CACHE_ENTRY, then
      
      *(fdecl **)((__builtin_expect (cache_entry == null, false)) 
		  ? cache_entry = _Jv_ResolvePoolEntry (output_class, cpool_index)
		  : cache_entry)

      This can mostly be optimized away, so that the usual path is a
      load followed by a test and branch.  _Jv_ResolvePoolEntry is
      only called once for each constant pool entry.

      There is an optimization that we don't do: at the start of a
      method, create a local copy of CACHE_ENTRY and use that instead.

      */

      int cpool_index = alloc_constant_fieldref (output_class, fdecl);
      tree cache_entry = build_fieldref_cache_entry (cpool_index, fdecl);
      tree test
        = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2,
			   build2 (EQ_EXPR, boolean_type_node,
				   cache_entry, null_pointer_node),
			   boolean_false_node);
      tree cpool_index_cst = build_int_cst (NULL_TREE, cpool_index);
      tree init
	= build_call_expr (soft_resolvepoolentry_node, 2,
			   build_class_ref (output_class),
			   cpool_index_cst);
      init = build2 (MODIFY_EXPR, ptr_type_node, cache_entry, init);
      init = build3 (COND_EXPR, ptr_type_node, test, init, cache_entry);
      init = fold_convert (build_pointer_type (TREE_TYPE (fdecl)), init);
      fdecl = build1 (INDIRECT_REF, TREE_TYPE (fdecl), init);
    }
  return fdecl;
}

int
get_access_flags_from_decl (tree decl)
{
  int access_flags = 0;
  if (TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == VAR_DECL)
    {
      if (FIELD_STATIC (decl))
	access_flags |= ACC_STATIC;
      if (FIELD_PUBLIC (decl))
	access_flags |= ACC_PUBLIC;
      if (FIELD_PROTECTED (decl))
	access_flags |= ACC_PROTECTED;
      if (FIELD_PRIVATE (decl))
	access_flags |= ACC_PRIVATE;
      if (FIELD_FINAL (decl))
	access_flags |= ACC_FINAL;
      if (FIELD_VOLATILE (decl))
	access_flags |= ACC_VOLATILE;
      if (FIELD_TRANSIENT (decl))
	access_flags |= ACC_TRANSIENT;
      if (FIELD_ENUM (decl))
	access_flags |= ACC_ENUM;
      if (FIELD_SYNTHETIC (decl))
	access_flags |= ACC_SYNTHETIC;
      return access_flags;
    }
  if (TREE_CODE (decl) == TYPE_DECL)
    {
      if (CLASS_PUBLIC (decl))
	access_flags |= ACC_PUBLIC;
      if (CLASS_FINAL (decl))
	access_flags |= ACC_FINAL;
      if (CLASS_SUPER (decl))
	access_flags |= ACC_SUPER;
      if (CLASS_INTERFACE (decl))
	access_flags |= ACC_INTERFACE;
      if (CLASS_ABSTRACT (decl))
	access_flags |= ACC_ABSTRACT;
      if (CLASS_STATIC (decl))
	access_flags |= ACC_STATIC;
      if (CLASS_PRIVATE (decl))
	access_flags |= ACC_PRIVATE;
      if (CLASS_PROTECTED (decl))
	access_flags |= ACC_PROTECTED;
      if (CLASS_STRICTFP (decl))
	access_flags |= ACC_STRICT;
      if (CLASS_ENUM (decl))
	access_flags |= ACC_ENUM;
      if (CLASS_SYNTHETIC (decl))
	access_flags |= ACC_SYNTHETIC;
      if (CLASS_ANNOTATION (decl))
	access_flags |= ACC_ANNOTATION;
      return access_flags;
    }
  if (TREE_CODE (decl) == FUNCTION_DECL)
    {
      if (METHOD_PUBLIC (decl))
	access_flags |= ACC_PUBLIC;
      if (METHOD_PRIVATE (decl))
	access_flags |= ACC_PRIVATE;
      if (METHOD_PROTECTED (decl))
	access_flags |= ACC_PROTECTED;
      if (METHOD_STATIC (decl))
	access_flags |= ACC_STATIC;
      if (METHOD_FINAL (decl))
	access_flags |= ACC_FINAL;
      if (METHOD_SYNCHRONIZED (decl))
	access_flags |= ACC_SYNCHRONIZED;
      if (METHOD_NATIVE (decl))
	access_flags |= ACC_NATIVE;
      if (METHOD_ABSTRACT (decl))
	access_flags |= ACC_ABSTRACT;
      if (METHOD_STRICTFP (decl))
	access_flags |= ACC_STRICT;
      if (METHOD_INVISIBLE (decl))
	access_flags |= ACC_INVISIBLE;
      if (DECL_ARTIFICIAL (decl))
	access_flags |= ACC_SYNTHETIC;
      if (METHOD_BRIDGE (decl))
	access_flags |= ACC_BRIDGE;
      if (METHOD_VARARGS (decl))
	access_flags |= ACC_VARARGS;
      return access_flags;
    }
  gcc_unreachable ();
}

static GTY (()) int alias_labelno = 0;

/* Create a private alias for METHOD. Using this alias instead of the method
   decl ensures that ncode entries in the method table point to the real function 
   at runtime, not a PLT entry.  */

static tree
make_local_function_alias (tree method)
{
#ifdef ASM_OUTPUT_DEF
  tree alias;
  
  const char *method_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (method));
  char *name = (char *) alloca (strlen (method_name) + 2);
  char *buf = (char *) alloca (strlen (method_name) + 128);

  /* Only create aliases for local functions.  */
  if (DECL_EXTERNAL (method))
    return method;
    
  /* Prefix method_name with 'L' for the alias label.  */
  *name = 'L';
  strcpy (name + 1, method_name);

  targetm.asm_out.generate_internal_label (buf, name, alias_labelno++);  
  alias = build_decl (input_location,
		      FUNCTION_DECL, get_identifier (buf),
		      TREE_TYPE (method));
  DECL_CONTEXT (alias) = NULL;
  TREE_READONLY (alias) = TREE_READONLY (method);
  TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (method);
  TREE_PUBLIC (alias) = 0;
  DECL_EXTERNAL (alias) = 0;
  DECL_ARTIFICIAL (alias) = 1;
  DECL_INITIAL (alias) = error_mark_node;
  TREE_ADDRESSABLE (alias) = 1;
  TREE_USED (alias) = 1;
  TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
  if (!flag_syntax_only)
    assemble_alias (alias, DECL_ASSEMBLER_NAME (method));
  return alias;
#else
  return method;
#endif
}

/** Make reflection data (_Jv_Field) for field FDECL. */

static tree
make_field_value (tree fdecl)
{
  tree finit;
  int flags;
  tree type = TREE_TYPE (fdecl);
  int resolved = is_compiled_class (type) && ! flag_indirect_dispatch;
  VEC(constructor_elt,gc) *v = NULL;

  START_RECORD_CONSTRUCTOR (v, field_type_node);
  PUSH_FIELD_VALUE (v, "name", build_utf8_ref (DECL_NAME (fdecl)));
  if (resolved)
    type = build_class_ref (type);
  else
    {
      tree signature = build_java_signature (type);

      type = build_utf8_ref (unmangle_classname 
			     (IDENTIFIER_POINTER (signature),
			      IDENTIFIER_LENGTH (signature)));
    }
  PUSH_FIELD_VALUE (v, "type", type);

  flags = get_access_flags_from_decl (fdecl);
  if (! resolved)
    flags |= 0x8000 /* FIELD_UNRESOLVED_FLAG */;

  PUSH_FIELD_VALUE (v, "accflags", build_int_cst (NULL_TREE, flags));
  PUSH_FIELD_VALUE (v, "bsize", TYPE_SIZE_UNIT (TREE_TYPE (fdecl)));

  {
    tree field_address = integer_zero_node;
    tree index, value;
    if ((DECL_INITIAL (fdecl) || ! flag_indirect_classes) 
	&& FIELD_STATIC (fdecl))
      field_address = build_address_of (fdecl);

    index = (FIELD_STATIC (fdecl)
	     ? DECL_CHAIN (TYPE_FIELDS (field_info_union_node))
	     : TYPE_FIELDS (field_info_union_node));
    value = (FIELD_STATIC (fdecl)
	     ? field_address
	     : byte_position (fdecl));

    PUSH_FIELD_VALUE
      (v, "info",
       build_constructor_single (field_info_union_node, index, value));
  }

  FINISH_RECORD_CONSTRUCTOR (finit, v, field_type_node);
  return finit;
}

/** Make reflection data (_Jv_Method) for method MDECL. */

static tree
make_method_value (tree mdecl)
{
  static int method_name_count = 0;
  tree minit;
  tree index;
  tree code;
  tree class_decl;
#define ACC_TRANSLATED          0x4000
  int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
  VEC(constructor_elt,gc) *v = NULL;

  class_decl = DECL_CONTEXT (mdecl);
  /* For interfaces, the index field contains the dispatch index. */
  if (CLASS_INTERFACE (TYPE_NAME (class_decl)))
    index = build_int_cst (NULL_TREE,
			   get_interface_method_index (mdecl, class_decl));
  else if (!flag_indirect_dispatch && get_method_index (mdecl) != NULL_TREE)
    index = get_method_index (mdecl);
  else
    index = integer_minus_one_node;

  code = null_pointer_node;
  if (METHOD_ABSTRACT (mdecl))
    code = build1 (ADDR_EXPR, nativecode_ptr_type_node,
		   soft_abstractmethod_node);
  else
    code = build1 (ADDR_EXPR, nativecode_ptr_type_node, 
		   make_local_function_alias (mdecl));
  START_RECORD_CONSTRUCTOR (v, method_type_node);
  PUSH_FIELD_VALUE (v, "name",
		    build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
				    init_identifier_node
				    : DECL_NAME (mdecl)));
  {
    tree signature = build_java_signature (TREE_TYPE (mdecl));
    PUSH_FIELD_VALUE (v, "signature", 
		      (build_utf8_ref 
		       (unmangle_classname 
			(IDENTIFIER_POINTER(signature),
			 IDENTIFIER_LENGTH(signature)))));
  }
  PUSH_FIELD_VALUE (v, "accflags", build_int_cst (NULL_TREE, accflags));
  PUSH_FIELD_VALUE (v, "index", index);
  PUSH_FIELD_VALUE (v, "ncode", code);

  {
    /* Compute the `throws' information for the method.  */
    tree table = null_pointer_node;

    if (!VEC_empty (tree, DECL_FUNCTION_THROWS (mdecl)))
      {
	int length = 1 + VEC_length (tree, DECL_FUNCTION_THROWS (mdecl));
	tree t, type, array;
	char buf[60];
	VEC(constructor_elt,gc) *v = NULL;
	int idx = length - 1;
	unsigned ix;
	constructor_elt *e;

	v = VEC_alloc (constructor_elt, gc, length);
	VEC_safe_grow_cleared (constructor_elt, gc, v, length);

	e = VEC_index (constructor_elt, v, idx--);
	e->value = null_pointer_node;

	FOR_EACH_VEC_ELT (tree, DECL_FUNCTION_THROWS (mdecl), ix, t)
	  {
	    tree sig = DECL_NAME (TYPE_NAME (t));
	    tree utf8
	      = build_utf8_ref (unmangle_classname (IDENTIFIER_POINTER (sig),
						    IDENTIFIER_LENGTH (sig)));
	    e = VEC_index (constructor_elt, v, idx--);
	    e->value = utf8;
	  }
	gcc_assert (idx == -1);
	type = build_prim_array_type (ptr_type_node, length);
	table = build_constructor (type, v);
	/* Compute something unique enough.  */
	sprintf (buf, "_methods%d", method_name_count++);
	array = build_decl (input_location,
			    VAR_DECL, get_identifier (buf), type);
	DECL_INITIAL (array) = table;
	TREE_STATIC (array) = 1;
	DECL_ARTIFICIAL (array) = 1;
	DECL_IGNORED_P (array) = 1;
	rest_of_decl_compilation (array, 1, 0);

	table = build1 (ADDR_EXPR, ptr_type_node, array);
      }

    PUSH_FIELD_VALUE (v, "throws", table);
  }

  FINISH_RECORD_CONSTRUCTOR (minit, v, method_type_node);
  return minit;
}

static tree
get_dispatch_vector (tree type)
{
  tree vtable = TYPE_VTABLE (type);

  if (vtable == NULL_TREE)
    {
      HOST_WIDE_INT i;
      tree method;
      tree super = CLASSTYPE_SUPER (type);
      HOST_WIDE_INT nvirtuals = tree_low_cst (TYPE_NVIRTUALS (type), 0);
      vtable = make_tree_vec (nvirtuals);
      TYPE_VTABLE (type) = vtable;
      if (super != NULL_TREE)
	{
	  tree super_vtable = get_dispatch_vector (super);

	  for (i = tree_low_cst (TYPE_NVIRTUALS (super), 0); --i >= 0; )
	    TREE_VEC_ELT (vtable, i) = TREE_VEC_ELT (super_vtable, i);
	}

      for (method = TYPE_METHODS (type);  method != NULL_TREE;
	   method = DECL_CHAIN (method))
	{
	  tree method_index = get_method_index (method);
	  if (method_index != NULL_TREE
	      && host_integerp (method_index, 0))
	    TREE_VEC_ELT (vtable, tree_low_cst (method_index, 0)) = method;
	}
    }

  return vtable;
}

static tree
get_dispatch_table (tree type, tree this_class_addr)
{
  int abstract_p = CLASS_ABSTRACT (TYPE_NAME (type));
  tree vtable = get_dispatch_vector (type);
  int i, j;
  int nvirtuals = TREE_VEC_LENGTH (vtable);
  int arraysize;
  tree gc_descr;
  VEC(constructor_elt,gc) *v = NULL;
  constructor_elt *e;
  tree arraytype;

  arraysize = (TARGET_VTABLE_USES_DESCRIPTORS? nvirtuals + 1 : nvirtuals + 2);
  if (TARGET_VTABLE_USES_DESCRIPTORS)
    arraysize *= TARGET_VTABLE_USES_DESCRIPTORS;
  arraysize += 2;

  VEC_safe_grow_cleared (constructor_elt, gc, v, arraysize);
  e = VEC_index (constructor_elt, v, arraysize - 1);

#define CONSTRUCTOR_PREPEND_VALUE(E, V) E->value = V, E--
  for (i = nvirtuals;  --i >= 0; )
    {
      tree method = TREE_VEC_ELT (vtable, i);
      if (METHOD_ABSTRACT (method))
	{
	  if (! abstract_p)
	    warning_at (DECL_SOURCE_LOCATION (method), 0,
			"abstract method in non-abstract class");

	  if (TARGET_VTABLE_USES_DESCRIPTORS)
	    for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
	      CONSTRUCTOR_PREPEND_VALUE (e, null_pointer_node);
	  else
	    CONSTRUCTOR_PREPEND_VALUE (e, null_pointer_node);
	}
      else
	{
	  if (TARGET_VTABLE_USES_DESCRIPTORS)
	    for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
	      {
		tree fdesc = build2 (FDESC_EXPR, nativecode_ptr_type_node, 
				     method, build_int_cst (NULL_TREE, j));
		TREE_CONSTANT (fdesc) = 1;
		CONSTRUCTOR_PREPEND_VALUE (e, fdesc);
	      }
	  else
	    CONSTRUCTOR_PREPEND_VALUE (e,
				       build1 (ADDR_EXPR,
					       nativecode_ptr_type_node,
					       method));
	}
    }

  /* Dummy entry for compatibility with G++ -fvtable-thunks.  When
     using the Boehm GC we sometimes stash a GC type descriptor
     there. We set the PURPOSE to NULL_TREE not to interfere (reset)
     the emitted byte count during the output to the assembly file. */
  /* With TARGET_VTABLE_USES_DESCRIPTORS, we only add one extra
     fake "function descriptor".  It's first word is the is the class
     pointer, and subsequent words (usually one) contain the GC descriptor.
     In all other cases, we reserve two extra vtable slots. */
  gc_descr =  get_boehm_type_descriptor (type);
  CONSTRUCTOR_PREPEND_VALUE (e, gc_descr);
  for (j = 1; j < TARGET_VTABLE_USES_DESCRIPTORS-1; ++j)
    CONSTRUCTOR_PREPEND_VALUE (e, gc_descr);
  CONSTRUCTOR_PREPEND_VALUE (e, this_class_addr);

  /** Pointer to type_info object (to be implemented), according to g++ ABI. */
  CONSTRUCTOR_PREPEND_VALUE (e, null_pointer_node);
  /** Offset to start of whole object.  Always (ptrdiff_t)0 for Java. */
  gcc_assert (e == VEC_address (constructor_elt, v));
  e->index = integer_zero_node;
  e->value = null_pointer_node;
#undef CONSTRUCTOR_PREPEND_VALUE

  arraytype = build_prim_array_type (nativecode_ptr_type_node, arraysize);
  return build_constructor (arraytype, v);
}


/* Set the method_index for a method decl.  */
void
set_method_index (tree decl, tree method_index)
{
  if (method_index != NULL_TREE)
    {
      /* method_index is null if we're using indirect dispatch.  */
      method_index = fold (convert (sizetype, method_index));

      if (TARGET_VTABLE_USES_DESCRIPTORS)
	/* Add one to skip bogus descriptor for class and GC descriptor. */
	method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
      else
	/* Add 1 to skip "class" field of dtable, and 1 to skip GC
	   descriptor.  */
	method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
    }

  DECL_VINDEX (decl) = method_index;
}

/* Get the method_index for a method decl.  */
tree
get_method_index (tree decl)
{
  tree method_index = DECL_VINDEX (decl);

  if (! method_index)
    return NULL;

  if (TARGET_VTABLE_USES_DESCRIPTORS)
    /* Sub one to skip bogus descriptor for class and GC descriptor. */
    method_index = size_binop (MINUS_EXPR, method_index, size_int (1));
  else
    /* Sub 1 to skip "class" field of dtable, and 1 to skip GC descriptor.  */
    method_index = size_binop (MINUS_EXPR, method_index, size_int (2));

  return method_index;
}

static int
supers_all_compiled (tree type)
{
  while (type != NULL_TREE)
    {
      if (!assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))))
	return 0;
      type = CLASSTYPE_SUPER (type);
    }
  return 1;
}

static void
add_table_and_syms (VEC(constructor_elt,gc) **v,
                    VEC(method_entry,gc) *methods,
                    const char *table_name, tree table_slot, tree table_type,
                    const char *syms_name, tree syms_slot)
{
  if (methods == NULL)
    {
      PUSH_FIELD_VALUE (*v, table_name, null_pointer_node);
      PUSH_FIELD_VALUE (*v, syms_name, null_pointer_node);
    }
  else
    {
      pushdecl_top_level (syms_slot);
      PUSH_FIELD_VALUE (*v, table_name,
                        build1 (ADDR_EXPR, table_type, table_slot));
      PUSH_FIELD_VALUE (*v, syms_name,
                        build1 (ADDR_EXPR, symbols_array_ptr_type,
                                syms_slot));
      TREE_CONSTANT (table_slot) = 1;
    }
}
                    
void
make_class_data (tree type)
{
  tree decl, cons, temp;
  tree field, fields_decl;
  HOST_WIDE_INT static_field_count = 0;
  HOST_WIDE_INT instance_field_count = 0;
  HOST_WIDE_INT field_count;
  tree field_array_type;
  tree method;
  tree dtable_decl = NULL_TREE;
  HOST_WIDE_INT method_count = 0;
  tree method_array_type;
  tree methods_decl;
  tree super;
  tree this_class_addr;
  tree constant_pool_constructor;
  tree interfaces = null_pointer_node;
  int interface_len = 0;
  int uses_jv_markobj = 0;
  tree type_decl = TYPE_NAME (type);
  tree id_main = get_identifier("main");
  tree id_class = get_identifier("java.lang.Class");
  /** Offset from start of virtual function table declaration
      to where objects actually point at, following new g++ ABI. */
  tree dtable_start_offset = size_int (2 * POINTER_SIZE / BITS_PER_UNIT);
  VEC(int, heap) *field_indexes;
  tree first_real_field;
  VEC(constructor_elt,gc) *v1 = NULL, *v2 = NULL;
  tree reflection_data;
  VEC(constructor_elt,gc) *static_fields = NULL;
  VEC(constructor_elt,gc) *instance_fields = NULL;
  VEC(constructor_elt,gc) *methods = NULL;

  this_class_addr = build_static_class_ref (type);
  decl = TREE_OPERAND (this_class_addr, 0);

  if (supers_all_compiled (type) && ! CLASS_INTERFACE (type_decl)
      && !flag_indirect_dispatch)
    {
      tree dtable = get_dispatch_table (type, this_class_addr);
      uses_jv_markobj = uses_jv_markobj_p (dtable);
      if (type == class_type_node && class_dtable_decl != NULL_TREE)
	{
	  /* We've already created some other class, and consequently
	     we made class_dtable_decl.  Now we just want to fill it
	     in.  */
	  dtable_decl = class_dtable_decl;
	}
      else
	{
	  dtable_decl = build_dtable_decl (type);
	  TREE_STATIC (dtable_decl) = 1;
	  DECL_ARTIFICIAL (dtable_decl) = 1;
	  DECL_IGNORED_P (dtable_decl) = 1;
	}

      TREE_PUBLIC (dtable_decl) = 1;
      DECL_INITIAL (dtable_decl) = dtable;
      /* The only dispatch table exported from a DSO is the dispatch
	 table for java.lang.Class.  */
      if (DECL_NAME (type_decl) != id_class)
	java_hide_decl (dtable_decl);
      if (! flag_indirect_classes)
	rest_of_decl_compilation (dtable_decl, 1, 0);
      /* Maybe we're compiling Class as the first class.  If so, set
	 class_dtable_decl to the decl we just made.  */
      if (type == class_type_node && class_dtable_decl == NULL_TREE)
	class_dtable_decl = dtable_decl;
    }

  /* Build Field array. */
  field = TYPE_FIELDS (type);
  while (field && DECL_ARTIFICIAL (field))
    field = DECL_CHAIN (field);  /* Skip dummy fields.  */
  if (field && DECL_NAME (field) == NULL_TREE)
    field = DECL_CHAIN (field);  /* Skip dummy field for inherited data. */
  first_real_field = field;

  /* First count static and instance fields.  */
  for ( ; field != NULL_TREE; field = DECL_CHAIN (field))
    {
      if (! DECL_ARTIFICIAL (field))
	{
	  if (FIELD_STATIC (field))
	    static_field_count++;
	  else if (uses_jv_markobj || !flag_reduced_reflection)
	    instance_field_count++;
	}
    }
  field_count = static_field_count + instance_field_count;
  field_indexes = VEC_alloc (int, heap, field_count);
  
  /* gcj sorts fields so that static fields come first, followed by
     instance fields.  Unfortunately, by the time this takes place we
     have already generated the reflection_data for this class, and
     that data contains indexes into the fields.  So, we generate a
     permutation that maps each original field index to its final
     position.  Then we pass this permutation to
     rewrite_reflection_indexes(), which fixes up the reflection
     data.  */
  {
    int i;
    int static_count = 0;
    int instance_count = static_field_count;
    int field_index;

    for (i = 0, field = first_real_field; 
	 field != NULL_TREE; 
	 field = DECL_CHAIN (field), i++)
    {
      if (! DECL_ARTIFICIAL (field))
	{
	  field_index = 0;
	  if (FIELD_STATIC (field))
	    field_index = static_count++;
	  else if (uses_jv_markobj || !flag_reduced_reflection)
	    field_index = instance_count++;
	  else
	    continue;
	  VEC_quick_push (int, field_indexes, field_index);
	}
    }
  }

  for (field = first_real_field; field != NULL_TREE; 
       field = DECL_CHAIN (field))
    {
      if (! DECL_ARTIFICIAL (field))
	{
	  if (FIELD_STATIC (field))
	    {
              /* We must always create reflection data for static fields
                 as it is used in the creation of the field itself. */
              tree init = make_field_value (field);
	      tree initial = DECL_INITIAL (field);
              CONSTRUCTOR_APPEND_ELT (static_fields, NULL_TREE, init);
	      /* If the initial value is a string constant,
		 prevent output_constant from trying to assemble the value. */
	      if (initial != NULL_TREE
		  && TREE_TYPE (initial) == string_ptr_type_node)
		DECL_INITIAL (field) = NULL_TREE;
	      rest_of_decl_compilation (field, 1, 1);
	      DECL_INITIAL (field) = initial;
	    }
	  else if (uses_jv_markobj || !flag_reduced_reflection)
	    {
              tree init = make_field_value (field);
              CONSTRUCTOR_APPEND_ELT (instance_fields, NULL_TREE, init);
	    }
	}
    }

  gcc_assert (static_field_count
              == (int) VEC_length (constructor_elt, static_fields));
  gcc_assert (instance_field_count
              == (int) VEC_length (constructor_elt, instance_fields));

  if (field_count > 0)
    {
      VEC_safe_splice (constructor_elt, gc, static_fields, instance_fields);
      field_array_type = build_prim_array_type (field_type_node, field_count);
      fields_decl = build_decl (input_location,
				VAR_DECL, mangled_classname ("_FL_", type),
				field_array_type);
      DECL_INITIAL (fields_decl)
        = build_constructor (field_array_type, static_fields);
      TREE_STATIC (fields_decl) = 1;
      DECL_ARTIFICIAL (fields_decl) = 1;
      DECL_IGNORED_P (fields_decl) = 1;
      rest_of_decl_compilation (fields_decl, 1, 0);
    }
  else
    fields_decl = NULL_TREE;

  /* Build Method array. */
  for (method = TYPE_METHODS (type);
       method != NULL_TREE; method = DECL_CHAIN (method))
    {
      tree init;
      if (METHOD_PRIVATE (method)
	  && ! flag_keep_inline_functions
	  && optimize)
	continue;
      /* Even if we have a decl, we don't necessarily have the code.
	 This can happen if we inherit a method from a superclass for
	 which we don't have a .class file.  */
      if (METHOD_DUMMY (method))
	continue;

      /* Generate method reflection data if:

          - !flag_reduced_reflection.

          - <clinit> -- The runtime uses reflection to initialize the
            class.

          - Any method in class java.lang.Class -- Class.forName() and
            perhaps other things require it.

          - class$ -- It does not work if reflection data missing.

          - main -- Reflection is used to find main(String[]) methods.

          - public not static -- It is potentially part of an
            interface.  The runtime uses reflection data to build
            interface dispatch tables.  */
      if (!flag_reduced_reflection
          || DECL_CLINIT_P (method)
          || DECL_NAME (type_decl) == id_class
          || DECL_NAME (method) == id_main
          || (METHOD_PUBLIC (method) && !METHOD_STATIC (method)))
        {
          init = make_method_value (method);
          method_count++;
          CONSTRUCTOR_APPEND_ELT (methods, NULL_TREE, init);
        }
    }
  method_array_type = build_prim_array_type (method_type_node, method_count);
  methods_decl = build_decl (input_location,
			     VAR_DECL, mangled_classname ("_MT_", type),
			     method_array_type);
  DECL_INITIAL (methods_decl) = build_constructor (method_array_type, methods);
  TREE_STATIC (methods_decl) = 1;
  DECL_ARTIFICIAL (methods_decl) = 1;
  DECL_IGNORED_P (methods_decl) = 1;
  rest_of_decl_compilation (methods_decl, 1, 0);

  if (class_dtable_decl == NULL_TREE)
    {
      class_dtable_decl = build_dtable_decl (class_type_node);
      TREE_STATIC (class_dtable_decl) = 1;
      DECL_ARTIFICIAL (class_dtable_decl) = 1;
      DECL_IGNORED_P (class_dtable_decl) = 1;
      if (is_compiled_class (class_type_node) != 2)
	{
	  DECL_EXTERNAL (class_dtable_decl) = 1;
	  rest_of_decl_compilation (class_dtable_decl, 1, 0);
	}
    }

  super = CLASSTYPE_SUPER (type);
  if (super == NULL_TREE)
    super = null_pointer_node;
  else if (! flag_indirect_dispatch
	   && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
	   && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (super)))))
    super = build_class_ref (super);
  else
    {
      int super_index = alloc_class_constant (super);
      super = build_int_cst (ptr_type_node, super_index);
    }

  /* Build and emit the array of implemented interfaces. */
  if (type != object_type_node)
    interface_len = BINFO_N_BASE_BINFOS (TYPE_BINFO (type)) - 1;
  
  if (interface_len > 0)
    {
      int i;
      tree interface_array_type, idecl;
      VEC(constructor_elt,gc) *init = VEC_alloc (constructor_elt, gc,
						 interface_len);
      interface_array_type
	= build_prim_array_type (class_ptr_type, interface_len);
      idecl = build_decl (input_location,
			  VAR_DECL, mangled_classname ("_IF_", type),
			  interface_array_type);
      
      for (i = 1; i <= interface_len; i++)
	{
	  tree child = BINFO_BASE_BINFO (TYPE_BINFO (type), i);
	  tree iclass = BINFO_TYPE (child);
	  tree index;
	  if (! flag_indirect_dispatch
	      && (assume_compiled 
		  (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (iclass))))))
	    index = build_class_ref (iclass);
	  else
	    {
	      int int_index = alloc_class_constant (iclass);
	      index = build_int_cst (ptr_type_node, int_index);
	    }
	  CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, index);
	}
      DECL_INITIAL (idecl) = build_constructor (interface_array_type, init);
      TREE_STATIC (idecl) = 1;
      DECL_ARTIFICIAL (idecl) = 1;
      DECL_IGNORED_P (idecl) = 1;
      interfaces = build1 (ADDR_EXPR, ptr_type_node, idecl);
      rest_of_decl_compilation (idecl, 1, 0);
    }

  constant_pool_constructor = build_constants_constructor ();

  if (flag_indirect_dispatch)
    {
      TYPE_OTABLE_DECL (type) 
	= emit_symbol_table 
	(DECL_NAME (TYPE_OTABLE_DECL (type)), 
	 TYPE_OTABLE_DECL (type), TYPE_OTABLE_METHODS (type), 
	 TYPE_OTABLE_SYMS_DECL (type), integer_type_node, 1);
       
      TYPE_ATABLE_DECL (type) 
	= emit_symbol_table 
	(DECL_NAME (TYPE_ATABLE_DECL (type)), 
	 TYPE_ATABLE_DECL (type), TYPE_ATABLE_METHODS (type), 
	 TYPE_ATABLE_SYMS_DECL (type), ptr_type_node, 1);
       
      TYPE_ITABLE_DECL (type) 
	= emit_symbol_table 
	(DECL_NAME (TYPE_ITABLE_DECL (type)), 
	 TYPE_ITABLE_DECL (type), TYPE_ITABLE_METHODS (type), 
	 TYPE_ITABLE_SYMS_DECL (type), ptr_type_node, 2);
    }
  
  TYPE_CTABLE_DECL (type) = emit_catch_table (type);

  START_RECORD_CONSTRUCTOR (v1, object_type_node);
  PUSH_FIELD_VALUE (v1, "vtable",
		    (flag_indirect_classes 
		     ? null_pointer_node
		     : build2 (POINTER_PLUS_EXPR, dtable_ptr_type,
			       build1 (ADDR_EXPR, dtable_ptr_type,
				       class_dtable_decl),
			       dtable_start_offset)));
  if (! flag_hash_synchronization)
    PUSH_FIELD_VALUE (v1, "sync_info", null_pointer_node);
  FINISH_RECORD_CONSTRUCTOR (temp, v1, object_type_node);
  START_RECORD_CONSTRUCTOR (v2, class_type_node);
  PUSH_SUPER_VALUE (v2, temp);
  PUSH_FIELD_VALUE (v2, "next_or_version", gcj_abi_version);
  PUSH_FIELD_VALUE (v2, "name", build_utf8_ref (DECL_NAME (type_decl)));
  PUSH_FIELD_VALUE (v2, "accflags",
		    build_int_cst (NULL_TREE,
				   get_access_flags_from_decl (type_decl)));

  PUSH_FIELD_VALUE (v2, "superclass", 
		    CLASS_INTERFACE (type_decl) ? null_pointer_node : super);
  PUSH_FIELD_VALUE (v2, "constants", constant_pool_constructor);
  PUSH_FIELD_VALUE (v2, "methods",
                    methods_decl == NULL_TREE ? null_pointer_node
		    : build1 (ADDR_EXPR, method_ptr_type_node, methods_decl));
  PUSH_FIELD_VALUE (v2, "method_count",
		    build_int_cst (NULL_TREE, method_count));

  PUSH_FIELD_VALUE (v2, "vtable_method_count",
                    (flag_indirect_dispatch
                     ? integer_minus_one_node
                     : TYPE_NVIRTUALS (type)));
    
  PUSH_FIELD_VALUE (v2, "fields",
		    fields_decl == NULL_TREE ? null_pointer_node
		    : build1 (ADDR_EXPR, field_ptr_type_node, fields_decl));
  /* If we're using the binary compatibility ABI we don't know the
     size until load time.  */
  PUSH_FIELD_VALUE (v2, "size_in_bytes", 
		    (flag_indirect_dispatch 
		     ? integer_minus_one_node 
		     : size_in_bytes (type)));
  PUSH_FIELD_VALUE (v2, "field_count", 
		    build_int_cst (NULL_TREE, field_count));
  PUSH_FIELD_VALUE (v2, "static_field_count",
		    build_int_cst (NULL_TREE, static_field_count));

  PUSH_FIELD_VALUE (v2, "vtable",
                    (flag_indirect_dispatch || dtable_decl == NULL_TREE
                     ? null_pointer_node
                     : build2 (POINTER_PLUS_EXPR, dtable_ptr_type,
				build1 (ADDR_EXPR, dtable_ptr_type,
					dtable_decl),
                               dtable_start_offset)));
  add_table_and_syms (&v2, TYPE_OTABLE_METHODS (type),
                      "otable", TYPE_OTABLE_DECL (type), otable_ptr_type,
                      "otable_syms", TYPE_OTABLE_SYMS_DECL (type));
  add_table_and_syms (&v2, TYPE_ATABLE_METHODS (type),
                      "atable", TYPE_ATABLE_DECL (type), atable_ptr_type,
                      "atable_syms", TYPE_ATABLE_SYMS_DECL (type));
  add_table_and_syms (&v2, TYPE_ITABLE_METHODS (type),
                      "itable", TYPE_ITABLE_DECL (type), itable_ptr_type,
                      "itable_syms", TYPE_ITABLE_SYMS_DECL (type));
 
  PUSH_FIELD_VALUE (v2, "catch_classes",
		    build1 (ADDR_EXPR, ptr_type_node, TYPE_CTABLE_DECL (type))); 
  PUSH_FIELD_VALUE (v2, "interfaces", interfaces);
  PUSH_FIELD_VALUE (v2, "loader", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "interface_count",
		    build_int_cst (NULL_TREE, interface_len));
  PUSH_FIELD_VALUE (v2, "state",
		    convert (byte_type_node,
			     build_int_cst (NULL_TREE, JV_STATE_PRELOADING)));

  PUSH_FIELD_VALUE (v2, "thread", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "depth", integer_zero_node);
  PUSH_FIELD_VALUE (v2, "ancestors", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "idt", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "arrayclass", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "protectionDomain", null_pointer_node);

  {
    tree assertion_table_ref;
    if (TYPE_ASSERTIONS (type) == NULL)
      assertion_table_ref = null_pointer_node;
    else
      assertion_table_ref = build1 (ADDR_EXPR, 
				    build_pointer_type (assertion_table_type),
				    emit_assertion_table (type));
    
    PUSH_FIELD_VALUE (v2, "assertion_table", assertion_table_ref);
  }

  PUSH_FIELD_VALUE (v2, "hack_signers", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "chain", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "aux_info", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "engine", null_pointer_node);

  if (TYPE_REFLECTION_DATA (current_class))
    {
      int i;
      int count = TYPE_REFLECTION_DATASIZE (current_class);
      VEC (constructor_elt, gc) *v
	= VEC_alloc (constructor_elt, gc, count);
      unsigned char *data = TYPE_REFLECTION_DATA (current_class);
      tree max_index = build_int_cst (sizetype, count);
      tree index = build_index_type (max_index);
      tree type = build_array_type (unsigned_byte_type_node, index);
      char buf[64];
      tree array;
      static int reflection_data_count;

      sprintf (buf, "_reflection_data_%d", reflection_data_count++);
      array = build_decl (input_location,
			  VAR_DECL, get_identifier (buf), type);

      rewrite_reflection_indexes (field_indexes);

      for (i = 0; i < count; i++)
	{
	  constructor_elt *elt = VEC_quick_push (constructor_elt, v, NULL);
 	  elt->index = build_int_cst (sizetype, i);
	  elt->value = build_int_cstu (byte_type_node, data[i]);
	}

      DECL_INITIAL (array) = build_constructor (type, v);
      TREE_STATIC (array) = 1;
      DECL_ARTIFICIAL (array) = 1;
      DECL_IGNORED_P (array) = 1;
      TREE_READONLY (array) = 1;
      TREE_CONSTANT (DECL_INITIAL (array)) = 1;
      rest_of_decl_compilation (array, 1, 0);

      reflection_data = build_address_of (array);

      free (data);
      TYPE_REFLECTION_DATA (current_class) = NULL;
    }
  else
    reflection_data = null_pointer_node;

  PUSH_FIELD_VALUE (v2, "reflection_data", reflection_data);
  FINISH_RECORD_CONSTRUCTOR (cons, v2, class_type_node);

  DECL_INITIAL (decl) = cons;
  
  /* Hash synchronization requires at least 64-bit alignment. */
  if (flag_hash_synchronization && POINTER_SIZE < 64)
    DECL_ALIGN (decl) = 64; 
  
  if (flag_indirect_classes)
    {
      TREE_READONLY (decl) = 1;
      TREE_CONSTANT (DECL_INITIAL (decl)) = 1;
    }

  rest_of_decl_compilation (decl, 1, 0);
  
  {
    tree classdollar_field = build_classdollar_field (type);
    if (!flag_indirect_classes)
      DECL_INITIAL (classdollar_field) = build_static_class_ref (type);
    rest_of_decl_compilation (classdollar_field, 1, 0);
  }

  TYPE_OTABLE_DECL (type) = NULL_TREE;
  TYPE_ATABLE_DECL (type) = NULL_TREE;
  TYPE_CTABLE_DECL (type) = NULL_TREE;
}

void
finish_class (void)
{
  java_expand_catch_classes (current_class);

  current_function_decl = NULL_TREE;
  TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (current_class)) = 0;
  make_class_data (current_class);
  register_class ();
  rest_of_decl_compilation (TYPE_NAME (current_class), 1, 0);
}

/* Return 2 if KLASS is compiled by this compilation job;
   return 1 if KLASS can otherwise be assumed to be compiled;
   return 0 if we cannot assume that KLASS is compiled.
   Returns 1 for primitive and 0 for array types.  */
int
is_compiled_class (tree klass)
{
  int seen_in_zip;
  if (TREE_CODE (klass) == POINTER_TYPE)
    klass = TREE_TYPE (klass);
  if (TREE_CODE (klass) != RECORD_TYPE)  /* Primitive types are static. */
    return 1;
  if (TYPE_ARRAY_P (klass))
    return 0;

  seen_in_zip = (TYPE_JCF (klass) && JCF_SEEN_IN_ZIP (TYPE_JCF (klass)));
  if (CLASS_FROM_CURRENTLY_COMPILED_P (klass))
    {
      /* The class was seen in the current ZIP file and will be
	 available as a compiled class in the future but may not have
	 been loaded already. Load it if necessary. This prevent
	 build_class_ref () from crashing. */

      if (seen_in_zip && !CLASS_LOADED_P (klass) && (klass != current_class))
        load_class (klass, 1);

      /* We return 2 for class seen in ZIP and class from files
         belonging to the same compilation unit */
      return 2;
    }

  if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (klass)))))
    {
      if (!CLASS_LOADED_P (klass))
	{
	  if (klass != current_class)
	    load_class (klass, 1);
	}
      return 1;
    }

  return 0;
}

/* Build a VAR_DECL for the dispatch table (vtable) for class TYPE. */

tree
build_dtable_decl (tree type)
{
  tree dtype, decl;

  /* We need to build a new dtable type so that its size is uniquely
     computed when we're dealing with the class for real and not just
     faking it (like java.lang.Class during the initialization of the
     compiler.) We know we're not faking a class when CURRENT_CLASS is
     TYPE. */
  if (current_class == type)
    {
      tree dummy = NULL_TREE;
      int n;

      dtype = make_node (RECORD_TYPE);

      PUSH_FIELD (input_location, dtype, dummy, "top_offset", ptr_type_node);
      PUSH_FIELD (input_location, dtype, dummy, "type_info", ptr_type_node);

      PUSH_FIELD (input_location, dtype, dummy, "class", class_ptr_type);
      for (n = 1; n < TARGET_VTABLE_USES_DESCRIPTORS; ++n)
	{
	  tree tmp_field = build_decl (input_location,
				       FIELD_DECL, NULL_TREE, ptr_type_node);
	  TREE_CHAIN (dummy) = tmp_field;
	  DECL_CONTEXT (tmp_field) = dtype;
	  DECL_ARTIFICIAL (tmp_field) = 1;
	  dummy = tmp_field;
	}

      PUSH_FIELD (input_location, dtype, dummy, "gc_descr", ptr_type_node);
      for (n = 1; n < TARGET_VTABLE_USES_DESCRIPTORS; ++n)
	{
	  tree tmp_field = build_decl (input_location,
				       FIELD_DECL, NULL_TREE, ptr_type_node);
	  TREE_CHAIN (dummy) = tmp_field;
	  DECL_CONTEXT (tmp_field) = dtype;
	  DECL_ARTIFICIAL (tmp_field) = 1;
	  dummy = tmp_field;
	}

      n = TREE_VEC_LENGTH (get_dispatch_vector (type));
      if (TARGET_VTABLE_USES_DESCRIPTORS)
	n *= TARGET_VTABLE_USES_DESCRIPTORS;

      PUSH_FIELD (input_location, dtype, dummy, "methods",
		  build_prim_array_type (nativecode_ptr_type_node, n));
      layout_type (dtype);
    }
  else
    dtype = dtable_type;

  decl = build_decl (input_location,
		     VAR_DECL, get_identifier ("vt$"), dtype);
  DECL_CONTEXT (decl) = type;
  MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
  DECL_VTABLE_P (decl) = 1;

  return decl;
}

/* Pre-pend the TYPE_FIELDS of THIS_CLASS with a dummy FIELD_DECL for the
   fields inherited from SUPER_CLASS. */

void
push_super_field (tree this_class, tree super_class)
{
  tree base_decl;
  /* Don't insert the field if we're just re-laying the class out. */ 
  if (TYPE_FIELDS (this_class) && !DECL_NAME (TYPE_FIELDS (this_class)))
    return;
  base_decl = build_decl (input_location,
			  FIELD_DECL, NULL_TREE, super_class);
  DECL_IGNORED_P (base_decl) = 1;
  DECL_CHAIN (base_decl) = TYPE_FIELDS (this_class);
  TYPE_FIELDS (this_class) = base_decl;
  DECL_SIZE (base_decl) = TYPE_SIZE (super_class);
  DECL_SIZE_UNIT (base_decl) = TYPE_SIZE_UNIT (super_class);
}

/* Handle the different manners we may have to lay out a super class.  */

static tree
maybe_layout_super_class (tree super_class, tree this_class ATTRIBUTE_UNUSED)
{
  if (!super_class)
    return NULL_TREE;
  else if (TREE_CODE (super_class) == RECORD_TYPE)
    {
      if (!CLASS_LOADED_P (super_class))
	load_class (super_class, 1);
    }
  /* We might have to layout the class before its dependency on
     the super class gets resolved by java_complete_class  */
  else if (TREE_CODE (super_class) == POINTER_TYPE)
    {
      if (TREE_TYPE (super_class) != NULL_TREE)
	super_class = TREE_TYPE (super_class);
      else
	gcc_unreachable ();
    }
  if (!TYPE_SIZE (super_class))
    safe_layout_class (super_class);

  return super_class;
}

/* safe_layout_class just makes sure that we can load a class without
   disrupting the current_class, input_file, input_line, etc, information
   about the class processed currently.  */

void
safe_layout_class (tree klass)
{
  tree save_current_class = current_class;
  location_t save_location = input_location;

  layout_class (klass);

  current_class = save_current_class;
  input_location = save_location;
}

void
layout_class (tree this_class)
{
  int i;
  tree super_class = CLASSTYPE_SUPER (this_class);

  class_list = tree_cons (this_class, NULL_TREE, class_list);
  if (CLASS_BEING_LAIDOUT (this_class))
    {
      char buffer [1024];
      char *report;
      tree current;

      sprintf (buffer, " with '%s'",
	       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))));
      obstack_grow (&temporary_obstack, buffer, strlen (buffer));

      for (current = TREE_CHAIN (class_list); current; 
	   current = TREE_CHAIN (current))
	{
	  tree decl = TYPE_NAME (TREE_PURPOSE (current));
	  sprintf (buffer, "\n  which inherits from '%s' (%s:%d)",
		   IDENTIFIER_POINTER (DECL_NAME (decl)),
		   DECL_SOURCE_FILE (decl),
		   DECL_SOURCE_LINE (decl));
	  obstack_grow (&temporary_obstack, buffer, strlen (buffer));
	}
      obstack_1grow (&temporary_obstack, '\0');
      report = XOBFINISH (&temporary_obstack, char *);
      cyclic_inheritance_report = ggc_strdup (report);
      obstack_free (&temporary_obstack, report);
      TYPE_SIZE (this_class) = error_mark_node;
      return;
    }
  CLASS_BEING_LAIDOUT (this_class) = 1;

  if (super_class && !CLASS_BEING_LAIDOUT (super_class))
    {
      tree maybe_super_class 
	= maybe_layout_super_class (super_class, this_class);
      if (maybe_super_class == NULL
	  || TREE_CODE (TYPE_SIZE (maybe_super_class)) == ERROR_MARK)
	{
	  TYPE_SIZE (this_class) = error_mark_node;
	  CLASS_BEING_LAIDOUT (this_class) = 0;
	  class_list = TREE_CHAIN (class_list);
	  return;
	}
      if (TYPE_SIZE (this_class) == NULL_TREE)
	push_super_field (this_class, maybe_super_class);
    }

  layout_type (this_class);

  /* Also recursively load/layout any superinterfaces.  */
  if (TYPE_BINFO (this_class))
    {
      for (i = BINFO_N_BASE_BINFOS (TYPE_BINFO (this_class)) - 1; i > 0; i--)
	{
	  tree binfo = BINFO_BASE_BINFO (TYPE_BINFO (this_class), i);
	  tree super_interface = BINFO_TYPE (binfo);
	  tree maybe_super_interface 
	    = maybe_layout_super_class (super_interface, NULL_TREE);
	  if (maybe_super_interface == NULL
	      || TREE_CODE (TYPE_SIZE (maybe_super_interface)) == ERROR_MARK)
	    {
	      TYPE_SIZE (this_class) = error_mark_node;
	      CLASS_BEING_LAIDOUT (this_class) = 0;
	      class_list = TREE_CHAIN (class_list);
	      return;
	    }
	}
    }

  /* Convert the size back to an SI integer value.  */
  TYPE_SIZE_UNIT (this_class) =
    fold (convert (int_type_node, TYPE_SIZE_UNIT (this_class)));

  CLASS_BEING_LAIDOUT (this_class) = 0;
  class_list = TREE_CHAIN (class_list);
}

static void
add_miranda_methods (tree base_class, tree search_class)
{
  int i;
  tree binfo, base_binfo;

  if (!CLASS_PARSED_P (search_class))
    load_class (search_class, 1);
  
  for (binfo = TYPE_BINFO (search_class), i = 1;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    {
      tree method_decl;
      tree elt = BINFO_TYPE (base_binfo);

      /* FIXME: This is totally bogus.  We should not be handling
	 Miranda methods at all if we're using the BC ABI.  */
      if (TYPE_DUMMY (elt))
	continue;

      /* Ensure that interface methods are seen in declared order.  */
      if (!CLASS_LOADED_P (elt))
	load_class (elt, 1);
      layout_class_methods (elt);

      /* All base classes will have been laid out at this point, so the order 
         will be correct.  This code must match similar layout code in the 
         runtime.  */
      for (method_decl = TYPE_METHODS (elt);
	   method_decl; method_decl = DECL_CHAIN (method_decl))
	{
	  tree sig, override;

	  /* An interface can have <clinit>.  */
	  if (ID_CLINIT_P (DECL_NAME (method_decl)))
	    continue;

	  sig = build_java_argument_signature (TREE_TYPE (method_decl));
	  override = lookup_argument_method (base_class,
					     DECL_NAME (method_decl), sig);
	  if (override == NULL_TREE)
	    {
	      /* Found a Miranda method.  Add it.  */
	      tree new_method;
	      sig = build_java_signature (TREE_TYPE (method_decl));
	      new_method
		= add_method (base_class,
			      get_access_flags_from_decl (method_decl),
			      DECL_NAME (method_decl), sig);
	      METHOD_INVISIBLE (new_method) = 1;
	    }
	}

      /* Try superinterfaces.  */
      add_miranda_methods (base_class, elt);
    }
}

void
layout_class_methods (tree this_class)
{
  tree method_decl, dtable_count;
  tree super_class, type_name;

  if (TYPE_NVIRTUALS (this_class))
    return;
  
  super_class = CLASSTYPE_SUPER (this_class);

  if (super_class)
    {
      super_class = maybe_layout_super_class (super_class, this_class);
      if (!TYPE_NVIRTUALS (super_class))
	layout_class_methods (super_class);
      dtable_count = TYPE_NVIRTUALS (super_class);
    }
  else
    dtable_count = integer_zero_node;

  type_name = TYPE_NAME (this_class);
  if (!flag_indirect_dispatch
      && (CLASS_ABSTRACT (type_name) || CLASS_INTERFACE (type_name)))
    {
      /* An abstract class can have methods which are declared only in
	 an implemented interface.  These are called "Miranda
	 methods".  We make a dummy method entry for such methods
	 here.  */
      add_miranda_methods (this_class, this_class);
    }

  TYPE_METHODS (this_class) = nreverse (TYPE_METHODS (this_class));

  for (method_decl = TYPE_METHODS (this_class);
       method_decl; method_decl = DECL_CHAIN (method_decl))
    dtable_count = layout_class_method (this_class, super_class,
					method_decl, dtable_count);

  TYPE_NVIRTUALS (this_class) = dtable_count;
}

/* Return the index of METHOD in INTERFACE.  This index begins at 1
   and is used as an argument for _Jv_LookupInterfaceMethodIdx(). */
int
get_interface_method_index (tree method, tree interface)
{
  tree meth;
  int i = 1;

  for (meth = TYPE_METHODS (interface); ; meth = DECL_CHAIN (meth))
    {
      if (meth == method)
	return i;
      /* We don't want to put <clinit> into the interface table.  */
      if (! ID_CLINIT_P (DECL_NAME (meth)))
	++i;
      gcc_assert (meth != NULL_TREE);
    }
}

/* Lay METHOD_DECL out, returning a possibly new value of
   DTABLE_COUNT. Also mangle the method's name. */

tree
layout_class_method (tree this_class, tree super_class,
		     tree method_decl, tree dtable_count)
{
  tree method_name = DECL_NAME (method_decl);

  TREE_PUBLIC (method_decl) = 1;

  if (flag_indirect_classes
      || (METHOD_PRIVATE (method_decl) && METHOD_STATIC (method_decl)
	  && ! METHOD_NATIVE (method_decl)
	  && ! special_method_p (method_decl)))
    java_hide_decl (method_decl);

  /* Considered external unless it is being compiled into this object
     file, or it was already flagged as external.  */
  if (!DECL_EXTERNAL (method_decl))
    DECL_EXTERNAL (method_decl) = ((is_compiled_class (this_class) != 2)
                                   || METHOD_NATIVE (method_decl));

  if (ID_INIT_P (method_name))
    {
      const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
      const char *ptr;
      for (ptr = p; *ptr; )
	{
	  if (*ptr++ == '.')
	    p = ptr;
	}
      DECL_CONSTRUCTOR_P (method_decl) = 1;
      build_java_signature (TREE_TYPE (method_decl));
    }
  else if (! METHOD_STATIC (method_decl))
    {
      tree method_sig =
	build_java_signature (TREE_TYPE (method_decl));
      bool method_override = false;
      tree super_method = lookup_java_method (super_class, method_name,
						  method_sig);
      if (super_method != NULL_TREE
	  && ! METHOD_DUMMY (super_method))
        {
	  method_override = true;
	  if (! METHOD_PUBLIC (super_method) && 
	      ! METHOD_PROTECTED (super_method))
	    {
	      /* Don't override private method, or default-access method in 
		 another package.  */
	      if (METHOD_PRIVATE (super_method) ||
		  ! in_same_package (TYPE_NAME (this_class), 
				     TYPE_NAME (super_class)))
		method_override = false;
	   }
	}
      if (method_override)
	{
	  tree method_index = get_method_index (super_method);
	  set_method_index (method_decl, method_index);
	  if (method_index == NULL_TREE 
	      && ! flag_indirect_dispatch
	      && ! DECL_ARTIFICIAL (super_method))
	    error ("non-static method %q+D overrides static method",
                   method_decl);
	}
      else if (this_class == object_type_node
	       && (METHOD_FINAL (method_decl)
		   || METHOD_PRIVATE (method_decl)))
	{
	  /* We don't generate vtable entries for final Object
	     methods.  This is simply to save space, since every
	     object would otherwise have to define them.  */
	}
      else if (! METHOD_PRIVATE (method_decl)
	       && dtable_count)
	{
	  /* We generate vtable entries for final methods because they
	     may one day be changed to non-final.  */
	  set_method_index (method_decl, dtable_count);
	  dtable_count = fold_build2 (PLUS_EXPR, integer_type_node,
				      dtable_count, integer_one_node);
	}
    }

  return dtable_count;
}

static void
register_class (void)
{
  tree node;

  if (!registered_class)
    registered_class = VEC_alloc (tree, gc, 8);

  if (flag_indirect_classes)
    node = current_class;
  else
    node = TREE_OPERAND (build_class_ref (current_class), 0);
  VEC_safe_push (tree, gc, registered_class, node);
}

/* Emit a function that calls _Jv_RegisterNewClasses with a list of
   all the classes we have emitted.  */

static void
emit_indirect_register_classes (tree *list_p)
{
  tree klass, t, register_class_fn;
  int i;

  int size = VEC_length (tree, registered_class) * 2 + 1;
  VEC(constructor_elt,gc) *init = VEC_alloc (constructor_elt, gc, size);
  tree class_array_type
    = build_prim_array_type (ptr_type_node, size);
  tree cdecl = build_decl (input_location,
			   VAR_DECL, get_identifier ("_Jv_CLS"),
			   class_array_type);
  tree reg_class_list;
  FOR_EACH_VEC_ELT (tree, registered_class, i, klass)
    {
      t = fold_convert (ptr_type_node, build_static_class_ref (klass));
      CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, t);
      t = fold_convert (ptr_type_node,
                        build_address_of (build_classdollar_field (klass)));
      CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, t);
    }
  CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, integer_zero_node);
  DECL_INITIAL (cdecl) = build_constructor (class_array_type, init);
  TREE_CONSTANT (DECL_INITIAL (cdecl)) = 1;
  TREE_STATIC (cdecl) = 1;
  DECL_ARTIFICIAL (cdecl) = 1;
  DECL_IGNORED_P (cdecl) = 1;
  TREE_READONLY (cdecl) = 1;
  TREE_CONSTANT (cdecl) = 1;
  rest_of_decl_compilation (cdecl, 1, 0);
  reg_class_list = fold_convert (ptr_type_node, build_address_of (cdecl));

  t = build_function_type_list (void_type_node, 
				build_pointer_type (ptr_type_node), NULL);
  t = build_decl (input_location,
		  FUNCTION_DECL, 
		  get_identifier ("_Jv_RegisterNewClasses"), t);
  TREE_PUBLIC (t) = 1;
  DECL_EXTERNAL (t) = 1;
  register_class_fn = t;
  t = build_call_expr (register_class_fn, 1, reg_class_list);
  append_to_statement_list (t, list_p);
}


/* Emit something to register classes at start-up time.

   The preferred mechanism is through the .jcr section, which contain
   a list of pointers to classes which get registered during constructor
   invocation time.

   The fallback mechanism is to add statements to *LIST_P to call
   _Jv_RegisterClass for each class in this file.  These statements will
   be added to a static constructor function for this translation unit.  */

void
emit_register_classes (tree *list_p)
{
  if (registered_class == NULL)
    return;

  if (flag_indirect_classes)
    {
      emit_indirect_register_classes (list_p);
      return;
    }

  /* TARGET_USE_JCR_SECTION defaults to 1 if SUPPORTS_WEAK and
     TARGET_ASM_NAMED_SECTION, else 0.  Some targets meet those conditions
     but lack suitable crtbegin/end objects or linker support.  These
     targets can override the default in tm.h to use the fallback mechanism.  */
  if (TARGET_USE_JCR_SECTION)
    {
      tree klass, t;
      int i;

#ifdef JCR_SECTION_NAME
      switch_to_section (get_section (JCR_SECTION_NAME, SECTION_WRITE, NULL));
#else
      /* A target has defined TARGET_USE_JCR_SECTION,
	 but doesn't have a JCR_SECTION_NAME.  */
      gcc_unreachable ();
#endif
      assemble_align (POINTER_SIZE);

      FOR_EACH_VEC_ELT (tree, registered_class, i, klass)
	{
	  t = build_fold_addr_expr (klass);
	  output_constant (t, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE);
	}
    }
  else
    {
      tree klass, t, register_class_fn;
      int i;

      t = build_function_type_list (void_type_node, class_ptr_type, NULL);
      t = build_decl (input_location,
		      FUNCTION_DECL, get_identifier ("_Jv_RegisterClass"), t);
      TREE_PUBLIC (t) = 1;
      DECL_EXTERNAL (t) = 1;
      register_class_fn = t;

      FOR_EACH_VEC_ELT (tree, registered_class, i, klass)
	{
	  t = build_fold_addr_expr (klass);
	  t = build_call_expr (register_class_fn, 1, t);
	  append_to_statement_list (t, list_p);
	}
    }
}

/* Build a constructor for an entry in the symbol table.  */

static tree
build_symbol_table_entry (tree clname, tree name, tree signature)
{
  tree symbol;
  VEC(constructor_elt,gc) *v = NULL;

  START_RECORD_CONSTRUCTOR (v, symbol_type);
  PUSH_FIELD_VALUE (v, "clname", clname);
  PUSH_FIELD_VALUE (v, "name", name);
  PUSH_FIELD_VALUE (v, "signature", signature);
  FINISH_RECORD_CONSTRUCTOR (symbol, v, symbol_type);
  TREE_CONSTANT (symbol) = 1;

  return symbol;
}

/* Make a symbol_type (_Jv_MethodSymbol) node for DECL. */

static tree
build_symbol_entry (tree decl, tree special)
{
  tree clname, name, signature;
  clname = build_utf8_ref (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))));
  /* ???  Constructors are given the name foo.foo all the way through
     the compiler, but in the method table they're all renamed
     foo.<init>.  So, we have to do the same here unless we want an
     unresolved reference at runtime.  */
  name = build_utf8_ref ((TREE_CODE (decl) == FUNCTION_DECL 
			  && DECL_CONSTRUCTOR_P (decl))
			 ? init_identifier_node
			 : DECL_NAME (decl));
  signature = build_java_signature (TREE_TYPE (decl));
  signature = build_utf8_ref (unmangle_classname 
			      (IDENTIFIER_POINTER (signature),
			       IDENTIFIER_LENGTH (signature)));
  /* SPECIAL is either NULL_TREE or integer_one_node.  We emit
     signature addr+1 if SPECIAL, and this indicates to the runtime
     system that this is a "special" symbol, i.e. one that should
     bypass access controls.  */
  if (special != NULL_TREE)
    signature = build2 (POINTER_PLUS_EXPR, TREE_TYPE (signature), signature,
			fold_convert (sizetype, special));

  return build_symbol_table_entry (clname, name, signature);
} 

/* Emit a symbol table: used by -findirect-dispatch.  */

tree
emit_symbol_table (tree name, tree the_table,
		   VEC(method_entry,gc) *decl_table,
                   tree the_syms_decl, tree the_array_element_type,
		   int element_size)
{
  tree table, null_symbol, table_size, the_array_type;
  unsigned index;
  method_entry *e;
  VEC(constructor_elt,gc) *v = NULL;
  
  /* Only emit a table if this translation unit actually made any
     references via it. */
  if (decl_table == NULL)
    return the_table;

  /* Build a list of _Jv_MethodSymbols for each entry in otable_methods. */
  FOR_EACH_VEC_ELT (method_entry, decl_table, index, e)
    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			    build_symbol_entry (e->method, e->special));

  /* Terminate the list with a "null" entry. */
  null_symbol = build_symbol_table_entry (null_pointer_node,
                                          null_pointer_node,
                                          null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, null_symbol);

  table = build_constructor (symbols_array_type, v);

  /* Make it the initial value for otable_syms and emit the decl. */
  DECL_INITIAL (the_syms_decl) = table;
  DECL_ARTIFICIAL (the_syms_decl) = 1;
  DECL_IGNORED_P (the_syms_decl) = 1;
  rest_of_decl_compilation (the_syms_decl, 1, 0);
  
  /* Now that its size is known, redefine the table as an
     uninitialized static array of INDEX + 1 elements. The extra entry
     is used by the runtime to track whether the table has been
     initialized. */
  table_size 
    = build_index_type (build_int_cst (NULL_TREE, index * element_size + 1));
  the_array_type = build_array_type (the_array_element_type, table_size);
  the_table = build_decl (input_location,
			  VAR_DECL, name, the_array_type);
  TREE_STATIC (the_table) = 1;
  TREE_READONLY (the_table) = 1;  
  rest_of_decl_compilation (the_table, 1, 0);

  return the_table;
}

/* Make an entry for the catch_classes list.  */
tree
make_catch_class_record (tree catch_class, tree classname)
{
  tree entry;
  tree type = TREE_TYPE (TREE_TYPE (TYPE_CTABLE_DECL (output_class)));
  VEC(constructor_elt,gc) *v = NULL;
  START_RECORD_CONSTRUCTOR (v, type);
  PUSH_FIELD_VALUE (v, "address", catch_class);
  PUSH_FIELD_VALUE (v, "classname", classname);
  FINISH_RECORD_CONSTRUCTOR (entry, v, type);
  return entry;
}


/* Generate the list of Throwable classes that are caught by exception
   handlers in this class.  */
tree 
emit_catch_table (tree this_class)
{
  tree table, table_size, array_type;
  int n_catch_classes;
  constructor_elt *e;
  /* Fill in the dummy entry that make_class created.  */
  e = VEC_index (constructor_elt, TYPE_CATCH_CLASSES (this_class), 0);
  e->value = make_catch_class_record (null_pointer_node, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (TYPE_CATCH_CLASSES (this_class), NULL_TREE,
			  make_catch_class_record (null_pointer_node,
						   null_pointer_node));
  n_catch_classes = VEC_length (constructor_elt,
				TYPE_CATCH_CLASSES (this_class));
  table_size = build_index_type (build_int_cst (NULL_TREE, n_catch_classes));
  array_type 
    = build_array_type (TREE_TYPE (TREE_TYPE (TYPE_CTABLE_DECL (this_class))),
			table_size);
  table = 
    build_decl (input_location,
		VAR_DECL, DECL_NAME (TYPE_CTABLE_DECL (this_class)), array_type);
  DECL_INITIAL (table) = 
    build_constructor (array_type, TYPE_CATCH_CLASSES (this_class));
  TREE_STATIC (table) = 1;
  TREE_READONLY (table) = 1;  
  DECL_IGNORED_P (table) = 1;
  rest_of_decl_compilation (table, 1, 0);
  return table;
}

/* Given a type, return the signature used by
   _Jv_FindClassFromSignature() in libgcj.  This isn't exactly the
   same as build_java_signature() because we want the canonical array
   type.  */

static tree
build_signature_for_libgcj (tree type)
{
  tree sig, ref;

  sig = build_java_signature (type);
  ref = build_utf8_ref (unmangle_classname (IDENTIFIER_POINTER (sig),
					    IDENTIFIER_LENGTH (sig)));
  return ref;
}

/* Build an entry in the type assertion table.  */

static tree
build_assertion_table_entry (tree code, tree op1, tree op2)
{
  VEC(constructor_elt,gc) *v = NULL;
  tree entry;

  START_RECORD_CONSTRUCTOR (v, assertion_entry_type);
  PUSH_FIELD_VALUE (v, "assertion_code", code);
  PUSH_FIELD_VALUE (v, "op1", op1);
  PUSH_FIELD_VALUE (v, "op2", op2);
  FINISH_RECORD_CONSTRUCTOR (entry, v, assertion_entry_type);

  return entry;
}

/* Add an entry to the type assertion table. Callback used during hashtable
   traversal.  */

static int
add_assertion_table_entry (void **htab_entry, void *ptr)
{
  tree entry;
  tree code_val, op1_utf8, op2_utf8;
  VEC(constructor_elt,gc) **v = (VEC(constructor_elt,gc) **) ptr;
  type_assertion *as = (type_assertion *) *htab_entry;

  code_val = build_int_cst (NULL_TREE, as->assertion_code);

  if (as->op1 == NULL_TREE)
    op1_utf8 = null_pointer_node;
  else
    op1_utf8 = build_signature_for_libgcj (as->op1);

  if (as->op2 == NULL_TREE)
    op2_utf8 = null_pointer_node;
  else
    op2_utf8 = build_signature_for_libgcj (as->op2);

  entry = build_assertion_table_entry (code_val, op1_utf8, op2_utf8);
  
  CONSTRUCTOR_APPEND_ELT (*v, NULL_TREE, entry);
  return true;
}

/* Generate the type assertion table for KLASS, and return its DECL.  */

static tree
emit_assertion_table (tree klass)
{
  tree null_entry, ctor, table_decl;
  htab_t assertions_htab = TYPE_ASSERTIONS (klass);
  VEC(constructor_elt,gc) *v = NULL;

  /* Iterate through the hash table.  */
  htab_traverse (assertions_htab, add_assertion_table_entry, &v);

  /* Finish with a null entry.  */
  null_entry = build_assertion_table_entry (integer_zero_node,
                                            null_pointer_node,
                                            null_pointer_node);
  
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, null_entry);
  
  ctor = build_constructor (assertion_table_type, v);

  table_decl = build_decl (input_location,
			   VAR_DECL, mangled_classname ("_type_assert_", klass),
			   assertion_table_type);

  TREE_STATIC (table_decl) = 1;
  TREE_READONLY (table_decl) = 1;
  TREE_CONSTANT (table_decl) = 1;
  DECL_IGNORED_P (table_decl) = 1;

  DECL_INITIAL (table_decl) = ctor;
  DECL_ARTIFICIAL (table_decl) = 1;
  rest_of_decl_compilation (table_decl, 1, 0);

  return table_decl;
}

void
init_class_processing (void)
{
  fields_ident = get_identifier ("fields");
  info_ident = get_identifier ("info");

  gcc_obstack_init (&temporary_obstack);
}

static hashval_t java_treetreehash_hash (const void *);
static int java_treetreehash_compare (const void *, const void *);

/* A hash table mapping trees to trees.  Used generally.  */

#define JAVA_TREEHASHHASH_H(t) ((hashval_t)TYPE_UID (t))

static hashval_t
java_treetreehash_hash (const void *k_p)
{
  const struct treetreehash_entry *const k
    = (const struct treetreehash_entry *) k_p;
  return JAVA_TREEHASHHASH_H (k->key);
}

static int
java_treetreehash_compare (const void * k1_p, const void * k2_p)
{
  const struct treetreehash_entry *const k1
    = (const struct treetreehash_entry *) k1_p;
  const_tree const k2 = (const_tree) k2_p;
  return (k1->key == k2);
}

tree 
java_treetreehash_find (htab_t ht, tree t)
{
  struct treetreehash_entry *e;
  hashval_t hv = JAVA_TREEHASHHASH_H (t);
  e = (struct treetreehash_entry *) htab_find_with_hash (ht, t, hv);
  if (e == NULL)
    return NULL;
  else
    return e->value;
}

tree *
java_treetreehash_new (htab_t ht, tree t)
{
  void **e;
  struct treetreehash_entry *tthe;
  hashval_t hv = JAVA_TREEHASHHASH_H (t);

  e = htab_find_slot_with_hash (ht, t, hv, INSERT);
  if (*e == NULL)
    {
      tthe = ggc_alloc_cleared_treetreehash_entry ();
      tthe->key = t;
      *e = tthe;
    }
  else
    tthe = (struct treetreehash_entry *) *e;
  return &tthe->value;
}

htab_t
java_treetreehash_create (size_t size)
{
  return htab_create_ggc (size, java_treetreehash_hash,
			  java_treetreehash_compare, NULL);
}

/* Break down qualified IDENTIFIER into package and class-name components.
   For example, given SOURCE "pkg.foo.Bar", LEFT will be set to
   "pkg.foo", and RIGHT to "Bar". */

int
split_qualified_name (tree *left, tree *right, tree source)
{
  char *p, *base;
  int l = IDENTIFIER_LENGTH (source);

  base = (char *) alloca (l + 1);
  memcpy (base, IDENTIFIER_POINTER (source), l + 1);

  /* Breakdown NAME into REMAINDER . IDENTIFIER.  */
  p = base + l - 1;
  while (*p != '.' && p != base)
    p--;

  /* We didn't find a '.'. Return an error.  */
  if (p == base)
    return 1;

  *p = '\0';
  if (right)
    *right = get_identifier (p+1);
  *left = get_identifier (base);

  return 0;
}

/* Given two classes (TYPE_DECL) or class names (IDENTIFIER), return TRUE 
   if the classes are from the same package. */

int
in_same_package (tree name1, tree name2)
{
  tree tmp;
  tree pkg1;
  tree pkg2;

  if (TREE_CODE (name1) == TYPE_DECL)
    name1 = DECL_NAME (name1);
  if (TREE_CODE (name2) == TYPE_DECL)
    name2 = DECL_NAME (name2);

  if (QUALIFIED_P (name1) != QUALIFIED_P (name2))
    /* One in empty package. */
    return 0;

  if (QUALIFIED_P (name1) == 0 && QUALIFIED_P (name2) == 0)
    /* Both in empty package. */
    return 1;

  split_qualified_name (&pkg1, &tmp, name1);
  split_qualified_name (&pkg2, &tmp, name2);

  return (pkg1 == pkg2);
}

/* lang_hooks.decls.final_write_globals: perform final processing on
   global variables.  */

void
java_write_globals (void)
{
  tree *vec = VEC_address (tree, pending_static_fields);
  int len = VEC_length (tree, pending_static_fields);
  write_global_declarations ();
  emit_debug_global_declarations (vec, len);
  VEC_free (tree, gc, pending_static_fields);
}

#include "gt-java-class.h"
