/* GNU Runtime ABI version 8
   Copyright (C) 2011-2018 Free Software Foundation, Inc.
   Contributed by Iain Sandoe (split from objc-act.c)

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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "options.h"
#include "tree.h"
#include "stringpool.h"
#include "attribs.h"

#ifdef OBJCPLUS
#include "cp/cp-tree.h"
#else
#include "c/c-tree.h"
#include "c/c-lang.h"
#endif

#include "langhooks.h"
#include "c-family/c-objc.h"
#include "objc-act.h"

/* When building Objective-C++, we are not linking against the C front-end
   and so need to replicate the C tree-construction functions in some way.  */
#ifdef OBJCPLUS
#define OBJCP_REMAP_FUNCTIONS
#include "objcp-decl.h"
#endif  /* OBJCPLUS */

#include "toplev.h"
#include "tree-iterator.h"

#include "objc-runtime-hooks.h"
#include "objc-runtime-shared-support.h"
#include "objc-encoding.h"

/* GNU runtime private definitions.  */
#define DEF_CONSTANT_STRING_CLASS_NAME "NXConstantString"

#define TAG_GETCLASS		"objc_get_class"
#define TAG_GETMETACLASS	"objc_get_meta_class"

#define TAG_MSGSEND		"objc_msg_lookup"
#define TAG_MSGSENDSUPER	"objc_msg_lookup_super"

/* GNU-specific tags.  */

#define TAG_EXECCLASS		"__objc_exec_class"
#define TAG_GNUINIT		"__objc_gnu_init"

/* The version identifies which language generation and runtime
   the module (file) was compiled for, and is recorded in the
   module descriptor.  */
#define OBJC_VERSION		8

#define PROTOCOL_VERSION	2

/* This macro provides a method of removing ambiguity between runtimes
   when LTO is in use on targets supporting multiple runtimes.

   For example, at present, any target that includes an implementation of
   the NeXT runtime needs to place Objective-C meta-data into specific
   named sections.  This should _not_ be done for the GNU runtime, and the
   following macro is used to attach Objective-C private attributes that may
   be used to identify the runtime for which the meta-data are intended.  */

#define OBJCMETA(DECL,VERS,KIND)					\
  if (VERS)								\
    DECL_ATTRIBUTES (DECL) = build_tree_list ((VERS), (KIND));

static void gnu_runtime_01_initialize (void);

static void build_selector_template (void);

static tree gnu_runtime_abi_01_super_superclassfield_id (void);

static tree gnu_runtime_abi_01_class_decl (tree);
static tree gnu_runtime_abi_01_metaclass_decl (tree);
static tree gnu_runtime_abi_01_category_decl (tree);
static tree gnu_runtime_abi_01_protocol_decl (tree);
static tree gnu_runtime_abi_01_string_decl (tree, const char *, string_section);

static tree gnu_runtime_abi_01_get_class_reference (tree);
static tree gnu_runtime_abi_01_build_typed_selector_reference (location_t, tree,
								tree);
static tree gnu_runtime_abi_01_get_protocol_reference (location_t, tree);
static tree gnu_runtime_abi_01_build_ivar_ref (location_t, tree, tree);
static tree gnu_runtime_abi_01_get_class_super_ref (location_t, struct imp_entry *, bool);
static tree gnu_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);

static tree gnu_runtime_abi_01_receiver_is_class_object (tree);
static void gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **,
						       tree, int, int);
static tree gnu_runtime_abi_01_build_objc_method_call (location_t, tree, tree,
							tree, tree, tree, int);

static bool gnu_runtime_abi_01_setup_const_string_class_decl (void);
static tree gnu_runtime_abi_01_build_const_string_constructor (location_t, tree,int);

static void objc_generate_v1_gnu_metadata (void);

static tree objc_eh_runtime_type (tree type);
static tree objc_eh_personality (void);
static tree objc_build_exc_ptr (struct objc_try_context **);
static tree build_throw_stmt (location_t, tree, bool);
static tree begin_catch (struct objc_try_context **, tree, tree, tree, bool);
static void finish_catch (struct objc_try_context **, tree);
static tree finish_try_stmt (struct objc_try_context **);

bool
objc_gnu_runtime_abi_01_init (objc_runtime_hooks *rthooks)
{
  /* GNU runtime does not need the compiler to change code in order to do GC. */
  if (flag_objc_gc)
    {
      warning_at (UNKNOWN_LOCATION, 0,
		  "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
      flag_objc_gc = 0;
    }

  /* Although I guess we could, we don't currently support SJLJ exceptions for the
     GNU runtime.  */
  if (flag_objc_sjlj_exceptions)
    {
      inform (UNKNOWN_LOCATION, "%<-fobjc-sjlj-exceptions%> is ignored for %<-fgnu-runtime%>");
      flag_objc_sjlj_exceptions = 0;
    }

  /* TODO: Complain if -fobjc-abi-version=N was used.  */

  /* TODO: Complain if -fobj-nilcheck was used.  */

  rthooks->initialize = gnu_runtime_01_initialize;
  rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME;
  rthooks->tag_getclass = TAG_GETCLASS;
  rthooks->super_superclassfield_ident = gnu_runtime_abi_01_super_superclassfield_id;

  rthooks->class_decl = gnu_runtime_abi_01_class_decl;
  rthooks->metaclass_decl = gnu_runtime_abi_01_metaclass_decl;
  rthooks->category_decl = gnu_runtime_abi_01_category_decl;
  rthooks->protocol_decl = gnu_runtime_abi_01_protocol_decl;
  rthooks->string_decl = gnu_runtime_abi_01_string_decl;

  rthooks->get_class_reference = gnu_runtime_abi_01_get_class_reference;
  rthooks->build_selector_reference = gnu_runtime_abi_01_build_typed_selector_reference;
  rthooks->get_protocol_reference = gnu_runtime_abi_01_get_protocol_reference;
  rthooks->build_ivar_reference = gnu_runtime_abi_01_build_ivar_ref;
  rthooks->get_class_super_ref = gnu_runtime_abi_01_get_class_super_ref;
  rthooks->get_category_super_ref = gnu_runtime_abi_01_get_category_super_ref;

  rthooks->receiver_is_class_object = gnu_runtime_abi_01_receiver_is_class_object;
  rthooks->get_arg_type_list_base = gnu_runtime_abi_01_get_arg_type_list_base;
  rthooks->build_objc_method_call = gnu_runtime_abi_01_build_objc_method_call;

  rthooks->setup_const_string_class_decl =
				gnu_runtime_abi_01_setup_const_string_class_decl;
  rthooks->build_const_string_constructor =
				gnu_runtime_abi_01_build_const_string_constructor;

  rthooks->build_throw_stmt = build_throw_stmt;
  rthooks->build_exc_ptr = objc_build_exc_ptr;
  rthooks->begin_catch = begin_catch;
  rthooks->finish_catch = finish_catch;
  rthooks->finish_try_stmt = finish_try_stmt;

  rthooks->generate_metadata = objc_generate_v1_gnu_metadata;
  return true;
}

static void build_selector_table_decl (void);
static void build_class_template (void);
static void build_category_template (void);
static void build_protocol_template (void);

static GTY(()) tree objc_meta;
static GTY(()) tree meta_base;

static void gnu_runtime_01_initialize (void)
{
  tree type, ftype, IMP_type;

  /* We do not need to mark GNU ObjC metadata for different sections,
     however, we do need to make sure that it is not mistaken for NeXT
     metadata.  */
  objc_meta = get_identifier ("OBJC1METG");
  meta_base = get_identifier ("NONE");

  /* Declare type of selector-objects that represent an operation name.  */
  /* `const struct objc_selector *' */
  type = xref_tag (RECORD_TYPE, get_identifier (TAG_SELECTOR));
  type = build_qualified_type (type, TYPE_QUAL_CONST);
  objc_selector_type = build_pointer_type (type);

  /* typedef id (*IMP)(id, SEL, ...); */
  ftype = build_varargs_function_type_list (objc_object_type,
					    objc_object_type,
					    objc_selector_type,
					    NULL_TREE);

  IMP_type = build_pointer_type (ftype);

  build_class_template ();
  build_super_template ();
  build_protocol_template ();
  build_category_template ();

  /* GNU runtime messenger entry points.  */
  /* TREE_NOTHROW is cleared for the message-sending functions,
     because the function that gets called can throw in Obj-C++, or
     could itself call something that can throw even in Obj-C.  */

  /* IMP objc_msg_lookup (id, SEL); */
  type = build_function_type_list (IMP_type,
				   objc_object_type,
				   objc_selector_type,
				   NULL_TREE);

  umsg_decl = add_builtin_function (TAG_MSGSEND,
				    type, 0, NOT_BUILT_IN,
				    NULL, NULL_TREE);
  TREE_NOTHROW (umsg_decl) = 0;

  /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
  type = build_function_type_list (IMP_type,
				   objc_super_type,
				   objc_selector_type,
				   NULL_TREE);

  umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
					  type, 0, NOT_BUILT_IN,
					  NULL, NULL_TREE);
  TREE_NOTHROW (umsg_super_decl) = 0;

  /* The following GNU runtime entry point is called to initialize
	 each module:

	 __objc_exec_class (void *); */
  type = build_function_type_list (void_type_node,
				   ptr_type_node,
				   NULL_TREE);

  execclass_decl = add_builtin_function (TAG_EXECCLASS,
					 type, 0, NOT_BUILT_IN,
					 NULL, NULL_TREE);

  type = build_function_type_list (objc_object_type,
				   const_string_type_node,
				   NULL_TREE);

  /* id objc_getClass (const char *); */
  objc_get_class_decl
    = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
			    NULL, NULL_TREE);

  /* id objc_getMetaClass (const char *); */
  objc_get_meta_class_decl = add_builtin_function (TAG_GETMETACLASS, type,
						   0, NOT_BUILT_IN, NULL,
						   NULL_TREE);

  /* static SEL _OBJC_SELECTOR_TABLE[]; */
  build_selector_table_decl ();

  /* Stuff for properties.
     The codegen relies on this being NULL for GNU.  */
  objc_copyStruct_decl = NULL_TREE;

  /* This is the type of all of the following functions
     bjc_getPropertyStruct() and objc_setPropertyStruct().  */
  type = build_function_type_list (void_type_node,
				   ptr_type_node,
				   const_ptr_type_node,
				   ptrdiff_type_node,
				   boolean_type_node,
				   boolean_type_node,
				   NULL_TREE);

  /* Declare the following function:
	 void
	 objc_getPropertyStruct (void *destination, const void *source,
                                 ptrdiff_t size, BOOL is_atomic, BOOL has_strong);  */
  objc_getPropertyStruct_decl = add_builtin_function ("objc_getPropertyStruct",
							  type, 0, NOT_BUILT_IN,
							  NULL, NULL_TREE);
  TREE_NOTHROW (objc_getPropertyStruct_decl) = 0;
  /* Declare the following function:
	 void
	 objc_setPropertyStruct (void *destination, const void *source,
	                         ptrdiff_t size, BOOL is_atomic, BOOL has_strong);  */
  objc_setPropertyStruct_decl = add_builtin_function ("objc_setPropertyStruct",
							  type, 0, NOT_BUILT_IN,
							  NULL, NULL_TREE);
  TREE_NOTHROW (objc_setPropertyStruct_decl) = 0;

  using_eh_for_cleanups ();
  lang_hooks.eh_runtime_type = objc_eh_runtime_type;
  lang_hooks.eh_personality = objc_eh_personality;
}

