/* Next Runtime (ABI-2) private.
   Copyright (C) 2011-2021 Free Software Foundation, Inc.

   Contributed by Iain Sandoe and based, in part, on an implementation in
   'branches/apple/trunk' contributed by Apple Computer Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* The NeXT ABI2 is used for m64 implementations on Darwin/OSX machines.

   This version is intended to match (logically) the output of Apple's
   4.2.1 compiler.  */

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

#ifdef OBJCPLUS
#include "cp/cp-tree.h"
#else
#include "c/c-tree.h"
#include "c/c-lang.h"
#endif
#include "langhooks.h"
#include "c-family/c-objc.h"
#include "objc-act.h"

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

#include "target.h"
#include "tree-iterator.h"
#include "opts.h"

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

/* ABI 2 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_MSGSENDID		"objc_msgSendId"
#define TAG_MSGSENDSUPER	"objc_msgSendSuper2"
#define TAG_MSGSEND_STRET	"objc_msgSend_stret"
#define TAG_MSGSENDID_STRET	"objc_msgSendId_stret"
#define TAG_MSGSENDSUPER_STRET	"objc_msgSendSuper2_stret"

#define USE_FIXUP_BEFORE	100600
#define TAG_FIXUP		"_fixup"


#define TAG_NEXT_EHVTABLE_NAME	"objc_ehtype_vtable"
#define TAG_V2_EH_TYPE		"objc_ehtype_t"

#define UTAG_V2_CLASS		"_class_t"
#define UTAG_V2_CLASS_RO	"_class_ro_t"
#define UTAG_V2_PROTOCOL	"_protocol_t"
#define UTAG_V2_PROTOCOL_LIST	"_protocol_list_t"

#define UTAG_V2_EH_TYPE		"_objc_ehtype_t"

#define OBJC2_CLS_HAS_CXX_STRUCTORS	0x0004L

enum objc_v2_tree_index
{
  /* Templates.  */
  OCTI_V2_CLS_TEMPL,
  OCTI_V2_CAT_TEMPL,
  OCTI_V2_CLS_RO_TEMPL,
  OCTI_V2_PROTO_TEMPL,
  OCTI_V2_IVAR_TEMPL,
  OCTI_V2_IVAR_LIST_TEMPL,
  OCTI_V2_MESSAGE_REF_TEMPL,
  OCTI_V2_SUPER_MESSAGE_REF_TEMPL,

  OCTI_V2_MESSAGE_SELECTOR_TYPE,
  OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE,
  OCTI_V2_IMP_TYPE,
  OCTI_V2_SUPER_IMP_TYPE,

  OCTI_V2_CACHE_DECL,
  OCTI_V2_VTABLE_DECL,

  OCTI_V2_PROPERTY_TEMPL,

  /* V2 messaging.  */
  OCTI_V2_UMSG_FIXUP_DECL,
  OCTI_V2_UMSG_STRET_FIXUP_DECL,
  OCTI_V2_UMSG_ID_FIXUP_DECL,
  OCTI_V2_UMSG_ID_STRET_FIXUP_DECL,
  OCTI_V2_UMSG_SUPER2_FIXUP_DECL,
  OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL,

  /* Exceptions - related.  */
  OCTI_V2_BEGIN_CATCH_DECL,
  OCTI_V2_END_CATCH_DECL,
  OCTI_V2_RETHROW_DECL,

  OCTI_V2_MAX
};

#define objc_v2_class_template	objc_v2_global_trees[OCTI_V2_CLS_TEMPL]
#define objc_v2_class_ro_template \
				objc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL]
#define objc_v2_category_template \
				objc_v2_global_trees[OCTI_V2_CAT_TEMPL]
#define objc_v2_protocol_template \
				objc_v2_global_trees[OCTI_V2_PROTO_TEMPL]

/* struct message_ref_t */
#define objc_v2_message_ref_template \
				objc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL]

#define objc_v2_ivar_list_ptr	objc_v2_global_trees[OCTI_V2_IVAR_LIST_TEMPL]

/* struct super_message_ref_t */
#define objc_v2_super_message_ref_template \
				objc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_REF_TEMPL]

/* struct message_ref_t* */
#define objc_v2_selector_type	objc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE]
/* struct super_super_message_ref_t */
#define objc_v2_super_selector_type \
				objc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE]
#define objc_v2_imp_type	objc_v2_global_trees[OCTI_V2_IMP_TYPE]
#define objc_v2_super_imp_type	objc_v2_global_trees[OCTI_V2_SUPER_IMP_TYPE]

#define UOBJC_V2_CACHE_decl	objc_v2_global_trees[OCTI_V2_CACHE_DECL]
#define UOBJC_V2_VTABLE_decl	objc_v2_global_trees[OCTI_V2_VTABLE_DECL]

#define objc_v2_ivar_template	objc_v2_global_trees[OCTI_V2_IVAR_TEMPL]
#define objc_v2_property_template \
				objc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL]

/* V2 Messaging */

/* objc_msgSend_fixup_rtp */
#define umsg_fixup_decl		objc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL]
/* objc_msgSend_stret_fixup_rtp */
#define umsg_stret_fixup_decl	objc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL]
/* objc_msgSendId_fixup_rtp */
#define umsg_id_fixup_decl	objc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL]
/* objc_msgSendId_stret_fixup_rtp */
#define umsg_id_stret_fixup_decl \
				objc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL]
/* objc_msgSendSuper2_fixup_rtp */
#define umsg_id_super2_fixup_decl \
				objc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL]
/* objc_msgSendSuper2_stret_fixup_rtp */
#define umsg_id_super2_stret_fixup_decl \
				objc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL]

#define objc2_begin_catch_decl	objc_v2_global_trees[OCTI_V2_BEGIN_CATCH_DECL]
#define objc2_end_catch_decl	objc_v2_global_trees[OCTI_V2_END_CATCH_DECL]
#define objc_rethrow_exception_decl \
				objc_v2_global_trees[OCTI_V2_RETHROW_DECL]

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

/* The OCTI_V2_... enumeration itself is in above.  */
static GTY(()) tree objc_v2_global_trees[OCTI_V2_MAX];

static void next_runtime_02_initialize (void);

static void build_v2_message_ref_templates (void);
static void build_v2_class_templates (void);
static void build_v2_super_template (void);
static void build_v2_category_template (void);
static void build_v2_protocol_template (void);

static tree next_runtime_abi_02_super_superclassfield_id (void);

static tree next_runtime_abi_02_class_decl (tree);
static tree next_runtime_abi_02_metaclass_decl (tree);
static tree next_runtime_abi_02_category_decl (tree);
static tree next_runtime_abi_02_protocol_decl (tree);
static tree next_runtime_abi_02_string_decl (tree, const char *, string_section);

static tree next_runtime_abi_02_get_class_reference (tree);
static tree next_runtime_abi_02_build_selector_reference (location_t, tree, tree);
static tree next_runtime_abi_02_get_protocol_reference (location_t, tree);
static tree next_runtime_abi_02_build_ivar_ref (location_t, tree, tree);
static tree next_runtime_abi_02_get_class_super_ref (location_t, struct imp_entry *, bool);
static tree next_runtime_abi_02_get_category_super_ref (location_t, struct imp_entry *, bool);

static tree next_runtime_abi_02_receiver_is_class_object (tree);
static void next_runtime_abi_02_get_arg_type_list_base (vec<tree, va_gc> **,
							tree, int, int);
static tree next_runtime_abi_02_build_objc_method_call (location_t, tree, tree,
							tree, tree, tree, int);
static bool next_runtime_abi_02_setup_const_string_class_decl (void);
static tree next_runtime_abi_02_build_const_string_constructor (location_t, tree, int);

static tree create_extern_decl (tree, const char *);

static void objc_generate_v2_next_metadata (void);
static bool objc2_objc_exception_attr (tree);

/* void build_v2_protocol_reference (tree);*/
static void build_v2_ehtype_template (void);
static void build_v2_eh_catch_objects (void);
static tree next_runtime_02_eh_type (tree);
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 **);

/* TODO: Use an objc-map.  */
static GTY ((length ("SIZEHASHTABLE"))) hash *extern_names;

