/* Next Runtime (ABI-0/1) private.
   Copyright (C) 2011-2021 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"
#include "opts.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%> "
		"argument less than 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 (!OPTION_SET_P (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)));

  /* SEL typedef.  */
  type = lang_hooks.decls.pushdecl (build_decl (input_location,
						TYPE_DECL,
						objc_selector_name,
						objc_selector_type));
  suppress_warning (type);

  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"