/* --- templates --- */
/* struct _objc_selector {
     SEL sel_id;
     char *sel_type;
   }; */

static void
build_selector_template (void)
{
  tree decls, *chain = NULL;

  objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));

  /* SEL sel_id; */
  decls = add_field_decl (objc_selector_type, "sel_id", &chain);

  /* char *sel_type; */
  add_field_decl (string_type_node, "sel_type", &chain);

  objc_finish_struct (objc_selector_template, decls);
}

/* struct _objc_class {
     struct _objc_class *isa;
     struct _objc_class *super_class;
     char *name;
     long version;
     long info;
     long instance_size;
     struct _objc_ivar_list *ivars;
     struct _objc_method_list *methods;
     struct sarray *dtable;
     struct _objc_class *subclass_list;
     struct _objc_class *sibling_class;
     struct _objc_protocol_list *protocols;
     void *gc_object_type;
   };  */

static void
build_class_template (void)
{
  tree ptype, decls, *chain = NULL;

  objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));

  /* struct _objc_class *isa; */
  decls = add_field_decl (build_pointer_type (objc_class_template),
			  "isa", &chain);

  /* struct _objc_class *super_class; */
  add_field_decl (build_pointer_type (objc_class_template),
		  "super_class", &chain);

  /* char *name; */
  add_field_decl (string_type_node, "name", &chain);

  /* long version; */
  add_field_decl (long_integer_type_node, "version", &chain);

  /* long info; */
  add_field_decl (long_integer_type_node, "info", &chain);

  /* long instance_size; */
  add_field_decl (long_integer_type_node, "instance_size", &chain);

  /* struct _objc_ivar_list *ivars; */
  add_field_decl (objc_ivar_list_ptr,"ivars", &chain);

  /* struct _objc_method_list *methods; */
  add_field_decl (objc_method_list_ptr, "methods", &chain);

  /* struct sarray *dtable; */
  ptype = build_pointer_type(xref_tag (RECORD_TYPE,
					   get_identifier ("sarray")));
  add_field_decl (ptype, "dtable", &chain);

  /* struct objc_class *subclass_list; */
  ptype = build_pointer_type (objc_class_template);
  add_field_decl (ptype, "subclass_list", &chain);

  /* struct objc_class *sibling_class; */
  ptype = build_pointer_type (objc_class_template);
  add_field_decl (ptype, "sibling_class", &chain);

  /* struct _objc_protocol **protocol_list; */
  ptype = build_pointer_type (build_pointer_type
			      (xref_tag (RECORD_TYPE,
					 get_identifier (UTAG_PROTOCOL))));
  add_field_decl (ptype, "protocol_list", &chain);

  /* void *gc_object_type; */
  add_field_decl (build_pointer_type (void_type_node),
		    "gc_object_type", &chain);

  objc_finish_struct (objc_class_template, decls);
}

/* struct _objc_category {
     char *category_name;
     char *class_name;
     struct _objc_method_list *instance_methods;
     struct _objc_method_list *class_methods;
     struct _objc_protocol_list *protocols;
   };   */

static void
build_category_template (void)
{
  tree ptype, decls, *chain = NULL;

  objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));

  /* char *category_name; */
  decls = add_field_decl (string_type_node, "category_name", &chain);

  /* char *class_name; */
  add_field_decl (string_type_node, "class_name", &chain);

  /* struct _objc_method_list *instance_methods; */
  add_field_decl (objc_method_list_ptr, "instance_methods", &chain);

  /* struct _objc_method_list *class_methods; */
  add_field_decl (objc_method_list_ptr, "class_methods", &chain);

  /* struct _objc_protocol **protocol_list; */
  ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
  add_field_decl (ptype, "protocol_list", &chain);

  objc_finish_struct (objc_category_template, decls);
}

/* struct _objc_protocol {
     struct _objc_class *isa;
     char *protocol_name;
     struct _objc_protocol **protocol_list;
     struct _objc__method_prototype_list *instance_methods;
     struct _objc__method_prototype_list *class_methods;
   };  */

static void
build_protocol_template (void)
{
  tree ptype, decls, *chain = NULL;

  objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));

  /* struct _objc_class *isa; */
  ptype = build_pointer_type (xref_tag (RECORD_TYPE,
					get_identifier (UTAG_CLASS)));
  decls = add_field_decl (ptype, "isa", &chain);

  /* char *protocol_name; */
  add_field_decl (string_type_node, "protocol_name", &chain);

  /* struct _objc_protocol **protocol_list; */
  ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
  add_field_decl (ptype, "protocol_list", &chain);

  /* struct _objc__method_prototype_list *instance_methods; */
  add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);

  /* struct _objc__method_prototype_list *class_methods; */
  add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);

  objc_finish_struct (objc_protocol_template, decls);
}

/* --- names, decls + identifiers --- */

static void
build_selector_table_decl (void)
{
  tree temp;

  build_selector_template ();
  temp = build_array_type (objc_selector_template, NULL_TREE);

  UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
  /* Squash `defined but not used' warning check_global_declaration.  */
  TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
  OBJCMETA (UOBJC_SELECTOR_TABLE_decl, objc_meta, meta_base);
}