bool
objc_next_runtime_abi_02_init (objc_runtime_hooks *rthooks)
{
  extern_names = ggc_cleared_vec_alloc<hash> (SIZEHASHTABLE);

  if (flag_objc_sjlj_exceptions)
    {
      inform (UNKNOWN_LOCATION,
	      "%<-fobjc-sjlj-exceptions%> is ignored for "
	      "%<-fnext-runtime%> when %<-fobjc-abi-version%> "
	      "greater than 1");
      flag_objc_sjlj_exceptions = 0;
    }

  /* NeXT ABI 2 is intended to default to checking for nil receivers.  */
  if (! OPTION_SET_P (flag_objc_nilcheck))
    flag_objc_nilcheck = 1;

  rthooks->initialize = next_runtime_02_initialize;
  rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME;
  rthooks->tag_getclass = TAG_GETCLASS;
  rthooks->super_superclassfield_ident = next_runtime_abi_02_super_superclassfield_id;

  rthooks->class_decl = next_runtime_abi_02_class_decl;
  rthooks->metaclass_decl = next_runtime_abi_02_metaclass_decl;
  rthooks->category_decl = next_runtime_abi_02_category_decl;
  rthooks->protocol_decl = next_runtime_abi_02_protocol_decl;
  rthooks->string_decl = next_runtime_abi_02_string_decl;

  rthooks->get_class_reference = next_runtime_abi_02_get_class_reference;
  rthooks->build_selector_reference = next_runtime_abi_02_build_selector_reference;
  rthooks->get_protocol_reference = next_runtime_abi_02_get_protocol_reference;
  rthooks->build_ivar_reference = next_runtime_abi_02_build_ivar_ref;
  rthooks->get_class_super_ref = next_runtime_abi_02_get_class_super_ref;
  rthooks->get_category_super_ref = next_runtime_abi_02_get_category_super_ref;

  rthooks->receiver_is_class_object = next_runtime_abi_02_receiver_is_class_object;
  rthooks->get_arg_type_list_base = next_runtime_abi_02_get_arg_type_list_base;
  rthooks->build_objc_method_call = next_runtime_abi_02_build_objc_method_call;

  rthooks->setup_const_string_class_decl =
				next_runtime_abi_02_setup_const_string_class_decl;
  rthooks->build_const_string_constructor =
				next_runtime_abi_02_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_v2_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 when LTO is used with 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_02_init_metadata_attributes (void)
{
  if (!objc_meta)
    objc_meta = get_identifier ("OBJC2META");

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

  meta_class = get_identifier ("G2_CLAS");
  meta_metaclass = get_identifier ("G2_META");
  meta_category = meta_base;
  meta_protocol = get_identifier ("V2_PCOL");

  meta_clac_vars =
  meta_clai_vars = meta_base;

  meta_clac_meth =
  meta_clai_meth =
  meta_catc_meth =
  meta_cati_meth =
  meta_proto_cls_meth =
  meta_proto_nst_meth = meta_base;

  meta_clas_prot =
  meta_catg_prot = meta_base;

  meta_sel_refs = get_identifier ("V2_SRFS");

  meta_class_name = get_identifier ("V2_CNAM");
  meta_meth_name = get_identifier ("V2_MNAM");

  meta_meth_type = get_identifier ("V2_MTYP");
  meta_prop_name_attr = get_identifier ("V2_STRG");

  meta_mref = get_identifier ("V2_MREF");
  meta_class_ref = get_identifier ("V2_CLRF");
  meta_superclass_ref = get_identifier ("V2_SURF");

  meta_label_classlist = get_identifier ("V2_CLAB");
  meta_label_nonlazy_classlist = get_identifier ("V2_NLCL");
  meta_label_categorylist = get_identifier ("V2_CALA");
  meta_label_nonlazy_categorylist = get_identifier ("V2_NLCA");

  meta_label_protocollist = get_identifier ("V2_PLST");
  meta_proto_ref = get_identifier ("V2_PRFS");

  meta_info = get_identifier ("V2_INFO");

  meta_ehtype = get_identifier ("V2_EHTY");

  meta_const_str = get_identifier ("V2_CSTR");

  meta_ivar_ref = get_identifier ("V2_IVRF");
}

static void next_runtime_02_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_02_init_metadata_attributes ();

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

  /* IMP : id (*) (id, _message_ref_t*, ...)
     SUPER_IMP : id (*) ( super_t*, _super_message_ref_t*, ...)
     objc_v2_selector_type.  */
  build_v2_message_ref_templates ();

  objc_v2_ivar_list_ptr =
		build_pointer_type (xref_tag (RECORD_TYPE,
				    get_identifier ("_ivar_list_t")));

  objc_prop_list_ptr =
		build_pointer_type (xref_tag (RECORD_TYPE,
				    get_identifier ("_prop_list_t")));

  build_v2_class_templates ();
  build_v2_super_template ();
  build_v2_protocol_template ();
  build_v2_category_template ();

  bool fixup_p = flag_next_runtime < USE_FIXUP_BEFORE;
  if (fixup_p)
    {
      /* id objc_msgSend_fixup_rtp (id, struct message_ref_t*, ...); */
      type = build_varargs_function_type_list (objc_object_type,
					       objc_object_type,
					       objc_v2_selector_type,
					       NULL_TREE);
    }
  else
    {
      /* id objc_msgSendXXXX (id, SEL, ...); */
      type = build_varargs_function_type_list (objc_object_type,
					       objc_object_type,
					       objc_selector_type,
					       NULL_TREE);
    }
  const char *fnam = fixup_p ? TAG_MSGSEND TAG_FIXUP : TAG_MSGSEND;
  umsg_fixup_decl =  add_builtin_function (fnam, type, 0, NOT_BUILT_IN,
					   NULL, NULL_TREE);
  TREE_NOTHROW (umsg_fixup_decl) = 0;

  /* id objc_msgSend_stret_fixup_rtp (id, struct message_ref_t*, ...); */
  fnam = fixup_p ? TAG_MSGSEND_STRET TAG_FIXUP : TAG_MSGSEND_STRET;
  umsg_stret_fixup_decl = add_builtin_function (fnam, type, 0, NOT_BUILT_IN,
						NULL, NULL_TREE);
  TREE_NOTHROW (umsg_stret_fixup_decl) = 0;

  /* id objc_msgSendId_fixup_rtp (id, struct message_ref_t*, ...); */
  fnam = fixup_p ? TAG_MSGSENDID TAG_FIXUP : TAG_MSGSENDID;
  umsg_id_fixup_decl = add_builtin_function (fnam, type, 0, NOT_BUILT_IN,
					     NULL, NULL_TREE);
  TREE_NOTHROW (umsg_id_fixup_decl) = 0;

  /* id objc_msgSendId_stret_fixup_rtp (id, struct message_ref_t*, ...); */
  fnam = fixup_p ? TAG_MSGSENDID_STRET TAG_FIXUP : TAG_MSGSENDID_STRET;
  umsg_id_stret_fixup_decl = add_builtin_function (fnam, type, 0, NOT_BUILT_IN,
						   NULL, NULL_TREE);
  TREE_NOTHROW (umsg_id_stret_fixup_decl) = 0;

 /* id objc_msgSendSuper2_fixup_rtp
			(struct objc_super *, struct message_ref_t*, ...); */
  type = build_varargs_function_type_list (objc_object_type,
					   objc_super_type,
					   objc_v2_super_selector_type,
					   NULL_TREE);
  fnam = fixup_p ? TAG_MSGSENDSUPER TAG_FIXUP : TAG_MSGSENDSUPER;
  umsg_id_super2_fixup_decl = add_builtin_function (fnam, type, 0, NOT_BUILT_IN,
						    NULL, NULL_TREE);
  TREE_NOTHROW (umsg_id_super2_fixup_decl) = 0;

  /* id objc_msgSendSuper2_stret_fixup_rtp
			(struct objc_super *, struct message_ref_t*, ...); */
  fnam = fixup_p ? TAG_MSGSENDSUPER_STRET TAG_FIXUP : TAG_MSGSENDSUPER_STRET;
  umsg_id_super2_stret_fixup_decl = add_builtin_function (fnam, type, 0,
							  NOT_BUILT_IN,  NULL,
							  NULL_TREE);
  TREE_NOTHROW (umsg_id_super2_stret_fixup_decl) = 0;

  /* Present in the library, but unused by the FE.  */
  /* Protocol *objc_getProtocol (const char *)
  type = build_function_type_list (objc_protocol_type,
				   const_string_type_node,
				   NULL_TREE);
  objc_v2_getprotocol_decl = add_builtin_function ("objc_getProtocol",
						    type, 0, NOT_BUILT_IN,
						    NULL, NULL_TREE);
  TREE_NOTHROW (objc_v2_getprotocol_decl) = 0;*/

  UOBJC_V2_CACHE_decl = create_extern_decl (ptr_type_node,
					    "_objc_empty_cache");

  UOBJC_V2_VTABLE_decl = create_extern_decl (objc_v2_imp_type,
					     "_objc_empty_vtable");

  /* id objc_getClass (const char *); */
  type = build_function_type_list (objc_object_type,
                                   const_string_type_node,
                                   NULL_TREE);
  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;

  gcc_checking_assert (!flag_objc_sjlj_exceptions);

  /* Although we warn that fobjc-exceptions is required for exceptions
     code, we carry on and create it anyway.  */

  /* This can be required, even when exceptions code is not present,
     when an __attribute__((objc_exception)) is applied to a
     class.  */
  build_v2_ehtype_template ();

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

  objc2_begin_catch_decl = add_builtin_function ("objc_begin_catch",
						 type, 0, NOT_BUILT_IN,
						 NULL, NULL_TREE);
  TREE_NOTHROW (objc2_begin_catch_decl) = 0;

  /* void objc_end_catch () */
  type = build_function_type_list (void_type_node, NULL_TREE);
  objc2_end_catch_decl = add_builtin_function ("objc_end_catch",
						type, 0, NOT_BUILT_IN,
						NULL, NULL_TREE);
  TREE_NOTHROW (objc2_end_catch_decl) = 0;

  /* void objc_exception_rethrow (void) */
  objc_rethrow_exception_decl =
			add_builtin_function ("objc_exception_rethrow",
					      type, 0, NOT_BUILT_IN,
					      NULL, NULL_TREE);
  TREE_NOTHROW (objc_rethrow_exception_decl) = 0;
  using_eh_for_cleanups ();
  lang_hooks.eh_runtime_type = next_runtime_02_eh_type;
  lang_hooks.eh_personality = objc_eh_personality;
}

/* NOTE --- templates --- */

/* Set 'objc_v2_message_ref_template' to the data type node for
   'struct _message_ref_t'.  This needs to be done just once per
   compilation.  Also Set 'objc_v2_super_message_ref_template' to data
   type node for 'struct _super_message_ref_t'.  */

/* struct _message_ref_t
   {
     IMP messenger;
     SEL name;
   };
   where IMP is: id (*) (id, _message_ref_t*, ...)
*/

/* struct _super_message_ref_t
   {
     SUPER_IMP messenger;
     SEL name;
   };
   where SUPER_IMP is: id (*) ( super_t*, _super_message_ref_t*, ...)
*/

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

  /* struct _message_ref_t {...} */
  objc_v2_message_ref_template =
		objc_start_struct (get_identifier ("_message_ref_t"));

  /* IMP messenger; */
  ptr_message_ref_t =
		build_pointer_type (xref_tag (RECORD_TYPE,
				    get_identifier ("_message_ref_t")));

  objc_v2_imp_type =
		build_pointer_type (build_function_type_list
					(objc_object_type,
					 objc_object_type,
					 ptr_message_ref_t,
					 NULL_TREE));

  decls = add_field_decl (objc_v2_imp_type, "messenger", &chain);

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

  objc_finish_struct (objc_v2_message_ref_template, decls);

  objc_v2_selector_type = build_pointer_type (objc_v2_message_ref_template);

  chain = NULL;
  /* struct _super_message_ref_t {...} */
  objc_v2_super_message_ref_template =
		objc_start_struct (get_identifier ("_super_message_ref_t"));

  /* SUPER_IMP messenger; */
  ptr_message_ref_t = build_pointer_type
			(xref_tag (RECORD_TYPE,
				   get_identifier ("_super_message_ref_t")));

  objc_v2_super_imp_type =
		build_pointer_type (build_function_type_list
					(objc_object_type,
					 objc_super_type,
					 ptr_message_ref_t,
					 NULL_TREE));

  add_field_decl (objc_v2_super_imp_type, "messenger", &chain);

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

  objc_finish_struct (objc_v2_super_message_ref_template, decls);
  objc_v2_super_selector_type =
		build_pointer_type (objc_v2_super_message_ref_template);
}

/* Build following types which represent each class implementation.

struct class_ro_t
{
    uint32_t const flags;
    uint32_t const instanceStart;
    uint32_t const instanceSize;
#ifdef __LP64__
    uint32_t const reserved;
#endif
    const uint8_t * const ivarLayout;
    const char *const name;
    const struct method_list_t * const baseMethods;
    const struct objc_protocol_list *const baseProtocols;
    const struct ivar_list_t *const ivars;
    const uint8_t * const weakIvarLayout;
    const struct _prop_list_t * const properties;
};

struct class_t
{
    struct class_t *isa;
    struct class_t *superclass;
    void *cache;
    IMP *vtable;

    ...When this is active - it will point to a rw version, but
       when we build the meta-data we point it to the ro...
    struct class_ro_t *data;
};

*/

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

  /* struct class_ro_t {...} */
  objc_v2_class_ro_template =
	objc_start_struct (get_identifier (UTAG_V2_CLASS_RO));

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

  /* uint32_t const instanceStart; */
  add_field_decl (integer_type_node, "instanceStart", &chain);

  /* uint32_t const instanceSize; */
  add_field_decl (integer_type_node, "instanceSize", &chain);

  /* This ABI is currently only used on m64 NeXT.  We always
     explicitly declare the alignment padding.  */
  /* uint32_t const reserved; */
  add_field_decl (integer_type_node, "reserved", &chain);

  /* const uint8_t * const ivarLayout; */
  cnst_strg_type = build_pointer_type (unsigned_char_type_node);
  add_field_decl (cnst_strg_type, "ivarLayout", &chain);

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

  /* const struct method_list_t * const baseMethods; */
  add_field_decl (objc_method_list_ptr, "baseMethods", &chain);

  /* const struct objc_protocol_list *const baseProtocols; */
  add_field_decl (build_pointer_type
			(xref_tag (RECORD_TYPE,
				   get_identifier (UTAG_V2_PROTOCOL_LIST))),
				  "baseProtocols", &chain);

  /* const struct ivar_list_t *const ivars; */
  add_field_decl (objc_v2_ivar_list_ptr, "ivars", &chain);

  /* const uint8_t * const weakIvarLayout; */
  add_field_decl (cnst_strg_type, "weakIvarLayout",  &chain);

  /* struct _prop_list_t * baseProperties; */
  add_field_decl (objc_prop_list_ptr, "baseProperties", &chain);

  objc_finish_struct (objc_v2_class_ro_template, decls);

  chain = NULL;
  /* struct class_t {...} */
  objc_v2_class_template =
	objc_start_struct (get_identifier (UTAG_V2_CLASS));

  /* struct class_t *isa; */
  decls = add_field_decl (build_pointer_type (objc_v2_class_template),
			  "isa", &chain);

  /* struct class_t * const superclass; */
  add_field_decl (build_pointer_type (objc_v2_class_template),
				      "superclass", &chain);

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

  /* IMP *vtable; */
  add_field_decl (build_pointer_type (objc_v2_imp_type), "vtable", &chain);

  /* struct class_ro_t *ro; */
  add_field_decl (build_pointer_type (objc_v2_class_ro_template), "ro", &chain);

  objc_finish_struct (objc_v2_class_template, decls);
}

/* struct _objc_super
   {
     struct _objc_object *self;
     Class cls;
   }; */
void
build_v2_super_template (void)
{
  tree decls, *chain = NULL;

  objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));

  /* struct _objc_object *self; */
  decls = add_field_decl (objc_object_type, "self", &chain);

  /* Class cls; */
  add_field_decl (objc_class_type, "cls", &chain);

  objc_finish_struct (objc_super_template, decls);
}

/* struct protocol_t
  {
     Class isa;
     const char * const protocol_name;
     const struct protocol_list_t * const protocol_list;
     const struct method_list_t * const instance_methods;
     const struct method_list_t * const class_methods;
     const struct method_list_t * optionalInstanceMethods;
     const struct method_list_t * optionalClassMethod
     const struct _prop_list_t * const properties;
     const uint32_t size;
     const uint32_t flags;
     const char ** extended_method_types;
     const char * demangled_name;
     const struct _prop_list_t * class_properties;
   }
*/
static void
build_v2_protocol_template (void)
{
  tree decls, *chain = NULL;

  objc_v2_protocol_template =
	objc_start_struct (get_identifier (UTAG_V2_PROTOCOL));

  /* Class isa; */
  decls = add_field_decl (objc_object_type, "isa", &chain);

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

  /* const struct protocol_list_t * const protocol_list; */
  add_field_decl (build_pointer_type (objc_v2_protocol_template),
		  "protocol_list", &chain);

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

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

  /* const struct method_list_t * optionalInstanceMethods; */
  add_field_decl (objc_method_proto_list_ptr, "optionalInstanceMethods", &chain);

  /* const struct method_list_t * optionalClassMethods; */
  add_field_decl (objc_method_proto_list_ptr, "optionalClassMethods", &chain);

  /* struct _prop_list_t * properties; */
  add_field_decl (objc_prop_list_ptr, "properties", &chain);

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

  /* const uint32_t flags; */
  add_field_decl (integer_type_node, "flags", &chain);

  /* const char **extendedMethodTypes; */
  tree ptr_to_ptr_to_char = build_pointer_type (string_type_node);
  add_field_decl (ptr_to_ptr_to_char, "extended_method_types", &chain);

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

  /* const struct _prop_list_t *class_properties; */
  add_field_decl (objc_prop_list_ptr, "class_properties", &chain);

  objc_finish_struct (objc_v2_protocol_template, decls);
}

