/* Next Runtime (ABI-0/1) private.
   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/>.  */

/* This implements the original NeXT ABI (0) used for m32 code and
   indicated by module version 6.  It also implements the small number
   of additions made for properties and optional protocol methods as
   ABI=1 (module version 7).  */

#include "config.h"
#include "system.h"
#include "coretypes.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 "target.h"
#include "c-family/c-target.h"
#include "tree-iterator.h"

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

/* NeXT ABI 0 and 1 private definitions.  */
#define DEF_CONSTANT_STRING_CLASS_NAME "NSConstantString"

#define TAG_GETCLASS			"objc_getClass"
#define TAG_GETMETACLASS		"objc_getMetaClass"

#define TAG_MSGSEND			"objc_msgSend"
#define TAG_MSGSENDSUPER		"objc_msgSendSuper"
#define TAG_MSGSEND_STRET		"objc_msgSend_stret"
#define TAG_MSGSENDSUPER_STRET		"objc_msgSendSuper_stret"

/* NeXT-specific tags.  */

#define TAG_MSGSEND_NONNIL		"objc_msgSendNonNil"
#define TAG_MSGSEND_NONNIL_STRET	"objc_msgSendNonNil_stret"
#define TAG_EXCEPTIONEXTRACT		"objc_exception_extract"
#define TAG_EXCEPTIONTRYENTER		"objc_exception_try_enter"
#define TAG_EXCEPTIONTRYEXIT		"objc_exception_try_exit"
#define TAG_EXCEPTIONMATCH		"objc_exception_match"
#define TAG_SETJMP			"_setjmp"

#define TAG_ASSIGNIVAR			"objc_assign_ivar"
#define TAG_ASSIGNGLOBAL		"objc_assign_global"
#define TAG_ASSIGNSTRONGCAST		"objc_assign_strongCast"

/* Branch entry points.  All that matters here are the addresses;
   functions with these names do not really exist in libobjc.  */

#define TAG_MSGSEND_FAST		"objc_msgSend_Fast"
#define TAG_ASSIGNIVAR_FAST		"objc_assign_ivar_Fast"

/* The version identifies which language generation and runtime the
   module (file) was compiled for, and is recorded in the module
   descriptor.  */
#define OBJC_VERSION			(flag_objc_abi >= 1 ? 7 : 6)

#define UTAG_CLASS_EXT			"_objc_class_ext"
#define UTAG_PROPERTY_LIST		"_prop_list_t"
#define UTAG_PROTOCOL_EXT		"_objc_protocol_extension"

#define CLS_HAS_CXX_STRUCTORS		0x2000L

/* rt_trees identifiers - shared between NeXT implementations.  These
   allow the FE to tag meta-data in a manner that survives LTO and can
   be used when the runtime requires that certain meta-data items
   appear in particular named sections.  */

#include "objc-next-metadata-tags.h"
extern GTY(()) tree objc_rt_trees[OCTI_RT_META_MAX];

static void next_runtime_01_initialize (void);

static tree next_runtime_abi_01_super_superclassfield_id (void);

static tree next_runtime_abi_01_class_decl (tree);
static tree next_runtime_abi_01_metaclass_decl (tree);
static tree next_runtime_abi_01_category_decl (tree);
static tree next_runtime_abi_01_protocol_decl (tree);
static tree next_runtime_abi_01_string_decl (tree, const char *, string_section);

static tree next_runtime_abi_01_get_class_reference (tree);
static tree next_runtime_abi_01_build_selector_reference (location_t, tree, tree);
static tree next_runtime_abi_01_get_protocol_reference (location_t, tree);
static tree next_runtime_abi_01_build_ivar_ref (location_t, tree, tree);
static tree next_runtime_abi_01_get_class_super_ref (location_t, struct imp_entry *, bool);
static tree next_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);

static tree next_runtime_abi_01_receiver_is_class_object (tree);
static void next_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **,
							tree, int, int);
static tree next_runtime_abi_01_build_objc_method_call (location_t, tree, tree,
							tree, tree, tree, int);
static bool next_runtime_abi_01_setup_const_string_class_decl (void);
static tree next_runtime_abi_01_build_const_string_constructor (location_t, tree, int);

static void objc_generate_v1_next_metadata (void);

static void build_next_objc_exception_stuff (void);
static tree objc_eh_runtime_type (tree type);
static tree objc_eh_personality (void);
static tree build_throw_stmt (location_t, tree, bool);
static tree objc_build_exc_ptr (struct objc_try_context **);
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_next_runtime_abi_01_init (objc_runtime_hooks *rthooks)
{
  if (flag_objc_exceptions
      && !flag_objc_sjlj_exceptions)
    {
      warning_at (UNKNOWN_LOCATION, OPT_Wall,
		"%<-fobjc-sjlj-exceptions%> is the only supported exceptions "
		"system for %<-fnext-runtime%> with %<-fobjc-abi-version%> < 2");
    }

  rthooks->initialize = next_runtime_01_initialize;
  rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME;
  rthooks->tag_getclass = TAG_GETCLASS;
  rthooks->super_superclassfield_ident = next_runtime_abi_01_super_superclassfield_id;

  rthooks->class_decl = next_runtime_abi_01_class_decl;
  rthooks->metaclass_decl = next_runtime_abi_01_metaclass_decl;
  rthooks->category_decl = next_runtime_abi_01_category_decl;
  rthooks->protocol_decl = next_runtime_abi_01_protocol_decl;
  rthooks->string_decl = next_runtime_abi_01_string_decl;

  rthooks->get_class_reference = next_runtime_abi_01_get_class_reference;
  rthooks->build_selector_reference = next_runtime_abi_01_build_selector_reference;
  rthooks->get_protocol_reference = next_runtime_abi_01_get_protocol_reference;
  rthooks->build_ivar_reference = next_runtime_abi_01_build_ivar_ref;
  rthooks->get_class_super_ref = next_runtime_abi_01_get_class_super_ref;
  rthooks->get_category_super_ref = next_runtime_abi_01_get_category_super_ref;

  rthooks->receiver_is_class_object = next_runtime_abi_01_receiver_is_class_object;
  rthooks->get_arg_type_list_base = next_runtime_abi_01_get_arg_type_list_base;
  rthooks->build_objc_method_call = next_runtime_abi_01_build_objc_method_call;

  rthooks->setup_const_string_class_decl =
				next_runtime_abi_01_setup_const_string_class_decl;
  rthooks->build_const_string_constructor =
				next_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_next_metadata;
  return true;
}

/* We need a way to convey what kind of meta-data are represented by a
   given variable, since each type is expected (by the runtime) to be
   found in a specific named section.  The solution must be usable
   with LTO.

   The scheme used for NeXT ABI 0/1 (partial matching of variable
   names) is not satisfactory for LTO & ABI-2.  We now tag ObjC
   meta-data with identification attributes in the front end.  The
   back-end may choose to act on these as it requires.  */