static tree
gnu_runtime_abi_01_super_superclassfield_id (void)
{
  if (!super_superclassfield_id)
    super_superclassfield_id = get_identifier ("super_class");
  return super_superclassfield_id;
}


static tree
gnu_runtime_abi_01_class_decl (tree klass)
{
  tree decl;
  char buf[BUFSIZE];
  snprintf (buf, BUFSIZE, "_OBJC_Class_%s",
	    IDENTIFIER_POINTER (CLASS_NAME (klass)));
  decl = start_var_decl (objc_class_template, buf);
  OBJCMETA (decl, objc_meta, meta_base);
  return decl;
}

static tree
gnu_runtime_abi_01_metaclass_decl (tree klass)
{
  tree decl;
  char buf[BUFSIZE];
  snprintf (buf, BUFSIZE, "_OBJC_MetaClass_%s",
	    IDENTIFIER_POINTER (CLASS_NAME (klass)));
  decl = start_var_decl (objc_class_template, buf);
  OBJCMETA (decl, objc_meta, meta_base);
  return decl;
}

static tree
gnu_runtime_abi_01_category_decl (tree klass)
{
  tree decl;
  char buf[BUFSIZE];
  snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s",
	    IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)),
	    IDENTIFIER_POINTER (CLASS_NAME (klass)));
  decl = start_var_decl (objc_category_template, buf);
  OBJCMETA (decl, objc_meta, meta_base);
  return decl;
}

static tree
gnu_runtime_abi_01_protocol_decl (tree p)
{
  tree decl;
  char buf[BUFSIZE];

  /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */
  snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s",
	    IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
  decl = start_var_decl (objc_protocol_template, buf);
  OBJCMETA (decl, objc_meta, meta_base);
  return decl;
}

static tree
gnu_runtime_abi_01_string_decl (tree type, const char *name,
				string_section where ATTRIBUTE_UNUSED)
{
  tree decl = start_var_decl (type, name);
  OBJCMETA (decl, objc_meta, meta_base);
  return decl;
}

/* --- entry --- */

static tree
gnu_runtime_abi_01_get_class_reference (tree ident)
{
  tree params;

  add_class_reference (ident);

  params = build_tree_list (NULL_TREE, my_build_string_pointer
						(IDENTIFIER_LENGTH (ident) + 1,
						 IDENTIFIER_POINTER (ident)));

  return build_function_call (input_location, objc_get_class_decl, params);
}

/* Used by build_function_type_for_method.  Append the types for
   receiver & _cmd at the start of a method argument list to ARGTYPES.
   CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
   trying to define a method or call one.  SUPERFLAG says this is for a
   send to super.  METH may be NULL, in the case that there is no
   prototype.  */

static void
gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **argtypes,
					   tree meth, int context,
					   int superflag ATTRIBUTE_UNUSED)
{
  tree receiver_type;

  if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
    receiver_type = objc_instance_type;
  else
    receiver_type = objc_object_type;

  vec_safe_push (*argtypes, receiver_type);
  /* Selector type - will eventually change to `int'.  */
  vec_safe_push (*argtypes, objc_selector_type);
}

/* Unused for GNU runtime.  */
static tree
gnu_runtime_abi_01_receiver_is_class_object (tree a ATTRIBUTE_UNUSED)
{
  return NULL_TREE;
}

/* sel_ref_chain is a list whose "value" fields will be instances of
   identifier_node that represent the selector.  LOC is the location of
   the @selector.  */

static tree
gnu_runtime_abi_01_build_typed_selector_reference (location_t loc, tree ident,
						   tree prototype)
{
  tree *chain = &sel_ref_chain;
  tree expr;
  int index = 0;

  while (*chain)
    {
      /* When we do a lookup for @selector () we have no idea of the
         prototype - so match the first we find.  */
      if (TREE_VALUE (*chain) == ident
          && (!prototype || TREE_PURPOSE (*chain) == prototype))
	goto return_at_index;

      index++;
      chain = &TREE_CHAIN (*chain);
    }

  *chain = tree_cons (prototype, ident, NULL_TREE);

  /* TODO: Use a vec and keep this in it to (a) avoid re-creating and
     (b) provide better diagnostics for the first time an undefined
     selector is used.  */
 return_at_index:
  expr = build_unary_op (loc, ADDR_EXPR,
			 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
					  build_int_cst (NULL_TREE, index)),
			 1);
  return convert (objc_selector_type, expr);
}

/* Build a tree expression to send OBJECT the operation SELECTOR,
   looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
   assuming the method has prototype METHOD_PROTOTYPE.
   (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
   LOC is the location of the expression to build.
   Use METHOD_PARAMS as list of args to pass to the method.
   If SUPER_FLAG is nonzero, we look up the superclass's method.  */

static tree
build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
			tree lookup_object, tree selector,
			tree method_params)
{
  tree sender = (super_flag ? umsg_super_decl
			    : (flag_objc_direct_dispatch ? umsg_fast_decl
							 : umsg_decl));
  tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
  vec<tree, va_gc> *parms;
  vec<tree, va_gc> *tv;
  unsigned nparm = (method_params ? list_length (method_params) : 0);

  /* If a prototype for the method to be called exists, then cast
     the sender's return type and arguments to match that of the method.
     Otherwise, leave sender as is.  */
  tree ret_type
    = (method_prototype
       ? TREE_VALUE (TREE_TYPE (method_prototype))
       : objc_object_type);
  tree ftype
    = build_function_type_for_method (ret_type, method_prototype,
				      METHOD_REF, super_flag);
  tree sender_cast;
  tree method, t;

  if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
    ftype = build_type_attribute_variant (ftype,
					  METHOD_TYPE_ATTRIBUTES
					  (method_prototype));

  sender_cast = build_pointer_type (ftype);

  lookup_object = build_c_cast (loc, rcv_p, lookup_object);

  /* Use SAVE_EXPR to avoid evaluating the receiver twice.  */
  lookup_object = save_expr (lookup_object);

  /* Param list + 2 slots for object and selector.  */
  vec_alloc (parms, nparm + 2);
  vec_alloc (tv, 2);

  /* First, call the lookup function to get a pointer to the method,
     then cast the pointer, then call it with the method arguments.  */
  tv->quick_push (lookup_object);
  tv->quick_push (selector);
  method = build_function_call_vec (loc, vNULL, sender, tv, NULL);
  vec_free (tv);

  /* Pass the appropriate object to the method.  */
  parms->quick_push ((super_flag ? self_decl : lookup_object));

  /* Pass the selector to the method.  */
  parms->quick_push (selector);
  /* Now append the remainder of the parms.  */
  if (nparm)
    for (; method_params; method_params = TREE_CHAIN (method_params))
      parms->quick_push (TREE_VALUE (method_params));

  /* Build an obj_type_ref, with the correct cast for the method call.  */
  t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
  t = build_function_call_vec (loc, vNULL, t, parms, NULL);
  vec_free (parms);
  return t;
}

static tree
gnu_runtime_abi_01_build_objc_method_call (location_t loc,
					   tree method_prototype,
					   tree receiver,
					   tree rtype ATTRIBUTE_UNUSED,
					   tree sel_name,
					   tree method_params,
					   int super ATTRIBUTE_UNUSED)
{
  tree selector =
	gnu_runtime_abi_01_build_typed_selector_reference (loc,
							  sel_name,
							  method_prototype);

  return build_objc_method_call (loc, super, method_prototype, receiver,
				 selector, method_params);
}