/* Build type for a category:
   struct category_t
   {
     const char * const name;
     struct class_t *const cls;
     const struct method_list_t * const instance_methods;
     const struct method_list_t * const class_methods;
     const struct protocol_list_t * const protocols;
     const struct _prop_list_t * const properties;
   }
*/

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

  objc_v2_category_template =
	objc_start_struct (get_identifier ("_category_t"));

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

  /* struct class_t *const cls; */
  add_field_decl (build_pointer_type (objc_v2_class_template), "cls", &chain);

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

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

  /* struct protocol_list_t *protocol_list; */
  add_field_decl (build_pointer_type (objc_v2_protocol_template),
                  "protocol_list", &chain );

  /* struct _prop_list_t * properties; */
  add_field_decl (objc_prop_list_ptr, "properties", &chain);

  objc_finish_struct (objc_v2_category_template, decls);
}

/* NOTE --- Decls, Identifiers, Names etc. --- */

/* This routine is given a name and returns a matching extern variable
   if one is found.  */

static tree
hash_name_lookup (hash *hashlist, tree name)
{
  hash target;

  target = hashlist[IDENTIFIER_HASH_VALUE (name) % SIZEHASHTABLE];

  while (target)
    {
      if (name == DECL_NAME (target->key))
	return target->key;

      target = target->next;
    }
  return 0;
}

/* This routine is given an extern variable and enters it in its hash
   table.  Note that hashing is done on its inner IDENTIFIER_NODE
   node.  */

static void
hash_name_enter (hash *hashlist, tree id)
{
  hash obj;
  int slot = IDENTIFIER_HASH_VALUE (DECL_NAME (id)) % SIZEHASHTABLE;

  obj = ggc_alloc<hashed_entry> ();
  obj->list = 0;
  obj->next = hashlist[slot];
  obj->key = id;

  hashlist[slot] = obj;		/* append to front */
}

/* Create a declaration "extern <type> <name>;"
   The var will need to be finalized (e.g. by calling finish_var_decl()).  */

static tree
create_extern_decl (tree type, const char *name)
{
  tree id = get_identifier (name);
  tree var = hash_name_lookup (extern_names, id);
  if (var)
      return var;
  /* New name. */
  var = start_var_decl (type, name);
  TREE_STATIC (var) = 0;
  DECL_EXTERNAL (var) = 1;
  TREE_PUBLIC (var) = 1;
  hash_name_enter (extern_names, var);
  return var;
}

/* Create a globally visible definition for variable NAME of a given TYPE. The
   finish_var_decl() routine will need to be called on it afterwards.  */
static tree
create_global_decl (tree type, const char *name, bool is_def = false);

static tree
create_global_decl (tree type, const char *name, bool is_def)
{
  tree id = get_identifier (name);
  tree var = hash_name_lookup (extern_names, id);
  if (var)
    is_def = true;
  else
    {
      var = start_var_decl (type, name);
      hash_name_enter (extern_names, var);
    }
  if (is_def)
    {
      DECL_EXTERNAL (var) = 0;
      TREE_STATIC (var) = 1;
    }
  TREE_PUBLIC (var) = 1;
  return var;
}

/* Create a symbol with __attribute__ ((visibility ("hidden")))
   attribute (private extern).  */
static tree
create_hidden_decl (tree type, const char *name, bool is_def = false);

static tree
create_hidden_decl (tree type, const char *name, bool is_def)
{
    tree decl = create_global_decl (type, name, is_def);
    DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
    DECL_VISIBILITY_SPECIFIED (decl) = 1;
    return decl;
}

/* Irritatingly, we have a different superclass field name for ABI=2.  */
/* PS/TODO: The field name does not matter, it is only used internally
   by the compiler.  We can rename it to whatever we want. ;-) */

static tree
next_runtime_abi_02_super_superclassfield_id (void)
{
  /* TODO: Simplify.  Just always return get_identifier ("cls"), or at
     most look it once at startup then always return it.  */
  if (!super_superclassfield_id)
    super_superclassfield_id = get_identifier ("cls");
  return super_superclassfield_id;
}

static tree
next_runtime_abi_02_class_decl (tree klass)
{
  tree decl;
  char buf[BUFSIZE];
  snprintf (buf, BUFSIZE, "OBJC_CLASS_$_%s",
	    IDENTIFIER_POINTER (CLASS_NAME (klass)));
  /* ObjC2 classes are extern visible.  */
  decl = create_global_decl (objc_v2_class_template, buf);
  OBJCMETA (decl, objc_meta, meta_class);
  return decl;
}

static tree
next_runtime_abi_02_metaclass_decl (tree klass)
{
  tree decl;
  char buf[BUFSIZE];
  snprintf (buf, BUFSIZE, "OBJC_METACLASS_$_%s",
	    IDENTIFIER_POINTER (CLASS_NAME (klass)));
  /* ObjC2 classes are extern visible.  */
  decl = create_global_decl (objc_v2_class_template, buf);
  OBJCMETA (decl, objc_meta, meta_metaclass);
  return decl;
}

static tree
next_runtime_abi_02_category_decl (tree klass)
{
  tree decl;
  char buf[BUFSIZE];
  snprintf (buf, BUFSIZE, "_OBJC_Category_%s_%s",
	    IDENTIFIER_POINTER (CLASS_NAME (klass)),
	    IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)));
  decl = start_var_decl (objc_v2_category_template, buf);
  OBJCMETA (decl, objc_meta, meta_category);
  return decl;
}

static tree
next_runtime_abi_02_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)));
  if (flag_next_runtime >= USE_FIXUP_BEFORE)
    {
      decl = create_hidden_decl (objc_v2_protocol_template, buf);
      DECL_WEAK (decl) = true;
    }
  else
    decl = start_var_decl (objc_v2_protocol_template, buf);
  OBJCMETA (decl, objc_meta, meta_protocol);
  return decl;
}

static tree
next_runtime_abi_02_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;
}

/* NOTE --- entry --- */

struct GTY(()) ident_data_tuple {
  tree ident;
  tree data;
};

/* This routine creates a file scope static variable of type 'Class'
   to hold the address of a class.  */

static tree
build_v2_class_reference_decl (tree ident)
{
  tree decl;
  char buf[BUFSIZE];

  snprintf (buf, BUFSIZE, "_OBJC_ClassRef_%s", IDENTIFIER_POINTER (ident));
  decl = start_var_decl (objc_class_type, buf);
  OBJCMETA (decl, objc_meta, meta_class_ref);
  return decl;
}

/* This routine builds a class refs entry for each class name used.
   Initially, a (static-ref, IDENT) tuple is added to the list.  The
   ident is replaced with address of the class metadata (of type
   'Class') in the output routine.  */

static GTY (()) vec<ident_data_tuple, va_gc> *classrefs;

static tree
objc_v2_get_class_reference (tree ident)
{
  tree decl;
  ident_data_tuple e;
  if (classrefs)
    {
      int count;
      ident_data_tuple *ref;
      FOR_EACH_VEC_ELT (*classrefs, count, ref)
	{
	  if (ref->ident == ident)
	    {
	      if (!ref->data)
		ref->data = build_v2_class_reference_decl (ident);
	      return ref->data;
	    }
	}
    }
  else
    /* Somewhat arbitrary initial provision.  */
    vec_alloc (classrefs, 16);

  /* We come here if we don't find the entry - or if the table was yet
     to be created.  */
  decl = build_v2_class_reference_decl (ident);
  e.ident = ident;
  e.data = decl;
  vec_safe_push (classrefs, e);
  return decl;
}

static tree
next_runtime_abi_02_get_class_reference (tree ident)
{
  if (!flag_zero_link)
    return objc_v2_get_class_reference (ident);
  else
    {
      /* We fall back to using objc_getClass ().  */
      vec<tree, va_gc> *v;
      vec_alloc (v, 1);
      tree t;
      /* ??? add_class_reference (ident); - is pointless, since the
         system lib does not export the equivalent symbols.  Maybe we
         need to build a class ref anyway.  */
      t = my_build_string_pointer (IDENTIFIER_LENGTH (ident) + 1,
				   IDENTIFIER_POINTER (ident));
      v->quick_push (t);
      t = build_function_call_vec (input_location, vNULL, objc_get_class_decl,
				   v, 0);
      vec_free (v);
      return t;
    }
}

/* 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_02_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);
  if (flag_next_runtime < USE_FIXUP_BEFORE)
    /* Selector type - will eventually change to `int'.  */
    vec_safe_push (*argtypes, superflag ? objc_v2_super_selector_type
					: objc_v2_selector_type);
  else
    vec_safe_push (*argtypes, objc_selector_type);
}

/* TODO: Merge this with the message refs.  */
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_02_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;
}

/* Declare a variable of type 'struct message_ref_t'. */
/* This will be finished in build_v2_message_ref_translation_table ().
   We take an idea from LLVM in making the names a bit more connected
   and thus the asm more readable.  */

static tree
build_v2_message_reference_decl (tree sel_name, tree message_func_ident)
{
  tree decl;
  char buf[BUFSIZE], *t;
  int offset = 12;

  /* Skip past the objc_msgSend it's the same for all...  */
  if (IDENTIFIER_POINTER (message_func_ident)[offset] == '_')
    offset++;

  snprintf (buf, BUFSIZE, "_OBJC_MsgRef_%s_%s",
	    &(IDENTIFIER_POINTER (message_func_ident)[offset]),
	    IDENTIFIER_POINTER (sel_name));
  t = buf;
  while (*t)
    {
      if (*t==':')
        *t = '$'; /* Underscore would clash between foo:bar and foo_bar.  */
      t++;
    }
  decl = start_var_decl (objc_v2_message_ref_template, buf);
  OBJCMETA (decl, objc_meta, meta_mref);
  return decl;
}

struct GTY(()) msgref_entry {
  tree func;
  tree selname;
  tree refdecl;
};

static GTY (()) vec<msgref_entry, va_gc> *msgrefs;

/* Build the list of (objc_msgSend_fixup_xxx, selector name), used
   later on to initialize the table of 'struct message_ref_t'
   elements.  */

static tree
build_v2_selector_messenger_reference (tree sel_name, tree message_func_decl)
{
  tree decl;
  msgref_entry e;
  if (msgrefs)
    {
      int count;
      msgref_entry *ref;
      FOR_EACH_VEC_ELT (*msgrefs, count, ref)
	if (ref->func == message_func_decl && ref->selname == sel_name)
	  return ref->refdecl;
    }
  else
    /* Somewhat arbitrary initial provision.  */
    vec_alloc (msgrefs, 32);

  /* We come here if we don't find a match or at the start.  */
  decl = build_v2_message_reference_decl (sel_name,
					  DECL_NAME (message_func_decl));
  e.func = message_func_decl;
  e.selname = sel_name;
  e.refdecl = decl;
  vec_safe_push (msgrefs, e);
  return decl;
}

static tree
build_v2_protocollist_ref_decl (tree protocol)
{
  tree decl;
  tree protocol_ident = PROTOCOL_NAME (protocol);
  char buf[BUFSIZE];

  snprintf (buf, BUFSIZE, "_OBJC_ProtocolRef_%s",
	    IDENTIFIER_POINTER (protocol_ident));
  /* TODO: other compiler versions make these hidden & weak.  */
  decl = create_global_decl (objc_protocol_type, buf);
  /* Let optimizer know that this decl is not removable.  */
  DECL_PRESERVE_P (decl) = 1;
  OBJCMETA (decl, objc_meta, meta_proto_ref);
  return decl;
}

struct GTY(()) prot_list_entry {
  tree id;
  tree refdecl;
};
static GTY (()) vec<prot_list_entry, va_gc> *protrefs;

static tree
objc_v2_get_protocol_reference (tree ident)
{
  tree decl;
  prot_list_entry e;
  if (protrefs)
    {
      int count;
      prot_list_entry *ref;
      FOR_EACH_VEC_ELT (*protrefs, count, ref)
	{
	  if (ref->id == ident)
	    {
	      if (!ref->refdecl)
		ref->refdecl = build_v2_protocollist_ref_decl (ident);
	      return ref->refdecl;
	    }
	}
    }
  else
    /* Somewhat arbitrary initial provision.  */
    vec_alloc (protrefs, 32);

  /* We come here if we don't find the entry - or if the table was yet
     to be created.  */
  decl = build_v2_protocollist_ref_decl (ident);
  e.id = ident;
  e.refdecl = decl;
  vec_safe_push (protrefs, e);
  return decl;
}

static tree
next_runtime_abi_02_get_protocol_reference (location_t loc ATTRIBUTE_UNUSED,
					    tree p)
{
  if (!PROTOCOL_FORWARD_DECL (p))
    PROTOCOL_FORWARD_DECL (p) = next_runtime_abi_02_protocol_decl (p);

  return objc_v2_get_protocol_reference (p);
}