static void
next_runtime_abi_01_init_metadata_attributes (void)
{
  if (!objc_meta)
    objc_meta = get_identifier ("OBJC1META");

  if (!meta_base)
    meta_base = get_identifier ("V1_BASE");

  meta_class = get_identifier ("V1_CLAS");
  meta_metaclass = get_identifier ("V1_META");
  meta_category = get_identifier ("V1_CATG");
  meta_protocol = get_identifier ("V1_PROT");

  meta_clac_vars = get_identifier ("V1_CLCV");
  meta_clai_vars = get_identifier ("V1_CLIV");

  meta_clac_meth = get_identifier ("V1_CLCM");
  meta_clai_meth = get_identifier ("V1_CLIM");
  meta_catc_meth = get_identifier ("V1_CACM");
  meta_cati_meth = get_identifier ("V1_CAIM");
  meta_proto_cls_meth = get_identifier ("V1_PCLM");
  meta_proto_nst_meth = get_identifier ("V1_PNSM");

  meta_clas_prot = get_identifier ("V1_CLPR");
  meta_catg_prot = get_identifier ("V1_CAPR");

  meta_class_reference = get_identifier ("V1_CLRF");
  meta_proto_ref = get_identifier ("V1_PRFS");
  meta_sel_refs = get_identifier ("V1_SRFS");

  meta_class_name = get_identifier ("V1_CLSN");
  meta_meth_name = get_identifier ("V1_METN");
  meta_meth_type = get_identifier ("V1_METT");
  meta_prop_name_attr = get_identifier ("V1_STRG");

  meta_modules = get_identifier ("V1_MODU");
  meta_symtab = get_identifier ("V1_SYMT");
  meta_info = get_identifier ("V1_INFO");

  meta_proplist = get_identifier ("V1_PLST");
  meta_protocol_extension = get_identifier ("V1_PEXT");
  meta_class_extension = get_identifier ("V1_CEXT");

  meta_const_str = get_identifier ("V1_CSTR");
}

static void build_v1_class_template (void);
static void build_v1_category_template (void);
static void build_v1_protocol_template (void);

static void next_runtime_01_initialize (void)
{
  tree type;

#ifdef OBJCPLUS
  /* For all NeXT objc ABIs -fobjc-call-cxx-cdtors is on by
     default.  */
  if (!global_options_set.x_flag_objc_call_cxx_cdtors)
    global_options.x_flag_objc_call_cxx_cdtors = 1;
#endif

  /* Set up attributes to be attached to the meta-data so that they
     will be placed in the correct sections.  */
  next_runtime_abi_01_init_metadata_attributes ();

  if (flag_objc_abi >= 1)
    objc_prop_list_ptr = build_pointer_type (xref_tag (RECORD_TYPE,
					     get_identifier ("_prop_list_t")));

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

  build_v1_class_template ();
  build_super_template ();
  build_v1_protocol_template ();
  build_v1_category_template ();

  /* NB: In order to call one of the ..._stret (struct-returning)
     functions, the function *MUST* first be cast to a signature that
     corresponds to the actual ObjC method being invoked.  This is
     what is done by the build_objc_method_call() routine below.  */

  /* id objc_msgSend (id, SEL, ...); */
  /* id objc_msgSendNonNil (id, SEL, ...); */
  /* id objc_msgSend_stret (id, SEL, ...); */
  /* id objc_msgSendNonNil_stret (id, SEL, ...); */
  type = build_varargs_function_type_list (objc_object_type,
					   objc_object_type,
					   objc_selector_type,
					   NULL_TREE);

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

  umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
					   type, 0, NOT_BUILT_IN,
					    NULL, NULL_TREE);

  umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
					  type, 0, NOT_BUILT_IN,
					  NULL, NULL_TREE);

  umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
						 type, 0, NOT_BUILT_IN,
						 NULL, NULL_TREE);

  /* These can throw, because the function that gets called can throw
     in Obj-C++, or could itself call something that can throw even in
     Obj-C.  */
  TREE_NOTHROW (umsg_decl) = 0;
  TREE_NOTHROW (umsg_nonnil_decl) = 0;
  TREE_NOTHROW (umsg_stret_decl) = 0;
  TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;

 /* id objc_msgSend_Fast (id, SEL, ...)
	   __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
#ifdef OFFS_MSGSEND_FAST
  umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
					     type, 0, NOT_BUILT_IN,
					     NULL, NULL_TREE);
  TREE_NOTHROW (umsg_fast_decl) = 0;
  DECL_ATTRIBUTES (umsg_fast_decl)
	= tree_cons (get_identifier ("hard_coded_address"),
		     build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
		     NULL_TREE);
#else
  /* No direct dispatch available.  */
  umsg_fast_decl = umsg_decl;
#endif

  /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
  /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
  type = build_varargs_function_type_list (objc_object_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);
  umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
						    type, 0, NOT_BUILT_IN, 0,
						    NULL_TREE);
  TREE_NOTHROW (umsg_super_decl) = 0;
  TREE_NOTHROW (umsg_super_stret_decl) = 0;

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

  /* This is the type of all of the following functions
     objc_copyStruct().  */
  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_copyStruct (void *destination, const void *source,
	                  ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
  objc_copyStruct_decl = add_builtin_function ("objc_copyStruct",
						   type, 0, NOT_BUILT_IN,
						   NULL, NULL_TREE);
  TREE_NOTHROW (objc_copyStruct_decl) = 0;
  objc_getPropertyStruct_decl = NULL_TREE;
  objc_setPropertyStruct_decl = NULL_TREE;

  build_next_objc_exception_stuff ();
  if (flag_objc_exceptions && !flag_objc_sjlj_exceptions)
    using_eh_for_cleanups ();
  lang_hooks.eh_runtime_type = objc_eh_runtime_type;
  lang_hooks.eh_personality = objc_eh_personality;
}

/* --- templates --- */

/* 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 objc_cache *cache;
     struct _objc_protocol_list *protocols;
   #if ABI=1
     const char *ivar_layout;
     struct _objc_class_ext *ext;
   #else
     void *sel_id;
     void *gc_object_type;
    #endif
   }; */

/* The 'sel_id' & 'gc_object_type' fields are not used by the NeXT
   runtime.  We generate them for ABI==0 to maintain backward binary
   compatibility.  */

static void
build_v1_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 objc_cache *cache; */
  ptype = build_pointer_type (xref_tag (RECORD_TYPE,
					    get_identifier ("objc_cache")));
  add_field_decl (ptype, "cache", &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);

  if (flag_objc_abi >= 1)
    {
      /* const char *ivar_layout; */
      add_field_decl (const_string_type_node, "ivar_layout", &chain);

      /* struct _objc_class_ext *ext; */
      ptype = build_pointer_type (xref_tag (RECORD_TYPE,
					    get_identifier (UTAG_CLASS_EXT)));
      add_field_decl (ptype, "ext", &chain);
    }
  else
    {
      /* void *sel_id; */
      add_field_decl (build_pointer_type (void_type_node), "sel_id", &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;
   #if ABI=1
     uint32_t size;	// sizeof (struct _objc_category)
     struct _objc_property_list *instance_properties;  // category's own @property decl.
   #endif
   };   */

static void
build_v1_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);

  if (flag_objc_abi >= 1)
    {
      add_field_decl (integer_type_node, "size", &chain);

      /* struct _objc_property_list *instance_properties;
         This field describes a category's @property declarations.
         Properties from inherited protocols are not included.  */
      ptype = build_pointer_type (xref_tag (RECORD_TYPE,
					    get_identifier (UTAG_PROPERTY_LIST)));
      add_field_decl (ptype, "instance_properties", &chain);
    }
  objc_finish_struct (objc_category_template, decls);
}

/* Begin code generation for protocols...
   Modified for ObjC #1 extensions.  */