static tree
gnu_runtime_abi_01_get_protocol_reference (location_t loc, tree p)
{
  tree expr, protocol_struct_type, *chain;
  if (!PROTOCOL_FORWARD_DECL (p))
    PROTOCOL_FORWARD_DECL (p) = gnu_runtime_abi_01_protocol_decl (p);

  expr = build_unary_op (loc, ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);

  /* ??? Ideally we'd build the reference with objc_protocol_type directly,
     if we have it, rather than converting it here.  */
  expr = convert (objc_protocol_type, expr);

  /* The @protocol() expression is being compiled into a pointer to a
     statically allocated instance of the Protocol class.  To become
     usable at runtime, the 'isa' pointer of the instance need to be
     fixed up at runtime by the runtime library, to point to the
     actual 'Protocol' class.  */

  /* For the GNU runtime, put the static Protocol instance in the list
     of statically allocated instances, so that we make sure that its
     'isa' pointer is fixed up at runtime by the GNU runtime library
     to point to the Protocol class (at runtime, when loading the
     module, the GNU runtime library loops on the statically allocated
     instances (as found in the defs field in objc_symtab) and fixups
     all the 'isa' pointers of those objects).  */

  /* This type is a struct containing the fields of a Protocol
     object.  (Cfr. objc_protocol_type instead is the type of a pointer
     to such a struct).  */
  protocol_struct_type = xref_tag (RECORD_TYPE,
				   get_identifier (PROTOCOL_OBJECT_CLASS_NAME));

  /* Look for the list of Protocol statically allocated instances
     to fixup at runtime.  Create a new list to hold Protocol
     statically allocated instances, if the list is not found.  At
     present there is only another list, holding NSConstantString
     static instances to be fixed up at runtime.  */

  for (chain = &objc_static_instances;
	*chain && TREE_VALUE (*chain) != protocol_struct_type;
	chain = &TREE_CHAIN (*chain));

  if (!*chain)
    {
       *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
       add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
                          class_names);
    }

  /* Add this statically allocated instance to the Protocol list.  */
  TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
				     PROTOCOL_FORWARD_DECL (p),
				     TREE_PURPOSE (*chain));
  return expr;
}

/* For ABI 8 an IVAR is just a fixed offset in the class struct.  */

static tree
gnu_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED,
				   tree base, tree id)
{
  return objc_build_component_ref (base, id);
}

/* We build super class references as we need them (but keep them once
   built for the sake of efficiency).  */

static tree
gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
					struct imp_entry *imp, bool inst_meth)
{
  if (inst_meth)
    {
      if (!ucls_super_ref)
	ucls_super_ref =
		objc_build_component_ref (imp->class_decl,
					  get_identifier ("super_class"));
	return ucls_super_ref;
    }
  else
    {
      if (!uucls_super_ref)
	uucls_super_ref =
		objc_build_component_ref (imp->meta_decl,
					  get_identifier ("super_class"));
	return uucls_super_ref;
    }
}

static tree
gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
					   struct imp_entry *imp, bool inst_meth)
{
  tree super_name = CLASS_SUPER_NAME (imp->imp_template);
  tree super_class;

  add_class_reference (super_name);
  super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl);
  super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
					IDENTIFIER_POINTER (super_name));
  /* super_class = get_{meta_}class("CLASS_SUPER_NAME");  */
  return build_function_call (input_location,
			      super_class,
			      build_tree_list (NULL_TREE, super_name));
}

static bool
gnu_runtime_abi_01_setup_const_string_class_decl (void)
{
  /* Do nothing, and create no error.  */
  return true;
}

/* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR.  */

static GTY(()) int num_static_inst;

static tree
objc_add_static_instance (tree constructor, tree class_decl)
{
  tree *chain, decl;
  char buf[BUFSIZE];

  /* Find the list of static instances for the CLASS_DECL.  Create one if
     not found.  */
  for (chain = &objc_static_instances;
       *chain && TREE_VALUE (*chain) != class_decl;
       chain = &TREE_CHAIN (*chain));
  if (!*chain)
    {
      *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
      add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
    }

  snprintf (buf, BUFSIZE, "_OBJC_INSTANCE_%d", num_static_inst++);
  decl = build_decl (input_location,
		     VAR_DECL, get_identifier (buf), class_decl);
  TREE_STATIC (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  TREE_USED (decl) = 1;
  DECL_INITIAL (decl) = constructor;
  DECL_CONTEXT (decl) = NULL;
  OBJCMETA (decl, objc_meta, meta_base);

  /* We may be writing something else just now.
     Postpone till end of input. */
  DECL_DEFER_OUTPUT (decl) = 1;
  lang_hooks.decls.pushdecl (decl);
  rest_of_decl_compilation (decl, 1, 0);

  /* Add the DECL to the head of this CLASS' list.  */
  TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));

  return decl;
}

static tree
gnu_runtime_abi_01_build_const_string_constructor (location_t loc, tree string,
						   int length)
{
  tree constructor, fields;
  vec<constructor_elt, va_gc> *v = NULL;

  /* GNU:    (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length })  */
  fields = TYPE_FIELDS (internal_const_str_type);
  CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, 0));

  fields = DECL_CHAIN (fields);
  CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc,
						     ADDR_EXPR, string, 1));

  fields = DECL_CHAIN (fields);
  CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
  constructor = objc_build_constructor (internal_const_str_type, v);

  constructor = objc_add_static_instance (constructor, constant_string_type);
  return constructor;
}

/* --- metadata - module initializer --- */

/* The GNU runtime requires us to provide a static initializer function
   for each module:

   static void __objc_gnu_init (void) {
     __objc_exec_class (&L_OBJC_MODULES);
   }  */


static void
build_module_initializer_routine (void)
{
  tree body;

#ifdef OBJCPLUS
  push_lang_context (lang_name_c); /* extern "C" */
#endif

  objc_push_parm (build_decl (input_location,
			      PARM_DECL, NULL_TREE, void_type_node));
#ifdef OBJCPLUS
  objc_start_function (get_identifier (TAG_GNUINIT),
		       build_function_type_list (void_type_node, NULL_TREE),
		       NULL_TREE, NULL_TREE);
#else
  objc_start_function (get_identifier (TAG_GNUINIT),
		       build_function_type_list (void_type_node, NULL_TREE),
		       NULL_TREE, objc_get_parm_info (0, NULL_TREE));
#endif
  body = c_begin_compound_stmt (true);
  add_stmt (build_function_call
	    (input_location,
	     execclass_decl,
	     build_tree_list
	     (NULL_TREE,
	      build_unary_op (input_location, ADDR_EXPR,
			      UOBJC_MODULES_decl, 0))));
  add_stmt (c_end_compound_stmt (input_location, body, true));

  TREE_PUBLIC (current_function_decl) = 0;

#ifndef OBJCPLUS
  /* For Objective-C++, we will need to call __objc_gnu_init
     from objc_generate_static_init_call() below.  */
  DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
#endif

  GNU_INIT_decl = current_function_decl;
  finish_function ();

#ifdef OBJCPLUS
    pop_lang_context ();
#endif
}

#ifdef OBJCPLUS
/* Return 1 if the __objc_gnu_init function has been synthesized and needs
   to be called by the module initializer routine.  */

int
objc_static_init_needed_p (void)
{
  return (GNU_INIT_decl != NULL_TREE);
}

/* Generate a call to the __objc_gnu_init initializer function.  */

tree
objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
{
  add_stmt (build_stmt (input_location, EXPR_STMT,
			build_function_call (input_location,
					     GNU_INIT_decl, NULL_TREE)));

  return ctors;
}
#endif /* OBJCPLUS */

/* --- Output GNU Meta-data --- */

static void
generate_classref_translation_entry (tree chain)
{
  tree expr, decl, type;

  decl = TREE_PURPOSE (chain);
  type = TREE_TYPE (decl);

  expr = add_objc_string (TREE_VALUE (chain), class_names);
  expr = convert (type, expr); /* cast! */

  /* This is a class reference.  It is re-written by the runtime,
     but will be optimized away unless we force it.  */
  DECL_PRESERVE_P (decl) = 1;
  OBJCMETA (decl, objc_meta, meta_base);
  finish_var_decl (decl, expr);
  return;
}


static void
handle_impent (struct imp_entry *impent)
{
  char *string;

/*  objc_implementation_context = impent->imp_context;
  implementation_template = impent->imp_template;*/

  switch (TREE_CODE (impent->imp_context))
    {
    case CLASS_IMPLEMENTATION_TYPE:
      {
	const char *const class_name =
	  IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));

	string = (char *) alloca (strlen (class_name) + 30);

	sprintf (string, "__objc_class_name_%s", class_name);
	break;
      }
    case CATEGORY_IMPLEMENTATION_TYPE:
      {
	const char *const class_name =
	  IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
	const char *const class_super_name =
	  IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));

	string = (char *) alloca (strlen (class_name)
				  + strlen (class_super_name) + 30);

	/* Do the same for categories.  Even though no references to
	   these symbols are generated automatically by the compiler,
	   it gives you a handle to pull them into an archive by
	   hand.  */
	sprintf (string, "*__objc_category_name_%s_%s", class_name, class_super_name);
	break;
      }
    default:
      return;
    }

    {
      tree decl, init;

      init = integer_zero_node;
      decl = build_decl (input_location,
			 VAR_DECL, get_identifier (string), TREE_TYPE (init));
      TREE_PUBLIC (decl) = 1;
      TREE_READONLY (decl) = 1;
      TREE_USED (decl) = 1;
      TREE_CONSTANT (decl) = 1;
      DECL_CONTEXT (decl) = NULL_TREE;
      DECL_ARTIFICIAL (decl) = 1;
      TREE_STATIC (decl) = 1;
      DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
      /* We must force the reference.  */
      DECL_PRESERVE_P (decl) = 1;

      finish_var_decl(decl, init) ;
    }
}