/* This routine returns the ivar declaration, if component is a valid
   ivar field; NULL_TREE otherwise. On finding an ivar, it also
   returns the class name in CLASS.  */

static tree
objc_is_ivar (tree expr, tree component, tree *klass)
{
  tree field = NULL_TREE;
  tree basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));

  if (TREE_CODE (basetype) == RECORD_TYPE
      && TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
    {
      *klass = lookup_interface (OBJC_TYPE_NAME (basetype));
      if (*klass)
	{
	  do
	    {
	      tree ivar_chain = CLASS_RAW_IVARS (*klass);
	      if (ivar_chain)
		{
		  field = is_ivar (ivar_chain, component);
		  if (field != NULL_TREE)
		    break;
	        }
	      *klass = lookup_interface (CLASS_SUPER_NAME (*klass));
	    }
	  while (*klass);
	}
    }
  return field;
}

static void
create_ivar_offset_name (char *buf, tree class_name, tree field_decl)
{
  tree fname = DECL_NAME (field_decl);

  sprintf (buf, "OBJC_IVAR_$_%s.%s", IDENTIFIER_POINTER (class_name),
	   IDENTIFIER_POINTER (fname));
  return;
}

/* This routine generates new abi's ivar reference tree.  It amounts
   to generating *(TYPE*)((char*)pObj + OFFSET_IVAR) when we normally
   generate pObj->IVAR.  OFFSET_IVAR is an 'extern' variable holding
   the offset for 'IVAR' field.  TYPE is type of IVAR field.  */

static tree
objc_v2_build_ivar_ref (tree datum, tree component)
{
  tree field, ref, class_name, offset, ftype, expr;
  char var_offset_name[512];

  field = objc_is_ivar (datum, component, &class_name);
  if (!field)
    return NULL_TREE;

  /* This routine only handles non-bitfield fields */
  if (DECL_C_BIT_FIELD (field))
    return NULL_TREE;

  create_ivar_offset_name (var_offset_name, CLASS_NAME (class_name),  field);

  offset = create_extern_decl (TREE_TYPE (size_zero_node), var_offset_name);

  ftype = TREE_TYPE (field);

  /* (char*)datum */
  expr = build_c_cast (input_location,
		       string_type_node, build_fold_addr_expr (datum));

  /* (char*)datum + offset */
  expr = fold_build_pointer_plus_loc (input_location, expr, offset);

  /* (ftype*)((char*)datum + offset) */
  expr = build_c_cast (input_location, build_pointer_type (ftype), expr);

  /* Finally: *(ftype*)((char*)datum + offset) */
  ref = build_indirect_ref (input_location, expr, RO_UNARY_STAR);

  /* We must set type of the resulting expression to be the same as
     the field type. This is because, build_indirect_ref (...)
     rebuilds the type which may result in lost information; as in the
     case of protocol-qualified types (id <protocol> ).  */
  TREE_TYPE (ref) = ftype;

  if (TREE_READONLY (datum) || TREE_READONLY (field))
    TREE_READONLY (ref) = 1;

  if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (field))
    TREE_THIS_VOLATILE (ref) = 1;

  if (TREE_DEPRECATED (field))
    warn_deprecated_use (field, NULL_TREE);

  return ref;
}

/* IVAR refs are made via an externally referenceable offset and built
   on the fly.  That is, unless they refer to (private) fields in  the
   class structure.  */
static tree
next_runtime_abi_02_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED,
				   tree base, tree id)
{
  tree ivar;
  if ((ivar = objc_v2_build_ivar_ref (base, id)))
    return ivar;
  return objc_build_component_ref (base, id);
}

/* [super ...] references are listed here (and built into a table at
   meta -data emit time).  */
static tree
build_v2_superclass_ref_decl (tree ident, bool inst)
{
  tree decl;
  char buf[BUFSIZE];

  snprintf (buf, BUFSIZE, "_OBJC_%sSuperRef_%s", (inst?"":"Meta"),
	    IDENTIFIER_POINTER (ident));
  decl = start_var_decl (objc_class_type, buf);
  OBJCMETA (decl, objc_meta, meta_superclass_ref);
  return decl;
}

static GTY (()) vec<ident_data_tuple, va_gc> *class_super_refs;
static GTY (()) vec<ident_data_tuple, va_gc> *metaclass_super_refs;

/* Find or build a superclass reference decl for class NAME.  */

static tree
objc_get_superclass_ref_decl (tree name, bool inst_meth)
{
  tree decl;
  vec<ident_data_tuple, va_gc> *list = inst_meth  ? class_super_refs
						: metaclass_super_refs;

  if (list)
    {
      int count;
      ident_data_tuple *ref;
      FOR_EACH_VEC_ELT (*list, count, ref)
	{
	  if (ref->ident == name)
	    {
	      if (!ref->data)
		ref->data = build_v2_superclass_ref_decl (name, inst_meth);
	      return ref->data;
	    }
	}
    }
  else
    {
      /* Somewhat arbitrary initial provision.  */
      if (inst_meth)
	{
	  vec_alloc (class_super_refs, 16);
	  list = class_super_refs;
	}
      else
	{
	  vec_alloc (metaclass_super_refs, 16);
	  list = metaclass_super_refs;
	}
    }
  /* We come here if we don't find the entry - or if the table was yet
     to be created.  */
  decl = build_v2_superclass_ref_decl (name, inst_meth);
  ident_data_tuple e;
  e.ident = name;
  e.data = decl;
  vec_safe_push (list, e);
  return decl;
}

/* Get a reference to the superclass for IMP.  */

static tree
next_runtime_abi_02_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
					 struct imp_entry *imp, bool inst_meth)
{
  tree name = CLASS_NAME (imp->imp_context);
  return objc_get_superclass_ref_decl (name, inst_meth);
}

/* Get a reference to the superclass for category IMP.  */

static tree
next_runtime_abi_02_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
					    struct imp_entry *imp,
					    bool inst_meth)
{
  if (flag_zero_link)
    {
      /* Do it the slow way.  */
      tree get_cl_fn = inst_meth ? objc_get_class_decl
				 : objc_get_meta_class_decl;
      tree super_name = CLASS_SUPER_NAME (imp->imp_template);
      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, get_cl_fn,
				  build_tree_list (NULL_TREE, super_name));
    }

  /* This is the 'usual' path.  */
  tree cls_name = CLASS_NAME (imp->imp_template);
  if (!inst_meth)
    return objc_get_superclass_ref_decl (cls_name, inst_meth);
  return objc_get_class_reference (cls_name);
}

static tree
next_runtime_abi_02_receiver_is_class_object (tree receiver)
{
  if (TREE_CODE (receiver) == VAR_DECL
      && IS_CLASS (TREE_TYPE (receiver))
      && vec_safe_length (classrefs))
    {
      int count;
      ident_data_tuple *ref;
      /* The receiver is a variable created by build_class_reference_decl.  */
      FOR_EACH_VEC_ELT (*classrefs, count, ref)
	if (ref->data == receiver)
	  return ref->ident;
    }
  return NULL_TREE;
}

/* Assign all arguments in VALUES which have side-effect to a temporary
   and replaced that argument in VALUES list with the temporary. The
   arguments will be passed to a function with FNTYPE.  */

static tree
objc_copy_to_temp_side_effect_params (tree fntype, tree values)
{
  tree valtail;
  function_args_iterator iter;

  /* Skip over receiver and the &_msf_ref types.  */
  function_args_iter_init (&iter, fntype);
  function_args_iter_next (&iter);
  function_args_iter_next (&iter);

  for (valtail = values; valtail;
       valtail = TREE_CHAIN (valtail), function_args_iter_next (&iter))
    {
      tree value = TREE_VALUE (valtail);
      tree type = function_args_iter_cond (&iter);
      if (type == NULL_TREE)
	break;
      if (!TREE_SIDE_EFFECTS (value))
	continue;
      /* To prevent re-evaluation.  */
      value = save_expr (value);
      add_stmt (value);
      TREE_VALUE (valtail) = value;
    }
  return values;
}

/* Build the new abi's messaging library call. It looks like:
   (*_msg.messenger) (receiver, &_msg, ...) */

static tree
build_v2_objc_method_fixup_call (int super_flag, tree method_prototype,
				tree lookup_object, tree selector,
				tree method_params, bool check_for_nil)
{
  tree ret_val;
  tree sender, rcv_p, t;
  tree ret_type
    = (method_prototype
       ? TREE_VALUE (TREE_TYPE (method_prototype))
       : objc_object_type);
  tree ftype = build_function_type_for_method (ret_type, method_prototype,
					       METHOD_REF, super_flag);
  tree sender_cast;

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

  if (check_for_nil)
    method_params = objc_copy_to_temp_side_effect_params (ftype,
							  method_params);

  /* Get &message_ref_t.messenger.  */
  sender = build_c_cast (input_location,
			 build_pointer_type (super_flag
					     ? objc_v2_super_imp_type
					     : objc_v2_imp_type),
			 selector);

  sender = build_indirect_ref (input_location, sender, RO_UNARY_STAR);

  rcv_p = (super_flag ? objc_super_type : objc_object_type);

  lookup_object = build_c_cast (input_location, rcv_p, lookup_object);

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

  method_params = tree_cons (NULL_TREE, lookup_object,
                             tree_cons (NULL_TREE, selector,
                                        method_params));
  t = build3 (OBJ_TYPE_REF, sender_cast, sender, lookup_object, size_zero_node);
  ret_val =  build_function_call (input_location, t, method_params);
  if (check_for_nil)
    {
      /* receiver != nil ? ret_val : 0 */
      tree ftree;
      tree ifexp;

      if (TREE_CODE (ret_type) == RECORD_TYPE
	  || TREE_CODE (ret_type) == UNION_TYPE)
	/* An empty constructor is zero-filled by the middle end.  */
	ftree = objc_build_constructor (ret_type, NULL);
      else
	ftree = fold_convert (ret_type, integer_zero_node);

      ifexp = build_binary_op (input_location, NE_EXPR,
			       lookup_object,
			       fold_convert (rcv_p, integer_zero_node), 1);

#ifdef OBJCPLUS
      ret_val = build_conditional_expr (input_location,
					ifexp, ret_val, ftree,
					tf_warning_or_error);
#else
      ret_val = build_conditional_expr (input_location,
					ifexp, 0,
					ret_val, NULL_TREE, input_location,
					ftree, NULL_TREE, input_location);
      ret_val = fold_convert (ret_type, ret_val);
#endif
    }
  return ret_val;
}

static tree
build_v2_build_objc_method_call (int super, tree method_prototype,
				 tree lookup_object, tree selector,
				 tree method_params, location_t loc,
				 bool check_for_nil, bool rx_is_id)
{
  tree sender, sender_cast, method, t;
  tree rcv_p = (super ? 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);

  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 an item that must be returned in memory, and the
     target ABI does this by an invisible pointer provided as the first arg,
     we need to adjust the message signature to include this.  The second
     part of this excludes targets that provide some alternate scheme for
     structure returns.  */
  if (ret_type && !VOID_TYPE_P (ret_type)
      && targetm.calls.return_in_memory (ret_type, 0)
      && !(targetm.calls.struct_value_rtx (0, 0)
	   && (TREE_CODE (ret_type) == RECORD_TYPE
	       || TREE_CODE (ret_type) == UNION_TYPE)))
    {
      if (super)
	sender = umsg_id_super2_stret_fixup_decl;
      else
	sender = rx_is_id ? umsg_id_stret_fixup_decl
			  : umsg_stret_fixup_decl;
    }
  else
    {
      if (super)
	sender = umsg_id_super2_fixup_decl;
      else
	sender = rx_is_id ? umsg_id_fixup_decl
			  : umsg_fixup_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);
  tree ret_val = build_function_call_vec (loc, vNULL, t, parms, NULL);
  vec_free (parms);
  if (check_for_nil)
    {
      /* receiver != nil ? ret_val : 0 */
      tree ftree;
      tree ifexp;

      if (TREE_CODE (ret_type) == RECORD_TYPE
	  || TREE_CODE (ret_type) == UNION_TYPE)
	{
	/* An empty constructor is zero-filled by the middle end.  */
	  ftree = objc_build_constructor (ret_type, NULL);
	}
      else
	ftree = fold_convert (ret_type, integer_zero_node);

      ifexp = build_binary_op (loc, NE_EXPR,
			       lookup_object,
			       fold_convert (rcv_p, integer_zero_node), 1);

#ifdef OBJCPLUS
      ret_val = build_conditional_expr (loc, ifexp, ret_val, ftree,
					tf_warning_or_error);
#else
      ret_val = build_conditional_expr (loc, ifexp, 1,
					ret_val, NULL_TREE, loc,
					ftree, NULL_TREE, loc);
      ret_val = fold_convert (ret_type, ret_val);
#endif
    }
  return ret_val;
}