/* struct _objc_protocol
   {
   #if ABI=1
     struct _objc_protocol_extension *isa;
   #else
     struct _objc_class *isa;
   #endif

     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_v1_protocol_template (void)
{
  tree ptype, decls, *chain = NULL;

  objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));

  if (flag_objc_abi >= 1)
    /* struct _objc_protocol_extension *isa; */
    ptype = build_pointer_type (xref_tag (RECORD_TYPE,
					  get_identifier (UTAG_PROTOCOL_EXT)));
  else
    /* 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 tree
next_runtime_abi_01_super_superclassfield_id (void)
{
  if (!super_superclassfield_id)
    super_superclassfield_id = get_identifier ("super_class");
  return super_superclassfield_id;
}

static tree
next_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_class);
  return decl;
}

static tree
next_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_metaclass);
  return decl;
}

static tree
next_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_category);
  return decl;
}

static tree
next_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_protocol);
  return decl;
}

static tree
next_runtime_abi_01_string_decl (tree type, const char *name,  string_section where)
{
  tree var = start_var_decl (type, name);
  switch (where)
    {
      case class_names:
	OBJCMETA (var, objc_meta, meta_class_name);
	break;
      case meth_var_names:
	OBJCMETA (var, objc_meta, meta_meth_name);
	break;
      case meth_var_types:
	OBJCMETA (var, objc_meta, meta_meth_type);
	break;
      case prop_names_attr:
	OBJCMETA (var, objc_meta, meta_prop_name_attr);
	break;
      default:
	OBJCMETA (var, objc_meta, meta_base);
	break;
    }
  return var;
}

/* --- entry --- */

static GTY(()) int class_reference_idx;

static tree
build_class_reference_decl (void)
{
  tree decl;
  char buf[BUFSIZE];

  sprintf (buf, "_OBJC_ClassRefs_%d", class_reference_idx++);
  decl = start_var_decl (objc_class_type, buf);

  return decl;
}

static tree
next_runtime_abi_01_get_class_reference (tree ident)
{
  if (!flag_zero_link)
    {
      tree *chain;
      tree decl;

      for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
	if (TREE_VALUE (*chain) == ident)
	  {
	    if (! TREE_PURPOSE (*chain))
	      TREE_PURPOSE (*chain) = build_class_reference_decl ();

	    return TREE_PURPOSE (*chain);
	  }

      decl = build_class_reference_decl ();
      *chain = tree_cons (decl, ident, NULL_TREE);
      return decl;
    }
  else
    {
      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
next_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **argtypes,
					    tree meth, int context,
					    int superflag)
{
  tree receiver_type;

  if (superflag)
    receiver_type = objc_super_type;
  else 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);
}

static tree
next_runtime_abi_01_receiver_is_class_object (tree receiver)
{
  if (TREE_CODE (receiver) == VAR_DECL
      && IS_CLASS (TREE_TYPE (receiver)))
    {
      /* The receiver is a variable created by build_class_reference_decl.  */
      tree chain = cls_ref_chain ;
      /* Look up the identifier in the relevant chain.  */
      for (; chain; chain = TREE_CHAIN (chain))
	if (TREE_PURPOSE (chain) == receiver)
	  return TREE_VALUE (chain);
    }
  return NULL_TREE;
}

static tree
build_selector_reference_decl (tree ident)
{
  tree decl;
  char *t, buf[BUFSIZE];

  snprintf (buf, BUFSIZE, "_OBJC_SelRef_%s", IDENTIFIER_POINTER (ident));
  t = buf;
  while (*t)
    {
      if (*t==':')
        *t = '$'; /* Underscore would clash between foo:bar and foo_bar.  */
      t++;
    }
  decl = start_var_decl (objc_selector_type, buf);
  OBJCMETA (decl, objc_meta, meta_sel_refs);
  return decl;
}

static tree
next_runtime_abi_01_build_selector_reference (location_t loc ATTRIBUTE_UNUSED,
					      tree ident,
					      tree proto ATTRIBUTE_UNUSED)
{
  tree *chain = &sel_ref_chain;
  tree expr;

  while (*chain)
    {
      if (TREE_VALUE (*chain) == ident)
	return TREE_PURPOSE (*chain);

      chain = &TREE_CHAIN (*chain);
    }

  expr = build_selector_reference_decl (ident);

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

  return 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, sender_cast, method, t;
  tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
  vec<tree, va_gc> *parms;
  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);

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

  /* If we are returning a struct in memory, and the address
     of that memory location is passed as a hidden first
     argument, then change which messenger entry point this
     expr will call.  NB: Note that sender_cast remains
     unchanged (it already has a struct return type).  */
  if (!targetm.calls.struct_value_rtx (0, 0)
      && (TREE_CODE (ret_type) == RECORD_TYPE
	  || TREE_CODE (ret_type) == UNION_TYPE)
      && targetm.calls.return_in_memory (ret_type, 0))
    sender = (super_flag ? umsg_super_stret_decl
			 : flag_nil_receivers ? umsg_stret_decl
					      : umsg_nonnil_stret_decl);
  else
    sender = (super_flag ? umsg_super_decl
			 : (flag_nil_receivers  ? (flag_objc_direct_dispatch
							? umsg_fast_decl
							: umsg_decl)
						: umsg_nonnil_decl));
  method = build_fold_addr_expr_loc (loc, sender);

  /* Pass the object to the method.  */
  parms->quick_push (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
next_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)
{
  tree selector = next_runtime_abi_01_build_selector_reference (loc, sel_name,
								NULL_TREE);

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

static tree
next_runtime_abi_01_get_protocol_reference (location_t loc, tree p)
{
  tree expr;

  if (!PROTOCOL_FORWARD_DECL (p))
    PROTOCOL_FORWARD_DECL (p) = next_runtime_abi_01_protocol_decl (p);

  expr = build_unary_op (loc, ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
  return convert (objc_protocol_type, expr);
}

/* For ABI 0/1 and IVAR is just a fixed offset in the class struct.  */

static tree
next_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
next_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
next_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;

  if (!flag_zero_link)
    {
      super_class = objc_get_class_reference (super_name);

      if (!inst_meth)

	/* If we are in a class method, we must retrieve the
	   _metaclass_ for the current class, pointed at by
	   the class's "isa" pointer.  The following assumes that
	   "isa" is the first ivar in a class (which it must be).  */
	   super_class =
		build_indirect_ref (input_location,
				    build_c_cast (input_location,
					build_pointer_type (objc_class_type),
					super_class),
				    RO_UNARY_STAR);
      return super_class;
    }

  /* else do it the slow way.  */
  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 = objc_get{Meta}Class("CLASS_SUPER_NAME"); */
  return build_function_call (input_location,
			      super_class,
			      build_tree_list (NULL_TREE, super_name));
}

static bool
next_runtime_abi_01_setup_const_string_class_decl (void)
{
  if (!constant_string_global_id)
    {
      /* Hopefully, this should not represent a serious limitation.  */
      char buf[BUFSIZE];
      snprintf (buf, BUFSIZE, "_%sClassReference", constant_string_class_name);
      constant_string_global_id = get_identifier (buf);
    }

  string_class_decl = lookup_name (constant_string_global_id);

  return (string_class_decl != NULL_TREE);
}

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

  /* NeXT:   (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length })   */
  fields = TYPE_FIELDS (internal_const_str_type);
  CONSTRUCTOR_APPEND_ELT (v, fields,
			  build_unary_op (loc, ADDR_EXPR, string_class_decl, 0));

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

  /* ??? check if this should be long.  */
  fields = DECL_CHAIN (fields);
  CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
  constructor = objc_build_constructor (internal_const_str_type, v);

  var = build_decl (input_location, CONST_DECL, NULL, TREE_TYPE (constructor));
  DECL_INITIAL (var) = constructor;
  TREE_STATIC (var) = 1;
  DECL_CONTEXT (var) = NULL;
  OBJCMETA (var, objc_meta, meta_const_str);
  return var;
}