tree
build_protocol_initializer (tree type, tree protocol_name, tree protocol_list,
			    tree inst_methods, tree class_methods)
{
  tree expr, ttyp;
  location_t loc;
  vec<constructor_elt, va_gc> *inits = NULL;

  /* TODO: pass the loc in or find it from args.  */
  loc = input_location;
  ttyp = build_pointer_type (xref_tag (RECORD_TYPE,
				       get_identifier (UTAG_CLASS)));
  /* Filling the "isa" in with a version allows the runtime system to
     detect this ...   */
  expr = build_int_cst (ttyp, PROTOCOL_VERSION);

  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);

  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);

  ttyp = objc_method_proto_list_ptr;
  if (inst_methods)
    expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
  else
    expr = convert (ttyp, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);

  if (class_methods)
    expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
  else
    expr = convert (ttyp, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);

  return objc_build_constructor (type, inits);
}

static tree
generate_protocol_list (tree i_or_p, tree klass_ctxt)
{
  tree array_type, ptype, refs_decl, lproto, e, plist;
  vec<constructor_elt, va_gc> *v = NULL;
  char buf[BUFSIZE];
  int size = 0;

  switch (TREE_CODE (i_or_p))
    {
    case CLASS_INTERFACE_TYPE:
    case CATEGORY_INTERFACE_TYPE:
      plist = CLASS_PROTOCOL_LIST (i_or_p);
      break;
    case PROTOCOL_INTERFACE_TYPE:
      plist = PROTOCOL_LIST (i_or_p);
      break;
    default:
      gcc_unreachable ();
    }

  /* Compute size.  */
  for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
    if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
	&& PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
      size++;

  /* Build initializer.  */
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
  e = build_int_cst (build_pointer_type (objc_protocol_template), size);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);

  for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
    {
      tree pval = TREE_VALUE (lproto);

      if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
	  && PROTOCOL_FORWARD_DECL (pval))
	{
	  tree fwref = PROTOCOL_FORWARD_DECL (pval);
	  location_t loc = DECL_SOURCE_LOCATION (fwref) ;
	  e = build_unary_op (loc, ADDR_EXPR, fwref, 0);
          CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
	}
    }

  /* static struct objc_protocol *refs[n]; */

  switch (TREE_CODE (i_or_p))
    {
    case PROTOCOL_INTERFACE_TYPE:
      snprintf (buf, BUFSIZE, "_OBJC_ProtocolRefs_%s",
		IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p)));
      break;
    case CLASS_INTERFACE_TYPE:
      snprintf (buf, BUFSIZE, "_OBJC_ClassProtocols_%s",
		IDENTIFIER_POINTER (CLASS_NAME (i_or_p)));
      break;
    case CATEGORY_INTERFACE_TYPE:
      snprintf (buf, BUFSIZE, "_OBJC_CategoryProtocols_%s_%s",
		IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt)),
		IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt)));
      break;
    default:
      gcc_unreachable ();
    }

  ptype = build_pointer_type (objc_protocol_template);
  array_type = build_sized_array_type (ptype, size + 3);
  refs_decl = start_var_decl (array_type, buf);
  OBJCMETA (refs_decl, objc_meta, meta_base);
  finish_var_decl (refs_decl,
                   objc_build_constructor (TREE_TYPE (refs_decl), v));

  return refs_decl;
}

static tree
generate_v1_meth_descriptor_table (tree chain, tree protocol, const char *prefix)
{
  tree method_list_template, initlist, decl;
  int size;
  vec<constructor_elt, va_gc> *v = NULL;
  char buf[BUFSIZE];

  if (!chain || !prefix)
    return NULL_TREE;

  if (!objc_method_prototype_template)
    objc_method_prototype_template = build_method_prototype_template ();

  size = list_length (chain);
  method_list_template =
	build_method_prototype_list_template (objc_method_prototype_template,
					      size);
  snprintf (buf, BUFSIZE, "%s_%s", prefix,
	    IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));

  decl = start_var_decl (method_list_template, buf);

  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
  initlist =
	build_descriptor_table_initializer (objc_method_prototype_template,
					    chain);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
  OBJCMETA (decl, objc_meta, meta_base);
  finish_var_decl (decl, objc_build_constructor (method_list_template, v));
  return decl;
}

/* For each protocol which was referenced either from a @protocol()
   expression, or because a class/category implements it (then a
   pointer to the protocol is stored in the struct describing the
   class/category), we create a statically allocated instance of the
   Protocol class.  The code is written in such a way as to generate
   as few Protocol objects as possible; we generate a unique Protocol
   instance for each protocol, and we don't generate a Protocol
   instance if the protocol is never referenced (either from a
   @protocol() or from a class/category implementation).  These
   statically allocated objects can be referred to via the static
   (that is, private to this module) symbols _OBJC_PROTOCOL_n.

   The statically allocated Protocol objects that we generate here
   need to be fixed up at runtime in order to be used: the 'isa'
   pointer of the objects need to be set up to point to the 'Protocol'
   class, as known at runtime.

   The GNU runtime fixes up all protocols before user code from the module
   is executed; it requires pointers to those symbols
   to be put in the objc_symtab (which is then passed as argument to
   the function __objc_exec_class() which the compiler sets up to be
   executed automatically when the module is loaded); setup of those
   Protocol objects happen in two ways in the GNU runtime: all
   Protocol objects referred to by a class or category implementation
   are fixed up when the class/category is loaded; all Protocol
   objects referred to by a @protocol() expression are added by the
   compiler to the list of statically allocated instances to fixup
   (the same list holding the statically allocated constant string
   objects).  Because, as explained above, the compiler generates as
   few Protocol objects as possible, some Protocol object might end up
   being referenced multiple times when compiled with the GNU runtime,
   and end up being fixed up multiple times at runtime initialization.
   But that doesn't hurt, it's just a little inefficient.  */

static void
generate_protocols (void)
{
  tree p, encoding;
  tree decl;
  tree initlist, protocol_name_expr, refs_decl, refs_expr;

  /* If a protocol was directly referenced, pull in indirect references.  */
  for (p = protocol_chain; p; p = TREE_CHAIN (p))
    if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
      generate_protocol_references (PROTOCOL_LIST (p));

  for (p = protocol_chain; p; p = TREE_CHAIN (p))
    {
      tree nst_methods = PROTOCOL_NST_METHODS (p);
      tree cls_methods = PROTOCOL_CLS_METHODS (p);

      /* If protocol wasn't referenced, don't generate any code.  */
      decl = PROTOCOL_FORWARD_DECL (p);

      if (!decl)
	continue;

      /* Make sure we link in the Protocol class.  */
      add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));

      while (nst_methods)
	{
	  if (! METHOD_ENCODING (nst_methods))
	    {
	      encoding = encode_method_prototype (nst_methods);
	      METHOD_ENCODING (nst_methods) = encoding;
	    }
	  nst_methods = DECL_CHAIN (nst_methods);
	}

      UOBJC_INSTANCE_METHODS_decl =
	generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p,
					   "_OBJC_PROTOCOL_INSTANCE_METHODS");

      while (cls_methods)
	{
	  if (! METHOD_ENCODING (cls_methods))
	    {
	      encoding = encode_method_prototype (cls_methods);
	      METHOD_ENCODING (cls_methods) = encoding;
	    }

	  cls_methods = DECL_CHAIN (cls_methods);
	}

      UOBJC_CLASS_METHODS_decl =
	generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p,
					   "_OBJC_PROTOCOL_CLASS_METHODS");
/*      generate_method_descriptors (p);*/

      if (PROTOCOL_LIST (p))
	refs_decl = generate_protocol_list (p, NULL_TREE);
      else
	refs_decl = 0;

      /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
      protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);

      if (refs_decl)
	refs_expr = convert (build_pointer_type (build_pointer_type
						 (objc_protocol_template)),
			     build_unary_op (input_location,
					     ADDR_EXPR, refs_decl, 0));
      else
	refs_expr = build_int_cst (NULL_TREE, 0);

      /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
	 by generate_method_descriptors, which is called above.  */
      initlist = build_protocol_initializer (TREE_TYPE (decl),
					     protocol_name_expr, refs_expr,
					     UOBJC_INSTANCE_METHODS_decl,
					     UOBJC_CLASS_METHODS_decl);
      finish_var_decl (decl, initlist);
    }
}

