/* Next Runtime (ABI-2) private.
   Copyright (C) 2011-2022 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-next-metadata-tags.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]

/* 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);
  DECL_PRESERVE_P (decl) = 1;
  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,
	      build_int_cst (TREE_TYPE (lookup_object), 0));
  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, build_int_cst (TREE_TYPE (lookup_object), 0));
  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);
      DECL_PRESERVE_P (decl) = 1;
    }

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