/* ---  metadata templates --- */

/* This routine builds the following type:
   struct _prop_t {
     const char * const name;			// property name
     const char * const attributes;		// comma-delimited, encoded,
						// property attributes
   };
*/

static GTY(()) tree objc_v1_property_template;

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

  prop_record = objc_start_struct (get_identifier ("_prop_t"));
  /* const char * name */
  decls = add_field_decl (string_type_node, "name", &chain);

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

  objc_finish_struct (prop_record, decls);
  return prop_record;
}

/* Build the following type:

  struct _objc_protocol_extension
    {
      uint32_t size;	// sizeof (struct _objc_protocol_extension)
      struct objc_method_list	*optional_instance_methods;
      struct objc_method_list   *optional_class_methods;
      struct objc_prop_list	*instance_properties;
    }
*/

static GTY(()) tree objc_protocol_extension_template;

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

  objc_protocol_extension_template =
	objc_start_struct (get_identifier (UTAG_PROTOCOL_EXT));

  /*  uint32_t size; */
  decls = add_field_decl (integer_type_node, "size", &chain);

  /* struct objc_method_list   *optional_instance_methods; */
  add_field_decl (objc_method_list_ptr, "optional_instance_methods", &chain);

  /* struct objc_method_list   *optional_class_methods; */
  add_field_decl (objc_method_list_ptr, "optional_class_methods", &chain);

  /* struct objc_prop_list     *instance_properties; */
  add_field_decl (objc_prop_list_ptr, "instance_properties", &chain);

  objc_finish_struct (objc_protocol_extension_template, decls);
}

/* This routine build following struct type:
   struct _objc_class_ext
     {
       uint32_t size;	// sizeof(struct _objc_class_ext)
       const char *weak_ivar_layout;
       struct _prop_list_t *properties;
     }
*/

static GTY(()) tree objc_class_ext_template;

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

  objc_class_ext_template = objc_start_struct (get_identifier (UTAG_CLASS_EXT));

  /* uint32_t size; */
  decls = add_field_decl (integer_type_node, "size", &chain);

  /* const char *weak_ivar_layout; */
  add_field_decl (const_string_type_node, "weak_ivar_layout", &chain);

  /* struct _prop_list_t *properties; */
  ptrt = build_pointer_type (xref_tag (RECORD_TYPE,
			     get_identifier(UTAG_PROPERTY_LIST)));
  add_field_decl (ptrt, "properties", &chain);

  objc_finish_struct (objc_class_ext_template, decls);
}

static void
build_metadata_templates (void)
{

  if (!objc_method_template)
    objc_method_template = build_method_template ();



}

/* --- emit metadata --- */

static tree
generate_v1_meth_descriptor_table (tree chain, tree protocol,
				   const char *prefix, tree attr)
{
  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);
  /* Get into the right section.  */
  OBJCMETA (decl, objc_meta, attr);
  finish_var_decl (decl, objc_build_constructor (method_list_template, v));
  return decl;
}

/* Build protocol ext =
   {size, opt_instance_meth, opt_class_meth, instance_props};
   or NULL_TREE if none are present.  */

static tree
generate_v1_objc_protocol_extension (tree proto_interface,
				     tree opt_instance_meth,
				     tree opt_class_meth,
				     tree instance_props)
{
  int size;
  location_t loc;
  vec<constructor_elt, va_gc> *v = NULL;
  tree decl, expr;
  char buf[BUFSIZE];

  /* If there are no extensions, then don't bother... */
  if (!opt_instance_meth && !opt_class_meth && !instance_props)
    return NULL_TREE;

  if (!objc_protocol_extension_template)
    build_v1_objc_protocol_extension_template ();

  /* uint32_t size */
  size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_protocol_extension_template));
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));

  /* Try for meaningful diagnostics.  */
  loc = DECL_SOURCE_LOCATION (PROTOCOL_FORWARD_DECL (proto_interface));

  /* struct objc_method_list *optional_instance_methods; */
  if (opt_instance_meth)
    expr = convert (objc_method_list_ptr,
		    build_unary_op (loc, ADDR_EXPR, opt_instance_meth, 0));
  else
    expr = convert (objc_method_list_ptr, null_pointer_node);

  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);

  /* struct objc_method_list *optional_class_methods; */
  if (opt_class_meth)
    expr = convert (objc_method_list_ptr,
		    build_unary_op (loc, ADDR_EXPR, opt_class_meth, 0));
  else
    expr = convert (objc_method_list_ptr, null_pointer_node);

  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
  /* struct objc_prop_list *instance_properties; */
  if (instance_props)
      expr = convert (objc_prop_list_ptr,
		      build_unary_op (loc, ADDR_EXPR, instance_props, 0));
  else
    expr = convert (objc_prop_list_ptr, null_pointer_node);

  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
  snprintf (buf, BUFSIZE, "_OBJC_ProtocolExt_%s",
	    IDENTIFIER_POINTER (PROTOCOL_NAME (proto_interface)));

  decl = start_var_decl (objc_protocol_extension_template, buf);
  expr = objc_build_constructor (TREE_TYPE (decl), v);
  OBJCMETA (decl, objc_meta, meta_protocol_extension);
  finish_var_decl (decl, expr);
  return decl;
}

/* This routine builds the following type:
   struct _prop_list_t {
     uint32_t entsize;			// sizeof (struct _prop_t)
     uint32_t prop_count;
     struct _prop_t prop_list [prop_count];
   }
*/

static tree
build_v1_property_list_template (tree list_type, int size)
{
  tree property_list_t_record;
  tree array_type, decls, *chain = NULL;

  /* anonymous.  */
  property_list_t_record = objc_start_struct (NULL_TREE);

  /* uint32_t const entsize */
  decls = add_field_decl (integer_type_node, "entsize", &chain);

  /* int prop_count */
  add_field_decl (integer_type_node, "prop_count", &chain);

  /* struct _prop_t prop_list[]; */
  array_type = build_sized_array_type (list_type, size);
  add_field_decl (array_type, "prop_list", &chain);

  objc_finish_struct (property_list_t_record, decls);
  return property_list_t_record;
}

/* This routine builds the initializer list to initialize the
   'struct _prop_t prop_list[]'  field of 'struct _prop_list_t' meta-data. */

static tree
build_v1_property_table_initializer (tree type, tree context)
{
  tree x;
  vec<constructor_elt, va_gc> *inits = NULL;

  if (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE)
    x = CLASS_PROPERTY_DECL (context);
  else
    x = IMPL_PROPERTY_DECL (context);

  for (; x; x = TREE_CHAIN (x))
    {
      vec<constructor_elt, va_gc> *elemlist = NULL;
      tree attribute, name_ident = PROPERTY_NAME (x);

      CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE,
			      add_objc_string (name_ident, prop_names_attr));

      attribute = objc_v2_encode_prop_attr (x);
      CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE,
			      add_objc_string (attribute, prop_names_attr));

      CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
			      objc_build_constructor (type, elemlist));
    }

  return objc_build_constructor (build_array_type (type, 0),inits);
}