static tree
generate_dispatch_table (tree chain, const char *name)
{
  tree decl, method_list_template, initlist;
  vec<constructor_elt, va_gc> *v = NULL;
  int size = list_length (chain);

  if (!objc_method_template)
    objc_method_template = build_method_template ();

  method_list_template = build_method_list_template (objc_method_template,
						     size);
  initlist = build_dispatch_table_initializer (objc_method_template, chain);

  decl = start_var_decl (method_list_template, name);

  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			  build_int_cst (integer_type_node, size));
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);

  OBJCMETA (decl, objc_meta, meta_base);
  finish_var_decl (decl,
		   objc_build_constructor (TREE_TYPE (decl), v));

  return decl;
}

/* Init a category.  */
static tree
build_category_initializer (tree type, tree cat_name, tree class_name,
			    tree inst_methods, tree class_methods,
			    tree protocol_list)
{
  tree expr, ltyp;
  location_t loc;
  vec<constructor_elt, va_gc> *v = NULL;

  /* TODO: pass the loc in or find it from args.  */
  /* TODO: pass the loc in or find it from args.  */
  loc = UNKNOWN_LOCATION;
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);

  ltyp = objc_method_list_ptr;
  if (inst_methods)
    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
  else
    expr = convert (ltyp, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);

  if (class_methods)
    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
  else
    expr = convert (ltyp, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);

  /* protocol_list = */
  ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
  if (protocol_list)
    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0));
  else
    expr = convert (ltyp, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);

  return objc_build_constructor (type, v);
}

/* static struct objc_category _OBJC_CATEGORY_<name> = { ... };  */

static void
generate_category (struct imp_entry *impent)
{
  tree initlist, cat_name_expr, class_name_expr;
  tree protocol_decl, category, cat_decl;
  tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
  tree cat = impent->imp_context;
  char buf[BUFSIZE];

  cat_decl = impent->class_decl;

  add_class_reference (CLASS_NAME (cat));
  cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);

  class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);

  category = lookup_category (impent->imp_template, CLASS_SUPER_NAME (cat));

  if (category && CLASS_PROTOCOL_LIST (category))
    {
      generate_protocol_references (CLASS_PROTOCOL_LIST (category));
      protocol_decl = generate_protocol_list (category, cat);
    }
  else
    protocol_decl = 0;

  if (CLASS_NST_METHODS (cat))
    {
      snprintf (buf, BUFSIZE, "_OBJC_CategoryInstanceMethods_%s_%s",
		IDENTIFIER_POINTER (CLASS_NAME (cat)),
		IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
      inst_methods = generate_dispatch_table (CLASS_NST_METHODS (cat), buf);
    }

  if (CLASS_CLS_METHODS (cat))
    {
      snprintf (buf, BUFSIZE, "_OBJC_CategoryClassMethods_%s_%s",
		IDENTIFIER_POINTER (CLASS_NAME (cat)),
		IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
      class_methods = generate_dispatch_table (CLASS_CLS_METHODS (cat), buf);
    }

  initlist = build_category_initializer (TREE_TYPE (cat_decl),
					 cat_name_expr, class_name_expr,
					 inst_methods, class_methods,
					 protocol_decl);
  /* Finish and initialize the forward decl.  */
  finish_var_decl (cat_decl, initlist);
  impent->class_decl = cat_decl;
}

/* struct _objc_class {
     struct objc_class *isa;
     struct objc_class *super_class;
     char *name;
     long version;
     long info;
     long instance_size;
     struct objc_ivar_list *ivars;
     struct objc_method_list *methods;
     struct sarray *dtable;
     struct objc_class *subclass_list;
     struct objc_class *sibling_class;
     struct objc_protocol_list *protocols;
     void *gc_object_type;
   };  */

static tree
build_shared_structure_initializer (tree type, tree isa, tree super,
				    tree name, tree size, int status,
				    tree dispatch_table, tree ivar_list,
				    tree protocol_list)
{
  tree expr, ltyp;
  vec<constructor_elt, va_gc> *v = NULL;

  /* isa = */
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);

  /* super_class = */
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);

  /* name = */
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));

  /* version = */
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
                          build_int_cst (long_integer_type_node, 0));

  /* info = */
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
                          build_int_cst (long_integer_type_node, status));

  /* instance_size = */
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
                          convert (long_integer_type_node, size));

  /* objc_ivar_list = */
  if (!ivar_list)
    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			    build_int_cst (objc_ivar_list_ptr, 0));
  else
    {
      expr = convert (objc_ivar_list_ptr,
		      build_unary_op (input_location, ADDR_EXPR,
				      ivar_list, 0));
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
    }

  /* objc_method_list = */
  if (!dispatch_table)
    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			   convert (objc_method_list_ptr, null_pointer_node));
  else
    {
      expr = convert (objc_method_list_ptr,
		      build_unary_op (input_location, ADDR_EXPR,
				      dispatch_table, 0));
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
    }

  /* FIXME: Remove NeXT runtime code.  */
  if (flag_next_runtime)
    {
      ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
					   get_identifier ("objc_cache")));
      /* method_cache = */
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (ltyp, null_pointer_node));
    }
  else
    {
      /* dtable = */
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));

      /* subclass_list = */
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));

      /* sibling_class = */
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
    }

  /* protocol_list = */
  ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
  if (! protocol_list)
    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (ltyp, 0));
  else
    {
      expr = convert (ltyp,
		      build_unary_op (input_location, ADDR_EXPR,
				      protocol_list, 0));
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
    }

  /* FIXME: Remove NeXT runtime code.  */
  if (flag_next_runtime)
    /* sel_id = NULL */
    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));

  /* gc_object_type = NULL */
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));

  return objc_build_constructor (type, v);
}


static tree
generate_ivars_list (tree chain, const char *name)
{
  tree initlist, ivar_list_template, decl;
  int size;
  vec<constructor_elt, va_gc> *inits = NULL;

  if (!chain)
    return NULL_TREE;

  if (!objc_ivar_template)
    objc_ivar_template = build_ivar_template ();

  size = ivar_list_length (chain);

  generating_instance_variables = 1;
  ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
  initlist = build_ivar_list_initializer (objc_ivar_template, chain);
  generating_instance_variables = 0;

  decl = start_var_decl (ivar_list_template, name);

  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);

  OBJCMETA (decl, objc_meta, meta_base);
  finish_var_decl (decl,
		   objc_build_constructor (TREE_TYPE (decl), inits));

  return decl;
}

/* static struct objc_class _OBJC_METACLASS_Foo={ ... };
   static struct objc_class _OBJC_CLASS_Foo={ ... };  */