static tree
next_runtime_abi_02_build_objc_method_call (location_t loc,
					    tree method_prototype,
					    tree receiver,
					    tree rtype,
					    tree sel_name,
					    tree method_params,
					    int super)
{
  /* Do we need to check for nil receivers ? */
  /* For now, message sent to classes need no nil check.  In the
      future, class declaration marked as weak_import must be nil
      checked.  */
  bool check_for_nil = flag_objc_nilcheck;
  if (super
      || (TREE_CODE (receiver) == VAR_DECL
	  && TREE_TYPE (receiver) == objc_class_type))
    check_for_nil = false;

  if (flag_next_runtime >= USE_FIXUP_BEFORE)
    {
      tree selector
	= next_runtime_abi_02_build_selector_reference (loc, sel_name,
						    method_prototype);
      return build_v2_build_objc_method_call (super, method_prototype,
					      receiver, selector,
					      method_params, loc,
					      check_for_nil,
					      objc_is_id (rtype));
    }

  /* else we have to build a pair of the function and selector.  */
  tree message_func_decl;
  tree  ret_type = method_prototype
	     ? TREE_VALUE (TREE_TYPE (method_prototype))
	     : objc_object_type;

  /* See comment for the fixup version above.  */
  if (ret_type && !VOID_TYPE_P (ret_type)
      && targetm.calls.return_in_memory (ret_type, 0)
      && !(targetm.calls.struct_value_rtx (0, 0)
	   && (TREE_CODE (ret_type) == RECORD_TYPE
	       || TREE_CODE (ret_type) == UNION_TYPE)))
    {
      if (super)
	message_func_decl = umsg_id_super2_stret_fixup_decl;
      else
	message_func_decl = objc_is_id (rtype)
			    ? umsg_id_stret_fixup_decl
			    : umsg_stret_fixup_decl;
    }
  else
    {
      if (super)
	message_func_decl = umsg_id_super2_fixup_decl;
      else
	message_func_decl = objc_is_id (rtype)
			    ? umsg_id_fixup_decl
			    : umsg_fixup_decl;
    }

  tree selector = build_v2_selector_messenger_reference (sel_name,
						      message_func_decl);

  /* selector = &_msg; */
  selector = build_unary_op (loc, ADDR_EXPR, selector, 0);

  selector = build_c_cast (loc, (super ? objc_v2_super_selector_type
				       : objc_v2_selector_type),
			   selector);

  /* (*_msg.messenger) (receiver, &_msg, ...); */
  return build_v2_objc_method_fixup_call (super, method_prototype, receiver,
					  selector, method_params,
					  check_for_nil);
}

/* NOTE --- Constant String Class Stuff --- */

static bool
next_runtime_abi_02_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, "OBJC_CLASS_$_%s", constant_string_class_name);
      constant_string_global_id = get_identifier (buf);
    }

  string_class_decl = lookup_name (constant_string_global_id);

  /* In OBJC2 abi, constant string class reference refers to class
     name for NSConstantString class.  This declaration may not be
     available yet (in fact it is not in most cases).  So, declare an
     extern OBJC_CLASS_$_NSConstantString in its place. */
  if (!string_class_decl)
    string_class_decl =
	create_extern_decl (objc_v2_class_template,
			    IDENTIFIER_POINTER (constant_string_global_id));

  return (string_class_decl != NULL_TREE);
}

static tree
next_runtime_abi_02_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;
}

/* NOTE --- NeXT V2 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 tree
build_v2_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;
}

/* struct ivar_t
   {
     unsigned long int *offset;
     char *name;
     char *type;
     uint32_t alignment;
     uint32_t size;
   };
*/

static tree
build_v2_ivar_t_template (void)
{
  tree objc_ivar_id, objc_ivar_record;
  tree decls, *chain = NULL;

  objc_ivar_id = get_identifier ("_ivar_t");
  objc_ivar_record = objc_start_struct (objc_ivar_id);

  /* unsigned long int *offset; */
  decls = add_field_decl (build_pointer_type
			   (TREE_TYPE (size_zero_node)), "offset", &chain);

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

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

  /* uint32_t alignment; */
  add_field_decl (integer_type_node, "alignment", &chain);

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

  objc_finish_struct (objc_ivar_record, decls);
  return objc_ivar_record;
}

static void
build_metadata_templates (void)
{

  if (!objc_method_template)
    objc_method_template = build_method_template ();

  if (!objc_v2_property_template)
    objc_v2_property_template = build_v2_property_template ();

  if (!objc_v2_ivar_template)
    objc_v2_ivar_template = build_v2_ivar_t_template ();

}

/* NOTE --- Output NeXT V2 Metadata --- */

/* Routine builds name of Interface's main meta-data of type class_t. */

static char *
objc_build_internal_classname (tree ident, bool metaclass)
{
  static char string[512];
  snprintf (string, 512, "%s_%s", metaclass ? "OBJC_METACLASS_$"
					    : "OBJC_CLASS_$",
	    IDENTIFIER_POINTER (ident));
  return string;
}

/* Build the name for object of type struct class_ro_t */

static const char *
newabi_append_ro (const char *name)
{
  const char *dollar;
  char *p;
  static char string[BUFSIZE];
  dollar = strchr (name, '$');
  gcc_assert (dollar);
  p = string;
  *p = '_'; p++;
  strncpy (p, name, (int)(dollar - name));
  p += (int)(dollar - name);
  sprintf (p, "RO_%s", dollar);
  return string;
}

/* Build the struct message_ref_t msg =
	       {objc_msgSend_fixup_xxx, @selector(func)}
   table.  */

static
void build_v2_message_ref_translation_table (void)
{
  int count;
  msgref_entry *ref;

  if (!vec_safe_length (msgrefs))
    return;

  FOR_EACH_VEC_ELT (*msgrefs, count, ref)
    {
      vec<constructor_elt, va_gc> *initializer;
      tree expr, constructor;
      tree struct_type = TREE_TYPE (ref->refdecl);
      location_t loc = DECL_SOURCE_LOCATION (ref->refdecl);

      initializer = NULL;
      /* First 'IMP messenger' field...  */
      expr = build_unary_op (loc, ADDR_EXPR, ref->func, 0);
      expr = convert (objc_v2_imp_type, expr);
      CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr);

      /* ... then 'SEL name' field.  */
      expr = build_selector (ref->selname);
      CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr);
      constructor = objc_build_constructor (struct_type, initializer);
      finish_var_decl (ref->refdecl, constructor);
    }
}

/* Build decl = initializer; for each externally visible class
   reference.  */

static void
build_v2_classrefs_table (void)
{
  int count;
  ident_data_tuple *ref;

  if (!vec_safe_length (classrefs))
    return;

  FOR_EACH_VEC_ELT (*classrefs, count, ref)
    {
      tree expr = ref->ident;
      tree decl = ref->data;
      /* Interface with no implementation and yet one of its messages
	 has been used. Need to generate a full address-of tree for it
	 here.  */
      if (TREE_CODE (expr) == IDENTIFIER_NODE)
        {
          const char *name = objc_build_internal_classname (expr, false);
          expr = create_extern_decl (objc_v2_class_template, name);
	  expr = convert (objc_class_type, build_fold_addr_expr (expr));
	}
      /* The runtime wants this, even if it appears unused, so we must force the
	 output.
      DECL_PRESERVE_P (decl) = 1; */
      finish_var_decl (decl, expr);
    }
}

/* Build decl = initializer; for each externally visible super class
   reference.  */

static void
build_v2_super_classrefs_table (bool metaclass)
{
  int count;
  ident_data_tuple *ref;
  vec<ident_data_tuple, va_gc> *list = metaclass  ? metaclass_super_refs
						: class_super_refs;

  if (!vec_safe_length (list))
    return;

  FOR_EACH_VEC_ELT (*list, count, ref)
    {
      tree expr = ref->ident;
      tree decl = ref->data;
      /* Interface with no implementation and yet one of its messages
	 has been used. Need to generate a full address-of tree for it
	 here.  */
      if (TREE_CODE (expr) == IDENTIFIER_NODE)
	{
	  const char * name = objc_build_internal_classname (expr, metaclass);
          expr = create_extern_decl (objc_v2_class_template, name);
	  expr = convert (objc_class_type, build_fold_addr_expr (expr));
	}
      finish_var_decl (decl, expr);
    }
}

/* Add the global class meta-data declaration to the list which later
   on ends up in the __class_list section.  */

static GTY(()) vec<tree, va_gc> *class_list;

static void
objc_v2_add_to_class_list (tree global_class_decl)
{
  vec_safe_push (class_list, global_class_decl);
}

static GTY(()) vec<tree, va_gc> *nonlazy_class_list;

/* Add the global class meta-data declaration to the list which later
   on ends up in the __nonlazy_class section.  */

static void
objc_v2_add_to_nonlazy_class_list (tree global_class_decl)
{
  vec_safe_push (nonlazy_class_list, global_class_decl);
}

static GTY(()) vec<tree, va_gc> *category_list;

/* Add the category meta-data declaration to the list which later on
   ends up in the __nonlazy_category section.  */

static void
objc_v2_add_to_category_list (tree decl)
{
  vec_safe_push (category_list, decl);
}

static GTY(()) vec<tree, va_gc> *nonlazy_category_list;

/* Add the category meta-data declaration to the list which later on
   ends up in the __category_list section.  */

static void
objc_v2_add_to_nonlazy_category_list (tree decl)
{
  vec_safe_push (nonlazy_category_list, decl);
}

static bool
has_load_impl (tree clsmeth)
{
  while (clsmeth)
    {
      tree id = METHOD_SEL_NAME (clsmeth);
      if (IDENTIFIER_LENGTH (id) == 4
	  && startswith (IDENTIFIER_POINTER (id), "load"))
        return true;
      clsmeth = DECL_CHAIN (clsmeth);
    }

  return false;
}

/* Build a __{class,category}_list section table containing address of
   all @implemented {class,category} meta-data.  */

static void
build_v2_address_table (vec<tree, va_gc> *src, const char *nam, tree attr)
{
  int count=0;
  tree type, decl, expr;
  vec<constructor_elt, va_gc> *initlist = NULL;

  if (!vec_safe_length (src))
    return;

  FOR_EACH_VEC_ELT (*src, count, decl)
    {
#ifndef OBJCPLUS
      tree purpose = build_int_cst (NULL_TREE, count);
#else
      tree purpose = NULL_TREE;
#endif
      expr = convert (objc_class_type, build_fold_addr_expr (decl));
      CONSTRUCTOR_APPEND_ELT (initlist, purpose, expr);
    }
  gcc_assert (count > 0);
  type = build_array_type (objc_class_type,
			   build_index_type (build_int_cst (NULL_TREE, count - 1)));
  decl = start_var_decl (type, nam);
  /* The runtime wants this, even if it appears unused, so we must
     force the output.  */
  DECL_PRESERVE_P (decl) = 1;
  expr = objc_build_constructor (type, initlist);
  OBJCMETA (decl, objc_meta, attr);
  finish_var_decl (decl, expr);
}

/* Build decl = initializer; for each protocol referenced in
   @protocol(MyProt) expression.  Refs as built in the entry section
   above.  */

static void
build_v2_protocol_list_translation_table (void)
{
  int count;
  prot_list_entry *ref;

  if (!protrefs)
    return;

  FOR_EACH_VEC_ELT (*protrefs, count, ref)
    {
      char buf[BUFSIZE];
      tree expr;
      gcc_assert (TREE_CODE (ref->id) == PROTOCOL_INTERFACE_TYPE);
      snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s",
		IDENTIFIER_POINTER (PROTOCOL_NAME (ref->id)));
      expr = start_var_decl (objc_v2_protocol_template, buf);
      expr = convert (objc_protocol_type, build_fold_addr_expr (expr));
      finish_var_decl (ref->refdecl, expr);
    }
  /* TODO: Maybe we could explicitly delete the vec. now?  */
}

static GTY (()) vec<prot_list_entry, va_gc> *protlist;

/* Add the local protocol meta-data declaration to the list which
   later on ends up in the __protocol_list section.  */

static void
objc_add_to_protocol_list (tree protocol_interface_decl, tree protocol_decl)
{
  prot_list_entry e;
  if (!protlist)
    /* Arbitrary init count.  */
    vec_alloc (protlist, 32);
  e.id = protocol_interface_decl;
  e.refdecl = protocol_decl;
  vec_safe_push (protlist, e);
}

/* Build the __protocol_list section table containing address of all
   generate protocol_t meta-data.  */

static void
build_v2_protocol_list_address_table (void)
{
  int count;
  prot_list_entry *ref;
  if (!vec_safe_length (protlist))
    return;

  FOR_EACH_VEC_ELT (*protlist, count, ref)
    {
      tree decl, expr;
      char buf[BUFSIZE];
      gcc_assert (ref->id && TREE_CODE (ref->id) == PROTOCOL_INTERFACE_TYPE);
      snprintf (buf, BUFSIZE, "_OBJC_LabelProtocol_%s",
		IDENTIFIER_POINTER (PROTOCOL_NAME (ref->id)));
      if (flag_next_runtime >= USE_FIXUP_BEFORE)
	{
	  decl = create_hidden_decl (objc_protocol_type, buf, /*is def=*/true);
	  DECL_WEAK (decl) = true;
	}
      else
	decl = create_global_decl (objc_protocol_type, buf, /*is def=*/true);
      expr = convert (objc_protocol_type, build_fold_addr_expr (ref->refdecl));
      OBJCMETA (decl, objc_meta, meta_label_protocollist);
      finish_var_decl (decl, expr);
    }

    /* TODO: delete the vec.  */
    /* TODO: upgrade to the clang/llvm hidden version.  */
}