/* This routine builds the 'struct _prop_list_t' variable declaration and
   initializes it with its initializer list. TYPE is 'struct _prop_list_t',
   NAME is the internal name of this variable, SIZE is number of properties
   for this class and LIST is the initializer list for its 'prop_list' field. */

static tree
generate_v1_property_table (tree context, tree klass_ctxt)
{
  tree x, decl, initlist, property_list_template;
  bool is_proto = false;
  vec<constructor_elt, va_gc> *inits = NULL;
  int init_val, size = 0;
  char buf[BUFSIZE];

  if (context)
    {
      gcc_assert (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE);
      x = CLASS_PROPERTY_DECL (context);
      is_proto = true;
    }
  else
    x = IMPL_PROPERTY_DECL (klass_ctxt);

  for (; x; x = TREE_CHAIN (x))
    size++;

  if (size == 0)
    return NULL_TREE;

  if (!objc_v1_property_template)
    objc_v1_property_template = build_v1_property_template ();

  property_list_template =
	build_v1_property_list_template (objc_v1_property_template,
					 size);
  initlist = build_v1_property_table_initializer (objc_v1_property_template,
						  is_proto ? context
							   : klass_ctxt);

  init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v1_property_template));
  if (is_proto)
    snprintf (buf, BUFSIZE, "_OBJC_ProtocolPropList_%s",
	      IDENTIFIER_POINTER (PROTOCOL_NAME (context)));
  else
    snprintf (buf, BUFSIZE, "_OBJC_ClassPropList_%s",
	      IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt)));

  decl = start_var_decl (property_list_template, buf);
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, init_val));
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
  x = objc_build_constructor (TREE_TYPE (decl), inits);
  OBJCMETA (decl, objc_meta, meta_proplist);
  finish_var_decl (decl, x);
  return decl;
}

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

  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)));
      attr = meta_proto_ref;
      break;
    case CLASS_INTERFACE_TYPE:
      snprintf (buf, BUFSIZE, "_OBJC_ClassProtocols_%s",
		IDENTIFIER_POINTER (CLASS_NAME (i_or_p)));
      attr = meta_clas_prot;
      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)));
      attr = meta_catg_prot;
      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, attr);
  finish_var_decl (refs_decl,
                   objc_build_constructor (TREE_TYPE (refs_decl), v));

  return refs_decl;
}

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

  if (!objc_protocol_extension_template)
    build_v1_objc_protocol_extension_template ();

  /* TODO: find a better representation of location from the inputs.  */
  loc = UNKNOWN_LOCATION;
  ttyp = build_pointer_type (objc_protocol_extension_template);
  /* Instead of jamming the protocol version number into the isa, we pass
     either a pointer to the protocol extension - or NULL.  */
  if (protocol_ext)
    expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, protocol_ext, 0));
  else
    expr = convert (ttyp, null_pointer_node);

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

/* An updated version of generate_protocols () that emit the protocol
   extension for ABI=1.  */

/* 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 NeXT runtime fixes up all protocols at program startup time,
   before main() is entered.  It uses a low-level trick to look up all
   those symbols, then loops on them and fixes them up.  */

/* TODO: finish getting rid of passing stuff around in globals.  */

static GTY(()) tree V1_Protocol_OPT_NST_METHODS_decl;
static GTY(()) tree V1_Protocol_OPT_CLS_METHODS_decl;
static GTY(()) tree V1_ProtocolExt_decl;
static GTY(()) tree V1_Property_decl;

static void
generate_v1_protocols (void)
{
  tree p;

  /* 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 decl, encoding, initlist, protocol_name_expr;
      tree refs_type, refs_decl, refs_expr;
      location_t loc;
      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 = TREE_CHAIN (nst_methods);
	}

      UOBJC_INSTANCE_METHODS_decl =
	generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p,
					   "_OBJC_ProtocolInstanceMethods",
					   meta_proto_nst_meth);

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

	  cls_methods = TREE_CHAIN (cls_methods);
	}

      UOBJC_CLASS_METHODS_decl =
	generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p,
					   "_OBJC_ProtocolClassMethods",
					   meta_proto_cls_meth);

      /* There should be no optional methods for ABI-0 - but we need to
         check all this here before the lists are made.  */
      nst_methods = PROTOCOL_OPTIONAL_NST_METHODS (p);
      while (nst_methods)
        {
          if (! METHOD_ENCODING (nst_methods))
            {
              encoding = encode_method_prototype (nst_methods);
              METHOD_ENCODING (nst_methods) = encoding;
            }
          nst_methods = TREE_CHAIN (nst_methods);
        }

      V1_Protocol_OPT_NST_METHODS_decl =
	generate_v1_meth_descriptor_table (PROTOCOL_OPTIONAL_NST_METHODS (p), p,
					   "_OBJC_OptionalProtocolInstanceMethods",
					   meta_proto_nst_meth);

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

          cls_methods = TREE_CHAIN (cls_methods);
        }

      V1_Protocol_OPT_CLS_METHODS_decl =
	generate_v1_meth_descriptor_table (PROTOCOL_OPTIONAL_CLS_METHODS (p), p,
					   "_OBJC_OptionalProtocolClassMethods",
					   meta_proto_cls_meth);

      if (PROTOCOL_LIST (p))
	refs_decl = generate_v1_protocol_list (p, objc_implementation_context);
      else
	refs_decl = 0;

      /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
      protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
      /* TODO: more locations to be fixed up... */
      loc = UNKNOWN_LOCATION;
      refs_type =
	build_pointer_type (build_pointer_type (objc_protocol_template));
      if (refs_decl)
	refs_expr = convert (refs_type,
			     build_unary_op (loc, ADDR_EXPR, refs_decl, 0));
      else
        refs_expr = convert (refs_type, null_pointer_node);

      if (flag_objc_abi < 1)
	{
	  /* Original ABI.  */
	  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);
          continue;
	}

      /* else - V1 extensions.  */

      V1_Property_decl =
		generate_v1_property_table (p, NULL_TREE);

      V1_ProtocolExt_decl =
	generate_v1_objc_protocol_extension (p,
					     V1_Protocol_OPT_NST_METHODS_decl,
					     V1_Protocol_OPT_CLS_METHODS_decl,
					     V1_Property_decl);

      initlist = build_v1_protocol_initializer (TREE_TYPE (decl),
						protocol_name_expr, refs_expr,
						UOBJC_INSTANCE_METHODS_decl,
						UOBJC_CLASS_METHODS_decl,
						V1_ProtocolExt_decl);
      finish_var_decl (decl, initlist);
    }
}

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

  if (!chain || !name || !(size = list_length (chain)))
    return NULL_TREE;

  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, attr);
  finish_var_decl (decl,
		   objc_build_constructor (TREE_TYPE (decl), v));

  return decl;
}

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

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

  if (flag_objc_abi >= 1)
    {
      int val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_category_template));
      expr = build_int_cst (NULL_TREE, val);
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
      ltyp = objc_prop_list_ptr;
      if (property_list)
	expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_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> = { ... }; */
/* TODO: get rid of passing stuff around in globals.  */
static void
generate_v1_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;
  location_t loc;
  char buf[BUFSIZE];

  cat_decl = impent->class_decl;
  loc = DECL_SOURCE_LOCATION (cat_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_v1_protocol_list (category, cat);
    }
  else
    protocol_decl = 0;

  if (flag_objc_abi >= 1)
    V1_Property_decl = generate_v1_property_table (NULL_TREE, cat);
  else
    V1_Property_decl = NULL_TREE;

  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,
					      meta_cati_meth);
    }

  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,
					       meta_catc_meth);
    }

  initlist = build_v1_category_initializer (TREE_TYPE (cat_decl),
					    cat_name_expr, class_name_expr,
					    inst_methods, class_methods,
					    protocol_decl, V1_Property_decl,
					    loc);

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