static void
generate_class_structures (struct imp_entry *impent)
{
  tree name_expr, super_expr, root_expr, class_decl, meta_decl;
  tree my_root_id, my_super_id;
  tree cast_type, initlist, protocol_decl;
  tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
  tree chain, inst_ivars = NULL_TREE, class_ivars = NULL_TREE;
  location_t loc;
  char buf[BUFSIZE];
  int cls_flags = 0 ;

/*  objc_implementation_context = impent->imp_context;
  implementation_template = impent->imp_template;*/
  class_decl = impent->class_decl;
  meta_decl = impent->meta_decl;
/*  UOBJC_CLASS_decl = impent->class_decl;
  UOBJC_METACLASS_decl = impent->meta_decl;*/

  loc = DECL_SOURCE_LOCATION (impent->class_decl);

  my_super_id = CLASS_SUPER_NAME (impent->imp_template);
  if (my_super_id)
    {
      add_class_reference (my_super_id);

      /* Compute "my_root_id" - this is required for code generation.
         the "isa" for all meta class structures points to the root of
         the inheritance hierarchy (e.g. "__Object")...  */
      my_root_id = my_super_id;
      do
	{
	  tree my_root_int = lookup_interface (my_root_id);

	  if (my_root_int && CLASS_SUPER_NAME (my_root_int))
	    my_root_id = CLASS_SUPER_NAME (my_root_int);
	  else
	    break;
	}
      while (1);
    }
  else
    /* No super class.  */
    my_root_id = CLASS_NAME (impent->imp_template);

  cast_type = build_pointer_type (objc_class_template);
  name_expr = add_objc_string (CLASS_NAME (impent->imp_template),
			       class_names);

  /* Install class `isa' and `super' pointers at runtime.  */
  if (my_super_id)
    super_expr = add_objc_string (my_super_id, class_names);
  else
    super_expr = null_pointer_node;

  super_expr = build_c_cast (loc, cast_type, super_expr);

  root_expr = add_objc_string (my_root_id, class_names);
  root_expr = build_c_cast (loc, cast_type, root_expr);

  if (CLASS_PROTOCOL_LIST (impent->imp_template))
    {
      generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template));
      protocol_decl = generate_protocol_list (impent->imp_template,
					      impent->imp_context);
    }
  else
    protocol_decl = NULL_TREE;

  if (CLASS_CLS_METHODS (impent->imp_context))
    {
      snprintf (buf, BUFSIZE, "_OBJC_ClassMethods_%s",
		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
      class_methods = generate_dispatch_table (CLASS_CLS_METHODS (impent->imp_context),
					       buf);
    }

  if (CLASS_SUPER_NAME (impent->imp_template) == NULL_TREE
      && (chain = TYPE_FIELDS (objc_class_template)))
    {
      snprintf (buf, BUFSIZE, "_OBJC_ClassIvars_%s",
		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
      class_ivars = generate_ivars_list (chain, buf);
    }

  /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */

  initlist =
	build_shared_structure_initializer
			(TREE_TYPE (meta_decl),
			root_expr, super_expr, name_expr,
			convert (integer_type_node,
				TYPE_SIZE_UNIT (objc_class_template)),
			CLS_META, class_methods, class_ivars,
			protocol_decl);

  finish_var_decl (meta_decl, initlist);
  impent->meta_decl = meta_decl;

  /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
  if (CLASS_NST_METHODS (impent->imp_context))
    {
      snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s",
		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
      inst_methods = generate_dispatch_table (CLASS_NST_METHODS (impent->imp_context),
					      buf);
    }

  if ((chain = CLASS_IVARS (impent->imp_template)))
    {
      snprintf (buf, BUFSIZE, "_OBJC_InstanceIvars_%s",
		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
      inst_ivars = generate_ivars_list (chain, buf);
    }

  initlist =
	build_shared_structure_initializer
		(TREE_TYPE (class_decl),
		build_unary_op (loc, ADDR_EXPR, meta_decl, 0),
		super_expr, name_expr,
		convert (integer_type_node,
			 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
					(impent->imp_template))),
		CLS_FACTORY | cls_flags, inst_methods, inst_ivars,
		protocol_decl);

  finish_var_decl (class_decl, initlist);
  impent->class_decl = class_decl;
}

/* --- Output GNU Metadata --- */

/* TODO: Make this into an array of refs.  */
static void
handle_class_ref (tree chain)
{
  const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
  char *string = (char *) alloca (strlen (name) + 30);
  tree decl;
  tree exp;

  sprintf (string, "__objc_class_name_%s", name);

  /* Make a decl for this name, so we can use its address in a tree.  */
  decl = build_decl (input_location,
		     VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
  DECL_EXTERNAL (decl) = 1;
  TREE_PUBLIC (decl) = 1;
  DECL_CONTEXT (decl) = NULL_TREE;
  finish_var_decl (decl, 0);

  /* Make a decl for the address.  */
  sprintf (string, "__objc_class_ref_%s", name);
  exp = build1 (ADDR_EXPR, string_type_node, decl);
  decl = build_decl (input_location,
		     VAR_DECL, get_identifier (string), string_type_node);
  TREE_STATIC (decl) = 1;
  TREE_USED (decl) = 1;
  DECL_READ_P (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_INITIAL (decl) = error_mark_node;

  /* We must force the reference.  */
  DECL_PRESERVE_P (decl) = 1;

  DECL_CONTEXT (decl) = NULL_TREE;
  finish_var_decl (decl, exp);
}

static tree
get_proto_encoding (tree proto)
{
  tree encoding;
  if (proto)
    {
      if (! METHOD_ENCODING (proto))
	{
	  encoding = encode_method_prototype (proto);
	  METHOD_ENCODING (proto) = encoding;
	}
      else
	encoding = METHOD_ENCODING (proto);

      return add_objc_string (encoding, meth_var_types);
    }
  else
    return build_int_cst (NULL_TREE, 0);
}

static void
build_gnu_selector_translation_table (void)
{
  tree chain, expr;
  vec<constructor_elt, va_gc> *inits = NULL;
  vec<constructor_elt, va_gc> *v ;

  /* Cause the selector table (previously forward-declared)
     to be actually output.  */

  for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
    {
      tree encoding;
      if (warn_selector)
	{
	  /* TODO: improve on the location for the diagnostic.  */
	  location_t loc = input_location;
	  diagnose_missing_method (TREE_VALUE (chain), loc);
	}

      v = NULL;
      expr = build_selector (TREE_VALUE (chain));
      encoding = get_proto_encoding (TREE_PURPOSE (chain));
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
      expr = objc_build_constructor (objc_selector_template, v);

      CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
    } /* each element in the chain */

  /* List terminator.  */
  v = NULL;
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
  expr = objc_build_constructor (objc_selector_template, v);

  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
  expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
				     inits);
  finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
}

/* Output references to all statically allocated objects.  Return the DECL
   for the array built.  */

static void
generate_static_references (void)
{
  tree expr = NULL_TREE;
  tree class_name, klass, decl;
  tree cl_chain, in_chain, type
    = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
  int num_inst, num_class;
  char buf[BUFSIZE];
  vec<constructor_elt, va_gc> *decls = NULL;

  /* FIXME: Remove NeXT runtime code.  */
  if (flag_next_runtime)
    gcc_unreachable ();

  for (cl_chain = objc_static_instances, num_class = 0;
       cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
    {
      vec<constructor_elt, va_gc> *v = NULL;

      for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
	   in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));

      snprintf (buf, BUFSIZE, "_OBJC_STATIC_INSTANCES_%d", num_class);
      decl = start_var_decl (type, buf);

      /* Output {class_name, ...}.  */
      klass = TREE_VALUE (cl_chain);
      class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			      build_unary_op (input_location,
					      ADDR_EXPR, class_name, 1));

      /* Output {..., instance, ...}.  */
      for (in_chain = TREE_PURPOSE (cl_chain);
	   in_chain; in_chain = TREE_CHAIN (in_chain))
	{
	  expr = build_unary_op (input_location,
				 ADDR_EXPR, TREE_VALUE (in_chain), 1);
	  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
	}

      /* Output {..., NULL}.  */
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));

      expr = objc_build_constructor (TREE_TYPE (decl), v);
      OBJCMETA (decl, objc_meta, meta_base);
      finish_var_decl (decl, expr);
      CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
			      build_unary_op (input_location,
					      ADDR_EXPR, decl, 1));
    }

  CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
  expr = objc_build_constructor (type, decls);
  static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
  OBJCMETA (static_instances_decl, objc_meta, meta_base);
  finish_var_decl (static_instances_decl, expr);
}

/* Create the initial value for the `defs' field of _objc_symtab.
   This is a CONSTRUCTOR.  */

static tree
init_def_list (tree type)
{
  tree expr;
  struct imp_entry *impent;
  location_t loc;
  vec<constructor_elt, va_gc> *v = NULL;

  if (imp_count)
    for (impent = imp_list; impent; impent = impent->next)
      {
	if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
	  {
	    loc = DECL_SOURCE_LOCATION (impent->class_decl);
	    expr = build_unary_op (loc,
				   ADDR_EXPR, impent->class_decl, 0);
	    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
	  }
      }

  if (cat_count)
    for (impent = imp_list; impent; impent = impent->next)
      {
	if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
	  {
	    loc = DECL_SOURCE_LOCATION (impent->class_decl);
	    expr = build_unary_op (loc,
				   ADDR_EXPR, impent->class_decl, 0);
	    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
	  }
      }

  loc = UNKNOWN_LOCATION;
  /* statics = { ..., _OBJC_STATIC_INSTANCES, ... }  */
  if (static_instances_decl)
    expr = build_unary_op (loc, ADDR_EXPR, static_instances_decl, 0);
  else
    expr = integer_zero_node;
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);

  return objc_build_constructor (type, v);
}