/* This routine declares a variable to hold meta data for 'struct
   protocol_list_t'.  */

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

  if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
      || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
    plist = CLASS_PROTOCOL_LIST (i_or_p);
  else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
    plist = PROTOCOL_LIST (i_or_p);
  else
    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.  */

  ptempl_p_t = build_pointer_type (objc_v2_protocol_template);
  e = build_int_cst (ptempl_p_t, size);
  CONSTRUCTOR_APPEND_ELT (initlist, 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 (initlist, NULL_TREE, e);
	}
    }

  /* static struct protocol_list_t *list[size]; */

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

  refs_decl = start_var_decl (build_sized_array_type (ptempl_p_t, size+1),
			      buf);
  /* ObjC2 puts all these in the base section.  */
  OBJCMETA (refs_decl, objc_meta, meta_base);
  DECL_PRESERVE_P (refs_decl) = 1;
  finish_var_decl (refs_decl,
		   objc_build_constructor (TREE_TYPE (refs_decl),initlist));
  return refs_decl;
}

/* This routine builds one 'struct method_t' initializer list. Note
   that the old ABI is supposed to build 'struct objc_method' which
   has 3 fields, but it does not build the initialization expression
   for 'method_imp' which for protocols is NULL any way.  To be
   consistent with declaration of 'struct method_t', in the new ABI we
   set the method_t.imp to NULL.  */

static tree
build_v2_descriptor_table_initializer (tree type, tree entries)
{
  vec<constructor_elt, va_gc> *initlist = NULL;
  do
    {
      vec<constructor_elt, va_gc> *eltlist = NULL;
      CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE,
			      build_selector (METHOD_SEL_NAME (entries)));
      CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE,
			      add_objc_string (METHOD_ENCODING (entries),
						meth_var_types));
      CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE, null_pointer_node);

      CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
			      objc_build_constructor (type, eltlist));
      entries = TREE_CHAIN (entries);
    }
  while (entries);

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

/* struct method_list_t
  {
     uint32_t entsize;
     uint32_t method_count;
     struct objc_method method_list[method_count];
   }; */

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

  method_list_t_record = objc_start_struct (NULL_TREE);

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

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

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

  objc_finish_struct (method_list_t_record, decls);
  return method_list_t_record;
}

/* Note, as above that we are building to the objc_method_template
   which has the *imp field.  ABI0/1 build with
   objc_method_prototype_template which is missing this field.  */
static tree
generate_v2_meth_descriptor_table (tree chain, tree protocol,
				   const char *prefix, tree attr,
				   vec<tree>& all_meths)
{
  tree method_list_template, initlist, decl;
  int size, entsize;
  vec<constructor_elt, va_gc> *v = NULL;
  char buf[BUFSIZE];

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

  tree method = chain;
  size = 0;
  while (method)
    {
      if (! METHOD_ENCODING (method))
	METHOD_ENCODING (method) = encode_method_prototype (method);
      all_meths.safe_push (method);
      method = TREE_CHAIN (method);
      size++;
    }

  gcc_assert (size);
  method_list_template = build_v2_method_list_template (objc_method_template,
							size);
  snprintf (buf, BUFSIZE, "%s_%s", prefix,
	    IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));

  decl = start_var_decl (method_list_template, buf);

  entsize = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_method_template));
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, entsize));
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
  initlist =
	build_v2_descriptor_table_initializer (objc_method_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;
}

static tree
generate_v2_meth_type_list (vec<tree>& all_meths, tree protocol,
			    const char *prefix)
{
  if (all_meths.is_empty () || !prefix)
    return NULL_TREE;

  unsigned size = all_meths.length ();
  tree list_type = build_sized_array_type (string_type_node, size);
  char *nam;
  asprintf (&nam, "%s_%s", prefix,
	    IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));
  tree decl = start_var_decl (list_type, nam);
  free (nam);
  OBJCMETA (decl, objc_meta, meta_base);
  vec<constructor_elt, va_gc> *v = NULL;

  for (unsigned i = 0; i < size; ++i)
    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			    add_objc_string (METHOD_ENCODING (all_meths[i]),
					     meth_var_types));
  finish_var_decl (decl, objc_build_constructor (list_type, v));
  return decl;
}

/* 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_v2_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;
      /* NOTE! sections where property name/attribute go MUST change
	 later.  */
      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 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_v2_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;
}

/* Top-level routine to generate property tables for each
   implementation.  */

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

  property_list_template =
	build_v2_property_list_template (objc_v2_property_template,
					 size);

  initlist = build_v2_property_table_initializer (objc_v2_property_template,
						  is_proto ? context
							   : klass_ctxt);

  init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_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);

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

static tree
build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list,
			      tree inst_methods, tree class_methods,
			      tree opt_ins_meth, tree opt_cls_meth,
			      tree property_list, tree ext_meth_types,
			      tree demangled_name, tree class_prop_list)
{
  tree expr, ttyp;
  location_t loc;
  vec<constructor_elt, va_gc> *inits = NULL;

  /* TODO: find a better representation of location from the inputs.  */
  loc = UNKNOWN_LOCATION;

  /*  This is NULL for the new ABI.  */
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
			      convert (objc_object_type, null_pointer_node));

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

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

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

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

  /* const uint32_t size;  = sizeof(struct protocol_t) */
  expr = build_int_cst (integer_type_node,
	      TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_protocol_template)));
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
  /* const uint32_t flags; = 0 */
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, integer_zero_node);

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

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

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

 return objc_build_constructor (type, inits);
}

/* Main routine to build all meta data for all protocols used in a
   translation unit.  */

static void
generate_v2_protocols (void)
{
  tree p ;
  bool some = false;

  if (!protocol_chain)
    return ;

  /* 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))
    {
      location_t loc;
      tree inst_meth, class_meth, opt_inst_meth, opt_class_meth, props;
      tree decl, initlist, protocol_name_expr, refs_decl, refs_expr;

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

      if (!decl)
	continue;

      loc = DECL_SOURCE_LOCATION (decl);
      some = true;

      vec<tree> all_meths = vNULL;
      inst_meth =
	generate_v2_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p,
					   "_OBJC_ProtocolInstanceMethods",
					   meta_proto_nst_meth, all_meths);

      class_meth =
	generate_v2_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p,
					   "_OBJC_ProtocolClassMethods",
					   meta_proto_cls_meth, all_meths);

      opt_inst_meth =
	generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_NST_METHODS (p), p,
					   "_OBJC_ProtocolOptInstMethods",
					   meta_proto_nst_meth, all_meths);

      opt_class_meth =
	generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_CLS_METHODS (p), p,
					   "_OBJC_ProtocolOptClassMethods",
					   meta_proto_cls_meth, all_meths);

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

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

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

      props = generate_v2_property_table (p, NULL_TREE);

      tree ext_meth_types
	= generate_v2_meth_type_list (all_meths, p,
				      "_OBJC_ProtocolMethodTypes");
      tree demangled_name = NULL_TREE;
      tree class_prop_list = NULL_TREE;

      initlist = build_v2_protocol_initializer (TREE_TYPE (decl),
						protocol_name_expr, refs_expr,
						inst_meth, class_meth,
						opt_inst_meth, opt_class_meth,
						props, ext_meth_types,
						demangled_name,class_prop_list);
      finish_var_decl (decl, initlist);
      objc_add_to_protocol_list (p, decl);
      all_meths.truncate (0);
    }

  if (some)
    {
      /* Make sure we get the Protocol class linked in - reference
	 it...  */
      p = objc_v2_get_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
      /* ... but since we don't specifically use the reference...  we
         need to force it.  */
      DECL_PRESERVE_P (p) = 1;
    }
}

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

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

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

  decl = start_var_decl  (method_list_template, name);

  init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_method_template));
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			  build_int_cst (integer_type_node, init_val));
  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_v2_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 (objc_v2_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);

  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 category_t _OBJC_CATEGORY_$_<name> = { ... }; */

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

  loc = DECL_SOURCE_LOCATION (cat_decl);

  /* ??? not sure this is really necessary, the following references should
     force appropriate linkage linkage...
     -- but ... ensure a reference to the class...  */
  t = objc_v2_get_class_reference (CLASS_NAME (cat));
  /* ... which we ignore so force it out.. */
  DECL_PRESERVE_P (t) = 1;

  snprintf (buf, BUFSIZE, "OBJC_CLASS_$_%s", IDENTIFIER_POINTER (CLASS_NAME (cat)));
  class_name_expr = create_extern_decl (objc_v2_class_template, buf);
  class_name_expr = build_fold_addr_expr (class_name_expr);

  cat_name_expr = add_objc_string (CLASS_SUPER_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_v2_protocol_list (category, cat);
    }
  else
    protocol_decl = NULL_TREE;

/* decl = update_var_decl(impent->class_decl); */

  props = generate_v2_property_table (NULL_TREE, cat);

  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_v2_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_v2_dispatch_table (CLASS_CLS_METHODS (cat), buf,
						  meta_catc_meth);
    }

  initlist = build_v2_category_initializer (TREE_TYPE (cat_decl),
					    cat_name_expr, class_name_expr,
					    inst_methods, class_methods,
					    protocol_decl, props, loc);

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

  /* Add to list of pointers in __category_list section.  */
  objc_v2_add_to_category_list (cat_decl);
  if (has_load_impl (CLASS_CLS_METHODS (impent->imp_context)))
    objc_v2_add_to_nonlazy_category_list (cat_decl);
}

/* This routine declares a variable to hold the offset for ivar
   FIELD_DECL.  Variable name is .objc_ivar.ClassName.IvarName.  */

struct GTY(()) ivarref_entry
{
  tree decl;
  tree offset;
};

static GTY (()) vec<ivarref_entry, va_gc> *ivar_offset_refs;

static tree
ivar_offset_ref (tree class_name, tree field_decl)
{
  tree decl, field_decl_id;
  ivarref_entry e;
  bool global_var;
  char buf[512];

  create_ivar_offset_name (buf, class_name, field_decl);
  field_decl_id = get_identifier (buf);

  if (ivar_offset_refs)
    {
      int count;
      ivarref_entry *ref;
      FOR_EACH_VEC_ELT (*ivar_offset_refs, count, ref)
	if (DECL_NAME (ref->decl) == field_decl_id)
	  return ref->decl;
    }
  else
    /* Somewhat arbitrary initial provision.  */
    vec_alloc (ivar_offset_refs, 32);

  /* We come here if we don't find a match or at the start.  */
  global_var = (TREE_PUBLIC (field_decl) || TREE_PROTECTED (field_decl));
  if (global_var)
    decl = create_global_decl (TREE_TYPE (size_zero_node), buf);
  else
    decl = create_hidden_decl (TREE_TYPE (size_zero_node), buf);

  /* Identify so that we can indirect these where the ABI requires.  */
  OBJCMETA (decl, objc_meta, meta_ivar_ref);

  e.decl = decl;
  e.offset = byte_position (field_decl);
  vec_safe_push (ivar_offset_refs, e);
  return decl;
}

/* This routine builds initializer-list needed to initialize 'struct
   ivar_t list[count] of 'struct ivar_list_t' meta data. TYPE is
   'struct ivar_t' and FIELD_DECL is list of ivars for the target
   class.  */

static tree
build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl)
{
  vec<constructor_elt, va_gc> *inits = NULL;

  do
    {
      vec<constructor_elt, va_gc> *ivar = NULL;
      int val;
      tree id;

      /* Unnamed bitfields are ignored.  */
      if (!DECL_NAME (field_decl))
	{
	  field_decl = DECL_CHAIN (field_decl);
	  continue;
	}

      /* Set offset.  */
      CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
			      build_unary_op (input_location,
					      ADDR_EXPR,
					      ivar_offset_ref (class_name,
							       field_decl), 0));

      /* Set name.  */
      CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
			      add_objc_string (DECL_NAME (field_decl),
						meth_var_names));

      /* Set type.  */
      id = add_objc_string (encode_field_decl (field_decl),
                            meth_var_types);
      CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);

      /* Set alignment.  */
      val = DECL_ALIGN_UNIT (field_decl);
      val = exact_log2 (val);
      CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
			      build_int_cst (integer_type_node, val));

      /* Set size.  */
      val = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field_decl));
      CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
			      build_int_cst (integer_type_node, val));

      CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
			      objc_build_constructor (type, ivar));

      do
	field_decl = DECL_CHAIN (field_decl);
      while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
    }
  while (field_decl);

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

/*
  struct ivar_list_t
  {
    uint32 entsize;
    uint32 count;
    struct iver_t list[count];
  };
*/