/* This routine builds the class extension used by v1 NeXT.  */

static tree
generate_objc_class_ext (tree property_list, tree context)
{
  tree decl, expr, ltyp;
  tree weak_ivar_layout_tree;
  int size;
  location_t loc;
  vec<constructor_elt, va_gc> *v = NULL;
  char buf[BUFSIZE];

  /* TODO: pass the loc in or find it from args.  */
  loc = UNKNOWN_LOCATION;

  /* const char *weak_ivar_layout
     TODO: Figure the ivar layouts out... */
  weak_ivar_layout_tree = NULL_TREE;

  if (!property_list && !weak_ivar_layout_tree)
    return NULL_TREE;

  if (!objc_class_ext_template)
    build_objc_class_ext_template ();

  /* uint32_t size */
  size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_class_ext_template));
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));

  ltyp = const_string_type_node;
  if (weak_ivar_layout_tree)
    expr = convert (ltyp, weak_ivar_layout_tree);
  else
    expr = convert (ltyp, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);

  /* struct _prop_list_t *properties; */
  ltyp = objc_prop_list_ptr;
  if (property_list)
     expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0));
  else
    expr = convert (ltyp, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);

  snprintf (buf, BUFSIZE, "_OBJC_ClassExt_%s",
	    IDENTIFIER_POINTER (CLASS_NAME (context)));
  decl = start_var_decl (objc_class_ext_template, buf);
  expr = objc_build_constructor (TREE_TYPE (decl), v);
  OBJCMETA (decl, objc_meta, meta_class_extension);
  finish_var_decl (decl, expr);
  return 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 objc_cache *cache;
     struct objc_protocol_list *protocols;
  #if ABI >= 1
     const char *ivar_layout;
     struct _objc_class_ext *ext;
  #else
     void *sel_id;
     void *gc_object_type;
  #endif
   }; */

static tree
build_v1_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 class_ext)
{
  tree expr, ltyp;
  location_t loc;
  vec<constructor_elt, va_gc> *v = NULL;

  /* TODO: fish the location out of the input data.  */
  loc = UNKNOWN_LOCATION;

  /* 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 = */
  ltyp = objc_ivar_list_ptr;
  if (ivar_list)
    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, ivar_list, 0));
  else
    expr = convert (ltyp, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);

  /* objc_method_list = */
  ltyp = objc_method_list_ptr;
  if (dispatch_table)
    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, dispatch_table, 0));
  else
    expr = convert (ltyp, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);

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

  /* 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);

  if (flag_objc_abi >= 1)
    {
      /* TODO: figure out the ivar_layout stuff.  */
      expr = convert (const_string_type_node, null_pointer_node);
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
      if (!objc_class_ext_template)
	build_objc_class_ext_template ();
      ltyp = build_pointer_type (objc_class_ext_template);
      if (class_ext)
	expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_ext, 0));
      else
	expr = convert (ltyp, null_pointer_node);
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
    }
  else
    {
      /* sel_id = NULL */
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, null_pointer_node);

      /* gc_object_type = NULL */
      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, null_pointer_node);
    }
  return objc_build_constructor (type, v);
}

static tree
generate_ivars_list (tree chain, const char *name, tree attr)
{
  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, attr);
  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_v1_class_structs (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 class_ext_decl = NULL_TREE, props = NULL_TREE;
  tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
  tree chain, inst_ivars = NULL_TREE, class_ivars = NULL_TREE;
  int cls_flags;
  location_t loc;
  char buf[BUFSIZE];

/*  objc_implementation_context = impent->imp_context;
  implementation_template = impent->imp_template;*/
  class_decl = impent->class_decl;
  meta_decl = impent->meta_decl;
  cls_flags = impent->has_cxx_cdtors ? CLS_HAS_CXX_STRUCTORS : 0 ;

  loc = DECL_SOURCE_LOCATION (impent->class_decl);

  if (flag_objc_abi >= 1)
    {
      /* ABI=1 additions.  */
      props = generate_v1_property_table (NULL_TREE, impent->imp_context);
      class_ext_decl = generate_objc_class_ext (props, impent->imp_context);
    }

  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);
      super_expr = add_objc_string (my_super_id, class_names);
    }
  else
    {
      /* No super class.  */
      my_root_id = CLASS_NAME (impent->imp_template);
      super_expr = null_pointer_node;
    }

  /* Install class `isa' and `super' pointers at runtime.  */
  cast_type = build_pointer_type (objc_class_template);
  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_v1_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, meta_clac_meth);
    }

  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, meta_clac_vars);
    }
  /* TODO: get rid of hidden passing of stuff in globals.  */
  /* UOBJC_INSTANCE/CLASS_Variables_decl made in generate_ivarlists().  */

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

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

  initlist = build_v1_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, NULL_TREE);

  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, meta_clai_meth);
    }

  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, meta_clai_vars);
    }

  initlist = build_v1_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, class_ext_decl);

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

/* --- Output NeXT V1 Metadata --- */

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

static tree
init_def_list (tree type)
{
  tree expr;
  location_t loc;
  struct imp_entry *impent;
  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);
	  }
      }

  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, *chain = NULL;

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

  if (imp_count || cat_count)
    {
      /* void *defs[imp_count + cat_count (+ 1)]; */
      /* NB: The index is one less than the size of the array.  */
      int index = imp_count + cat_count;
      tree array_type = build_sized_array_type (ptr_type_node, index);
      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)
{
  vec<constructor_elt, va_gc> *v = NULL;

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

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

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

  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			  convert (build_pointer_type (objc_selector_type),
							integer_zero_node));

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

  if (imp_count || cat_count)
    {
      tree 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");
  /* Allow the runtime to mark meta-data such that it can be assigned to target
     specific sections by the back-end.  */
  OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_symtab);
  finish_var_decl (UOBJC_SYMBOLS_decl,
		   init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
}

/* Any target implementing NeXT ObjC m32 ABI has to ensure that objects
   refer to, and define, symbols that enforce linkage of classes into the
   executable image, preserving unix archive semantics.

   At present (4.8), the only targets implementing this are Darwin; these
   use top level asms to implement a scheme (see config/darwin-c.c).  The
   latter method is a hack, but compatible with LTO see also PR48109 for
   further discussion and other possible methods.  */

static void
handle_next_class_ref (tree chain ATTRIBUTE_UNUSED)
{
  if (targetcm.objc_declare_unresolved_class_reference)
    {
      const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
      char *string = (char *) alloca (strlen (name) + 30);
      sprintf (string, ".objc_class_name_%s", name);
      targetcm.objc_declare_unresolved_class_reference (string);
    }
}

static void
handle_next_impent (struct imp_entry *impent ATTRIBUTE_UNUSED)
{
  if (targetcm.objc_declare_class_definition)
    {
      char buf[BUFSIZE];

      switch (TREE_CODE (impent->imp_context))
	{
	  case CLASS_IMPLEMENTATION_TYPE:
	    snprintf (buf, BUFSIZE, ".objc_class_name_%s",
		      IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
	    break;
	  case CATEGORY_IMPLEMENTATION_TYPE:
	    snprintf (buf, BUFSIZE, "*.objc_category_name_%s_%s",
		      IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)),
		      IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)));
	    break;
	  default:
	    return;
	}
      targetcm.objc_declare_class_definition (buf);
    }
}

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_class_reference);
  finish_var_decl (decl, expr);
  return;
}