/* Take care of defining and initializing _OBJC_SYMBOLS.  */

/* Predefine the following data type:

   struct _objc_symtab
   {
     long sel_ref_cnt;
     SEL *refs;
     short cls_def_cnt;
     short cat_def_cnt;
     void *defs[cls_def_cnt + cat_def_cnt];
   }; */

static void
build_objc_symtab_template (void)
{
  tree fields, array_type, *chain = NULL;
  int index;

  objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));

  /* long sel_ref_cnt; */
  fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);

  /* SEL *refs; */
  add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);

  /* short cls_def_cnt; */
  add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);

  /* short cat_def_cnt; */
  add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);

  /* Note that padding will be added here on LP64.  */

  /* void *defs[imp_count + cat_count (+ 1)]; */
  /* NB: The index is one less than the size of the array.  */
  index = imp_count + cat_count;
  array_type = build_sized_array_type (ptr_type_node, index + 1);
  add_field_decl (array_type, "defs", &chain);

  objc_finish_struct (objc_symtab_template, fields);
}
/* Construct the initial value for all of _objc_symtab.  */

static tree
init_objc_symtab (tree type)
{
  tree field, expr, ltyp;
  location_t loc;
  vec<constructor_elt, va_gc> *v = NULL;

  loc = UNKNOWN_LOCATION;

  /* sel_ref_cnt = { ..., 5, ... } */

  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			  build_int_cst (long_integer_type_node, 0));

  /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */

  ltyp = build_pointer_type (objc_selector_type);
  if (sel_ref_chain)
    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR,
					  UOBJC_SELECTOR_TABLE_decl, 1));
  else
    expr = convert (ltyp, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);

  /* cls_def_cnt = { ..., 5, ... } */

  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			  build_int_cst (short_integer_type_node, imp_count));

  /* cat_def_cnt = { ..., 5, ... } */

  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			  build_int_cst (short_integer_type_node, cat_count));

  /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */

  field = TYPE_FIELDS (type);
  field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));

  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));

  return objc_build_constructor (type, v);
}

/* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
   and initialized appropriately.  */

static void
generate_objc_symtab_decl (void)
{
  build_objc_symtab_template ();
  UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
  OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_base);
  finish_var_decl (UOBJC_SYMBOLS_decl,
		   init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
}

static void
objc_generate_v1_gnu_metadata (void)
{
  struct imp_entry *impent;
  tree chain;

  /* Process the static instances here because initialization of objc_symtab
     depends on them.  */
  if (objc_static_instances)
    generate_static_references ();

  objc_implementation_context =
  implementation_template =
  UOBJC_CLASS_decl =
  UOBJC_METACLASS_decl = NULL_TREE;

  for (impent = imp_list; impent; impent = impent->next)
    {
      /* If -gen-decls is present, Dump the @interface of each class.
	 TODO: Dump the classes in the  order they were found, rather than in
	 reverse order as we are doing now.  */
      if (flag_gen_declaration)
	dump_interface (gen_declaration_file, impent->imp_context);

      /* all of the following reference the string pool...  */
      if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
	generate_class_structures (impent);
      else
	generate_category (impent);
    }

  /* If we are using an array of selectors, we must always
     finish up the array decl even if no selectors were used.  */
  build_gnu_selector_translation_table ();

  if (protocol_chain)
    generate_protocols ();

  /* Arrange for ObjC data structures to be initialized at run time.  */
  /* FIXME: Have some more elegant way to determine if we need to
     generate objc_symtab_decl or not, instead of checking these
     global symbols.  */
  if (imp_list || class_names_chain
      || meth_var_names_chain || meth_var_types_chain || sel_ref_chain
      || prop_names_attr_chain)
    generate_objc_symtab_decl ();

  if (imp_list || class_names_chain || objc_static_instances
      || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
    {
      /* Make sure that the meta-data are identified as being
	 GNU-runtime.  */
      build_module_descriptor (OBJC_VERSION,
			       build_tree_list (objc_meta, meta_base));
      build_module_initializer_routine ();
    }

  /* Dump the class references.  This forces the appropriate classes
     to be linked into the executable image, preserving unix archive
     semantics.  This can be removed when we move to a more dynamically
     linked environment.  */

  for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
    {
      handle_class_ref (chain);
      if (TREE_PURPOSE (chain))
	generate_classref_translation_entry (chain);
    }

  for (impent = imp_list; impent; impent = impent->next)
    handle_impent (impent);

  generate_strings ();
}

/* --- exceptions --- */

static GTY(()) tree objc_eh_personality_decl;

static tree
objc_eh_runtime_type (tree type)
{
  tree ident, eh_id, decl, str;

  if (type == error_mark_node
      || errorcount || sorrycount)
    {
      /* Use 'ErrorMarkNode' as class name when error_mark_node is found
	 to prevent an ICE.  Note that we know that the compiler will
	 terminate with an error and this 'ErrorMarkNode' class name will
	 never be actually used.  */
      ident = get_identifier ("ErrorMarkNode");
      goto make_err_class;
    }

  if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
    /* We don't want to identify 'id' for GNU. Instead, build a 0
       entry in the exceptions table.  */
    return null_pointer_node;

  if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
    {
#ifdef OBJCPLUS
      /* This routine is also called for c++ catch clauses; in which case,
	 we use the c++ typeinfo decl. */
      return build_eh_type_type (type);
#else
      error ("non-objective-c type %qT cannot be caught", type);
      ident = get_identifier ("ErrorMarkNode");
      goto make_err_class;
#endif
    }
  else
    ident = OBJC_TYPE_NAME (TREE_TYPE (type));

make_err_class:
  /* If this class was already referenced, then it will be output during
     meta-data emission, so we don't need to do it here.  */
  decl = get_objc_string_decl (ident, class_names);
  eh_id = add_objc_string (ident, class_names);
  if (!decl)
    {
      /* Not found ... so we need to build it - from the freshly-entered id.  */
      decl = get_objc_string_decl (ident, class_names);
      str = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
			     IDENTIFIER_POINTER (ident));
      /* We have to finalize this var here, because this might be called after
	 all the other metadata strings have been emitted.  */
      finish_var_decl (decl, str);
    }
  return eh_id;
}

static tree
objc_eh_personality (void)
{
  if (!objc_eh_personality_decl)
#ifndef OBJCPLUS
    objc_eh_personality_decl = build_personality_function  ("gnu_objc");
#else
    objc_eh_personality_decl = build_personality_function  ("gxx");
#endif
  return objc_eh_personality_decl;
}

/* -- interfaces --- */

static tree
build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED)
{
  tree t;
  vec<tree, va_gc> *parms;
  vec_alloc (parms, 1);
  /* A throw is just a call to the runtime throw function with the
     object as a parameter.  */
  parms->quick_push (throw_expr);
  t = build_function_call_vec (loc, vNULL, objc_exception_throw_decl, parms,
			       NULL);
  vec_free (parms);
  return add_stmt (t);
}

/* Build __builtin_eh_pointer.  */

static tree
objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED)
{
  tree t;
  t = builtin_decl_explicit (BUILT_IN_EH_POINTER);
  t = build_call_expr (t, 1, integer_zero_node);
  return fold_convert (objc_object_type, t);
}

static tree
begin_catch (struct objc_try_context **cur_try_context, tree type,
	     tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED)
{
  tree t;
  /* Record the data for the catch in the try context so that we can
     finalize it later.  */
  if (ellipsis)
    t = build_stmt (input_location, CATCH_EXPR, NULL, compound);
  else
    t = build_stmt (input_location, CATCH_EXPR, type, compound);
  (*cur_try_context)->current_catch = t;

  /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime.  */
  t = objc_build_exc_ptr (cur_try_context);
  t = convert (TREE_TYPE (decl), t);
  return build2 (MODIFY_EXPR, void_type_node, decl, t);
}

static void
finish_catch (struct objc_try_context **cur_try_context, tree current_catch)
{
  append_to_statement_list (current_catch, &((*cur_try_context)->catch_list));
}

static tree
finish_try_stmt (struct objc_try_context **cur_try_context)
{
  struct objc_try_context *c = *cur_try_context;
  tree stmt = c->try_body;
  if (c->catch_list)
    stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list);
  if (c->finally_body)
    stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body);
  return stmt;
}

#include "gt-objc-objc-gnu-runtime-abi-01.h"