static tree
build_v2_ivar_list_t_template (tree list_type, int size)
{
  tree objc_ivar_list_record;
  tree decls, *chain = NULL;

  /* Anonymous.  */
  objc_ivar_list_record = objc_start_struct (NULL_TREE);

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

  /* uint32 count; */
  add_field_decl (integer_type_node, "count", &chain);

  /* struct objc_ivar ivar_list[]; */
  add_field_decl (build_sized_array_type (list_type, size),
			  "list", &chain);

  objc_finish_struct (objc_ivar_list_record, decls);
  return objc_ivar_list_record;
}

/* This routine declares a static variable of type 'struct
   ivar_list_t' and initializes it.  chain is the source of the data,
   name is the name for the var.  attr is the meta-data section tag
   attribute.  templ is the implementation template for the class.  */

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

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

  generating_instance_variables = 1;
  ivar_list_template = build_v2_ivar_list_t_template (objc_v2_ivar_template,
						      size);

  initlist = build_v2_ivar_list_initializer (CLASS_NAME (templ),
					     objc_v2_ivar_template, chain);
  ivar_t_size = TREE_INT_CST_LOW  (TYPE_SIZE_UNIT (objc_v2_ivar_template));

  decl = start_var_decl (ivar_list_template, name);
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
			  build_int_cst (integer_type_node, ivar_t_size));
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
			  build_int_cst (integer_type_node, size));
  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
  OBJCMETA (decl, objc_meta, attr);
  finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), inits));
  generating_instance_variables = 0;
  return decl;
}

/* Routine to build initializer list to initialize objects of type
   struct class_t; */

static tree
build_v2_class_t_initializer (tree type, tree isa, tree superclass,
			      tree ro, tree cache, tree vtable)
{
  vec<constructor_elt, va_gc> *initlist = NULL;

  /* isa */
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, isa);

  /* superclass */
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, superclass);

  /* cache */
  if (cache)
    CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, cache);
  else
    CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, null_pointer_node);

  /* vtable */
  if (vtable)
    CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, vtable);
  else
    CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, null_pointer_node);

  /* ro */
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, ro);

  return objc_build_constructor (type, initlist);
}

/* Routine to build object of struct class_ro_t { ... }; */

static tree
build_v2_class_ro_t_initializer (tree type, tree name,
			       unsigned int flags, unsigned int instanceStart,
			       unsigned int instanceSize,
			       tree ivarLayout,
			       tree baseMethods, tree baseProtocols,
			       tree ivars, tree property_list)
{
  tree expr, unsigned_char_star, ltyp;
  location_t loc;
  vec<constructor_elt, va_gc> *initlist = NULL;

  /* TODO: fish out the real location from somewhere.  */
  loc = UNKNOWN_LOCATION;

  /* flags */
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
			  build_int_cst (integer_type_node, flags));

  /* instanceStart */
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
			  build_int_cst (integer_type_node, instanceStart));

  /* instanceSize */
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
			  build_int_cst (integer_type_node, instanceSize));

  /* This ABI is currently only used on m64 NeXT.  We always
     explicitly declare the alignment padding.  */
  /* reserved, pads alignment.  */
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
			    build_int_cst (integer_type_node, 0));

  /* ivarLayout */
  unsigned_char_star = build_pointer_type (unsigned_char_type_node);
  if (ivarLayout)
    expr = ivarLayout;
  else
    expr = convert (unsigned_char_star, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr);

  /* name */
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, default_conversion (name));

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

  /* baseProtocols */
  ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
			               get_identifier (UTAG_V2_PROTOCOL_LIST)));
  if (baseProtocols)
    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, baseProtocols, 0));
  else
    expr = convert (ltyp, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr);

  /* ivars */
  ltyp = objc_v2_ivar_list_ptr;
  if (ivars)
    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, ivars, 0));
  else
    expr = convert (ltyp, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr);

  /* TODO: We don't yet have the weak/strong stuff...  */
  /* weakIvarLayout */
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
			  convert (unsigned_char_star, null_pointer_node));

  /* property list */
  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 (initlist, NULL_TREE, expr);
  return objc_build_constructor (type, initlist);
}

static GTY (()) vec<ident_data_tuple, va_gc> *ehtype_list;

/* Record a name as needing a catcher.  */
static void
objc_v2_add_to_ehtype_list (tree name)
{
  ident_data_tuple e;
  if (ehtype_list)
    {
      int count = 0;
      ident_data_tuple *ref;

      FOR_EACH_VEC_ELT (*ehtype_list, count, ref)
	if (ref->ident == name)
	  return; /* Already entered.  */
     }
  else
    /* Arbitrary initial count.  */
    vec_alloc (ehtype_list, 8);

  /* Not found, or new list.  */
  e.ident = name;
  e.data = NULL_TREE;
  vec_safe_push (ehtype_list, e);
}

static void
generate_v2_class_structs (struct imp_entry *impent)
{
  tree decl, name_expr, initlist, protocol_decl, metaclass_decl, class_decl;
  tree field, firstIvar, chain;
  tree class_superclass_expr, metaclass_superclass_expr, props;
  /* TODO: figure out how to compute this.  */
  tree ivarLayout = NULL_TREE;
  tree my_super_id = NULL_TREE, root_expr = NULL_TREE;
  tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
  tree inst_ivars = NULL_TREE, class_ivars = NULL_TREE;
  location_t loc;
  char buf[BUFSIZE];
  unsigned int instanceStart, instanceSize;
  unsigned int flags = 0x01; /* RO_META */
  int cls_flags = impent->has_cxx_cdtors ? OBJC2_CLS_HAS_CXX_STRUCTORS
					 : 0 ;

  class_decl = impent->class_decl;
  metaclass_decl = impent->meta_decl;
  loc = DECL_SOURCE_LOCATION (class_decl);

  DECL_EXTERNAL (class_decl) = DECL_EXTERNAL (metaclass_decl) = 0;
  TREE_PUBLIC (class_decl) = TREE_PUBLIC (metaclass_decl) = 1;
#ifdef OBJCPLUS
  gcc_assert (!CP_DECL_CONTEXT (class_decl) || CP_DECL_CONTEXT (class_decl) == global_namespace);
  gcc_assert (!CP_DECL_CONTEXT (metaclass_decl) || CP_DECL_CONTEXT (metaclass_decl) == global_namespace);
#endif

  /* Generation of data for meta class.  */
  my_super_id = CLASS_SUPER_NAME (impent->imp_template);
  if (my_super_id)
    {
      /* Compute reference to root's name.  For a meta class, "isa" is
	 a reference to the root class name. */
      tree my_root_id = my_super_id;
      tree my_root_int, interface;
      do
        {
          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);

      /* {extern} struct class_t OBJC_METACLASS_$_<my_root_int>
         create extern if not already declared.  */
      snprintf (buf, BUFSIZE, "OBJC_METACLASS_$_%s",
		IDENTIFIER_POINTER (CLASS_NAME (my_root_int)));
      root_expr = create_extern_decl (objc_v2_class_template, buf);
      root_expr = build_fold_addr_expr (root_expr);

      /* Install class `isa' and `super' pointers at runtime.  */
      interface = lookup_interface (my_super_id);
      gcc_assert (interface);
      /* Similarly, for OBJC_CLASS_$_<interface>...  */
      snprintf (buf, BUFSIZE, "OBJC_CLASS_$_%s",
		IDENTIFIER_POINTER (CLASS_NAME (interface)));
      class_superclass_expr = create_extern_decl (objc_v2_class_template, buf);
      class_superclass_expr = build_fold_addr_expr (class_superclass_expr);
      /* ... and for OBJC_METACLASS_$_<interface>.  */
      snprintf (buf, BUFSIZE, "OBJC_METACLASS_$_%s",
		IDENTIFIER_POINTER (CLASS_NAME (interface)));
      metaclass_superclass_expr = create_extern_decl (objc_v2_class_template, buf);
      metaclass_superclass_expr = build_fold_addr_expr (metaclass_superclass_expr);
    }
  else
    {
      /* Root class.  */
      root_expr = build_unary_op (loc, ADDR_EXPR, metaclass_decl, 0);
      metaclass_superclass_expr = build_unary_op (loc, ADDR_EXPR, class_decl, 0);
      class_superclass_expr = build_int_cst (NULL_TREE, 0);
      flags |= 0x02; /* RO_ROOT: it is also a root meta class.  */
    }

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

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

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

  instanceStart = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_class_template));

  /* Currently there are no class ivars and generation of class
     variables for the root of the inheritance has been removed.  It
     causes multiple defines if there are two root classes in the
     link, because each will define its own identically-named offset
     variable.  */

  class_ivars = NULL_TREE;
  /* TODO: Add total size of class variables when implemented. */
  instanceSize = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_class_template));

  /* So now build the META CLASS structs.  */
  /* static struct class_ro_t  _OBJC_METACLASS_Foo = { ... }; */

  decl = start_var_decl (objc_v2_class_ro_template,
			 newabi_append_ro (IDENTIFIER_POINTER
						(DECL_NAME (metaclass_decl))));

  /* TODO: ivarLayout needs t be built.  */
  initlist =
	build_v2_class_ro_t_initializer (TREE_TYPE (decl), name_expr,
					(flags | cls_flags), instanceStart,
					instanceSize, ivarLayout,
					class_methods, protocol_decl,
					class_ivars, NULL_TREE);
  /* The ROs sit in the default const section.  */
  OBJCMETA (decl, objc_meta, meta_base);
  finish_var_decl (decl, initlist);

  /* static struct class_t _OBJC_METACLASS_Foo = { ... }; */
  initlist =
	build_v2_class_t_initializer (TREE_TYPE (metaclass_decl),
				      root_expr,
				      metaclass_superclass_expr,
				      build_fold_addr_expr (decl),
				      build_fold_addr_expr (UOBJC_V2_CACHE_decl),
				      build_fold_addr_expr (UOBJC_V2_VTABLE_decl));
  /* The class section attributes are set when they are created.  */
  finish_var_decl (metaclass_decl, initlist);
  impent->meta_decl = metaclass_decl;

  /* So now build the CLASS structs.  */

  flags = 0x0;		/* ... */
  if (!my_super_id)
    flags |= 0x02;	/* RO_ROOT: this is a root class */

  if (DECL_VISIBILITY (class_decl) == VISIBILITY_HIDDEN)
    flags |= 0x10;	/* RO_HIDDEN, OBJC2_CLS_HIDDEN; */

  if (objc2_objc_exception_attr (impent->imp_template))
    flags |= 0x20;	/* RO_EXCEPTION */

  if (CLASS_NST_METHODS (impent->imp_context))
    {
      snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s",
		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
      inst_methods =
	generate_v2_dispatch_table (CLASS_NST_METHODS (impent->imp_context),
				    buf, meta_clai_meth);
    }

  /* Sort out the ivars before we try to compute the class sizes.  */
  if ((chain = CLASS_IVARS (impent->imp_template)))
    {
      snprintf (buf, BUFSIZE, "_OBJC_InstanceIvars_%s",
		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
      inst_ivars = generate_v2_ivars_list (chain, buf, meta_clai_vars,
					   impent->imp_template);
    }

  /* Compute instanceStart.  */
  gcc_assert (CLASS_STATIC_TEMPLATE (impent->imp_template));
  field = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (impent->imp_template));
  if (my_super_id && field && TREE_CHAIN (field))
    field = TREE_CHAIN (field);

  firstIvar = field;

  while (firstIvar && TREE_CODE (firstIvar) != FIELD_DECL)
    firstIvar = TREE_CHAIN (firstIvar);

  gcc_assert (inst_ivars? (firstIvar != NULL_TREE): true);

  /* Compute instanceSize.  */
  while (field && TREE_CHAIN (field)
         && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
    field = TREE_CHAIN (field);

  if (field && TREE_CODE (field) == FIELD_DECL)
    instanceSize = int_byte_position (field) * BITS_PER_UNIT
		   + tree_to_shwi (DECL_SIZE (field));
  else
    instanceSize = 0;
  instanceSize /= BITS_PER_UNIT;

  props = generate_v2_property_table (NULL_TREE, impent->imp_context);

  /* If the class has no ivars, instanceStart should be set to the
     superclass's instanceSize.  */
  instanceStart =
	(inst_ivars != NULL_TREE) ? (unsigned) int_byte_position (firstIvar)
				  : instanceSize;

  /* static struct class_ro_t  _OBJC_CLASS_Foo = { ... }; */
  decl = start_var_decl (objc_v2_class_ro_template,
			 newabi_append_ro (IDENTIFIER_POINTER
						(DECL_NAME (class_decl))));

  initlist =
	build_v2_class_ro_t_initializer (TREE_TYPE (decl), name_expr,
					 (flags | cls_flags), instanceStart,
					 instanceSize, ivarLayout,
					 inst_methods, protocol_decl,
					 inst_ivars, props);
  /* The ROs sit in the default const section.  */
  OBJCMETA (decl, objc_meta, meta_base);
  finish_var_decl (decl, initlist);

  /* static struct class_t _OBJC_CLASS_Foo = { ... }; */
  initlist = build_v2_class_t_initializer (TREE_TYPE (class_decl),
					build_fold_addr_expr (metaclass_decl),
					class_superclass_expr,
					build_fold_addr_expr (decl),
					build_fold_addr_expr (UOBJC_V2_CACHE_decl),
					build_fold_addr_expr (UOBJC_V2_VTABLE_decl));

  /* The class section attributes are set when they are created.  */
  finish_var_decl (class_decl, initlist);
  impent->class_decl = class_decl;

  objc_v2_add_to_class_list (class_decl);
  if (has_load_impl (CLASS_CLS_METHODS (impent->imp_context)))
    objc_v2_add_to_nonlazy_class_list (class_decl);

  if (flags & 0x20) /* RO_EXCEPTION */
    objc_v2_add_to_ehtype_list (CLASS_NAME (impent->imp_template));
}