static void
objc_generate_v1_next_metadata (void)
{
  struct imp_entry *impent;
  tree chain, attr;
  long vers;

  /* FIXME: Make sure that we generate no metadata if there is nothing
     to put into it.  */

  if (objc_static_instances)
    gcc_unreachable (); /* Not for NeXT */

  build_metadata_templates ();
  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_v1_class_structs (impent);
      else
	generate_v1_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_next_selector_translation_table ();

  if (protocol_chain)
    generate_v1_protocols ();

  /* Pass summary information to the runtime.  */
  if (imp_count || cat_count)
    generate_objc_symtab_decl ();

  vers = OBJC_VERSION;
  attr = build_tree_list (objc_meta, meta_modules);
  build_module_descriptor (vers, attr);

  /* Dump the class references.  This forces the appropriate classes
     to be linked into the executable image, preserving unix archive
     semantics.  */
  for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
    {
      handle_next_class_ref (chain);
      if (TREE_PURPOSE (chain))
	generate_classref_translation_entry (chain);
    }

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

  /* Emit the strings tables.  */
  generate_strings ();
}

/* --- exceptions stuff --- */

/* Predefine the following data type:

   struct _objc_exception_data
   {
     int buf[OBJC_JBLEN];
     void *pointers[4];
   }; */

/* The following yuckiness should prevent users from having to #include
   <setjmp.h> in their code... */

/* Define to a harmless positive value so the below code doesn't die.  */
#ifndef OBJC_JBLEN
#define OBJC_JBLEN 18
#endif

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

  objc_exception_data_template
    = objc_start_struct (get_identifier (UTAG_EXCDATA));

  /* int buf[OBJC_JBLEN]; */

  temp_type = build_sized_array_type (integer_type_node, OBJC_JBLEN);
  decls = add_field_decl (temp_type, "buf", &chain);

  /* void *pointers[4]; */

  temp_type = build_sized_array_type (ptr_type_node, 4);
  add_field_decl (temp_type, "pointers", &chain);

  objc_finish_struct (objc_exception_data_template, decls);

  /* int _setjmp(...); */
  /* If the user includes <setjmp.h>, this shall be superseded by
     'int _setjmp(jmp_buf);' */
  temp_type = build_varargs_function_type_list (integer_type_node, NULL_TREE);
  objc_setjmp_decl
    = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);

  /* id objc_exception_extract(struct _objc_exception_data *); */
  temp_type
    = build_function_type_list (objc_object_type,
                                build_pointer_type (objc_exception_data_template),
                                NULL_TREE);
  objc_exception_extract_decl
    = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
			    NULL_TREE);
  /* void objc_exception_try_enter(struct _objc_exception_data *); */
  /* void objc_exception_try_exit(struct _objc_exception_data *); */
  temp_type
    = build_function_type_list (void_type_node,
                                build_pointer_type (objc_exception_data_template),
                                NULL_TREE);
  objc_exception_try_enter_decl
    = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
			    NULL_TREE);
  objc_exception_try_exit_decl
    = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
			    NULL_TREE);

  /* int objc_exception_match(id, id); */
  temp_type
    = build_function_type_list (integer_type_node,
                                objc_object_type, objc_object_type, NULL_TREE);
  objc_exception_match_decl
    = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
			    NULL_TREE);

  /* id objc_assign_ivar (id, id, unsigned int); */
  /* id objc_assign_ivar_Fast (id, id, unsigned int)
       __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
  temp_type
    = build_function_type_list (objc_object_type,
                                objc_object_type,
                                objc_object_type,
                                unsigned_type_node,
                                NULL_TREE);
  objc_assign_ivar_decl
    = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
			    NULL, NULL_TREE);
#ifdef OFFS_ASSIGNIVAR_FAST
  objc_assign_ivar_fast_decl
    = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
			    NOT_BUILT_IN, NULL, NULL_TREE);
  DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
    = tree_cons (get_identifier ("hard_coded_address"),
		 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
		 NULL_TREE);
#else
  /* Default to slower ivar method.  */
  objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
#endif

  /* id objc_assign_global (id, id *); */
  /* id objc_assign_strongCast (id, id *); */
  temp_type = build_function_type_list (objc_object_type,
                                        objc_object_type,
                                        build_pointer_type (objc_object_type),
                                        NULL_TREE);
  objc_assign_global_decl
	= add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
				NULL_TREE);
  objc_assign_strong_cast_decl
	= add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
				NULL_TREE);
}

/* --- NeXT V1 SJLJ Exceptions --- */

/* Build "objc_exception_try_exit(&_stack)".  */

static tree
next_sjlj_build_try_exit (struct objc_try_context **ctcp)
{
  tree t;
  t = build_fold_addr_expr_loc (input_location, (*ctcp)->stack_decl);
  t = tree_cons (NULL, t, NULL);
  t = build_function_call (input_location,
			   objc_exception_try_exit_decl, t);
  return t;
}

/* Build
	objc_exception_try_enter (&_stack);
	if (_setjmp(&_stack.buf))
	  ;
	else
	  ;
   Return the COND_EXPR.  Note that the THEN and ELSE fields are left
   empty, ready for the caller to fill them in.  */

static tree
next_sjlj_build_enter_and_setjmp (struct objc_try_context **ctcp)
{
  tree t, enter, sj, cond;

  t = build_fold_addr_expr_loc (input_location, (*ctcp)->stack_decl);
  t = tree_cons (NULL, t, NULL);
  enter = build_function_call (input_location,
			       objc_exception_try_enter_decl, t);

  t = objc_build_component_ref ((*ctcp)->stack_decl,
				get_identifier ("buf"));
  t = build_fold_addr_expr_loc (input_location, t);
#ifdef OBJCPLUS
  /* Convert _setjmp argument to type that is expected.  */
  if (prototype_p (TREE_TYPE (objc_setjmp_decl)))
    t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
  else
    t = convert (ptr_type_node, t);
#else
  t = convert (ptr_type_node, t);
#endif
  t = tree_cons (NULL, t, NULL);
  sj = build_function_call (input_location,
			    objc_setjmp_decl, t);

  cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
  cond = c_common_truthvalue_conversion (input_location, cond);

  return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
}

/* Build:

   DECL = objc_exception_extract(&_stack); */

static tree
next_sjlj_build_exc_extract (struct objc_try_context **ctcp, tree decl)
{
  tree t;

  t = build_fold_addr_expr_loc (input_location, (*ctcp)->stack_decl);
  t = tree_cons (NULL, t, NULL);
  t = build_function_call (input_location,
			   objc_exception_extract_decl, t);
  t = convert (TREE_TYPE (decl), t);
  t = build2 (MODIFY_EXPR, void_type_node, decl, t);

  return t;
}

/* Build
	if (objc_exception_match(obj_get_class(TYPE), _caught)
	  BODY
	else if (...)
	  ...
	else
	  {
	    _rethrow = _caught;
	    objc_exception_try_exit(&_stack);
	  }
   from the sequence of CATCH_EXPRs in the current try context.  */