/* This routine outputs the (ivar_reference_offset, offset)
   tuples.  */

static void
build_v2_ivar_offset_ref_table (void)
{
  int count;
  ivarref_entry *ref;

  if (!vec_safe_length (ivar_offset_refs))
    return;

  FOR_EACH_VEC_ELT (*ivar_offset_refs, count, ref)
    finish_var_decl (ref->decl, ref->offset);
}

static void
objc_generate_v2_next_metadata (void)
{
  struct imp_entry *impent;

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

  gcc_assert (!objc_static_instances); /* Not for NeXT */

  build_metadata_templates ();

  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_v2_class_structs (impent);
      else
	generate_v2_category (impent);
    }

  build_next_selector_translation_table ();
  build_v2_message_ref_translation_table ();

  /* This will add "Protocol" to the class refs.  */
  generate_v2_protocols ();

  build_v2_classrefs_table ();
  build_v2_super_classrefs_table (/*metaclass= */false);
  build_v2_super_classrefs_table (/*metaclass= */true);

  build_v2_ivar_offset_ref_table ();

  build_v2_protocol_list_translation_table ();
  build_v2_protocol_list_address_table ();

  build_v2_address_table (class_list, "_OBJC_ClassList$",
			  meta_label_classlist);
  build_v2_address_table (category_list, "_OBJC_CategoryList$",
			  meta_label_categorylist);
  build_v2_address_table (nonlazy_class_list, "_OBJC_NonLazyClassList$",
			  meta_label_nonlazy_classlist);
  build_v2_address_table (nonlazy_category_list, "_OBJC_NonLazyCategoryList$",
			  meta_label_nonlazy_categorylist);

  /* Generate catch objects for eh, if any are needed.  */
  build_v2_eh_catch_objects ();

  /* Emit the string table last.  */
  generate_strings ();
}

/* NOTE --- Output NeXT V2 Exceptions --- */

static GTY(()) tree objc_v2_ehtype_template;
static GTY(()) tree next_v2_ehvtable_decl;
static GTY(()) tree next_v2_EHTYPE_id_decl;

static void
build_v2_ehtype_template (void)
{
  tree decls, *chain = NULL;
  objc_v2_ehtype_template = objc_start_struct (get_identifier (UTAG_V2_EH_TYPE));

  /* void *_objc_ehtype_vtable; */
  decls = add_field_decl (ptr_type_node, "_objc_ehtype_vtable_ptr", &chain);

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

  /* struct class_t *const cls; */
  add_field_decl (build_pointer_type (objc_v2_class_template), "cls", &chain);

  objc_finish_struct (objc_v2_ehtype_template, decls);
}

/* Template for the Objective-C family typeinfo type for ABI=2.  This
   starts off the same as the gxx/cxx eh typeinfo.

   struct _objc_ehtype_t
   {
     void *_objc_ehtype_vtable_ptr;	- as per c++
     const char *className;		- as per c++
     struct class_t *const cls;
   }
*/

/* This routine builds initializer list for object of type struct _objc_ehtype_t.
*/

static tree
objc2_build_ehtype_initializer (tree name, tree cls)
{
  vec<constructor_elt, va_gc> *initlist = NULL;
  tree addr, offs;

  /* This is done the same way as c++, missing the two first entries
     in the parent vtable.  NOTE: there is a fix-me in the Apple/NeXT
     runtime source about this so, perhaps, this will change at some
     point.  */
  /* _objc_ehtype_vtable + 2*sizeof(void*)  */
  if (!next_v2_ehvtable_decl)
    {
      next_v2_ehvtable_decl =
			start_var_decl (ptr_type_node, TAG_NEXT_EHVTABLE_NAME);
      TREE_STATIC (next_v2_ehvtable_decl) = 0;
      DECL_EXTERNAL (next_v2_ehvtable_decl) = 1;
      TREE_PUBLIC (next_v2_ehvtable_decl) = 1;
    }
  addr = build_fold_addr_expr_with_type (next_v2_ehvtable_decl, ptr_type_node);
  offs = size_int (2 * int_cst_value (TYPE_SIZE_UNIT (ptr_type_node)));
  addr = fold_build_pointer_plus (addr, offs);

  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, addr);

  /* className */
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, name);

  /* cls */
  CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, cls);

  return objc_build_constructor (objc_v2_ehtype_template, initlist);
}

static tree
build_ehtype (tree name, const char *eh_name, bool weak)
{
  tree name_expr, class_name_expr, ehtype_decl, inits;

  name_expr = add_objc_string (name, class_names);
  /* Extern ref. for the class. ???  Maybe we can look this up
     somewhere.  */
  class_name_expr =
	create_extern_decl (objc_v2_class_template,
			    objc_build_internal_classname (name, false));
  class_name_expr = build_fold_addr_expr (class_name_expr);
  ehtype_decl = create_global_decl (objc_v2_ehtype_template, eh_name);
  if (weak)
    DECL_WEAK (ehtype_decl) = 1;
  inits = objc2_build_ehtype_initializer (name_expr, class_name_expr);
  OBJCMETA (ehtype_decl, objc_meta, meta_ehtype);
  finish_var_decl (ehtype_decl, inits);
  return ehtype_decl;
}

/* This routine returns TRUE if CLS or any of its super classes has
   __attribute__ ((objc_exception)).  */

static bool
objc2_objc_exception_attr (tree cls)
{
  while (cls)
    {
      if (CLASS_HAS_EXCEPTION_ATTR (cls))
	return true;
      cls = lookup_interface (CLASS_SUPER_NAME (cls));
    }

  return false;
}

static bool
is_implemented (tree name)
{
  struct imp_entry *t;
  for (t = imp_list; t; t = t->next)
    if (TREE_CODE (t->imp_context) == CLASS_IMPLEMENTATION_TYPE
	&& CLASS_NAME (t->imp_template) == name)
      return true;

  return false;
}

/* We will build catch objects:
     for any type  implemented here.
     for any type used in a catch that has no exception attribute.  */
static void build_v2_eh_catch_objects (void)
{
  int count=0;
  ident_data_tuple *ref;

  if (!vec_safe_length (ehtype_list))
    return;

  FOR_EACH_VEC_ELT (*ehtype_list, count, ref)
    {
      char buf[BUFSIZE];
      bool impl = is_implemented (ref->ident);
      bool excpt = objc2_objc_exception_attr (lookup_interface (ref->ident));
      snprintf (buf, BUFSIZE, "OBJC_EHTYPE_$_%s", IDENTIFIER_POINTER (ref->ident));
      if (!impl && excpt)
	/* The User says this class has a catcher already.  */
	ref->data = create_extern_decl (objc_v2_ehtype_template, buf);
      else
	/* Create a catcher, weak if it wasn't marked.  */
	ref->data = build_ehtype (ref->ident, buf, !excpt);
    }
}

static tree
lookup_ehtype_ref (tree id)
{
  int count=0;
  ident_data_tuple *ref;

  if (!vec_safe_length (ehtype_list))
    return NULL_TREE;

  FOR_EACH_VEC_ELT (*ehtype_list, count, ref)
    if (ref->ident == id)
      return ref->data;
  return NULL_TREE;
}

/* This hook, called via lang_eh_runtime_type, generates a runtime
   object which is either the address of the 'OBJC_EHTYPE_$_class'
   object or address of external OBJC_EHTYPE_id object.  */
static tree
next_runtime_02_eh_type (tree type)
{
  tree t;

  if (type == error_mark_node
      /*|| errorcount || sorrycount*/)
    goto err_mark_in;

  if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
    {
      if (!next_v2_EHTYPE_id_decl)
	{
	  /* This is provided by the Apple/NeXT libobjc.dylib so we
	     need only to reference it.  */
	  next_v2_EHTYPE_id_decl =
		start_var_decl (objc_v2_ehtype_template, "OBJC_EHTYPE_id");
	  DECL_EXTERNAL (next_v2_EHTYPE_id_decl) = 1;
	  TREE_PUBLIC (next_v2_EHTYPE_id_decl) = 1;
	  TREE_STATIC (next_v2_EHTYPE_id_decl) = 0;
	}
      return build_fold_addr_expr (next_v2_EHTYPE_id_decl);
    }

  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);
      goto err_mark_in;
#endif
    }
  else
    t = OBJC_TYPE_NAME (TREE_TYPE (type));

  /* We have to build a reference to the OBJC_EHTYPE_<Class>.  */
  t = lookup_ehtype_ref (t);
  if (!t)
    goto err_mark_in;

  return build_fold_addr_expr (t);

err_mark_in:
  return error_mark_node;
}

static GTY(()) tree objc_eh_personality_decl;

static tree
objc_eh_personality (void)
{
  if (!objc_eh_personality_decl)
    objc_eh_personality_decl = build_personality_function  ("objc");
  return objc_eh_personality_decl;
}

/* NOTE --- interfaces --- */

static tree
build_throw_stmt (location_t loc, tree throw_expr, bool rethrown)
{
  tree t;
  if (rethrown)
    /* We have a separate re-throw entry.  */
    t = build_function_call_vec (loc, vNULL, objc_rethrow_exception_decl,
				 NULL, NULL);
  else
    {
      /* Throw like the others...  */
      vec<tree, va_gc> *parms;
      vec_alloc (parms, 1);
      parms->quick_push (throw_expr);
      t = build_function_call_vec (loc, vNULL, objc_exception_throw_decl,
				   parms, 0);
      vec_free (parms);
    }
  return add_stmt (t);
}

/* Build __builtin_eh_pointer.  */

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

static tree begin_catch (struct objc_try_context **cur_try_context, tree type,
			 tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED)
{
  tree t;

  /* Record the data for the catch in the try context so that we can
     finalize it later.  Ellipsis is signalled by a NULL entry.  */
  if (ellipsis)
    t = build_stmt (input_location, CATCH_EXPR, NULL_TREE, compound);
  else
    t = build_stmt (input_location, CATCH_EXPR, type, compound);
  (*cur_try_context)->current_catch = t;

  /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime.  */
  t = objc_build_exc_ptr (cur_try_context);
  t = convert (TREE_TYPE (decl), t);
  /* FIXME: location.  */
  if (type && type != error_mark_node)
    {
      t = build1(NOP_EXPR, ptr_type_node, t);
      t = build_function_call (input_location, objc2_begin_catch_decl,
			      tree_cons (NULL_TREE, t, NULL_TREE));

      /* We might want to build a catch object for this (if it's not
	 id).  */
      if (POINTER_TYPE_P (type)
	  && !objc_is_object_id (TREE_TYPE (type))
	  && TYPED_OBJECT (TREE_TYPE (type)))
	objc_v2_add_to_ehtype_list (OBJC_TYPE_NAME (TREE_TYPE (type)));
    }
  return build2 (MODIFY_EXPR, void_type_node, decl, t);
}

/* try { catch-body } finally { objc_end_catch (); } */
static void
finish_catch (struct objc_try_context **cur_try_context, tree curr_catch)
{
  struct objc_try_context *ct;
  tree try_exp, func, *l, t ;
  location_t loc = (*cur_try_context)->try_locus;

  if (!curr_catch || curr_catch == error_mark_node)
    return;

  t = CATCH_BODY (curr_catch);
  if (TREE_CODE (t) == BIND_EXPR)
    {
      /* Usual case of @catch (objc-expr).  */
      objc_begin_try_stmt (loc, BIND_EXPR_BODY (t));
      BIND_EXPR_BODY (t) = NULL_TREE;
      l = &BIND_EXPR_BODY (t);
    }
  else
    {
      /* NULL entry, meaning @catch (...).  */
      objc_begin_try_stmt (loc, t);
      CATCH_BODY (curr_catch) = NULL_TREE;
      l = &CATCH_BODY (curr_catch);
    }

  /* Pick up the new context we made in begin_try above...  */
  ct = *cur_try_context;
  func = build_function_call_vec (loc, vNULL, objc2_end_catch_decl, NULL,
				  NULL);
  append_to_statement_list (func, &ct->finally_body);
  try_exp = build_stmt (loc, TRY_FINALLY_EXPR, ct->try_body, ct->finally_body);
  *cur_try_context = ct->outer;
  free (ct);
  append_to_statement_list (try_exp, l);
  append_to_statement_list (curr_catch, &((*cur_try_context)->catch_list));
}

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

#include "gt-objc-objc-next-runtime-abi-02.h"