static tree
next_sjlj_build_catch_list (struct objc_try_context **ctcp)
{
  tree_stmt_iterator i = tsi_start ((*ctcp)->catch_list);
  tree catch_seq, t;
  tree *last = &catch_seq;
  bool saw_id = false;

  for (; !tsi_end_p (i); tsi_next (&i))
    {
      tree stmt = tsi_stmt (i);
      tree type = CATCH_TYPES (stmt);
      tree body = CATCH_BODY (stmt);

      if (type != error_mark_node
	  && objc_is_object_id (TREE_TYPE (type)))
	{
	  *last = body;
	  saw_id = true;
	  break;
	}
      else
	{
	  tree args, cond;

	  if (type == error_mark_node)
	    cond = error_mark_node;
	  else
	    {
	      args = tree_cons (NULL, (*ctcp)->caught_decl, NULL);
	      t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
	      args = tree_cons (NULL, t, args);
	      t = build_function_call (input_location,
				       objc_exception_match_decl, args);
	      cond = c_common_truthvalue_conversion (input_location, t);
	    }
	  t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
	  SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));

	  *last = t;
	  last = &COND_EXPR_ELSE (t);
	}
    }

  if (!saw_id)
    {
      t = build2 (MODIFY_EXPR, void_type_node, (*ctcp)->rethrow_decl,
		  (*ctcp)->caught_decl);
      SET_EXPR_LOCATION (t, (*ctcp)->end_catch_locus);
      append_to_statement_list (t, last);

      t = next_sjlj_build_try_exit (ctcp);
      SET_EXPR_LOCATION (t, (*ctcp)->end_catch_locus);
      append_to_statement_list (t, last);
    }

  return catch_seq;
}

/* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
   exception handling.  We aim to build:

	{
	  struct _objc_exception_data _stack;
	  id _rethrow = 0;
	  try
	    {
	      objc_exception_try_enter (&_stack);
	      if (_setjmp(&_stack.buf))
	        {
		  id _caught = objc_exception_extract(&_stack);
		  objc_exception_try_enter (&_stack);
		  if (_setjmp(&_stack.buf))
		    _rethrow = objc_exception_extract(&_stack);
		  else
		    CATCH-LIST
	        }
	      else
		TRY-BLOCK
	    }
	  finally
	    {
	      if (!_rethrow)
		objc_exception_try_exit(&_stack);
	      FINALLY-BLOCK
	      if (_rethrow)
		objc_exception_throw(_rethrow);
	    }
	}

   If CATCH-LIST is empty, we can omit all of the block containing
   "_caught" except for the setting of _rethrow.  Note the use of
   a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
   but handles goto and other exits from the block.  */

static tree
next_sjlj_build_try_catch_finally (struct objc_try_context **ctcp)
{
  tree rethrow_decl, stack_decl, t;
  tree catch_seq, try_fin, bind;
  struct objc_try_context *cur_try_context = *ctcp;

  /* Create the declarations involved.  */
  t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
  stack_decl = objc_create_temporary_var (t, NULL);
  cur_try_context->stack_decl = stack_decl;

  rethrow_decl = objc_create_temporary_var (objc_object_type, NULL);
  cur_try_context->rethrow_decl = rethrow_decl;
  TREE_CHAIN (rethrow_decl) = stack_decl;

  /* Build the outermost variable binding level.  */
  bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
  SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
  TREE_SIDE_EFFECTS (bind) = 1;

  /* Initialize rethrow_decl.  */
  t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
	      convert (objc_object_type, null_pointer_node));
  SET_EXPR_LOCATION (t, cur_try_context->try_locus);
  append_to_statement_list (t, &BIND_EXPR_BODY (bind));

  /* Build the outermost TRY_FINALLY_EXPR.  */
  try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
  SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
  TREE_SIDE_EFFECTS (try_fin) = 1;
  append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));

  /* Create the complete catch sequence.  */
  if (cur_try_context->catch_list)
    {
      tree caught_decl = objc_build_exc_ptr (ctcp);
      catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
      TREE_SIDE_EFFECTS (catch_seq) = 1;

      t = next_sjlj_build_exc_extract (ctcp, caught_decl);
      append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));

      t = next_sjlj_build_enter_and_setjmp (ctcp);
      COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (ctcp, rethrow_decl);
      COND_EXPR_ELSE (t) = next_sjlj_build_catch_list (ctcp);
      append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
    }
  else
    catch_seq = next_sjlj_build_exc_extract (ctcp, rethrow_decl);
  SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);

  /* Build the main register-and-try if statement.  */
  t = next_sjlj_build_enter_and_setjmp (ctcp);
  SET_EXPR_LOCATION (t, cur_try_context->try_locus);
  COND_EXPR_THEN (t) = catch_seq;
  COND_EXPR_ELSE (t) = cur_try_context->try_body;
  TREE_OPERAND (try_fin, 0) = t;

  /* Build the complete FINALLY statement list.  */
  t = next_sjlj_build_try_exit (ctcp);
  t = build_stmt (input_location, COND_EXPR,
		  c_common_truthvalue_conversion
		    (input_location, rethrow_decl),
		  NULL, t);
  SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
  append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));

  append_to_statement_list (cur_try_context->finally_body,
			    &TREE_OPERAND (try_fin, 1));

  t = tree_cons (NULL, rethrow_decl, NULL);
  t = build_function_call (input_location,
			   objc_exception_throw_decl, t);
  t = build_stmt (input_location, COND_EXPR,
		  c_common_truthvalue_conversion (input_location,
						  rethrow_decl),
		  t, NULL);
  SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
  append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));

  return bind;
}

/* We do not expect this to be used at the moment.
   If (a) it is possible to implement unwinder exceptions.
      (b) we do it... then it might be possibly useful.
*/
static GTY(()) tree objc_eh_personality_decl;

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

  gcc_unreachable ();
  if (type == error_mark_node)
    {
      /* 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)))
    {
      ident = get_identifier ("id");
      goto make_err_class;
    }

  if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
    {
#ifdef OBJCPLUS
      /* This routine is also called for c++'s catch clause; in which case,
	 we use c++'s 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;
}

/* For NeXT ABI 0 and 1, the personality routines are just those of the 
   underlying language.  */

static tree
objc_eh_personality (void)
{
  if (!objc_eh_personality_decl)
#ifndef OBJCPLUS
    objc_eh_personality_decl = build_personality_function ("gcc");
#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, or the moral equivalent.  In the case
   of Darwin, we'll arrange for it to be initialized (and associated
   with a binding) later.  */

static tree
objc_build_exc_ptr (struct objc_try_context **cur_try_context)
{
  if (flag_objc_sjlj_exceptions)
    {
      tree var = (*cur_try_context)->caught_decl;
      if (!var)
	{
	  var = objc_create_temporary_var (objc_object_type, NULL);
	  (*cur_try_context)->caught_decl = var;
	}
      return var;
    }
  else
    {
      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.  We treat ellipsis the same way as catching
     with 'id xyz'.  */
  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)
{
  tree stmt;
  struct objc_try_context *c = *cur_try_context;
  /* If we're doing Darwin setjmp exceptions, build the big nasty.  */
  if (flag_objc_sjlj_exceptions)
    {
      bool save = in_late_binary_op;
      in_late_binary_op = true;
      if (!c->finally_body)
	{
	  c->finally_locus = input_location;
	  c->end_finally_locus = input_location;
	}
      stmt = next_sjlj_build_try_catch_finally (cur_try_context);
      in_late_binary_op = save;
    }
  else
    /* This doesn't happen at the moment... but maybe one day... */
    {
      /* Otherwise, nest the CATCH inside a FINALLY.  */
      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-next-runtime-abi-01.h"
