/* Implement classes and message passing for Objective C.
   Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
   Contributed by Steve Naroff.

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 2, 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 COPYING.  If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.  */

/* Purpose: This module implements the Objective-C 4.0 language.

   compatibility issues (with the Stepstone translator):

   - does not recognize the following 3.3 constructs.
     @requires, @classes, @messages, = (...)
   - methods with variable arguments must conform to ANSI standard.
   - tagged structure definitions that appear in BOTH the interface
     and implementation are not allowed.
   - public/private: all instance variables are public within the
     context of the implementation...I consider this to be a bug in
     the translator.
   - statically allocated objects are not supported. the user will
     receive an error if this service is requested.

   code generation `options':

   */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "expr.h"

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

#include "c-common.h"
#include "c-pragma.h"
#include "flags.h"
#include "langhooks.h"
#include "objc-act.h"
#include "input.h"
#include "except.h"
#include "function.h"
#include "output.h"
#include "toplev.h"
#include "ggc.h"
#include "varray.h"
#include "debug.h"
#include "target.h"
#include "diagnostic.h"
#include "cgraph.h"
#include "tree-iterator.h"
#include "libfuncs.h"
#include "hashtab.h"
#include "langhooks-def.h"
/* APPLE LOCAL optimization pragmas 3124235/3420242 */
#include "opts.h"
/* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
#include "llvm.h"               /* for reset_initializer_llvm */
#endif
/* LLVM LOCAL end */

#define OBJC_VOID_AT_END	void_list_node

/* APPLE LOCAL radar 4506893 */
static bool in_objc_property_setter_name_context = false;
static unsigned int should_call_super_dealloc = 0;
/* APPLE LOCAL begin radar 4757423 */
static bool should_call_super_finalize = false;
/* APPLE LOCAL end radar 4757423 */

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

/* This is the default way of generating a method name.  */
/* I am not sure it is really correct.
   Perhaps there's a danger that it will make name conflicts
   if method names contain underscores. -- rms.  */
#ifndef OBJC_GEN_METHOD_LABEL
#define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
  do {					    \
    char *temp;				    \
    sprintf ((BUF), "_%s_%s_%s_%s",	    \
	     ((IS_INST) ? "i" : "c"),	    \
	     (CLASS_NAME),		    \
	     ((CAT_NAME)? (CAT_NAME) : ""), \
	     (SEL_NAME));		    \
    for (temp = (BUF); *temp; temp++)	    \
      if (*temp == ':') *temp = '_';	    \
  } while (0)
#endif
/* APPLE LOCAL begin radar 4862848 */
#ifndef OBJC_FLAG_OBJC_ABI
#define OBJC_FLAG_OBJC_ABI \
  do { if (flag_objc_abi == -1)   \
         flag_objc_abi = 1;   \
  } while (0)
#endif
/* APPLE LOCAL end radar 4862848 */
/* APPLE LOCAL begin radar 5023725 */
#ifndef OBJC_FLAG_ZEROCOST_EXCEPTIONS
#define OBJC_FLAG_ZEROCOST_EXCEPTIONS
#endif
/* APPLE LOCAL end radar 5023725 */
/* LLVM LOCAL begin */
/* APPLE LOCAL begin radar 4590191 */
#ifndef OBJC_FLAG_SJLJ_EXCEPTIONS
#define OBJC_FLAG_SJLJ_EXCEPTIONS
#endif
/* APPLE LOCAL end radar 4590191 */
/* LLVM LOCAL end */
/* APPLE LOCAL begin radar 4531086 */
#ifndef OBJC_WARN_OBJC2_FEATURES
#define OBJC_WARN_OBJC2_FEATURES(MESSAGE)
#endif
/* APPLE LOCAL end radar 4531086 */

/* APPLE LOCAL begin radar 6307941 */
#ifndef OBJC2_ABI_DISPATCH
#define OBJC2_ABI_DISPATCH 0
#endif
/* APPLE LOCAL end radar 6307941 */

/* These need specifying.  */
#ifndef OBJC_FORWARDING_STACK_OFFSET
#define OBJC_FORWARDING_STACK_OFFSET 0
#endif

#ifndef OBJC_FORWARDING_MIN_OFFSET
#define OBJC_FORWARDING_MIN_OFFSET 0
#endif

/* Set up for use of obstacks.  */

#include "obstack.h"

/* This obstack is used to accumulate the encoding of a data type.  */
static struct obstack util_obstack;

/* This points to the beginning of obstack contents, so we can free
   the whole contents.  */
char *util_firstobj;

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

/* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
/* Bump version number to 7 */
/* APPLE LOCAL mainline */
#define OBJC_VERSION    (flag_next_runtime ? 7 : 8)
/* APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions */
#define PROTOCOL_VERSION 2
/* APPLE LOCAL radar 4533974 - ObjC newprotocol */
#define NEW_PROTOCOL_VERSION 3

/* (Decide if these can ever be validly changed.) */
#define OBJC_ENCODE_INLINE_DEFS 	0
#define OBJC_ENCODE_DONT_INLINE_DEFS	1

/*** Private Interface (procedures) ***/

/* Used by compile_file.  */

static void init_objc (void);
static void finish_objc (void);

/* Code generation.  */

static tree objc_build_constructor (tree, tree);
/* APPLE LOCAL radar 6307941 */
static tree build_objc_method_call (int, tree, tree, tree, tree, tree);
static tree get_proto_encoding (tree);
static tree lookup_interface (tree);
static tree objc_add_static_instance (tree, tree);
/* APPLE LOCAL radar 5168496 */
static bool objc_is_object_id (tree);

static tree start_class (enum tree_code, tree, tree, tree);
static tree continue_class (tree);
static void finish_class (tree);
static void start_method_def (tree);
/* APPLE LOCAL begin radar 5839812 - location for synthesized methods  */
#ifdef OBJCPLUS
static void objc_start_function (tree, tree, tree, tree, tree);
#else
static void objc_start_function (tree, tree, tree, struct c_arg_info *, tree);
#endif
/* APPLE LOCAL end radar 5839812 - location for synthesized methods  */
/* APPLE LOCAL radar 4947311 - protocol attributes */
static tree start_protocol (tree, tree, tree);
static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
/* APPLE LOCAL C* language */
static tree objc_add_method (tree, tree, int, int);
static tree add_instance_variable (tree, int, tree);
static tree build_ivar_reference (tree);
static tree is_ivar (tree, tree);

/* APPLE LOCAL begin objc new property */
static bool objc_lookup_protocol (tree, tree, tree, bool);
/* APPLE LOCAL radar 5277239 */
static tree lookup_method_static (tree, tree, int, bool, bool);
/* APPLE LOCAL radar 4817072 */
static void objc_lookup_property_ivar (tree, tree);
/* APPLE LOCAL end objc new property */
static void build_objc_exception_stuff (void);
static void build_next_objc_exception_stuff (void);
/* APPLE LOCAL radar 5285911 */
static tree nested_ivar_lookup (tree, tree);

/* APPLE LOCAL radar 4431864 */
static void objc_set_global_decl_fields (tree);
/* APPLE LOCAL begin ObjC GC */
static int objc_is_strong_p (tree);
static int objc_is_gcable_p (tree);
/* APPLE LOCAL end ObjC GC */

/* We only need the following for ObjC; ObjC++ will use C++'s definition
   of DERIVED_FROM_P.  */
#ifndef OBJCPLUS
static bool objc_derived_from_p (tree, tree);
#define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
#endif
/* APPLE LOCAL begin C* language */
/* code removed */
/* APPLE LOCAL end C* language */
/* APPLE LOCAL begin C* property (Radar 4436866) */
static char *objc_build_property_setter_name (tree, bool);
static int match_proto_with_proto (tree, tree, int);
static char * objc_build_property_ivar_name (tree);
/* APPLE LOCAL end C* property (Radar 4436866) */
static void objc_xref_basetypes (tree, tree);
/* APPLE LOCAL radar 5376125 */
static void objc_warn_direct_ivar_access (tree, tree);

/* APPLE LOCAL begin ObjC new abi */
static void build_v2_class_template (void);
static void build_v2_protocol_template (void);
static void build_message_ref_template (void);
/* APPLE LOCAL radar 6307941 */
static tree build_v2_build_objc_method_call (int, tree, tree, tree, tree, tree, bool);
/* APPLE LOCAL radar 4695109 */
static void build_v2_protocol_reference (tree);
/* APPLE LOCAL radar 5153561 */
static void init_UOBJC2_EHTYPE_decls (void);
static void create_ivar_offset_name (char *, tree, tree);
static void build_v2_category_template (void);
/* APPLE LOCAL radar 4533974 - ObjC new protocol - radar 6351990 */
static tree build_protocollist_reference_decl (tree);
static void objc_add_to_category_list_chain (tree);
static void objc_add_to_nonlazy_category_list_chain (tree);
/* APPLE LOCAL begin radar 4441049 */
static void hash_name_enter (hash *, tree);
static tree hash_name_lookup (hash *, tree);
/* APPLE LOCAL end radar 4441049 */
/* APPLE LOCAL end ObjC new abi */
/* APPLE LOCAL C* language */
static void build_objc_fast_enum_state_type (void);

static void build_class_template (void);
static void build_selector_template (void);
static void build_category_template (void);
static void build_super_template (void);
/* APPLE LOCAL begin ObjC new abi - radar 4695109 */
static tree build_protocol_initializer (tree, tree, tree, tree, tree, bool, tree, tree, tree);
/* APPLE LOCAL end ObjC new abi - radar 4695109 */

static tree get_class_ivars (tree, bool);
static tree generate_protocol_list (tree);
static void build_protocol_reference (tree);

#ifdef OBJCPLUS
static void objc_generate_cxx_cdtors (void);
#endif
/* APPLE LOCAL begin radar 4359757 */
static size_t hash_func (tree);
static void hash_add_attr (hash, tree);
static hash hash_ident_lookup (hash *, tree);
static hash hash_ident_enter (hash *, tree);
/* APPLE LOCAL end radar 4359757 */

/* APPLE LOCAL radar 3803157 - objc attribute */
static void objc_decl_method_attributes (tree*, tree, int);
static const char *synth_id_with_class_suffix (const char *, tree);

/* APPLE LOCAL begin radar 4548636 */
static void objc_warn_on_class_attributes (tree, bool);
static void objc_attach_attrs_to_type (tree, tree);
/* APPLE LOCAL end radar 4548636 */
/* APPLE LOCAL radar 4664707 */
static tree objc_create_named_tmp_var (tree, const char *);
/* APPLE LOCAL radar 2848255 */
static tree objc2_eh_runtime_type (tree);
/* APPLE LOCAL radar 4982951 */
static tree objc_v2_ivar_reference (tree);
/* APPLE LOCAL radar 5277239 */
static tree receiver_is_class_object (tree, int, int);

/* APPLE LOCAL radar 5040740 */
static tree lookup_nested_method (tree, tree);

/* APPLE LOCAL begin radar 5607453 */
static bool objc_is_object_id (tree);
static bool objc_is_class_id (tree);
/* APPLE LOCAL end radar 5607453 */
/* Hash tables to manage the global pool of method prototypes.  */

hash *nst_method_hash_list = 0;
hash *cls_method_hash_list = 0;
/* APPLE LOCAL begin radar 4359757 */
hash *class_nst_method_hash_list = 0;
hash *class_cls_method_hash_list = 0;
hash *class_names_hash_list = 0;
hash *meth_var_names_hash_list = 0;
hash *meth_var_types_hash_list = 0;
hash *prop_names_attr_hash_list = 0;
hash *sel_ref_hash_list = 0;
/* APPLE LOCAL end radar 4359757 */

/* APPLE LOCAL begin radar 4345837 */
hash *cls_name_hash_list = 0;
hash *als_name_hash_list = 0;
/* APPLE LOCAL end radar 4345837 */

/* APPLE LOCAL radar 4441049 */
hash *ivar_offset_hash_list = 0;

/* APPLE LOCAL begin radar 4345837 */
static void hash_class_name_enter (hash *, tree, tree);
static hash hash_class_name_lookup (hash *, tree);
/* APPLE LOCAL end radar 4345837 */
static hash hash_lookup (hash *, tree);
static tree lookup_method (tree, tree);
/* APPLE LOCAL C* property (Radar 4436866) */
static inline tree lookup_category (tree, tree);

enum string_section
{
  class_names,		/* class, category, protocol, module names */
  meth_var_names,	/* method and variable names */
  /* APPLE LOCAL begin C* property metadata (Radar 4498373) */
  meth_var_types,	/* method and variable type descriptors */
  prop_names_attr	/* property names and their attributes. */
  /* APPLE LOCAL end C* property metadata (Radar 4498373) */
};

static tree add_objc_string (tree, enum string_section);
/* APPLE LOCAL do not create an unreferenced decl */
static tree build_objc_string_ident (enum string_section);
static void build_selector_table_decl (void);

/* Protocol additions.  */

static tree lookup_protocol (tree);
/* APPLE LOCAL radar 4398221 */
static tree lookup_and_install_protocols (tree, bool);
/* APPLE LOCAL radar 4869979 */
static int conforms_to_protocol (tree, tree);

/* Type encoding.  */

static void encode_type_qualifiers (tree);
static void encode_type (tree, int, int);
static void encode_field_decl (tree, int, int);

#ifdef OBJCPLUS
static void really_start_method (tree, tree);
#else
static void really_start_method (tree, struct c_arg_info *);
#endif
static int comp_proto_with_proto (tree, tree, int);
/* APPLE LOCAL begin 4209854 */
/* APPLE LOCAL radar 6307941 */
static tree get_arg_type_list (tree, tree, int, int);
static tree objc_decay_parm_type (tree);
/* APPLE LOCAL end 4209854 */
static void objc_push_parm (tree);
#ifdef OBJCPLUS
static tree objc_get_parm_info (int);
#else
static struct c_arg_info *objc_get_parm_info (int);
#endif

/* Utilities for debugging and error diagnostics.  */

static void warn_with_method (const char *, int, tree);
static char *gen_type_name (tree);
static char *gen_type_name_0 (tree);
static char *gen_method_decl (tree);
static char *gen_declaration (tree);

/* Everything else.  */

/* APPLE LOCAL begin C* property metadata (Radar 4498373) */
static tree start_var_decl (tree, const char *);
static void finish_var_decl (tree, tree);
/* APPLE LOCAL end C* property metadata (Radar 4498373) */
static tree create_field_decl (tree, const char *);
static void add_class_reference (tree);
static void build_protocol_template (void);
static tree encode_method_prototype (tree);
static void generate_classref_translation_entry (tree);
static void handle_class_ref (tree);
static void generate_struct_by_value_array (void)
     ATTRIBUTE_NORETURN;
static void mark_referenced_methods (void);
static void generate_objc_image_info (void);

/*** Private Interface (data) ***/

/* Reserved tag definitions.  */

#define OBJECT_TYPEDEF_NAME		"id"
#define CLASS_TYPEDEF_NAME		"Class"

#define TAG_OBJECT			"objc_object"
#define TAG_CLASS			"objc_class"
#define TAG_SUPER			"objc_super"
#define TAG_SELECTOR			"objc_selector"

#define UTAG_CLASS			"_objc_class"
#define UTAG_IVAR			"_objc_ivar"
#define UTAG_IVAR_LIST			"_objc_ivar_list"
#define UTAG_METHOD			"_objc_method"
#define UTAG_METHOD_LIST		"_objc_method_list"
#define UTAG_CATEGORY			"_objc_category"
#define UTAG_MODULE			"_objc_module"
#define UTAG_SYMTAB			"_objc_symtab"
#define UTAG_SUPER			"_objc_super"
#define UTAG_SELECTOR			"_objc_selector"

#define UTAG_PROTOCOL			"_objc_protocol"
#define UTAG_METHOD_PROTOTYPE		"_objc_method_prototype"
#define UTAG_METHOD_PROTOTYPE_LIST	"_objc__method_prototype_list"

/* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
#define UTAG_CLASS_EXT			"_objc_class_ext"
#define UTAG_PROPERTY_LIST		"_prop_list_t"
#define UTAG_PROTOCOL_EXT		"_objc_protocol_extension"
/* APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions */

/* Note that the string object global name is only needed for the
   NeXT runtime.  */
#define STRING_OBJECT_GLOBAL_FORMAT	"_%sClassReference"
/* APPLE LOCAL radar 4719165 */
#define STRING_V2_OBJECT_GLOBAL_FORMAT     "OBJC_CLASS_$_%s"
/* APPLE LOCAL radar 4894756 */
#define STRING_V2_IVAR_OFFSET_PREFIX	   "OBJC_IVAR_$_"
/* APPLE LOCAL radar 5008110 */
#define STRING_V2_OBJC_EHTYPE_PREFIX    "OBJC_EHTYPE_$"

#define PROTOCOL_OBJECT_CLASS_NAME	"Protocol"

/* APPLE LOCAL begin ObjC new abi */
#define UTAG_V2_CLASS			"_class_t"
#define UTAG_V2_CLASS_RO			"_class_ro_t"
#define UTAG_V2_PROTOCOL_LIST		"_protocol_list_t"
#define UTAG_V2_PROTOCOL			"_protocol_t"
/* APPLE LOCAL end ObjC new abi */

static const char *TAG_GETCLASS;
static const char *TAG_GETMETACLASS;
static const char *TAG_MSGSEND;
static const char *TAG_MSGSENDSUPER;
/* The NeXT Objective-C messenger may have two extra entry points, for use
   when returning a structure. */
static const char *TAG_MSGSEND_STRET;
static const char *TAG_MSGSENDSUPER_STRET;
static const char *default_constant_string_class_name;
/* APPLE LOCAL radar 4666559 */
static const struct gcc_debug_hooks *save_default_debug_hooks;
/* APPLE LOCAL radar 5932809 - copyable byref blocks */
static int donot_warn_missing_methods;

/* Runtime metadata flags.  */
#define CLS_FACTORY			0x0001L
#define CLS_META			0x0002L
/* APPLE LOCAL radar 5142207 */
#define IS_CLS_META(X)			((X & 0x0003) == CLS_META)
#define CLS_HAS_CXX_STRUCTORS		0x2000L
/* APPLE LOCAL radar 4923634 */
#define OBJC2_CLS_HAS_CXX_STRUCTORS	0x0004L
/* APPLE LOCAL begin radar 5142207 */
#define CLS_HIDDEN			0x20000
#define OBJC2_CLS_HIDDEN		0x10
/* APPLE LOCAL end radar 5142207 */

#define OBJC_MODIFIER_STATIC		0x00000001
#define OBJC_MODIFIER_FINAL		0x00000002
#define OBJC_MODIFIER_PUBLIC		0x00000004
#define OBJC_MODIFIER_PRIVATE		0x00000008
#define OBJC_MODIFIER_PROTECTED		0x00000010
#define OBJC_MODIFIER_NATIVE		0x00000020
#define OBJC_MODIFIER_SYNCHRONIZED	0x00000040
#define OBJC_MODIFIER_ABSTRACT		0x00000080
#define OBJC_MODIFIER_VOLATILE		0x00000100
#define OBJC_MODIFIER_TRANSIENT		0x00000200
#define OBJC_MODIFIER_NONE_SPECIFIED	0x80000000

/* NeXT-specific tags.  */

#define TAG_MSGSEND_NONNIL		"objc_msgSendNonNil"
#define TAG_MSGSEND_NONNIL_STRET	"objc_msgSendNonNil_stret"
#define TAG_EXCEPTIONEXTRACT		"objc_exception_extract"
#define TAG_EXCEPTIONTRYENTER		"objc_exception_try_enter"
#define TAG_EXCEPTIONTRYEXIT		"objc_exception_try_exit"
#define TAG_EXCEPTIONMATCH		"objc_exception_match"
#define TAG_EXCEPTIONTHROW		"objc_exception_throw"
#define TAG_SYNCENTER			"objc_sync_enter"
#define TAG_SYNCEXIT			"objc_sync_exit"
#define TAG_SETJMP			"_setjmp"
#define UTAG_EXCDATA			"_objc_exception_data"
/* APPLE LOCAL radar 4280641 */
#define TAG_MSGSEND_FPRET		"objc_msgSend_fpret"

/* APPLE LOCAL begin radar 4426814 */
#define TAG_ASSIGN_WEAK			"objc_assign_weak"
#define TAG_READ_WEAK			"objc_read_weak"
/* APPLE LOCAL end radar 4426814 */
/* APPLE LOCAL radar 3742561 */
#define TAG_MEMMOVE_COLLECTABLE		"objc_memmove_collectable"

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

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

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

/* APPLE LOCAL begin radar 4590221 */
#ifndef OFFS_MSGSEND_FAST
#define OFFS_MSGSEND_FAST 0
#endif
#ifndef OFFS_ASSIGNIVAR_FAST
#define OFFS_ASSIGNIVAR_FAST 0
#endif
/* APPLE LOCAL end radar 4590221 */

#define TAG_CXX_CONSTRUCT		".cxx_construct"
#define TAG_CXX_DESTRUCT		".cxx_destruct"

/* GNU-specific tags.  */

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

/* Flags for lookup_method_static().  */
#define OBJC_LOOKUP_CLASS	1	/* Look for class methods.  */
#define OBJC_LOOKUP_NO_SUPER	2	/* Do not examine superclasses.  */

/* The OCTI_... enumeration itself is in objc/objc-act.h.  */
tree objc_global_trees[OCTI_MAX];

static void handle_impent (struct imp_entry *);

struct imp_entry *imp_list = 0;
int imp_count = 0;	/* `@implementation' */
int cat_count = 0;	/* `@category' */

enum tree_code objc_inherit_code;
int objc_public_flag;

/* APPLE LOCAL C* language */
static int objc_method_optional_flag = 0;
/* APPLE LOCAL begin C* property (Radar 4436866, 4591909) */
static bool property_readonly;
static tree property_getter;
static tree property_setter;
/* APPLE LOCAL end C* property (Radar 4436866, 4591909) */
/* APPLE LOCAL begin objc new property */
static bool property_readwrite;
static bool property_assign;
static bool property_retain;
static bool property_copy;
/* APPLE LOCAL end objc new property */
/* APPLE LOCAL radar 4947014 - objc atomic property */
static bool property_atomic;
/* Use to generate method labels.  */
static int method_slot = 0;

/* APPLE LOCAL begin radar 4291785 */
static int objc_collecting_ivars = 0;
/* APPLE LOCAL end radar 4291785 */

#define BUFSIZE		1024

static char *errbuf;	/* Buffer for error diagnostics */

/* Data imported from tree.c.  */

extern enum debug_info_type write_symbols;

/* Data imported from toplev.c.  */

extern const char *dump_base_name;
/* APPLE LOCAL radar 5130983 */
int lvalue_or_else (tree*, enum lvalue_use);

static int flag_typed_selectors;

/* Store all constructed constant strings in a hash table so that
   they get uniqued properly.  */

struct string_descriptor GTY(())
{
  /* The literal argument .  */
  tree literal;

  /* The resulting constant string.  */
  tree constructor;
};

static GTY((param_is (struct string_descriptor))) htab_t string_htab;

/* APPLE LOCAL begin radar 4204796 */
/* struct volatilized_type and volatilized_htab removed */
/* APPLE LOCAL end radar 4204796 */

FILE *gen_declaration_file;

/* APPLE LOCAL begin radar 5002848 */
/* Tells "encode_pointer" that we are encoding for a property type. */
static int generating_property_type_encoding = 0;
/* APPLE LOCAL end radar 5002848 */

/* Tells "encode_pointer/encode_aggregate" whether we are generating
   type descriptors for instance variables (as opposed to methods).
   Type descriptors for instance variables contain more information
   than methods (for static typing and embedded structures).  */

static int generating_instance_variables = 0;

/* Some platforms pass small structures through registers versus
   through an invisible pointer.  Determine at what size structure is
   the transition point between the two possibilities.  */

static void
generate_struct_by_value_array (void)
{
  tree type;
  tree field_decl, field_decl_chain;
  int i, j;
  int aggregate_in_mem[32];
  int found = 0;

  /* Presumably no platform passes 32 byte structures in a register.  */
  for (i = 1; i < 32; i++)
    {
      char buffer[5];

      /* Create an unnamed struct that has `i' character components */
      type = start_struct (RECORD_TYPE, NULL_TREE);

      strcpy (buffer, "c1");
      field_decl = create_field_decl (char_type_node,
				      buffer);
      field_decl_chain = field_decl;

      for (j = 1; j < i; j++)
	{
	  sprintf (buffer, "c%d", j + 1);
	  field_decl = create_field_decl (char_type_node,
					  buffer);
	  chainon (field_decl_chain, field_decl);
	}
      finish_struct (type, field_decl_chain, NULL_TREE);

      aggregate_in_mem[i] = aggregate_value_p (type, 0);
      if (!aggregate_in_mem[i])
	found = 1;
    }

  /* We found some structures that are returned in registers instead of memory
     so output the necessary data.  */
  if (found)
    {
      for (i = 31; i >= 0;  i--)
	if (!aggregate_in_mem[i])
	  break;
      printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);

      /* The first member of the structure is always 0 because we don't handle
	 structures with 0 members */
      printf ("static int struct_forward_array[] = {\n  0");

      for (j = 1; j <= i; j++)
	printf (", %d", aggregate_in_mem[j]);
      printf ("\n};\n");
    }

  exit (0);
}

bool
objc_init (void)
{
/* APPLE LOCAL begin ARM 5726269 */
#ifdef OBJC_TARGET_FLAG_OBJC_ABI
  OBJC_TARGET_FLAG_OBJC_ABI;
#endif
/* APPLE LOCAL end ARM 5726269 */
  /* APPLE LOCAL radar 4862848 */
  OBJC_FLAG_OBJC_ABI;
  /* APPLE LOCAL begin radar 4531086 */
  if (flag_objc_abi == 2)
    OBJC_WARN_OBJC2_FEATURES ("the new objc abi");
  /* APPLE LOCAL end radar 4531086 */
#ifdef OBJCPLUS
  if (cxx_init () == false)
#else
  if (c_objc_common_init () == false)
#endif
    return false;

#ifndef USE_MAPPED_LOCATION
  /* Force the line number back to 0; check_newline will have
     raised it to 1, which will make the builtin functions appear
     not to be built in.  */
  input_line = 0;
#endif

  /* If gen_declaration desired, open the output file.  */
  if (flag_gen_declaration)
    {
      register char * const dumpname = concat (dump_base_name, ".decl", NULL);
      gen_declaration_file = fopen (dumpname, "w");
      if (gen_declaration_file == 0)
	fatal_error ("can't open %s: %m", dumpname);
      free (dumpname);
    }

  if (flag_next_runtime)
    {
      /* APPLE LOCAL begin ARM hybrid objc-2.0 */
      /* APPLE LOCAL radar 6307941 */
      /* code removed. */
      TAG_GETCLASS = "objc_getClass";
      TAG_GETMETACLASS = "objc_getMetaClass";
      TAG_MSGSEND = "objc_msgSend";
      /* APPLE LOCAL begin radar 6307941 */
      TAG_MSGSENDSUPER = flag_objc_abi==2 ? "objc_msgSendSuper2"
					  : "objc_msgSendSuper";
      TAG_MSGSEND_STRET = "objc_msgSend_stret";
      TAG_MSGSENDSUPER_STRET = flag_objc_abi==2 ? "objc_msgSendSuper2_stret"
						: "objc_msgSendSuper_stret";
      /* APPLE LOCAL end radar 6307941 */
      /* APPLE LOCAL end ARM hybrid objc-2.0 */
      default_constant_string_class_name = "NSConstantString";
      /* APPLE LOCAL begin radar 4810609 */
      if (flag_objc_gc_only)
        flag_objc_gc = 1;
      /* APPLE LOCAL end radar 4810609 */
      /* APPLE LOCAL begin radar 4949034 */
#ifdef OBJCPLUS
      /* APPLE LOCAL begin radar 5809596 */
      /* For all objc ABIs -fobjc-call-cxx-cdtors is on by default. */
      if (flag_objc_call_cxx_cdtors == -1)
        flag_objc_call_cxx_cdtors = 1;
      /* APPLE LOCAL end radar 5809596 */
#endif
      /* APPLE LOCAL end radar 4949034 */
    }
  else
    {
      TAG_GETCLASS = "objc_get_class";
      TAG_GETMETACLASS = "objc_get_meta_class";
      TAG_MSGSEND = "objc_msg_lookup";
      TAG_MSGSENDSUPER = "objc_msg_lookup_super";
      /* GNU runtime does not provide special functions to support
	 structure-returning methods.  */
      default_constant_string_class_name = "NXConstantString";
      flag_typed_selectors = 1;
    }

  init_objc ();

/* APPLE LOCAL begin radar 2848255 - radar 5153561 */
#ifdef OBJCPLUS
  if (flag_objc_zerocost_exceptions)
    {
      lang_eh_runtime_type = objc2_eh_runtime_type;
      init_UOBJC2_EHTYPE_decls ();
    }
#endif
/* APPLE LOCAL end radar 2848255 - radar 5153561 */
  if (print_struct_values)
    generate_struct_by_value_array ();

  return true;
}

void
objc_finish_file (void)
{
  mark_referenced_methods ();

#ifdef OBJCPLUS
  /* We need to instantiate templates _before_ we emit ObjC metadata;
     if we do not, some metadata (such as selectors) may go missing.  */
  /* APPLE LOCAL begin radar 4721858 */
  {
    /* APPLE LOCAL radar 4874626 */
    location_t locus = input_location;
    emit_instantiate_pending_templates (&locus);
  }
  /* APPLE LOCAL end radar 4721858 */
#endif

  /* Finalize Objective-C runtime data.  No need to generate tables
     and code if only checking syntax, or if generating a PCH file.  */
  if (!flag_syntax_only && !pch_file)
    finish_objc ();

  if (gen_declaration_file)
    fclose (gen_declaration_file);

#ifdef OBJCPLUS
  cp_finish_file ();
#endif
}

/* Return the first occurrence of a method declaration corresponding
   to sel_name in rproto_list.  Search rproto_list recursively.
   If is_class is 0, search for instance methods, otherwise for class
   methods.  */
static tree
lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
				int is_class)
{
   tree rproto, p;
   tree fnd = 0;

   for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
     {
        p = TREE_VALUE (rproto);

	if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
	  {
	    /* APPLE LOCAL begin radar 4550413 */
	    fnd = lookup_method (is_class
				 ? PROTOCOL_CLS_METHODS (p)
				 : PROTOCOL_NST_METHODS (p), sel_name);
	    if (!fnd)
	      fnd = lookup_method (is_class
				   ? PROTOCOL_OPTIONAL_CLS_METHODS (p)
				   : PROTOCOL_OPTIONAL_NST_METHODS (p), sel_name);	
	    if (!fnd && PROTOCOL_LIST (p))
	    /* APPLE LOCAL end radar 4550413 */
	      fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
						    sel_name, is_class);
	  }
	else
          {
	    ; /* An identifier...if we could not find a protocol.  */
          }

	if (fnd)
	  return fnd;
     }

   return 0;
}

static tree
lookup_protocol_in_reflist (tree rproto_list, tree lproto)
{
  tree rproto, p;

  /* Make sure the protocol is supported by the object on the rhs.  */
  if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
    {
      tree fnd = 0;
      for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
	{
	  p = TREE_VALUE (rproto);

	  if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
	    {
	      if (lproto == p)
		fnd = lproto;

	      else if (PROTOCOL_LIST (p))
		fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
	    }

	  if (fnd)
	    return fnd;
	}
    }
  else
    {
      ; /* An identifier...if we could not find a protocol.  */
    }

  return 0;
}

void
/* APPLE LOCAL radar 4548636 */
objc_start_class_interface (tree class, tree super_class, tree protos, tree attributes)
{
  objc_interface_context
    = objc_ivar_context
    = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
/* APPLE LOCAL begin radar 4548636 */
  CLASS_ATTRIBUTES (objc_interface_context) = attributes;
  objc_warn_on_class_attributes (objc_interface_context, false);
/* APPLE LOCAL end radar 4548636 */
  objc_public_flag = 0;
}

void
objc_start_category_interface (tree class, tree categ, tree protos)
{
  /* APPLE LOCAL begin radar 4994854 */
  if (categ == NULL_TREE)
    {
      /* Anonymous category. Check if it is a continuation anonymous category? */
      tree class_category_is_assoc_with = lookup_interface (class);
      if (class_category_is_assoc_with)
        {
          tree cat = lookup_category (class_category_is_assoc_with, NULL_TREE);
          if (cat)
            {
              /* This is a continuation anonymous category. Use the first declaration. */
              objc_interface_context = cat;
              objc_ivar_chain = continue_class (objc_interface_context);
              return;
            }
        }
    }
  /* APPLE LOCAL end radar 4994854 */
  objc_interface_context
    = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
  objc_ivar_chain
    = continue_class (objc_interface_context);
}

void
/* APPLE LOCAL radar 4947311 - protocol attributes */
objc_start_protocol (tree name, tree protos, tree prefix_attrs)
{
  objc_interface_context
    /* APPLE LOCAL radar 4947311 - protocol attributes */
    = start_protocol (name, protos, prefix_attrs);
  /* APPLE LOCAL C* language */
  objc_method_optional_flag = 0;
}

void
objc_continue_interface (void)
{
  /* APPLE LOCAL begin radar 4666559 */
  /* Since we may add additional ivars for @property declarations,
     do not output any debug info. for class type as yet. */
  gcc_assert (TREE_CODE (objc_interface_context) == CLASS_INTERFACE_TYPE);
  save_default_debug_hooks = debug_hooks;
  debug_hooks = &do_nothing_debug_hooks;
  /* APPLE LOCAL end radar 4666559 */
  objc_ivar_chain
    = continue_class (objc_interface_context);
  /* APPLE LOCAL radar 4666559 */
  debug_hooks = save_default_debug_hooks;
}

void
objc_finish_interface (void)
{
  finish_class (objc_interface_context);
  /* APPLE LOCAL begin radar 4666559 */
  if (TREE_CODE (objc_interface_context) == CLASS_INTERFACE_TYPE)
    {
      tree record = CLASS_STATIC_TEMPLATE (objc_interface_context);
      /* Now output debug info. Since ivar list is now complete. */
      gcc_assert (record);
#ifdef OBJCPLUS
      push_lang_context (lang_name_c);
#endif /* OBJCPLUS */
      rest_of_type_compilation (record, 1);
      if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
	TREE_USED (TYPE_STUB_DECL (record)) = 1;
#ifdef OBJCPLUS
      pop_lang_context ();
#endif /* OBJCPLUS */
    }
  /* APPLE LOCAL end radar 4666559 */
  objc_interface_context = NULL_TREE;
  /* APPLE LOCAL C* language */
  objc_method_optional_flag = 0;
}

void
objc_start_class_implementation (tree class, tree super_class)
{
  objc_implementation_context
    = objc_ivar_context
    = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
  objc_public_flag = 0;
  /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
  if (flag_objc_abi == 2) 
    {
      tree record = CLASS_STATIC_TEMPLATE(implementation_template);
      if (record) 
        {
          bool changed = false;
          tree field;
          for (field = TYPE_FIELDS(record); field; field = TREE_CHAIN (field))
            {
#ifdef OBJCPLUS
              /* Skip C++ static members, and things that are not fields at all. */
              if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
                continue;
#endif
              /* If we have an embedded base class, and its size doesn't match the
                 size in the field node, that's because ivars were added to the base
                 class after the field node was built.  We need to update the field
                 node and re-layout the outer record. */
              if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
                  && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
                  && DECL_SIZE (field) && TYPE_SIZE(TREE_TYPE(field))
                  && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
                  && TREE_CODE (TYPE_SIZE (TREE_TYPE (field))) == INTEGER_CST
                  && TREE_INT_CST_LOW (DECL_SIZE (field))
                     != TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (field))))
                {
                  DECL_SIZE (field) = TYPE_SIZE (TREE_TYPE (field));
                  DECL_SIZE_UNIT (field) = TYPE_SIZE_UNIT (TREE_TYPE (field));
                  changed = true;
                }
            }
          if (changed) 
            {
              TYPE_SIZE (record) = 0;
              layout_type (record);
            }
        }
    }
#endif
  /* LLVM LOCAL end */
}

void
objc_start_category_implementation (tree class, tree categ)
{
  objc_implementation_context
    = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
  objc_ivar_chain
    = continue_class (objc_implementation_context);
}

void
objc_continue_implementation (void)
{
  objc_ivar_chain
    = continue_class (objc_implementation_context);
}

void
objc_finish_implementation (void)
{
#ifdef OBJCPLUS
  if (flag_objc_call_cxx_cdtors)
    objc_generate_cxx_cdtors ();
#endif

  if (objc_implementation_context)
    {
      finish_class (objc_implementation_context);
      objc_ivar_chain = NULL_TREE;
      objc_implementation_context = NULL_TREE;
    }
  else
    warning (0, "%<@end%> must appear in an @implementation context");
}

void
objc_set_visibility (int visibility)
{
  objc_public_flag = visibility;
}

/* APPLE LOCAL begin C* language */
void
objc_set_method_opt (int optional)
{
  objc_method_optional_flag = optional;
  if (!objc_interface_context
      || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
    {
      error ("@optional/@required is allowed in @protocol context only.");
      objc_method_optional_flag = 0;
    }
}

/* This routine gather property attribute information from attribute
   portion of a property declaration. */

void
objc_set_property_attr (int attr, tree ident)
{
  static char string[BUFSIZE];
  switch (attr)
    {
    case 0: /* init */
	property_readonly = false;
	property_setter = property_getter = NULL_TREE;
 	property_readwrite = property_assign = property_retain = property_copy = false;
	/* APPLE LOCAL radar 4947014 - objc atomic property */
	property_atomic = true;
	break;
    case 1: /* readonly */
	property_readonly = true;
	break;
    case 2: /* getter = ident */
	if (property_getter != NULL_TREE)
	  error("getter attribute can be specified only once");
        property_getter = ident;
	break;
    case 3: /* setter = ident */
	if (property_setter != NULL_TREE)
	  error("setter attribute can be specified only once");
	/* setters always have a trailing ':' in their name. In fact, this is the
	   only syntax that parser recognizes for a setter name. Must add a trailing
	   ':' here so name matches that of the declaration of user instance method
	   for the setter. */
	sprintf (string, "%s:", IDENTIFIER_POINTER (ident));
	property_setter = get_identifier (string);;
	break;
    case 9: /* readwrite */
	property_readwrite = true;
	break;
    case 10: /* assign */
	property_assign = true;
	break;
    case 11: /* retain */
	property_retain = true;
	break;
    case 12: /* copy */
	property_copy = true;
	break;
    /* APPLE LOCAL begin radar 4947014 - objc atomic property */
    case 13: /* nonatomic */
	property_atomic = false;
	break;
    /* APPLE LOCAL end radar 4947014 - objc atomic property */
    default:
	break;
    }
}

/* APPLE LOCAL begin radar 5168496 */
/* Return TRUE if object of TYPE pointer type requires explicit memory management. 
   This is reserved for objctivec-c object pointers; such as 'id'. */
static bool
managed_objc_object_pointer (tree type)
{
  return type && type != error_mark_node && POINTER_TYPE_P (type)
	 && (objc_is_object_id (TREE_TYPE (type)) || TYPED_OBJECT (TREE_TYPE (type))
             /* APPLE LOCAL radar 6255671 */
             || TREE_CODE (type) == BLOCK_POINTER_TYPE);
}
/* APPLE LOCAL end radar 5168496 */

/* This routine declares a 'setter' method for property X in class CLASS. */
static void
objc_add_property_setter_method (tree class, tree x)
{
  tree type = TREE_TYPE (x);
  tree key_name, arg_type, arg_name;
  tree setter_decl, selector;
  tree ret_type = build_tree_list (NULL_TREE, void_type_node);
  tree mth;
  /* setter name. */
  key_name = get_identifier (objc_build_property_setter_name (
                             PROPERTY_NAME (x), false));
  arg_type = build_tree_list (NULL_TREE, type);
  arg_name = get_identifier ("_value");
  /* APPLE LOCAL radar 4157812 */
  selector = objc_build_keyword_decl (key_name, arg_type, arg_name, NULL_TREE);
  /* APPLE LOCAL radar 5839812 - location for synthesized methods  */
  DECL_SOURCE_LOCATION (selector) = DECL_SOURCE_LOCATION (x);
  setter_decl = build_method_decl (INSTANCE_METHOD_DECL,
                                   ret_type, selector,
                                   build_tree_list (NULL_TREE, NULL_TREE),
				   false);
  /* APPLE LOCAL radar 4712415 */
  TREE_DEPRECATED (setter_decl) = TREE_DEPRECATED (x);
  mth = lookup_method (CLASS_NST_METHODS (class),
                       METHOD_SEL_NAME (setter_decl));
  if (PROPERTY_IVAR_NAME (x)
      && (mth = lookup_method (CLASS_NST_METHODS (class),
                               METHOD_SEL_NAME (setter_decl))))
    {
      /* user declared accessor is encounterred. This is error. */
      error ("user accessor %<%c%s%> not allowed for property %qs",
             '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)),
             IDENTIFIER_POINTER (PROPERTY_NAME (x)));
    }
  else
    /* APPLE LOCAL radar 4653422 */
    objc_add_method (class, setter_decl, false, OPTIONAL_PROPERTY (x));
  METHOD_PROPERTY_CONTEXT (setter_decl) = x;
  return;
}

/* This routine builds a 'property_decl' tree node and adds it to the list
   of such properties in the current class. It also checks for duplicates.  */

void
objc_add_property_variable (tree decl)
{
  tree property_decl;
  tree x;

  /* APPLE LOCAL radar 4531086 */
  OBJC_WARN_OBJC2_FEATURES ("property");
  if (DECL_INITIAL (decl) || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    {
      error ("bad property declaration");
      return;
    }
  if (objc_implementation_context)
    {
      error ("property cannot be declared inside @implemenation context");
      return;
    }
  else if (!objc_interface_context)
    {
      fatal_error ("property declaration not in @interface or @implementation context");
      return;
    }

  property_decl = make_node (PROPERTY_DECL);
  TREE_TYPE (property_decl) = TREE_TYPE (decl);

  PROPERTY_NAME (property_decl) = DECL_NAME (decl);
  PROPERTY_GETTER_NAME (property_decl) = property_getter;
  PROPERTY_SETTER_NAME (property_decl) = property_setter;
  PROPERTY_READONLY (property_decl) = property_readonly
					? boolean_true_node
					: boolean_false_node;
  PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
  PROPERTY_DYNAMIC (property_decl) = NULL_TREE;
  /* APPLE LOCAL radar 4712415 */
  TREE_DEPRECATED (property_decl) = TREE_DEPRECATED (decl);
  /* APPLE LOCAL radar 4653422 */
  OPTIONAL_PROPERTY (property_decl) = objc_method_optional_flag;
  /* assign, retain and copy are mutually exclusive. */
  if ((property_assign && property_retain)
      || (property_assign && property_copy) 
      || (property_retain && property_copy))
    {
      error ("assign, retain and copy are mutually exclusive");
      property_copy = property_retain = false;
    }
 else if (!property_assign && !property_retain && !property_copy
          && !property_readonly
          /* APPLE LOCAL radar 5168496 */
	  && managed_objc_object_pointer (TREE_TYPE (property_decl)))
        {
          /* For -fobjc-gc-only, a warning is issued under more restricted condition. See below. */
          if (!flag_objc_gc_only && warn_property_assign_default)
            warning (0, "no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed");
        }

  /* readwrite is the default */
  if (!property_readonly)
    property_readwrite = true;
  /* readonly and readwrite are mutually exclusive. */
  else if (property_readwrite)
    {
      error ("readonly and readwrite are mutually exclusive");
      property_readwrite = false;
      PROPERTY_READONLY (property_decl) = boolean_false_node;
    }
  PROPERTY_COPY (property_decl) = property_copy 
			          ? boolean_true_node 
			          : boolean_false_node;
  PROPERTY_RETAIN (property_decl) = property_retain 
				    ? boolean_true_node 
				    : boolean_false_node;
  PROPERTY_READWRITE (property_decl) = property_readwrite
				       ? boolean_true_node 
				       : boolean_false_node;
  /* APPLE LOCAL radar 4947014 - objc atomic property */
  ATOMIC_PROPERTY (property_decl) = property_atomic;

  if (objc_interface_context)
    {
      /* Doing the property in interface declaration. */
      if (PROPERTY_ASSIGN (property_decl))
	{
	  /* APPLE LOCAL radar 5168496 */
	  if (managed_objc_object_pointer (TREE_TYPE (property_decl)))
	    {
	      /* APPLE LOCAL begin radar 4855821 */
	      if (!flag_objc_gc)
		{
                  /* APPLE LOCAL begin radar 6255671 */
		  if (!property_assign)
                  {
                    if (TREE_CODE (TREE_TYPE (property_decl)) == BLOCK_POINTER_TYPE)
                      error ("assign attribute (default) not appropriate for non-gc object property %qs",
                             IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
                    else
                      warning (0, "assign attribute (default) not appropriate for non-gc object property %qs",
                               IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
                  }
                  /* APPLE LOCAL end radar 6255671 */
		}
	      /* APPLE LOCAL end radar 4855821 */
              else if (!property_assign)
                {
                  /* under -fobjc-gc[-only], a warning should be issued if none of those were specified
                     AND the object type conforms to <NSCopying>. */
                  tree ltyp = TREE_TYPE (property_decl);
                  /* APPLE LOCAL begin radar 6379842 */
                  /* under -fobjc-gc-only flag, a warning to be issued if 
                   block pointer property does not have 'copy' attribute. */
                  if (flag_objc_gc_only 
                      && TREE_CODE (ltyp) == BLOCK_POINTER_TYPE
                      && !property_copy)
                    warning (0, "'copy' attribute must be specified for the block"
                           " property %qs when -fobjc-gc-only is specified",
                           IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
                  /* APPLE LOCAL end radar 6379842 */
                  do
                    ltyp = TREE_TYPE (ltyp);
                  while (POINTER_TYPE_P (ltyp));
		  /* APPLE LOCAL begin radar 5607453 */
                  /* APPLE LOCAL radar 5096644 */
                  if (TYPE_HAS_OBJC_INFO (ltyp) 
		      && !objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
		      && TREE_CODE (TYPE_OBJC_INTERFACE (ltyp)) != IDENTIFIER_NODE)
		  /* APPLE LOCAL end radar 5607453 */
                    {
                      tree id_NSCopying = get_identifier ("NSCopying");
                      tree lproto = lookup_protocol (id_NSCopying);
		      /* APPLE LOCAL radar 4947311 - protocol attributes */
                      objc_declare_protocols (tree_cons (NULL_TREE, id_NSCopying, NULL_TREE), NULL_TREE);
                      /* APPLE LOCAL begin radar 5096644 */
                      if (lproto && TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE
                          && objc_lookup_protocol (lproto , TYPE_OBJC_INTERFACE (ltyp), ltyp, false))
                        /* APPLE LOCAL begin radar 5698469 */
                        warning (0, "%s'assign' attribute on property %qs which implements 'NSCopying' "
                                 "protocol not appropriate with %s",
                                 !property_assign ? "default " :  "",
                                 IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)),
                                 flag_objc_gc_only ? "-fobjc-gc-only" : "-fobjc-gc");
                      /* APPLE LOCAL end radar 5698469 */
                      /* APPLE LOCAL end radar 5096644 */
                    }
                }
	    }
	}

      /* must check for duplicate property declarations. */
      for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
	{
	  if (PROPERTY_NAME (x) == DECL_NAME (decl))
	    {
	      error ("%Jduplicate property declaration %qD", decl, decl);
	      return;
	    }
	}

      /* APPLE LOCAL begin radar 4965989 */
      /* New property's anonymous category */
      if (ANONYMOUS_CATEGORY (objc_interface_context))
        {
          /* @interface INTF() ... @end */
          tree class = lookup_interface (CLASS_NAME (objc_interface_context));
          if (class)
            {
              /* Find the property in the class. */
              for (x = CLASS_PROPERTY_DECL (class); x; x = TREE_CHAIN (x))
                if (PROPERTY_NAME (x) == DECL_NAME (decl))
                  break;
              if (x)
                {
                  if (PROPERTY_READONLY (x) == boolean_true_node
                      && PROPERTY_READWRITE (property_decl) == boolean_true_node)
                    {
                      /* APPLE LOCAL begin radar 5159695 */
                      if ((PROPERTY_ASSIGN (x) != PROPERTY_ASSIGN (property_decl))
                          || (PROPERTY_RETAIN (x) != PROPERTY_RETAIN (property_decl))
                          || (PROPERTY_COPY (x) != PROPERTY_COPY (property_decl))
                          || (IS_ATOMIC (x) != IS_ATOMIC (property_decl)))
                        warning (0, "property %qs attribute in %qs class continuation"
                                 " does not match class %qs property",
                                 IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)),
                                 IDENTIFIER_POINTER (CLASS_NAME (class)),
                                 IDENTIFIER_POINTER (CLASS_NAME (class)));
                      /* APPLE LOCAL end radar 5159695 */

                      /* class property is now 'readwrite'. */
                      PROPERTY_READONLY (x) = boolean_false_node;
                      PROPERTY_READWRITE (x) = boolean_true_node;
                      PROPERTY_COPY (x) = PROPERTY_COPY (property_decl);
                      PROPERTY_RETAIN (x) = PROPERTY_RETAIN (property_decl);
                      PROPERTY_SETTER_NAME (x) = PROPERTY_SETTER_NAME (property_decl);
                    }
                  else
		    error ("use class continuation to override %<readonly%> property %qs with %<readwrite%> in class %qs",
                           IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)),
                           IDENTIFIER_POINTER (CLASS_NAME (class)));

 		  /* APPLE LOCAL begin radar 5159707 */
 		  if (!comptypes (TREE_TYPE (x), TREE_TYPE (property_decl)))
 		    {
 		      warning (0, "property %qs type in %qs class continuation does not match class %qs property",
 			        IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)),
 			        IDENTIFIER_POINTER (CLASS_NAME (class)),
 			        IDENTIFIER_POINTER (CLASS_NAME (class)));
 		      TREE_TYPE (property_decl) = TREE_TYPE (x);
 		    }
 		  /* APPLE LOCAL end radar 5159707 */
  		}
              /* APPLE LOCAL begin radar 4994854 */
              else
                {
                  /* Inject anonymous categories property declaration into promary class. */
                  tree save_objc_interface_context = objc_interface_context;
                  objc_interface_context = class;
                  objc_add_property_variable (decl);
                  objc_interface_context = save_objc_interface_context;
                }
              /* APPLE LOCAL end radar 4994854 */
            }
          else
            error ("anonymous category %qs has no primary class", IDENTIFIER_POINTER (CLASS_NAME (class)));
        }
      /* APPLE LOCAL end radar 4965989 */
      TREE_CHAIN (property_decl) = CLASS_PROPERTY_DECL (objc_interface_context);
      CLASS_PROPERTY_DECL (objc_interface_context) = property_decl;
    }
}

/* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
   PROTOCOL.  */

static tree
lookup_property_in_list (tree chain, tree property)
{
  tree x;
  for (x = CLASS_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
    if (PROPERTY_NAME (x) == property)
      return x;
  return NULL_TREE;
}

/* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */

static tree
lookup_property_in_protocol_list (tree rproto_list, tree property)
{
  tree rproto, x;
  for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
    {
      tree p = TREE_VALUE (rproto);
      if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
	{
	  if ((x = lookup_property_in_list (p, property)))
	    return x;
	  if (PROTOCOL_LIST (p)
	      && (x = lookup_property_in_protocol_list (PROTOCOL_LIST (p), property)))
	    return x;
	}
      else
	{
	  ; /* An identifier...if we could not find a protocol.  */
	}
    }
  return NULL_TREE;
}

/* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
   chain of interface hierarchy.  */

static tree
lookup_property (tree interface_type, tree property)
{
  tree inter = interface_type;
  while (inter)
    {
      tree x, category;
      if (TREE_CODE (inter) != CLASS_INTERFACE_TYPE)
	  return NULL_TREE;  /* error - caller will issue it */
      if ((x = lookup_property_in_list (inter, property)))
	return x;
      /* Failing that, look for the property in each category of the class.  */
      category = inter;
      while ((category = CLASS_CATEGORY_LIST (category)))

	if ((x = lookup_property_in_list (category, property)))
	  return x;

      /*  Failing to find in categories, look for property in protocol list. */
      if (CLASS_PROTOCOL_LIST (inter)
	  && (x = lookup_property_in_protocol_list (
		    CLASS_PROTOCOL_LIST (inter), property)))
	return x;

      /* Failing that, climb up the inheritance hierarchy.  */
      inter = lookup_interface (CLASS_SUPER_NAME (inter));
    }
  return inter;
}

static tree
objc_get_inner_exp (tree t)
{
  while (TREE_CODE (t) == COMPOUND_EXPR
         || TREE_CODE (t) == MODIFY_EXPR
         || TREE_CODE (t) == NOP_EXPR
         || TREE_CODE (t) == CONVERT_EXPR
         || TREE_CODE (t) == COMPONENT_REF)
    t = TREE_OPERAND (t, 0);
  return t;
}

/* APPLE LOCAL begin radar 5285911 */
/* This routine, given RECEIVER.COMPONENT, RTYPE for type of the class for the
   receiver, returns in PROP the property declaration and in INTERFACE_TYPE class
   declaration. Furthermore, if CHECK_PROP_COND is true, it checks for correctness of
   property use in dot syntax and issues diagnostic. If CHECK_PROP_COND is false, it assumes
   that tree is a correct property access. On sucessess it returns RECEIVER.
   Finally, if RECEIVER is a class object, true is returned in RECEIVER_IS_CLASS.
*/
static tree
objc_property_access_info (tree receiver, tree component, tree rtype, 
			   bool check_prop_cond, 
			   tree *interface_type, tree *prop, bool *receiver_is_class)
{
  *prop = NULL_TREE;
  *interface_type = NULL_TREE;
  *receiver_is_class = false;
  if (objc_is_id (rtype))
    {
      tree rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
                      ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
                      : NULL_TREE);
      if (rprotos)
        *prop = lookup_property_in_protocol_list (rprotos, component);
      else
      /* Could be super.property */
	{
      	  tree t = objc_get_inner_exp (receiver);
	  /* APPLE LOCAL begin radar 5277239 */
	  int super = (t == UOBJC_SUPER_decl);
	  tree class_tree = receiver_is_class_object (receiver, (t == self_decl), super);
	  /* CLASSNAME.class_method ? */
	  if (class_tree)
	    {
	      tree class_type = lookup_interface (class_tree);
	      if (class_type)
	      {
	        *interface_type = class_type;
	        *receiver_is_class = true;
	      }
	    }
	  else if (super)
	  /* APPLE LOCAL end radar 5277239 */
            {
              /* super.property */
              if (implementation_template && CLASS_SUPER_NAME (implementation_template))
		{
                  *interface_type = lookup_interface (CLASS_SUPER_NAME (implementation_template));
		  if (*interface_type)
		    *prop = lookup_property (*interface_type, component);
		}
            }
	}
    }
  else
    {
      tree basetype = TYPE_MAIN_VARIANT (rtype);
      if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE)
        basetype = TREE_TYPE (basetype);
      else if (check_prop_cond)
	/* APPLE LOCAL begin radar 5376125 */
	{
	  /* Note that for objc2, this warning is issued when ivar reference
	     tree is generated in call to objc_v2_build_ivar_ref */
	  if (!flag_objc_gc && warn_direct_ivar_access && flag_objc_abi != 2)
            objc_warn_direct_ivar_access (basetype, component);
	  return NULL_TREE;
	}
	/* APPLE LOCAL end radar 5376125 */

      while (basetype != NULL_TREE
             && TREE_CODE (basetype) == RECORD_TYPE && OBJC_TYPE_NAME (basetype)
             && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
             && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
      basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
      if (basetype != NULL_TREE && TYPED_OBJECT (basetype))
        {
          *interface_type = TYPE_OBJC_INTERFACE (basetype);
          /* Handle more user error conditions */
          if (check_prop_cond && 
	      (!*interface_type ||
              (TREE_CODE (*interface_type) != CLASS_INTERFACE_TYPE
               &&  TREE_CODE (*interface_type) != PROTOCOL_INTERFACE_TYPE
               && TREE_CODE (*interface_type) != CATEGORY_INTERFACE_TYPE)))
	    {
	      /* Better error recovery */
	      if (TREE_CODE (receiver) == OBJC_PROPERTY_REFERENCE_EXPR)
		{
		  error ("accessing unknown %qs component of a property",
                         IDENTIFIER_POINTER (component));
                  return error_mark_node;
                }
	      return NULL_TREE;
	    }
          *prop = lookup_property (*interface_type, component);
          /* APPLE LOCAL begin radar 4959107 */
          if (!*prop && TYPE_OBJC_PROTOCOL_LIST (basetype))
            *prop = lookup_property_in_protocol_list (TYPE_OBJC_PROTOCOL_LIST (basetype), 
						      component);
          /* APPLE LOCAL end radar 4959107 */
        }
    }
  return receiver;
}

/*
  This routine builds the OBJC_PROPERTY_REFERENCE_EXPR for 
  RECEIVER.COMPONENT which later on gets transformed into a 'getter' or 
  'setter' call depending on its use.
*/

tree
objc_build_property_reference_expr (tree receiver, tree component)
{
  tree interface_type;
  tree rtype;
  tree prop, prop_type, res;
  bool receiver_is_class;

  if (component == error_mark_node || component == NULL_TREE
      || TREE_CODE (component) != IDENTIFIER_NODE)
    return NULL_TREE;
  if (receiver == error_mark_node || receiver == NULL_TREE
      || (rtype = TREE_TYPE (receiver)) == NULL_TREE)
    return NULL_TREE;
  res = objc_property_access_info (receiver, component, rtype, true, 
				   &interface_type, &prop, &receiver_is_class);
  /* These are conditions for errornous property access or not a property
     access syntax. */
  if (res == NULL_TREE || res == error_mark_node)
    return res;

  prop_type = NULL_TREE;
  /* APPLE LOCAL begin objc2 5512183 */
  if (interface_type && !receiver_is_class)
  /* APPLE LOCAL end objc2 5512183 */
    {
      /* type of the expression is either the property type or, if no property declared,
	 then ivar type used in receiver.ivar expression. */
      tree ivar = nested_ivar_lookup (interface_type, component);
      if (ivar)
	prop_type = TREE_TYPE (ivar);
      else
        {
	  /* Try to get the type for the 'getter' declaration. */
          tree getter = lookup_method_static (interface_type, component, 0, false, false);
	  if (getter)
	    prop_type = TREE_VALUE (TREE_TYPE (getter));
        }
    }
  /* APPLE LOCAL begin radar 5277239 */
  else if (interface_type)
    {
      /* CLASS_NAME.getter expression. Try finding a class method and, if one not found, 
	 attach a dummy 'int' type to the expression tree (presumably because we end up 
	 using it on the LHS of assignment only. */
      tree getter = lookup_method_static (interface_type, component, 1, false, true);
      prop_type = getter ? TREE_VALUE (TREE_TYPE (getter)) : integer_type_node;
    }
  /* APPLE LOCAL end radar 5277239 */
  /* APPLE LOCAL begin radar 5893391 */
  else if (!prop && objc_is_id (rtype))
  {
    tree rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
                    ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
                    : NULL_TREE);
    if (rprotos) {
        tree getter = lookup_method_in_protocol_list (rprotos, component, 0);
        prop_type = getter ? TREE_VALUE (TREE_TYPE (getter)) : integer_type_node;
    }
  }
  /* APPLE LOCAL end radar 5893391 */
  
  /* APPLE LOCAL begin objc2 5512183 */
  if (prop)
    {
      /* APPLE LOCAL begin radar 6029577 */
      tree property_type = TREE_TYPE (prop);
      bool comparison_result = false;
      if (prop_type)
      {
#ifdef OBJCPLUS
        if (TREE_CODE (property_type) == REFERENCE_TYPE
            || TREE_CODE (prop_type) == REFERENCE_TYPE)
        {
          if (TREE_CODE (property_type) == REFERENCE_TYPE)
            property_type = TREE_TYPE (property_type);
          if (TREE_CODE (prop_type) == REFERENCE_TYPE)
            prop_type = TREE_TYPE (prop_type);
          comparison_result =
            !objcp_reference_related_p (prop_type, property_type);
        }
        else
#endif
          comparison_result = comptypes (prop_type, property_type) != 1;
      }
      if (prop_type && comparison_result)
	error ("type of accessor does not match the type of property %qs",
	       IDENTIFIER_POINTER (PROPERTY_NAME (prop)));
      else
	prop_type = property_type;
      /* APPLE LOCAL end radar 6029577 */
    }
  /* APPLE LOCAL end objc2 5512183 */

  if (prop_type)
    {
      /* APPLE LOCAL begin 5494488 */
      tree prop_expr = build3 (OBJC_PROPERTY_REFERENCE_EXPR, prop_type,
			       receiver, component, UOBJC_SUPER_decl);
      /* APPLE LOCAL end 5494488 */
      TREE_SIDE_EFFECTS (prop_expr) = 1;
      return prop_expr;
    }
  else
    return NULL_TREE;
}

/* This routine generates a 'getter' call tree, using the input parameters. It returns 
   the CALL_EXPR tree or error_mark_node */

static tree
objc_build_getter_call (tree receiver, tree component)
{
  tree interface_type;
  tree x;
  bool receiver_is_class;
  tree getter = error_mark_node;
  tree rtype = TREE_TYPE (receiver);
  (void)objc_property_access_info (receiver, component, rtype, false, 
				   &interface_type, &x, &receiver_is_class);

  if (x)
    {
      /* Get the getter name. */
      gcc_assert (PROPERTY_NAME (x));
      if (PROPERTY_GETTER_NAME (x))
	/* If 'getter=getter_name' attribute is specified, must use the user provided
	   getter name in generating messaging call. */
        getter = objc_finish_message_expr (receiver, PROPERTY_GETTER_NAME (x), NULL_TREE);
      else
        getter = objc_finish_message_expr (receiver, PROPERTY_NAME (x), NULL_TREE);
    }
  else if (interface_type)
    {
      /* APPLE LOCAL begin radar 5277239 */
      getter = lookup_method_static (interface_type, component, receiver_is_class, 
				     false, receiver_is_class);
      /* APPLE LOCAL end radar 5277239 */
      if (getter)
#ifdef OBJCPLUS
	getter = objc_build_message_expr (
		   build_tree_list (receiver, 
				    build_tree_list (component, NULL_TREE)));
#else
	getter = objc_build_message_expr (build_tree_list (receiver, component));
#endif
      else
	{
	  error ("accessing unknown %qs %s method",
		  IDENTIFIER_POINTER (component), receiver_is_class ? "class" : "getter");
	  getter = receiver;	/* recover */
	}
    }
  /* APPLE LOCAL begin radar 5893391 */
  else if (objc_is_id (rtype))
  {
    tree rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
                    ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
                    : NULL_TREE);
    if (rprotos) {
      getter = lookup_method_in_protocol_list (rprotos, component, 0);
      if (getter)
#ifdef OBJCPLUS
	getter = objc_build_message_expr (
          build_tree_list (receiver, build_tree_list (component, NULL_TREE)));
#else
      getter = objc_build_message_expr (build_tree_list (receiver, component));
#endif
      else
      {
        error ("accessing unknown %qs getter method",
               IDENTIFIER_POINTER (component));
        getter = receiver;	/* recover */
      }      
    }
  }
  /* APPLE LOCAL end radar 5893391 */
  return getter;
}
/* APPLE LOCAL end radar 5285911 */

/* This routine is called with PROPERTY_IDENT being the name of the getter method,
   ; user attribute specified or the default. From the getter name, it first finds 
   the property name and from property name it finds the setter_name; one specified
   by user or the default. */

static const char *
objc_resolve_build_property_setter_name (tree receiver, tree property_ident)
{
  tree rtype, basetype,x,class=NULL_TREE;
  bool receiver_is_class = false;
  gcc_assert (receiver && TREE_TYPE (receiver));
  rtype = TREE_TYPE (receiver);
  if (objc_is_id (rtype))
    {
      tree t = objc_get_inner_exp (receiver);
      /* APPLE LOCAL begin radar 5277239 */
      int super = (t == UOBJC_SUPER_decl);
      tree class_tree = receiver_is_class_object (receiver, (t == self_decl), super);
      /* CLASSNAME.class_method = rhs ? */
      if (class_tree)
        {
          class = lookup_interface (class_tree);
          receiver_is_class = true;
        }
      else if (super)
      /* APPLE LOCAL end radar 5277239 */
	{
	  /* super.property */
	  if (implementation_template
                && CLASS_SUPER_NAME (implementation_template))
	    class = lookup_interface (CLASS_SUPER_NAME (implementation_template));
	}
    }
  else
    {
      basetype = TYPE_MAIN_VARIANT (rtype);
      gcc_assert (basetype && TREE_CODE (basetype) == POINTER_TYPE);
      basetype = TREE_TYPE (basetype);
      while (basetype != NULL_TREE
             && TREE_CODE (basetype) == RECORD_TYPE && OBJC_TYPE_NAME (basetype)
             && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
             && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
        basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
      gcc_assert (basetype && TYPED_OBJECT (basetype));
      class = TYPE_OBJC_INTERFACE (basetype);
    }
  gcc_assert (class);
  /* APPLE LOCAL begin radar 5277239 */
  if (receiver_is_class)
    {
      /* Direct access of a class method using the dot syntax. 
         Make up a 'setter' method name. */
      char *setter_name = objc_build_property_setter_name (property_ident, true);
      /* A class method of the given name must exist or it is error. */
      if (!lookup_method_static (class, get_identifier (setter_name), 1, false, true))
        error ("accessing unknown %qs class method", setter_name);
      return setter_name; 
    }
  /* APPLE LOCAL end radar 5277239 */
  /* APPLE LOCAL begin radar 5390587 */
  x = lookup_property (class, property_ident);
  return (x && PROPERTY_SETTER_NAME (x)) ? IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x))
					 : objc_build_property_setter_name 
					     (property_ident, true);
  /* APPLE LOCAL end radar 5390587 */
}

/* This routine builds a call to property's 'setter' function. RECEIVER is the 
   receiving object for 'setter'. PROPERTY_IDENT is name of the property and
   RHS is the argument passed to the 'setter' function.  */

static tree
objc_setter_func_call (tree receiver, tree property_ident, tree rhs)
{
  tree setter_argument = build_tree_list (NULL_TREE, rhs);
  const char *setter_name = objc_resolve_build_property_setter_name (receiver, property_ident); 
  tree setter;
  in_objc_property_setter_name_context = true;
  setter = objc_finish_message_expr (receiver, 
				     get_identifier (setter_name),
                                     setter_argument);
  in_objc_property_setter_name_context = false;
  /* APPLE LOCAL begin radar 4838528 */
  if (TREE_CODE (setter) == CALL_EXPR && TREE_TYPE (setter) != void_type_node)
    warning (0, "type of setter %qs must be 'void' instead of '%T'", 
	     setter_name, TREE_TYPE (setter) );
  /* APPLE LOCAL end radar 4838528 */
  return setter;
}

/* This routine builds a compound expression which implements semantics
   of property's setter expression:
   typeof (rhs) temp; (temp = rhs, [receiver prop_setter:temp], temp)
   if rhs has no side-effect, simply generate:
   ([receiver prop_setter:rhs], rhs)
*/
static tree
objc_build_compound_setter_call (tree receiver, tree prop_ident, tree rhs)
{
  tree temp, bind, comma_exp;
  if (TREE_SIDE_EFFECTS (rhs))
    {
      /* To allow for correct property assignment semantics
         and in accordance with C99 rules we generate: type temp;
         (temp = rhs, [lhs Setter:temp], temp) */
      /* APPLE LOCAL begin radar 5279122 */
      /* APPLE LOCAL radar 6264448 */
      /* rhs = default_conversion (rhs);  removed */
      temp = objc_create_named_tmp_var (TREE_TYPE (rhs), "prop");
      /* APPLE LOCAL end radar 5279122 */
      bind = build3 (BIND_EXPR, void_type_node, temp, NULL, NULL);
      TREE_SIDE_EFFECTS (bind) = 1;
      add_stmt (bind);
      comma_exp = build_modify_expr (temp, NOP_EXPR, rhs);
      comma_exp = build_compound_expr (comma_exp,
		    objc_setter_func_call (receiver, prop_ident, temp));
      /* APPLE LOCAL begin radar 6264448 */
      /* conversion of 'temp' moved *after* it is passed ar argument to build
         setter call. This is because its type must match the setter's argument
         type. */
      temp = default_conversion (temp);
      /* APPLE LOCAL end radar 6264448 */
    }
  else
    {
      comma_exp = objc_setter_func_call (receiver, prop_ident, rhs);
      /* APPLE LOCAL radar 5279122 */
      rhs = default_conversion (rhs);
      /* APPLE LOCAL radar 5140757 */
      temp = save_expr (rhs);
      /* APPLE LOCAL begin radar 4727191 */
      if (TREE_CODE (temp) == VAR_DECL)
        DECL_SEEN_IN_BIND_EXPR_P (temp) = 1;
      /* APPLE LOCAL end radar 4727191 */
    }
  /* Suppress C++'s warning of comma-expr with no side-effect. */
  TREE_NO_WARNING (temp) = 1;
  /* Suppress warning on value computed is not used */
  comma_exp = build_compound_expr (comma_exp, temp);
  TREE_NO_WARNING (comma_exp) = 1;
  return comma_exp;
}

/* APPLE LOCAL begin radar 5285911 */
bool
objc_property_reference_expr (tree expr)
{
  return (expr 
	  && TREE_CODE (expr) == OBJC_PROPERTY_REFERENCE_EXPR);
}

/* This routine converts a previously synthesized 'getter' function call for
   a property and converts it to a 'setter' function call for the same
   property.  */

tree
objc_build_setter_call (tree lhs, tree rhs)
{
  if (objc_property_reference_expr (lhs))
    return objc_build_compound_setter_call (TREE_OPERAND (lhs, 0), 
					    TREE_OPERAND (lhs, 1), rhs);
  return NULL_TREE;
}
/* APPLE LOCAL end radar 5285911 */

/* 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 field_decl, field_decl_chain;

  prop_record = start_struct (RECORD_TYPE, get_identifier ("_prop_t"));
  /* const char * name */
  field_decl = create_field_decl (string_type_node, "name");
  field_decl_chain = field_decl;
  /* const char * attribute */
  field_decl = create_field_decl (string_type_node, "attribute");
  chainon (field_decl_chain, field_decl);
  finish_struct (prop_record, field_decl_chain, NULL_TREE);
  return prop_record;
}

/* 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 field_decl, field_decl_chain;

  property_list_t_record = start_struct (RECORD_TYPE, NULL_TREE);

  /* uint32_t const entsize */
  field_decl = create_field_decl (integer_type_node, "entsize");
  field_decl_chain = field_decl;

  /* int prop_count */
  field_decl = create_field_decl (integer_type_node, "prop_count");
  chainon (field_decl_chain, field_decl);

  /* struct _prop_t prop_list[]; */
  field_decl = create_field_decl (build_array_type
				  (list_type,
				   build_index_type
				   (build_int_cst (NULL_TREE, size - 1))),
				   "prop_list");
  chainon (field_decl_chain, field_decl);

  finish_struct (property_list_t_record, field_decl_chain, NULL_TREE);

  return property_list_t_record;
}

/* This routine encodes the attribute of the input PROPERTY according to following
   formula:

Property attributes are stored as a comma-delimited C string. The simple attributes
readonly and bycopy are encoded as single characters. The parametrized attributes,
getter=name, setter=name, and ivar=name, are encoded as single characters, followed
by an identifier. Property types are also encoded as a parametrized attribute. The
characters used to encode these attributes are defined by the following enumeration:

enum PropertyAttributes {
    kPropertyReadOnly = 'R',                    // property is read-only.
    kPropertyBycopy = 'C',                      // property is a copy of the value last assigned
    kPropertyByref = '&',                      // property is a reference to the value last assigned
    kPropertyDynamic = 'D',			// property is dynamic
    kPropertyGetter = 'G',                      // followed by getter selector name
    kPropertySetter = 'S',                      // followed by setter selector name
    kPropertyInstanceVariable = 'V'     	// followed by instance variable  name
    kPropertyType = 't'                         // followed by old-style type encoding.
    kPropertyWeak = 'W'				// 'weak' property
    kPropertyStrong = 'P'			// property GC'able
    kPropertyNonAtomic = 'N'			// property non-atomic
};  */

static tree
objc_v2_encode_prop_attr (tree property)
{
  const char *string;
  tree type = TREE_TYPE (property);
  obstack_1grow (&util_obstack, 'T');
  /* APPLE LOCAL radar 5002848 */
  generating_property_type_encoding = 1;
  encode_type (type, obstack_object_size (&util_obstack),
	       OBJC_ENCODE_INLINE_DEFS);
  /* APPLE LOCAL radar 5002848 */
  generating_property_type_encoding = 0;

  if (PROPERTY_READONLY (property) == boolean_true_node)
    obstack_grow (&util_obstack, ",R", 2);

  if (PROPERTY_COPY (property) == boolean_true_node)
    obstack_grow (&util_obstack, ",C", 2);

  if (PROPERTY_RETAIN (property) == boolean_true_node)
    obstack_grow (&util_obstack, ",&", 2);

  if (PROPERTY_DYNAMIC (property) == boolean_true_node)
    obstack_grow (&util_obstack, ",D", 2);

  /* APPLE LOCAL begin radar 5407792 */
  if (!IS_ATOMIC (property))
    obstack_grow (&util_obstack, ",N", 2);
  /* APPLE LOCAL end radar 5407792 */

  if (PROPERTY_GETTER_NAME (property))
    {
      obstack_grow (&util_obstack, ",G", 2);
      string = IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property));
      obstack_grow (&util_obstack, string, strlen (string));
    }
  if (PROPERTY_SETTER_NAME (property))
    {
      obstack_grow (&util_obstack, ",S", 2);
      string = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property));
      obstack_grow (&util_obstack, string, strlen (string));
    }
  if (PROPERTY_IVAR_NAME (property))
    {
      obstack_grow (&util_obstack, ",V", 2);
      if (PROPERTY_IVAR_NAME (property) != boolean_true_node)
	string = IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property));
      else
	string = objc_build_property_ivar_name (property);
      obstack_grow (&util_obstack, string, strlen (string));
    }
    if (flag_objc_gc)
      {
	int g = objc_is_gcable_type (type);
	if (g == -1)
	  obstack_grow (&util_obstack, ",W", 2);
	else if (g == 1)
	  obstack_grow (&util_obstack, ",P", 2);
      }

  obstack_1grow (&util_obstack, 0);    /* null terminate string */
  string = obstack_finish (&util_obstack);
  obstack_free (&util_obstack, util_firstobj);
  return get_identifier (string);
}

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

static tree
build_v2_property_table_initializer (tree type)
{
  tree x;
  tree initlist = NULL_TREE;
  generating_instance_variables = 1;
  for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
    {
      /* NOTE! sections where property name/attribute go MUST change later. */
      tree name_ident = PROPERTY_NAME (x);
      tree elemlist = tree_cons (NULL_TREE,
				 add_objc_string (name_ident, prop_names_attr),
				 NULL_TREE);
      tree attribute = objc_v2_encode_prop_attr (x);
      elemlist = tree_cons (NULL_TREE, add_objc_string (attribute, prop_names_attr),
			    elemlist);

      initlist = tree_cons (NULL_TREE,
			    objc_build_constructor (type, nreverse (elemlist)),
			    initlist);
    }
    generating_instance_variables = 0;
    return objc_build_constructor (build_array_type (type, 0),
				   nreverse (initlist));
}

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

static tree
generate_v2_property_list (tree type, const char *name, int size, tree list)
{
  tree decl, initlist;
  int init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_property_template));

  /* APPLE LOCAL begin radar 6064186 */
  const char * ref_name = synth_id_with_class_suffix (name, objc_implementation_context);
  decl = start_var_decl (type, ref_name);
  set_user_assembler_name (decl, ref_name);
  /* APPLE LOCAL end radar 6064186 */

  initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, init_val));
  initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
  initlist = tree_cons (NULL_TREE, list, initlist);

  finish_var_decl (decl,
		   objc_build_constructor (TREE_TYPE (decl),
					   nreverse (initlist)));
  return decl;
}

/* APPLE LOCAL begin radar 5082000 */
#define OUTPUT_LAYOUT_BYTE(BYTE)		  \
	do {					  \
	    obstack_1grow (&util_obstack, BYTE);  \
	    if (print_objc_ivar_layout)		  \
	      {					  \
		if (first_nibble)		  \
		  {		  		  \
		    first_nibble = false;	  \
		    printf ("\n%s for class \'%s\': ", \
			    strong_ivar_layout ?  \
			    "strong ivar layout" :\
			    "weak ivar layout",   \
			    IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));  \
		  }				  \
		if (!(BYTE & 0xf0))		  \
	          printf ("0x0%x%s", BYTE, BYTE != 0 ? ", " : ""); \
		else				  \
	          printf ("0x%x%s", BYTE, BYTE != 0 ? ", " : ""); \
		if (++num_nibbles > 20 		  \
		    || BYTE == 0)		  \
		  { printf("\n"); num_nibbles=1; }\
	      }					  \
	} while (0);				

#define GC_IVAR_BUFSIZE_INCR	256

struct GC_IVAR {
  unsigned int ivar_bytepos;
  unsigned int ivar_size;
};

static struct GC_IVAR *ivar;
static struct GC_IVAR *sk_ivar;
struct skip_scan
  {
    unsigned int skip;
    unsigned int scan;
  };
static struct skip_scan *skip_scan;
static int max_layout_buf_size = 0;

static void
/* Routine for dynamic allocation of various byffers used by GC layout mapper. */
adjust_max_layout_buf_size (int index)
{
  if (index < max_layout_buf_size-1)
    return;
  max_layout_buf_size += GC_IVAR_BUFSIZE_INCR;
  ivar = (struct GC_IVAR*)xrealloc (ivar, sizeof(struct GC_IVAR) * max_layout_buf_size); 
  sk_ivar = (struct GC_IVAR*)xrealloc  (sk_ivar, sizeof(struct GC_IVAR) * max_layout_buf_size); 
  skip_scan = (struct skip_scan*)xrealloc (skip_scan, sizeof(struct GC_IVAR) * max_layout_buf_size); 
  return;
}

static int
ivar_bytepos_cmp (const void *a, const void *b)
{
  HOST_WIDE_INT sa = ((struct GC_IVAR *)a)->ivar_bytepos;
  HOST_WIDE_INT sb = ((struct GC_IVAR *)b)->ivar_bytepos;

  if (sa < sb)
    return -1;
  if (sa > sb)
    return 1;
  return 0;
}

/* This routine returns total count of array elements. Returns 0 if
   there was an error. */
static HOST_WIDE_INT
total_type_elements (tree type)
{
  HOST_WIDE_INT el_count = 1;
  do {
    tree telts = array_type_nelts (type);
    if (telts && host_integerp (telts, 1))
      el_count *= (tree_low_cst (telts, 1) + 1);
    else
      {
        /* error case, reported elsewhere. */
        el_count = 0;
        break;
      }
    type = TREE_TYPE (type);
  } while (TREE_CODE (type) == ARRAY_TYPE);
  return el_count;
}
/* APPLE LOCAL end radar 5082000 */

/* APPLE LOCAL begin radar 6133042 */
/* This routine checks block pointers and either returns
   1 for GCable, or -1 if they are tagged as __weak. */
static int
block_pointer_strong_value (tree type)
{
  gcc_assert (type && TREE_CODE (type) == BLOCK_POINTER_TYPE);
  type = TREE_TYPE (TREE_TYPE (type));
  while (POINTER_TYPE_P (type))
     type = TREE_TYPE (type);
  return (objc_is_strong_p (type) >= 0 ? 1 : -1);
}
/* APPLE LOCAL end radar 6133042 */

static void
objc_build_aggregate_ivar_layout (tree aggr_type, tree field_decl,
				  unsigned int base_byte_pos,
				  bool strong_ivar_layout,
				  int *index,
				  int *sk_index,
				  bool *hasUnion)
{
  int iIndex = *index;
  int iSkIndex = *sk_index;
  unsigned int max_gc_union_ivar_size = 0;
  tree max_field_decl = NULL_TREE;
  unsigned int max_sk_union_ivar_size = 0;
  tree max_sk_field_decl = NULL_TREE;
  bool is_union = (aggr_type && TREE_CODE (aggr_type) == UNION_TYPE);
  unsigned int base = 0;
  /* APPLE LOCAL begin radar 5781140 */
  if (!field_decl)
    return;
  /* APPLE LOCAL end radar 5781140 */
  if (is_union)
    base = base_byte_pos + int_byte_position (field_decl);
 
  do {
    tree type;
    int strong;
    /* APPLE LOCAL objc gc 5547128 */

    /* Unnamed bitfields are ignored. */
    if (!DECL_NAME (field_decl) || DECL_BIT_FIELD_TYPE (field_decl))
      {
        /* APPLE LOCAL radar 5791701 */
        tree last_field_decl = field_decl;
	do
	  field_decl = TREE_CHAIN (field_decl);
	while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
        /* APPLE LOCAL begin radar 5791701 */
        if (field_decl)
          continue;
        /* last field was a bitfield. Must update the skip info. */
        field_decl = last_field_decl;
        /* APPLE LOCAL end radar 5791701 */
      }
#ifdef OBJCPLUS
    if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
      {
	/* C++ static members, and things that are not field at all, 
	   are not in the ivar map. */
	do
	  field_decl = TREE_CHAIN (field_decl);
	while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
	continue;
      }
#endif
    type = TREE_TYPE (field_decl); 
    if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE)
      {
	if (TREE_CODE (type) == UNION_TYPE)
	  *hasUnion = true;
	objc_build_aggregate_ivar_layout (type, TYPE_FIELDS (type), 
					  base_byte_pos + int_byte_position (field_decl),
					  strong_ivar_layout,
					  &iIndex, 
					  &iSkIndex, 
					  hasUnion);
	do
	  field_decl = TREE_CHAIN (field_decl);
	while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
	continue;
      }
    /* APPLE LOCAL begin radar 5082000 */
    else if (TREE_CODE (type) == ARRAY_TYPE)
      {
        tree inner = TREE_TYPE (type);
	while (TREE_CODE (inner) == ARRAY_TYPE)
	  inner = TREE_TYPE (inner);
        if (TREE_CODE (inner) == UNION_TYPE)
	  error ("Layout for array of unions not supported");
        else if (TREE_CODE (inner) == RECORD_TYPE)
	  {
	    HOST_WIDE_INT el_count = total_type_elements (type);
	    HOST_WIDE_INT el_ix;
	    int old_iIndex = iIndex, old_iSkIndex = iSkIndex;
	    int first_iIndex, first_iSkIndex;
	    objc_build_aggregate_ivar_layout (inner, TYPE_FIELDS (inner), 
					      base_byte_pos + int_byte_position (field_decl),
					      strong_ivar_layout,
					      &iIndex, 
					      &iSkIndex, 
					      hasUnion);
	    /* Replicate layout information for each array element. Note that
	       one element is already done. */
	    first_iIndex = iIndex;
	    first_iSkIndex = iSkIndex;
	    for (el_ix = 1; el_ix < el_count; el_ix++)
	      {
		int i;
		int size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (inner));
		for (i = old_iIndex+1; i <= first_iIndex; ++i)
		  {
		    adjust_max_layout_buf_size (iIndex);
		    ivar[++iIndex].ivar_bytepos = ivar[i].ivar_bytepos + size*el_ix;
		    ivar[iIndex].ivar_size = ivar[i].ivar_size;
		  }
		for (i = old_iSkIndex+1; i <= first_iSkIndex; ++i)
		  {
		    adjust_max_layout_buf_size (iSkIndex);
		    sk_ivar[++iSkIndex].ivar_bytepos = sk_ivar[i].ivar_bytepos + size*el_ix;
		    sk_ivar[iSkIndex].ivar_size = sk_ivar[i].ivar_size;
		  }
	      }
	    do
	      field_decl = TREE_CHAIN (field_decl);
	    while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
	    continue;
	  }	
      }
    /* APPLE LOCAL end radar 5082000 */

    strong = 0;
    do
      {
        strong = objc_is_strong_p (type);
        if (strong)
          break;

	/* APPLE LOCAL begin objc gc 5547128 */
        if (TREE_CODE (type) == FUNCTION_TYPE
	    || TREE_CODE (type) == METHOD_TYPE)
          break;
	/* APPLE LOCAL end objc gc 5547128 */

        if (objc_is_object_ptr (type))
	/* APPLE LOCAL begin objc gc 5547128 */
	  {
	    strong = ((objc_is_strong_p (TREE_TYPE (type)) >= 0) ? 1 : -1);
	    break;
	  }
	/* APPLE LOCAL end objc gc 5547128 */
	/* APPLE LOCAL begin radar 6133042 */
        if (TREE_CODE (type) == BLOCK_POINTER_TYPE)
          {
            strong = block_pointer_strong_value (type);
            break;
          }
	/* APPLE LOCAL end radar 6133042 */
        type = TREE_TYPE (type);
      }
    while (!strong && type);

    if ((strong_ivar_layout && strong == 1)
        || (!strong_ivar_layout && strong == -1))
      {
	if (is_union)
	  {
	    unsigned int u_ivar_size = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field_decl))
				       / GET_MODE_SIZE (Pmode);
	    if (u_ivar_size > max_gc_union_ivar_size)
	      {
	        max_gc_union_ivar_size = u_ivar_size;	    
	        max_field_decl = field_decl;
	      }
	  }
	else
	  {  
	    adjust_max_layout_buf_size (iIndex);
            ivar[++iIndex].ivar_bytepos = base_byte_pos + int_byte_position (field_decl);
            ivar[iIndex].ivar_size = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field_decl))
                                     / GET_MODE_SIZE (Pmode);
	  }
      }
    else if ((strong_ivar_layout && strong <= 0)
	     || (!strong_ivar_layout && strong != -1))
      {
	if (is_union)
	  {
	    unsigned int u_ivar_size = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field_decl));
	    if (u_ivar_size > max_sk_union_ivar_size)
	      {
	        max_sk_union_ivar_size = u_ivar_size;	    
	        max_sk_field_decl = field_decl;
	      }
	  }
	else
	  {  
	    adjust_max_layout_buf_size (iSkIndex);
            sk_ivar[++iSkIndex].ivar_bytepos = base_byte_pos + int_byte_position (field_decl);
            sk_ivar[iSkIndex].ivar_size = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field_decl));
	  }
      }

    do
      field_decl = TREE_CHAIN (field_decl);
    while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
  }
  while (field_decl);
  if (max_field_decl)
    {
      adjust_max_layout_buf_size (iIndex);
      ivar[++iIndex].ivar_bytepos = base_byte_pos + int_byte_position (max_field_decl);
      ivar[iIndex].ivar_size = max_gc_union_ivar_size;
    }
  if (max_sk_field_decl)
    {
      adjust_max_layout_buf_size (iSkIndex);
      sk_ivar[++iSkIndex].ivar_bytepos = base_byte_pos + int_byte_position (max_sk_field_decl);
      sk_ivar[iSkIndex].ivar_size = max_sk_union_ivar_size;
    }
  *index = iIndex;
  *sk_index = iSkIndex;
}


/* This routine builds the ivar_layout (when STRONG_IVAR_LAYOUT is true), or otherwise
   weak_ivar_layout and returns it in a c-string. The layout map displays which words
   in ivar list must be skipped and which must be scanned by GC (see below). 
   String is built of bytes. Each byte is divided up in two nibbles (4-bit each). Left
   nibble is count of words to skip and right nibble is count of words to scan. So, each
   nibble represents up to 15 workds to skip or scan. Skipping the rest is represented
   by a 0x00 byte which also ends the string.

   1. when STRONG_IVAR_LAYOUT is true, following ivars are scanned:
	- id, Class
	- object *
	- __strong anything

   2. When STRONG_IVAR_LAYOUT is false, following ivars are scanned:
	- __weak anything
*/

static tree 
objc_build_ivar_layout (bool strong_ivar_layout)
{
  tree field_decl;
  unsigned int words_to_skip, words_to_scan;
  int i;
  int iIndex = -1;
  int iSkIndex = -1;
  int iSkip_scan;
  unsigned char byte;
  const char *string;
  bool hasUnion, bytesSkipped;
  int num_nibbles = 0;
  bool first_nibble = true;
  /* APPLE LOCAL radar 6003871 */
  tree retval;

  if (!flag_objc_gc || !implementation_template)
    return NULL_TREE;

  field_decl = CLASS_IVARS (implementation_template);
  if (CLASS_SUPER_NAME (implementation_template))
    {
      /* Must build an ivar-list of all ivars in the inheritiance hierarchy. */
      tree interface = implementation_template;
      field_decl = copy_list (field_decl);
      while (CLASS_SUPER_NAME (interface))
	{
	  interface = lookup_interface (CLASS_SUPER_NAME (interface));
	  field_decl = chainon (copy_list (CLASS_IVARS (interface)),
				field_decl);
	}
    }
  if (!field_decl)
    return NULL_TREE;

  hasUnion = false;
  if (max_layout_buf_size == 0)
    {
      gcc_assert (ivar == NULL && sk_ivar == NULL && skip_scan == NULL);
      adjust_max_layout_buf_size (GC_IVAR_BUFSIZE_INCR);
    }
  objc_build_aggregate_ivar_layout (NULL_TREE, field_decl, 0, strong_ivar_layout, 
				    &iIndex, &iSkIndex, &hasUnion);

  if (iIndex == -1)
    {
      /* Skip everything */
      return NULL_TREE;
    }

  /* Must sort on byte position in case we encounterred a union nested in
     the ivar list. */
  if (hasUnion && iIndex > 0)
    qsort (ivar, iIndex+1, sizeof (struct GC_IVAR), ivar_bytepos_cmp);

  if (hasUnion && iSkIndex > 0)
    qsort (sk_ivar, iSkIndex+1, sizeof (struct GC_IVAR), ivar_bytepos_cmp);

  /* Now build the string of skip/scan nibbles */
  /* Initialization */
  iSkip_scan = -1;

  if (ivar[0].ivar_bytepos == 0)
    {
      words_to_skip = 0;
      words_to_scan = ivar[0].ivar_size;
    }
  else
    {
      words_to_skip = ivar[0].ivar_bytepos / GET_MODE_SIZE (Pmode);
      words_to_scan = ivar[0].ivar_size;
    }

  for (i=1; i <= iIndex; i++)
    {
      unsigned int tail_prev_gc_obj = ivar[i-1].ivar_bytepos + 
				      ivar[i-1].ivar_size * GET_MODE_SIZE (Pmode);
      if (ivar[i].ivar_bytepos == tail_prev_gc_obj)
	{
	  /* consecutive 'scanned' object pointers. */
	  words_to_scan += ivar[i].ivar_size;
	}
      else
	{
	  /* Skip over 'gc'able object pointer which lay over each other. */
	  if (tail_prev_gc_obj > ivar[i].ivar_bytepos)
	    continue;
	  /* Must skip over 1 or more words. We save current skip/scan values
	     and start a new pair. */
	  adjust_max_layout_buf_size (iSkip_scan);
	  skip_scan[++iSkip_scan].skip = words_to_skip;
	  skip_scan[iSkip_scan].scan = words_to_scan;
	  /* APPLE LOCAL begin radar 5109807 */
	  /* Skip the hole */
	  skip_scan[++iSkip_scan].skip = (ivar[i].ivar_bytepos - tail_prev_gc_obj)
			  		 / GET_MODE_SIZE (Pmode);
	  skip_scan[iSkip_scan].scan = 0;
	  words_to_skip = 0;
	  /* APPLE LOCAL end radar 5109807 */
	  words_to_scan = ivar[i].ivar_size;
	}
    }
  if (words_to_scan > 0)
    {
      adjust_max_layout_buf_size (iSkip_scan);
      skip_scan[++iSkip_scan].skip = words_to_skip;
      skip_scan[iSkip_scan].scan = words_to_scan;
    }
  /* APPLE LOCAL begin radar 5251019 */
  bytesSkipped = false;
  if (iSkIndex >= 0)
    {
      int lastByteSkipped = sk_ivar[iSkIndex].ivar_bytepos + sk_ivar[iSkIndex].ivar_size;
      int lastByteScanned = ivar[iIndex].ivar_bytepos + ivar[iIndex].ivar_size * GET_MODE_SIZE (Pmode);
      bytesSkipped = (lastByteSkipped > lastByteScanned);
      /* Compute number of bytes to skip at the tail end of the last ivar scanned. */
      if (bytesSkipped)
        {
          unsigned int totalWord = (lastByteSkipped + (GET_MODE_SIZE (Pmode) -1))
                                   / GET_MODE_SIZE (Pmode);
          adjust_max_layout_buf_size (iSkip_scan);
          skip_scan[++iSkip_scan].skip = totalWord - (lastByteScanned / GET_MODE_SIZE (Pmode));
          skip_scan[iSkip_scan].scan = 0;
        }
    }
  /* APPLE LOCAL end radar 5251019 */
 
  /* APPLE LOCAL begin radar 5259868 */
  /* Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
     as 0xMN. */
  for (i = 0; i <= iSkip_scan; i++)
    {
      if (i < iSkip_scan)
	{
	  if (skip_scan[i].skip && skip_scan[i].scan == 0
	      && skip_scan[i+1].skip == 0 && skip_scan[i+1].scan)
	    {
	      /* 0xM0 followed by 0x0N detected. */
	      int j;
	      skip_scan[i].scan = skip_scan[i+1].scan;
	      for (j = i+1; j < iSkip_scan; j++)
		skip_scan[j] = skip_scan[j+1];
	      --iSkip_scan;
	    }
	} 
    }
  /* APPLE LOCAL end radar 5259868 */
  /* Now generate the string */
  for (i = 0; i <= iSkip_scan; i++)
    {
      unsigned int skip_small = skip_scan[i].skip % 0xf;
      unsigned int scan_small = skip_scan[i].scan % 0xf;
      unsigned int skip_big  = skip_scan[i].skip / 0xf;
      unsigned int scan_big  = skip_scan[i].scan / 0xf;
      unsigned int ix;
      if (skip_small > 0 || skip_big > 0)
	bytesSkipped = true;
      /* APPLE LOCAL begin radar 5217964 */
      /* first skip big. */
      for (ix = 0; ix < skip_big; ix++)
        OUTPUT_LAYOUT_BYTE (0xf0);

      /* next (skip small, scan) */
      if (skip_small)
	{
	  byte = skip_small << 4;
	  if (scan_big > 0)
	    {
	      byte |= 0xf;
	      --scan_big;
	    }
	  else if (scan_small)
	    {
	      byte |= scan_small;
	      scan_small = 0;
	    }
	  OUTPUT_LAYOUT_BYTE (byte);
	}
      /* next scan big */
      for (ix = 0; ix < scan_big; ix++)
	OUTPUT_LAYOUT_BYTE (0x0f);
      /* last scan small */
      if (scan_small)
	{
	  byte = scan_small; 
	  OUTPUT_LAYOUT_BYTE (byte);
	}
       /* APPLE LOCAL end radar 5217964 */
    }
  OUTPUT_LAYOUT_BYTE (0);  /* null terminate string */
  string = obstack_finish (&util_obstack);
  /* APPLE LOCAL begin radar 6003871 */
  /* if ivar_layout bitmap is all 1 bits (nothing skipped) then use NULL as
     final layout. */
  retval =  (strong_ivar_layout && !bytesSkipped) 
	     ? NULL_TREE 
	     : add_objc_string (get_identifier (string), class_names);
  obstack_free (&util_obstack, util_firstobj);
  return retval;
  /* APPLE LOCAL end radar 6003871 */
}

/**
  This routine build following type:

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

static void build_objc_protocol_extension_template (void)
{
  tree field_decl, field_decl_chain;
  
  objc_protocol_extension_template = start_struct (RECORD_TYPE,
						   get_identifier (UTAG_PROTOCOL_EXT));
  /*  uint32_t size; */
  field_decl = create_field_decl (integer_type_node, "size");
  field_decl_chain = field_decl;

  /* struct objc_method_list   *optional_instance_methods; */
  field_decl = create_field_decl (objc_method_list_ptr, "optional_instance_methods");
  chainon (field_decl_chain, field_decl);

  /* struct objc_method_list   *optional_class_methods; */
  field_decl = create_field_decl (objc_method_list_ptr, "optional_class_methods");
  chainon (field_decl_chain, field_decl);

  /* struct objc_prop_list     *instance_properties; */
  field_decl = create_field_decl (objc_prop_list_ptr, "instance_properties");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_protocol_extension_template, field_decl_chain, NULL_TREE);
}

static tree
generate_objc_protocol_extension (tree proto_interface, tree optional_instance_meth, 
				  tree optional_class_meth, tree instance_prop)
{
  int size;
  tree decl, initlist, expr;

  if (!optional_instance_meth && !optional_class_meth && !instance_prop)
    return NULL_TREE;

  if (!objc_protocol_extension_template)
    build_objc_protocol_extension_template ();    

  /* uint32_t size */
  size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_protocol_extension_template));
  initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));

  /* struct objc_method_list   *optional_instance_methods; */
  if (!optional_instance_meth)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (objc_method_list_ptr, integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_method_list_ptr, build_unary_op (ADDR_EXPR, 
					      optional_instance_meth, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }

  /* struct objc_method_list   *optional_class_methods; */
  if (!optional_class_meth)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (objc_method_list_ptr, integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_method_list_ptr, build_unary_op (ADDR_EXPR, 
					      optional_class_meth, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }

  /* struct objc_prop_list     *instance_properties; */
  if (!instance_prop)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (objc_prop_list_ptr, integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_prop_list_ptr, build_unary_op (ADDR_EXPR, 
							  instance_prop, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }

  decl = start_var_decl (objc_protocol_extension_template, 
                         synth_id_with_class_suffix 
                           ("_OBJC_PROTOCOLEXT", proto_interface));
  expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
  finish_var_decl (decl, expr);
  return decl;
}

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

static void
build_objc_class_ext_template (void)
{
  tree field_decl, field_decl_chain;

  objc_class_ext_template = start_struct (RECORD_TYPE,
					  get_identifier (UTAG_CLASS_EXT));

  /* uint32_t size; */
  field_decl = create_field_decl (integer_type_node, "size");
  field_decl_chain = field_decl;

  /* const char *weak_ivar_layout; */
  field_decl = create_field_decl (string_type_node, "weak_ivar_layout");
  chainon (field_decl_chain, field_decl);

  /* struct _prop_list_t *properties; */
  field_decl 
   = create_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
                                            get_identifier(UTAG_PROPERTY_LIST))),
                                  	    "properties");
  chainon (field_decl_chain, field_decl);
  finish_struct (objc_class_ext_template, field_decl_chain, NULL_TREE);
}

/* This routine declares UOBJC_CLASS_EXT_decl and initializes its 'size',
   'weak_ivar_layout' (with WEAK_IVAR_LAYOUT) and 'properties' (with
   PROPERTY_LIST).
*/

static tree
generate_objc_class_ext (tree property_list)
{
  tree decl, initlist, expr;
  int size;
  tree weak_ivar_layout_tree;

  /* const char *weak_ivar_layout */
  weak_ivar_layout_tree = objc_build_ivar_layout (false);
  if (!property_list && !weak_ivar_layout_tree)
    return NULL_TREE;

  if (!objc_class_ext_template)
    build_objc_class_ext_template ();

  /* uint32_t size */
  size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_class_ext_template));
  initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));

  initlist = tree_cons (NULL_TREE,
			(!weak_ivar_layout_tree ? integer_zero_node
					        : weak_ivar_layout_tree),
			initlist);

  /* struct _prop_list_t *properties; */
  if (!property_list)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (objc_prop_list_ptr, integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_prop_list_ptr,
                      build_unary_op (ADDR_EXPR, property_list, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }

  decl = start_var_decl (objc_class_ext_template,
		         synth_id_with_class_suffix
			   ("_OBJC_CLASSEXT", objc_implementation_context));
  expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
  finish_var_decl (decl, expr);
  return decl;
}

/* Top-level routine to generate property tables for each implementation.
   PROTOCOL, if not NULL, is the PROTOCOL_INTERFACE_TYPE of the protocol
   whose property meta-data must be generated, via @implementation <protoname>
   syntax.  */

static void
generate_v2_property_tables (tree protocol)
{
  tree x, initlist, property_list_template;
  int size = 0;
  x = protocol ? CLASS_PROPERTY_DECL (protocol)
	       : IMPL_PROPERTY_DECL (objc_implementation_context);
  for (; x; x = TREE_CHAIN (x))
    size++;

  if (size == 0)
    {
      UOBJC_V2_PROPERTY_decl = NULL_TREE;
      return;
    }

  if (!objc_v2_property_template)
    objc_v2_property_template = build_v2_property_template ();
  property_list_template = build_v2_property_list_template (objc_v2_property_template,
							    size);
  initlist
    = build_v2_property_table_initializer (objc_v2_property_template);
  /* A property meta-data can be generated via @implementation <protoname> or
     via implementation of an interface where properties are declaraed. Make sure
     name of property meta-data is unique for each case. */
  UOBJC_V2_PROPERTY_decl = generate_v2_property_list (
			     property_list_template,
			     /* APPLE LOCAL begin radar 6064186 */
			     protocol ? "l_OBJC_$_PROP_PROTO_LIST"
				      : "l_OBJC_$_PROP_LIST",
			     /* APPLE LOCAL end radar 6064186 */
			     size, initlist);
}

/* This routine merges properties undeclared in implementation from its interface 
   declaration.  */

static void
objc_v2_merge_property (void)
{
  tree property_decl;
  tree interface = NULL_TREE;
  tree x, y;

  gcc_assert (objc_implementation_context);
  interface = lookup_interface (CLASS_NAME (objc_implementation_context));
  /* May be null due to some previously declared diagnostic. */
  if (!interface)
    return;

  if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
    {
      interface = lookup_category (interface,
				   CLASS_SUPER_NAME (objc_implementation_context));
      if (!interface)
        return;
    }

  /* Check for properties declared in interface but not in implementations.
     These are 'dynamic' properties. */
  for (x = CLASS_PROPERTY_DECL (interface); x; x = TREE_CHAIN (x))
    {
      for (y = IMPL_PROPERTY_DECL (objc_implementation_context); y; y = TREE_CHAIN (y))
	 if (PROPERTY_NAME (x) == PROPERTY_NAME (y))
	   break;
      if (y)
	continue;
      else 
	{
	  property_decl = copy_node (x);
	  /* Add the property to the list of properties for current implementation. */
	  TREE_CHAIN (property_decl) = IMPL_PROPERTY_DECL (objc_implementation_context);
	  IMPL_PROPERTY_DECL (objc_implementation_context) = property_decl;
	  continue;
	}
      /* 'x' is dynamic propeperty. Add it to the list of properties for this
	  implementation. */	
      property_decl = make_node (PROPERTY_DECL);
      TREE_TYPE (property_decl) = TREE_TYPE (x);
      PROPERTY_NAME (property_decl) = PROPERTY_NAME (x);
      PROPERTY_READONLY (property_decl) = PROPERTY_READONLY (x);
      PROPERTY_DYNAMIC (property_decl) = PROPERTY_DYNAMIC (x);
      PROPERTY_GETTER_NAME (property_decl) = NULL_TREE;
      PROPERTY_SETTER_NAME (property_decl) = NULL_TREE;
      PROPERTY_IVAR_NAME (property_decl) = PROPERTY_IVAR_NAME (x);
      /* Add the property to the list of properties for current implementation. */
      TREE_CHAIN (property_decl) = IMPL_PROPERTY_DECL (objc_implementation_context);
      IMPL_PROPERTY_DECL (objc_implementation_context) = property_decl;
    }
  return;
}
/* APPLE LOCAL end C* language */

void
objc_set_method_type (enum tree_code type)
{
  objc_inherit_code = (type == PLUS_EXPR
		       ? CLASS_METHOD_DECL
		       : INSTANCE_METHOD_DECL);
}


/* APPLE LOCAL begin radar 6307941 */
/* Non-legacy dispatch is a performance optimization only. 
   Using the "wrong" dispatch is not a correctness problem, 
   assuming non-legacy dispatch is supported at all. 

   SnowLeopard: only the selectors below are optimized by the runtime. 
     Other selectors should use legacy dispatch to save memory.
*/
static const char * const nonlegacy_dispatched_selectors[] = {
  "allocWithZone:",
  "alloc",
  "class",
  "self",
  "isKindOfClass:",
  "respondsToSelector:",
  "isFlipped",
  "length",
  "objectForKey:",
  "count",
  "objectAtIndex:",
  "isEqualToString:",
  "isEqual:",
  "retain",
  "release",
  "autorelease",
  "hash",
  "addObject:",
  "countByEnumeratingWithState:objects:count:",
};

static int
objc_legacy_dispatched_selector_p (tree sel_name)
{
  gcc_assert (flag_objc_abi == 2);
  gcc_assert (sel_name);
  if (flag_objc_legacy_dispatch) 
    return true;
  if (OBJC2_ABI_DISPATCH)
    /* Do this for Snow Leopard ot later only. */
    return false;
  else {
    size_t i, count;
    const char *sel_cname = IDENTIFIER_POINTER (sel_name);
    count = sizeof(nonlegacy_dispatched_selectors) / sizeof(nonlegacy_dispatched_selectors[0]);
    for (i = 0; i < count; i++) 
    {
      if (!strcmp (sel_cname, nonlegacy_dispatched_selectors[i]))
        return false;
    }
  } 
  return true;
}
/* APPLE LOCAL end radar 6307941 */

tree
objc_build_method_signature (tree rettype, tree selector,
			     tree optparms, bool ellipsis)
{
  return build_method_decl (objc_inherit_code, rettype, selector,
			    optparms, ellipsis);
}

/* APPLE LOCAL begin radar 4869979 */
/* Return 'true' if chain of attributes includes 'bycopy' */
static bool
objc_type_has_bycopy_attr (tree list)
{
  tree p;
  for (p = list; p; p = TREE_CHAIN (p))
    {
      tree v = TREE_VALUE (p);
      if (v && TREE_CODE (v) == IDENTIFIER_NODE
	  && !strcmp (IDENTIFIER_POINTER (v), "bycopy"))
        return true;
    }
  return false;
}

/* This routine issues a warning if instance method declaration has a 'bycopy' 
   attribute of an object which does not include 'NSCoding' protocol. */
static void
objc_diagnose_bycopy_type (tree decl)
{
  tree type = TREE_TYPE (decl);
  if (type && TREE_CODE (type) == TREE_LIST)
    {
      tree p = TREE_PURPOSE (type);
      if (p && TREE_CODE (p) == TREE_LIST)
	{
	  if (objc_type_has_bycopy_attr (p))
	    {
	      tree intf;
	      tree objc_class = objc_is_object_ptr (TREE_VALUE (type));
	      if (objc_class && objc_is_class_name (objc_class)
		  && (intf = lookup_interface (objc_class)))
		{
		  tree proto = lookup_protocol (get_identifier ("NSCoding"));
		  if (proto && !conforms_to_protocol (intf, proto))
		    warning (0, "\"bycopy\" specified on instance method type of '%T' that does not conform to \"NSCoding\" protocol",
			     TREE_VALUE (type));
		}
	    } 
	}
    }
}
/* APPLE LOCAL end radar 4869979 */

void
/* APPLE LOCAL radar 3803157 - objc attribute */
objc_add_method_declaration (tree decl, tree attributes)
{
  /* APPLE LOCAL begin radar 4157812 */
  if (decl == error_mark_node)
    return;
  /* APPLE LOCAL end radar 4157812 */

  if (!objc_interface_context)
    fatal_error ("method declaration not in @interface context");

  /* APPLE LOCAL radar 3803157 - objc attribute */
  objc_decl_method_attributes (&decl, attributes, 0);
  /* APPLE LOCAL begin C* language */
  objc_add_method (objc_interface_context,
		   decl,
		   objc_inherit_code == CLASS_METHOD_DECL,
		   objc_method_optional_flag);
  /* APPLE LOCAL end C* language */
  /* APPLE LOCAL begin radar 4869979 */
  if (objc_interface_context &&
      TREE_CODE (objc_interface_context) == CLASS_INTERFACE_TYPE
      && objc_inherit_code == INSTANCE_METHOD_DECL)
    objc_diagnose_bycopy_type (decl);
  /* APPLE LOCAL end radar 4869979 */
}

/* APPLE LOCAL begin deprecated use in deprecated 6425499 */
static tree fast_lookup_method (int is_class, tree class, tree method_ident);
/* APPLE LOCAL end deprecated use in deprecated 6425499 */

void
/* APPLE LOCAL radar 3803157 - objc attribute */
objc_start_method_definition (tree decl, tree attributes)
{
  /* APPLE LOCAL begin deprecated use in deprecated 6425499 */
  tree class;
  /* APPLE LOCAL end deprecated use in deprecated 6425499 */

  if (!objc_implementation_context)
    fatal_error ("method definition not in @implementation context");

  /* APPLE LOCAL begin radar 4290840 */
  if (decl != NULL_TREE  && METHOD_SEL_NAME (decl) == error_mark_node)
    return;
  /* APPLE LOCAL end radar 4290840 */

  /* APPLE LOCAL begin radar 4219590 */
#ifndef OBJCPLUS
  /* Indicate no valid break/continue context by setting these variables
     to some non-null, non-label value.  We'll notice and emit the proper
     error message in c_finish_bc_stmt.  */
  c_break_label = c_cont_label = size_zero_node;
#endif
  /* APPLE LOCAL end radar 4219590 */

  /* APPLE LOCAL begin radar 4529765 */
  if (attributes)
    warning (0, "method attribute may be specified on method declarations only");
  /* APPLE LOCAL end radar 4529765 */
  /* APPLE LOCAL begin radar 5424416 */
  if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
  {
    tree type = TREE_VALUE (TREE_TYPE (decl));
    if (type)
    {
      if (TREE_CODE (type) == FUNCTION_TYPE)
        {
          error ("%qs declared as method returning a function", 
                 IDENTIFIER_POINTER (DECL_NAME (decl)));
	}
      else if (TREE_CODE (type) == ARRAY_TYPE)
	{
          error ("%qs declared as method returning an array", 
                 IDENTIFIER_POINTER (DECL_NAME (decl)));
	}
    }
  }
  /* APPLE LOCAL end radar 5424416 */
  /* APPLE LOCAL radar 3803157 - objc attribute */
  objc_decl_method_attributes (&decl, attributes, 0);
  objc_add_method (objc_implementation_context,
		   decl,
		   /* APPLE LOCAL C* language */
		   objc_inherit_code == CLASS_METHOD_DECL, 0);
  /* APPLE LOCAL begin deprecated use in deprecated 6425499 */
  /* We have to copy the TREE_DEPRECATED bit from the interface.  */
  class = lookup_interface (CLASS_NAME (objc_implementation_context));
  if (class)
    {
      tree decl2 = fast_lookup_method (objc_inherit_code == CLASS_METHOD_DECL,
				       class,
				       METHOD_SEL_NAME (decl));
      if (decl2)
	TREE_DEPRECATED (decl) = TREE_DEPRECATED (decl2);
  }
  /* APPLE LOCAL end deprecated use in deprecated 6425499 */
  start_method_def (decl);

  /* APPLE LOCAL begin ObjC abi v2 */
  /* APPLE LOCAL radar 4581680 */
  if (flag_objc_abi == 2 && objc_inherit_code == CLASS_METHOD_DECL)
    {
      /* Insert declaration of class method "load" in one of the __nonlazy_class
         or __nonlazy_category lists. */
      tree id = DECL_NAME (decl);
      if (id && TREE_CODE (id) == IDENTIFIER_NODE)
        {
          const char *name = IDENTIFIER_POINTER (id);
	  if (!strcmp (name, "load"))
	    CLASS_OR_CATEGORY_HAS_LOAD_IMPL (objc_implementation_context) = decl;
	}
    }
  /* APPLE LOCAL end ObjC abi v2 */
}

void
objc_add_instance_variable (tree decl)
{
  (void) add_instance_variable (objc_ivar_context,
				objc_public_flag,
				decl);
}

/* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
   an '@'.  */

int
objc_is_reserved_word (tree ident)
{
  unsigned char code = C_RID_CODE (ident);

  return (OBJC_IS_AT_KEYWORD (code)
#ifdef OBJCPLUS
          /* APPLE LOCAL radar 4564694 */
          || code == RID_AT_PACKAGE
	  || code == RID_CLASS || code == RID_PUBLIC
	  || code == RID_PROTECTED || code == RID_PRIVATE
	  || code == RID_TRY || code == RID_THROW || code == RID_CATCH
#endif
	    );
}

/* Return true if TYPE is 'id'.  */

static bool
objc_is_object_id (tree type)
{
  return OBJC_TYPE_NAME (type) == objc_object_id;
}

static bool
objc_is_class_id (tree type)
{
  return OBJC_TYPE_NAME (type) == objc_class_id;
}

/* Construct a C struct with same name as CLASS, a base struct with tag
   SUPER_NAME (if any), and FIELDS indicated.  */

static tree
objc_build_struct (tree class, tree fields, tree super_name)
{
  tree name = CLASS_NAME (class);
  tree s = start_struct (RECORD_TYPE, name);
  tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
  /* APPLE LOCAL begin radar 5676962 */
  tree t;
  int cv = 0;
  /* APPLE LOCAL radar 6285794 */
  struct lang_type ** pTypeLang = 0;
  /* APPLE LOCAL end radar 5676962 */

  /* APPLE LOCAL begin radar 5025001 */
  if (flag_objc_abi == 2 && TREE_CODE (class) == CLASS_INTERFACE_TYPE
      && fields != NULL_TREE)
    {
      /* append char :0; field if last field is a bit field. */
      tree last = fields;
      while (TREE_CHAIN (last))
        last = TREE_CHAIN (last);
      gcc_assert (TREE_CODE (last) == FIELD_DECL);
      if (DECL_INITIAL (last) && DECL_INITIAL (last) != error_mark_node)
        {
          tree bf_zero = build_decl (FIELD_DECL, NULL_TREE, char_type_node);
          DECL_INITIAL (bf_zero) = size_zero_node;
          SET_DECL_C_BIT_FIELD (bf_zero);
          DECL_NONADDRESSABLE_P (bf_zero) = 1;
          TREE_CHAIN (last) = bf_zero;
        }
    }
  /* APPLE LOCAL end radar 5025001 */

  if (super)
    {
      /* Prepend a packed variant of the base class into the layout.  This
	 is necessary to preserve ObjC ABI compatibility.  */
      tree base = build_decl (FIELD_DECL, NULL_TREE, super);
      tree field = TYPE_FIELDS (super);

      while (field && TREE_CHAIN (field)
	     && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
	field = TREE_CHAIN (field);

      /* For ObjC ABI purposes, the "packed" size of a base class is the
	 the sum of the offset and the size (in bits) of the last field
	 in the class.  */
      DECL_SIZE (base)
	= (field && TREE_CODE (field) == FIELD_DECL
	   ? size_binop (PLUS_EXPR,
			 size_binop (PLUS_EXPR,
				     size_binop
				     (MULT_EXPR,
				      convert (bitsizetype,
					       DECL_FIELD_OFFSET (field)),
				      bitsize_int (BITS_PER_UNIT)),
				     DECL_FIELD_BIT_OFFSET (field)),
			 DECL_SIZE (field))
	   : bitsize_zero_node);
      DECL_SIZE_UNIT (base)
	= size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
		      size_int (BITS_PER_UNIT));
      DECL_ARTIFICIAL (base) = 1;
      DECL_ALIGN (base) = 1;
      DECL_FIELD_CONTEXT (base) = s;
      /* APPLE LOCAL begin radar 4477797 */
      if (write_symbols == DWARF2_DEBUG)
	DECL_IGNORED_P (base) = 1;
      /* APPLE LOCAL end radar 4477797 */
#ifdef OBJCPLUS
      DECL_FIELD_IS_BASE (base) = 1;

      if (fields)
	TREE_NO_WARNING (fields) = 1;	/* Suppress C++ ABI warnings -- we   */
#endif					/* are following the ObjC ABI here.  */
      TREE_CHAIN (base) = fields;
      fields = base;
    }

  /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
     in all variants of this RECORD_TYPE to be clobbered, but it is therein
     that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
     Hence, we must squirrel away the ObjC-specific information before calling
     finish_struct(), and then reinstate it afterwards.  */

  /* APPLE LOCAL begin radar 5676962 */
#if 0
     removed:
  for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
    objc_info
      = chainon (objc_info,
		 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
#endif
  /* APPLE LOCAL end radar 5676962 */

  /* Point the struct at its related Objective-C class.  */
  INIT_TYPE_OBJC_INFO (s);
  TYPE_OBJC_INTERFACE (s) = class;

  /* APPLE LOCAL begin radar 5676962, 4310884, 4945770 */
  /* Call to finish_struct has the side-effect of unifying TYPE_LANG_SPECIFIC
     of all variants to be same as the main variant's. We must preseve objc-c's
     TYPE_LANG_SPECIFIC objects as they have unique information in them; such as
     TYPE_OBJC_INFO. So, we save and restore TYPE_LANG_SPECIFIC objects. */
  for (t = TYPE_MAIN_VARIANT (s); t && TYPE_LANG_SPECIFIC (t) && TYPE_OBJC_INFO (t); 
       t = TYPE_NEXT_VARIANT (t))
    ++cv;
  if (cv > 1) {
    int i=0;
    pTypeLang = (struct lang_type **) xmalloc (sizeof (struct lang_type *) * cv);
    for (t = TYPE_MAIN_VARIANT (s); t && TYPE_LANG_SPECIFIC (t) && TYPE_OBJC_INFO (t);
	 t = TYPE_NEXT_VARIANT (t))
      pTypeLang[i++] = TYPE_LANG_SPECIFIC(t);

  }
  /* APPLE LOCAL end radar 5676962, 4310884, 4945770 */

  s = finish_struct (s, fields, NULL_TREE);

  /* APPLE LOCAL begin radar 5676962, 4310884, 4945770 */
  if (cv > 1) {
    int i=0;
    for (t = TYPE_MAIN_VARIANT (s); t && TYPE_LANG_SPECIFIC (t) && TYPE_OBJC_INFO (t);
         t = TYPE_NEXT_VARIANT (t))
      TYPE_LANG_SPECIFIC(t) = pTypeLang[i++];
    free (pTypeLang);
  }
  /* APPLE LOCAL end radar 5676962, 4310884, 4945770 */

  /* Use TYPE_BINFO structures to point at the super class, if any.  */
  objc_xref_basetypes (s, super);

  /* Mark this struct as a class template.  */
  CLASS_STATIC_TEMPLATE (class) = s;

  return s;
}

/* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
   Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
   process.  */
static tree
objc_build_volatilized_type (tree type)
{
  tree t;

  /* Check if we have not constructed the desired variant already.  */
  for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
    {
      /* The type qualifiers must (obviously) match up.  */
      if (!TYPE_VOLATILE (t)
	  || (TYPE_READONLY (t) != TYPE_READONLY (type))
	  || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
	continue;

      /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
	 info, if any) must match up.  */
      if (POINTER_TYPE_P (t)
	  && (TREE_TYPE (t) != TREE_TYPE (type)))
	continue;

      /* APPLE LOCAL begin radar 4204796 */
      /* Only match up the types which were previously volatilized in similar fashion and not
	 because they were declared as such. */
      if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t)))
	continue;
      /* APPLE LOCAL end radar 4204796 */
      
      /* Everything matches up!  */
      return t;
    }

  /* Ok, we could not re-use any of the pre-existing variants.  Create
     a new one.  */
  t = build_variant_type_copy (type);
  TYPE_VOLATILE (t) = 1;
  /* APPLE LOCAL begin radar 4204796 */
  TYPE_ATTRIBUTES (t) = merge_attributes (TYPE_ATTRIBUTES (type),
                      			  tree_cons (get_identifier ("objc_volatilized"),
                                 	  NULL_TREE,
                                 	  NULL_TREE));
  if (TREE_CODE (t) == ARRAY_TYPE)
    TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (t));
  /* APPLE LOCAL end radar 4204796 */

  return t;
}

/* Mark DECL as being 'volatile' for purposes of Darwin
   _setjmp()/_longjmp() exception handling.  Called from
   objc_mark_locals_volatile().  */
void
objc_volatilize_decl (tree decl)
{
  /* Do not mess with variables that are 'static' or (already)
     'volatile'.  */
  if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
      && (TREE_CODE (decl) == VAR_DECL
	  || TREE_CODE (decl) == PARM_DECL))
    {
      tree t = TREE_TYPE (decl);
      /* APPLE LOCAL begin radar 4204796 */
      /* code removed */
      /* APPLE LOCAL end radar 4204796 */

      t = objc_build_volatilized_type (t);
      /* APPLE LOCAL begin radar 4204796 */
      /* code removed */
      /* APPLE LOCAL end radar 4204796 */

      TREE_TYPE (decl) = t;
      TREE_THIS_VOLATILE (decl) = 1;
      TREE_SIDE_EFFECTS (decl) = 1;
      DECL_REGISTER (decl) = 0;
#ifndef OBJCPLUS
      C_DECL_REGISTER (decl) = 0;
#endif
    }
}

/* APPLE LOCAL begin radar 4697411 */
/* This routine sets the "objc_volatilized" attribute on COMPONENT_REF
   node if 1) it is not already 'volatile' and 2) datum node
   has its "objc_volatilized" attribute set.
*/
void
objc_volatilize_component_ref (tree cref, tree member_type)
{
  tree object, type;

  if (TYPE_VOLATILE (member_type))
    return;
  object = TREE_OPERAND (cref, 0);
  if (TREE_THIS_VOLATILE (object))
    {
      type = TREE_TYPE (object);
      if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type)))
	{
	  member_type = objc_build_volatilized_type (member_type);
	  TREE_TYPE (cref) = member_type;
	  TREE_THIS_VOLATILE (cref) = 1;
	  TREE_SIDE_EFFECTS (cref) = 1;
	}
    }
  return;
}
/* APPLE LOCAL end radar 4697411 */

/* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
   (including its categoreis and superclasses) or by object type TYP.
   Issue a warning if PROTO is not adopted anywhere and WARN is set.  */

static bool
objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
{
  bool class_type = (cls != NULL_TREE);

  while (cls)
    {
      tree c;

      /* Check protocols adopted by the class and its categories.  */
      for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
	{
	  if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
	    return true;
	}

      /* Repeat for superclasses.  */
      cls = lookup_interface (CLASS_SUPER_NAME (cls));
    }

  /* Check for any protocols attached directly to the object type.  */
  if (TYPE_HAS_OBJC_INFO (typ))
    {
      if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
	return true;
    }

  if (warn)
    {
      strcpy (errbuf, class_type ? "class \'" : "type \'");
      gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
      strcat (errbuf, "\' does not ");
      /* NB: Types 'id' and 'Class' cannot reasonably be described as
	 "implementing" a given protocol, since they do not have an
	 implementation.  */
      strcat (errbuf, class_type ? "implement" : "conform to");
      strcat (errbuf, " the \'");
      strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
      strcat (errbuf, "\' protocol");
      /* APPLE LOCAL default to Wformat-security 5764921 */
      warning (0, "%s", errbuf);
    }

  return false;
}

/* Check if class RCLS and instance struct type RTYP conform to at least the
   same protocols that LCLS and LTYP conform to.  */

static bool
objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
{
  tree p;
  bool have_lproto = false;

  while (lcls)
    {
      /* NB: We do _not_ look at categories defined for LCLS; these may or
	 may not get loaded in, and therefore it is unreasonable to require
	 that RCLS/RTYP must implement any of their protocols.  */
      for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
	{
	  have_lproto = true;

	  if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
	    return warn;
	}

      /* Repeat for superclasses.  */
      lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
    }

  /* Check for any protocols attached directly to the object type.  */
  if (TYPE_HAS_OBJC_INFO (ltyp))
    {
      for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
	{
	  have_lproto = true;

	  if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
	    return warn;
	}
    }

  /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
     vacuously, _unless_ RTYP is a protocol-qualified 'id'.  We can get
     away with simply checking for 'id' or 'Class' (!RCLS), since this
     routine will not get called in other cases.  */
  return have_lproto || (rcls != NULL_TREE);
}

/* APPLE LOCAL begin 4154928 */
/* Given two types TYPE1 and TYPE2, return their least common ancestor.
   Both TYPE1 and TYPE2 must be pointers, and already determined to be
   compatible by objc_compare_types() below.  */

tree
objc_common_type (tree type1, tree type2)
{
  tree inner1 = TREE_TYPE (type1), inner2 = TREE_TYPE (type2);

  while (POINTER_TYPE_P (inner1))
    {
      inner1 = TREE_TYPE (inner1);
      inner2 = TREE_TYPE (inner2);
    }

  /* If one type is derived from another, return the base type.  */
  if (DERIVED_FROM_P (inner1, inner2))
    return type1;
  else if (DERIVED_FROM_P (inner2, inner1))
    return type2;

  /* If both types are 'Class', return 'Class'.  */
  if (objc_is_class_id (inner1) && objc_is_class_id (inner2))
    return objc_class_type;

  /* Otherwise, return 'id'.  */
  return objc_object_type;
}
/* APPLE LOCAL end 4154928 */

/* APPLE LOCAL begin radar 5595325 */
/* This routine checks that TYPE has __attribute__((NSObject)) */
static bool
objc_nsobject_attribute_type (tree type)
{
  return POINTER_TYPE_P (type) && 
  lookup_attribute ("NSObject", TYPE_ATTRIBUTES (type));
}
/* APPLE LOCAL end radar 5595325 */

/* Determine if it is permissible to assign (if ARGNO is greater than -3)
   an instance of RTYP to an instance of LTYP or to compare the two
   (if ARGNO is equal to -3), per ObjC type system rules.  Before
   returning 'true', this routine may issue warnings related to, e.g.,
   protocol conformance.  When returning 'false', the routine must
   produce absolutely no warnings; the C or C++ front-end will do so
   instead, if needed.  If either LTYP or RTYP is not an Objective-C type,
   the routine must return 'false'.

   The ARGNO parameter is encoded as follows:
     >= 1	Parameter number (CALLEE contains function being called);
     0		Return value;
     -1		Assignment;
     -2		Initialization;
     APPLE LOCAL begin 4175534
     -3		Comparison (LTYP and RTYP may match in either direction);
     -4		Silent comparison (for C++ overload resolution).
     -5         Comparison of ivar and @synthesized property type
     // APPLE LOCAL begin radar 5218071
     -6         Comparison of two property types; RTYP is type of property
                in 'base' and LTYP is property type in derived class. They
                match if LTYP is more specialized than RTYP; this includes
                when RTYP is 'id' or LTYP is an object derived from an object 
                of RTYP.
    // APPLE LOCAL end radar 5218071
     APPLE LOCAL end 4175534  */

bool
/* APPLE LOCAL radar 6231433 */
objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee, const char *message)
{
  tree lcls, rcls, lproto, rproto;
  bool pointers_compatible;

  /* APPLE LOCAL begin radar 5595325 */
  tree orig_ltyp, orig_rtyp;
  /* APPLE LOCAL end radar 5595325 */

  /* We must be dealing with pointer types */
  if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
    return false;

  /* APPLE LOCAL begin radar 5595325 */
  orig_ltyp = ltyp;
  orig_rtyp = rtyp;
  /* APPLE LOCAL end radar 5595325 */
  do
    {
      ltyp = TREE_TYPE (ltyp);  /* Remove indirections.  */
      rtyp = TREE_TYPE (rtyp);
    }
  while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));

  /* APPLE LOCAL begin 4174166 */
  /* We must also handle function pointers, since ObjC is a bit more
     lenient than C or C++ on this.  */
  if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
    {
      /* Return types must be covariant.  */
      if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
	  && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
				  /* APPLE LOCAL radar 6231433 */
				  argno, callee, message))
      return false;

      /* Argument types must be contravariant.  */
      for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
	   ltyp && rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
	{
	  if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
	      && !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
				      /* APPLE LOCAL radar 6231433 */
				      argno, callee, message))
	    return false;
      }

      return (ltyp == rtyp);
    }

  /* APPLE LOCAL end 4174166 */
  /* Past this point, we are only interested in ObjC class instances,
     or 'id' or 'Class'.  */
  if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
    return false;

  if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
  /* APPLE LOCAL begin radar 5595325 */
      && !TYPE_HAS_OBJC_INFO (ltyp)) {
    /* Allow NSObject pointers to match 'id' */
    return (objc_nsobject_attribute_type (orig_ltyp) && objc_is_object_id (rtyp)) 
           ? true : false;
  }
  /* APPLE LOCAL end radar 5595325 */

  if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
  /* APPLE LOCAL begin radar 5595325 */
      && !TYPE_HAS_OBJC_INFO (rtyp)) {
    /* Allow NSObject pointers to match 'id' */
    return (objc_nsobject_attribute_type (orig_rtyp) && objc_is_object_id (ltyp)) 
           ? true : false;
  }
  /* APPLE LOCAL end radar 5595325 */

  /* APPLE LOCAL begin 4175534 */
  /* Past this point, we are committed to returning 'true' to the caller
     (unless performing a silent comparison; see below).  However, we can
     still warn about type and/or protocol mismatches.  */
  /* APPLE LOCAL end 4175534 */

  if (TYPE_HAS_OBJC_INFO (ltyp))
    {
      lcls = TYPE_OBJC_INTERFACE (ltyp);
      lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
    }
  else
    lcls = lproto = NULL_TREE;

  if (TYPE_HAS_OBJC_INFO (rtyp))
    {
      rcls = TYPE_OBJC_INTERFACE (rtyp);
      rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
    }
  else
    rcls = rproto = NULL_TREE;

  /* If we could not find an @interface declaration, we must have
     only seen a @class declaration; for purposes of type comparison,
     treat it as a stand-alone (root) class.  */

  /* APPLE LOCAL begin radar 6061276 */
  if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
    /* A previously declared @class may have its @interface declared at
       this point. Find it. */
    lcls = lookup_interface (lcls);

  if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
    /* A previously declared @class may have its @interface declared at
       this point. Find it. */
    rcls = lookup_interface (rcls);
  /* APPLE LOCAL end radar 6061276 */

  /* If either type is an unqualified 'id', we're done.  */
  /* APPLE LOCAL radar 5218071 */
  if ((argno != -6 && !lproto && objc_is_object_id (ltyp))
      || (!rproto && objc_is_object_id (rtyp)))
    return true;

  pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));

  /* If the underlying types are the same, and at most one of them has
     a protocol list, we do not need to issue any diagnostics.  */
  if (pointers_compatible && (!lproto || !rproto))
    return true;

  /* If exactly one of the types is 'Class', issue a diagnostic; any
     exceptions of this rule have already been handled.  */
  if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
    pointers_compatible = false;
  /* Otherwise, check for inheritance relations.  */
  else
    {
      if (!pointers_compatible)
	pointers_compatible
        /* APPLE LOCAL radar 5218071 */
	  = ((argno != -6 && objc_is_object_id (ltyp)) || objc_is_object_id (rtyp));
      /* APPLE LOCAL radar 5218071 */
      if (!pointers_compatible && argno != -6)
	pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);

      /* APPLE LOCAL 4175534 */
      if (!pointers_compatible && argno <= -3 && argno != -5)
	pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
    }

  /* If the pointers match modulo protocols, check for protocol conformance
     mismatches.  */
  if (pointers_compatible)
    {
      pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
						    /* APPLE LOCAL 4175534 */
						    (argno > -3 || argno == -5));

      if (!pointers_compatible && argno == -3)
	pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
						      /* APPLE LOCAL 4175534 */
						      false);
    }

  if (!pointers_compatible)
    {
      /* APPLE LOCAL begin 4175534 */
      /* The two pointers are not exactly compatible.  Issue a warning, unless
	 we are performing a silent comparison, in which case return 'false'
	 instead.  */
      /* APPLE LOCAL end 4175534 */
      switch (argno)
	{
	/* APPLE LOCAL begin 4175534 */
        /* APPLE LOCAL radar 5218071 */
        case -6:
	case -5:
	case -4:
	  return false;

	/* APPLE LOCAL end 4175534 */
        /* APPLE LOCAL begin radar 5839123 */
	case -3:
	  /* APPLE LOCAL begin radar 6231433 */
	  warning (0, "%s of distinct Objective-C types %qT and %qT lacks a cast",
                   message, orig_rtyp, orig_ltyp);
	  /* APPLE LOCAL end radar 6231433 */
	  break;

	case -2:
	  warning (0, "incompatible Objective-C types initializing %qT, expected %qT",
                   orig_rtyp, orig_ltyp);
	  break;

	case -1:
	  warning (0, "incompatible Objective-C types assigning %qT, expected %qT", 
		   orig_rtyp, orig_ltyp);
	  break;

	case 0:
	  warning (0, "incompatible Objective-C types returning %qT, expected %qT",
                   orig_rtyp, orig_ltyp);
	  break;

	default:
	  warning (0, "incompatible Objective-C types %qT, expected %qT when"
                       " passing argument %d of %qE from distinct "
		       "Objective-C type"
                        , orig_rtyp, orig_ltyp, argno, callee);
          /* APPLE LOCAL end radar 5839123 */
	  break;
	}
    }

  return true;
}

/* APPLE LOCAL begin radar 4229905 - radar 6131433 */
/* This routine is similar to objc_compare_types except that function-pointers are
   excluded. This is because, caller assumes that common types are of (id, Object*)
   variety and calls objc_common_type to obtain a common type. There is no commonolty
   between two function-pointers in this regard. */

bool
objc_have_common_type (tree ltyp, tree rtyp, int argno, tree callee, const char *message)
{
  if (objc_compare_types (ltyp, rtyp, argno, callee, message))
    {
      /* exclude function-pointer types. */
      do
        {
          ltyp = TREE_TYPE (ltyp);  /* Remove indirections.  */
          rtyp = TREE_TYPE (rtyp);
        }
      while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
      return !(TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE);
    }
  return false;
}
/* APPLE LOCAL end radar 4229905 - radar 6131433 */

/* Check if LTYP and RTYP have the same type qualifiers.  If either type
   lives in the volatilized hash table, ignore the 'volatile' bit when
   making the comparison.  */

bool
objc_type_quals_match (tree ltyp, tree rtyp)
{
  int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
  
  /* APPLE LOCAL begin radar 4204796 */
  if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp)))
    lquals &= ~TYPE_QUAL_VOLATILE;

  if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp)))
    rquals &= ~TYPE_QUAL_VOLATILE;
  /* APPLE LOCAL end radar 4204796 */

  return (lquals == rquals);
}

#ifndef OBJCPLUS
/* Determine if CHILD is derived from PARENT.  The routine assumes that
   both parameters are RECORD_TYPEs, and is non-reflexive.  */

static bool
objc_derived_from_p (tree parent, tree child)
{
  parent = TYPE_MAIN_VARIANT (parent);

  for (child = TYPE_MAIN_VARIANT (child);
       TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
    {
      child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
					     (TYPE_BINFO (child),
					      0)));

      if (child == parent)
	return true;
    }

  return false;
}
#endif

/* APPLE LOCAL C* language */
tree
objc_build_component_ref (tree datum, tree component)
{
  /* If COMPONENT is NULL, the caller is referring to the anonymous
     base class field.  */
  if (!component)
    {
      tree base = TYPE_FIELDS (TREE_TYPE (datum));

      return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
    }

  /* The 'build_component_ref' routine has been removed from the C++
     front-end, but 'finish_class_member_access_expr' seems to be
     a worthy substitute.  */
#ifdef OBJCPLUS
  return finish_class_member_access_expr (datum, component, false);
#else
  return build_component_ref (datum, component);
#endif
}

/* Recursively copy inheritance information rooted at BINFO.  To do this,
   we emulate the song and dance performed by cp/tree.c:copy_binfo().  */

static tree
objc_copy_binfo (tree binfo)
{
  tree btype = BINFO_TYPE (binfo);
  tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
  tree base_binfo;
  int ix;

  BINFO_TYPE (binfo2) = btype;
  BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
  BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);

  /* Recursively copy base binfos of BINFO.  */
  for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
    {
      tree base_binfo2 = objc_copy_binfo (base_binfo);

      BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
      BINFO_BASE_APPEND (binfo2, base_binfo2);
    }

  return binfo2;
}

/* Record superclass information provided in BASETYPE for ObjC class REF.
   This is loosely based on cp/decl.c:xref_basetypes().  */

static void
objc_xref_basetypes (tree ref, tree basetype)
{
  tree binfo = make_tree_binfo (basetype ? 1 : 0);

  TYPE_BINFO (ref) = binfo;
  BINFO_OFFSET (binfo) = size_zero_node;
  BINFO_TYPE (binfo) = ref;

  if (basetype)
    {
      tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));

      BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
      BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
      BINFO_BASE_APPEND (binfo, base_binfo);
      BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
    }
}

/* APPLE LOCAL begin radar 4204796 */
/* volatilized_hash and volatilized_eq removed */
/* APPLE LOCAL end radar 4204796 */
/* Called from finish_decl.  */

void
objc_check_decl (tree decl)
{
  tree type = TREE_TYPE (decl);

  /* APPLE LOCAL begin 6393374 */
  while (TREE_CODE (type) == ARRAY_TYPE)
    type = TREE_TYPE (type);
  /* APPLE LOCAL end 6393374 */
  if (TREE_CODE (type) != RECORD_TYPE)
    return;
  if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
    error ("statically allocated instance of Objective-C class %qs",
	   IDENTIFIER_POINTER (type));
}

/* APPLE LOCAL begin radar 4281748 */
void
objc_check_global_decl (tree decl)
{
  tree id = DECL_NAME (decl);
  if (objc_is_class_name (id) && global_bindings_p())
    error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
}
/* APPLE LOCAL end radar 4281748 */

/* APPLE LOCAL begin radar 4330422 */
/* Return a non-volatalized version of TYPE. */

tree
objc_non_volatilized_type (tree type)
{
  if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type)))
    type = build_qualified_type (type, (TYPE_QUALS (type) & ~TYPE_QUAL_VOLATILE));
  return type;
}
/* APPLE LOCAL end radar 4330422 */

/* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
   either name an Objective-C class, or refer to the special 'id' or 'Class'
   types.  If INTERFACE is not a valid ObjC type, just return it unchanged.  */

tree
objc_get_protocol_qualified_type (tree interface, tree protocols)
{
  /* If INTERFACE is not provided, default to 'id'.  */
  tree type = (interface ? objc_is_id (interface) : objc_object_type);
  bool is_ptr = (type != NULL_TREE);

  if (!is_ptr)
    {
      type = objc_is_class_name (interface);

      if (type)
	/* APPLE LOCAL begin 4216500 */
	{
	  /* If looking at a typedef, retrieve the precise type it
	     describes.  */
	  if (TREE_CODE (interface) == IDENTIFIER_NODE)
	    interface = identifier_global_value (interface);

	  type = ((interface && TREE_CODE (interface) == TYPE_DECL
		   && DECL_ORIGINAL_TYPE (interface))
		  ? DECL_ORIGINAL_TYPE (interface)
		  : xref_tag (RECORD_TYPE, type));
	}
	/* APPLE LOCAL end 4216500 */
      /* APPLE LOCAL begin radar 6267049 */
      else {
        /* This can only happen because of bogus code. Note that in this
	   path, protocols is not even considered. */
	error ("qualified type is not a valid object");
        /* Check further to see if protocol is valid. */
        if (protocols)
	  (void) lookup_and_install_protocols (protocols, false);
        return interface;
      }
      /* APPLE LOCAL end radar 6267049 */
    }

  if (protocols)
    {
      type = build_variant_type_copy (type);

      /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
	 to the pointee.  */
      if (is_ptr)
	{
	  TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
	  TYPE_POINTER_TO (TREE_TYPE (type)) = type;
	  type = TREE_TYPE (type);
	}

      /* Look up protocols and install in lang specific list.  */
      DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
      /* APPLE LOCAL radar 4398221 */
      TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols, false);

      /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
	 return the pointer to the new pointee variant.  */
      if (is_ptr)
	type = TYPE_POINTER_TO (type);
      else
	TYPE_OBJC_INTERFACE (type)
	  = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
    }

  return type;
}

/* Check for circular dependencies in protocols.  The arguments are
   PROTO, the protocol to check, and LIST, a list of protocol it
   conforms to.  */

static void
check_protocol_recursively (tree proto, tree list)
{
  tree p;

  for (p = list; p; p = TREE_CHAIN (p))
    {
      tree pp = TREE_VALUE (p);

      if (TREE_CODE (pp) == IDENTIFIER_NODE)
	pp = lookup_protocol (pp);

      if (pp == proto)
	fatal_error ("protocol %qs has circular dependency",
		     IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
      if (pp)
	check_protocol_recursively (proto, PROTOCOL_LIST (pp));
    }
}

/* APPLE LOCAL begin radar 4947311 - protocol attributes */
static void
objc_handle_protocol_attrs (tree proto)
{
  tree chain;

  for (chain = PROTOCOL_ATTRIBUTES (proto); chain; chain = TREE_CHAIN (chain))
    {
      if (is_attribute_p ("deprecated", TREE_PURPOSE (chain)))
	warning (0, "protocol %qs is deprecated",
		 IDENTIFIER_POINTER (CLASS_NAME (proto)));
      if (is_attribute_p ("unavailable", TREE_PURPOSE (chain)))
	warning (0, "protocol %qs is unavailable",
	         IDENTIFIER_POINTER (CLASS_NAME (proto)));
    }
  return;
}

/* APPLE LOCAL end radar 4947311 - protocol attributes */

/* Look up PROTOCOLS, and return a list of those that are found.
   If none are found, return NULL.  */

static tree
/* APPLE LOCAL radar 4398221 */
lookup_and_install_protocols (tree protocols, bool defNeeded)
{
  tree proto;
  tree return_value = NULL_TREE;

  for (proto = protocols; proto; proto = TREE_CHAIN (proto))
    {
      tree ident = TREE_VALUE (proto);
      tree p = lookup_protocol (ident);

      if (p)
	/* APPLE LOCAL begin radar 4398221 */
	{
	  if (defNeeded && !PROTOCOL_DEFINED (p))
	    warning (0, "no definition of protocol %qs is found",
		     IDENTIFIER_POINTER (ident));
	  /* APPLE LOCAL radar 4947311 - protocol attributes */
	  objc_handle_protocol_attrs (p);
	  return_value = chainon (return_value,
				  build_tree_list (NULL_TREE, p));
	}
      /* APPLE LOCAL end radar 4398221 */
      else if (ident != error_mark_node)
	error ("cannot find protocol declaration for %qs",
	       IDENTIFIER_POINTER (ident));
    }

  return return_value;
}

/* Create a declaration for field NAME of a given TYPE.  */

static tree
create_field_decl (tree type, const char *name)
{
  return build_decl (FIELD_DECL, get_identifier (name), type);
}

/* Create a global, static declaration for variable NAME of a given TYPE.  The
   finish_var_decl() routine will need to be called on it afterwards.  */

/* APPLE LOCAL begin radar 4431864 */
static tree
start_var_decl (tree type, const char *name)
{
  /* LLVM LOCAL begin */
  tree var = NULL_TREE;
#ifdef ENABLE_LLVM
  /* Prefer to use 'L' as a prefix so symbols can be stripped at assembly
     time. GCC codegen handles this later while emitting symbols, but fix
     it here for llvm.  */
  /* Special ObjC symbols in __data should use 'l' so the assembler
     will not strip the symbol; the linker needs to see these, but
     strip them after use. */
  char *new_name;
  if (name && strncmp (name, "_OBJC_", 6) == 0) {
    new_name = alloca (strlen (name) + 2);
#if TARGET_MACHO
    {
      const char* section = darwin_objc_llvm_special_name_section(name+6);
      new_name[0] = (section==0 || strcmp(section, "__DATA,__data")==0) 
                    ? 'l' : 'L';
    }
#else
    new_name[0] = 'L';
#endif
    strcpy (new_name + 1, name);
    var = build_decl (VAR_DECL, get_identifier (new_name), type);
    set_user_assembler_name (var, IDENTIFIER_POINTER (DECL_NAME (var)));
    /* Let optimizer know that this var is not removable.  */
    DECL_PRESERVE_P (var) = 1;
    TREE_USED(var) = 1;
  } 
  else
    /* Fall through. Build using 'name' */
#endif
  var = build_decl (VAR_DECL, get_identifier (name), type);
  /* LLVM LOCAL end */
  objc_set_global_decl_fields (var);
  return var;
}

/* Utility routine to set global flags for a global, static declaration. */

static void 
objc_set_global_decl_fields (tree var)
{
  TREE_STATIC (var) = 1;
  DECL_INITIAL (var) = error_mark_node;  /* A real initializer is coming... */
  DECL_IGNORED_P (var) = 1;
  DECL_ARTIFICIAL (var) = 1;
  DECL_CONTEXT (var) = NULL_TREE;
#ifdef OBJCPLUS
  DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
#endif
  /* APPLE LOCAL begin 6255801 */
  /* Keep word alignment for metadata records.  */
  DECL_USER_ALIGN (var) = 1;
  /* APPLE LOCAL end 6255801 */
}
/* APPLE LOCAL end radar 4431864 */

/* APPLE LOCAL begin ObjC new abi */
/* 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)
{
  /* APPLE LOCAL begin radar 4431864 */
  tree id = get_identifier (name);
  /* APPLE LOCAL radar 4441049 */
  tree var = hash_name_lookup (ivar_offset_hash_list, id);
  if (var)
    {
      DECL_EXTERNAL (var) = 0;
      /* APPLE LOCAL radar 4431864 */
      objc_set_global_decl_fields (var);
    }
  else
  /* APPLE LOCAL begin radar 4441049 */
    {
      var = start_var_decl (type, name);
      hash_name_enter (ivar_offset_hash_list, var);
    }
  /* APPLE LOCAL end radar 4441049 */
  /* APPLE LOCAL end radar 4431864 */
  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)
{
    tree decl = create_global_decl (type, name);
    DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
    DECL_VISIBILITY_SPECIFIED (decl) = 1;
    return decl;
}

/* Create an extern declaration for variable NAME of a given TYPE. The
   finish_var_decl() routine will need to be called on it afterwards.  */

static tree
create_extern_decl (tree type, const char *name)
{
  tree id = get_identifier (name);
  /* APPLE LOCAL radar 4441049 */
  tree var = hash_name_lookup (ivar_offset_hash_list, id);
  if (var)
    return var;
  /* Name not already declared. */
  var = build_decl (VAR_DECL, id, type); 
  DECL_EXTERNAL (var) = 1;
  TREE_PUBLIC (var) = 1;
  /* All external declarations are at file_scope to prevent 
     duplication of declarations; a common occurance for external
     variables holding ivar offsets in the new abi. */
  pushdecl_top_level (var);
  rest_of_decl_compilation (var, 0, 0);
  /* APPLE LOCAL radar 4441049 */
  hash_name_enter (ivar_offset_hash_list, var);
  return var;
}

/* APPLE LOCAL begin radar 4947014 - objc atomic property */
/* This routine declares prototypes:
   id objc_getProperty (id, SEL, ptrdiff_t, bool)
   void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
   void objc_copyStruct (void *, const void *, size_t, bool, bool)
*/
static void
declare_atomic_property_api (void)
{
  tree func_type;

  umsg_GetAtomicProperty = lookup_name (get_identifier ("objc_getProperty"));
  umsg_SetAtomicProperty = lookup_name (get_identifier ("objc_setProperty"));
  umsg_CopyAtomicStruct = lookup_name (get_identifier ("objc_copyStruct"));
  if (umsg_GetAtomicProperty && umsg_SetAtomicProperty && umsg_CopyAtomicStruct)
    return;

  if (!umsg_GetAtomicProperty)
    {
      /* id objc_getProperty (id, SEL, ptrdiff_t, bool) */
      func_type
        = build_function_type (objc_object_type,
		           tree_cons (NULL_TREE, objc_object_type,
	              	     tree_cons (NULL_TREE, objc_selector_type,
			       tree_cons (NULL_TREE, long_integer_type_node, 
			    	 tree_cons (NULL_TREE, boolean_type_node, NULL_TREE)))));
      umsg_GetAtomicProperty = builtin_function (
			        "objc_getProperty",
			        func_type, 0, NOT_BUILT_IN, 0, NULL_TREE);
      TREE_NOTHROW (umsg_GetAtomicProperty) = 0;
    }

  if (!umsg_SetAtomicProperty)
    {
      /* void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) */
      func_type
        = build_function_type (void_type_node,
		           tree_cons (NULL_TREE, objc_object_type,
			     tree_cons (NULL_TREE, objc_selector_type,
			       tree_cons (NULL_TREE, long_integer_type_node, 
			         tree_cons (NULL_TREE, objc_object_type, 
				   tree_cons (NULL_TREE, boolean_type_node, 
				     tree_cons (NULL_TREE, boolean_type_node, NULL_TREE)))))));
      umsg_SetAtomicProperty = builtin_function (
			        "objc_setProperty",
			        func_type, 0, NOT_BUILT_IN, 0, NULL_TREE);
      TREE_NOTHROW (umsg_SetAtomicProperty) = 0;
    }

  if (!umsg_CopyAtomicStruct)
    {
      /* void objc_copyStruct (void *, const void *, size_t, bool, bool) */
      func_type
        = build_function_type (void_type_node,
		           tree_cons (NULL_TREE, ptr_type_node,
			     tree_cons (NULL_TREE, ptr_type_node,
			       tree_cons (NULL_TREE, long_unsigned_type_node, 
				   tree_cons (NULL_TREE, boolean_type_node, 
				     tree_cons (NULL_TREE, boolean_type_node, NULL_TREE))))));
      umsg_CopyAtomicStruct = builtin_function (
			        "objc_copyStruct",
			        func_type, 0, NOT_BUILT_IN, 0, NULL_TREE);
      TREE_NOTHROW (umsg_CopyAtomicStruct) = 0;
    }
  return; 
}

/* This routine returns true if struct/union contains an object pointer or a __strong pointer. */
static bool
aggregate_contains_objc_pointer (tree type)
{
  tree field;
  field = TYPE_FIELDS (type);

  for (; field; field = TREE_CHAIN (field))
    {
#ifdef OBJCPLUS
      if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
        continue;
#endif
      type = TREE_TYPE (field);
      if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE)
	if (aggregate_contains_objc_pointer (type))
	  return true;
      if (objc_is_gcable_type (type) == 1)
	return true; 
    }
  return false;
}

/* APPLE LOCAL end radar 4947014 - objc atomic property */

/* APPLE LOCAL end ObjC new abi */

/* Finish off the variable declaration created by start_var_decl().  */

static void
finish_var_decl (tree var, tree initializer)
{
  finish_decl (var, initializer, NULL_TREE);
  /* Ensure that the variable actually gets output.  */
  mark_decl_referenced (var);
  /* Mark the decl to avoid "defined but not used" warning.  */
  TREE_USED (var) = 1;
}

/* Find the decl for the constant string class reference.  This is only
   used for the NeXT runtime.  */

static tree
setup_string_decl (void)
{
  char *name;
  size_t length;
  /* APPLE LOCAL begin radar 4719165 */
  const char *prefix = (flag_objc_abi == 2) 
			? STRING_V2_OBJECT_GLOBAL_FORMAT 
			: STRING_OBJECT_GLOBAL_FORMAT;

  /* %s in format will provide room for terminating null */
  length = strlen (prefix)
	   + strlen (constant_string_class_name);
  name = xmalloc (length);
  sprintf (name, prefix,
	   constant_string_class_name);
  constant_string_global_id = get_identifier (name);
  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 (flag_objc_abi == 2 && !string_class_decl)
    string_class_decl = create_extern_decl (objc_v2_class_template, name);
  /* APPLE LOCAL end radar 4719165 */
  return string_class_decl;
}

/* Purpose: "play" parser, creating/installing representations
   of the declarations that are required by Objective-C.

   Model:

	type_spec--------->sc_spec
	(tree_list)        (tree_list)
	    |                  |
	    |                  |
	identifier_node    identifier_node  */

static void
synth_module_prologue (void)
{
  tree type;
  enum debug_info_type save_write_symbols = write_symbols;
  const struct gcc_debug_hooks *const save_hooks = debug_hooks;
  /* APPLE LOCAL 6348516 */
  int save_warn_padded;

  /* Suppress outputting debug symbols, because
     dbxout_init hasn'r been called yet.  */
  write_symbols = NO_DEBUG;
  debug_hooks = &do_nothing_debug_hooks;

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

  /* The following are also defined in <objc/objc.h> and friends.  */

  objc_object_id = get_identifier (TAG_OBJECT);
  objc_class_id = get_identifier (TAG_CLASS);

  objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
  objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);

  objc_object_type = build_pointer_type (objc_object_reference);
  objc_class_type = build_pointer_type (objc_class_reference);

  objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
  objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);

  /* Declare the 'id' and 'Class' typedefs.  */

  type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
						objc_object_name,
						objc_object_type));
  DECL_IN_SYSTEM_HEADER (type) = 1;
  type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
						objc_class_name,
						objc_class_type));
  DECL_IN_SYSTEM_HEADER (type) = 1;

  /* Forward-declare '@interface Protocol'.  */

  type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
  objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
  objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
                                type));

  /* Declare type of selector-objects that represent an operation name.  */

  if (flag_next_runtime)
    /* `struct objc_selector *' */
    objc_selector_type
      = build_pointer_type (xref_tag (RECORD_TYPE,
				      get_identifier (TAG_SELECTOR)));
  else
    /* `const struct objc_selector *' */
    objc_selector_type
      = build_pointer_type
	(build_qualified_type (xref_tag (RECORD_TYPE,
					 get_identifier (TAG_SELECTOR)),
			       TYPE_QUAL_CONST));

  /* Declare receiver type used for dispatching messages to 'super'.  */

  /* `struct objc_super *' */
  objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
						  get_identifier (TAG_SUPER)));

  /* Declare pointers to method and ivar lists.  */
  objc_method_list_ptr = build_pointer_type
			 (xref_tag (RECORD_TYPE,
				    get_identifier (UTAG_METHOD_LIST)));
  objc_method_proto_list_ptr
    = build_pointer_type (xref_tag (RECORD_TYPE,
				    get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
  objc_ivar_list_ptr = build_pointer_type
		       (xref_tag (RECORD_TYPE,
				  get_identifier (UTAG_IVAR_LIST)));

  /* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
  objc_prop_list_ptr 
   = build_pointer_type (xref_tag (RECORD_TYPE,
				     get_identifier ("_prop_list_t")));
  /* APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions */

  /* APPLE LOCAL begin ObjC new abi */
  if (flag_objc_abi == 2)
    {
      objc_v2_ivar_list_ptr = build_pointer_type (
				    xref_tag (RECORD_TYPE, 
					      get_identifier ("_ivar_list_t")));
    }

  /* typedef id (*IMP)(id, SEL, ...); */
  objc_imp_type
    = build_pointer_type
	  (build_function_type (objc_object_type,      
				tree_cons (NULL_TREE, objc_object_type,      
					   tree_cons (NULL_TREE, objc_selector_type,      
						      NULL_TREE))));      
  /* APPLE LOCAL end ObjC new abi */

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

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

      /* id objc_msgSend (id, SEL, ...); */
      /* id objc_msgSendNonNil (id, SEL, ...); */
      /* id objc_msgSend_stret (id, SEL, ...); */
      /* id objc_msgSendNonNil_stret (id, SEL, ...); */
      type
	= build_function_type (objc_object_type,
			       tree_cons (NULL_TREE, objc_object_type,
					  tree_cons (NULL_TREE, objc_selector_type,
						     NULL_TREE)));
      umsg_decl = builtin_function (TAG_MSGSEND,
				    type, 0, NOT_BUILT_IN,
				    NULL, NULL_TREE);
      umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
					   type, 0, NOT_BUILT_IN,
					   NULL, NULL_TREE);
      umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
					  type, 0, NOT_BUILT_IN,
					  NULL, NULL_TREE);
      umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
						 type, 0, NOT_BUILT_IN,
						 NULL, NULL_TREE);

      /* APPLE LOCAL begin ObjC new abi */
      /* APPLE LOCAL ARM hybrid objc-2.0 */
      if (flag_objc_abi == 2 && !flag_objc_legacy_dispatch)
	{
          /* APPLE LOCAL radar 4699834 */
 	  /* Removed _rtp suffix from objc_msgSend_fixup_rtp and variants */
    	  build_message_ref_template ();
	  /* id objc_msgSend_fixup (id, struct message_ref_t*, ...); */
	  type 
	    = build_function_type (objc_object_type,
				   tree_cons (NULL_TREE, objc_object_type,
					      tree_cons (NULL_TREE, objc_v2_selector_type,
						          NULL_TREE)));
	  umsg_fixup_decl = builtin_function ("objc_msgSend_fixup",
					      type, 0, NOT_BUILT_IN,
					      NULL, NULL_TREE);
	  TREE_NOTHROW (umsg_fixup_decl) = 0;
	  /* APPLE LOCAL begin radar 4557598 */
	  umsg_fpret_fixup_decl = builtin_function ("objc_msgSend_fpret_fixup",
					      type, 0, NOT_BUILT_IN,
					      NULL, NULL_TREE);
	  TREE_NOTHROW (umsg_fpret_fixup_decl) = 0;
	  /* APPLE LOCAL end radar 4557598 */

	  /* id objc_msgSend_stret_fixup (id, struct message_ref_t*, ...); */
	  umsg_stret_fixup_decl = builtin_function ("objc_msgSend_stret_fixup",
					      	    type, 0, NOT_BUILT_IN,
					      	    NULL, NULL_TREE);
	  TREE_NOTHROW (umsg_stret_fixup_decl) = 0;

	  /* id objc_msgSendId_fixup (id, struct message_ref_t*, ...); */
	  umsg_id_fixup_decl = builtin_function ("objc_msgSendId_fixup",
                                              type, 0, NOT_BUILT_IN,
                                              NULL, NULL_TREE);
          TREE_NOTHROW (umsg_id_fixup_decl) = 0;

	  /* id objc_msgSendId_stret_fixup (id, struct message_ref_t*, ...); */
	  umsg_id_stret_fixup_decl = builtin_function ("objc_msgSendId_stret_fixup",
                                              type, 0, NOT_BUILT_IN,
                                              NULL, NULL_TREE);
          TREE_NOTHROW (umsg_id_stret_fixup_decl) = 0;

          /* id objc_msgSendSuper2_fixup (struct objc_super *, struct message_ref_t*, ...); */
          type
	    = build_function_type (objc_object_type,
			           tree_cons (NULL_TREE, objc_super_type,
				   tree_cons (NULL_TREE, objc_v2_super_selector_type,
					      NULL_TREE)));
          umsg_id_super2_fixup_decl = builtin_function ("objc_msgSendSuper2_fixup",
					      		type, 0, NOT_BUILT_IN,
					      		NULL, NULL_TREE);
	  TREE_NOTHROW (umsg_id_super2_fixup_decl) = 0;
          /* id objc_msgSendSuper2_stret_fixup (struct objc_super *, struct message_ref_t*, ...); */
          umsg_id_super2_stret_fixup_decl = builtin_function ("objc_msgSendSuper2_stret_fixup",
						    	      type, 0, NOT_BUILT_IN, 0,
						              NULL_TREE);
	  TREE_NOTHROW (umsg_id_super2_stret_fixup_decl) = 0;

	  /* APPLE LOCAL radar 4533974 - ObjC new protocol */
	  /* code removed */
	}
      /* APPLE LOCAL end ObjC new abi */

      /* APPLE LOCAL begin C* language */
      build_objc_fast_enum_state_type ();

      /* void objc_enumerationMutation (id) */
      type = build_function_type (void_type_node, 
				  tree_cons (NULL_TREE, objc_object_type, NULL_TREE));
      objc_enum_mutation_decl = builtin_function (
				  "objc_enumerationMutation",
				  type, 0, NOT_BUILT_IN, 0, NULL_TREE);
      TREE_NOTHROW (objc_enum_mutation_decl) = 0;

      /* APPLE LOCAL end C* language */

      /* APPLE LOCAL begin radar 4280641 */
      /* Not needed for ppc */
      umsg_fpret_decl = builtin_function (TAG_MSGSEND_FPRET,
				          type, 0, NOT_BUILT_IN,
					  NULL, NULL_TREE);
      TREE_NOTHROW (umsg_fpret_decl) = 0;
      /* APPLE LOCAL end radar 4280641 */

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

      /* id objc_msgSend_Fast (id, SEL, ...)
	   __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
      /* APPLE LOCAL begin radar 4590221 */
      if (OFFS_MSGSEND_FAST)
	{
          /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
          tree umsg_fast_decl;
          umsg_fast_decl = build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST);
          umsg_fast_decl = build_c_cast (build_pointer_type (TREE_TYPE (umsg_decl)),
                                    umsg_fast_decl);
          umsg_fast_decl = build_indirect_ref (umsg_fast_decl, "*"); 
          umsg_decl = umsg_fast_decl;
#else
          umsg_decl = builtin_function (TAG_MSGSEND_FAST,
					type, 0, NOT_BUILT_IN,
					NULL, NULL_TREE);
          TREE_NOTHROW (umsg_decl) = 0;
          DECL_ATTRIBUTES (umsg_decl) 
	    = tree_cons (get_identifier ("hard_coded_address"), 
		         build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
		         NULL_TREE);
#endif
          /* LLVM LOCAL end */
	}
      /* APPLE LOCAL end radar 4590221 */

      /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
      /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
      type
	= build_function_type (objc_object_type,
			       tree_cons (NULL_TREE, objc_super_type,
					  tree_cons (NULL_TREE, objc_selector_type,
						     NULL_TREE)));
      umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
					  type, 0, NOT_BUILT_IN,
					  NULL, NULL_TREE);
      umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
						type, 0, NOT_BUILT_IN, 0,
						NULL_TREE);
      TREE_NOTHROW (umsg_super_decl) = 0;
      TREE_NOTHROW (umsg_super_stret_decl) = 0;
    }
  else
    {
      /* GNU runtime messenger entry points.  */

      /* APPLE LOCAL begin ObjC new abi */
      /* code removed */
      /* APPLE LOCAL end ObjC new abi */
      /* IMP objc_msg_lookup (id, SEL); */
      type
      /* APPLE LOCAL ObjC new abi */
        = build_function_type (objc_imp_type,
			       tree_cons (NULL_TREE, objc_object_type,
					  tree_cons (NULL_TREE, objc_selector_type,
						     OBJC_VOID_AT_END)));
      umsg_decl = builtin_function (TAG_MSGSEND,
				    type, 0, NOT_BUILT_IN,
				    NULL, NULL_TREE);
      TREE_NOTHROW (umsg_decl) = 0;

      /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
      type
      /* APPLE LOCAL ObjC new abi */
        = build_function_type (objc_imp_type,
			       tree_cons (NULL_TREE, objc_super_type,
					  tree_cons (NULL_TREE, objc_selector_type,
						     OBJC_VOID_AT_END)));
      umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
					  type, 0, NOT_BUILT_IN,
					  NULL, NULL_TREE);
      TREE_NOTHROW (umsg_super_decl) = 0;

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

	 __objc_exec_class (void *); */
      type
	= build_function_type (void_type_node,
			       tree_cons (NULL_TREE, ptr_type_node,
					  OBJC_VOID_AT_END));
      execclass_decl = builtin_function (TAG_EXECCLASS,
					 type, 0, NOT_BUILT_IN,
					 NULL, NULL_TREE);
    }

  /* id objc_getClass (const char *); */

  type = build_function_type (objc_object_type,
				   tree_cons (NULL_TREE,
					      const_string_type_node,
					      OBJC_VOID_AT_END));

  objc_get_class_decl
    = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
			NULL, NULL_TREE);

  /* id objc_getMetaClass (const char *); */

  objc_get_meta_class_decl
    = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);

  /* APPLE LOCAL begin radar 4698856 */
  if (flag_objc_abi == 2)
    build_v2_class_template ();
  /* APPLE LOCAL end radar 4698856 */

  build_class_template ();
  build_super_template ();
  /* APPLE LOCAL begin ObjC new abi */
  if (flag_objc_abi == 2)
    {
      build_v2_protocol_template ();
      build_v2_category_template ();
    }
  /* APPLE LOCAL end ObjC new abi */
  build_protocol_template ();
  /* APPLE LOCAL begin 6348516 */
  save_warn_padded = warn_padded;
  warn_padded = 0;
  /* APPLE LOCAL end 6348516 */
  build_category_template ();
  build_objc_exception_stuff ();

  if (flag_next_runtime)
    build_next_objc_exception_stuff ();

  /* APPLE LOCAL 6348516 */
  warn_padded = save_warn_padded;
  /* static SEL _OBJC_SELECTOR_TABLE[]; */

  if (! flag_next_runtime)
    build_selector_table_decl ();

  /* Forward declare constant_string_id and constant_string_type.  */
  if (!constant_string_class_name)
    constant_string_class_name = default_constant_string_class_name;

  constant_string_id = get_identifier (constant_string_class_name);
  objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));

  /* Pre-build the following entities - for speed/convenience.  */
  self_id = get_identifier ("self");
  ucmd_id = get_identifier ("_cmd");

#ifdef OBJCPLUS
  pop_lang_context ();
#endif

  write_symbols = save_write_symbols;
  debug_hooks = save_hooks;
  /* APPLE LOCAL radar 4590221 */
  /* code removed */
}

/* Ensure that the ivar list for NSConstantString/NXConstantString
   (or whatever was specified via `-fconstant-string-class')
   contains fields at least as large as the following three, so that
   the runtime can stomp on them with confidence:

   struct STRING_OBJECT_CLASS_NAME
   {
     Object isa;
     char *cString;
     unsigned int length;
   }; */

static int
check_string_class_template (void)
{
  tree field_decl = objc_get_class_ivars (constant_string_id);

#define AT_LEAST_AS_LARGE_AS(F, T) \
  (F && TREE_CODE (F) == FIELD_DECL \
     && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
	 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))

  if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
    return 0;

  field_decl = TREE_CHAIN (field_decl);
  if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
    return 0;

  field_decl = TREE_CHAIN (field_decl);
  return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);

#undef AT_LEAST_AS_LARGE_AS
}

/* Avoid calling `check_string_class_template ()' more than once.  */
static GTY(()) int string_layout_checked;

/* Construct an internal string layout to be used as a template for
   creating NSConstantString/NXConstantString instances.  */

static tree
objc_build_internal_const_str_type (void)
{
  tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
  tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
  tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);

  TREE_CHAIN (field) = fields; fields = field;
  field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
  TREE_CHAIN (field) = fields; fields = field;
  /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
     reverse order!  */
  finish_builtin_struct (type, "__builtin_ObjCString",
			 fields, NULL_TREE);

  return type;
}

/* Custom build_string which sets TREE_TYPE!  */

static tree
my_build_string (int len, const char *str)
{
  return fix_string_type (build_string (len, str));
}

/* Build a string with contents STR and length LEN and convert it to a
   pointer.  */

static tree
my_build_string_pointer (int len, const char *str)
{
  tree string = my_build_string (len, str);
  tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
  return build1 (ADDR_EXPR, ptrtype, string);
}

static hashval_t
string_hash (const void *ptr)
{
  tree str = ((struct string_descriptor *)ptr)->literal;
  const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
  int i, len = TREE_STRING_LENGTH (str);
  hashval_t h = len;

  for (i = 0; i < len; i++)
    h = ((h * 613) + p[i]);

  return h;
}

static int
string_eq (const void *ptr1, const void *ptr2)
{
  tree str1 = ((struct string_descriptor *)ptr1)->literal;
  tree str2 = ((struct string_descriptor *)ptr2)->literal;
  int len1 = TREE_STRING_LENGTH (str1);

  return (len1 == TREE_STRING_LENGTH (str2)
	  && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
		      len1));
}

/* APPLE LOCAL begin radar 5982789 */
/* This routine build "NSString" type if "NSString" class is declared
  in scope where it is needed. */
static tree buildNSStringType(void)
{
  tree NSString_decl;

  NSString_decl = objc_is_class_name (get_identifier ("NSString"));
  if (!NSString_decl)
    return NULL_TREE;
  return objc_get_protocol_qualified_type (NSString_decl, NULL_TREE);
}
/* APPLE LOCAL end radar 5982789 */

/* Given a chain of STRING_CST's, build a static instance of
   NXConstantString which points at the concatenation of those
   strings.  We place the string object in the __string_objects
   section of the __OBJC segment.  The Objective-C runtime will
   initialize the isa pointers of the string objects to point at the
   NXConstantString class object.  */

tree
objc_build_string_object (tree string)
{
  tree initlist, constructor, constant_string_class;
  int length;
  tree fields, addr;
  struct string_descriptor *desc, key;
  void **loc;

  /* APPLE LOCAL begin radar 5887355 */
#ifdef OBJCPLUS
  if (processing_template_decl)
    /* Must wait until template instantiation time.  */
    return build_min_nt (OBJC_STRING_REFERENCE, string);
#endif
  /* APPLE LOCAL end radar 5887355 */

  /* Prep the string argument.  */
  string = fix_string_type (string);
  TREE_SET_CODE (string, STRING_CST);
  length = TREE_STRING_LENGTH (string) - 1;

  /* APPLE LOCAL begin constant cfstrings */
  /* The target may have different ideas on how to construct an
     ObjC string literal.  On Darwin (Mac OS X), for example,
     we may wish to obtain a constant CFString reference instead.  */
  constructor = (*targetm.construct_objc_string) (string);
  /* APPLE LOCAL begin radar 4494634, 5982789 */
  if (constructor)
    {
      tree NSStringPtrType = buildNSStringType();
      return build1 (NOP_EXPR, 
                     NSStringPtrType ? build_pointer_type (NSStringPtrType)
                                     : objc_object_type, constructor);
    }
  /* APPLE LOCAL end radar 4494634, 5982789 */
  /* APPLE LOCAL end constant cfstrings */  
    
  /* Check whether the string class being used actually exists and has the
     correct ivar layout.  */
  if (!string_layout_checked)
    {
      string_layout_checked = -1;
      constant_string_class = lookup_interface (constant_string_id);
      internal_const_str_type = objc_build_internal_const_str_type ();

      if (!constant_string_class
	  || !(constant_string_type
	       = CLASS_STATIC_TEMPLATE (constant_string_class)))
	error ("cannot find interface declaration for %qs",
	       IDENTIFIER_POINTER (constant_string_id));
      /* The NSConstantString/NXConstantString ivar layout is now known.  */
      else if (!check_string_class_template ())
	error ("interface %qs does not have valid constant string layout",
	       IDENTIFIER_POINTER (constant_string_id));
      /* For the NeXT runtime, we can generate a literal reference
	 to the string class, don't need to run a constructor.  */
      else if (flag_next_runtime && !setup_string_decl ())
	error ("cannot find reference tag for class %qs",
	       IDENTIFIER_POINTER (constant_string_id));
      else
	{
	  string_layout_checked = 1;  /* Success!  */
	  add_class_reference (constant_string_id);
	}
    }

  if (string_layout_checked == -1)
    return error_mark_node;

  /* Perhaps we already constructed a constant string just like this one? */
  key.literal = string;
  loc = htab_find_slot (string_htab, &key, INSERT);
  desc = *loc;

  if (!desc)
    {
      tree var;
      *loc = desc = ggc_alloc (sizeof (*desc));
      desc->literal = string;

      /* GNU:    (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length })  */
      /* NeXT:   (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length })   */
      fields = TYPE_FIELDS (internal_const_str_type);
      initlist
	= build_tree_list (fields,
			   flag_next_runtime
			   ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
			   /* APPLE LOCAL radar 6285794 */
			   : integer_zero_node);
      fields = TREE_CHAIN (fields);
      initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
			    initlist);
      fields = TREE_CHAIN (fields);
      initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
 			    initlist);
      constructor = objc_build_constructor (internal_const_str_type,
					    nreverse (initlist));
      TREE_INVARIANT (constructor) = true;

      if (!flag_next_runtime)
	constructor
	  = objc_add_static_instance (constructor, constant_string_type);
      else
        {
	  var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
	  DECL_INITIAL (var) = constructor;
	  TREE_STATIC (var) = 1;
	  pushdecl_top_level (var);
	  constructor = var;
	}
      desc->constructor = constructor;
    }

  addr = convert (build_pointer_type (constant_string_type),
		  build_unary_op (ADDR_EXPR, desc->constructor, 1));

  return addr;
}

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

static GTY(()) int num_static_inst;

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

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

  sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
  decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
  DECL_COMMON (decl) = 1;
  TREE_STATIC (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  TREE_USED (decl) = 1;
  DECL_INITIAL (decl) = constructor;

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

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

  return decl;
}

/* Build a static constant CONSTRUCTOR
   with type TYPE and elements ELTS.  */

static tree
objc_build_constructor (tree type, tree elts)
{
  tree constructor = build_constructor_from_list (type, elts);

  TREE_CONSTANT (constructor) = 1;
  TREE_STATIC (constructor) = 1;
  TREE_READONLY (constructor) = 1;

#ifdef OBJCPLUS
  /* Adjust for impedance mismatch.  We should figure out how to build
     CONSTRUCTORs that consistently please both the C and C++ gods.  */
  if (!TREE_PURPOSE (elts))
    TREE_TYPE (constructor) = NULL_TREE;
  TREE_HAS_CONSTRUCTOR (constructor) = 1;
#endif

  return constructor;
}

/* Take care of defining and initializing _OBJC_SYMBOLS.  */

/* Predefine the following data type:

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

static void
build_objc_symtab_template (void)
{
  tree field_decl, field_decl_chain;

  objc_symtab_template
    = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));

  /* long sel_ref_cnt; */
  field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
  field_decl_chain = field_decl;

  /* SEL *refs; */
  field_decl = create_field_decl (build_pointer_type (objc_selector_type),
				  "refs");
  chainon (field_decl_chain, field_decl);

  /* short cls_def_cnt; */
  field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
  chainon (field_decl_chain, field_decl);

  /* short cat_def_cnt; */
  field_decl = create_field_decl (short_integer_type_node,
				  "cat_def_cnt");
  chainon (field_decl_chain, field_decl);

  if (imp_count || cat_count || !flag_next_runtime)
    {
      /* void *defs[imp_count + cat_count (+ 1)]; */
      /* NB: The index is one less than the size of the array.  */
      int index = imp_count + cat_count
		+ (flag_next_runtime? -1: 0);
      field_decl = create_field_decl
		   (build_array_type
		    (ptr_type_node,
		     build_index_type (build_int_cst (NULL_TREE, index))),
		    "defs");
      chainon (field_decl_chain, field_decl);
    }

  finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
}

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

static tree
init_def_list (tree type)
{
  tree expr, initlist = NULL_TREE;
  struct imp_entry *impent;

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

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

  if (!flag_next_runtime)
    {
      /* statics = { ..., _OBJC_STATIC_INSTANCES, ... }  */
      tree expr;

      if (static_instances_decl)
	expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
      else
	/* APPLE LOCAL radar 6285794 */
	expr = integer_zero_node;

      initlist = tree_cons (NULL_TREE, expr, initlist);
    }

  return objc_build_constructor (type, nreverse (initlist));
}

/* Construct the initial value for all of _objc_symtab.  */

static tree
init_objc_symtab (tree type)
{
  tree initlist;

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

  initlist = build_tree_list (NULL_TREE,
			      build_int_cst (long_integer_type_node, 0));

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

  if (flag_next_runtime || ! sel_ref_chain)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (build_pointer_type (objc_selector_type),
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    initlist
      = tree_cons (NULL_TREE,
		   convert (build_pointer_type (objc_selector_type),
			    build_unary_op (ADDR_EXPR,
					    UOBJC_SELECTOR_TABLE_decl, 1)),
		   initlist);

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

  /* APPLE LOCAL begin radar 4349670 */
  /* NULL_TREE for the type means to use integer_type_node.  However, this should 
     be a short. */
  initlist = tree_cons (NULL_TREE, build_int_cst (short_integer_type_node, 
						  imp_count), initlist);

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

  initlist = tree_cons (NULL_TREE, build_int_cst (short_integer_type_node, 
						  cat_count), initlist);
  /* APPLE LOCAL end radar 4349670 */

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

  if (imp_count || cat_count || !flag_next_runtime)
    {

      tree field = TYPE_FIELDS (type);
      field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));

      initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
			    initlist);
    }

  return objc_build_constructor (type, nreverse (initlist));
}

/* Generate forward declarations for metadata such as
  'OBJC_CLASS_...'.  */

static tree
/* APPLE LOCAL radar 5202926 */
build_metadata_decl (const char *name, tree type, bool external_linkage)
{
  tree decl;

  /* struct TYPE NAME_<name>; */
  decl = start_var_decl (type, synth_id_with_class_suffix
			       (name,
				objc_implementation_context));
  /* APPLE LOCAL begin radar 5202926 */
  if (external_linkage)
    TREE_PUBLIC (decl) = 1;
  /* APPLE LOCAL end radar 5202926 */
  return decl;
}

/* Push forward-declarations of all the categories so that
   init_def_list can use them in a CONSTRUCTOR.  */

static void
forward_declare_categories (void)
{
  struct imp_entry *impent;
  tree sav = objc_implementation_context;

  for (impent = imp_list; impent; impent = impent->next)
    {
      if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
	{
	  /* Set an invisible arg to synth_id_with_class_suffix.  */
	  objc_implementation_context = impent->imp_context;
	  /* APPLE LOCAL begin new ObjC abi v2 */
	  if (flag_objc_abi == 2)
	    {
	      /* APPLE LOCAL begin radar 6064186 */
	      /* extern struct category_t l_OBJC_$_CATEGORY_<name>; */
	      impent->class_v2_decl = build_metadata_decl ("l_OBJC_$_CATEGORY",
							   /* APPLE LOCAL radar 5202926 */
						           objc_v2_category_template, false); 
	      set_user_assembler_name (impent->class_v2_decl, 
				       IDENTIFIER_POINTER (DECL_NAME (impent->class_v2_decl)));
	      /* APPLE LOCAL end radar 6064186 */
	    }
	  else
	    {
	      /* extern struct objc_category _OBJC_CATEGORY_<name>; */
	      impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
							/* APPLE LOCAL radar 5202926 */
						        objc_category_template, false);
	    }
	  /* APPLE LOCAL end new ObjC abi v2 */
	}
    }
  objc_implementation_context = sav;
}

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

static void
generate_objc_symtab_decl (void)
{
  /* forward declare categories */
  if (cat_count)
    forward_declare_categories ();

  /* APPLE LOCAL begin new ObjC abi v2 */
  /* APPLE LOCAL radar 4531482 */
  if (flag_objc_abi != 2)
    {
      build_objc_symtab_template ();
      UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
      finish_var_decl (UOBJC_SYMBOLS_decl,
		       init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
    }
  /* APPLE LOCAL end new ObjC abi v2 */
}

static tree
init_module_descriptor (tree type)
{
  tree initlist, expr;

  /* version = { 1, ... } */

  expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
  initlist = build_tree_list (NULL_TREE, expr);

  /* size = { ..., sizeof (struct _objc_module), ... } */

  expr = convert (long_integer_type_node,
		  size_in_bytes (objc_module_template));
  initlist = tree_cons (NULL_TREE, expr, initlist);

  /* Don't provide any file name for security reasons. */
  /* name = { ..., "", ... } */

  expr = add_objc_string (get_identifier (""), class_names);
  initlist = tree_cons (NULL_TREE, expr, initlist);

  /* symtab = { ..., _OBJC_SYMBOLS, ... } */

  if (UOBJC_SYMBOLS_decl)
    expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
  else
    /* APPLE LOCAL radar 6285794 */
    expr = integer_zero_node;
  initlist = tree_cons (NULL_TREE, expr, initlist);

  return objc_build_constructor (type, nreverse (initlist));
}

/* Write out the data structures to describe Objective C classes defined.

   struct _objc_module { ... } _OBJC_MODULE = { ... };   */

static void
build_module_descriptor (void)
{
  tree field_decl, field_decl_chain;

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

  objc_module_template
    = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));

  /* long version; */
  field_decl = create_field_decl (long_integer_type_node, "version");
  field_decl_chain = field_decl;

  /* long size; */
  field_decl = create_field_decl (long_integer_type_node, "size");
  chainon (field_decl_chain, field_decl);

  /* char *name; */
  field_decl = create_field_decl (string_type_node, "name");
  chainon (field_decl_chain, field_decl);

  /* struct _objc_symtab *symtab; */
  field_decl
    = create_field_decl (build_pointer_type
			 (xref_tag (RECORD_TYPE,
				    get_identifier (UTAG_SYMTAB))),
			 "symtab");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_module_template, field_decl_chain, NULL_TREE);

  /* Create an instance of "_objc_module".  */
  UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
  finish_var_decl (UOBJC_MODULES_decl,
		   init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));

#ifdef OBJCPLUS
  pop_lang_context ();
#endif
}

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

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

static void
build_module_initializer_routine (void)
{
  tree body;

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

  objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
  /* APPLE LOCAL begin radar 5839812 - location for synthesized methods  */
  objc_start_function (get_identifier (TAG_GNUINIT),
		       build_function_type (void_type_node,
					    OBJC_VOID_AT_END),
		       NULL_TREE, objc_get_parm_info (0), NULL_TREE);
  /* APPLE LOCAL end radar 5839812 - location for synthesized methods  */

  body = c_begin_compound_stmt (true);
  add_stmt (build_function_call
	    (execclass_decl,
	     build_tree_list
	     (NULL_TREE,
	      build_unary_op (ADDR_EXPR,
			      UOBJC_MODULES_decl, 0))));
  add_stmt (c_end_compound_stmt (body, true));

  TREE_PUBLIC (current_function_decl) = 0;

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

  GNU_INIT_decl = current_function_decl;
  finish_function ();

#ifdef OBJCPLUS
    pop_lang_context ();
#endif
}

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

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

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

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

  return ctors;
}
#endif /* OBJCPLUS */

/* Return the DECL of the string IDENT in the SECTION.  */
/* APPLE LOCAL begin radar 4359757 */
/* This routine has been rewritten for compile-time performance improvement. */

static tree
get_objc_string_decl (tree ident, enum string_section section)
{
  hash *hash_table;
  hash hsh;

  if (section == class_names)
    hash_table = class_names_hash_list;
  else if (section == meth_var_names)
    hash_table = meth_var_names_hash_list;
  else if (section == meth_var_types)
    hash_table = meth_var_types_hash_list;
  else if (section == prop_names_attr)
    hash_table = prop_names_attr_hash_list;
  else
    abort ();

  hsh = hash_ident_lookup (hash_table, ident);
  if (hsh)
    return hsh->list->value;

  abort ();
  return NULL_TREE;
}
/* APPLE LOCAL end radar 4359757 */

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

static void
generate_static_references (void)
{
  tree decls = NULL_TREE, expr = NULL_TREE;
  tree class_name, class, decl, initlist;
  tree cl_chain, in_chain, type
    = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
  int num_inst, num_class;
  char buf[256];

  if (flag_next_runtime)
    abort ();

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

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

      /* Output {class_name, ...}.  */
      class = TREE_VALUE (cl_chain);
      class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
      initlist = build_tree_list (NULL_TREE,
				  build_unary_op (ADDR_EXPR, class_name, 1));

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

      /* Output {..., NULL}.  */
      /* APPLE LOCAL radar 6285794 */
      initlist = tree_cons (NULL_TREE, integer_zero_node, initlist);

      expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
      finish_var_decl (decl, expr);
      decls
	= tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
    }

  /* APPLE LOCAL radar 6285794 */
  decls = tree_cons (NULL_TREE, integer_zero_node, decls);
  expr = objc_build_constructor (type, nreverse (decls));
  static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
  finish_var_decl (static_instances_decl, expr);
}

/* APPLE LOCAL begin radar 4349690 */
/* MERGE FIXME 5416374 See how

   2005-08-31  Andrew Pinski  <pinskia@physics.uc.edu> PR objc/23306

   Updated the code to not need update_var_decl and transform leftover code to use that strategy.  */

/* This routine is used to get finish_decl to install an initializer for this 
   forward definition and get the declaration resent to the backend.  After 
   this is called, finish_decl or finish_var_decl must be used. */

static tree
update_var_decl (tree decl)
{
  DECL_INITIAL (decl) = error_mark_node;
  DECL_EXTERNAL (decl) = 0;
  TREE_STATIC (decl) = 1;
  TREE_ASM_WRITTEN (decl) = 0;
  return decl;
}
/* APPLE LOCAL end radar 4349690 */

/* APPLE LOCAL begin ObjC new abi */
static GTY(()) int classlist_reference_idx;

/* This routine creates a global variable of type 'Class' to hold address of a
   class. */

static tree
build_classlist_reference_decl (void)
{
  tree decl;
  char buf[256];

  sprintf (buf, "_OBJC_CLASSLIST_REFERENCES_$_%d", classlist_reference_idx++);
  decl = start_var_decl (objc_class_type, buf);

  return decl;
}

/* 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[BUFSIZE];
  sprintf (string, "%s_%s", !metaclass ? "OBJC_CLASS_$" 
				       : "OBJC_METACLASS_$", 
			    IDENTIFIER_POINTER (ident));
  return string;
}

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

static void
build_classlist_translation_table (bool metaclass_chain)
{
  tree chain;

  for (chain = !metaclass_chain ? classlist_ref_chain 
			        : metaclasslist_ref_chain; 
       chain; chain = TREE_CHAIN (chain))
    {
      tree expr = TREE_VALUE (chain);
      tree decl = TREE_PURPOSE (chain);
      /* 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)
        {
          expr = create_extern_decl (objc_v2_class_template,
				     objc_build_internal_classname (expr, metaclass_chain));
	  expr = convert (objc_class_type, build_fold_addr_expr (expr));
	}
      finish_var_decl (decl, expr);
      /* LLVM LOCAL begin - radar 5720120 */
#ifdef ENABLE_LLVM
      /* Reset the initializer for this reference as it most likely changed.  */
      if (!optimize)
        reset_initializer_llvm(decl);
#endif
      /* LLVM LOCAL end - radar 5720120 */
    }
}

/* APPLE LOCAL begin radar 4561192 */
/* Set the alignment to __attribute__ ((size_of_el_type)) */

static void
objc_set_alignment_attribute (tree decl, tree el_type)
{
  int int_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (el_type));
  tree size = build_int_cst (NULL_TREE, int_size);
  tree attribute = build_tree_list (get_identifier ("aligned"),
				    build_tree_list (NULL_TREE, size));
  decl_attributes (&decl, attribute, 0);
  return;
}
/* APPLE LOCAL end radar 4561192 */

/* Build the __class_list section table containing address of all @implemented class 
   meta-data. */

static void
build_class_list_address_table (bool nonlazy)
{
  tree chain;
  int count=0;
  tree type;
  tree initlist = NULL_TREE;
  tree decl;
  tree expr;
  tree list_chain = nonlazy ? nonlazy_class_list_chain : class_list_chain;
  const char *label_name = nonlazy ? "_OBJC_LABEL_NONLAZY_CLASS_$" 
			     	   : "_OBJC_LABEL_CLASS_$";

  for (chain = list_chain; chain; chain = TREE_CHAIN (chain))
    {
      tree purpose = NULL_TREE;
      expr = TREE_VALUE (chain);
      expr = convert (objc_class_type, build_fold_addr_expr (expr));
#ifndef OBJCPLUS
      purpose = build_int_cst (NULL_TREE, count);
#endif
      ++count;
      initlist = tree_cons (purpose, expr, initlist);
    }
  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, label_name);
  expr = objc_build_constructor (type, nreverse (initlist));
  /* APPLE LOCAL radar 4561192 */
  objc_set_alignment_attribute (decl, objc_class_type);
  finish_var_decl (decl, expr);
}

/* Build the __category_list (NONLAZY is false) or __nonlazy_category (NONLAZY is true)
   section table containing address of all @implemented category meta-data. */

static void
build_category_list_address_table (bool nonlazy)
{
  tree chain;
  int count=0;
  tree type;
  tree initlist = NULL_TREE;
  tree decl;
  tree expr;
  tree list_chain = nonlazy ? nonlazy_category_list_chain : category_list_chain;
  const char * label_name = nonlazy ? "_OBJC_LABEL_NONLAZY_CATEGORY_$" 
			      	    : "_OBJC_LABEL_CATEGORY_$";

  for (chain = list_chain; chain; chain = TREE_CHAIN (chain))
    {
      tree purpose = NULL_TREE;
      expr = TREE_VALUE (chain);
      expr = convert (objc_class_type, build_fold_addr_expr (expr));
#ifndef OBJCPLUS
      purpose = build_int_cst (NULL_TREE, count);
#endif
      ++count;
      initlist = tree_cons (purpose, expr, initlist);
    }
  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, label_name);
  expr = objc_build_constructor (type, nreverse (initlist));
  /* APPLE LOCAL radar 4561192 */
  objc_set_alignment_attribute (decl, objc_class_type);
  finish_var_decl (decl, expr);
}
/* APPLE LOCAL end ObjC new abi */

static GTY(()) int selector_reference_idx;

static tree
build_selector_reference_decl (void)
{
  tree decl;
  char buf[256];

  sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
  decl = start_var_decl (objc_selector_type, buf);

  return decl;
}

static void
build_selector_table_decl (void)
{
  tree temp;

  if (flag_typed_selectors)
    {
      build_selector_template ();
      temp = build_array_type (objc_selector_template, NULL_TREE);
    }
  else
    temp = build_array_type (objc_selector_type, NULL_TREE);

  UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
}

/* Just a handy wrapper for add_objc_string.  */

static tree
build_selector (tree ident)
{
  return convert (objc_selector_type,
		  add_objc_string (ident, meth_var_names));
}

static void
build_selector_translation_table (void)
{
  tree chain, initlist = NULL_TREE;
  int offset = 0;
  tree decl = NULL_TREE;

  for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
    {
      tree expr;

      if (warn_selector && objc_implementation_context)
      {
        tree method_chain;
        bool found = false;
        for (method_chain = meth_var_names_chain;
             method_chain;
             method_chain = TREE_CHAIN (method_chain))
          {
            if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
              {
                found = true;
                break;
              }
          }
        if (!found)
	  {
	    location_t *loc;
	    if (flag_next_runtime && TREE_PURPOSE (chain))
	      loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
	    else
	      loc = &input_location;
	    warning (0, "%Hcreating selector for nonexistent method %qE",
		     loc, TREE_VALUE (chain));
	  }
      }

      expr = build_selector (TREE_VALUE (chain));
      /* add one for the '\0' character */
      offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;

      if (flag_next_runtime)
	{
	  decl = TREE_PURPOSE (chain);
	  finish_var_decl (decl, expr);
          /* LLVM LOCAL begin - radar 5676233 */
#ifdef ENABLE_LLVM
          /* Reset the initializer for this reference as it most likely
             changed.  */
          reset_initializer_llvm(decl);
#endif
          /* LLVM LOCAL end - radar 5676233 */
	}
      else
	{
	  if (flag_typed_selectors)
	    {
	      tree eltlist = NULL_TREE;
	      tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
	      eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
	      eltlist = tree_cons (NULL_TREE, encoding, eltlist);
	      expr = objc_build_constructor (objc_selector_template,
					     nreverse (eltlist));
	    }

	  initlist = tree_cons (NULL_TREE, expr, initlist);
	}
    }

  if (! flag_next_runtime)
    {
      /* Cause the selector table (previously forward-declared)
	 to be actually output.  */
      initlist = tree_cons (NULL_TREE,
			    flag_typed_selectors
			    ? objc_build_constructor
			      (objc_selector_template,
			       tree_cons (NULL_TREE,
					  /* APPLE LOCAL radar 6285794 */
					  integer_zero_node,
					  tree_cons (NULL_TREE,
						     /* APPLE LOCAL radar 6285794 */
						     integer_zero_node,
						     NULL_TREE)))
			    /* APPLE LOCAL radar 6285794 */
			    : integer_zero_node, initlist);
      initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
					 nreverse (initlist));
      finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
    }
}

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

      return add_objc_string (encoding, meth_var_types);
    }
  else
    /* APPLE LOCAL radar 6285794 */
    return integer_zero_node;
}

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

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

  while (*chain)
    {
      if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
	goto return_at_index;

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

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

 return_at_index:
  expr = build_unary_op (ADDR_EXPR,
			 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
					  build_int_cst (NULL_TREE, index)),
			 1);
  return convert (objc_selector_type, expr);
}

/* APPLE LOCAL begin radar 4359757 */
/* New routine replacing old build_selector_reference to improve 
   compile-time performance. */
static tree
build_next_runtime_selector_reference (tree ident)
{
  hash hsh;
  tree *chain = &sel_ref_chain;
  tree expr;

  hsh = hash_ident_lookup (sel_ref_hash_list, ident);
  if (hsh)
    return hsh->list->value;

  expr = build_selector_reference_decl ();
  hsh = hash_ident_enter (sel_ref_hash_list, ident);
  hash_add_attr (hsh, expr);

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

  return expr;
}

static tree
build_selector_reference (tree ident)
{
  tree *chain = &sel_ref_chain;
  tree expr;
  int index = 0;

  while (*chain)
    {
      if (TREE_VALUE (*chain) == ident)
	return build_array_ref (UOBJC_SELECTOR_TABLE_decl,
				build_int_cst (NULL_TREE, index));

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

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

  return build_array_ref (UOBJC_SELECTOR_TABLE_decl,
			  build_int_cst (NULL_TREE, index));
}
/* APPLE LOCAL end radar 4359757 */

/* APPLE LOCAL begin ObjC new abi */
/* Declare a variable of type 'struct message_ref_t'. */

static GTY(()) int message_reference_idx;

/* APPLE LOCAL begin radar 5575115 - radar 6064186 */
static tree
build_message_reference_decl (tree sel_name, tree message_func_ident)
{
  tree decl;
  char *buf;
  char *temp;
  int fixed_prefix_size = 
        2 + IDENTIFIER_LENGTH (message_func_ident) + 1;
  buf = (char *)alloca (fixed_prefix_size + 
                        strlen (IDENTIFIER_POINTER (sel_name)) + 1);
  sprintf (buf, "l_%s_%s", IDENTIFIER_POINTER (message_func_ident),
		IDENTIFIER_POINTER (sel_name));
  for (temp = buf+fixed_prefix_size; *temp; temp++)
    if (*temp == ':') *temp = '_';

  decl = create_hidden_decl (objc_v2_message_ref_template, buf);
  DECL_WEAK (decl) = 1;
  /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
  /* These are 4-byte aligned in 32-bit, 16-byte in 64-bit, which does not
     follow from the alignments of the component types. */
  DECL_ALIGN(decl) = BITS_PER_WORD==32 ? 32 : 128;
  DECL_USER_ALIGN(decl) = 1;
#endif
  /* LLVM LOCAL end */
  set_user_assembler_name (decl, buf);
  return decl;
}
/* APPLE LOCAL end radar 5575115 - radar 6064186 */

/* 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_selector_messenger_reference (tree sel_name, tree message_func_decl)
{
  tree *chain = &message_ref_chain;
  tree mess_expr;

  while (*chain)
    {
      if (TREE_VALUE (*chain) == message_func_decl)
	{
	  if (TREE_CHAIN (*chain) && TREE_VALUE (TREE_CHAIN (*chain)) == sel_name)
	    return TREE_PURPOSE (*chain);
	}
      chain = &TREE_CHAIN (*chain);
    }

  /* APPLE LOCAL radar 5575115 - radar 6064186 */
  mess_expr = build_message_reference_decl (sel_name, DECL_NAME (message_func_decl));
  *chain = tree_cons (mess_expr, message_func_decl, NULL_TREE);

  chain = &TREE_CHAIN (*chain);

  *chain = tree_cons (NULL_TREE, sel_name, NULL_TREE);

  return mess_expr;
}

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

static void
build_message_ref_translation_table (void)
{
  tree chain;
  tree decl = NULL_TREE;
  for (chain = message_ref_chain; chain; chain = TREE_CHAIN (chain))
    {
      tree expr;
      tree fields;
      tree initializer = NULL_TREE;
      tree constructor;
      tree struct_type;

      decl = TREE_PURPOSE (chain);
      struct_type = TREE_TYPE (decl);
      fields = TYPE_FIELDS (struct_type);

      /* First 'IMP messenger' field */
      expr = build_unary_op (ADDR_EXPR, TREE_VALUE (chain), 0);
      /* APPLE LOCAL begin radar 4582204 */
      expr = convert (objc_v2_imp_type, expr);
      initializer = build_tree_list (NULL_TREE, expr);
      /* APPLE LOCAL end radar 4582204 */
    
      /* Next the 'SEL name' field */
      fields = TREE_CHAIN (fields);
      gcc_assert (TREE_CHAIN (chain));
      chain = TREE_CHAIN (chain);
      expr = build_selector (TREE_VALUE (chain));
      /* APPLE LOCAL radar 4582204 */
      initializer = tree_cons (NULL_TREE, expr, initializer);
      constructor = objc_build_constructor (struct_type, nreverse (initializer));
      TREE_INVARIANT (constructor) = true;
      finish_var_decl (decl, constructor); 
      /* LLVM LOCAL begin - radar 5720120 */
#ifdef ENABLE_LLVM
      /* Reset the initializer for this reference as it most likely changed.  */
      reset_initializer_llvm(decl);
#endif
      /* LLVM LOCAL end - radar 5720120 */
    }
}

/* Assign all arguments in VALUES which have side-effect to a temporary and
   replaced that argument in VALUES list with the temporary. TYPELIST is the
   list of argument types. */

static tree
objc_copy_to_temp_side_effect_params (tree typelist, tree values)
{
  tree valtail, typetail;
  /* skip over receiver and the &_msf_ref types */
  gcc_assert (TREE_CHAIN (typelist));
  typetail = TREE_CHAIN (TREE_CHAIN (typelist));

  for (valtail = values;
       valtail; 
       valtail = TREE_CHAIN (valtail), typetail = TREE_CHAIN (typetail))
    {
      tree value = TREE_VALUE (valtail);
      tree type = typetail ? TREE_VALUE (typetail) : NULL_TREE;
      if (type == NULL_TREE)
	break; 
      if (!TREE_SIDE_EFFECTS (value))
	continue;
      /* To prevent reevaluation */
      value = save_expr (value);
      add_stmt (value);
      TREE_VALUE (valtail) = value;
    }
  return values;
}
/* APPLE LOCAL end ObjC new abi */

static GTY(()) int class_reference_idx;

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

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

  return decl;
}

/* Create a class reference, but don't create a variable to reference
   it.  */

static void
add_class_reference (tree ident)
{
  tree chain;

  if ((chain = cls_ref_chain))
    {
      tree tail;
      do
        {
	  if (ident == TREE_VALUE (chain))
	    return;

	  tail = chain;
	  chain = TREE_CHAIN (chain);
        }
      while (chain);

      /* Append to the end of the list */
      TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
    }
  else
    cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
}

/* APPLE LOCAL begin ObjC abi v2 */
/* This routine builds the class_reference_chain for each class name used
   in a [super class_name] message. IDENT is current a class's name. Initially,
   a (global_name, IDENT) tuple is added to the list. But in call to
   build_classlist_translation_table (), each IDENT is replaced with address of
   the class metadata (of type 'Class'). */

static tree
objc_v2_get_class_reference (tree ident)
{
  tree *chain;
  tree decl;

  for (chain = &classlist_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
    if (TREE_VALUE (*chain) == ident)
      {
        if (! TREE_PURPOSE (*chain))
          TREE_PURPOSE (*chain) = build_classlist_reference_decl ();

        return TREE_PURPOSE (*chain);
      }

  decl = build_classlist_reference_decl ();
  *chain = tree_cons (decl, ident, NULL_TREE);
  return decl;
}
/* APPLE LOCAL end ObjC abi v2 */

/* APPLE LOCAL begin radar 4535676 */

/* This routine creates a global variable of type 'Class' to hold address of a
   class. */

static tree
build_classlist_super_reference_decl (void)
{
  tree decl;
  char buf[256];

  sprintf (buf, "_OBJC_CLASSLIST_SUP_REFS_$_%d", classlist_reference_idx++);
  decl = start_var_decl (objc_class_type, buf);

  return decl;
}
/* This routine builds the class_super_ref_chain/metaclass_super_ref_chain 
   for each class name used in a [super class_name] message. IDENT is 
   current a class's name. Initially,
   a (global_name, IDENT) tuple is added to the list. But in call to
   build_classlist_translation_table (), each IDENT is replaced with address of
   the class metadata (of type 'Class'). */

static tree
objc_v2_get_class_super_reference (tree ident, bool inst)
{
  tree *chain;
  tree decl;

  for (chain = inst ? &classlist_super_ref_chain : &metaclasslist_super_ref_chain; 
       *chain; chain = &TREE_CHAIN (*chain))
    if (TREE_VALUE (*chain) == ident)
      {
        if (! TREE_PURPOSE (*chain))
          TREE_PURPOSE (*chain) = build_classlist_super_reference_decl ();

        return TREE_PURPOSE (*chain);
      }

  decl = build_classlist_super_reference_decl ();
  *chain = tree_cons (decl, ident, NULL_TREE);
  return decl;
}

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

static void
build_classlist_super_translation_table (bool metaclass_chain)
{
  tree chain;

  for (chain = !metaclass_chain ? classlist_super_ref_chain 
			        : metaclasslist_super_ref_chain; 
       chain; chain = TREE_CHAIN (chain))
    {
      tree expr = TREE_VALUE (chain);
      tree decl = TREE_PURPOSE (chain);
      /* 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)
        {
          expr = create_extern_decl (objc_v2_class_template,
				     objc_build_internal_classname (expr, metaclass_chain));
	  expr = convert (objc_class_type, build_fold_addr_expr (expr));
	}
      finish_var_decl (decl, expr);
      /* LLVM LOCAL begin - radar 5998983 */
#ifdef ENABLE_LLVM
      /* Reset the initializer for this reference as it most likely changed.  */
      if (!optimize)
        reset_initializer_llvm(decl);
#endif
      /* LLVM LOCAL end - radar 5998983 */
    }
}
/* APPLE LOCAL end radar 4535676 */

/* Get a class reference, creating it if necessary.  Also create the
   reference variable.  */

tree
objc_get_class_reference (tree ident)
{
  tree orig_ident = (DECL_P (ident)
		     ? DECL_NAME (ident)
		     : TYPE_P (ident)
		     ? OBJC_TYPE_NAME (ident)
		     : ident);
  bool local_scope = false;

  /* APPLE LOCAL begin prevent extra error diagnostics. */
  if (orig_ident == error_mark_node)
    return orig_ident;
  /* APPLE LOCAL end prevent extra error diagnostics. */

#ifdef OBJCPLUS
  if (processing_template_decl)
    /* Must wait until template instantiation time.  */
    return build_min_nt (CLASS_REFERENCE_EXPR, ident);
#endif

  if (TREE_CODE (ident) == TYPE_DECL)
    ident = (DECL_ORIGINAL_TYPE (ident)
	     ? DECL_ORIGINAL_TYPE (ident)
	     : TREE_TYPE (ident));

#ifdef OBJCPLUS
  if (TYPE_P (ident) && TYPE_CONTEXT (ident)
      && TYPE_CONTEXT (ident) != global_namespace)
    local_scope = true;
#endif

  if (local_scope || !(ident = objc_is_class_name (ident)))
    {
      error ("%qs is not an Objective-C class name or alias",
	     IDENTIFIER_POINTER (orig_ident));
      return error_mark_node;
    }

  /* APPLE LOCAL begin ObjC abi v2 */
  if (flag_objc_abi == 2 && !flag_zero_link)
    return objc_v2_get_class_reference (ident);
  /* APPLE LOCAL end ObjC abi v2 */
  if (flag_next_runtime && !flag_zero_link)
    {
      tree *chain;
      tree decl;

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

	    return TREE_PURPOSE (*chain);
	  }

      decl = build_class_reference_decl ();
      *chain = tree_cons (decl, ident, NULL_TREE);
      return decl;
    }
  else
    {
      tree params;

      add_class_reference (ident);

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

      assemble_external (objc_get_class_decl);
      return build_function_call (objc_get_class_decl, params);
    }
}

/* APPLE LOCAL begin radar 4359757 */
/* New routine to do hash lookup keyed on IDENTIFIER node. */

static hash
hash_ident_lookup (hash *hashlist, tree sel_name)
{
  hash target;

  target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];

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

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

/* New routine to add IDENTIFIER node to hash table. */
static hash
hash_ident_enter (hash *hashlist, tree ident)
{
  hash obj;
  int slot = hash_func (ident) % SIZEHASHTABLE;

  obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
  obj->list = 0;
  obj->next = hashlist[slot];
  obj->key = ident;

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

/* For each string section we have a chain which maps identifier nodes
   to decls for the strings.  */

static tree
add_objc_string (tree ident, enum string_section section)
{
  /* APPLE LOCAL do not create an unreferenced decl */
  tree *chain, decl, type, string_expr, sectionname;
  hash *hash_table;
  hash hsh;

  if (section == class_names)
    {
      chain = &class_names_chain;
      hash_table = class_names_hash_list;
    }
  else if (section == meth_var_names)
    {
      chain = &meth_var_names_chain;
      hash_table = meth_var_names_hash_list;
    }
  else if (section == meth_var_types)
    {
      chain = &meth_var_types_chain;
      hash_table = meth_var_types_hash_list;
    }
  else if (section == prop_names_attr)
    {
      chain = &prop_names_attr_chain;
      hash_table = prop_names_attr_hash_list;
    }
  else
    abort ();

  hsh = hash_ident_lookup (hash_table, ident);
  if (hsh)
    return convert (string_type_node, 
		    build_unary_op (ADDR_EXPR, hsh->list->value, 1));

  /* APPLE LOCAL do not create an unreferenced decl */
  sectionname = build_objc_string_ident (section);

  type = build_array_type
	 (char_type_node,
	  build_index_type
	  (build_int_cst (NULL_TREE,
			  IDENTIFIER_LENGTH (ident))));
  /* APPLE LOCAL do not create an unreferenced decl */
  decl = start_var_decl (type, IDENTIFIER_POINTER (sectionname));
  string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
				 IDENTIFIER_POINTER (ident));
  finish_var_decl (decl, string_expr);

  hsh = hash_ident_enter (hash_table, ident);
  hash_add_attr (hsh, decl);
  *chain = tree_cons (decl, ident, *chain);

  return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
}
/* APPLE LOCAL end radar 4359757 */

static GTY(()) int class_names_idx;
static GTY(()) int meth_var_names_idx;
static GTY(()) int meth_var_types_idx;
/* APPLE LOCAL C* property metadata (Radar 4498373) */
static GTY(()) int property_name_attr_idx;

static tree
/* APPLE LOCAL do not create an unreferenced decl */
build_objc_string_ident (enum string_section section)
{
/* APPLE LOCAL begin do not create an unreferenced decl */
/* APPLE LOCAL end do not create an unreferenced decl */
  char buf[256];

  if (section == class_names)
    sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
  else if (section == meth_var_names)
    sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
  else if (section == meth_var_types)
    sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
  /* APPLE LOCAL begin C* property metadata (Radar 4498373) */
  else if (section == prop_names_attr)
    sprintf (buf, "_OBJC_PROP_NAME_ATTR_%d", property_name_attr_idx++);
  /* APPLE LOCAL end C* property metadata (Radar 4498373) */
  /* APPLE LOCAL begin do not create an unreferenced decl */
  return get_identifier (buf);
  /* APPLE LOCAL end do not create an unreferenced decl */
}


void
objc_declare_alias (tree alias_ident, tree class_ident)
{
  tree underlying_class;

#ifdef OBJCPLUS
  if (current_namespace != global_namespace) {
    error ("Objective-C declarations may only appear in global scope");
  }
#endif /* OBJCPLUS */

  if (!(underlying_class = objc_is_class_name (class_ident)))
    warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
  else if (objc_is_class_name (alias_ident))
    warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
  else
    {
      /* Implement @compatibility_alias as a typedef.  */
#ifdef OBJCPLUS
      push_lang_context (lang_name_c); /* extern "C" */
#endif
      lang_hooks.decls.pushdecl (build_decl
				 (TYPE_DECL,
				  alias_ident,
				  xref_tag (RECORD_TYPE, underlying_class)));
#ifdef OBJCPLUS
      pop_lang_context ();
#endif
      /* APPLE LOCAL begin radar 4345837 */
      hash_class_name_enter (als_name_hash_list, alias_ident, 
			     underlying_class);
      /* APPLE LOCAL end radar 4345837 */
    }
}

void
objc_declare_class (tree ident_list)
{
  tree list;
#ifdef OBJCPLUS
  if (current_namespace != global_namespace) {
    error ("Objective-C declarations may only appear in global scope");
  }
#endif /* OBJCPLUS */

  for (list = ident_list; list; list = TREE_CHAIN (list))
    {
      tree ident = TREE_VALUE (list);

      if (! objc_is_class_name (ident))
	{
	  tree record = lookup_name (ident), type = record;

	  if (record)
	    {
	      if (TREE_CODE (record) == TYPE_DECL)
	      /* APPLE LOCAL begin radar 4278236 */
		type = DECL_ORIGINAL_TYPE (record) ? 
			DECL_ORIGINAL_TYPE (record) : 
			TREE_TYPE (record);
	      /* APPLE LOCAL end radar 4278236 */

	      /* APPLE LOCAL radar 4829851 */
	      if (TREE_CODE (type) != RECORD_TYPE || !TYPE_HAS_OBJC_INFO (type)
		  || !TYPE_OBJC_INTERFACE (type))
		{
		  error ("%qs redeclared as different kind of symbol",
			 IDENTIFIER_POINTER (ident));
		  error ("previous declaration of %q+D",
			 record);
		}
	    }

	  record = xref_tag (RECORD_TYPE, ident);
	  INIT_TYPE_OBJC_INFO (record);
	  TYPE_OBJC_INTERFACE (record) = ident;
	  /* APPLE LOCAL radar 4345837 */
	  hash_class_name_enter (cls_name_hash_list, ident, NULL_TREE);
	}
    }
}

tree
objc_is_class_name (tree ident)
{
  /* APPLE LOCAL radar 4345837 */
  hash target;

  if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
      && identifier_global_value (ident))
    ident = identifier_global_value (ident);
  while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
    ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));

  if (ident && TREE_CODE (ident) == RECORD_TYPE)
    ident = OBJC_TYPE_NAME (ident);
#ifdef OBJCPLUS
  if (ident && TREE_CODE (ident) == TYPE_DECL)
    /* APPLE LOCAL begin radar 4407151 */
    {
      tree type = TREE_TYPE (ident);
      if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
        return NULL_TREE;
      ident = DECL_NAME (ident);
    }
    /* APPLE LOCAL end radar 4407151 */
#endif
  if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
    return NULL_TREE;

  if (lookup_interface (ident))
    return ident;
  /* APPLE LOCAL begin radar 4345837 */
  target = hash_class_name_lookup (cls_name_hash_list, ident);
  if (target)
    return target->key;

  target = hash_class_name_lookup (als_name_hash_list, ident);
  if (target)
    {
      gcc_assert (target->list && target->list->value);
      return target->list->value;
    }
  /* APPLE LOCAL end radar 4345837 */

  return 0;
}

/* Check whether TYPE is either 'id' or 'Class'.  */

tree
objc_is_id (tree type)
{
  if (type && TREE_CODE (type) == IDENTIFIER_NODE
      && identifier_global_value (type))
    type = identifier_global_value (type);

  if (type && TREE_CODE (type) == TYPE_DECL)
    type = TREE_TYPE (type);

  /* NB: This function may be called before the ObjC front-end has
     been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL.  */
  return (objc_object_type && type
	  && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
	  ? type
	  : NULL_TREE);
}

/* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
   class instance.  This is needed by other parts of the compiler to
   handle ObjC types gracefully.  */

tree
objc_is_object_ptr (tree type)
{
  tree ret;
  /* APPLE LOCAL begin radar 5595325 */
  if (objc_nsobject_attribute_type (type))
    return TREE_TYPE (type);
  /* APPLE LOCAL end radar 5595325 */

  type = TYPE_MAIN_VARIANT (type);
  if (!POINTER_TYPE_P (type))
    return 0;

  ret = objc_is_id (type);
  if (!ret)
    /* APPLE LOCAL ObjC GC */
    ret = objc_is_class_name (TYPE_MAIN_VARIANT (TREE_TYPE (type)));

  return ret;
}

/* APPLE LOCAL begin ObjC GC */
/* Return 1 if TYPE should be garbage collected, -1 if has __weak attribut
   and 0 otherwise.  Types marked with the '__strong' attribute are GC-able, 
   whereas those marked with __weak' are not.  Types marked with neither 
   attribute are GC-able if (a) they are Objective-C pointer types or (b) 
   they are pointers to types that are themselves GC-able.  */

/* APPLE LOCAL end ObjC GC */
/* APPLE LOCAL radar 5847976 */
int
/* APPLE LOCAL ObjC GC */
objc_is_gcable_type (tree type)
{
  /* APPLE LOCAL begin objc gc 5547128 */
  int strong;
  /* APPLE LOCAL end objc gc 5547128 */

  /* APPLE LOCAL ObjC GC */
  /* CODE FRAGMENT REMOVED.  */
  /* APPLE LOCAL begin radar 4829803 */
  if (!TYPE_P (type) 
#ifdef OBJCPLUS
      || type_unknown_p (type)
#endif
     )
  /* APPLE LOCAL end radar 4829803 */
    return 0;
  /* APPLE LOCAL begin ObjC GC */

  /* APPLE LOCAL objc gc 5547128 */
  strong = 0;
  do
    {
      /* The '__strong' and '__weak' keywords trump all.  */
      /* APPLE LOCAL objc gc 5547128 */
      strong = objc_is_strong_p (type);

      /* APPLE LOCAL begin radar 4426814 */
      if (strong)
	/* APPLE LOCAL objc gc 5547128 */
	break;
      /* APPLE LOCAL end radar 4426814 */

      /* APPLE LOCAL begin objc gc 5547128 */
      /* Function pointers are not GC-able.  */
      if (TREE_CODE (type) == FUNCTION_TYPE
	  || TREE_CODE (type) == METHOD_TYPE)
	break;
      /* APPLE LOCAL end objc gc 5547128 */

      /* Objective-C objects are GC-able, unless they were tagged with
	 '__weak'.  */
      if (objc_is_object_ptr (type))
 	/* APPLE LOCAL radar 4426814 */
	/* APPLE LOCAL begin objc gc 5547128 */
	{
	  strong = (objc_is_strong_p (TREE_TYPE (type)) >= 0 ? 1 : -1);
	  break;
	}
      /* APPLE LOCAL begin radar 5882266, 5832193 */
      /* Block pointer types are GC-able, unless they were tagged with
         '__weak' */
      if (TREE_CODE (type) == BLOCK_POINTER_TYPE)
        {
	  strong = block_pointer_strong_value (type);
          break;
        }
      /* APPLE LOCAL end radar 5882266, 5832193 */
      /* APPLE LOCAL end objc gc 5547128 */

      type = TREE_TYPE (type);
    }
  while (type);

  /* APPLE LOCAL objc gc 5547128 */
  return strong;
}
/* APPLE LOCAL end ObjC GC */
/* APPLE LOCAL begin radar 4982951 */
/* This routine retrievs the outervar of the objc2 tree EXPR representing address of an ivar.
   Tree EXPR is in the form of ((*typeof ivar)(OUTERVAR + OBJC2_IVAR_OFFSET_VAR)).
   It returns OUTERVAR. Note that input EXPR tree is already validate via call to
   objc_v2_ivar_reference. So no additional checking is done in this routine. */
static
tree objc2_outervar (tree expr)
{
  gcc_assert (TREE_CODE (expr) == NOP_EXPR);
  expr = TREE_OPERAND (expr, 0);
  gcc_assert (TREE_CODE (expr) == PLUS_EXPR);
  return TREE_OPERAND (expr, 0);
}

/* This routine builds * ((typeof (INDIR)*) 0 + OFFSET)
   This tree corresponds to * (&((typeof(outervar) *) 0)->ivar) in 'fragile' objc1
   abi. (see comment in objc_build_ivar_assignment)
*/

static tree
objc2_build_indirect_ref_ivar2 (tree indir, tree offset, tree newoutervar)
{
  tree ftype = TREE_TYPE (indir);
  tree expr = build_c_cast (string_type_node, newoutervar);
  /* (char*)newoutervar + offset */
  expr = fold (build2 (PLUS_EXPR, string_type_node, expr, offset));

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

  /* Finally: *(ftype*)((char*)newoutervar + offset) */
  expr = build_indirect_ref (expr, "unary *");
  return expr;
}	/* This comment appeases the checklocal daemon.  */
/* APPLE LOCAL end radar 4982951 */

/* LLVM LOCAL - begin pointer arithmetic */
#ifdef ENABLE_LLVM
/* llvm-gcc intentionally preserves array notation &array[i] and avoids
   pointer arithmetic.

   Example 1: struct { int *a; } *b;    b->a[2] = 42;
   Example 2: struct { int a[42]; } *b;  b->a[2] = 42;

   In both of this cases, expr is preserved as ARRAY_REF. Normally, gcc
   would decomponse first example into a pointer arithmetic expression.
   So in llvm mode, check expression's field type to ensure that this is really
   an array reference or not.  */
static int objc_is_really_array_ref(tree expr) {
  tree base = NULL_TREE;

  if (TREE_CODE(expr) != ARRAY_REF)
    return 0;

  base = TREE_OPERAND(expr, 0);
  return base && TREE_CODE(TREE_TYPE(base)) == ARRAY_TYPE;
}
#endif
/* LLVM LOCAL - end pointer arithmetic */

static tree
objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
{
  if (expr == oldexpr)
    return newexpr;

  switch (TREE_CODE (expr))
    {
    case COMPONENT_REF:
      return objc_build_component_ref
	     (objc_substitute_decl (TREE_OPERAND (expr, 0),
				    oldexpr,
				    newexpr),
	      DECL_NAME (TREE_OPERAND (expr, 1)));
    /* LLVM LOCAL - begin pointer arithmetic */
#ifndef ENABLE_LLVM
    case ARRAY_REF:
      return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
						    oldexpr,
						    newexpr),
			      TREE_OPERAND (expr, 1));
#else
    /* Moved ARRAY_REF to "default" case */
#endif
    /* LLVM LOCAL - end pointer arithmetic */
    case INDIRECT_REF:
      /* APPLE LOCAL begin radar 4982951 */
      {
        tree ivar_offset_var;
        ivar_offset_var = objc_v2_ivar_reference (expr);
        if (ivar_offset_var != NULL_TREE)
          return objc2_build_indirect_ref_ivar2 (expr, ivar_offset_var, newexpr);
      }
      /* APPLE LOCAL end radar 4982951 */
      return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
						       oldexpr,
						       newexpr), "->");
    default:
      /* LLVM LOCAL - begin pointer arithmetic */
#ifdef ENABLE_LLVM
      if (objc_is_really_array_ref(expr))
        return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
                                                      oldexpr,
                                                      newexpr),
                                TREE_OPERAND (expr, 1));
#endif
      /* LLVM LOCAL - end pointer arithmetic */
      return expr;
    }
}

static tree
/* APPLE LOCAL radar 4995066 */
objc_build_ivar_assignment (tree outervar, bool objc2_ivar_ref, tree lhs, tree rhs)
{
  tree func_params;
  /* The LHS parameter contains the expression 'outervar->memberspec';
     we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
     where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
  */
  /* APPLE LOCAL begin radar 4783068 */
  tree offs, func;
  int save_warn_invalid_offsetof = warn_invalid_offsetof;
  warn_invalid_offsetof = 0;
  /* APPLE LOCAL begin radar 4982951 */
  /* APPLE LOCAL radar 4995066 */
  if (flag_objc_abi == 2 && objc2_ivar_ref)
    outervar = objc2_outervar (outervar);
  /* APPLE LOCAL end radar 4982951 */
  offs
    = objc_substitute_decl
      (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
  warn_invalid_offsetof = save_warn_invalid_offsetof;
  /* APPLE LOCAL radar 4590221 */
  func = objc_assign_ivar_decl;
  /* APPLE LOCAL end radar 4783068 */

  /* APPLE LOCAL objc gc 5547128 */
  offs = convert (ptrdiff_type_node, build_unary_op (ADDR_EXPR, offs, 0));
  offs = fold (offs);
  func_params = tree_cons (NULL_TREE,
	convert (objc_object_type, rhs),
	    tree_cons (NULL_TREE, convert (objc_object_type, outervar),
		tree_cons (NULL_TREE, offs,
		    NULL_TREE)));

  assemble_external (func);
  return build_function_call (func, func_params);
}

static tree
/* APPLE LOCAL radar 4426814 */
objc_build_global_assignment (tree lhs, tree rhs, int strong)
{
  tree func_params = tree_cons (NULL_TREE,
	convert (objc_object_type, rhs),
	    tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
		      build_unary_op (ADDR_EXPR, lhs, 0)),
		    NULL_TREE));
  /* APPLE LOCAL begin radar 4426814 */
  tree func = (strong == 1) ? objc_assign_global_decl : objc_assign_weak_decl;

  assemble_external (func);
  return build_function_call (func, func_params);
}
/* APPLE LOCAL end radar 4426814 */

/* APPLE LOCAL begin radar 4426814 */

/* APPLE LOCAL begin radar 4591756 */
/* This routine generates call to objc_read_weak (&EXPR);  */

static tree
objc_build_weak_read (tree expr)
{
  tree func_params;
  expr = build_unary_op (ADDR_EXPR, expr, 1);
  expr = convert (build_pointer_type (objc_object_type), expr);
  func_params = tree_cons (NULL_TREE, expr, NULL_TREE);

  assemble_external (objc_read_weak_decl);
  return build_function_call (objc_read_weak_decl, func_params);
}
/* APPLE LOCAL end radar 4591756 */

/* APPLE LOCAL begin radar 5276085 */
/* Return TRUE if EXPR is a 'weak' expression */
static bool
objc_tree_is_weak_expr (tree expr)
{
#ifdef OBJCPLUS
  if (processing_template_decl)
    return false;
#endif
  if (skip_evaluation || TREE_CODE (expr) == OBJC_WEAK_REFERENCE_EXPR
      || TREE_TYPE (expr) == NULL_TREE)
    return false;

  return (objc_is_gcable_p (expr) == -1);
}

/* This routine builds a tree referencing the 'weak' object pointer expression */
tree
objc_build_weak_reference_tree (tree expr)
{
  /* APPLE LOCAL begin radar 5847976 */
  if (!flag_objc_gc)
    return expr;
  /* APPLE LOCAL end radar 5847976 */
  return objc_tree_is_weak_expr (expr) ?
         build1 (OBJC_WEAK_REFERENCE_EXPR, TREE_TYPE (expr), expr) : expr;
}

/* Return 'weak' reference object pointer expression */
void
objc_weak_reference_expr (tree *ref)
{
  tree expr = *ref;
  if (expr && TREE_CODE (expr) == OBJC_WEAK_REFERENCE_EXPR)
    *ref = TREE_OPERAND (expr, 0);
}
/* APPLE LOCAL end radar 5276085 */
/* APPLE LOCAL end radar 4426814 */


static tree
objc_build_strong_cast_assignment (tree lhs, tree rhs)
{
  /* APPLE LOCAL begin objc gc 5547128 */
  tree func_params
    = tree_cons (NULL_TREE,
		 convert (objc_object_type, rhs),
		 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
						build_unary_op (ADDR_EXPR, lhs, 0)),
			    NULL_TREE));
  /* APPLE LOCAL end objc gc 5547128 */

  assemble_external (objc_assign_strong_cast_decl);
  return build_function_call (objc_assign_strong_cast_decl, func_params);
}

/* APPLE LOCAL begin radar 4592503 */
/* This routine checks to see if a local variable or a structure field
   has __weak attribute and issues warning in that case.  */
void
objc_checkon_weak_attribute (tree decl)
{
  /* APPLE LOCAL begin radar 5747976 */
  if (!flag_objc_gc)
    return;
  /* APPLE LOCAL end radar 5747976 */
  if (decl && DECL_P (decl))
    {
      if (objc_collecting_ivars
	  || (TREE_CODE (decl) == VAR_DECL
	      && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))))
	return;

      /* APPLE LOCAL radar 5847976 */
      if ((TREE_CODE (decl) == FIELD_DECL || (TREE_CODE (decl) == VAR_DECL && !COPYABLE_BYREF_LOCAL_VAR (decl)))
	  && objc_is_gcable_type (TREE_TYPE (decl)) == -1)
	{
	  location_t saved_location = input_location;
	  input_location = DECL_SOURCE_LOCATION (decl);
	  warning (0, "__weak attribute cannot be specified on a %s declaration",
		   TREE_CODE (decl) == FIELD_DECL ? "field" : "local object");
	  input_location = saved_location;
	  return;
	}
    }
}

/* APPLE LOCAL end radar 4592503 */

/* APPLE LOCAL begin radar 3742561 */
/* This routine build a call to void *objc_memmove_collectable (&LHS, &RHS, sizeof(TYPE))
*/
static tree
objc_build_memmove_collectable (tree lhs, tree rhs, tree type)
{
  tree arg1 = convert (ptr_type_node, build_unary_op (ADDR_EXPR, lhs, 1));
  tree arg2 = convert (ptr_type_node, build_unary_op (ADDR_EXPR, rhs, 1));
  int size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
  tree arg3 = build_int_cst (NULL_TREE, size);
  tree func_params = tree_cons (NULL_TREE, arg1,
		       tree_cons (NULL_TREE, arg2,
		         tree_cons (NULL_TREE, arg3, NULL_TREE)));
  assemble_external (objc_memmove_collectable_decl);
  return build_function_call (objc_memmove_collectable_decl, func_params);  
}

/* Check aggregate type and return 1 if it contains a field of object pointer type or one
   whose pointer type is '__strong'. */

static int
objc_aggr_type_strong (tree aggr_type)
{
  tree  fieldlist, field_decl;

  if (!flag_objc_gc && !flag_objc_gc_only)
    return 0;

  gcc_assert (TREE_CODE (aggr_type) == RECORD_TYPE 
	      || TREE_CODE (aggr_type) == UNION_TYPE);

  fieldlist = TYPE_FIELDS (aggr_type);

  for (field_decl = fieldlist; field_decl; field_decl = TREE_CHAIN (field_decl))
  {
    if (TREE_TYPE (field_decl) == error_mark_node)
      continue;

    if (field_decl && TREE_CODE (field_decl) == FIELD_DECL
        && DECL_NAME (field_decl) && !DECL_BIT_FIELD_TYPE (field_decl)
#ifdef OBJCPLUS
        && !TREE_STATIC (field_decl)
#endif
       )
    {
      tree field_type = TREE_TYPE (field_decl);
      if (TREE_CODE (field_type) == ARRAY_TYPE)
        {
	  /* Get element type of the array. */
	  field_type = TREE_TYPE (field_type);
	  while (TREE_CODE (field_type) == ARRAY_TYPE)
	    field_type = TREE_TYPE (field_type);
        }
      if (TREE_CODE (field_type) == RECORD_TYPE || TREE_CODE (field_type) == UNION_TYPE)
	{
	  if (objc_aggr_type_strong (field_type))
	    return 1;
	  else
	    continue;
	}
      if (objc_is_gcable_type (field_type) == 1)
	return 1;
      continue;
    }
  }
  return 0;
}
/* APPLE LOCAL end radar 3742561 */

/* APPLE LOCAL begin ObjC GC */
/* Return 1 if EXPR is marked with the __strong attribute, -1 if it is marked
   with the __weak attribute, and 0 if it is marked with neither (regardless
   if it is otherwise GC-able).  */

static int
objc_is_strong_p (tree expr)
{
  if (TYPE_P (expr) || DECL_P (expr))
    {
      tree attr = lookup_attribute ("objc_gc",
				    (TYPE_P (expr)
				     ? TYPE_ATTRIBUTES (expr)
				     : DECL_ATTRIBUTES (expr)));

      if (attr && TREE_VALUE (attr))
	{
	  if (TREE_VALUE (TREE_VALUE (attr)) == get_identifier ("strong"))
	    return 1;

	  if (TREE_VALUE (TREE_VALUE (attr)) == get_identifier ("weak"))
	    return -1;
	}
    }

  return 0;
}

/* Return 1 (__strong) if a call to a write-barrier should be generated when assigning
   to EXPR.  Return -1 if a call to objc_assign_weak should be generated when assigning
   to  EXPR with a __weak attribute; 0 otherwise. */

/* APPLE LOCAL end ObjC GC */
static int
objc_is_gcable_p (tree expr)
/* APPLE LOCAL begin ObjC GC */
{
  tree t = TREE_TYPE (expr);
  /* The '__strong' and '__weak' keywords trump all.  */
  int strong = objc_is_strong_p (t);

  /* APPLE LOCAL begin radar 4426814 */
  if (strong)
    return strong;
  /* APPLE LOCAL end radar 4426814 */

  /* Discard lvalue casts, if any.  */
  while (TREE_CODE (expr) == INDIRECT_REF
	 && TREE_CODE (TREE_OPERAND (expr, 0)) == NOP_EXPR
	 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)) == ADDR_EXPR)
    expr = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (expr, 0), 0), 0);

  /* Zero in on the variable/parameter being assigned to.  */
  /* LLVM LOCAL - begin pointer arithmetic */
#ifdef ENABLE_LLVM
  while (TREE_CODE (expr) == COMPONENT_REF || objc_is_really_array_ref(expr))
#else
  while (TREE_CODE (expr) == COMPONENT_REF || TREE_CODE (expr) == ARRAY_REF)
#endif
  /* LLVM LOCAL - end pointer arithmetic */
    expr = TREE_OPERAND (expr, 0);

  /* Parameters and local variables (and their fields) are NOT GC-able.  */
  if (TREE_CODE (expr) == PARM_DECL ||
      (TREE_CODE (expr) == VAR_DECL
       && DECL_CONTEXT (expr)
       && !TREE_STATIC (expr)))
    return 0;

  return objc_is_gcable_type (t);
}
/* APPLE LOCAL end ObjC GC */

/* APPLE LOCAL begin radar 4894756 */
/* This routine checks and returns true if tree is reference to an 'ivar' through the ivar offset
   variable reference. See objc_v2_build_ivar_ref for detail of how this tree is generated. */

static
tree objc_v2_ivar_reference (tree expr)
{
  if (flag_objc_abi < 2 || TREE_CODE (expr) != INDIRECT_REF)
    return NULL_TREE;
  expr = TREE_OPERAND (expr, 0);
  if (TREE_CODE (expr) != NOP_EXPR)
    return NULL_TREE;
  expr = TREE_OPERAND (expr, 0);
  if (TREE_CODE (expr) != PLUS_EXPR)
    return NULL_TREE;
  expr = TREE_OPERAND (expr, 1);

  return (TREE_CODE (expr) == VAR_DECL && DECL_NAME (expr)
          && strncmp (IDENTIFIER_POINTER (DECL_NAME (expr)), STRING_V2_IVAR_OFFSET_PREFIX,
                      strlen (STRING_V2_IVAR_OFFSET_PREFIX)) == 0) ? expr : NULL_TREE;
}
/* APPLE LOCAL end radar 4894756 */

/* APPLE LOCAL begin radar 4591756 */
static tree
objc_strip_off_indirection (tree expr)
{
  if ((TREE_CODE (expr) == INDIRECT_REF && (objc_v2_ivar_reference (expr) == NULL_TREE))
      || TREE_CODE (expr) == NOP_EXPR
      || TREE_CODE (expr) == ADDR_EXPR || TREE_CODE (expr) == PLUS_EXPR)
    return objc_strip_off_indirection (TREE_OPERAND (expr, 0));
  return expr;
}
/* APPLE LOCAL end radar 4591756 */

static int
objc_is_ivar_reference_p (tree expr)
{
  /* LLVM LOCAL - begin pointer arithmetic */
#ifdef ENABLE_LLVM
  return (objc_is_really_array_ref(expr) == 1 
#else
  return (TREE_CODE (expr) == ARRAY_REF
#endif
  /* LLVM LOCAL - end pointer arithmetic */
	  ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
	  : TREE_CODE (expr) == COMPONENT_REF
	  ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
	  /* APPLE LOCAL objc2 4894756 */
	  : (objc_v2_ivar_reference (expr) != NULL_TREE));
}

static int
objc_is_global_reference_p (tree expr)
{
  return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
	  ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
	  : DECL_P (expr)
	  ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
	  : 0);
}

tree
objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
{
  /* APPLE LOCAL begin ObjC GC */
  tree outer;
  int indirect_p = 0;
  /* APPLE LOCAL radar 4426814 */
  int strong;
  bool objc2_ivar_ref;
  /* APPLE LOCAL begin radar 3742561 */
  tree lhs_type = TREE_TYPE (lhs);
  if (TREE_CODE (lhs_type) == RECORD_TYPE || TREE_CODE (lhs_type) == UNION_TYPE)
    {
      strong = objc_aggr_type_strong (lhs_type);
      return strong ? objc_build_memmove_collectable (lhs, rhs, lhs_type) 
		    : NULL_TREE;
    }
  /* APPLE LOCAL end radar 3742561 */

  /* APPLE LOCAL begin objc gc 5547128 */
  /* Only pointers need barriers.  We can get here when
       __strong float *p; p[0] = 3.14;  */
  /* APPLE LOCAL begin radar 5832193 */
  if (TREE_CODE (lhs_type) != POINTER_TYPE
      && TREE_CODE (TREE_TYPE (rhs)) != POINTER_TYPE
      && TREE_CODE (lhs_type) != BLOCK_POINTER_TYPE
      && TREE_CODE (TREE_TYPE (rhs)) != BLOCK_POINTER_TYPE)
  /* APPLE LOCAL end radar 5832193 */
    return NULL_TREE;
  /* APPLE LOCAL end objc gc 5547128 */

  /* the lhs must be of a suitable type, regardless of its underlying
     structure.  Furthermore, __weak must not have been used.  */
  /* APPLE LOCAL radar 4426814 */
  if ((strong = objc_is_gcable_p (lhs)) == 0)
    return NULL_TREE;

  /* At this point, we are committed to using one of the write-barriers,
     unless the user is attempting to perform pointer arithmetic.  */
  /* APPLE LOCAL radar 4291099 */
  if (modifycode != NOP_EXPR && modifycode != INIT_EXPR)
    {
      warning (0, "pointer arithmetic for garbage-collected objects not allowed");
      return NULL_TREE;
    }
  /* APPLE LOCAL end ObjC GC */
  /* APPLE LOCAL radar 4291099 */
  gcc_assert (modifycode != INIT_EXPR || c_dialect_cxx ());

  /* APPLE LOCAL ObjC GC */
  /* CODE FRAGMENT REMOVED.  */
  outer = lhs;

  /* APPLE LOCAL begin radar 4591756 */
  if (strong == -1)
    outer = objc_strip_off_indirection (outer);
  /* APPLE LOCAL end radar 4591756 */
  while (outer
	 && (TREE_CODE (outer) == COMPONENT_REF
             /* LLVM LOCAL - begin pointer arithmetic */
#ifdef ENABLE_LLVM
             || objc_is_really_array_ref(outer)))
#else
	     || TREE_CODE (outer) == ARRAY_REF))
#endif
             /* LLVM LOCAL - end pointer arithmetic */
    outer = TREE_OPERAND (outer, 0);

  /* APPLE LOCAL objc2 */
  objc2_ivar_ref = objc_v2_ivar_reference (outer) != NULL_TREE;
  /* APPLE LOCAL objc2 */
  if (TREE_CODE (outer) == INDIRECT_REF && !objc2_ivar_ref)
    {
      outer = TREE_OPERAND (outer, 0);
      indirect_p = 1;
    }

  /* APPLE LOCAL ObjC GC */
  /* CODE FRAGMENT REMOVED.  */

  /* Handle ivar assignments. */
  /* APPLE LOCAL begin ObjC GC */
  /* APPLE LOCAL begin radar 4591756 */
  if (indirect_p && objc_is_ivar_reference_p (strong == -1 
						? objc_strip_off_indirection (lhs) 
						: lhs)
  /* APPLE LOCAL end radar 4591756 */
      && objc_is_object_ptr (TREE_TYPE (outer)))
  /* APPLE LOCAL end ObjC GC */
    {
      /* APPLE LOCAL ObjC GC */
      /* CODE FRAGMENT REMOVED.  */
      if (warn_assign_intercept)
	warning (0, "instance variable assignment has been intercepted");

      /* APPLE LOCAL begin radar 4426814 */
      /* APPLE LOCAL ObjC GC */
      return strong == 1 
		/* APPLE LOCAL radar 4995066 */
		? objc_build_ivar_assignment (outer, objc2_ivar_ref, lhs, rhs)
		: objc_build_global_assignment (lhs, rhs, strong);
      /* APPLE LOCAL end radar 4426814 */
    }
  /* APPLE LOCAL begin objc2 */
  if (!indirect_p && objc2_ivar_ref)
    {
      if (warn_assign_intercept)
	warning (0, "instance variable assignment has been intercepted");

      return strong == 1
		/* APPLE LOCAL radar 4995066 */
		? objc_build_ivar_assignment (TREE_OPERAND (outer, 0), objc2_ivar_ref, lhs, rhs)
	        : objc_build_global_assignment (lhs, rhs, strong);
    }
  /* APPLE LOCAL end objc2 */
  /* Likewise, intercept assignment to global/static variables if their type is
     GC-marked.  */
  /* APPLE LOCAL ObjC GC */
  if (!indirect_p && objc_is_global_reference_p (outer))
    {
      /* APPLE LOCAL ObjC GC */
      /* CODE FRAGMENT REMOVED.  */
      /* APPLE LOCAL begin confused diff */
      if (warn_assign_intercept)
	warning (0, "global/static variable assignment has been intercepted");
      /* APPLE LOCAL end confused diff */

      /* APPLE LOCAL begin radar 4426814 */
      /* APPLE LOCAL ObjC GC */
      return objc_build_global_assignment (lhs, rhs, strong);
      /* APPLE LOCAL end radar 4426814 */
    /* APPLE LOCAL confused diff */
    }
  /* APPLE LOCAL begin radar 4426814 */
  if (strong == -1)
    {
      /* APPLE LOCAL begin radar 5847976 */
      /* Must generate write barrier for __block objects which are __weak
         and used in an assignment. */
      if (TREE_CODE (outer) == COMPONENT_REF && TREE_OPERAND (outer, 0)
	  && TREE_CODE (TREE_OPERAND (outer, 0)) == VAR_DECL)
        {
	  tree var_decl = TREE_OPERAND (outer, 0);
	  if (COPYABLE_WEAK_BLOCK (var_decl))
	    return objc_build_global_assignment (lhs, rhs, -1);
        }
      /* APPLE LOCAL end radar 5847976 */
      return NULL_TREE;
    }
  /* APPLE LOCAL end radar 4426814 */

  /* LLVM LOCAL - begin 5541393 */
#ifdef ENABLE_LLVM
  if (TREE_CODE(TREE_TYPE(lhs)) != POINTER_TYPE) return NULL_TREE;  
#endif
  /* LLVM LOCAL - end 5541393 */
  /* APPLE LOCAL begin ObjC GC */
  /* Use the strong-cast write barrier as a last resort.  */
  if (warn_assign_intercept)
    warning (0, "strong-cast assignment has been intercepted");

  return objc_build_strong_cast_assignment (lhs, rhs);
  /* APPLE LOCAL end ObjC GC */
/* APPLE LOCAL confused diff */
}

/* APPLE LOCAL begin ObjC new abi */

/* 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 *class)
{
  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))
    {
      *class = lookup_interface (OBJC_TYPE_NAME (basetype));
      if (*class)
	{
	  do
	    {
	      tree ivar_chain = CLASS_RAW_IVARS (*class);
	      if (ivar_chain)
		{
		  field = is_ivar (ivar_chain, component);
		  if (field != NULL_TREE)
		    break;
	        }
	      *class = lookup_interface (CLASS_SUPER_NAME (*class));
	    }
	  while (*class);
	}
    }
  return field;
} 

/* APPLE LOCAL begin radar 4441049 */
/* This routine creates an OFFSET_IVAR variable for COMPONENT_REF EXP
   and returns it. This routine is for bitfield ivars only.  */
tree
objc_v2_component_ref_field_offset (tree exp)
{
  char var_offset_name[512];
  tree class_name, offset;
  tree datum = TREE_OPERAND (exp, 0);
  tree field = TREE_OPERAND (exp, 1);
  tree component = DECL_NAME (field);

  /* unnamed bitfields are not user ivars. */
  if (!component)
    return NULL_TREE;

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

  /* This routine must only be called for bitfield ivars. */
  /* DECL_INITIAL macro is set to width of bitfield and can be relied on to
     check for bitfield ivars. Note that I cannot rely on DECL_BIT_FIELD macro
     because it is only set when the whole struct is seen (at finish_struct) 
     and not when the ivar chain is built. */
  gcc_assert (DECL_INITIAL (field));

  create_ivar_offset_name (var_offset_name, CLASS_NAME (class_name), 
			   field);
  /* NOTE! type of variable for ivar offset MUST match type of offset assumed
     by the front-end. Otherwise, FE asserts when attempting to do futher
     math on the tree whose one operand is one of these offsets. */
  offset = create_extern_decl (TREE_TYPE (size_zero_node), var_offset_name);
  return offset;
}

/* This routine computes the bit position from the beginning of its byte. 
   This is only done for bitfield ivars. */

tree
objc_v2_bitfield_ivar_bitpos (tree exp)
{
  tree class_name;
  int bitpos;
  tree datum = TREE_OPERAND (exp, 0);
  tree field = TREE_OPERAND (exp, 1);
  tree component = DECL_NAME (field);
  tree ivar_field;

  if (!((flag_objc_abi == 2)
        && (ivar_field = objc_is_ivar (datum, component, &class_name))))
    return NULL_TREE;
  
  /* This routine must only be called for bitfield ivars. */
  /* DECL_INITIAL macro is set to width of bitfield and can be relied on to
     check for bitfield ivars. Note that I cannot rely on DECL_BIT_FIELD macro
     because it is only set when the whole struct is seen (at finish_struct) 
     and not when the ivar chain is built. */
  gcc_assert (DECL_INITIAL (ivar_field));

  bitpos = tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 0);
  bitpos = bitpos % BITS_PER_UNIT;
  return build_int_cst (TREE_TYPE (bitsize_zero_node), bitpos);
}

/* APPLE LOCAL end radar 4441049 */

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

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

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

  /* APPLE LOCAL begin radar 4441049 */
  /* This routine only handles non-bitfield fields */
  /* DECL_INITIAL macro is set to width of bitfield and can be relied on to
     check for bitfield ivars. Note that I cannot rely on DECL_BIT_FIELD macro
     because it is only set when the whole struct is seen (at finish_struct) 
     and not when the ivar chain is built. */
  if (DECL_INITIAL (field))
    return NULL_TREE;
  /* APPLE LOCAL end radar 4441049 */
  /* APPLE LOCAL begin radar 4954480 */
  if (TREE_CODE (datum) == INDIRECT_REF && (TREE_OPERAND (datum, 0) == null_pointer_node
#ifdef OBJCPLUS
    || (TREE_CODE (TREE_OPERAND (datum, 0)) == NOP_EXPR 
	&& TREE_OPERAND (TREE_OPERAND (datum, 0), 0) == null_pointer_node)
#endif
     ))
    {
      /* APPLE LOCAL radar 6230800 */
      error ("Illegal reference to non-fragile ivar");
      return error_mark_node;
    }
  /* APPLE LOCAL end radar 4954480 */

  create_ivar_offset_name (var_offset_name, CLASS_NAME (class_name), 
			   field);
  /* APPLE LOCAL radar 4441049 */
  offset = create_extern_decl (TREE_TYPE (size_zero_node), var_offset_name);

  ftype = TREE_TYPE (field);

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

  /* (char*)datum + offset */
  expr = fold (build2 (PLUS_EXPR, string_type_node, expr, offset));
  
  /* (ftype*)((char*)datum + offset) */
  expr = build_c_cast (build_pointer_type (ftype), expr);

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

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

  /* APPLE LOCAL begin "unavailable" attribute (radar 2809697) */
  if (TREE_UNAVAILABLE (field))
    error_unavailable_use (field);
  /* APPLE LOCAL end "unavailable" attribute (radar 2809697) */

  /* APPLE LOCAL begin radar 5376125 */
  if (!flag_objc_gc && warn_direct_ivar_access)
    objc_warn_direct_ivar_access (TYPE_MAIN_VARIANT (TREE_TYPE (datum)), 
				  component);
  /* APPLE LOCAL end radar 5376125 */
  return ref;
}
/* APPLE LOCAL end ObjC new abi */

struct interface_tuple GTY(())
{
  tree id;
  tree class_name;
};

static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;

static hashval_t
hash_interface (const void *p)
{
  const struct interface_tuple *d = p;
  return IDENTIFIER_HASH_VALUE (d->id);
}

static int
eq_interface (const void *p1, const void *p2)
{
  const struct interface_tuple *d = p1;
  return d->id == p2;
}

static tree
lookup_interface (tree ident)
{
#ifdef OBJCPLUS
  if (ident && TREE_CODE (ident) == TYPE_DECL)
    ident = DECL_NAME (ident);
#endif

  if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
    return NULL_TREE;

  {
    struct interface_tuple **slot;
    tree i = NULL_TREE;

    if (interface_htab)
      {
	slot = (struct interface_tuple **)
	  htab_find_slot_with_hash (interface_htab, ident,
				    IDENTIFIER_HASH_VALUE (ident),
				    NO_INSERT);
	if (slot && *slot)
	  i = (*slot)->class_name;
      }
    return i;
  }
}

/* Implement @defs (<classname>) within struct bodies.  */

tree
objc_get_class_ivars (tree class_name)
{
  tree interface = lookup_interface (class_name);

  if (interface)
    return get_class_ivars (interface, true);

  error ("cannot find interface declaration for %qs",
	 IDENTIFIER_POINTER (class_name));

  return error_mark_node;
}

/* APPLE LOCAL begin radar 4291785 */
/* Generate an error for any duplicate field names in FIELDLIST.  Munge
   the list such that this does not present a problem later.  */

void
objc_detect_field_duplicates (tree fieldlist)
{
  tree x, y;
  int timeout = 10;
#ifdef OBJCPLUS
  /* for objective-c++, we only care about duplicate checking of ivars. */
  if (!objc_collecting_ivars)
    return;
#endif

  /* First, see if there are more than "a few" fields.
     This is trivially true if there are zero or one fields.  */
  if (!fieldlist)
    return;
  x = TREE_CHAIN (fieldlist);
  if (!x)
    return;
  do {
    timeout--;
    x = TREE_CHAIN (x);
  } while (timeout > 0 && x);

  /* If there were "few" fields, avoid the overhead of allocating
     a hash table.  Instead just do the nested traversal thing.  */
  if (timeout > 0)
    {
      for (x = TREE_CHAIN (fieldlist); x ; x = TREE_CHAIN (x))
        if (DECL_NAME (x))
          {
            for (y = fieldlist; y != x; y = TREE_CHAIN (y))
              if (DECL_NAME (y) == DECL_NAME (x))
                {
		  if (objc_collecting_ivars)
		    {
		      error ("%Jduplicate member %qD", y, y);
		      DECL_NAME (y) = NULL_TREE;
		    }
		  else
		    {
		      error ("%Jduplicate member %qD", x, x);
		      DECL_NAME (x) = NULL_TREE;
		    }
                }
          }
    }
  else
    {
      htab_t htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
      void **slot;

      for (x = fieldlist; x ; x = TREE_CHAIN (x))
        if ((y = DECL_NAME (x)) != 0)
          {
            slot = htab_find_slot (htab, y, INSERT);
            if (*slot)
              {
	        if (objc_collecting_ivars)
	          {
		    tree z;
		    /* Hackery to get the correct position of the duplicate field.
		       It is slow, but we are reporting error, remember. */
		    for (z = fieldlist; z ; z = TREE_CHAIN (z))
		      if (DECL_NAME (x) == DECL_NAME (z))
			{
		          error ("%Jduplicate member %qD", z, z);
			  DECL_NAME (z) = NULL_TREE;
		          break;
			}
		  }
	        else
		  {
		    error ("%Jduplicate member %qD", x, x);
                    DECL_NAME (x) = NULL_TREE;
		  }
              }
            *slot = y;
          }

      htab_delete (htab);
    }
}

/* For current interface with inherited interface chain, this function returns the
   flattened list of ivars in current and inherited interfaces. Otherwise, it
   returns the argument passed to it. */
tree
objc_get_interface_ivars (tree fieldlist)
{
  tree ivar_chain;
  tree interface;
  if (!objc_collecting_ivars || !objc_interface_context 
      || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE
      || CLASS_SUPER_NAME (objc_interface_context) == NULL_TREE)
    return fieldlist;
  interface = objc_interface_context;
  gcc_assert (TOTAL_CLASS_RAW_IVARS (objc_interface_context) == NULL_TREE);
  ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
  if (CLASS_SUPER_NAME (interface))
    {
      /* Prepend super-class ivars.  */
      interface = lookup_interface (CLASS_SUPER_NAME (interface));
      /* Root base interface may not have its TOTAL_CLASS_RAW_IVARS set yet. */
      if (TOTAL_CLASS_RAW_IVARS (interface) == NULL_TREE)
        TOTAL_CLASS_RAW_IVARS (interface) = copy_list (CLASS_RAW_IVARS (interface));
      ivar_chain = chainon (ivar_chain, TOTAL_CLASS_RAW_IVARS (interface));
    }
  TOTAL_CLASS_RAW_IVARS (objc_interface_context) = ivar_chain;
  return ivar_chain;
}
/* APPLE LOCAL end radar 4291785 */

/* Used by: build_private_template, continue_class,
   and for @defs constructs.  */

static tree
get_class_ivars (tree interface, bool inherited)
{
  tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));

  /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
     by the current class (i.e., they do not include super-class ivars).
     However, the CLASS_IVARS list will be side-effected by a call to
     finish_struct(), which will fill in field offsets.  */
  if (!CLASS_IVARS (interface))
    CLASS_IVARS (interface) = ivar_chain;

  if (!inherited)
    return ivar_chain;

  while (CLASS_SUPER_NAME (interface))
    {
      /* Prepend super-class ivars.  */
      interface = lookup_interface (CLASS_SUPER_NAME (interface));
      ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
			    ivar_chain);
    }

  return ivar_chain;
}

static tree
objc_create_temporary_var (tree type)
{
  tree decl;

  decl = build_decl (VAR_DECL, NULL_TREE, type);
  TREE_USED (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  DECL_CONTEXT (decl) = current_function_decl;

  return decl;
}


/* APPLE LOCAL begin radar 2848255 */
static tree
create_weak_decl (tree type, const char *name)
{
    tree decl = create_global_decl (type, name);
    DECL_WEAK (decl) = 1;
    return decl;
}

/* This routine builds objc2's typeinfo type for the purpose of zero-cost exception.
   Declaration of this type is:

   struct _objc_ehtype_t {
     void *_objc_ehtype_vtable;
     const char *className;
     struct class_t *const cls;
   }
*/

static void
objc2_build_ehtype (void)
{
  tree field_decl, field_decl_chain;
  objc2_ehtype_template = start_struct (RECORD_TYPE,
				     get_identifier ("_objc_ehtype_t"));

  /* void *_objc_ehtype_vtable; */
  field_decl = create_field_decl (ptr_type_node, "_objc_ehtype_vtable");
  field_decl_chain = field_decl;

  /* const char *className; */
  field_decl = create_field_decl (string_type_node, "className");
  chainon (field_decl_chain, field_decl);

  /* struct class_t *const cls; */
  field_decl = create_field_decl (build_pointer_type (objc_v2_class_template),
				  "cls");
  chainon (field_decl_chain, field_decl);
  finish_struct (objc2_ehtype_template, field_decl_chain, NULL_TREE);
}

/* Declare objc_ehtype_vtable and OBJC_EHTYPE_id. */
static
void init_UOBJC2_EHTYPE_decls (void)
{
      /* declare extern void *objc_ehtype_vtable */
      if (!UOBJC2_EHTYPE_VTABLE_decl)
        {
          UOBJC2_EHTYPE_VTABLE_decl = lookup_name (get_identifier ("objc_ehtype_vtable"));
          if (!UOBJC2_EHTYPE_VTABLE_decl)
	    UOBJC2_EHTYPE_VTABLE_decl = create_extern_decl (ptr_type_node, 
							    "objc_ehtype_vtable");
	}
      /* declare extern struct _objc_ehtype_t OBJC_EHTYPE_id; */
      if (!UOBJC2_EHTYPE_id_decl)
	{
          UOBJC2_EHTYPE_id_decl = lookup_name (get_identifier ("OBJC_EHTYPE_id")); 
          if (!UOBJC2_EHTYPE_id_decl)
            UOBJC2_EHTYPE_id_decl = create_extern_decl (objc2_ehtype_template, 
						        "OBJC_EHTYPE_id");
	}

}

/* This routine builds initializer list for object of type struct _objc_ehtype_t.
*/
 
static tree
objc2_build_ehtype_initializer (tree name, tree cls)
{
  tree initlist = NULL_TREE;
  tree addr;
  init_UOBJC2_EHTYPE_decls ();
  /* APPLE LOCAL begin radar 4995942 */
  /* _objc_ehtype_vtable + 2*sizeof(void*) */
  addr = 
    fold (build2 (MULT_EXPR, ptr_type_node, 
	  TYPE_SIZE_UNIT (ptr_type_node), build_int_cst (NULL_TREE, 2)));
  addr = fold (build2 (PLUS_EXPR, ptr_type_node, 
	      build_fold_addr_expr (UOBJC2_EHTYPE_VTABLE_decl), addr));
  initlist = tree_cons (NULL_TREE, addr, initlist);
  /* APPLE LOCAL end radar 4995942 */

  /* className */
  initlist = tree_cons (NULL_TREE, name, initlist);

  /* cls */
  initlist = tree_cons (NULL_TREE, cls, initlist);

  return objc_build_constructor (objc2_ehtype_template, nreverse (initlist));
}

static char*
objc2_internal_ehtype_name (tree cls_name_ident)
{
  static char string[BUFSIZE];
  sprintf (string, "%s_%s", STRING_V2_OBJC_EHTYPE_PREFIX, IDENTIFIER_POINTER (cls_name_ident));
  return string;
}

/* This routine declares objective-c's 'typeinfo' data structure. */

static tree
/* APPLE LOCAL radar 5008110 */
objc2_build_ehtype_var_decl (tree cls_name_ident, bool extern_decl, bool weak_decl)
{
  tree initlist, ehtype_vdecl;
  tree name_expr, class_name_expr;

  const char* string = objc2_internal_ehtype_name (cls_name_ident);
  /* APPLE LOCAL begin radar 5008110 */
  if (extern_decl)
    return create_extern_decl (objc2_ehtype_template, string);
  name_expr = add_objc_string (cls_name_ident, class_names);
  class_name_expr = create_extern_decl (objc_v2_class_template,
					objc_build_internal_classname (cls_name_ident, false));
  class_name_expr = build_fold_addr_expr (class_name_expr);
  ehtype_vdecl = weak_decl ? create_weak_decl (objc2_ehtype_template, string)
			   : create_global_decl (objc2_ehtype_template, string);
  /* APPLE LOCAL end radar 5008110 */
  initlist = objc2_build_ehtype_initializer (name_expr, class_name_expr);
  finish_var_decl (ehtype_vdecl, initlist);
  return ehtype_vdecl;
}

#ifdef OBJCPLUS
/* This routine returns true if TYPE is a valid objective-c type which can be
   used in a @catch clause */
bool
objc2_valid_objc_catch_type (tree type)
{
  return flag_objc_zerocost_exceptions && managed_objc_object_pointer (type);
}
#endif

/* APPLE LOCAL begin radar 5008110 */
/* This routine returns TRUE if CLS or any of its super classes have their 
   __objc_exception__ atttribute set.
*/
static bool
objc2_objc_exception_attr (tree cls)
{
  tree chain;
  while (cls)
    {
      for (chain = CLASS_ATTRIBUTES (cls); chain; chain = TREE_CHAIN (chain))
        if (is_attribute_p ("objc_exception", TREE_PURPOSE (chain)))
          return true;
      cls = lookup_interface (CLASS_SUPER_NAME (cls));
    }

  return false; 
}

/* APPLE LOCAL end radar 5008110 */

/* 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
objc2_eh_runtime_type (tree type)
{
  tree t;
  if (type == error_mark_node)
    return type;
  if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
    return build_fold_addr_expr (UOBJC2_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 objcp_build_eh_type_type (type);
#else
      error ("non-objective-c type '%T' cannot be caught", type);
      return error_mark_node;
#endif
    }

  t = OBJC_TYPE_NAME (TREE_TYPE (type));
  /* APPLE LOCAL begin radar 5008110 */
  t = objc2_build_ehtype_var_decl (t, 
	objc2_objc_exception_attr (lookup_interface (t)), true);
  /* APPLE LOCAL end radar 5008110 */
  return build_fold_addr_expr (t);
}

/* APPLE LOCAL begin radar 4951324 */
/* This routine declares an external class object to be used by
   objc2_build_ehtype_var_decl routine. */
static void
objc2_build_extern_decl_catch_object (tree type)
{
  if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
    return;

  if (POINTER_TYPE_P (type) && TYPED_OBJECT (TREE_TYPE (type)))
    {
      tree t = OBJC_TYPE_NAME (TREE_TYPE (type));
      (void)add_objc_string (t, class_names);
      (void) create_extern_decl (objc_v2_class_template, 
				 objc_build_internal_classname (t, false));
      if (objc2_objc_exception_attr (lookup_interface (t)))
	(void) create_extern_decl (objc2_ehtype_template, objc2_internal_ehtype_name (t));
    }
}
/* APPLE LOCAL end radar 4951324 */
/* APPLE LOCAL end radar 2848255 */

/* Exception handling constructs.  We begin by having the parser do most
   of the work and passing us blocks.  What we do next depends on whether
   we're doing "native" exception handling or legacy Darwin setjmp exceptions.
   We abstract all of this in a handful of appropriately named routines.  */

/* Stack of open try blocks.  */

struct objc_try_context
{
  struct objc_try_context *outer;

  /* Statements (or statement lists) as processed by the parser.  */
  tree try_body;
  tree finally_body;

  /* Some file position locations.  */
  location_t try_locus;
  location_t end_try_locus;
  location_t end_catch_locus;
  location_t finally_locus;
  location_t end_finally_locus;

  /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
     of a TRY_CATCH_EXPR.  Even when doing Darwin setjmp.  */
  tree catch_list;

  /* The CATCH_EXPR of an open @catch clause.  */
  tree current_catch;

  /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR.  */
  tree caught_decl;
  tree stack_decl;
  tree rethrow_decl;
};

static struct objc_try_context *cur_try_context;

/* This hook, called via lang_eh_runtime_type, generates a runtime object
   that represents TYPE.  For Objective-C, this is just the class name.  */
/* ??? Isn't there a class object or some such?  Is it easy to get?  */

#ifndef OBJCPLUS
static tree
objc_eh_runtime_type (tree type)
{
  return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
}
#endif

/* Initialize exception handling.  */

static void
objc_init_exceptions (void)
{
  static bool done = false;
  if (done)
    return;
  done = true;

  /* APPLE LOCAL begin radar 4590191 */
  if (flag_objc_sjlj_exceptions)
    {
      /* LLVM LOCAL begin */    
#ifdef ENABLE_LLVM
      OBJC_FLAG_SJLJ_EXCEPTIONS;
#else
      if (darwin_macosx_version_min 
	  && strverscmp (darwin_macosx_version_min, "10.3") < 0)
	warning (0, "Mac OS X version 10.3 or later is needed instead of %s for objc/obj-c++ exceptions",
	         darwin_macosx_version_min);
#endif
      /* LLVM LOCAL end */
    }
  /* APPLE LOCAL end radar 4590191 */
 /* APPLE LOCAL begin radar 2848255 */
  else if (flag_objc_zerocost_exceptions)
    {
#ifndef OBJCPLUS
      c_eh_initialized_p = true;
#endif
      /* APPPLE LOCAL radar 5023725 */
      OBJC_FLAG_ZEROCOST_EXCEPTIONS; 
      /* LLVM local begin */
#ifdef ENABLE_LLVM
      llvm_eh_personality_libfunc
        = llvm_init_one_libfunc ("__objc_personality_v0");
#else
      eh_personality_libfunc
        = init_one_libfunc ("__objc_personality_v0");
#endif
      /* LLVM local end */
      default_init_unwind_resume_libfunc ();
      using_eh_for_cleanups ();
      lang_eh_runtime_type = objc2_eh_runtime_type;
      /* APPLE LOCAL radar 4951324 */
      init_UOBJC2_EHTYPE_decls ();
    }
  /* APPLE LOCAL end radar 2848255 */
#ifndef OBJCPLUS
  else
    {
      c_eh_initialized_p = true;
      /* LLVM local begin */
#ifdef ENABLE_LLVM
      llvm_eh_personality_libfunc
	= llvm_init_one_libfunc (USING_SJLJ_EXCEPTIONS
                                 ? "__gnu_objc_personality_sj0"
                                 : "__gnu_objc_personality_v0");
#else
      eh_personality_libfunc
	= init_one_libfunc (USING_SJLJ_EXCEPTIONS
			    ? "__gnu_objc_personality_sj0"
			    : "__gnu_objc_personality_v0");
#endif
      /* LLVM local end */
      default_init_unwind_resume_libfunc ();
      using_eh_for_cleanups ();
      lang_eh_runtime_type = objc_eh_runtime_type;
    }
#endif
}

/* Build an EXC_PTR_EXPR, or the moral equivalent.  In the case of Darwin,
   we'll arrange for it to be initialized (and associated with a binding)
   later.  */

static tree
objc_build_exc_ptr (void)
{
  if (flag_objc_sjlj_exceptions)
    {
      tree var = cur_try_context->caught_decl;
      if (!var)
	{
	  var = objc_create_temporary_var (objc_object_type);
	  cur_try_context->caught_decl = var;
	}
      return var;
    }
  else
    return build0 (EXC_PTR_EXPR, objc_object_type);
}

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

static tree
next_sjlj_build_try_exit (void)
{
  tree t;
  t = build_fold_addr_expr (cur_try_context->stack_decl);
  t = tree_cons (NULL, t, NULL);
  t = build_function_call (objc_exception_try_exit_decl, t);
  return t;
}

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

static tree
next_sjlj_build_enter_and_setjmp (void)
{
  tree t, enter, sj, cond;

  t = build_fold_addr_expr (cur_try_context->stack_decl);
  t = tree_cons (NULL, t, NULL);
  enter = build_function_call (objc_exception_try_enter_decl, t);

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

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

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

/* Build:

   DECL = objc_exception_extract(&_stack);  */

static tree
next_sjlj_build_exc_extract (tree decl)
{
  tree t;

  t = build_fold_addr_expr (cur_try_context->stack_decl);
  t = tree_cons (NULL, t, NULL);
  t = build_function_call (objc_exception_extract_decl, t);
  t = convert (TREE_TYPE (decl), t);
  t = build2 (MODIFY_EXPR, void_type_node, decl, t);

  return t;
}

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

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

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

      if (type == NULL)
	{
	  *last = body;
	  saw_id = true;
	  break;
	}
      else
	{
	  tree args, cond;

	  if (type == error_mark_node)
	    cond = error_mark_node;
	  else
	    {
	      args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
	      t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
	      args = tree_cons (NULL, t, args);
	      t = build_function_call (objc_exception_match_decl, args);
	      cond = c_common_truthvalue_conversion (t);
	    }
	  t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
	  SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));

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

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

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

  return catch_seq;
}

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

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

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

static tree
next_sjlj_build_try_catch_finally (void)
{
  tree rethrow_decl, stack_decl, t;
  tree catch_seq, try_fin, bind;

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

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

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

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

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

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

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

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

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

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

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

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

  return bind;
}

/* Called just after parsing the @try and its associated BODY.  We now
   must prepare for the tricky bits -- handling the catches and finally.  */

void
objc_begin_try_stmt (location_t try_locus, tree body)
{
  struct objc_try_context *c = xcalloc (1, sizeof (*c));
  c->outer = cur_try_context;
  c->try_body = body;
  c->try_locus = try_locus;
  c->end_try_locus = input_location;
  cur_try_context = c;

  objc_init_exceptions ();

  if (flag_objc_sjlj_exceptions)
    objc_mark_locals_volatile (NULL);
}

/* Called just after parsing "@catch (parm)".  Open a binding level,
   enter DECL into the binding level, and initialize it.  Leave the
   binding level open while the body of the compound statement is parsed.  */

void
objc_begin_catch_clause (tree decl)
{
  tree compound, type, t;

  /* Begin a new scope that the entire catch clause will live in.  */
  compound = c_begin_compound_stmt (true);

  /* APPLE LOCAL begin radar 2848255 */
  if (decl == NULL_TREE)
    {
      /* @catch (...) */
      if (flag_objc_zerocost_exceptions)
        {
          t = build_stmt (CATCH_EXPR, NULL_TREE, compound);
          cur_try_context->current_catch = t;
          /* APPLE LOCAL 5837617 */
          t = build1(NOP_EXPR, ptr_type_node, objc_build_exc_ptr ());
          t = build_function_call (objc2_begin_catch_decl,
                                   tree_cons (NULL_TREE, t, NULL_TREE));
          add_stmt (t);
          return;
        }
      else
        /* APPLE LOCAL begin radar 4995967 */
        /* Assumes @catch (...) is same as @catch (id). */
          decl = create_tmp_var_raw (objc_object_type, NULL);
        /* APPLE LOCAL end radar 4995967 */
    }
  /* APPLE LOCAL end radar 2848255 */

  /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL.  */
  decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
  lang_hooks.decls.pushdecl (decl);

  /* Since a decl is required here by syntax, don't warn if its unused.  */
  /* ??? As opposed to __attribute__((unused))?  Anyway, this appears to
     be what the previous objc implementation did.  */
  TREE_USED (decl) = 1;

  /* Verify that the type of the catch is valid.  It must be a pointer
     to an Objective-C class, or "id" (which is catch-all).  */
  type = TREE_TYPE (decl);

  if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
    /* APPLE LOCAL radar 2848255 */
    type = !flag_objc_zerocost_exceptions ? NULL : type;
  else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
    {
      error ("@catch parameter is not a known Objective-C class type");
      type = error_mark_node;
    }
  else if (cur_try_context->catch_list)
    {
      /* Examine previous @catch clauses and see if we've already
	 caught the type in question.  */
      tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
      for (; !tsi_end_p (i); tsi_next (&i))
	{
	  tree stmt = tsi_stmt (i);
	  t = CATCH_TYPES (stmt);
	  if (t == error_mark_node)
	    continue;
	  if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
	    {
	      warning (0, "exception of type %<%T%> will be caught",
		       TREE_TYPE (type));
	      warning (0, "%H   by earlier handler for %<%T%>",
		       EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
	      break;
	    }
	}
    }

  /* Record the data for the catch in the try context so that we can
     finalize it later.  */
  t = build_stmt (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 ();
  t = convert (TREE_TYPE (decl), t);
  /* APPLE LOCAL begin radar 2848255 - radar 4951324 */
  if (flag_objc_zerocost_exceptions)
    {     
      /* Decl an external declaration for the objc class for this catch type. */
      objc2_build_extern_decl_catch_object (type);
      /* APPLE LOCAL 5837617 */
      t = build1(NOP_EXPR, ptr_type_node, t);
      t = build_function_call (objc2_begin_catch_decl,
                               tree_cons (NULL_TREE, t, NULL_TREE));
    }
  /* APPLE LOCAL end radar 2848255 - radar 4951324 */
  t = build2 (MODIFY_EXPR, void_type_node, decl, t);
  add_stmt (t);
}

/* APPLE LOCAL begin radar 2848255 */
/* This routine adds a finally { objc_end_catch (); } block to end of try-block. */
static tree
objc2_liteweight_finish_try_stmt (void)
{    
  struct objc_try_context *c = cur_try_context;
  tree stmt, t;
  
  stmt = c->try_body;
  t = build_function_call (objc2_end_catch_decl, NULL_TREE);
  append_to_statement_list (t, &c->finally_body);
  stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
  SET_EXPR_LOCATION (stmt, c->try_locus);
      
  cur_try_context = c->outer;
  free (c);
  return stmt;
}
/* APPLE LOCAL end radar 2848255 */

/* Called just after parsing the closing brace of a @catch clause.  Close
   the open binding level, and record a CATCH_EXPR for it.  */

void
objc_finish_catch_clause (void)
{
  tree c = cur_try_context->current_catch;
  cur_try_context->current_catch = NULL;
  cur_try_context->end_catch_locus = input_location;

  CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
  /* APPLE LOCAL begin radar 2848255 */
  if (flag_objc_zerocost_exceptions)
    {
      /* try { catch-body } finally { objc_end_catch (); } */
      tree try_exp, t;
      t = CATCH_BODY (c);
      if (TREE_CODE (t) == BIND_EXPR)
        {
          /* more common case of @catch (objc-expr). */
          objc_begin_try_stmt (cur_try_context->try_locus, BIND_EXPR_BODY (t));
          try_exp = objc2_liteweight_finish_try_stmt ();
          BIND_EXPR_BODY (t) = NULL_TREE;
          append_to_statement_list (try_exp, &BIND_EXPR_BODY (t));
        }
      else
        {
          /* case of the new @catch (...) */
          objc_begin_try_stmt (cur_try_context->try_locus, t);
          try_exp = objc2_liteweight_finish_try_stmt ();
          CATCH_BODY (c) = NULL_TREE;
          append_to_statement_list (try_exp, &CATCH_BODY (c));
        }
    }
  /* APPLE LOCAL end radar 2848255 */
  append_to_statement_list (c, &cur_try_context->catch_list);
}

/* Called after parsing a @finally clause and its associated BODY.
   Record the body for later placement.  */

void
objc_build_finally_clause (location_t finally_locus, tree body)
{
  cur_try_context->finally_body = body;
  cur_try_context->finally_locus = finally_locus;
  cur_try_context->end_finally_locus = input_location;
}

/* Called to finalize a @try construct.  */

tree
objc_finish_try_stmt (void)
{
  struct objc_try_context *c = cur_try_context;
  tree stmt;

  if (c->catch_list == NULL && c->finally_body == NULL)
    error ("%<@try%> without %<@catch%> or %<@finally%>");

  /* If we're doing Darwin setjmp exceptions, build the big nasty.  */
  if (flag_objc_sjlj_exceptions)
    {
      if (!cur_try_context->finally_body)
	{
	  cur_try_context->finally_locus = input_location;
	  cur_try_context->end_finally_locus = input_location;
	}
      stmt = next_sjlj_build_try_catch_finally ();
    }
  else
    {
      /* Otherwise, nest the CATCH inside a FINALLY.  */
      stmt = c->try_body;
      if (c->catch_list)
	{
          stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
	  SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
	}
      if (c->finally_body)
	{
	  stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
	  SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
	}
    }
  add_stmt (stmt);

  cur_try_context = c->outer;
  free (c);
  return stmt;
}

/* APPLE LOCAL begin radar 2848255 */
tree
objc2_build_throw_call (tree throw_expr)
{
  tree args;

  objc_init_exceptions ();

  if (throw_expr == NULL)
    {
      /* If we're not inside a @catch block, there is no "current
         exception" to be rethrown.  */
      if (cur_try_context == NULL
          || cur_try_context->current_catch == NULL)
        {
          error ("%<@throw%> (rethrow) used outside of a @catch block");
          return error_mark_node;
        }
      /* APPLE LOCAL begin radar 4957534 */
      if (flag_objc_zerocost_exceptions)
        return build_function_call (objc_rethrow_exception_decl, NULL_TREE);
      /* APPLE LOCAL end radar 4957534 */
      /* Otherwise the object is still sitting in the EXC_PTR_EXPR
         value that we get from the runtime.  */
      throw_expr = objc_build_exc_ptr ();
    }

  /* A throw is just a call to the runtime throw function with the
     object as a parameter.  */
  args = tree_cons (NULL, throw_expr, NULL);
  return build_function_call (objc_exception_throw_decl, args);
}

tree objc_build_throw_stmt (tree throw_expr)
{
  return add_stmt (objc2_build_throw_call (throw_expr));
}
/* APPLE LOCAL end radar 2848255 */

tree
objc_build_synchronized (location_t start_locus, tree mutex, tree body)
{
  tree args, call;

  /* First lock the mutex.  */
  mutex = save_expr (mutex);
  args = tree_cons (NULL, mutex, NULL);
  call = build_function_call (objc_sync_enter_decl, args);
  SET_EXPR_LOCATION (call, start_locus);
  add_stmt (call);

  /* Build the mutex unlock.  */
  args = tree_cons (NULL, mutex, NULL);
  call = build_function_call (objc_sync_exit_decl, args);
  SET_EXPR_LOCATION (call, input_location);

  /* Put the that and the body in a TRY_FINALLY.  */
  objc_begin_try_stmt (start_locus, body);
  objc_build_finally_clause (input_location, call);
  return objc_finish_try_stmt ();
}


/* Predefine the following data type:

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

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

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

static void
build_next_objc_exception_stuff (void)
{
  tree field_decl, field_decl_chain, index, temp_type;

  objc_exception_data_template
    = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));

  /* int buf[OBJC_JBLEN]; */

  index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
  field_decl = create_field_decl (build_array_type (integer_type_node, index),
				  "buf");
  field_decl_chain = field_decl;

  /* void *pointers[4]; */

  index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
  field_decl = create_field_decl (build_array_type (ptr_type_node, index),
				  "pointers");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);

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

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

  /* int objc_exception_match(id, id); */
  temp_type
    = build_function_type (integer_type_node,
			   tree_cons (NULL_TREE, objc_object_type,
				      tree_cons (NULL_TREE, objc_object_type,
						 OBJC_VOID_AT_END)));
  objc_exception_match_decl
    = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);

  /* APPLE LOCAL objc gc 5656857 */
  /* id objc_assign_ivar (id, id, ptrdiff_t); */
  /* APPLE LOCAL objc gc 5656857 */
  /* id objc_assign_ivar_Fast (id, id, ptrdiff_t)
       __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
  temp_type
    = build_function_type (objc_object_type,
			   tree_cons
			   (NULL_TREE, objc_object_type,
			    tree_cons (NULL_TREE, objc_object_type,
				       tree_cons (NULL_TREE,
						  /* APPLE LOCAL objc gc 5656857 */
						  ptrdiff_type_node,
						  OBJC_VOID_AT_END))));
  /* APPLE LOCAL begin radar 4590221 */
  if (OFFS_ASSIGNIVAR_FAST)
    {
      /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
      tree objc_assign_ivar_fast_decl;
      objc_assign_ivar_decl
	= builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0, 
			    NOT_BUILT_IN, NULL, NULL_TREE);
      objc_assign_ivar_fast_decl = build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST);
      objc_assign_ivar_fast_decl
        = build_c_cast (build_pointer_type (TREE_TYPE (objc_assign_ivar_decl)),
                        objc_assign_ivar_fast_decl);
      objc_assign_ivar_fast_decl
        = build_indirect_ref (objc_assign_ivar_fast_decl, "*");
      objc_assign_ivar_decl = objc_assign_ivar_fast_decl;
#else
      objc_assign_ivar_decl
	= builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0, 
			    NOT_BUILT_IN, NULL, NULL_TREE);
      DECL_ATTRIBUTES (objc_assign_ivar_decl)
	= tree_cons (get_identifier ("hard_coded_address"),
		     build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
		     NULL_TREE);
#endif
      /* LLVM LOCAL end */
    }
  else
    {
      objc_assign_ivar_decl
	= builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
    }
  /* APPLE LOCAL end radar 4590221 */
  /* id objc_assign_global (id, id *); */
  /* id objc_assign_strongCast (id, id *); */
  temp_type = build_function_type (objc_object_type,
		tree_cons (NULL_TREE, objc_object_type,
		    tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
			OBJC_VOID_AT_END)));
  objc_assign_global_decl
	= builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
  objc_assign_strong_cast_decl
	= builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
  /* APPLE LOCAL begin radar 4426814 */
  /* id objc_assign_weak (id, id *); */
  objc_assign_weak_decl
	= builtin_function (TAG_ASSIGN_WEAK, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
  /* APPLE LOCAL radar 4591756 */
  /* id objc_read_weak (id *); */
  temp_type = build_function_type (objc_object_type, 
				   tree_cons (NULL_TREE, 
					      build_pointer_type (objc_object_type), 
					      OBJC_VOID_AT_END));
  /* APPLE LOCAL radar 4591756 */
  objc_read_weak_decl
	= builtin_function (TAG_READ_WEAK, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
  /* APPLE LOCAL end radar 4426814 */
  /* APPLE LOCAL begin radar 3742561 */
  /* void *objc_memmove_collectable(void *dst, const void *src, size_t size) */
  temp_type = build_function_type (ptr_type_node,
				     tree_cons (NULL_TREE, ptr_type_node,
				       tree_cons (NULL_TREE, ptr_type_node,
				         tree_cons (NULL_TREE, long_unsigned_type_node, 
						    OBJC_VOID_AT_END))));
  objc_memmove_collectable_decl
	= builtin_function (TAG_MEMMOVE_COLLECTABLE, temp_type, 0, 
			    NOT_BUILT_IN, NULL, NULL_TREE);
  /* APPLE LOCAL end radar 3742561 */
}

static void
build_objc_exception_stuff (void)
{
  tree noreturn_list, nothrow_list, temp_type;

  noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
  nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);

  /* void objc_exception_throw(id) __attribute__((noreturn)); */
  /* void objc_sync_enter(id); */
  /* void objc_sync_exit(id); */
  temp_type = build_function_type (void_type_node,
				   tree_cons (NULL_TREE, objc_object_type,
					      OBJC_VOID_AT_END));
  objc_exception_throw_decl
    = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
			noreturn_list);
  objc_sync_enter_decl
    = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
			NULL, nothrow_list);
  objc_sync_exit_decl
    = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
			NULL, nothrow_list);
  /* APPLE LOCAL begin radar 2848255 */
  if (flag_objc_zerocost_exceptions)
    {
      /* void * objc_begin_catch (void *) */
      tree type
        = build_function_type (ptr_type_node,
                           tree_cons (NULL_TREE, ptr_type_node,
                           OBJC_VOID_AT_END));
      objc2_begin_catch_decl = 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 (void_type_node, OBJC_VOID_AT_END);
      objc2_end_catch_decl = builtin_function ("objc_end_catch",
                                               type, 0, NOT_BUILT_IN,
                                               NULL, NULL_TREE);
      TREE_NOTHROW (objc2_end_catch_decl) = 0;

      /* APPLE LOCAL begin radar 4957534 */
      /* void objc_exception_rethrow (void) */
      type
        = build_function_type (void_type_node, OBJC_VOID_AT_END);
      objc_rethrow_exception_decl = builtin_function ("objc_exception_rethrow",
                                               type, 0, NOT_BUILT_IN,
                                               NULL, NULL_TREE);
      TREE_NOTHROW (objc_rethrow_exception_decl) = 0;
      /* APPLE LOCAL end radar 4957534 */

      /* APPLE LOCAL begin radar 5060975 */
      /* Make sure that objc_exception_throw (id) claims that it may throw an exception. */
      TREE_NOTHROW (objc_exception_throw_decl) = 0;
      /* APPLE LOCAL end radar 5060975 */

      /* build struct _objc_ehtype_t type */
      objc2_build_ehtype ();
    }
  /* APPLE LOCAL end radar 2848255 */
}

/* Construct a C struct corresponding to ObjC class CLASS, with the same
   name as the class:

   struct <classname> {
     struct _objc_class *isa;
     ...
   };  */

static void
build_private_template (tree class)
{
  if (!CLASS_STATIC_TEMPLATE (class))
    {
      tree record = objc_build_struct (class,
				       get_class_ivars (class, false),
				       CLASS_SUPER_NAME (class));

      /* Set the TREE_USED bit for this struct, so that stab generator
	 can emit stabs for this struct type.  */
      /* APPLE LOCAL begin radar 4666559 */
      if (flag_debug_only_used_symbols && !objc_collecting_ivars 
	  && TYPE_STUB_DECL (record))
      /* APPLE LOCAL end radar 4666559 */
	TREE_USED (TYPE_STUB_DECL (record)) = 1;

      /* APPLE LOCAL begin radar 4548636 */
      if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
	objc_attach_attrs_to_type (record, class); 
      /* APPLE LOCAL end radar 4548636 */
      /* APPLE LOCAL begin ObjC new abi */
      if (flag_objc_abi == 2)
        CLASS_TYPE (class) = record;
    }
}
      /* APPLE LOCAL end ObjC new abi */

/* APPLE LOCAL begin ObjC new abi */
/* struct protocol_t {
     // APPLE LOCAL radar 4695109
     id isa;  // NULL
     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;
     // APPLE LOCAL begin radar 4695109 
     const struct method_list_t *optionalInstanceMethods;
     const struct method_list_t *optionalClassMethods;
     // APPLE LOCAL end radar 4695109 
     const struct _prop_list_t * const properties;
     // APPLE LOCAL begin radar 5192466
     const uint32_t size;  // sizeof(struct protocol_t)
     const uint32_t flags;  // = 0
     // APPLE LOCAL end radar 5192466
   }  */

static void
build_v2_protocol_template (void)
{
  tree field_decl, field_decl_chain;

  objc_v2_protocol_template = start_struct (RECORD_TYPE,
                                         get_identifier (UTAG_V2_PROTOCOL));

  /* APPLE LOCAL begin radar 4533974 - ObjC new protocol - radar 4695109 */
  /* id isa; */
  field_decl = create_field_decl (objc_object_type, "isa");
  field_decl_chain = field_decl;
  /* APPLE LOCAL end radar 4533974 - ObjC new protocol - radar 4695109 */

  /* char *protocol_name; */ 
  field_decl = create_field_decl (string_type_node, "protocol_name");
  /* APPLE LOCAL radar 4533974 - ObjC new protocol */
  chainon (field_decl_chain, field_decl);

  /* const struct protocol_list_t * const protocol_list; */
  field_decl = create_field_decl (build_pointer_type
                                   (objc_v2_protocol_template),
                                  "protocol_list");
  chainon (field_decl_chain, field_decl);

  /* const struct method_list_t * const instance_methods; */
  field_decl = create_field_decl (objc_method_proto_list_ptr,
				  "instance_methods");
  chainon (field_decl_chain, field_decl);

  /* const struct method_list_t * const class_methods; */
  field_decl = create_field_decl (objc_method_proto_list_ptr,
                                  "class_methods");
  chainon (field_decl_chain, field_decl);

  /* APPLE LOCAL begin radar 4695109 */
  /* const struct method_list_t * optionalInstanceMethods */
  field_decl = create_field_decl (objc_method_proto_list_ptr,
                                  "optionalInstanceMethods");
  chainon (field_decl_chain, field_decl);

  /* const struct method_list_t * optionalClassMethods */
  field_decl = create_field_decl (objc_method_proto_list_ptr,
                                  "optionalClassMethods");
  chainon (field_decl_chain, field_decl);
  /* APPLE LOCAL end radar 4695109 */

  /* APPLE LOCAL begin C* property metadata (Radar 4498373) */
  /* struct _prop_list_t * properties; */
  field_decl = create_field_decl (objc_prop_list_ptr,
				  "properties");
  chainon (field_decl_chain, field_decl);
  /* APPLE LOCAL end C* property metadata (Radar 4498373) */
  /* APPLE LOCAL begin radar 5192466 */
  /* const uint32_t size;  */
  field_decl = create_field_decl (integer_type_node, "size");
  chainon (field_decl_chain, field_decl);
  /* const uint32_t flags;  */
  field_decl = create_field_decl (integer_type_node, "flags");
  chainon (field_decl_chain, field_decl);
  /* APPLE LOCAL end radar 5192466 */

  finish_struct (objc_v2_protocol_template, field_decl_chain, NULL_TREE);


}

/* This routine declares all variables used to declare protocol references.  */

static void
/* APPLE LOCAL radar 4695109 */
/* Any reference to protocol_impl is removed */
generate_v2_protocol_references (tree plist)
{
  tree lproto;

  /* Forward declare protocols referenced.  */
  for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
    {
      tree proto = TREE_VALUE (lproto);

      if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
	  && PROTOCOL_NAME (proto))
	{
          if (! PROTOCOL_V2_FORWARD_DECL (proto))
            build_v2_protocol_reference (proto);

          if (PROTOCOL_LIST (proto))
            generate_v2_protocol_references (PROTOCOL_LIST (proto));
        }
    }
}
/* APPLE LOCAL end ObjC new abi */


/* Begin code generation for protocols...  */

/* struct _objc_protocol {
     // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
     struct _objc_protocol_extension *isa;
     char *protocol_name;
     struct _objc_protocol **protocol_list;
     struct _objc__method_prototype_list *instance_methods;
     struct _objc__method_prototype_list *class_methods;
   };  */

static void
build_protocol_template (void)
{
  tree field_decl, field_decl_chain;

  objc_protocol_template = start_struct (RECORD_TYPE,
					 get_identifier (UTAG_PROTOCOL));

  /* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
  /* struct _objc_protocol_extension *isa; */
  field_decl = create_field_decl (build_pointer_type
				  (xref_tag (RECORD_TYPE,
					     get_identifier (UTAG_PROTOCOL_EXT))),
				  "isa");
  /* APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions */
  field_decl_chain = field_decl;

  /* char *protocol_name; */
  field_decl = create_field_decl (string_type_node, "protocol_name");
  chainon (field_decl_chain, field_decl);

  /* struct _objc_protocol **protocol_list; */
  field_decl = create_field_decl (build_pointer_type
				  (build_pointer_type
				   (objc_protocol_template)),
				  "protocol_list");
  chainon (field_decl_chain, field_decl);

  /* struct _objc__method_prototype_list *instance_methods; */
  field_decl = create_field_decl (objc_method_proto_list_ptr,
				  "instance_methods");
  chainon (field_decl_chain, field_decl);

  /* struct _objc__method_prototype_list *class_methods; */
  field_decl = create_field_decl (objc_method_proto_list_ptr,
				  "class_methods");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
}

static tree
build_descriptor_table_initializer (tree type, tree entries)
{
  tree initlist = NULL_TREE;

  do
    {
      tree eltlist = NULL_TREE;

      eltlist
	= tree_cons (NULL_TREE,
		     build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
      eltlist
	= tree_cons (NULL_TREE,
		     add_objc_string (METHOD_ENCODING (entries),
				      meth_var_types),
		     eltlist);

      initlist
	= tree_cons (NULL_TREE,
		     objc_build_constructor (type, nreverse (eltlist)),
		     initlist);

      entries = TREE_CHAIN (entries);
    }
  while (entries);

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

/* struct objc_method_prototype_list {
     int count;
     struct objc_method_prototype {
	SEL name;
	char *types;
     } list[1];
   };  */

static tree
build_method_prototype_list_template (tree list_type, int size)
{
  tree objc_ivar_list_record;
  tree field_decl, field_decl_chain;

  /* Generate an unnamed struct definition.  */

  objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);

  /* int method_count; */
  field_decl = create_field_decl (integer_type_node, "method_count");
  field_decl_chain = field_decl;

  /* struct objc_method method_list[]; */
  field_decl = create_field_decl (build_array_type
				  (list_type,
				   build_index_type
				   (build_int_cst (NULL_TREE, size - 1))),
				  "method_list");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);

  return objc_ivar_list_record;
}

static tree
build_method_prototype_template (void)
{
  tree proto_record;
  tree field_decl, field_decl_chain;

  proto_record
    = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));

  /* SEL _cmd; */
  field_decl = create_field_decl (objc_selector_type, "_cmd");
  field_decl_chain = field_decl;

  /* char *method_types; */
  field_decl = create_field_decl (string_type_node, "method_types");
  chainon (field_decl_chain, field_decl);

  finish_struct (proto_record, field_decl_chain, NULL_TREE);

  return proto_record;
}

static tree
objc_method_parm_type (tree type)
{
  type = TREE_VALUE (TREE_TYPE (type));
  if (TREE_CODE (type) == TYPE_DECL)
    type = TREE_TYPE (type);
  return type;
}

static int
objc_encoded_type_size (tree type)
{
  int sz = int_size_in_bytes (type);

  /* Make all integer and enum types at least as large
     as an int.  */
  if (sz > 0 && INTEGRAL_TYPE_P (type))
    sz = MAX (sz, int_size_in_bytes (integer_type_node));
  /* Treat arrays as pointers, since that's how they're
     passed in.  */
  else if (TREE_CODE (type) == ARRAY_TYPE)
    sz = int_size_in_bytes (ptr_type_node);
  return sz;
}

static tree
encode_method_prototype (tree method_decl)
{
  tree parms;
  int parm_offset, i;
  char buf[40];
  tree result;

  /* ONEWAY and BYCOPY, for remote object are the only method qualifiers.  */
  encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));

  /* Encode return type.  */
  encode_type (objc_method_parm_type (method_decl),
	       obstack_object_size (&util_obstack),
	       OBJC_ENCODE_INLINE_DEFS);

  /* Stack size.  */
  /* The first two arguments (self and _cmd) are pointers; account for
     their size.  */
  i = int_size_in_bytes (ptr_type_node);
  parm_offset = 2 * i;
  for (parms = METHOD_SEL_ARGS (method_decl); parms;
       parms = TREE_CHAIN (parms))
    {
      tree type = objc_method_parm_type (parms);
      int sz = objc_encoded_type_size (type);

      /* If a type size is not known, bail out.  */
      if (sz < 0)
	{
	  error ("type %q+D does not have a known size",
		 type);
	  /* Pretend that the encoding succeeded; the compilation will
	     fail nevertheless.  */
	  goto finish_encoding;
	}
      parm_offset += sz;
    }

  sprintf (buf, "%d@0:%d", parm_offset, i);
  obstack_grow (&util_obstack, buf, strlen (buf));

  /* Argument types.  */
  parm_offset = 2 * i;
  for (parms = METHOD_SEL_ARGS (method_decl); parms;
       parms = TREE_CHAIN (parms))
    {
      tree type = objc_method_parm_type (parms);

      /* Process argument qualifiers for user supplied arguments.  */
      encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));

      /* Type.  */
      encode_type (type, obstack_object_size (&util_obstack),
		   OBJC_ENCODE_INLINE_DEFS);

      /* Compute offset.  */
      sprintf (buf, "%d", parm_offset);
      parm_offset += objc_encoded_type_size (type);

      obstack_grow (&util_obstack, buf, strlen (buf));
    }

  finish_encoding:
  obstack_1grow (&util_obstack, '\0');
  result = get_identifier (obstack_finish (&util_obstack));
  obstack_free (&util_obstack, util_firstobj);
  return result;
}

static tree
generate_descriptor_table (tree type, const char *name, int size, tree list,
			   /* APPLE LOCAL ObjC new abi */
			   tree proto, bool newabi)
{
  tree decl, initlist;
  /* APPLE LOCAL begin radar 6064186 */
  const char* ref_name = synth_id_with_class_suffix (name, proto);
  decl = start_var_decl (type, ref_name);
  /* APPLE LOCAL end radar 6064186 */

  /* APPLE LOCAL begin ObjC new abi */
  if (newabi)
    {
      int entsize;
      /* APPLE LOCAL radar 6064186 */
      set_user_assembler_name (decl, ref_name);
      entsize = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_method_template));
      initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, entsize));
      initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
    }
  else
    initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
  /* APPLE LOCAL end ObjC new abi */
  initlist = tree_cons (NULL_TREE, list, initlist);

  finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));

  return decl;
}

/* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
static void
generate_method_descriptors (tree protocol, bool is_optional)
{
  tree initlist, chain, method_list_template;
  int size;

  if (!objc_method_prototype_template)
    objc_method_prototype_template = build_method_prototype_template ();

  chain = is_optional ? PROTOCOL_OPTIONAL_CLS_METHODS (protocol) 
		      : PROTOCOL_CLS_METHODS (protocol);
  if (chain)
    {
      size = list_length (chain);

      method_list_template
	= build_method_prototype_list_template (objc_method_prototype_template,
						size);

      initlist
	= build_descriptor_table_initializer (objc_method_prototype_template,
					      chain);

      if (is_optional)
	UOBJC_PROTOCOL_OPT_CLS_METHODS_decl
	  = generate_descriptor_table (method_list_template,
				       /* APPLE LOCAL radar 4695109 */
				       "_OBJC_PROTOCOL_CLASS_METHODS_OPT",
				       /* APPLE LOCAL ObjC new abi */
				       size, initlist, protocol, false);
      else
        UOBJC_CLASS_METHODS_decl
	  = generate_descriptor_table (method_list_template,
				       "_OBJC_PROTOCOL_CLASS_METHODS",
				       /* APPLE LOCAL ObjC new abi */
				       size, initlist, protocol, false);
    }
  else
    {
      if (is_optional)
	UOBJC_PROTOCOL_OPT_CLS_METHODS_decl = 0;
      else
        UOBJC_CLASS_METHODS_decl = 0;
    }

  chain = is_optional ? PROTOCOL_OPTIONAL_NST_METHODS (protocol) 
		      : PROTOCOL_NST_METHODS (protocol);
  if (chain)
    {
      size = list_length (chain);

      method_list_template
	= build_method_prototype_list_template (objc_method_prototype_template,
						size);
      initlist
	= build_descriptor_table_initializer (objc_method_prototype_template,
					      chain);

      if (is_optional)
        UOBJC_PROTOCOL_OPT_NST_METHODS_decl
	  = generate_descriptor_table (method_list_template,
				       /* APPLE LOCAL radar 4695109 */
				       "_OBJC_PROTOCOL_INSTANCE_METHODS_OPT",
				       /* APPLE LOCAL ObjC new abi */
				       size, initlist, protocol, false);
      else
        UOBJC_INSTANCE_METHODS_decl
	  = generate_descriptor_table (method_list_template,
				       "_OBJC_PROTOCOL_INSTANCE_METHODS",
				       /* APPLE LOCAL ObjC new abi */
				       size, initlist, protocol, false);
    }
  else
    {
      if (is_optional)
	UOBJC_PROTOCOL_OPT_NST_METHODS_decl = 0;
      else
    	UOBJC_INSTANCE_METHODS_decl = 0;
    }
}
/* APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions */

static void
generate_protocol_references (tree plist)
{
  tree lproto;

  /* Forward declare protocols referenced.  */
  for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
    {
      tree proto = TREE_VALUE (lproto);

      if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
	  && PROTOCOL_NAME (proto))
	{
          if (! PROTOCOL_FORWARD_DECL (proto))
            build_protocol_reference (proto);

          if (PROTOCOL_LIST (proto))
            generate_protocol_references (PROTOCOL_LIST (proto));
        }
    }
}

/* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
   current class.  */
#ifdef OBJCPLUS
static void
objc_generate_cxx_ctor_or_dtor (bool dtor)
{
  tree fn, body, compound_stmt, ivar;

  /* - (id) .cxx_construct { ... return self; } */
  /* - (void) .cxx_construct { ... }            */

  objc_set_method_type (MINUS_EXPR);
  objc_start_method_definition
   (objc_build_method_signature (build_tree_list (NULL_TREE,
						  dtor
						  ? void_type_node
						  : objc_object_type),
				 get_identifier (dtor
						 ? TAG_CXX_DESTRUCT
						 : TAG_CXX_CONSTRUCT),
				 make_node (TREE_LIST),
				 /* APPLE LOCAL radar 3803157 - objc attribute */
				 false), NULL_TREE);
  body = begin_function_body ();
  compound_stmt = begin_compound_stmt (0);

  ivar = CLASS_IVARS (implementation_template);
  /* Destroy ivars in reverse order.  */
  if (dtor)
    ivar = nreverse (copy_list (ivar));

  for (; ivar; ivar = TREE_CHAIN (ivar))
    {
      if (TREE_CODE (ivar) == FIELD_DECL)
	{
	  tree type = TREE_TYPE (ivar);

	  /* Call the ivar's default constructor or destructor.  Do not
	     call the destructor unless a corresponding constructor call
	     has also been made (or is not needed).  */
	  if (IS_AGGR_TYPE (type)
	      && (dtor
		  ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
		     && (!TYPE_NEEDS_CONSTRUCTING (type)
			 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
		  : (TYPE_NEEDS_CONSTRUCTING (type)
		     && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
	    finish_expr_stmt
	     (build_special_member_call
	      (build_ivar_reference (DECL_NAME (ivar)),
	       dtor ? complete_dtor_identifier : complete_ctor_identifier,
	       NULL_TREE, type, LOOKUP_NORMAL));
	}
    }

  /* The constructor returns 'self'.  */
  if (!dtor)
    finish_return_stmt (self_decl);

  finish_compound_stmt (compound_stmt);
  finish_function_body (body);
  fn = current_function_decl;
  finish_function ();
  objc_finish_method_definition (fn);
}

/* The following routine will examine the current @interface for any
   non-POD C++ ivars requiring non-trivial construction and/or
   destruction, and then synthesize special '- .cxx_construct' and/or
   '- .cxx_destruct' methods which will run the appropriate
   construction or destruction code.  Note that ivars inherited from
   super-classes are _not_ considered.  */
static void
objc_generate_cxx_cdtors (void)
{
  bool need_ctor = false, need_dtor = false;
  tree ivar;

  /* APPLE LOCAL begin radar 4407151 */
  /* Error case, due to possibly an extra @end. */
  if (!objc_implementation_context)
    return;
  /* APPLE LOCAL end radar 4407151 */

  /* We do not want to do this for categories, since they do not have
     their own ivars.  */

  if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
    return;

  /* First, determine if we even need a constructor and/or destructor.  */

  for (ivar = CLASS_IVARS (implementation_template); ivar;
       ivar = TREE_CHAIN (ivar))
    {
      if (TREE_CODE (ivar) == FIELD_DECL)
	{
	  tree type = TREE_TYPE (ivar);

	  if (IS_AGGR_TYPE (type))
	    {
	      if (TYPE_NEEDS_CONSTRUCTING (type)
		  && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
		/* NB: If a default constructor is not available, we will not
		   be able to initialize this ivar; the add_instance_variable()
		   routine will already have warned about this.  */
		need_ctor = true;

	      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
		  && (!TYPE_NEEDS_CONSTRUCTING (type)
		      || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
		/* NB: If a default constructor is not available, we will not
		   call the destructor either, for symmetry.  */
		need_dtor = true;
	    }
	}
    }

  /* Generate '- .cxx_construct' if needed.  */

  if (need_ctor)
    objc_generate_cxx_ctor_or_dtor (false);

  /* Generate '- .cxx_destruct' if needed.  */

  if (need_dtor)
    objc_generate_cxx_ctor_or_dtor (true);

  /* The 'imp_list' variable points at an imp_entry record for the current
     @implementation.  Record the existence of '- .cxx_construct' and/or
     '- .cxx_destruct' methods therein; it will be included in the
     metadata for the class.  */
  if (flag_next_runtime)
    imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
}
#endif

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

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

   The NeXT runtime fixes up all protocols at program startup time,
   before main() is entered.  It uses a low-level trick to look up all
   those symbols, then loops on them and fixes them up.

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

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

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

  for (p = protocol_chain; p; p = TREE_CHAIN (p))
    {
      /* APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions */
      tree save_objc_implementation_context;
      tree nst_methods = PROTOCOL_NST_METHODS (p);
      tree cls_methods = PROTOCOL_CLS_METHODS (p);

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

      if (!decl)
	continue;

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

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

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

	  cls_methods = TREE_CHAIN (cls_methods);
	}
      /* APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions */
      generate_method_descriptors (p, false);

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

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

      if (refs_decl)
	refs_expr = convert (build_pointer_type (build_pointer_type
						 (objc_protocol_template)),
			     build_unary_op (ADDR_EXPR, refs_decl, 0));
      else
      /* APPLE LOCAL begin radar 6285794 */
        refs_expr =
          convert (build_pointer_type (build_pointer_type (objc_protocol_template)),
                   integer_zero_node);
      /* APPLE LOCAL end radar 6285794 */
      /* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
      save_objc_implementation_context = objc_implementation_context;
      objc_implementation_context = p;
      generate_v2_property_tables (p);
      objc_implementation_context = save_objc_implementation_context;

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

          cls_methods = TREE_CHAIN (cls_methods);
        }
      generate_method_descriptors (p, true);
      UOBJC_PROTOCOL_EXT_decl = generate_objc_protocol_extension (p, 
				  UOBJC_PROTOCOL_OPT_NST_METHODS_decl,
				  UOBJC_PROTOCOL_OPT_CLS_METHODS_decl, 
				  UOBJC_V2_PROPERTY_decl);

      /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
	 by generate_method_descriptors, which is called above.  */
      initlist = build_protocol_initializer (TREE_TYPE (decl),
					     protocol_name_expr, refs_expr,
					     UOBJC_INSTANCE_METHODS_decl,
					     /* APPLE LOCAL ObjC new abi */
					     UOBJC_CLASS_METHODS_decl, false, NULL_TREE,
					     /* APPLE LOCAL radar 4695109 */
					     UOBJC_PROTOCOL_EXT_decl, NULL_TREE);
      /* APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions */
      /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
      /* Force 4 byte alignment for protocols */
      DECL_ALIGN(decl) = 32;
      DECL_USER_ALIGN(decl) = 1;
#endif

      finish_var_decl (decl, initlist);

#ifdef ENABLE_LLVM
      /* At -O0, we may have emitted references to the decl earlier. */
      if (!optimize)
        reset_initializer_llvm(decl);
#endif
      /* LLVM LOCAL end */
    }
}

static tree
build_protocol_initializer (tree type, tree protocol_name,
			    tree protocol_list, tree instance_methods,
			    /* APPLE LOCAL ObjC new abi */
			    tree class_methods, bool newabi, tree property_list,
/* APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions - radar 4695109 */
			    tree objc_protocol_or_opt_ins_meth, tree opt_cls_meth)
{
  tree initlist = NULL_TREE, expr;
  /* APPLE LOCAL begin ObjC new abi */
  /* APPLE LOCAL begin radar 4533974 - ObjC new protocol */
  /* APPLE LOCAL begin radar 4533974 - ObjC newprotocol - radar 4695109 */
  if (newabi)
    {
      /* 'isa' is NULL in the new ObjC abi */
      /* APPLE LOCAL begin radar 6285794 */
      expr = convert (objc_object_type, integer_zero_node);
      /* APPLE LOCAL end radar 6285794 */
    }
  /* APPLE LOCAL end radar 4533974 - ObjC newprotocol - radar 4695109 */
  /* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
  /* "isa" field now points to struct _objc_protocol_extension * */
  else
    {
      if (!objc_protocol_or_opt_ins_meth)
        /* APPLE LOCAL begin radar 6285794 */
        {
          if (!objc_protocol_extension_template)
            build_objc_protocol_extension_template ();    
          
          expr =
            convert (build_pointer_type (objc_protocol_extension_template),
                     integer_zero_node);
        }
        /* APPLE LOCAL end radar 6285794 */
      else
	expr = convert (build_pointer_type (objc_protocol_extension_template),
			build_unary_op (ADDR_EXPR, objc_protocol_or_opt_ins_meth, 0));	
    }
  /* APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions */

  initlist = tree_cons (NULL_TREE, expr, initlist);
  /* APPLE LOCAL end radar 4533974 - ObjC new protocol */
  /* APPLE LOCAL end ObjC new abi */
  initlist = tree_cons (NULL_TREE, protocol_name, initlist);
  initlist = tree_cons (NULL_TREE, protocol_list, initlist);

  if (!instance_methods)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (objc_method_proto_list_ptr,
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_method_proto_list_ptr,
		      build_unary_op (ADDR_EXPR, instance_methods, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }

  if (!class_methods)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (objc_method_proto_list_ptr,
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_method_proto_list_ptr,
		      build_unary_op (ADDR_EXPR, class_methods, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }

  /* APPLE LOCAL begin C* property metadata (Radar 4498373) */
  if (newabi)
    {
      /* APPLE LOCAL begin radar 4695109 */
      if (!objc_protocol_or_opt_ins_meth)
        /* APPLE LOCAL begin radar 6285794 */
        initlist = tree_cons (NULL_TREE,
                              convert (objc_method_proto_list_ptr,
                                       integer_zero_node),
                              initlist);
        /* APPLE LOCAL end radar 6285794 */
      else
	{
	  expr = convert (objc_method_proto_list_ptr,
			  build_unary_op (ADDR_EXPR, objc_protocol_or_opt_ins_meth, 0));
	  initlist = tree_cons (NULL_TREE, expr, initlist);
	}
      if (!opt_cls_meth)
        /* APPLE LOCAL begin radar 6285794 */
        initlist = tree_cons (NULL_TREE,
                              convert (objc_method_proto_list_ptr,
                                       integer_zero_node),
                              initlist);
        /* APPLE LOCAL end radar 6285794 */
      else
	{
	  expr = convert (objc_method_proto_list_ptr,
			  build_unary_op (ADDR_EXPR, opt_cls_meth, 0));
	  initlist = tree_cons (NULL_TREE, expr, initlist);
	}
      /* APPLE LOCAL end radar 4695109 */
      if (!property_list)
        /* APPLE LOCAL begin radar 6285794 */
        initlist = tree_cons (NULL_TREE,
                              convert (objc_prop_list_ptr,
                                       integer_zero_node),
                              initlist);
        /* APPLE LOCAL end radar 6285794 */
      else
	{
	  expr = convert (objc_prop_list_ptr,
			  build_unary_op (ADDR_EXPR, property_list, 0));
	  initlist = tree_cons (NULL_TREE, expr, initlist);
	}
      /* APPLE LOCAL begin radar 5192466 */
      /* const uint32_t size;  = sizeof(struct protocol_t) */
      expr = build_int_cst (
	      NULL_TREE, 
	      TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_protocol_template)));
      initlist = tree_cons (NULL_TREE, expr, initlist);
      /* const uint32_t flags; = 0 */
      initlist = tree_cons (NULL_TREE, integer_zero_node, initlist);
      /* APPLE LOCAL end radar 5192466 */
    }
  /* APPLE LOCAL end C* property metadata (Radar 4498373) */
  return objc_build_constructor (type, nreverse (initlist));
}

/* struct _objc_category {
     char *category_name;
     char *class_name;
     struct _objc_method_list *instance_methods;
     struct _objc_method_list *class_methods;
     struct _objc_protocol_list *protocols;
     // APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions
     uint32_t size;	// sizeof (struct _objc_category)
     struct _objc_property_list *instance_properties;  // category's own @property decl.
     // APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions
   };   */

static void
build_category_template (void)
{
  tree field_decl, field_decl_chain;

  objc_category_template = start_struct (RECORD_TYPE,
					 get_identifier (UTAG_CATEGORY));

  /* char *category_name; */
  field_decl = create_field_decl (string_type_node, "category_name");
  field_decl_chain = field_decl;

  /* char *class_name; */
  field_decl = create_field_decl (string_type_node, "class_name");
  chainon (field_decl_chain, field_decl);

  /* struct _objc_method_list *instance_methods; */
  field_decl = create_field_decl (objc_method_list_ptr,
				  "instance_methods");
  chainon (field_decl_chain, field_decl);

  /* struct _objc_method_list *class_methods; */
  field_decl = create_field_decl (objc_method_list_ptr,
				  "class_methods");
  chainon (field_decl_chain, field_decl);

  /* struct _objc_protocol **protocol_list; */
  field_decl = create_field_decl (build_pointer_type
				  (build_pointer_type
				   (objc_protocol_template)),
				  "protocol_list");
  chainon (field_decl_chain, field_decl);

  /* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
  /*  uint32_t size; - sizeof (struct _objc_category) */
  field_decl = create_field_decl (integer_type_node, "size");
  chainon (field_decl_chain, field_decl);
  /*  struct _objc_property_list *instance_properties;  This field describes
      the category's @property declarations. Properties from inherited protocols
      are not included. */
  field_decl = create_field_decl (build_pointer_type (
				    xref_tag (RECORD_TYPE, 
					      get_identifier (UTAG_PROPERTY_LIST))), 
				  "instance_properties");
  chainon (field_decl_chain, field_decl);
  /* APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions */

  finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
}

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

static void
build_selector_template (void)
{

  tree field_decl, field_decl_chain;

  objc_selector_template
    = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));

  /* SEL sel_id; */
  field_decl = create_field_decl (objc_selector_type, "sel_id");
  field_decl_chain = field_decl;

  /* char *sel_type; */
  field_decl = create_field_decl (string_type_node, "sel_type");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
}

/* APPLE LOCAL begin ObjC new abi */

/* 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 field_decl, field_decl_chain;

  objc_v2_category_template = start_struct (RECORD_TYPE,
                                         get_identifier ("_category_t"));

  /* char *name; */
  field_decl = create_field_decl (string_type_node, "name");
  field_decl_chain = field_decl;

  /* struct class_t *const cls; */
  field_decl = create_field_decl (build_pointer_type (objc_v2_class_template), 
				  "cls");
  chainon (field_decl_chain, field_decl);

  /* struct method_list_t *instance_methods; */
  field_decl = create_field_decl (objc_method_list_ptr,
                                  "instance_methods");
  chainon (field_decl_chain, field_decl);

  /* struct method_list_t *class_methods; */
  field_decl = create_field_decl (objc_method_list_ptr,
                                  "class_methods");
  chainon (field_decl_chain, field_decl);

  /* struct protocol_list_t *protocol_list; */
  field_decl = create_field_decl (build_pointer_type
                                   (objc_v2_protocol_template),
                                  "protocol_list");
  chainon (field_decl_chain, field_decl);

  /* APPLE LOCAL begin C* property metadata (Radar 4498373) */
  /* struct _prop_list_t * properties; */
  field_decl = create_field_decl (objc_prop_list_ptr,
				  "properties");
  chainon (field_decl_chain, field_decl);
  /* APPLE LOCAL end C* property metadata (Radar 4498373) */
  finish_struct (objc_v2_category_template, field_decl_chain, NULL_TREE);
}


/* Build following types which represent each class implemenation.

  struct class_t {
    struct class_t *isa;
    // APPLE LOCAL radar 4705214
    struct class_t * const superclass;
    __strong void *cache;
    __strong IMP *vtable;
    // APPLE LOCAL radar 4705214
    __strong struct class_ro_t *ro;
  };

  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;
    // APPLE LOCAL radar 4705214
    // - Moved to: 'struct class_t' struct class_t * const superclass;

    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;
    // APPLE LOCAL radar 4695101
    const uint8_t * const weakIvarLayout;
    const struct _prop_list_t * const properties;
  };  */

static void
build_v2_class_template (void)
{
  tree field_decl, field_decl_chain;

  objc_v2_class_ro_template
    = start_struct (RECORD_TYPE, get_identifier (UTAG_V2_CLASS_RO));

  objc_v2_class_template
    = start_struct (RECORD_TYPE, get_identifier (UTAG_V2_CLASS));

  /* struct class_t *isa; */
  field_decl = create_field_decl (build_pointer_type (objc_v2_class_template),
				  "isa");
  field_decl_chain = field_decl;

  /* struct class_t * const superclass */
  field_decl = create_field_decl (build_pointer_type (objc_v2_class_template),
				  "superclass");
  chainon (field_decl_chain, field_decl);

  /* __strong void *cache; */
  /* TODO: __strong is missing. */
  field_decl = create_field_decl (build_pointer_type (void_type_node),
				  "cache");
  chainon (field_decl_chain, field_decl);
  
  /* __strong IMP *vtable; */
  /* TODO: __strong is missing. */
  field_decl = create_field_decl (build_pointer_type (objc_imp_type),
				  "vtable");
  chainon (field_decl_chain, field_decl);

  /* __strong struct class_ro_t *ro; */
  /* TODO: __strong is missing. */
  field_decl = create_field_decl (build_pointer_type (objc_v2_class_ro_template),
				  "ro");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_v2_class_template, field_decl_chain, NULL_TREE);

  /* struct class_ro_t {...} */
  
  /* uint32_t const flags; */
  field_decl = create_field_decl (integer_type_node, "flags");
  field_decl_chain = field_decl;

  /* uint32_t const instanceStart */
  field_decl = create_field_decl (integer_type_node, "instanceStart");
  chainon (field_decl_chain, field_decl);

  /* uint32_t const instanceSize */
  field_decl = create_field_decl (integer_type_node, "instanceSize");
  chainon (field_decl_chain, field_decl);
  
  if (TARGET_64BIT)
    {
      /* uint32_t const reserved */
      field_decl = create_field_decl (integer_type_node, "reserved");
      chainon (field_decl_chain, field_decl);
    }

  /* const uint8_t * const ivarLayout */
  /* APPLE LOCAL 4695101 */
  field_decl = create_field_decl (string_type_node, 
				  "ivarLayout");
  chainon (field_decl_chain, field_decl);

  /* const char *const name; */
  field_decl = create_field_decl (string_type_node, "name");
  chainon (field_decl_chain, field_decl);
  
  /* const struct method_list_t * const baseMethods */
  field_decl = create_field_decl (objc_method_list_ptr,
				  "baseMethods");
  chainon (field_decl_chain, field_decl);

  /* const struct objc_protocol_list *const baseProtocols */
  field_decl = create_field_decl (build_pointer_type 
				  (xref_tag (RECORD_TYPE, 
					     get_identifier
					     (UTAG_V2_PROTOCOL_LIST))),
				  "baseProtocols");
  chainon (field_decl_chain, field_decl);

  /* const struct ivar_list_t *const ivars */
  field_decl = create_field_decl (objc_v2_ivar_list_ptr,
				  "ivars");  
  chainon (field_decl_chain, field_decl);

  /* APPLE LOCAL begin radar 4695101 */
  /* const uint8_t * const weakIvarLayout; */
  field_decl = create_field_decl (string_type_node, "weakIvarLayout");
  chainon (field_decl_chain, field_decl);
  /* APPLE LOCAL end radar 4695101 */

  /* APPLE LOCAL begin C* property metadata (Radar 4498373) */
  /* struct _prop_list_t * properties */
  field_decl = create_field_decl (objc_prop_list_ptr,
				  "properties");
  chainon (field_decl_chain, field_decl);
  /* APPLE LOCAL end C* property metadata (Radar 4498373) */
   finish_struct (objc_v2_class_ro_template, field_decl_chain, NULL_TREE);
}
/* APPLE LOCAL end ObjC new abi */

/* struct _objc_class {
     struct _objc_class *isa;
     struct _objc_class *super_class;
     char *name;
     long version;
     long info;
     long instance_size;
     struct _objc_ivar_list *ivars;
     struct _objc_method_list *methods;
     #ifdef __NEXT_RUNTIME__
       struct objc_cache *cache;
     #else
       struct sarray *dtable;
       struct _objc_class *subclass_list;
       struct _objc_class *sibling_class;
     #endif
     struct _objc_protocol_list *protocols;
     // APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions
     #ifdef __NEXT_RUNTIME__
       const char *ivar_layout;
       struct _objc_class_ext  *ext;
     #else
       void *gc_object_type;
     #endif
     // APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions
   };  */

/* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
   the NeXT/Apple runtime; still, the compiler must generate them to
   maintain backward binary compatibility (and to allow for future
   expansion).  */

static void
build_class_template (void)
{
  tree field_decl, field_decl_chain;

  objc_class_template
    = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));

  /* struct _objc_class *isa; */
  field_decl = create_field_decl (build_pointer_type (objc_class_template),
				  "isa");
  field_decl_chain = field_decl;

  /* struct _objc_class *super_class; */
  field_decl = create_field_decl (build_pointer_type (objc_class_template),
				  "super_class");
  chainon (field_decl_chain, field_decl);

  /* char *name; */
  field_decl = create_field_decl (string_type_node, "name");
  chainon (field_decl_chain, field_decl);

  /* long version; */
  field_decl = create_field_decl (long_integer_type_node, "version");
  chainon (field_decl_chain, field_decl);

  /* long info; */
  field_decl = create_field_decl (long_integer_type_node, "info");
  chainon (field_decl_chain, field_decl);

  /* long instance_size; */
  field_decl = create_field_decl (long_integer_type_node, "instance_size");
  chainon (field_decl_chain, field_decl);

  /* struct _objc_ivar_list *ivars; */
  field_decl = create_field_decl (objc_ivar_list_ptr,
				  "ivars");
  chainon (field_decl_chain, field_decl);

  /* struct _objc_method_list *methods; */
  field_decl = create_field_decl (objc_method_list_ptr,
				  "methods");
  chainon (field_decl_chain, field_decl);

  if (flag_next_runtime)
    {
      /* struct objc_cache *cache; */
      field_decl = create_field_decl (build_pointer_type
				      (xref_tag (RECORD_TYPE,
						 get_identifier
						 ("objc_cache"))),
				      "cache");
      chainon (field_decl_chain, field_decl);
    }
  else
    {
      /* struct sarray *dtable; */
      field_decl = create_field_decl (build_pointer_type
				      (xref_tag (RECORD_TYPE,
						 get_identifier
						 ("sarray"))),
				      "dtable");
      chainon (field_decl_chain, field_decl);

      /* struct objc_class *subclass_list; */
      field_decl = create_field_decl (build_pointer_type
				      (objc_class_template),
				      "subclass_list");
      chainon (field_decl_chain, field_decl);

      /* struct objc_class *sibling_class; */
      field_decl = create_field_decl (build_pointer_type
				      (objc_class_template),
				      "sibling_class");
      chainon (field_decl_chain, field_decl);
    }

  /* struct _objc_protocol **protocol_list; */
  field_decl = create_field_decl (build_pointer_type
				  (build_pointer_type
				   (xref_tag (RECORD_TYPE,
					     get_identifier
					     (UTAG_PROTOCOL)))),
				  "protocol_list");
  chainon (field_decl_chain, field_decl);

  /* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
  if (flag_next_runtime)
    {
      /* const char *ivar_layout; */
      field_decl = create_field_decl (string_type_node, "ivar_layout");
      chainon (field_decl_chain, field_decl);

      /* struct _objc_class_ext *ext; */
      field_decl = create_field_decl (build_pointer_type (
					xref_tag (RECORD_TYPE, 
						  get_identifier 
						  (UTAG_CLASS_EXT))),
				      "ext");
      chainon (field_decl_chain, field_decl);
    }
  else
    {
      /* void *gc_object_type; */
      field_decl = create_field_decl (build_pointer_type (void_type_node),
				      "gc_object_type");
      chainon (field_decl_chain, field_decl);
    }
  /* APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions */

  finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
}

/* Generate appropriate forward declarations for an implementation.  */

static void
synth_forward_declarations (void)
{
  tree an_id;

  /* static struct objc_class _OBJC_CLASS_<my_name>; */
  UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
					  /* APPLE LOCAL radar 5202926 */
					  objc_class_template, false);

  /* static struct objc_class _OBJC_METACLASS_<my_name>; */
  UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
						  /* APPLE LOCAL radar 5202926 */
						  objc_class_template, false);

  /* Pre-build the following entities - for speed/convenience.  */

  an_id = get_identifier ("super_class");
  ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
  uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
}

/* APPLE LOCAL begin ObjC abi v2 */
/* Generate appropriate forward declarations for an implementation.  */

static void
synth_v2_forward_declarations (void)
{
  /* struct class_t OBJC_CLASS_$_<my_name>; */
  UOBJC_V2_CLASS_decl = build_metadata_decl ("OBJC_CLASS_$",
					     /* APPLE LOCAL radar 5202926 */
                                             objc_v2_class_template, true);

 /* struct class_t OBJC_METACLASS_$_<my_name>; */
 UOBJC_V2_METACLASS_decl = build_metadata_decl ("OBJC_METACLASS_$",
						/* APPLE LOCAL radar 5202926 */
                                                objc_v2_class_template, true);
}

static void
/* APPLE LOCAL end ObjC abi v2 */
error_with_ivar (const char *message, tree decl)
{
  error ("%J%s %qs", decl,
         message, gen_declaration (decl));

}

static void
check_ivars (tree inter, tree imp)
{
  tree intdecls = CLASS_RAW_IVARS (inter);
  tree impdecls = CLASS_RAW_IVARS (imp);

  while (1)
    {
      tree t1, t2;

#ifdef OBJCPLUS
      if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
	intdecls = TREE_CHAIN (intdecls);
#endif
      if (intdecls == 0 && impdecls == 0)
	break;
      if (intdecls == 0 || impdecls == 0)
	{
	  error ("inconsistent instance variable specification");
	  break;
	}

      t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);

      if (!comptypes (t1, t2)
	  || !tree_int_cst_equal (DECL_INITIAL (intdecls),
				  DECL_INITIAL (impdecls)))
	{
	  if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
	    {
	      error_with_ivar ("conflicting instance variable type",
			       impdecls);
	      error_with_ivar ("previous declaration of",
			       intdecls);
	    }
	  else			/* both the type and the name don't match */
	    {
	      error ("inconsistent instance variable specification");
	      break;
	    }
	}

      else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
	{
	  error_with_ivar ("conflicting instance variable name",
			   impdecls);
	  error_with_ivar ("previous declaration of",
			   intdecls);
	}

      intdecls = TREE_CHAIN (intdecls);
      impdecls = TREE_CHAIN (impdecls);
    }
}

/* APPLE LOCAL begin ObjC new abi */
/* 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_message_ref_template (void)
{
  tree ptr_message_ref_t;
  tree field_decl, field_decl_chain;
  /* struct _message_ref_t {...} */
  objc_v2_message_ref_template = start_struct (RECORD_TYPE, 
						   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 (objc_object_type,
                                tree_cons (NULL_TREE, objc_object_type,
                                           tree_cons (NULL_TREE, ptr_message_ref_t,
                                                      NULL_TREE))));
  field_decl = create_field_decl (objc_v2_imp_type, "messenger");
  field_decl_chain = field_decl;

  /* SEL name; */
  field_decl = create_field_decl (objc_selector_type, "name");
  chainon (field_decl_chain, field_decl); 

  finish_struct (objc_v2_message_ref_template, field_decl_chain, NULL_TREE);
  objc_v2_selector_type = build_pointer_type (objc_v2_message_ref_template);

  /* struct _super_message_ref_t {...} */
  objc_v2_super_message_ref_template = start_struct (RECORD_TYPE, 
						         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 (objc_object_type,
                                tree_cons (NULL_TREE, objc_super_type,
                                           tree_cons (NULL_TREE, ptr_message_ref_t,
                                                      NULL_TREE))));
  field_decl = create_field_decl (objc_v2_super_imp_type, "messenger");
  field_decl_chain = field_decl;

  /* SEL name; */
  field_decl = create_field_decl (objc_selector_type, "name");
  chainon (field_decl_chain, field_decl); 

  finish_struct (objc_v2_super_message_ref_template, field_decl_chain, NULL_TREE);
  objc_v2_super_selector_type = build_pointer_type (objc_v2_super_message_ref_template);
}
/* APPLE LOCAL end ObjC new abi */

/* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
   This needs to be done just once per compilation.  */

/* APPLE LOCAL begin ObjC abi v2 */
/* struct _objc_super {
     struct _objc_object *self;
     struct _objc_class *cls;   // or Class cls; for the abi v2
   };  */
/* APPLE LOCAL end ObjC abi v2 */

static void
build_super_template (void)
{
  tree field_decl, field_decl_chain;

  objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));

  /* struct _objc_object *self; */
  field_decl = create_field_decl (objc_object_type, "self");
  field_decl_chain = field_decl;

  /* APPLE LOCAL begin ObjC abi v2 */
  if (flag_objc_abi == 2)
    {
      /* Class cls; */
      field_decl = create_field_decl (objc_class_type, "cls");
    }
  else
    {
      /* struct _objc_class *cls; */
      field_decl = create_field_decl (build_pointer_type (objc_class_template),
                                      "cls");
    }
  /* APPLE LOCAL end ObjC abi v2 */
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
}

/* APPLE LOCAL begin ObjC new abi */

/* 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 field_decl, field_decl_chain;

  objc_ivar_id = get_identifier ("_ivar_t");
  objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);

  /* uint32_t *offset */
  field_decl = create_field_decl (
		 /* APPLE LOCAL radar 4441049 */
		 build_pointer_type (TREE_TYPE (size_zero_node)), "offset");
  field_decl_chain = field_decl;

  /* char *name; */
  field_decl = create_field_decl (string_type_node, "name");
  chainon (field_decl_chain, field_decl);

  /* char *type; */
  field_decl = create_field_decl (string_type_node, "type");
  chainon (field_decl_chain, field_decl);

  /* uint32_t alignment; */
  field_decl = create_field_decl (integer_type_node, "alignment");
  chainon (field_decl_chain, field_decl);

  /* uint32_t size; */
  field_decl = create_field_decl (integer_type_node, "size");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);

  return objc_ivar_record;
}

/* Build up:

  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 field_decl, field_decl_chain;

  objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);

  /* uint32 entsize; */
  field_decl = create_field_decl (integer_type_node, "entsize");
  field_decl_chain = field_decl;

  /* uint32 count; */
  field_decl = create_field_decl (integer_type_node, "count");
  chainon (field_decl_chain, field_decl);

  /* struct objc_ivar ivar_list[]; */
  field_decl = create_field_decl (build_array_type
                                  (list_type,
                                   build_index_type
                                   (build_int_cst (NULL_TREE, size - 1))),
                                  "list");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);

  return objc_ivar_list_record;

}
     
/* APPLE LOCAL end ObjC new abi */

/* struct _objc_ivar {
     char *ivar_name;
     char *ivar_type;
     int ivar_offset;
   };  */

static tree
build_ivar_template (void)
{
  tree objc_ivar_id, objc_ivar_record;
  tree field_decl, field_decl_chain;

  objc_ivar_id = get_identifier (UTAG_IVAR);
  objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);

  /* char *ivar_name; */
  field_decl = create_field_decl (string_type_node, "ivar_name");
  field_decl_chain = field_decl;

  /* char *ivar_type; */
  field_decl = create_field_decl (string_type_node, "ivar_type");
  chainon (field_decl_chain, field_decl);

  /* int ivar_offset; */
  field_decl = create_field_decl (integer_type_node, "ivar_offset");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);

  return objc_ivar_record;
}

/* struct {
     int ivar_count;
     struct objc_ivar ivar_list[ivar_count];
   };  */

static tree
build_ivar_list_template (tree list_type, int size)
{
  tree objc_ivar_list_record;
  tree field_decl, field_decl_chain;

  objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);

  /* int ivar_count; */
  field_decl = create_field_decl (integer_type_node, "ivar_count");
  field_decl_chain = field_decl;

  /* struct objc_ivar ivar_list[]; */
  field_decl = create_field_decl (build_array_type
				  (list_type,
				   build_index_type
				   (build_int_cst (NULL_TREE, size - 1))),
				  "ivar_list");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);

  return objc_ivar_list_record;
}

/* struct {
     struct _objc__method_prototype_list *method_next;
     int method_count;
     struct objc_method method_list[method_count];
   };  */

/* APPLE LOCAL begin ObjC new abi */
/* 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 field_decl, field_decl_chain;

  method_list_t_record = start_struct (RECORD_TYPE, NULL_TREE);

  /* uint32_t const entsize */
  field_decl = create_field_decl (integer_type_node, "entsize");

  field_decl_chain = field_decl;

  /* int method_count; */
  field_decl = create_field_decl (integer_type_node, "method_count");
  chainon (field_decl_chain, field_decl);

  /* struct objc_method method_list[]; */
  field_decl = create_field_decl (build_array_type
				  (list_type,
				   build_index_type
				   (build_int_cst (NULL_TREE, size - 1))),
				  "method_list");
  chainon (field_decl_chain, field_decl);

  finish_struct (method_list_t_record, field_decl_chain, NULL_TREE);

  return method_list_t_record;
}
static tree
/* APPLE LOCAL end ObjC new abi */
build_method_list_template (tree list_type, int size)
{
  tree objc_ivar_list_record;
  tree field_decl, field_decl_chain;

  objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);

  /* struct _objc__method_prototype_list *method_next; */
  field_decl = create_field_decl (objc_method_proto_list_ptr,
				  "method_next");
  field_decl_chain = field_decl;

  /* int method_count; */
  field_decl = create_field_decl (integer_type_node, "method_count");
  chainon (field_decl_chain, field_decl);

  /* struct objc_method method_list[]; */
  field_decl = create_field_decl (build_array_type
				  (list_type,
				   build_index_type
				   (build_int_cst (NULL_TREE, size - 1))),
				  "method_list");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);

  return objc_ivar_list_record;
}

/* APPLE LOCAL begin ObjC new abi */

/* APPLE LOCAL begin radar 4705298, 4843145 */

/* Return a class's visibility attribute string, or 
   NULL if it has no visibility attribute set. */

static const char *
objc_class_visibility (tree class)
{
  tree chain;
  /* APPLE LOCAL begin radar 4894756 */
  /* Handle very odd case of a class with no @interface but with @implementation only! */
  if (class && TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
    return NULL;
  /* APPLE LOCAL end radar 4894756 */
  gcc_assert (class && TREE_CODE (class) == CLASS_INTERFACE_TYPE);
  for (chain = CLASS_ATTRIBUTES (class); chain; chain = TREE_CHAIN (chain))
    if (is_attribute_p ("visibility", TREE_PURPOSE (chain)))
      return TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE ((chain))));
  return NULL;
}

/* Create a symbol whose visibility attribute matches that of 
   the given class. */

static tree
objc_create_global_decl_for_class (tree type, const char *name, tree class)
{
  tree decl = create_global_decl (type, name);
  const char *visibility = objc_class_visibility (class);

  if (visibility  &&  strcmp (visibility, "hidden") == 0) 
    {
      DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
      DECL_VISIBILITY_SPECIFIED (decl) = 1;
    } 
  else if (visibility  &&  strcmp (visibility, "default") == 0) 
    {
      DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
      DECL_VISIBILITY_SPECIFIED (decl) = 1;
    }

  return decl;
}
/* APPLE LOCAL end radar 4705298 , 4843145*/

/* This routine builds a name to hold ivar offset. It is of the form:
   .objc_ivar.CLASS_NAME.FIELD_DECL  */

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

  /* APPLE LOCAL radar 4540451 */
  sprintf (buf, "%s%s.%s", STRING_V2_IVAR_OFFSET_PREFIX,
	   IDENTIFIER_POINTER (class_name),
	   IDENTIFIER_POINTER (fname));
  return;
}

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

static tree
ivar_offset_ref (tree class_name, tree field_decl)
{
  tree decl;
  char buf[512];
  tree *chain;
  tree iter;
  bool global_var;
  tree field_decl_id;

  /* APPLE LOCAL radar 5610134 */
  gcc_assert (field_decl);
  create_ivar_offset_name (buf, class_name, field_decl);
  field_decl_id = get_identifier (buf);

  for (iter = ivar_offset_ref_chain; iter; iter = TREE_CHAIN (iter))
    {
      tree var = TREE_PURPOSE (iter);
      if (DECL_NAME (var) == field_decl_id)
	return var;
    }

  /* An existing offset symbol not found. Create a new one and add to the chain. */
  chain = &ivar_offset_ref_chain;
  /* APPLE LOCAL radar 4951615 */
  global_var =  IVAR_PUBLIC_OR_PROTECTED (field_decl);
  /* APPLE LOCAL begin radar 4441049 */
  /* APPLE LOCAL begin radar 4705298, 4843145 */
  decl = global_var ? 
         objc_create_global_decl_for_class (
	   TREE_TYPE (size_zero_node), buf, implementation_template) : 
	 create_hidden_decl (TREE_TYPE (size_zero_node), buf);
  /* APPLE LOCAL end radar 4705298 , 4843145*/
  /* APPLE LOCAL end radar 4441049 */

  while (*chain)
    chain = &TREE_CHAIN (*chain);

  /* APPLE LOCAL begin radar 4441049 */
  *chain = tree_cons (decl, byte_position (field_decl), NULL_TREE);
  /* APPLE LOCAL end radar 4441049 */
  
  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)
{
  tree initlist = NULL_TREE;
  int val;

  do {
    tree ivar = NULL_TREE;

    /* Unnamed bitfields are ignored. */
    if (!DECL_NAME (field_decl))
      {
        do
          field_decl = TREE_CHAIN (field_decl);
        while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
        continue;
      }

    /* Set offset */
    ivar = tree_cons (NULL_TREE, 
		      build_unary_op (ADDR_EXPR, ivar_offset_ref (class_name, field_decl), 0), 
		      ivar);

    /* Set name */
    /* APPLE LOCAL begin radar 5724385 */
    /* At this point fields must be named (no unnamed bitfield, that is) */
    gcc_assert (DECL_NAME (field_decl));
    ivar = tree_cons (NULL_TREE,
                      add_objc_string (DECL_NAME (field_decl),
                                       meth_var_names), ivar);
    /* APPLE LOCAL end radar 5724385 */

    /* Set type */
    encode_field_decl (field_decl,
		       obstack_object_size (&util_obstack),
		       OBJC_ENCODE_DONT_INLINE_DEFS);
    /* Null terminate string.  */
    obstack_1grow (&util_obstack, 0);
    ivar
      = tree_cons
          (NULL_TREE,
           add_objc_string (get_identifier (obstack_finish (&util_obstack)),
                            meth_var_types),
           ivar);
    obstack_free (&util_obstack, util_firstobj);

    /* Set alignment */
    /* APPLE LOCAL begin radar 5724385 */
    val = TYPE_ALIGN_UNIT (
            DECL_BIT_FIELD_TYPE (field_decl) ? DECL_BIT_FIELD_TYPE (field_decl) : 
            TREE_TYPE (field_decl));
    /* APPLE LOCAL end radar 5724385 */
    val = exact_log2 (val);
    ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, val), ivar);

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

    initlist = tree_cons (NULL_TREE,
			  objc_build_constructor (type, nreverse (ivar)),
			  initlist);

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

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

static tree
/* APPLE LOCAL end ObjC new abi */
build_ivar_list_initializer (tree type, tree field_decl)
{
  tree initlist = NULL_TREE;

  do
    {
      tree ivar = NULL_TREE;

      /* Set name.  */
      if (DECL_NAME (field_decl))
	ivar = tree_cons (NULL_TREE,
			  add_objc_string (DECL_NAME (field_decl),
					   meth_var_names),
			  ivar);
      else
	/* Unnamed bit-field ivar (yuck).  */
        /* APPLE LOCAL begin radar 6285794 */
        ivar = tree_cons (NULL_TREE,
                          convert (string_type_node,
                                   integer_zero_node),
                          ivar);
        /* APPLE LOCAL end radar 6285794 */

      /* Set type.  */
      encode_field_decl (field_decl,
			 obstack_object_size (&util_obstack),
			 OBJC_ENCODE_DONT_INLINE_DEFS);

      /* Null terminate string.  */
      obstack_1grow (&util_obstack, 0);
      ivar
	= tree_cons
	  (NULL_TREE,
	   add_objc_string (get_identifier (obstack_finish (&util_obstack)),
			    meth_var_types),
	   ivar);
      obstack_free (&util_obstack, util_firstobj);

      /* Set offset.  */
      /* LLVM LOCAL - begin make initializer size match type size */
      ivar = tree_cons (NULL_TREE, convert (integer_type_node,
                                            byte_position (field_decl)), ivar);
      /* LLVM LOCAL - end make initializer size match type size */
      initlist = tree_cons (NULL_TREE,
			    objc_build_constructor (type, nreverse (ivar)),
			    initlist);
      do
	field_decl = TREE_CHAIN (field_decl);
      while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
    }
  while (field_decl);

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

static tree
generate_ivars_list (tree type, const char *name, int size, tree list)
{
  tree decl, initlist;

  decl = start_var_decl (type, synth_id_with_class_suffix
			       (name, objc_implementation_context));

  initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
  initlist = tree_cons (NULL_TREE, list, initlist);

  finish_var_decl (decl,
		   objc_build_constructor (TREE_TYPE (decl),
					   nreverse (initlist)));

  return decl;
}

/* Count only the fields occurring in T.  */

static int
ivar_list_length (tree t)
{
  int count = 0;

  for (; t; t = TREE_CHAIN (t))
    if (TREE_CODE (t) == FIELD_DECL)
      ++count;

  return count;
}

/* APPLE LOCAL begin ObjC new abi */

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

static void
generate_v2_ivar_offset_ref_lists (void)
{
  tree chain;

  for (chain = ivar_offset_ref_chain; chain; chain = TREE_CHAIN (chain))
    {
      tree decl = TREE_PURPOSE (chain);
      tree offset = TREE_VALUE (chain);
      finish_var_decl (decl, offset);      
      /* LLVM LOCAL begin - radar 5698757 */
#ifdef ENABLE_LLVM
      /* Reset the initializer for this reference as it may have changed with
         -O0  */
      if (!optimize)
        reset_initializer_llvm (decl);
#endif
      /* LLVM LOCAL end - radar 5698757 */
    }
}

/* This routine declares a static variable of type 'struct ivar_list_t' and initializes
   it. TYPE is 'struct ivar_list_t'. NAME is the suffix for the variable. SIZE is
   number of ivars. LIST is the initializer list for list data member of 
   'struct ivar_list_t'. IVAR_T_SIZE is size of (struct ivar_t). */

static tree
generate_v2_ivars_list (tree type, const char *name, int ivar_t_size,
			    int size, tree list)
{
  tree decl, initlist;
  /* APPLE LOCAL begin radar 6064186 */
  const char *ref_name = synth_id_with_class_suffix (name, objc_implementation_context);
  decl = start_var_decl (type, ref_name);
  set_user_assembler_name (decl, ref_name);
  /* APPLE LOCAL end radar 6064186 */

  initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, ivar_t_size));

  initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);

  initlist = tree_cons (NULL_TREE, list, initlist);

  finish_var_decl (decl,
		   objc_build_constructor (TREE_TYPE (decl),
					   nreverse (initlist)));

  return decl;
}

/* This is the top-level routine to build and initialize meta-data for both class and
   instance variables.  */

static void
generate_v2_ivar_lists (void)
{
  tree initlist, ivar_list_template, chain;
  int size;

  generating_instance_variables = 1;

  /* build:  struct ivar_t {...}; type if not already done so. */
  if (!objc_v2_ivar_template)
    objc_v2_ivar_template = build_v2_ivar_t_template ();

  /* Currently there is 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. */

  UOBJC_V2_CLASS_VARIABLES_decl = 0;

  chain = CLASS_IVARS (implementation_template);
  if (chain)
    {
      /* APPLE LOCAL begin radar 5724385 */
      /* Only named data fields are generated. 'size' is this count. */
      tree field_decl = chain;
      size = 0;
      while (field_decl) {
	if (TREE_CODE (field_decl) == FIELD_DECL && DECL_NAME (field_decl))
	  size++;
	field_decl = TREE_CHAIN (field_decl);
      }
      /* APPLE LOCAL end radar 5724385 */
      ivar_list_template = build_v2_ivar_list_t_template (objc_v2_ivar_template, 
							      size);
      initlist = build_v2_ivar_list_initializer (CLASS_NAME (implementation_template),
						     objc_v2_ivar_template, chain);

      UOBJC_V2_INSTANCE_VARIABLES_decl
	/* APPLE LOCAL radar 6064186 */
        = generate_v2_ivars_list (ivar_list_template, "l_OBJC_$_INSTANCE_VARIABLES",
				      TREE_INT_CST_LOW (
				   	TYPE_SIZE_UNIT (objc_v2_ivar_template)),
                               	      size, initlist);
    }
  else
    UOBJC_V2_INSTANCE_VARIABLES_decl = 0;

  generating_instance_variables = 0;
}

static void
/* APPLE LOCAL end ObjC new abi */
generate_ivar_lists (void)
{
  tree initlist, ivar_list_template, chain;
  int size;

  generating_instance_variables = 1;

  if (!objc_ivar_template)
    objc_ivar_template = build_ivar_template ();

  /* Only generate class variables for the root of the inheritance
     hierarchy since these will be the same for every class.  */

  if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
      && (chain = TYPE_FIELDS (objc_class_template)))
    {
      size = ivar_list_length (chain);

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

      UOBJC_CLASS_VARIABLES_decl
	= generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
			       size, initlist);
    }
  else
    UOBJC_CLASS_VARIABLES_decl = 0;

  chain = CLASS_IVARS (implementation_template);
  if (chain)
    {
      size = ivar_list_length (chain);
      ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
      initlist = build_ivar_list_initializer (objc_ivar_template, chain);

      UOBJC_INSTANCE_VARIABLES_decl
	= generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
			       size, initlist);
    }
  else
    UOBJC_INSTANCE_VARIABLES_decl = 0;

  generating_instance_variables = 0;
}

static tree
build_dispatch_table_initializer (tree type, tree entries)
{
  tree initlist = NULL_TREE;

  do
    {
      tree elemlist = NULL_TREE;

      elemlist = tree_cons (NULL_TREE,
			    build_selector (METHOD_SEL_NAME (entries)),
			    NULL_TREE);

      /* Generate the method encoding if we don't have one already.  */
      if (! METHOD_ENCODING (entries))
	METHOD_ENCODING (entries) =
	  encode_method_prototype (entries);

      elemlist = tree_cons (NULL_TREE,
			    add_objc_string (METHOD_ENCODING (entries),
					     meth_var_types),
			    elemlist);

      elemlist
	= tree_cons (NULL_TREE,
		     convert (ptr_type_node,
			      build_unary_op (ADDR_EXPR,
					      METHOD_DEFINITION (entries), 1)),
		     elemlist);

      initlist = tree_cons (NULL_TREE,
			    objc_build_constructor (type, nreverse (elemlist)),
			    initlist);

      entries = TREE_CHAIN (entries);
    }
  while (entries);

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

/* To accomplish method prototyping without generating all kinds of
   inane warnings, the definition of the dispatch table entries were
   changed from:

	struct objc_method { SEL _cmd; ...; id (*_imp)(); };
   to:
	struct objc_method { SEL _cmd; ...; void *_imp; };  */

static tree
build_method_template (void)
{
  tree _SLT_record;
  tree field_decl, field_decl_chain;

  _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));

  /* SEL _cmd; */
  field_decl = create_field_decl (objc_selector_type, "_cmd");
  field_decl_chain = field_decl;

  /* char *method_types; */
  field_decl = create_field_decl (string_type_node, "method_types");
  chainon (field_decl_chain, field_decl);

  /* void *_imp; */
  field_decl = create_field_decl (build_pointer_type (void_type_node),
				  "_imp");
  chainon (field_decl_chain, field_decl);

  finish_struct (_SLT_record, field_decl_chain, NULL_TREE);

  return _SLT_record;
}


static tree
/* APPLE LOCAL ObjC new abi */
generate_dispatch_table (tree type, const char *name, int size, tree list, bool newabi)
{
  tree decl, initlist;
  /* APPLE LOCAL begin ObjC new abi */
  int init_val = newabi 
	         ? TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_method_template)) 
	         : 0;
  /* APPLE LOCAL end ObjC new abi */
  /* APPLE LOCAL begin radar 6064186 */
  const char* ref_name = synth_id_with_class_suffix (name, objc_implementation_context);
  decl = start_var_decl (type, ref_name);
  if (newabi)
    set_user_assembler_name (decl, ref_name);
  /* APPLE LOCAL end radar 6064186 */

  /* LLVM LOCAL - begin make initializer size match type size */
  /* APPLE LOCAL ObjC new abi */
#ifdef OBJCPLUS
  initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, init_val));
#else
  initlist = build_tree_list (NULL_TREE,
                              build_int_cst (newabi ? NULL_TREE : ptr_type_node,
					     init_val));
#endif
  /* LLVM LOCAL - end make initializer size match type size */
  initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
  initlist = tree_cons (NULL_TREE, list, initlist);

  finish_var_decl (decl,
		   objc_build_constructor (TREE_TYPE (decl),
					   nreverse (initlist)));

  return decl;
}

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

  for (impent = imp_list; impent; impent = impent->next)
    {
      chain = CLASS_CLS_METHODS (impent->imp_context);
      while (chain)
	{
	  cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
	  chain = TREE_CHAIN (chain);
	}

      chain = CLASS_NST_METHODS (impent->imp_context);
      while (chain)
	{
	  cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
	  chain = TREE_CHAIN (chain);
	}
    }
}

static void
generate_dispatch_tables (void)
{
  tree initlist, chain, method_list_template;
  int size;

  if (!objc_method_template)
    objc_method_template = build_method_template ();

  chain = CLASS_CLS_METHODS (objc_implementation_context);
  if (chain)
    {
      size = list_length (chain);

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

      /* APPLE LOCAL begin ObjC new abi */
      UOBJC_CLASS_METHODS_decl
	= generate_dispatch_table (method_list_template,
				   ((TREE_CODE (objc_implementation_context)
				     == CLASS_IMPLEMENTATION_TYPE)
				    ? "_OBJC_CLASS_METHODS"
				    : "_OBJC_CATEGORY_CLASS_METHODS"),
				   size, initlist, false);
      /* APPLE LOCAL end ObjC new abi */
    }
  else
    UOBJC_CLASS_METHODS_decl = 0;

  chain = CLASS_NST_METHODS (objc_implementation_context);
  if (chain)
    {
      size = list_length (chain);

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

      /* APPLE LOCAL begin ObjC new abi */
      if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
	UOBJC_INSTANCE_METHODS_decl
	  = generate_dispatch_table (method_list_template,
				     "_OBJC_INSTANCE_METHODS",
				     size, initlist, false);
      else
	/* We have a category.  */
	UOBJC_INSTANCE_METHODS_decl
	  = generate_dispatch_table (method_list_template,
				     "_OBJC_CATEGORY_INSTANCE_METHODS",
				     size, initlist, false);
      /* APPLE LOCAL end ObjC new abi */
    }
  else
    UOBJC_INSTANCE_METHODS_decl = 0;
}

/* APPLE LOCAL begin ObjC new abi */
static void
generate_v2_dispatch_tables (void)
{
  tree initlist, chain, method_list_template;
  int size;

  if (!objc_method_template)
    objc_method_template = build_method_template ();

  chain = CLASS_CLS_METHODS (objc_implementation_context);
  if (chain)
    {
      size = list_length (chain);

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

      UOBJC_V2_CLASS_METHODS_decl
	= generate_dispatch_table (method_list_template,
				   ((TREE_CODE (objc_implementation_context)
				     == CLASS_IMPLEMENTATION_TYPE)
				    /* APPLE LOCAL begin radar 6064186 */
				    ? "l_OBJC_$_CLASS_METHODS"
				    : "l_OBJC_$_CATEGORY_CLASS_METHODS"),
				    /* APPLE LOCAL end radar 6064186 */
				   size, initlist, true);
    }
  else
    UOBJC_V2_CLASS_METHODS_decl = 0;

  chain = CLASS_NST_METHODS (objc_implementation_context);
  if (chain)
    {
      size = list_length (chain);

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

      if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
	UOBJC_V2_INSTANCE_METHODS_decl
	  = generate_dispatch_table (method_list_template,
				     /* APPLE LOCAL radar 6064186 */
				     "l_OBJC_$_INSTANCE_METHODS",
				     size, initlist, true);
      else
	/* We have a category.  */
	UOBJC_V2_INSTANCE_METHODS_decl
	  = generate_dispatch_table (method_list_template,
				     /* APPLE LOCAL radar 6064186 */
				     "l_OBJC_$_CATEGORY_INSTANCE_METHODS",
				     size, initlist, true);
    }
  else
    UOBJC_V2_INSTANCE_METHODS_decl = 0;
}

/* 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 initlist;
  tree refs_decl, lproto, e, plist;
  int size = 0;
  const char *ref_name;

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

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

  /* Build initializer.  */
  initlist = NULL_TREE;
  e = build_int_cst (build_pointer_type (objc_v2_protocol_template), size);
  initlist = tree_cons (NULL_TREE, e, initlist);

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

      if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
	  && PROTOCOL_V2_FORWARD_DECL (pval))
	{
	  e = build_unary_op (ADDR_EXPR, PROTOCOL_V2_FORWARD_DECL (pval), 0);
	  initlist = tree_cons (NULL_TREE, e, initlist);
	}
    }

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

  /* APPLE LOCAL begin radar 6064186 */
  if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
    ref_name = synth_id_with_class_suffix ("l_OBJC_$_PROTOCOL_REFS", i_or_p);
  else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
    ref_name = synth_id_with_class_suffix ("l_OBJC_CLASS_PROTOCOLS_$", i_or_p);
  else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
    ref_name = synth_id_with_class_suffix ("l_OBJC_CATEGORY_PROTOCOLS_$", i_or_p);
  else
    abort ();

  refs_decl = start_var_decl
	      (build_array_type
	       (build_pointer_type (objc_v2_protocol_template),
		build_index_type (build_int_cst (NULL_TREE, size))),
	       ref_name);
  set_user_assembler_name (refs_decl, ref_name);
  /* APPLE LOCAL end radar 6064186 */

  finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
  						      nreverse (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. But to be consistant 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)
{
  tree initlist = NULL_TREE;

  do
    {
      tree eltlist
        = tree_cons (NULL_TREE,
                     build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
      eltlist
        = tree_cons (NULL_TREE,
                     add_objc_string (METHOD_ENCODING (entries),
                                      meth_var_types),
                     eltlist);

      /* APPLE LOCAL begin radar 6285794 */
      eltlist = tree_cons (NULL_TREE, 
                           convert (objc_method_list_ptr,
                                    integer_zero_node),
                           eltlist);
      /* APPLE LOCAL end radar 6285794 */
      initlist
        = tree_cons (NULL_TREE,
                     objc_build_constructor (type, nreverse (eltlist)),
                     initlist);

      entries = TREE_CHAIN (entries);
    }
  while (entries);

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

/* This routine builds instance_methods and class_methods use to declare a 
   protocole. */

static void
/* APPLE LOCAL begin radar 4695109 */
generate_v2_method_descriptors (tree protocol, bool is_optional)
{
  tree initlist, chain, method_list_template;
  int size;

  if (!objc_method_template)
    objc_method_template = build_method_template ();

  chain = is_optional ? PROTOCOL_OPTIONAL_CLS_METHODS (protocol)
		      : PROTOCOL_CLS_METHODS (protocol);
  if (chain)
    {
      size = list_length (chain);

      method_list_template
	= build_v2_method_list_template (objc_method_template, size);

      initlist
	= build_v2_descriptor_table_initializer (objc_method_template, chain);

      if (is_optional)
	UOBJC_PROTOCOL_OPT_CLS_METHODS_decl
	  = generate_descriptor_table (method_list_template,
				       /* APPLE LOCAL radar 6064186 */
				       "l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT",
				       size, initlist, protocol, true);
      else
        UOBJC_V2_CLASS_METHODS_decl
	  = generate_descriptor_table (method_list_template,
				       /* APPLE LOCAL radar 6064186 */
			       	       "l_OBJC_$_PROTOCOL_CLASS_METHODS",
				       size, initlist, protocol, true);
    }
  else
    {
      if (is_optional)
	UOBJC_PROTOCOL_OPT_CLS_METHODS_decl = 0;
      else
        UOBJC_V2_CLASS_METHODS_decl = 0;
    }

  chain = is_optional ? PROTOCOL_OPTIONAL_NST_METHODS (protocol)
		      : PROTOCOL_NST_METHODS (protocol);
  if (chain)
    {
      size = list_length (chain);

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

      if (is_optional)
	UOBJC_PROTOCOL_OPT_NST_METHODS_decl
	  = generate_descriptor_table (method_list_template,
				       /* APPLE LOCAL radar 6064186 */
				       "l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT",
				       size, initlist, protocol, true);
      else
        UOBJC_V2_INSTANCE_METHODS_decl
	  = generate_descriptor_table (method_list_template,
				       /* APPLE LOCAL radar 6064186 */
				       "l_OBJC_$_PROTOCOL_INSTANCE_METHODS",
				       size, initlist, protocol, true);
    }
  else
    {
      if (is_optional)
	UOBJC_PROTOCOL_OPT_NST_METHODS_decl = 0;
      else
        UOBJC_V2_INSTANCE_METHODS_decl = 0;
    }
}
/* APPLE LOCAL end radar 4695109 */

static tree
/* APPLE LOCAL end ObjC new abi */
generate_protocol_list (tree i_or_p)
{
  tree initlist;
  tree refs_decl, lproto, e, plist;
  int size = 0;
  const char *ref_name;

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

  /* 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.  */
  /* APPLE LOCAL radar 6285794 */
  initlist = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
  e = build_int_cst (build_pointer_type (objc_protocol_template), size);
  initlist = tree_cons (NULL_TREE, e, initlist);

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

      if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
	  && PROTOCOL_FORWARD_DECL (pval))
	{
	  e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
	  initlist = tree_cons (NULL_TREE, e, initlist);
	}
    }

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

  if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
    ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
  else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
    ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
  else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
    ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
  else
    abort ();

  refs_decl = start_var_decl
	      (build_array_type
	       (build_pointer_type (objc_protocol_template),
		build_index_type (build_int_cst (NULL_TREE, size + 2))),
	       ref_name);

  finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
  						      nreverse (initlist)));

  return refs_decl;
}

static tree
build_category_initializer (tree type, tree cat_name, tree class_name,
			    tree instance_methods, tree class_methods,
			    /* APPLE LOCAL begin C* property metadata (Radar 4498373) */
			    tree protocol_list,
			    bool abi_v2, tree property_list)
			    /* APPLE LOCAL end C* property metadata (Radar 4498373) */
{
  tree initlist = NULL_TREE, expr;

  initlist = tree_cons (NULL_TREE, cat_name, initlist);
  initlist = tree_cons (NULL_TREE, class_name, initlist);

  if (!instance_methods)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (objc_method_list_ptr,
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_method_list_ptr,
		      build_unary_op (ADDR_EXPR, instance_methods, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }
  if (!class_methods)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (objc_method_list_ptr,
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_method_list_ptr,
		      build_unary_op (ADDR_EXPR, class_methods, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }

  /* protocol_list = */
  /* APPLE LOCAL begin radar 6285794 */
  {
    tree protocol_list_ptr =
      (abi_v2) ? build_pointer_type (objc_v2_protocol_template)
               : build_pointer_type (build_pointer_type (objc_protocol_template));
    
    if (!protocol_list)
      initlist = tree_cons (NULL_TREE, 
                            convert (protocol_list_ptr,
                                     integer_zero_node),
                            initlist);
    else
      {
        /* APPLE LOCAL begin radar 4533974 - ObjC new protocol */
        expr = convert (protocol_list_ptr, build_unary_op (ADDR_EXPR, protocol_list, 0));
        /* APPLE LOCAL end radar 4533974 - ObjC new protocol */
        initlist = tree_cons (NULL_TREE, expr, initlist);
      }
  }
  /* APPLE LOCAL end radar 6285794 */
  /* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
  if (!abi_v2)
    {
      /* uint32_t size; */
      int val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_category_template));
      expr = build_int_cst (NULL_TREE, val);
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }
  /* APPLE LOCAL begin C* property metadata (Radar 4498373) */
  /* struct _objc_property_list *instance_properties; */
  if (!property_list)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE, 
                          convert (objc_prop_list_ptr,
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_prop_list_ptr,
		      build_unary_op (ADDR_EXPR, property_list, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }
  /* APPLE LOCAL end C* property metadata (Radar 4498373) */
  /* APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions */
  return objc_build_constructor (type, nreverse (initlist));
}

/* struct _objc_class {
     struct objc_class *isa;
     struct objc_class *super_class;
     char *name;
     long version;
     long info;
     long instance_size;
     struct objc_ivar_list *ivars;
     struct objc_method_list *methods;
     if (flag_next_runtime)
       struct objc_cache *cache;
     else {
       struct sarray *dtable;
       struct objc_class *subclass_list;
       struct objc_class *sibling_class;
     }
     struct objc_protocol_list *protocols;
     if (flag_next_runtime)
       void *sel_id;
     void *gc_object_type;
   };  */

static tree
build_shared_structure_initializer (tree type, tree isa, tree super,
				    tree name, tree size, int status,
				    tree dispatch_table, tree ivar_list,
	        /* APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions */
				    tree protocol_list, tree objc_class_ext)
{
  tree initlist = NULL_TREE, expr;

  /* isa = */
  initlist = tree_cons (NULL_TREE, isa, initlist);

  /* super_class = */
  initlist = tree_cons (NULL_TREE, super, initlist);

  /* name = */
  initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);

  /* version = */
  initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
			initlist);

  /* info = */
  initlist = tree_cons (NULL_TREE,
			build_int_cst (long_integer_type_node, status),
			initlist);

  /* instance_size = */
  initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
			initlist);

  /* objc_ivar_list = */
  if (!ivar_list)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE, 
                          convert (objc_ivar_list_ptr,
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_ivar_list_ptr,
		      build_unary_op (ADDR_EXPR, ivar_list, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }

  /* objc_method_list = */
  if (!dispatch_table)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (objc_method_list_ptr,
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_method_list_ptr,
		      build_unary_op (ADDR_EXPR, dispatch_table, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }

  /* APPLE LOCAL begin radar 6285794 */
  if (flag_next_runtime)
    /* method_cache = */
    initlist = tree_cons (NULL_TREE,
                          convert (build_pointer_type
                                   (xref_tag (RECORD_TYPE,
                                              get_identifier
                                              ("objc_cache"))),
                                   integer_zero_node),
                          initlist);
  else
    {
      tree null_objc_class_ptr = 
        convert (build_pointer_type (objc_class_template),
                 integer_zero_node);
 
      /* dtable = */
      initlist = tree_cons (NULL_TREE,
                            convert (build_pointer_type (xref_tag (RECORD_TYPE,
                                                                   get_identifier
                                                                   ("sarray"))),
                                     integer_zero_node),
                            initlist);
 
      /* subclass_list = */
      initlist = tree_cons (NULL_TREE, null_objc_class_ptr, initlist);
 
      /* sibling_class = */
      initlist = tree_cons (NULL_TREE, null_objc_class_ptr, initlist);
    }
    /* APPLE LOCAL end radar 6285794 */

  /* protocol_list = */
  /* APPLE LOCAL begin radar 6285794 */
  {
    tree objc_protocol_ptr_ptr =
      build_pointer_type (build_pointer_type (objc_protocol_template));
 
    if (!protocol_list)
      initlist = tree_cons (NULL_TREE,
                            convert (objc_protocol_ptr_ptr,
                                     integer_zero_node),
                            initlist);
    else
      {
        expr = convert (objc_protocol_ptr_ptr,
                        build_unary_op (ADDR_EXPR, protocol_list, 0));
        initlist = tree_cons (NULL_TREE, expr, initlist);
      }
  }
  /* APPLE LOCAL end radar 6285794 */

  /* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
  if (flag_next_runtime)
    {
      /* const char *ivar_layout; */
      if (IS_CLS_META (status)) /* Meta Class ? */
 	/* APPLE LOCAL begin radar 6285794 */
        initlist = tree_cons (NULL_TREE,
                              convert (string_type_node,
                                       integer_zero_node),
                              initlist);
 	/* APPLE LOCAL end radar 6285794 */
      else
	{
	  tree ivar_layout = objc_build_ivar_layout (true);
	  if (!ivar_layout)
            /* APPLE LOCAL begin radar 6285794 */
            initlist = tree_cons (NULL_TREE,
                                  convert (string_type_node,
                                           integer_zero_node),
                                  initlist);
 	    /* APPLE LOCAL end radar 6285794 */
	  else
	    initlist = tree_cons (NULL_TREE, ivar_layout, initlist);
	}
      /* struct _objc_class_ext *ext; */
      /* APPLE LOCAL begin radar 6285794 */
      if (!objc_class_ext_template)
        build_objc_class_ext_template ();

      {
        tree objc_class_ext_ptr =
          build_pointer_type (objc_class_ext_template);
 
        if (!objc_class_ext)
          initlist = tree_cons (NULL_TREE,
                                convert (objc_class_ext_ptr,
                                         integer_zero_node),
                                initlist);
        else
          {
            expr = convert (objc_class_ext_ptr,
                            build_unary_op (ADDR_EXPR, objc_class_ext, 0));
            initlist = tree_cons (NULL_TREE, expr, initlist);
          }
      }
      /* APPLE LOCAL end radar 6285794 */
    }
  else
    /* gc_object_type = NULL */
    /* APPLE LOCAL radar 6285794 - NUL pointer */
    initlist = tree_cons (NULL_TREE, null_pointer_node, initlist);
  /* APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions */

  return objc_build_constructor (type, nreverse (initlist));
}

/* Retrieve category interface CAT_NAME (if any) associated with CLASS.  */

static inline tree
lookup_category (tree class, tree cat_name)
{
  tree category = CLASS_CATEGORY_LIST (class);

  while (category && CLASS_SUPER_NAME (category) != cat_name)
    category = CLASS_CATEGORY_LIST (category);
  return category;
}

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

static void
/* APPLE LOCAL radar 4349690 */
generate_category (tree cat, struct imp_entry *impent)
{
  tree decl;
  tree initlist, cat_name_expr, class_name_expr;
  tree protocol_decl, category;

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

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

  category = lookup_category (implementation_template,
				CLASS_SUPER_NAME (cat));

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

  /* APPLE LOCAL radar 4349690 */
  decl = update_var_decl(impent->class_decl);

  initlist = build_category_initializer (TREE_TYPE (decl),
					 cat_name_expr, class_name_expr,
					 UOBJC_INSTANCE_METHODS_decl,
					 UOBJC_CLASS_METHODS_decl,
/* APPLE LOCAL begin C* property metadata (Radar 4498373) */
					 protocol_decl,
/* APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions */
					 false, UOBJC_V2_PROPERTY_decl);

  finish_var_decl (decl, initlist);
}
/* APPLE LOCAL end C* property metadata (Radar 4498373) */
/* APPLE LOCAL begin ObjC new abi */

/* APPLE LOCAL begin radar 4698856 */
/* Routine to build UOBJC_V2_CACHE_decl and UOBJC_V2_VTABLE_decl,
   if need be.
*/

static void
build_empty_cache_vtable_vars (void)
{
  UOBJC_V2_CACHE_decl = lookup_name (get_identifier ("_objc_empty_cache"));
  if (!UOBJC_V2_CACHE_decl)
    UOBJC_V2_CACHE_decl = create_extern_decl (ptr_type_node, "_objc_empty_cache");
  UOBJC_V2_VTABLE_decl = lookup_name (get_identifier ("_objc_empty_vtable"));
  if (!UOBJC_V2_VTABLE_decl)
    UOBJC_V2_VTABLE_decl = create_extern_decl (objc_imp_type, "_objc_empty_vtable");
}
/* APPLE LOCAL end radar 4698856 */

/* static struct category_t _OBJC_CATEGORY_$_<name> = { ... };  */

static void
generate_v2_category (tree cat, struct imp_entry *impent)
{
  tree decl;
  tree initlist, cat_name_expr, class_name_expr;
  tree protocol_decl, category;

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

  (void)objc_v2_get_class_reference (CLASS_NAME (cat));

  class_name_expr = create_extern_decl (objc_v2_class_template,
				        objc_build_internal_classname (
					  CLASS_NAME (cat), false));
  class_name_expr = build_fold_addr_expr (class_name_expr);

  category = lookup_category (implementation_template,
				CLASS_SUPER_NAME (cat));

  if (category && CLASS_PROTOCOL_LIST (category))
    {
      /* APPLE LOCAL radar 4695109 */
      generate_v2_protocol_references (CLASS_PROTOCOL_LIST (category));
      protocol_decl = generate_v2_protocol_list (category);
    }
  else
    protocol_decl = 0;

  decl = update_var_decl(impent->class_v2_decl);

  initlist = build_category_initializer (TREE_TYPE (decl),
					 cat_name_expr, class_name_expr,
					 UOBJC_V2_INSTANCE_METHODS_decl,
					 UOBJC_V2_CLASS_METHODS_decl,
  /* APPLE LOCAL begin C* property metadata (Radar 4498373) */
					 protocol_decl,
					 true, UOBJC_V2_PROPERTY_decl);
  /* APPLE LOCAL end C* property metadata (Radar 4498373) */

  finish_var_decl (decl, initlist);
  
  /* Add to list of pointers in __category_list section */
  objc_add_to_category_list_chain (decl);
  if (CLASS_OR_CATEGORY_HAS_LOAD_IMPL (objc_implementation_context) != NULL_TREE)
    objc_add_to_nonlazy_category_list_chain (decl);
}

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

static const char *
newabi_append_ro (const char *name)
{
  char *dollar;
  char *p;
  static char string[BUFSIZE];
  dollar = strchr (name, '$');
  gcc_assert (dollar);
  p = string;
  /* APPLE LOCAL radar 6064186 */
  *p = 'l'; p++;
  *p = '_'; p++;
  strncpy (p, name, (int)(dollar - name));
  p += (int)(dollar - name);
  sprintf (p, "RO_%s", dollar);
  return string;
}
 
/* Routine to build initializer list to initialize objects of type struct class_t; */

static tree
build_class_t_initializer (tree type, tree isa, tree superclass, tree ro, tree cache, tree vtable)
{
  tree initlist = NULL_TREE;

  /* isa */
  initlist = tree_cons (NULL_TREE, isa, initlist);

  /* superclass */
  initlist = tree_cons (NULL_TREE, superclass, initlist);

  /* cache */
  if (cache)
    initlist = tree_cons (NULL_TREE, cache, initlist);
  else
    /* APPLE LOCAL radar 6285794 - NUL pointer */
    initlist = tree_cons (NULL_TREE, null_pointer_node, initlist);

  /* vtable */
  if (vtable)
    initlist = tree_cons (NULL_TREE, vtable, initlist);
  else
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (build_pointer_type (objc_imp_type),
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */

  /* ro */
  initlist = tree_cons (NULL_TREE, ro, initlist);

  return objc_build_constructor (type, nreverse (initlist));
}

static tree
build_class_ro_t_initializer (tree type, tree name, 
			      unsigned int flags, unsigned int instanceStart, unsigned int instanceSize,
			      /* APPLE LOCAL radar 4695101 */
			      tree ivarLayout, 
			      tree baseMethods, tree baseProtocols, tree ivars,
			      /* APPLE LOCAL radar 4695101 */
			      tree weakIvarLayout,
			      tree property_list)
{
  tree initlist = NULL_TREE, expr;

  /* flags */
  initlist = tree_cons (NULL_TREE, 
		 	build_int_cst (integer_type_node, flags), 
			initlist);  

  /* instanceStart */
  initlist = tree_cons (NULL_TREE, 
		 	build_int_cst (integer_type_node, instanceStart), 
			initlist);  

  /* instanceSize */
  initlist = tree_cons (NULL_TREE, 
		 	build_int_cst (integer_type_node, instanceSize), 
			initlist);  

  /* reserved */
  if (TARGET_64BIT)
    initlist = tree_cons (NULL_TREE, 
		 	  build_int_cst (integer_type_node, 0), 
			  initlist);  

  /* APPLE LOCAL begin radar 4695101 */
  /* ivarLayout */
  if (!ivarLayout)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (string_type_node,
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    initlist = tree_cons (NULL_TREE, ivarLayout, initlist);
  /* APPLE LOCAL end radar 4695101 */

  /* name */
  initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);

  /* baseMethods */
  if (!baseMethods)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (objc_method_list_ptr,
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_method_list_ptr,
                      build_unary_op (ADDR_EXPR, baseMethods, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }

  /* baseProtocols */
  /* APPLE LOCAL begin radar 6285794 */
  {
    tree protocol_list_t_p =
      build_pointer_type (xref_tag (RECORD_TYPE, 
                                    get_identifier (UTAG_V2_PROTOCOL_LIST)));

    if (!baseProtocols)
      initlist = tree_cons (NULL_TREE,
                            convert (protocol_list_t_p,
                                     integer_zero_node),
                            initlist);
    else
      {
        expr = convert (protocol_list_t_p,
                        build_unary_op (ADDR_EXPR, baseProtocols, 0));
        initlist = tree_cons (NULL_TREE, expr, initlist);
      }
  }
  /* APPLE LOCAL end radar 6285794 */

  /* ivars */
  if (!ivars)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (objc_v2_ivar_list_ptr,
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_v2_ivar_list_ptr,
                      build_unary_op (ADDR_EXPR, ivars, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }

  /* APPLE LOCAL begin radar 4695101 */
  /* weakIvarLayout */
  if (!weakIvarLayout)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (string_type_node,
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    initlist = tree_cons (NULL_TREE, weakIvarLayout, initlist);
  /* APPLE LOCAL end radar 4695101 */

  /* APPLE LOCAL begin C* property metadata (Radar 4498373) */
  /* property list */
  if (!property_list)
    /* APPLE LOCAL begin radar 6285794 */
    initlist = tree_cons (NULL_TREE,
                          convert (objc_prop_list_ptr,
                                   integer_zero_node),
                          initlist);
    /* APPLE LOCAL end radar 6285794 */
  else
    {
      expr = convert (objc_prop_list_ptr,
                      build_unary_op (ADDR_EXPR, property_list, 0));
      initlist = tree_cons (NULL_TREE, expr, initlist);
    }
  /* APPLE LOCAL end C* property metadata (Radar 4498373) */
  return objc_build_constructor (type, nreverse (initlist));
}

/* APPLE LOCAL begin radar 4533974 - ObjC new protocol  - radar 4695109 */
/* Add the local protocol meta-data declaration to the list which later on ends up 
   in the __protocol_list section. */

static void
/* APPLE LOCAL begin radar 6351990 */
objc_add_to_protocol_list_chain (tree protocol_interface_decl, tree protocol_decl)
{
  tree *chain;
  for (chain = &protocol_list_chain; *chain; chain = &TREE_CHAIN (*chain))
    ;
  *chain = tree_cons (protocol_interface_decl, protocol_decl, NULL_TREE);
}

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

static void
build_protocol_list_address_table (void)
{
  tree chain;
  tree list_chain = protocol_list_chain;
  char *string = NULL;
  unsigned int  buf_size = 0;

  for (chain = list_chain; chain; chain = TREE_CHAIN (chain))
    {
      tree decl = TREE_PURPOSE (chain);
      tree expr = TREE_VALUE (chain);
      gcc_assert (decl && TREE_CODE (decl) == PROTOCOL_INTERFACE_TYPE);
      if ((strlen ("l_OBJC_LABEL_PROTOCOL_$_") + strlen (IDENTIFIER_POINTER (PROTOCOL_NAME (decl))) + 1) > buf_size)
        {
	  if (!buf_size)
	    buf_size = BUFSIZE;
	  else
	    buf_size = strlen ("l_OBJC_LABEL_PROTOCOL_$_") + strlen (IDENTIFIER_POINTER (PROTOCOL_NAME (decl))) + 1;
	  string = (char *)alloca (buf_size);
	} 
      sprintf (string,  "l_OBJC_LABEL_PROTOCOL_$_%s", IDENTIFIER_POINTER (PROTOCOL_NAME (decl)));
      decl = create_hidden_decl (objc_protocol_type, string);
      DECL_WEAK (decl) = 1;
      set_user_assembler_name (decl, string);
      expr = convert (objc_protocol_type, build_fold_addr_expr (expr));
      /* APPLE LOCAL radar 4561192 */
      objc_set_alignment_attribute (decl, objc_protocol_type);
      finish_var_decl (decl, expr);
    }
}
/* APPLE LOCAL end radar 6351990 */

/* Build decl = initializer; for each protocol referenced in @protocol(MyProtole) expression. */

static void
build_protocollist_translation_table (void)
{
  tree chain;
  static char string[BUFSIZE];

  for (chain = protocollist_ref_chain; chain; chain = TREE_CHAIN (chain))
    {
      tree expr = TREE_VALUE (chain);
      tree decl = TREE_PURPOSE (chain);
      gcc_assert (TREE_CODE (expr) == PROTOCOL_INTERFACE_TYPE);
      /* APPLE LOCAL begin radar 4695109 */
      /* APPLE LOCAL begin - LLVM radar 5476262 */
#ifdef ENABLE_LLVM
      if (flag_objc_abi == 2)
        /* LLVM LOCAL - add 'l' prefix */
        sprintf (string, "l_OBJC_PROTOCOL_$_%s", 
                 IDENTIFIER_POINTER (PROTOCOL_NAME (expr)));
      else
          /* LLVM LOCAL - add 'L' prefix */
          sprintf (string, "L_OBJC_PROTOCOL_$_%s", 
                   IDENTIFIER_POINTER (PROTOCOL_NAME (expr)));

      expr = lookup_name (get_identifier(string));

      if (expr == NULL_TREE)
        /* LLVM LOCAL - &string[1] because of '[Ll]' prefix */
	expr = start_var_decl (objc_v2_protocol_template, &string[1]);
#else
      /* APPLE LOCAL begin radar 6255913 */
      if (flag_objc_abi == 2)
      {
        sprintf (string, "l_OBJC_PROTOCOL_$_%s", 
	         IDENTIFIER_POINTER (PROTOCOL_NAME (expr)));
        expr = start_var_decl (objc_v2_protocol_template, string);
	set_user_assembler_name (expr, string);
      }
      /* APPLE LOCAL end radar 6255913 */
      else
      {
        sprintf (string, "_OBJC_PROTOCOL_$_%s", 
	         IDENTIFIER_POINTER (PROTOCOL_NAME (expr)));
        expr = start_var_decl (objc_v2_protocol_template, string);
      }
#endif
      /* APPLE LOCAL end - LLVM radar 5476262 */
      /* APPLE LOCAL end radar 4695109 */
      expr = convert (objc_protocol_type, build_fold_addr_expr (expr));
      finish_var_decl (decl, expr);
#ifdef ENABLE_LLVM
      /* At -O0, we may have emitted references to the decl earlier. */
      if (!optimize)
        reset_initializer_llvm(decl);
#endif
    }
}

/* This routine builds the protocol_reference_chain for each protocol name used
   @protocol(MyProtocol) expression. IDENT is current protocol name.  */

static tree
objc_v2_get_protocol_reference (tree ident)
{
  tree *chain;
  tree decl;

  for (chain = &protocollist_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
    if (TREE_VALUE (*chain) == ident)
      {
        if (! TREE_PURPOSE (*chain))
	  /* APPLE LOCAL radar 6351990 */
          TREE_PURPOSE (*chain) = build_protocollist_reference_decl (ident);

        return TREE_PURPOSE (*chain);
      }

  /* APPLE LOCAL radar 6351990 */
  decl = build_protocollist_reference_decl (ident);
  *chain = tree_cons (decl, ident, NULL_TREE);
  return decl;
}

/* This routine creates a static variable used to implement @protocol(MyProtocol) 
   expression. This variable will be initialized to global protocol_t meta-data
   pointer. */

/* APPLE LOCAL begin radar 6351990 */
static tree
build_protocollist_reference_decl (tree protocol)
{
  tree decl;
  tree protocol_ident = PROTOCOL_NAME (protocol);
  char *buf = (char *)alloca (strlen ("l_OBJC_PROTOCOL_REFERENCE_$_") + 
	       		      IDENTIFIER_LENGTH (protocol_ident) + 1);

  sprintf (buf, "l_OBJC_PROTOCOL_REFERENCE_$_%s", IDENTIFIER_POINTER (protocol_ident));
  decl = create_hidden_decl (objc_protocol_type, buf);
  DECL_WEAK (decl) = 1;
  set_user_assembler_name (decl, buf);

  return decl;
}
/* APPLE LOCAL end radar 6351990 */
/* APPLE LOCAL end radar 4533974 - ObjC new protocol */

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

static void
objc_add_to_nonlazy_class_list_chain (tree global_class_decl)
{
  tree *chain;
  for (chain = &nonlazy_class_list_chain; *chain; chain = &TREE_CHAIN (*chain))
    ;
  *chain = tree_cons (NULL_TREE, global_class_decl, NULL_TREE);
}

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

static void
objc_add_to_class_list_chain (tree global_class_decl)
{
  tree *chain;
  for (chain = &class_list_chain; *chain; chain = &TREE_CHAIN (*chain))
    ;
  *chain = tree_cons (NULL_TREE, global_class_decl, NULL_TREE);
}

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

static void
objc_add_to_nonlazy_category_list_chain (tree global_category_decl)
{
  tree *chain;
  for (chain = &nonlazy_category_list_chain; *chain; chain = &TREE_CHAIN (*chain))
    ;
  *chain = tree_cons (NULL_TREE, global_category_decl, NULL_TREE);
}

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

static void
objc_add_to_category_list_chain (tree global_category_decl)
{
  tree *chain;
  for (chain = &category_list_chain; *chain; chain = &TREE_CHAIN (*chain))
    ;
  *chain = tree_cons (NULL_TREE, global_category_decl, NULL_TREE);
}

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

static void
generate_v2_shared_structures (int cls_flags)
{
  tree sc_spec, decl_specs, decl;
  tree name_expr, root_expr = NULL_TREE;
  tree my_super_id = NULL_TREE;
  tree initlist, protocol_decl;
  unsigned int instanceStart, instanceSize;
  /* APPLE LOCAL begin radar 4695101 */
  tree ivarLayout;
  tree weakIvarLayout;
  /* APPLE LOCAL end radar 4695101 */
  tree metaclass_decl, class_decl;
  tree field, firstIvar;
  tree class_superclass_expr, metaclass_superclass_expr;
  unsigned int flags = 0x1; /* Start with CLS_META */
  /* APPLE LOCAL radar 6064186 */
  const char* ref_name;
  /* APPLE LOCAL begin radar 4705298, 4843145 */
  class_decl = objc_create_global_decl_for_class (
		 objc_v2_class_template, 
		 IDENTIFIER_POINTER (DECL_NAME (UOBJC_V2_CLASS_decl)), 
		 implementation_template);
  metaclass_decl = objc_create_global_decl_for_class (
		     objc_v2_class_template, 
		     IDENTIFIER_POINTER (DECL_NAME (UOBJC_V2_METACLASS_decl)), 
		     implementation_template);

  if (DECL_VISIBILITY (class_decl) == VISIBILITY_HIDDEN)
    flags |= OBJC2_CLS_HIDDEN; 
  /* APPLE LOCAL end radar 4705298, 4843145*/

  /* Generation of data for meta class */
  my_super_id = CLASS_SUPER_NAME (implementation_template);
  if (my_super_id)
    {
      /* compute reference to root's name. For meta class, "isa" is reference 
	 to root class name. */
      tree sav;
      tree my_root_id = my_super_id;
      tree my_root_int;
      tree 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);
      sav = objc_implementation_context;
      objc_implementation_context = my_root_int;
      /* APPLE LOCAL radar 5202926 */
      root_expr = build_metadata_decl ("OBJC_METACLASS_$", objc_v2_class_template, true);
      /* LLVM LOCAL begin - radar 5658734 */
#ifdef ENABLE_LLVM
      DECL_EXTERNAL(root_expr) = 1;
#endif
      /* LLVM LOCAL end - radar 5658734 */
      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);
      objc_implementation_context = interface;
      /* Note! I had to remove '_' prefix to 'OBJC' to make this an extern symbol. Darwin's
         back-end, recognizes '_OBJC_' prefix and prepends an 'L' in front of this. Darwin
         assembler treats names starting with 'L_' as local symbols. */
      /* APPLE LOCAL radar 5202926 */
      class_superclass_expr = build_metadata_decl ("OBJC_CLASS_$", objc_v2_class_template, true);
      /* LLVM LOCAL begin - radar 5658734 */
#ifdef ENABLE_LLVM
      DECL_EXTERNAL(class_superclass_expr) = 1;
#endif
      /* LLVM LOCAL end - radar 5658734 */
      class_superclass_expr = build_fold_addr_expr (class_superclass_expr);
      /* APPLE LOCAL radar 5202926 */
      metaclass_superclass_expr = build_metadata_decl ("OBJC_METACLASS_$", objc_v2_class_template, true);
      /* LLVM LOCAL begin - radar 5658734 */
#ifdef ENABLE_LLVM
      DECL_EXTERNAL(metaclass_superclass_expr) = 1;
#endif
      /* LLVM LOCAL end - radar 5658734 */
      metaclass_superclass_expr = build_fold_addr_expr (metaclass_superclass_expr);
      objc_implementation_context = sav;
    }
  else
    {
      /* root class.  */
      root_expr = build_unary_op (ADDR_EXPR, metaclass_decl, 0);
      metaclass_superclass_expr = build_unary_op (ADDR_EXPR, class_decl, 0);
      /* APPLE LOCAL begin radar 6285794 */
      class_superclass_expr = convert (build_pointer_type (objc_v2_class_template),
                                       integer_zero_node);
      /* APPLE LOCAL end radar 6285794 */
      flags |= 0x2; /* CLS_ROOT: it is also a root meta class */
    }


  if (CLASS_PROTOCOL_LIST (implementation_template))
    {
      /* APPLE LOCAL begin radar 4695109 */
      generate_v2_protocol_references
        (CLASS_PROTOCOL_LIST (implementation_template));
      /* APPLE LOCAL end radar 4695109 */
      protocol_decl = generate_v2_protocol_list (implementation_template);
    }
  else
    protocol_decl = 0;

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

  /* APPLE LOCAL begin radar 4702359 */
  instanceStart = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_class_template));
  instanceSize =  TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_class_template)); 
  /* APPLE LOCAL end radar 4702359 */

  name_expr = add_objc_string (CLASS_NAME (implementation_template),
                               class_names);

  sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
  decl_specs = tree_cons (NULL_TREE, objc_v2_class_ro_template, sc_spec);

  /* APPLE LOCAL begin radar 6064186 */
  ref_name = newabi_append_ro (
	       IDENTIFIER_POINTER (DECL_NAME (UOBJC_V2_METACLASS_decl))); 
  decl = start_var_decl (objc_v2_class_ro_template, ref_name);
  set_user_assembler_name (decl, ref_name);
  /* APPLE LOCAL end radar 6064186 */

  initlist = build_class_ro_t_initializer
	       (TREE_TYPE (decl),
		name_expr,
		(flags | cls_flags), instanceStart, instanceSize, 
		/* APPLE LOCAL radar 4695101 */
		NULL_TREE, UOBJC_V2_CLASS_METHODS_decl, protocol_decl,
		UOBJC_V2_CLASS_VARIABLES_decl,
		/* APPLE LOCAL radar 4695101 */
		NULL_TREE,
		NULL_TREE);

  finish_var_decl (decl, initlist);

  /* APPLE LOCAL radar 4698856*/
  build_empty_cache_vtable_vars ();

  /* static struct class_t _OBJC_METACLASS_Foo = { ... }; */
  initlist = build_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));
  finish_var_decl (metaclass_decl, initlist);

  /* Generation of data for the class */

  flags = 0x0;		/* CLS */
  /* APPLE LOCAL begin radar 4705298, 4843145 */
  if (DECL_VISIBILITY (class_decl) == VISIBILITY_HIDDEN)
    flags |= OBJC2_CLS_HIDDEN;
  /* APPLE LOCAL end radar 4705298, 48431458 */
  if (!my_super_id)
    flags |= 0x2;	/* CLS_ROOT: this is a root class */
  /* APPLE LOCAL begin radar 5008110 */
  if (objc2_objc_exception_attr (implementation_template))
    flags |= 0x20;
  /* APPLE LOCAL end radar 5008110 */

  /* Compute instanceStart */
  gcc_assert (CLASS_TYPE (implementation_template));
  field = TYPE_FIELDS (CLASS_TYPE (implementation_template));
  /* APPLE LOCAL begin radar 5333233 */
  /* If class has no ivar, 'field' remains the super class hidden field. */
  if (UOBJC_V2_INSTANCE_VARIABLES_decl 
      && my_super_id && field && TREE_CHAIN (field))
  /* APPLE LOCAL end radar 5333233 */
    field = TREE_CHAIN (field);

  firstIvar = field;

  while (firstIvar && TREE_CODE (firstIvar) != FIELD_DECL)
    firstIvar = TREE_CHAIN (firstIvar);
  gcc_assert (UOBJC_V2_INSTANCE_VARIABLES_decl? (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_low_cst (DECL_SIZE (field), 0);
  else
    instanceSize = 0;
  instanceSize /= BITS_PER_UNIT;

  /* If the class has no ivars, instanceStart should be set to the superclass's 
     instanceSize */
  /* APPLE LOCAL begin ARM signedness mismatch */
  instanceStart = UOBJC_V2_INSTANCE_VARIABLES_decl
		  ? (unsigned int) int_byte_position (firstIvar)
		  : instanceSize;
  /* APPLE LOCAL end ARM signedness mismatch */

  /* APPLE LOCAL begin radar 6064186 */
  ref_name = newabi_append_ro (IDENTIFIER_POINTER (DECL_NAME (UOBJC_V2_CLASS_decl)));
  decl = start_var_decl (objc_v2_class_ro_template, ref_name);
  set_user_assembler_name (decl, ref_name);
  /* APPLE LOCAL end radar 6064186 */

  /* APPLE LOCAL begin radar 4695101 */
  ivarLayout = objc_build_ivar_layout (true);
  weakIvarLayout = objc_build_ivar_layout (false); 
  /* APPLE LOCAL end radar 4695101 */

  initlist = build_class_ro_t_initializer (TREE_TYPE (decl),
					   name_expr,
					   (flags | cls_flags), instanceStart, instanceSize,
					   ivarLayout, UOBJC_V2_INSTANCE_METHODS_decl, protocol_decl,
					   UOBJC_V2_INSTANCE_VARIABLES_decl,
					   /* APPLE LOCAL radar 4695101 */
					   weakIvarLayout,
					   UOBJC_V2_PROPERTY_decl);
  finish_var_decl (decl, initlist);

  /* static struct class_t _OBJC_ACLASS_Foo = { ... }; */
  initlist = build_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)); 

  finish_var_decl (class_decl, initlist);
  /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
  /* At -O0, we may have emitted references to the decl earlier. */
  if (!optimize)
    reset_type_and_initializer_llvm(class_decl);
#endif
  /* LLVM LOCAL end */
  objc_add_to_class_list_chain (class_decl);
  if (CLASS_OR_CATEGORY_HAS_LOAD_IMPL (objc_implementation_context) != NULL_TREE)
    objc_add_to_nonlazy_class_list_chain (class_decl);
  /* APPLE LOCAL begin radar 5008110 */
  if (flag_objc_zerocost_exceptions && (flags & 0x20))
    objc2_build_ehtype_var_decl (CLASS_NAME (implementation_template),
                                 false, false);
  /* APPLE LOCAL end radar 5008110 */
}
/* APPLE LOCAL end ObjC new abi */

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

static void
generate_shared_structures (int cls_flags)
{
  tree sc_spec, decl_specs, decl;
  tree name_expr, super_expr, root_expr;
  tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
  tree cast_type, initlist, protocol_decl;
  /* APPLE LOCAL begin radar 5142207 */
  const char *visibility = objc_class_visibility (implementation_template);
  int hidden_flag = (visibility  &&  strcmp (visibility, "hidden") == 0) ? CLS_HIDDEN : 0;
  /* APPLE LOCAL end radar 5142207 */

  my_super_id = CLASS_SUPER_NAME (implementation_template);
  if (my_super_id)
    {
      add_class_reference (my_super_id);

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

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

  cast_type = build_pointer_type (objc_class_template);
  name_expr = add_objc_string (CLASS_NAME (implementation_template),
			       class_names);

  /* Install class `isa' and `super' pointers at runtime.  */
  if (my_super_id)
    {
      super_expr = add_objc_string (my_super_id, class_names);
      super_expr = build_c_cast (cast_type, super_expr); /* cast! */
    }
  else
    /* APPLE LOCAL begin radar 6285794 */
    {
      super_expr = convert (string_type_node,
                            integer_zero_node);
      super_expr = build_c_cast (cast_type, super_expr); /* cast! */
    }
    /* APPLE LOCAL end radar 6285794 */

  root_expr = add_objc_string (my_root_id, class_names);
  root_expr = build_c_cast (cast_type, root_expr); /* cast! */

  if (CLASS_PROTOCOL_LIST (implementation_template))
    {
      generate_protocol_references
	(CLASS_PROTOCOL_LIST (implementation_template));
      protocol_decl = generate_protocol_list (implementation_template);
    }
  else
    protocol_decl = 0;

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

  sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
  decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);

  /* APPLE LOCAL begin radar 4349690 */
  decl = update_var_decl (UOBJC_METACLASS_decl);
  /* APPLE LOCAL end radar 4349690 */

  initlist
    = build_shared_structure_initializer
      (TREE_TYPE (decl),
       root_expr, super_expr, name_expr,
       convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
       /* APPLE LOCAL radar 5142207 */
       CLS_META | hidden_flag,
       UOBJC_CLASS_METHODS_decl,
       UOBJC_CLASS_VARIABLES_decl,
       /* APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions */
       protocol_decl, NULL_TREE);

  finish_var_decl (decl, initlist);

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

  /* APPLE LOCAL begin radar 4349690 */
  decl = update_var_decl (UOBJC_CLASS_decl);
  /* APPLE LOCAL end radar 4349690 */

  initlist
    = build_shared_structure_initializer
      (TREE_TYPE (decl),
       build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
       super_expr, name_expr,
       convert (integer_type_node,
		TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
				(implementation_template))),
       /* APPLE LOCAL radar 5142207 */
       CLS_FACTORY | hidden_flag | cls_flags,
       UOBJC_INSTANCE_METHODS_decl,
       UOBJC_INSTANCE_VARIABLES_decl,
/* APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions */
       protocol_decl, UOBJC_CLASS_EXT_decl);

  finish_var_decl (decl, initlist);
}


static const char *
synth_id_with_class_suffix (const char *preamble, tree ctxt)
{
  static char string[BUFSIZE];

  if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
      || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
    {
      sprintf (string, "%s_%s", preamble,
	       IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
    }
  else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
	   || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
    {
      /* We have a category.  */
      const char *const class_name
	= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
      const char *const class_super_name
	= IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
      /* APPLE LOCAL begin ObjC abi v2 */
      if (flag_objc_abi == 2)
        sprintf (string, "%s_%s_$_%s", preamble, class_name, class_super_name);
      else
        sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
      /* APPLE LOCAL end ObjC abi v2 */
    }
  else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
    {
      const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
      sprintf (string, "%s_%s", preamble, protocol_name);
    }
  else
    abort ();

  return string;
}

/* If type is empty or only type qualifiers are present, add default
   type of id (otherwise grokdeclarator will default to int).  */

static tree
adjust_type_for_id_default (tree type)
{
  if (!type)
    type = make_node (TREE_LIST);

  if (!TREE_VALUE (type))
    TREE_VALUE (type) = objc_object_type;
  else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
	   && TYPED_OBJECT (TREE_VALUE (type)))
    error ("can not use an object as parameter to a method");

  return type;
}

/*   Usage:
		keyworddecl:
			// APPLE LOCAL radar 4157812
			selector ':' '(' typename ')' [attr-list] identifier

     Purpose:
		Transform an Objective-C keyword argument into
		the C equivalent parameter declarator.

     In:	key_name, an "identifier_node" (optional).
		arg_type, a  "tree_list" (optional).
		arg_name, an "identifier_node".
		// APPLE LOCAL radar 4157812
		arg_attr, a  "tree_list" (optional)

     Note:	It would be really nice to strongly type the preceding
		arguments in the function prototype; however, then I
		could not use the "accessor" macros defined in "tree.h".

     Out:	an instance of "keyword_decl".  */

tree
/* APPLE LOCAL radar 4157812 */
objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name, tree arg_attr)
{
  tree keyword_decl;

  /* If no type is specified, default to "id".  */
  arg_type = adjust_type_for_id_default (arg_type);

  keyword_decl = make_node (KEYWORD_DECL);

  TREE_TYPE (keyword_decl) = arg_type;
  KEYWORD_ARG_NAME (keyword_decl) = arg_name;
  /* APPLE LOCAL radar 4157812 */
  KEYWORD_ARG_ATTRIBUTE (keyword_decl) = arg_attr;
  KEYWORD_KEY_NAME (keyword_decl) = key_name;

  return keyword_decl;
}

/* Given a chain of keyword_decl's, synthesize the full keyword selector.  */

static tree
build_keyword_selector (tree selector)
{
  int len = 0;
  tree key_chain, key_name;
  char *buf;

  /* Scan the selector to see how much space we'll need.  */
  for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
    {
      if (TREE_CODE (selector) == KEYWORD_DECL)
	key_name = KEYWORD_KEY_NAME (key_chain);
      else if (TREE_CODE (selector) == TREE_LIST)
	key_name = TREE_PURPOSE (key_chain);
      else
	abort ();

      if (key_name)
	len += IDENTIFIER_LENGTH (key_name) + 1;
      else
	/* Just a ':' arg.  */
	len++;
    }

  buf = (char *) alloca (len + 1);
  /* Start the buffer out as an empty string.  */
  buf[0] = '\0';

  for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
    {
      if (TREE_CODE (selector) == KEYWORD_DECL)
	key_name = KEYWORD_KEY_NAME (key_chain);
      else if (TREE_CODE (selector) == TREE_LIST)
	{
	  key_name = TREE_PURPOSE (key_chain);
	  /* The keyword decl chain will later be used as a function argument
	     chain.  Unhook the selector itself so as to not confuse other
	     parts of the compiler.  */
	  TREE_PURPOSE (key_chain) = NULL_TREE;
	}
      else
	abort ();

      if (key_name)
	strcat (buf, IDENTIFIER_POINTER (key_name));
      strcat (buf, ":");
    }

  return get_identifier (buf);
}

/* Used for declarations and definitions.  */

static tree
build_method_decl (enum tree_code code, tree ret_type, tree selector,
		   tree add_args, bool ellipsis)
{
  tree method_decl;

  /* If no type is specified, default to "id".  */
  ret_type = adjust_type_for_id_default (ret_type);

  method_decl = make_node (code);
  TREE_TYPE (method_decl) = ret_type;

  /* If we have a keyword selector, create an identifier_node that
     represents the full selector name (`:' included)...  */
  if (TREE_CODE (selector) == KEYWORD_DECL)
    {
      METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
      METHOD_SEL_ARGS (method_decl) = selector;
      METHOD_ADD_ARGS (method_decl) = add_args;
      METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
    }
  else
    {
      METHOD_SEL_NAME (method_decl) = selector;
      METHOD_SEL_ARGS (method_decl) = NULL_TREE;
      METHOD_ADD_ARGS (method_decl) = NULL_TREE;
    }

  return method_decl;
}

#define METHOD_DEF 0
#define METHOD_REF 1

/* APPLE LOCAL begin radar 3803157 - objc attribute */
/* APPLE LOCAL begin radar 4529765 */
/* This routine is called for a "format" attribute. It adds the number of
   hidden argument ('2') to the format's 2nd and 3rd argument to compensate
   for these two arguments. This is to make rest of the "format" attribute
   processing done in the middle-end to work seemlessly. */

static void
objc_delta_format_args (tree format)
{
  tree format_num_expr, first_arg_num_expr;
  int val; 
  tree args = TREE_VALUE (format);
  gcc_assert (TREE_CHAIN (args) && TREE_CHAIN (TREE_CHAIN (args)));
  format_num_expr = TREE_VALUE (TREE_CHAIN (args));
  first_arg_num_expr = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
  if (format_num_expr && TREE_CODE (format_num_expr) == INTEGER_CST)
    {
      val = TREE_INT_CST_LOW (format_num_expr);
      TREE_VALUE (TREE_CHAIN (args)) = build_int_cst (NULL_TREE, val+2);
    }
  if (first_arg_num_expr && TREE_CODE (first_arg_num_expr) == INTEGER_CST)
    {
      val = TREE_INT_CST_LOW (first_arg_num_expr);
      /* APPLE LOCAL begin radar 6157135 */
      if (val != 0)
        TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args))) = build_int_cst (NULL_TREE, val+2);
      /* APPLE LOCAL end radar 6157135 */
    }
}

/* This routine recognizes objc legal attributes. In case of "format" 
   attribute, it calls objc_delta_format_args to compensate for hidden 
   argument objc passes to its messaging call. */
static bool
objc_any_recognized_attribute (tree attributes)
{
  tree chain;
  bool res = false;
  for (chain = attributes; chain; chain = TREE_CHAIN (chain))
    {
      if (is_attribute_p ("format", TREE_PURPOSE (chain)))
	{
	  objc_delta_format_args (chain);
	  res = true;
	}
      else if (is_attribute_p ("sentinel", TREE_PURPOSE (chain)))
	res = true;	
    }
  return res;
}
/* APPLE LOCAL end radar 4529765 */
/* This routine processes objective-c method attributes. */

static void
objc_decl_method_attributes (tree *node, tree attributes, int flags)
{
  /* APPLE LOCAL radar 4529765 */
  if (objc_any_recognized_attribute (attributes))
    {
      /* hackery to make an obj method look like a function type. */
      tree rettype = TREE_TYPE (*node);
      TREE_TYPE (*node) = build_function_type (TREE_VALUE (rettype), 
			    /* APPLE LOCAL radar 6307941 */
                            get_arg_type_list (METHOD_SEL_NAME (*node), 
                                               *node, METHOD_REF, 0));
      decl_attributes (node, attributes, flags);
      METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
      TREE_TYPE (*node) = rettype;
    }
  else
    decl_attributes (node, attributes, flags);
}
/* APPLE LOCAL end radar 3803157 - objc attribute */

/* Used by `build_objc_method_call' and `comp_proto_with_proto'.  Return
   an argument list for method METH.  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; this makes a
   difference for the NeXT calling sequence in which the lookup and
   the method call are done together.  If METH is null, user-defined
   arguments (i.e., beyond self and _cmd) shall be represented by `...'.  */

static tree
/* APPLE LOCAL radar 6307941 */
get_arg_type_list (tree sel_name, tree meth, int context, int superflag)
{
  tree arglist, akey;

  /* Receiver type.  */
  if (flag_next_runtime && superflag)
    arglist = build_tree_list (NULL_TREE, objc_super_type);
  else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
    arglist = build_tree_list (NULL_TREE, objc_instance_type);
  else
    arglist = build_tree_list (NULL_TREE, objc_object_type);

  /* Selector type - will eventually change to `int'.  */
  /* APPLE LOCAL begin ObjC new abi */
  chainon (arglist, build_tree_list (NULL_TREE, flag_objc_abi == 2 
				     /* APPLE LOCAL ARM hybrid objc-2.0 - radar 6307941 */
                                     && !objc_legacy_dispatched_selector_p (sel_name)
				     ? (superflag 
					? objc_v2_super_selector_type 
					: objc_v2_selector_type)
				     : objc_selector_type));
  /* APPLE LOCAL end ObjC new abi */

  /* No actual method prototype given -- assume that remaining arguments
     are `...'.  */
  if (!meth)
    return arglist;

  /* Build a list of argument types.  */
  for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
    {
      tree arg_type = TREE_VALUE (TREE_TYPE (akey));

      /* APPLE LOCAL begin 4209854 */
      /* Decay argument types for the underlying C function as appropriate.  */
      arg_type = objc_decay_parm_type (arg_type);
      /* APPLE LOCAL end 4209854 */

      chainon (arglist, build_tree_list (NULL_TREE, arg_type));
    }

  if (METHOD_ADD_ARGS (meth))
    {
      for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
	   akey; akey = TREE_CHAIN (akey))
	{
	  tree arg_type = TREE_TYPE (TREE_VALUE (akey));

	  /* APPLE LOCAL begin 4209854 */
	  arg_type = objc_decay_parm_type (arg_type);

	  /* APPLE LOCAL end 4209854 */
	  chainon (arglist, build_tree_list (NULL_TREE, arg_type));
	}

      if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
	goto lack_of_ellipsis;
    }
  else
    {
     lack_of_ellipsis:
      chainon (arglist, OBJC_VOID_AT_END);
    }

  return arglist;
}

static tree
check_duplicates (hash hsh, int methods, int is_class)
{
  tree meth = NULL_TREE;

  if (hsh)
    {
      meth = hsh->key;

      if (hsh->list)
        {
	  /* We have two or more methods with the same name but
	     different types.  */
	  attr loop;

	  /* But just how different are those types?  If
	     -Wno-strict-selector-match is specified, we shall not
	     complain if the differences are solely among types with
	     identical size and alignment.  */
	  if (!warn_strict_selector_match)
	    {
	      for (loop = hsh->list; loop; loop = loop->next)
		if (!comp_proto_with_proto (meth, loop->value, 0))
		  goto issue_warning;

	      return meth;
	    }

	issue_warning:
	  warning (0, "multiple %s named %<%c%s%> found",
		   methods ? "methods" : "selectors",
		   (is_class ? '+' : '-'),
		   IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));

	  warn_with_method (methods ? "using" : "found",
			    ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
			     ? '-'
			     : '+'),
			    meth);
	  for (loop = hsh->list; loop; loop = loop->next)
	    warn_with_method ("also found",
			      ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
			       ? '-'
			       : '+'),
			      loop->value);
        }
    }
  return meth;
}

/* If RECEIVER is a class reference, return the identifier node for
   the referenced class.  RECEIVER is created by objc_get_class_reference,
   so we check the exact form created depending on which runtimes are
   used.  */

static tree
receiver_is_class_object (tree receiver, int self, int super)
{
  tree chain, exp, arg;

  /* The receiver is 'self' or 'super' in the context of a class method.  */
  if (objc_method_context
      && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
      && (self || super))
    return (super
	    ? CLASS_SUPER_NAME (implementation_template)
	    : CLASS_NAME (implementation_template));

  if (flag_next_runtime)
    {
      /* The receiver is a variable created by
         build_class_reference_decl.  */
      if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
        /* Look up the identifier.  */
  	/* APPLE LOCAL begin ObjC abi v2 */
	for (chain = (flag_objc_abi == 2) 
		      ? classlist_ref_chain 
		      : cls_ref_chain; chain; chain = TREE_CHAIN (chain))
  	/* APPLE LOCAL end ObjC abi v2 */
	  if (TREE_PURPOSE (chain) == receiver)
            return TREE_VALUE (chain);
    }

  /* The receiver is a function call that returns an id.  Check if
     it is a call to objc_getClass, if so, pick up the class name.  */
  if (TREE_CODE (receiver) == CALL_EXPR
      && (exp = TREE_OPERAND (receiver, 0))
      && TREE_CODE (exp) == ADDR_EXPR
      && (exp = TREE_OPERAND (exp, 0))
      && TREE_CODE (exp) == FUNCTION_DECL
      /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
	 prototypes for objc_get_class().  Thankfully, they seem to share the
	 same function type.  */
      && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
      && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
      /* We have a call to objc_get_class/objc_getClass!  */
      && (arg = TREE_OPERAND (receiver, 1))
      && TREE_CODE (arg) == TREE_LIST
      && (arg = TREE_VALUE (arg)))
    {
      STRIP_NOPS (arg);
      if (TREE_CODE (arg) == ADDR_EXPR
	  && (arg = TREE_OPERAND (arg, 0))
	  && TREE_CODE (arg) == STRING_CST)
	/* Finally, we have the class name.  */
	return get_identifier (TREE_STRING_POINTER (arg));
    }
  return 0;
}

/* If we are currently building a message expr, this holds
   the identifier of the selector of the message.  This is
   used when printing warnings about argument mismatches.  */

static tree current_objc_message_selector = 0;

tree
objc_message_selector (void)
{
  return current_objc_message_selector;
}

/* Construct an expression for sending a message.
   MESS has the object to send to in TREE_PURPOSE
   and the argument list (including selector) in TREE_VALUE.

   (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
   (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...);  */

tree
objc_build_message_expr (tree mess)
{
  tree receiver = TREE_PURPOSE (mess);
  tree sel_name;
#ifdef OBJCPLUS
  tree args = TREE_PURPOSE (TREE_VALUE (mess));
#else
  tree args = TREE_VALUE (mess);
#endif
  tree method_params = NULL_TREE;

  /* APPLE LOCAL radar 4294425 */
  if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
    return error_mark_node;

  /* Obtain the full selector name.  */
  if (TREE_CODE (args) == IDENTIFIER_NODE)
    /* A unary selector.  */
    sel_name = args;
  else if (TREE_CODE (args) == TREE_LIST)
    sel_name = build_keyword_selector (args);
  else
    abort ();

  /* Build the parameter list to give to the method.  */
  if (TREE_CODE (args) == TREE_LIST)
#ifdef OBJCPLUS
    method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
#else
    {
      tree chain = args, prev = NULL_TREE;

      /* We have a keyword selector--check for comma expressions.  */
      while (chain)
	{
	  tree element = TREE_VALUE (chain);

	  /* We have a comma expression, must collapse...  */
	  if (TREE_CODE (element) == TREE_LIST)
	    {
	      if (prev)
		TREE_CHAIN (prev) = element;
	      else
		args = element;
	    }
	  prev = chain;
	  chain = TREE_CHAIN (chain);
        }
      method_params = args;
    }
#endif

#ifdef OBJCPLUS
  if (processing_template_decl)
    /* Must wait until template instantiation time.  */
    return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
			 method_params);
#endif

  return objc_finish_message_expr (receiver, sel_name, method_params);
}

/* Look up method SEL_NAME that would be suitable for receiver
   of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
   nonzero), and report on any duplicates.  */

static tree
lookup_method_in_hash_lists (tree sel_name, int is_class)
{
  hash method_prototype = NULL;

  if (!is_class)
    method_prototype = hash_lookup (nst_method_hash_list,
				    sel_name);

  if (!method_prototype)
    {
      method_prototype = hash_lookup (cls_method_hash_list,
				      sel_name);
      is_class = 1;
    }

  return check_duplicates (method_prototype, 1, is_class);
}

/* The 'objc_finish_message_expr' routine is called from within
   'objc_build_message_expr' for non-template functions.  In the case of
   C++ template functions, it is called from 'build_expr_from_tree'
   (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded.  */

tree
objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
{
  tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
  tree selector, retval, class_tree;
  int self, super, have_cast;
  /* APPLE LOCAL radar 4547918 */
  bool forward_class = false;

  /* APPLE LOCAL begin radar 4180592 */
  if (receiver == error_mark_node || TREE_TYPE (receiver) == error_mark_node)
    return receiver;
  /* APPLE LOCAL end radar 4180592 */
  /* APPLE LOCAL begin radar 5809099 */
  if (TREE_CODE (TREE_TYPE (receiver)) == BLOCK_POINTER_TYPE)
    receiver = convert (objc_object_type, receiver);
  /* APPLE LOCAL end radar 5809099 */
  /* Extract the receiver of the message, as well as its type
     (where the latter may take the form of a cast or be inferred
     from the implementation context).  */
  /* APPLE LOCAL begin radar 4653319 */
  rtype = objc_get_inner_exp (receiver);
  /* APPLE LOCAL end radar 4653319 */
  self = (rtype == self_decl);
  super = (rtype == UOBJC_SUPER_decl);
  rtype = TREE_TYPE (receiver);
  have_cast = (TREE_CODE (receiver) == NOP_EXPR
	       || (TREE_CODE (receiver) == COMPOUND_EXPR
		   && !IS_SUPER (rtype)));

  /* If we are calling [super dealloc], reset our warning flag.  */
  if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
    should_call_super_dealloc = 0;
  /* APPLE LOCAL begin radar 4757423 */
  /* If we are calling [super finalize], reset our warning flag.  */
  if (super && !strcmp ("finalize", IDENTIFIER_POINTER (sel_name)))
    should_call_super_finalize = 0;
  /* APPLE LOCAL end radar 4757423 */

  /* If the receiver is a class object, retrieve the corresponding
     @interface, if one exists. */
  class_tree = receiver_is_class_object (receiver, self, super);

  /* Now determine the receiver type (if an explicit cast has not been
     provided).  */
  if (!have_cast)
    {
      if (class_tree)
      /* APPLE LOCAL begin radar 4547918 */
	{
	  /* APPLE LOCAL begin radar 5741070  */
	  tree interface_record_type = NULL;
	  rtype = lookup_interface (class_tree);

	  /* Find the record type definition for the interface class.  */

	  if (rtype)
	    interface_record_type = 
	      c_return_interface_record_type (OBJC_TYPE_NAME (rtype));

	  /* If the record type is found, mark is as used (since it
	     is used to dispatch a method call).  */

	  if (interface_record_type != NULL)
	    used_types_insert (interface_record_type);
	  /* APPLE LOCAL end radar 5741070  */
	  forward_class = !rtype;
	}
      /* APPLE LOCAL end radar 4547918 */
      /* Handle `self' and `super'.  */
      else if (super)
	{
	  if (!CLASS_SUPER_NAME (implementation_template))
	    {
	      error ("no super class declared in @interface for %qs",
		     IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
	      return error_mark_node;
	    }
	  rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
	}
      else if (self)
	rtype = lookup_interface (CLASS_NAME (implementation_template));
    }

  /* If receiver is of type `id' or `Class' (or if the @interface for a
     class is not visible), we shall be satisfied with the existence of
     any instance or class method. */
  if (objc_is_id (rtype))
    {
      class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
      rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
		 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
		 : NULL_TREE);
      rtype = NULL_TREE;

      if (rprotos)
	{
	  /* If messaging 'id <Protos>' or 'Class <Proto>', first search
	     in protocols themselves for the method prototype.  */
	  method_prototype
	    = lookup_method_in_protocol_list (rprotos, sel_name,
					      class_tree != NULL_TREE);

	  /* If messaging 'Class <Proto>' but did not find a class method
	     prototype, search for an instance method instead, and warn
	     about having done so.  */
	  if (!method_prototype && !rtype && class_tree != NULL_TREE)
	    {
	      method_prototype
		= lookup_method_in_protocol_list (rprotos, sel_name, 0);

	      if (method_prototype)
		warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
			 IDENTIFIER_POINTER (sel_name),
			 IDENTIFIER_POINTER (sel_name));
	    }
	}
    }
  else if (rtype)
    {
      tree orig_rtype = rtype, saved_rtype;

      if (TREE_CODE (rtype) == POINTER_TYPE)
	rtype = TREE_TYPE (rtype);
      /* Traverse typedef aliases */
      while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
	     && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
	     && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
	rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
      saved_rtype = rtype;
      if (TYPED_OBJECT (rtype))
	{
	  rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
	  rtype = TYPE_OBJC_INTERFACE (rtype);
	}
      /* If we could not find an @interface declaration, we must have
	 only seen a @class declaration; so, we cannot say anything
	 more intelligent about which methods the receiver will
	 understand. */
      if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
	/* APPLE LOCAL begin radar 4457381 */
	{
	  rtype = NULL_TREE;
	  /* We could not find an @interface declaration, yet Message maybe in a 
	     @class's protocol. */
	  if (!method_prototype && rprotos)
	    method_prototype
	      = lookup_method_in_protocol_list (rprotos, sel_name, 0);
	}
	/* APPLE LOCAL end radar 4457381 */
      else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
	  || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
	{
	  /* We have a valid ObjC class name.  Look up the method name
	     in the published @interface for the class (and its
	     superclasses). */
	  method_prototype
	    /* APPLE LOCAL objc new property */
	    = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE, false, false);

	  /* If the method was not found in the @interface, it may still
	     exist locally as part of the @implementation.  */
	  if (!method_prototype && objc_implementation_context
	     && CLASS_NAME (objc_implementation_context)
		== OBJC_TYPE_NAME (rtype))
	    method_prototype
	      = lookup_method
		((class_tree
		  ? CLASS_CLS_METHODS (objc_implementation_context)
		  : CLASS_NST_METHODS (objc_implementation_context)),
		  sel_name);

	  /* If we haven't found a candidate method by now, try looking for
	     it in the protocol list.  */
	  if (!method_prototype && rprotos)
	    method_prototype
	      = lookup_method_in_protocol_list (rprotos, sel_name,
						class_tree != NULL_TREE);
	}
      else
	{
	  /* APPLE LOCAL begin decay function/array receivers */
#ifndef OBJCPLUS
	  /* In C need to decay array/function receivers so can be converted 
	     to id. */
	  struct c_expr exp;
	  exp.value = receiver;
	  exp = default_function_array_conversion (exp);
	  receiver = exp.value;
	/* APPLE LOCAL begin radar 3533972 */
#else
	  if (can_convert_arg (objc_object_type, TREE_TYPE (receiver), 
				receiver, LOOKUP_NORMAL))
	    {
	      /* In rare cases, 'receiver' must be converted to type 'id' using
	         user-defined type conversion. 'id' is type of the 1st argument to
	         objc_msgSend (id self, SEL op, ...); */
	      tree cnv_rec = perform_implicit_conversion (objc_object_type, receiver);
              if (cnv_rec && cnv_rec != error_mark_node)
	        return objc_finish_message_expr (cnv_rec, sel_name, method_params);
	    }
	/* APPLE LOCAL end radar 3533972 */
#endif
	  /* APPLE LOCAL end decay function/array receivers */
          /* APPLE LOCAL begin radar 5595325 */
          /* Do not issue this warning on random NSObject objects. */
          if (!objc_nsobject_attribute_type (orig_rtype))
            warning (0, "invalid receiver type %qs",
                     gen_type_name (orig_rtype));
            /* After issuing the "invalid receiver" warning, perform method
              lookup as if we were messaging 'id'.  */
           /* APPLE LOCAL end radar 5595325 */
	  rtype = rprotos = NULL_TREE;
	}
    }


  /* For 'id' or 'Class' receivers, search in the global hash table
     as a last resort.  For all receivers, warn if protocol searches
     have failed.  */
  if (!method_prototype)
    {
      if (rprotos)
	warning (0, "%<%c%s%> not found in protocol(s)",
		 (class_tree ? '+' : '-'),
		 IDENTIFIER_POINTER (sel_name));

      if (!rtype)
	/* APPLE LOCAL begin radar 4547918 */
	{
	  method_prototype
	    = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
	  if (forward_class && method_prototype)
	    warning (0, "receiver %qs is a forward class and corresponding @interface may not exist",
		     IDENTIFIER_POINTER (class_tree));
	}
	/* APPLE LOCAL end radar 4547918 */
    }

  /* APPLE LOCAL begin radar 4506893 */
  /* APPLE LOCAL begin objc new property */
  if (!method_prototype && in_objc_property_setter_name_context)
    {
      error ("object cannot be set - either readonly property or no setter found");
      /* APPLE LOCAL radar 5390587 */
      return error_mark_node;
    }
  /* APPLE LOCAL end objc new property */
  else if (!method_prototype) 
  /* APPLE LOCAL end radar 4506893 */
    {
      static bool warn_missing_methods = false;

      if (rtype)
	warning (0, "%qs may not respond to %<%c%s%>",
		 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
		 (class_tree ? '+' : '-'),
		 IDENTIFIER_POINTER (sel_name));
      /* If we are messaging an 'id' or 'Class' object and made it here,
	 then we have failed to find _any_ instance or class method,
	 respectively.  */
       /* APPLE LOCAL radar 5932809 - copyable byref blocks */
      else if (!donot_warn_missing_methods)
	warning (0, "no %<%c%s%> method found",
		 (class_tree ? '+' : '-'),
		 IDENTIFIER_POINTER (sel_name));
      /* APPLE LOCAL radar 5932809 - copyable byref blocks */
      if (!warn_missing_methods && !donot_warn_missing_methods)
	{
	  warning (0, "(Messages without a matching method signature");
	  warning (0, "will be assumed to return %<id%> and accept");
	  warning (0, "%<...%> as arguments.)");
	  warn_missing_methods = true;
	}
    }

  /* APPLE LOCAL begin radar 6049617 - radar 5005756 */
  /* If receiver has an 'id' type, then method selection happens at runtime.
   It is misleading to issue warning on a method call not knowing which
   method actually gets called; thus check for objc_is_id is added. */
  if (method_prototype && rtype)
  {
    if (TREE_DEPRECATED (method_prototype))
      warn_deprecated_use (method_prototype);
    if (TREE_UNAVAILABLE (method_prototype))
      error_unavailable_use (method_prototype);    
  }
  /* APPLE LOCAL end radar 6049617 - radar 5005756 */
  /* Save the selector name for printing error messages.  */
  current_objc_message_selector = sel_name;

  /* Build the parameters list for looking up the method.
     These are the object itself and the selector.  */

  /* APPLE LOCAL ObjC new abi */
  /* Code moved down */
  /* APPLE LOCAL begin ObjC new abi */
  /* APPLE LOCAL ARM hybrid objc-2.0 - radar 6307941 */
  if (flag_objc_abi == 2 && !objc_legacy_dispatched_selector_p (sel_name))
    {
      tree ret_type;
      tree message_func_decl;
      bool check_for_nil = flag_objc_nilcheck;

      ret_type = (method_prototype ? 
	      	    TREE_VALUE (TREE_TYPE (method_prototype)) : 
		    objc_object_type);

      /* Do we need to check for nil receivers ? */
      /* For now, message sent to classes need no nil check. In future, class
	 declaration marked as weak_import must be nil checked. */
      if (super 
	  || (TREE_CODE (receiver) == VAR_DECL 
	      && TREE_TYPE (receiver) == objc_class_type))
	check_for_nil = false;

      /* LLVM LOCAL - begin PR1654 */
#ifdef ENABLE_LLVM
      if (aggregate_value_p (ret_type, 0))
#else
      if (!targetm.calls.struct_value_rtx (0, 0)
          && (TREE_CODE (ret_type) == RECORD_TYPE 
       	      || TREE_CODE (ret_type) == UNION_TYPE)
          /* APPLE LOCAL begin radar 5080710 */
          && (TREE_ADDRESSABLE (ret_type)
              || targetm.calls.return_in_memory (ret_type, 0)))
          /* APPLE LOCAL end radar 5080710 */
#endif
      /* LLVM LOCAL - end PR1654 */
	{
	  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
	  /* APPLE LOCAL begin radar 4557598 */
	    {
	      if (objc_is_id (rtype))
		message_func_decl = umsg_id_fixup_decl;
	      else if (targetm.calls.objc_fpreturn_msgcall (ret_type, true))
		message_func_decl = umsg_fixup_decl;
	      else if (targetm.calls.objc_fpreturn_msgcall (ret_type, false))
		message_func_decl = umsg_fpret_fixup_decl;
	      else
		message_func_decl = umsg_fixup_decl;
	    }
	  /* APPLE LOCAL end radar 4557598 */
	}

      selector =  build_selector_messenger_reference (sel_name,  
						      message_func_decl);

      /* selector = &_msg; */
      selector = build_unary_op (ADDR_EXPR, selector, 0);
 
      selector = build_c_cast (super 
			       ? objc_v2_super_selector_type 
			       : objc_v2_selector_type, selector);

      /* (*_msg.messenger) (receiver, &_msg, ...); */
      retval = build_v2_build_objc_method_call (super, method_prototype,
						/* APPLE LOCAL radar 6307941 */
                                                receiver, sel_name, selector, 
                                                method_params,
                                                check_for_nil);
    }
  else
    {
      if (flag_typed_selectors)
        selector = build_typed_selector_reference (sel_name, method_prototype);
      else
/* APPLE LOCAL begin radar 4359757 */
        selector = flag_next_runtime 
		     ? build_next_runtime_selector_reference (sel_name) 
		     : build_selector_reference (sel_name);
/* APPLE LOCAL end radar 4359757 */

        retval = build_objc_method_call (super, method_prototype,
					 /* APPLE LOCAL radar 6307941 */
				         receiver, sel_name, 
				         selector, method_params);
    }
  /* APPLE LOCAL end ObjC new abi */

  current_objc_message_selector = 0;

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

static tree
build_objc_method_call (int super_flag, tree method_prototype,
			/* APPLE LOCAL radar 6307941 */
			tree lookup_object, tree sel_name, tree selector,
			tree method_params)
{
  tree sender = (super_flag ? umsg_super_decl :
		 (!flag_next_runtime || flag_nil_receivers
		  /* APPLE LOCAL begin radar 4590221 */
		  ? umsg_decl
		  /* APPLE LOCAL end radar 4590221 */
		  : umsg_nonnil_decl));
  tree rcv_p = (super_flag ? objc_super_type : objc_object_type);

  /* 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);
  /* APPLE LOCAL begin radar 3803157 - objc attribute */
  /* APPLE LOCAL radar 6307941 */
  tree method_param_types = get_arg_type_list (sel_name, method_prototype, 
                                               METHOD_REF, super_flag);
  tree ftype = build_function_type (ret_type, method_param_types);
  tree sender_cast;
  tree method, t;
  if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
    ftype = build_type_attribute_variant (
	      ftype, METHOD_TYPE_ATTRIBUTES (method_prototype));

  sender_cast = build_pointer_type (ftype);
  lookup_object = build_c_cast (rcv_p, lookup_object);
  /* APPLE LOCAL end radar 3803157 - objc attribute */

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

  if (flag_next_runtime)
    {
/* APPLE LOCAL begin radar 4491211 */
#ifdef OBJCPLUS
      complete_type (ret_type);
#endif
/* APPLE LOCAL end radar 4491211 */
      /* If we are returning a struct in memory, and the address
	 of that memory location is passed as a hidden first
	 argument, then change which messenger entry point this
	 expr will call.  NB: Note that sender_cast remains
	 unchanged (it already has a struct return type).  */
      /* APPLE LOCAL begin ARM 4961719 */
      if (aggregate_value_p (ret_type, 0))
      /* APPLE LOCAL end ARM 4961719 */
	sender = (super_flag ? umsg_super_stret_decl :
		flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
      /* APPLE LOCAL begin radar 4280641 */
      else if (!super_flag && targetm.calls.objc_fpreturn_msgcall (ret_type, true))
	sender = umsg_decl;
      else if (!super_flag && targetm.calls.objc_fpreturn_msgcall (ret_type, false))
	sender = umsg_fpret_decl;
      /* APPLE LOCAL end radar 4280641 */

      method_params = tree_cons (NULL_TREE, lookup_object,
				 tree_cons (NULL_TREE, selector,
					    method_params));
      method = build_fold_addr_expr (sender);
    }
  else
    {
      /* This is the portable (GNU) way.  */
      tree object;

      /* First, call the lookup function to get a pointer to the method,
	 then cast the pointer, then call it with the method arguments.  */

      object = (super_flag ? self_decl : lookup_object);

      t = tree_cons (NULL_TREE, selector, NULL_TREE);
      t = tree_cons (NULL_TREE, lookup_object, t);
      method = build_function_call (sender, t);

      /* Pass the object to the method.  */
      method_params = tree_cons (NULL_TREE, object,
				 tree_cons (NULL_TREE, selector,
					    method_params));
    }

  /* ??? Selector is not at this point something we can use inside
     the compiler itself.  Set it to garbage for the nonce.  */
  t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
  return build_function_call (t, method_params);
}


/* APPLE LOCAL begin ObjC new abi */
/* Build the new abi's messaging librrary call. It looks like:
   (*_msg.messanger) (receiver, &_msg, ...)  */

static tree
build_v2_build_objc_method_call (int super_flag, tree method_prototype,
                                 tree lookup_object, tree sel_name, 
                                 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);
  /* APPLE LOCAL radar 6307941 */
  tree method_param_types = get_arg_type_list (sel_name, method_prototype, 
					       METHOD_REF, super_flag);
  /* APPLE LOCAL begin radar 3803157 - objc attribute */
  tree ftype = build_function_type (ret_type, method_param_types);
  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);
  /* APPLE LOCAL end radar 3803157 - objc attribute */
  if (check_for_nil)
    method_params = objc_copy_to_temp_side_effect_params (method_param_types, 
							  method_params);

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

  sender = build_indirect_ref (sender, "unary *");

  rcv_p = (super_flag ? objc_super_type : objc_object_type);

  lookup_object = build_c_cast (rcv_p, lookup_object);

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

  method_params = tree_cons (NULL_TREE, lookup_object,
                             tree_cons (NULL_TREE, selector,
                                        method_params));
  t = build3 (OBJ_TYPE_REF, sender_cast, sender, lookup_object, size_zero_node);
  ret_val =  build_function_call (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)
	ftree = build_constructor_from_list (ret_type, NULL_TREE);
      else
	ftree = fold_convert (ret_type, integer_zero_node);

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

      ret_val = build_conditional_expr (ifexp, ret_val, ftree);
 
    }
  return ret_val;
}

/* Declare variable which holds 'struct protocol_t' meta data.  */
/* APPLE LOCAL begin radar 4695109 */
/* poniter to protocol metadata in new ABI protocol is now generated 
   like the old abi. */
static void
build_v2_protocol_reference (tree p)
{
  tree decl;
  const char *proto_name;

  /* static struct protocol_t  _OBJC_PROTOCOL_$<mumble>; */

  /* APPLE LOCAL begin radar 6255913 */
  proto_name = synth_id_with_class_suffix ("l_OBJC_PROTOCOL_$", p);
  decl = create_hidden_decl (objc_v2_protocol_template, proto_name);
  DECL_WEAK (decl) = 1;
  set_user_assembler_name (decl, proto_name);
  /* APPLE LOCAL end radar 6255913 */
  PROTOCOL_V2_FORWARD_DECL (p) = decl;
  /* APPLE LOCAL begin - LLVM radar 5476262 */
#ifdef ENABLE_LLVM
  pushdecl_top_level(decl);
#endif
  /* APPLE LOCAL end - LLVM radar 5476262 */
}
/* APPLE LOCAL end radar 4695109 */

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

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

  /* If a protocol was directly referenced, pull in indirect references.  */
  for (p = protocol_chain; p; p = TREE_CHAIN (p))
    /* APPLE LOCAL begin radar 4695109 */
    if (PROTOCOL_V2_FORWARD_DECL (p) && PROTOCOL_LIST (p))
      generate_v2_protocol_references (PROTOCOL_LIST (p));
    /* APPLE LOCAL end radar 4695109 */

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

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

      /* APPLE LOCAL radar 4695109 */
      if (!decl)
	continue;

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

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

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

	  cls_methods = TREE_CHAIN (cls_methods);
	}
      /* APPLE LOCAL begin radar 4695109 */
      generate_v2_method_descriptors (p, false);

      nst_methods = PROTOCOL_OPTIONAL_NST_METHODS (p);
      while (nst_methods)
	{
	  if (! METHOD_ENCODING (nst_methods))
	    {
	      encoding = encode_method_prototype (nst_methods);
	      METHOD_ENCODING (nst_methods) = encoding;
	    }
	  nst_methods = TREE_CHAIN (nst_methods);
	}

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

	  cls_methods = TREE_CHAIN (cls_methods);
	}

      generate_v2_method_descriptors (p, true);
      /* APPLE LOCAL end radar 4695109 */

      if (PROTOCOL_LIST (p))
	refs_decl = generate_v2_protocol_list (p);
      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 (ADDR_EXPR, refs_decl, 0));
      else
	/* APPLE LOCAL begin radar 6285794 */
        refs_expr =
          convert (build_pointer_type (objc_v2_protocol_template),
                   integer_zero_node);
	/* APPLE LOCAL end radar 6285794 */

      /* APPLE LOCAL begin radar 4695101 */
      /* Build table of list of properties for this protocol. */
      objc_implementation_context = p;
      generate_v2_property_tables (p);
      /* UOBJC_V2_PROPERTY_decl points to table of properties for 
	 this protocol. */
      /* APPLE LOCAL end radar 4695101 */

      /* UOBJC_V2_INSTANCE_METHODS_decl/UOBJC_V2_CLASS_METHODS_decl are set
	 by generate_v2_method_descriptors, which is called above.  */
      initlist = build_protocol_initializer (TREE_TYPE (decl),
					     protocol_name_expr, refs_expr,
					     UOBJC_V2_INSTANCE_METHODS_decl,
					     UOBJC_V2_CLASS_METHODS_decl, true,
					     /* APPLE LOCAL radar 4695101 */
					     UOBJC_V2_PROPERTY_decl,
					     /* APPLE LOCAL begin radar 4695109 */
					     UOBJC_PROTOCOL_OPT_NST_METHODS_decl, 
					     UOBJC_PROTOCOL_OPT_CLS_METHODS_decl);
					     /* APPLE LOCAL end radar 4695109 */
      finish_var_decl (decl, initlist);
      /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
      /* At -O0, we may have emitted references to the decl earlier. */
      if (!optimize)
        reset_initializer_llvm(decl);
#endif
      /* LLVM LOCAL end */
      /* APPLE LOCAL radar 4533974 - ObjC new protocol - radar 6351990 */
      objc_add_to_protocol_list_chain (p, decl);
    }
}

static void
/* APPLE LOCAL end ObjC new abi */
build_protocol_reference (tree p)
{
  tree decl;
  const char *proto_name;

  /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */

  proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
  decl = start_var_decl (objc_protocol_template, proto_name);
  /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
  /* Force 4 byte alignment for protocols */
  DECL_ALIGN(decl) = 32;
  DECL_USER_ALIGN(decl) = 1;
#endif
  /* LLVM LOCAL end */
  PROTOCOL_FORWARD_DECL (p) = decl;
}

/* This function is called by the parser when (and only when) a
   @protocol() expression is found, in order to compile it.  */
tree
objc_build_protocol_expr (tree protoname)
{
  tree expr;
  tree p = lookup_protocol (protoname);

  if (!p)
    {
      error ("cannot find protocol declaration for %qs",
	     IDENTIFIER_POINTER (protoname));
      return error_mark_node;
    }

  /* APPLE LOCAL begin ObjC abi v2 */
  if (flag_objc_abi == 2)
    {
      /* APPLE LOCAL begin radar 4533974 - ObjC new protocol */
      if (!PROTOCOL_V2_FORWARD_DECL (p))
    	build_v2_protocol_reference (p);
      return objc_v2_get_protocol_reference (p);
      /* APPLE LOCAL end radar 4533974 - ObjC new protocol */
    }
  else
    {
      if (!PROTOCOL_FORWARD_DECL (p))
    	build_protocol_reference (p);

      expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
    }
  /* APPLE LOCAL end ObjC abi v2 */

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

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

  /* For the GNU runtime, put the static Protocol instance in the list
     of statically allocated instances, so that we make sure that its
     'isa' pointer is fixed up at runtime by the GNU runtime library
     to point to the Protocol class (at runtime, when loading the
     module, the GNU runtime library loops on the statically allocated
     instances (as found in the defs field in objc_symtab) and fixups
     all the 'isa' pointers of those objects).  */
  if (! flag_next_runtime)
    {
      /* This type is a struct containing the fields of a Protocol
        object.  (Cfr. objc_protocol_type instead is the type of a pointer
        to such a struct).  */
      tree protocol_struct_type = xref_tag
       (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
      tree *chain;

      /* Look for the list of Protocol statically allocated instances
        to fixup at runtime.  Create a new list to hold Protocol
        statically allocated instances, if the list is not found.  At
        present there is only another list, holding NSConstantString
        static instances to be fixed up at runtime.  */
      for (chain = &objc_static_instances;
	   *chain && TREE_VALUE (*chain) != protocol_struct_type;
	   chain = &TREE_CHAIN (*chain));
      if (!*chain)
	{
         *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
         add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
                          class_names);
       }

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


  return expr;
}

/* This function is called by the parser when a @selector() expression
   is found, in order to compile it.  It is only called by the parser
   and only to compile a @selector().  */
tree
objc_build_selector_expr (tree selnamelist)
{
  tree selname;

  /* APPLE LOCAL begin radar 5409313 */
  if (selnamelist == NULL_TREE)
    {
      error ("method name missing in @selector");
      return error_mark_node;
    }
  /* APPLE LOCAL end radar 5409313 */
  /* Obtain the full selector name.  */
  if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
    /* A unary selector.  */
    selname = selnamelist;
  else if (TREE_CODE (selnamelist) == TREE_LIST)
    selname = build_keyword_selector (selnamelist);
  else
    abort ();

  /* If we are required to check @selector() expressions as they
     are found, check that the selector has been declared.  */
  if (warn_undeclared_selector)
    {
      /* Look the selector up in the list of all known class and
         instance methods (up to this line) to check that the selector
         exists.  */
      hash hsh;

      /* First try with instance methods.  */
      hsh = hash_lookup (nst_method_hash_list, selname);

      /* If not found, try with class methods.  */
      if (!hsh)
	{
	  hsh = hash_lookup (cls_method_hash_list, selname);
	}

      /* If still not found, print out a warning.  */
      if (!hsh)
	{
	  warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
	}
    }


  if (flag_typed_selectors)
    return build_typed_selector_reference (selname, 0);
  else
/* APPLE LOCAL begin radar 4359757 */
    return flag_next_runtime 
	     ? build_next_runtime_selector_reference (selname) 
	     : build_selector_reference (selname);
/* APPLE LOCAL end radar 4359757 */
}

tree
objc_build_encode_expr (tree type)
{
  tree result;
  const char *string;

  encode_type (type, obstack_object_size (&util_obstack),
	       OBJC_ENCODE_INLINE_DEFS);
  obstack_1grow (&util_obstack, 0);    /* null terminate string */
  string = obstack_finish (&util_obstack);

  /* Synthesize a string that represents the encoded struct/union.  */
  result = my_build_string (strlen (string) + 1, string);
  obstack_free (&util_obstack, util_firstobj);
  return result;
}

/* APPLE LOCAL begin radar 6230701 */
/* Find a 'self' declaration in this block.  If not found,
   add a 'const' copy in current block. */
static void
access_block_ref_self_decl (tree *decl)
{
  if (lookup_name_in_block (DECL_NAME (*decl), decl))
    *decl = lookup_name (DECL_NAME (*decl));
  else
    *decl = build_block_ref_decl (DECL_NAME (*decl), *decl);
  gcc_assert (*decl);
}
/* APPLE LOCAL end radar 6230701 */

static tree
build_ivar_reference (tree id)
{
  /* APPLE LOCAL radar 5811191 - blocks */
  tree decl;
  /* APPLE LOCAL ObjC new abi */
  tree ivar, base;
  if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
    {
      /* Historically, a class method that produced objects (factory
	 method) would assign `self' to the instance that it
	 allocated.  This would effectively turn the class method into
	 an instance method.  Following this assignment, the instance
	 variables could be accessed.  That practice, while safe,
	 violates the simple rule that a class method should not refer
	 to an instance variable.  It's better to catch the cases
	 where this is done unknowingly than to support the above
	 paradigm.  */
      warning (0, "instance variable %qs accessed in class method",
	       IDENTIFIER_POINTER (id));
      self_decl = convert (objc_instance_type, self_decl); /* cast */
    }

  /* APPLE LOCAL begin ObjC new abi */
  /* APPLE LOCAL begin radar 5811191 - blocks */
  decl = self_decl;
  if (cur_block)
  {
    /* Find a 'self' declaration in this block.  If not found,
       add a 'const' copy in current block. */
    access_block_ref_self_decl (&decl);
    gcc_assert (decl);
  }
  base = build_indirect_ref (decl, "->");
  /* APPLE LOCAL end radar 5811191 - blocks */
  if ((ivar = objc_v2_build_ivar_ref (base, id)))
    return ivar;
  else
    return objc_build_component_ref (base, id);
  /* APPLE LOCAL end ObjC new abi */
}

/* Compute a hash value for a given method SEL_NAME.  */

static size_t
hash_func (tree sel_name)
{
  const unsigned char *s
    = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
  size_t h = 0;

  while (*s)
    h = h * 67 + *s++ - 113;
  return h;
}

static void
hash_init (void)
{
  nst_method_hash_list
    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
  cls_method_hash_list
    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
  /* APPLE LOCAL begin radar 4359757 */
  class_nst_method_hash_list
    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
  class_cls_method_hash_list
    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
  class_names_hash_list
    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
  meth_var_names_hash_list
    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
  meth_var_types_hash_list
    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
  prop_names_attr_hash_list
    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
  sel_ref_hash_list
    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
  /* APPLE LOCAL end radar 4359757 */

  /* APPLE LOCAL begin radar 4345837 */
  cls_name_hash_list
    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
  als_name_hash_list
    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
  /* APPLE LOCAL end radar 4345837 */

  /* APPLE LOCAL begin radar 4441049 */
  ivar_offset_hash_list
    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
  /* APPLE LOCAL end radar 4441049 */

  /* Initialize the hash table used to hold the constant string objects.  */
  string_htab = htab_create_ggc (31, string_hash,
				   string_eq, NULL);
/* APPLE LOCAL begin radar 4204796 */
  /* code removed */
}
/* APPLE LOCAL end radar 4204796 */
/* APPLE LOCAL begin radar 4345837 */
/* This routine adds sel_name to the hash list. sel_name  is a class or alias
   name for the class. If alias name, then value is its underlying class.
   If class, the value is NULL_TREE. */

static void
hash_class_name_enter (hash *hashlist, tree sel_name, tree value)
{
  hash obj;
  int slot = hash_func (sel_name) % SIZEHASHTABLE;

  obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
  if (value != NULL_TREE)
    {
      /* Save the underlying class for the 'alias' in the hash table */
      attr obj_attr = (attr) ggc_alloc (sizeof (struct hashed_attribute));
      obj_attr->value = value;
      obj->list = obj_attr;
    }
  else
    obj->list = 0;
  obj->next = hashlist[slot];
  obj->key = sel_name;

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

}

/* Searches in the hash table looking for a match for class or alias name.  */

static hash
hash_class_name_lookup (hash *hashlist, tree sel_name)
{
  hash target;

  target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];

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

      target = target->next;
    }
  return 0;
}
/* APPLE LOCAL end radar 4345837 */

/* APPLE LOCAL begin radar 4441049 */
/* 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 ivar)
{
  hash obj;
  int slot = hash_func (DECL_NAME (ivar)) % SIZEHASHTABLE;

  obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
  obj->list = 0;
  obj->next = hashlist[slot];
  obj->key = ivar;

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

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

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

  target = hashlist[hash_func (ivar_name) % SIZEHASHTABLE];

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

      target = target->next;
    }
  return 0;
}
/* APPLE LOCAL end radar 4441049 */

/* WARNING!!!!  hash_enter is called with a method, and will peek
   inside to find its selector!  But hash_lookup is given a selector
   directly, and looks for the selector that's inside the found
   entry's key (method) for comparison.  */

static void
hash_enter (hash *hashlist, tree method)
{
  hash obj;
  int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;

  obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
  obj->list = 0;
  obj->next = hashlist[slot];
  obj->key = method;

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

static hash
hash_lookup (hash *hashlist, tree sel_name)
{
  hash target;

  target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];

  while (target)
    {
      if (sel_name == METHOD_SEL_NAME (target->key))
	return target;

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

static void
hash_add_attr (hash entry, tree value)
{
  attr obj;

  obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
  obj->next = entry->list;
  obj->value = value;

  entry->list = obj;		/* append to front */
}

static tree
lookup_method (tree mchain, tree method)
{
  tree key;

  if (TREE_CODE (method) == IDENTIFIER_NODE)
    key = method;
  else
    key = METHOD_SEL_NAME (method);

  while (mchain)
    {
      if (METHOD_SEL_NAME (mchain) == key)
	return mchain;

      mchain = TREE_CHAIN (mchain);
    }
  return NULL_TREE;
}

/* APPLE LOCAL begin radar 4359757 */
/* This routine does a hash lookup keyed on method name and further
   qualified by its 'class'. */
static hash
class_method_hash_lookup (hash *hashlist, tree sel_name, tree class)
{
  hash target;

  target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
  while (target)
    {
      if (sel_name == METHOD_SEL_NAME (target->key)
	  && class == METHOD_CONTEXT (target->key))
        return target;
      target = target->next;
    }
  return 0;
}

static void
add_class_method_hash (hash *hash_list, tree method, tree class)
{
  hash_enter (hash_list, method);
  METHOD_CONTEXT (method) = class;
}

/* This routine does a quick hash look up of METHOD_IDENT in global 
   class-method hash table. Hash function is keyed on method name but 
   'context' of method found must also match CLASS. 
*/ 
static tree 
fast_lookup_method (int is_class, tree class, tree method_ident)
{
  hash hsh = (!is_class) ? class_method_hash_lookup (class_nst_method_hash_list, 
				              	     method_ident, class) 
			 : class_method_hash_lookup (class_cls_method_hash_list, 
					             method_ident, class);
  return !hsh ? NULL_TREE : hsh->key;
}
/* APPLE LOCAL end radar 4359757 */

/* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
   in INTERFACE, along with any categories and protocols attached thereto.
   If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
   recursively examine the INTERFACE's superclass.  If OBJC_LOOKUP_CLASS is
   set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
   be found in INTERFACE or any of its superclasses, look for an _instance_
   method of the same name in the root class as a last resort.

   If a suitable method cannot be found, return NULL_TREE.  */

static tree
/* APPLE LOCAL objc new property */
lookup_method_static (tree interface, tree ident, int flags, bool property_lookup,
/* APPLE LOCAL radar 5277239 */
		      bool class_method_only)
{
  tree meth = NULL_TREE, root_inter = NULL_TREE;
  tree inter = interface;
  int is_class = (flags & OBJC_LOOKUP_CLASS);
  int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);

  while (inter)
    {
      tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
      tree category = inter;

      /* First, look up the method in the class itself.  */
      /* APPLE LOCAL begin objc new property - radar 4359757 */
      if ((meth = fast_lookup_method (is_class, inter, ident)) 
	  && (!property_lookup || METHOD_PROPERTY_CONTEXT (meth)))
      /* APPLE LOCAL end objc new property */
	return meth;

      /* Failing that, look for the method in each category of the class.  */
      while ((category = CLASS_CATEGORY_LIST (category)))
	{
	  chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);

	  /* Check directly in each category.  */
	  /* APPLE LOCAL begin objc new property */
	  if ((meth = lookup_method (chain, ident))
	      && (!property_lookup || METHOD_PROPERTY_CONTEXT (meth)))
	  /* APPLE LOCAL end objc new property */
	    return meth;

	  /* Failing that, check in each category's protocols.  */
	  if (CLASS_PROTOCOL_LIST (category))
	    {
	      /* APPLE LOCAL begin objc new property */
	      if ((meth = (lookup_method_in_protocol_list
			   (CLASS_PROTOCOL_LIST (category), ident, is_class)))
		  && (!property_lookup || METHOD_PROPERTY_CONTEXT (meth)))
	      /* APPLE LOCAL end objc new property */
		return meth;
	    }
	}

      /* If not found in categories, check in protocols of the main class.  */
      if (CLASS_PROTOCOL_LIST (inter))
	{
	  /* APPLE LOCAL begin objc new property */
	  if ((meth = (lookup_method_in_protocol_list
		       (CLASS_PROTOCOL_LIST (inter), ident, is_class)))
	      && (!property_lookup || METHOD_PROPERTY_CONTEXT (meth)))
	  /* APPLE LOCAL end objc new property */
	    return meth;
	}

      /* If we were instructed not to look in superclasses, don't.  */
      if (no_superclasses)
	return NULL_TREE;

      /* Failing that, climb up the inheritance hierarchy.  */
      root_inter = inter;
      inter = lookup_interface (CLASS_SUPER_NAME (inter));
    }
  while (inter);

  /* If no class (factory) method was found, check if an _instance_
     method of the same name exists in the root class.  This is what
     the Objective-C runtime will do.  If an instance method was not
     found, return 0.  */
  /* APPLE LOCAL begin radar 5277239 */
  /* APPLE LOCAL objc new property */
  return (is_class && !class_method_only) 
	   ? lookup_method_static (root_inter, ident, 0, property_lookup, false): NULL_TREE;
  /* APPLE LOCAL end radar 5277239 */
}

/* Add the method to the hash list if it doesn't contain an identical
   method already. */

static void
add_method_to_hash_list (hash *hash_list, tree method)
{
  hash hsh;

  if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
    {
      /* Install on a global chain.  */
      hash_enter (hash_list, method);
    }
  else
    {
      /* Check types against those; if different, add to a list.  */
      attr loop;
      /* APPLE LOCAL radar 5370783 */
      int already_there = comp_proto_with_proto (method, hsh->key, 2);
      for (loop = hsh->list; !already_there && loop; loop = loop->next)
        /* APPLE LOCAL radar 5370783 */
	already_there |= comp_proto_with_proto (method, loop->value, 2);
      if (!already_there)
	hash_add_attr (hsh, method);
    }
}

static tree
/* APPLE LOCAL C* language */
objc_add_method (tree class, tree method, int is_class, int is_optional)
{
  tree mth;

  /* APPLE LOCAL begin C* language */
  /* @optional methods are added to protocol's OPTIONAL list */
  if (is_optional)
    {
      gcc_assert (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE);
      if (!(mth = lookup_method (is_class
                                ? PROTOCOL_OPTIONAL_CLS_METHODS (class)
                                : PROTOCOL_OPTIONAL_NST_METHODS (class), method)))
	{
	  if (is_class)
	    {
	      TREE_CHAIN (method) = PROTOCOL_OPTIONAL_CLS_METHODS (class);
	      PROTOCOL_OPTIONAL_CLS_METHODS (class) = method;
	    }
	  else
	    {
	      TREE_CHAIN (method) = PROTOCOL_OPTIONAL_NST_METHODS (class);
	      PROTOCOL_OPTIONAL_NST_METHODS (class) = method;
	    }
	}
    }
  else
  /* APPLE LOCAL end C* language */
  /* APPLE LOCAL begin radar 4359757 */
  if (!(mth = fast_lookup_method (is_class, class, METHOD_SEL_NAME (method))))
  /* APPLE LOCAL end radar 4359757 */
    {
      /* put method on list in reverse order */
      if (is_class)
	{
	  TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
	  CLASS_CLS_METHODS (class) = method;
	}
      else
	{
	  TREE_CHAIN (method) = CLASS_NST_METHODS (class);
	  CLASS_NST_METHODS (class) = method;
	}
      /* APPLE LOCAL begin radar 4359757 */
      add_class_method_hash ((!is_class) ? class_nst_method_hash_list
                                         : class_cls_method_hash_list,
                              method, class);
      /* APPLE LOCAL end radar 4359757 */
    }
  else
    {
      /* When processing an @interface for a class or category, give hard
	 errors on methods with identical selectors but differing argument
	 and/or return types. We do not do this for @implementations, because
	 C/C++ will do it for us (i.e., there will be duplicate function
	 definition errors).  */
      if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
	   || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
          /* APPLE LOCAL radar 5370783 */
	  && !comp_proto_with_proto (method, mth, 2))
	error ("duplicate declaration of method %<%c%s%>",
		is_class ? '+' : '-',
		IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
    }

  if (is_class)
    add_method_to_hash_list (cls_method_hash_list, method);
  else
    {
      add_method_to_hash_list (nst_method_hash_list, method);

      /* Instance methods in root classes (and categories thereof)
	 may act as class methods as a last resort.  We also add
	 instance methods listed in @protocol declarations to
	 the class hash table, on the assumption that @protocols
	 may be adopted by root classes or categories.  */
      if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
	  || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
	class = lookup_interface (CLASS_NAME (class));

      if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
	  || !CLASS_SUPER_NAME (class))
	add_method_to_hash_list (cls_method_hash_list, method);
    }

  return method;
}

static tree
add_class (tree class_name, tree name)
{
  struct interface_tuple **slot;

  /* Put interfaces on list in reverse order.  */
  TREE_CHAIN (class_name) = interface_chain;
  interface_chain = class_name;

  if (interface_htab == NULL)
    interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
  slot = (struct interface_tuple **)
    htab_find_slot_with_hash (interface_htab, name,
			      IDENTIFIER_HASH_VALUE (name),
			      INSERT);
  if (!*slot)
    {
      *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
      (*slot)->id = name;
    }
  (*slot)->class_name = class_name;

  return interface_chain;
}

/* APPLE LOCAL begin radar 4548636 */
/* This routine updates TREE_DEPRECATED/TREE_UNAVAILABLE fields of 'record' 
   type of the class. */
static void
objc_attach_attrs_to_type (tree type, tree class)
{
  tree chain;

  if (!CLASS_ATTRIBUTES (class))
    return;  /* The most common case. */

  for (chain = CLASS_ATTRIBUTES (class); chain; chain = TREE_CHAIN (chain))
    {
      if (is_attribute_p ("deprecated", TREE_PURPOSE (chain)))
	TREE_DEPRECATED (type) = 1;
      else if (is_attribute_p ("unavailable", TREE_PURPOSE (chain)))
	TREE_UNAVAILABLE (type) = 1;
    }
  return;
}

/* Warn when a 'class' with deprecated/available attribute 
   set is used. */

static void
objc_warn_on_class_attributes (tree class, bool use)
{
  tree chain;

  if (!class || !CLASS_ATTRIBUTES (class))
    return;  /* The most common case. */
  for (chain = CLASS_ATTRIBUTES (class); chain; chain = TREE_CHAIN (chain))
    {
      if (is_attribute_p ("deprecated", TREE_PURPOSE (chain)))
	{
	  if (use)
	    warning (0, "class %qs is deprecated",
		     IDENTIFIER_POINTER (CLASS_NAME (class))); 
	}
      else if (is_attribute_p ("unavailable", TREE_PURPOSE (chain)))
	{
	  if (use)
	    warning (0, "class %qs is unavailable",
		     IDENTIFIER_POINTER (CLASS_NAME (class)));
	}
      /* APPLE LOCAL begin radar 4705298, 48431458 */
      else if (!use && is_attribute_p ("visibility", TREE_PURPOSE (chain)))
        {
          tree id = TREE_VALUE (TREE_VALUE ((chain)));
          const char *attr_arg = TREE_STRING_POINTER (id);
          if (strcmp (attr_arg, "hidden") && strcmp (attr_arg, "default"))
            warning (0, "only \"hidden\" or \"default\" visibility attribute allowed on a class");
          return;
        }
      /* APPLE LOCAL end radar 4705298, 48431458 */
      /* APPLE LOCAL begin radar 5008110 */
      else if (is_attribute_p ("objc_exception", TREE_PURPOSE (chain)))
        ;
      /* APPLE LOCAL end radar 5008110 */
      else if (!use)
	warning (0, "attribute %s is unknown - ignored",
		  IDENTIFIER_POINTER (TREE_PURPOSE (chain)));
    }
  return;
}
/* APPLE LOCAL end radar 4548636 */

static void
add_category (tree class, tree category)
{
  /* Put categories on list in reverse order.  */
  tree cat = lookup_category (class, CLASS_SUPER_NAME (category));

  if (cat)
    {
      warning (0, "duplicate interface declaration for category %<%s(%s)%>",
	       IDENTIFIER_POINTER (CLASS_NAME (class)),
	       IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
    }
  else
    {
      CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
      CLASS_CATEGORY_LIST (class) = category;
    }
  /* APPLE LOCAL radar 4548636 */
  objc_warn_on_class_attributes (class, true);
}

/* Called after parsing each instance variable declaration. Necessary to
   preserve typedefs and implement public/private...

   PUBLIC is 1 for public, 0 for protected, and 2 for private.  */

static tree
add_instance_variable (tree class, int public, tree field_decl)
{
  tree field_type = TREE_TYPE (field_decl);
  const char *ivar_name = DECL_NAME (field_decl)
			  ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
			  : "<unnamed>";

#ifdef OBJCPLUS
  if (TREE_CODE (field_type) == REFERENCE_TYPE)
    {
      error ("illegal reference type specified for instance variable %qs",
	     ivar_name);
      /* Return class as is without adding this ivar.  */
      return class;
    }
#endif

  if (field_type == error_mark_node || !TYPE_SIZE (field_type)
      || TYPE_SIZE (field_type) == error_mark_node)
      /* 'type[0]' is allowed, but 'type[]' is not! */
    {
      error ("instance variable %qs has unknown size", ivar_name);
      /* Return class as is without adding this ivar.  */
      return class;
    }

#ifdef OBJCPLUS
  /* Check if the ivar being added has a non-POD C++ type.   If so, we will
     need to either (1) warn the user about it or (2) generate suitable
     constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
     methods (if '-fobjc-call-cxx-cdtors' was specified).  */
  if (IS_AGGR_TYPE (field_type)
      && (TYPE_NEEDS_CONSTRUCTING (field_type)
	  || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
	  || TYPE_POLYMORPHIC_P (field_type)))
    {
      const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));

      if (flag_objc_call_cxx_cdtors)
        {
	  /* Since the ObjC runtime will be calling the constructors and
	     destructors for us, the only thing we can't handle is the lack
	     of a default constructor.  */
	  if (TYPE_NEEDS_CONSTRUCTING (field_type)
	      && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
	    {
	      warning (0, "type %qs has no default constructor to call",
		       type_name);

	      /* If we cannot call a constructor, we should also avoid
		 calling the destructor, for symmetry.  */
	      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
		warning (0, "destructor for %qs shall not be run either",
			 type_name);
	    }
        }
      else
	{
	  static bool warn_cxx_ivars = false;

	  if (TYPE_POLYMORPHIC_P (field_type))
	    {
	      /* Vtable pointers are Real Bad(tm), since Obj-C cannot
		 initialize them.  */
	      error ("type %qs has virtual member functions", type_name);
	      error ("illegal aggregate type %qs specified "
		     "for instance variable %qs",
		     type_name, ivar_name);
	      /* Return class as is without adding this ivar.  */
	      return class;
	    }

	  /* User-defined constructors and destructors are not known to Obj-C
	     and hence will not be called.  This may or may not be a problem. */
	  if (TYPE_NEEDS_CONSTRUCTING (field_type))
	    warning (0, "type %qs has a user-defined constructor", type_name);
	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
	    warning (0, "type %qs has a user-defined destructor", type_name);

	  if (!warn_cxx_ivars)
	    {
	      warning (0, "C++ constructors and destructors will not "
		       "be invoked for Objective-C fields");
	      warn_cxx_ivars = true;
	    }
	}
    }
#endif

  /* Overload the public attribute, it is not used for FIELD_DECLs.  */
  switch (public)
    {
    case 0:
      TREE_PUBLIC (field_decl) = 0;
      TREE_PRIVATE (field_decl) = 0;
      TREE_PROTECTED (field_decl) = 1;
      /* APPLE LOCAL radar 4951615 */
      IVAR_PUBLIC_OR_PROTECTED (field_decl) = 1;
      break;

    /* APPLE LOCAL radar 4564694 */
    case 3: /* @package */
    case 1:
      TREE_PUBLIC (field_decl) = 1;
      /* APPLE LOCAL radar 4951615, radar 4564694 */
      IVAR_PUBLIC_OR_PROTECTED (field_decl) = (flag_objc_abi == 2 && public == 3) ? 0 : 1;
      TREE_PRIVATE (field_decl) = 0;
      TREE_PROTECTED (field_decl) = 0;
      break;

    case 2:
      TREE_PUBLIC (field_decl) = 0;
      TREE_PRIVATE (field_decl) = 1;
      TREE_PROTECTED (field_decl) = 0;
      /* APPLE LOCAL radar 4951615 */
      IVAR_PUBLIC_OR_PROTECTED (field_decl) = 0;
      break;

    }

  CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);

  return class;
}

static tree
is_ivar (tree decl_chain, tree ident)
{
  for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
    if (DECL_NAME (decl_chain) == ident)
      return decl_chain;
  return NULL_TREE;
}

/* APPLE LOCAL begin radar 4653319 */
/* Just like is_ivar, except it also looks into inheritance chain. */

static tree
nested_ivar_lookup (tree interface, tree ident)
{
  tree ivar_chain = CLASS_IVARS (interface);
  tree res = is_ivar (ivar_chain, ident);
  if (res)
    return res;

  while (CLASS_SUPER_NAME (interface))
    {
      interface = lookup_interface (CLASS_SUPER_NAME (interface));
      if (interface)
        return nested_ivar_lookup (interface, ident);
    }
  return res;
}

/* APPLE LOCAL end radar 4653319 */

/* True if the ivar is private and we are not in its implementation.  */

static int
is_private (tree decl)
{
  return (TREE_PRIVATE (decl)
	  && ! is_ivar (CLASS_IVARS (implementation_template),
			DECL_NAME (decl)));
}

/* We have an instance variable reference;, check to see if it is public.  */

int
objc_is_public (tree expr, tree identifier)
{
  tree basetype, decl;

#ifdef OBJCPLUS
  if (processing_template_decl)
    return 1;
#endif
  /* APPLE LOCAL begin radar 4862848 */
  if (expr == error_mark_node)
    return 0;
  /* APPLE LOCAL end radar 4862848 */

  if (TREE_TYPE (expr) == error_mark_node)
    return 1;

  basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));

  if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
    {
      if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
	{
	  tree class = lookup_interface (OBJC_TYPE_NAME (basetype));

	  if (!class)
	    {
	      error ("cannot find interface declaration for %qs",
		     IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
	      return 0;
	    }

	  if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
	    {
	      if (TREE_PUBLIC (decl))
		return 1;

	      /* Important difference between the Stepstone translator:
		 all instance variables should be public within the context
		 of the implementation.  */
	      if (objc_implementation_context
		 && ((TREE_CODE (objc_implementation_context)
		      == CLASS_IMPLEMENTATION_TYPE)
		     || (TREE_CODE (objc_implementation_context)
			 == CATEGORY_IMPLEMENTATION_TYPE)))
		{
		  tree curtype = TYPE_MAIN_VARIANT
				 (CLASS_STATIC_TEMPLATE
				  (implementation_template));

		  if (basetype == curtype
		      || DERIVED_FROM_P (basetype, curtype))
		    {
		      int private = is_private (decl);

		      if (private)
			error ("instance variable %qs is declared private",
			       IDENTIFIER_POINTER (DECL_NAME (decl)));

		      return !private;
		    }
		}

	      /* The 2.95.2 compiler sometimes allowed C functions to access
		 non-@public ivars.  We will let this slide for now...  */
	      if (!objc_method_context)
	      {
		/* APPLE LOCAL begin radar 4805612 */
		/* Now must allow access to private/protected ivar through an object 
		   pointer in a nested C function. */
		if (objc_interface_context &&
		    (TREE_CODE (objc_interface_context) == CLASS_INTERFACE_TYPE
		     || TREE_CODE (objc_interface_context) == CATEGORY_INTERFACE_TYPE))
		  {
                    /* APPLE LOCAL begin radar 5471096 */
                    tree class = 
                      TREE_CODE (objc_interface_context) == CLASS_INTERFACE_TYPE 
                        ? objc_interface_context 
                        : lookup_interface (CLASS_NAME (objc_interface_context));
		    tree curtype = 
                      TYPE_MAIN_VARIANT (CLASS_STATIC_TEMPLATE (class));
                    /* APPLE LOCAL end radar 5471096 */
		    if (basetype == curtype
			|| DERIVED_FROM_P (basetype, curtype))
		     {
		       int private;
		       gcc_assert (!implementation_template);
		       implementation_template = objc_interface_context; /* ref'ed in is_private */
		       private = is_private (decl);
		       implementation_template = NULL_TREE;
		       if (private)
			 error ("instance variable %qs is declared private",
				IDENTIFIER_POINTER (DECL_NAME (decl)));
		       return !private;
		     }
		  }
		/* APPLE LOCAL end radar 4805612 */
		warning (0, "instance variable %qs is %s; "
			 "this will be a hard error in the future",
			 IDENTIFIER_POINTER (identifier),
			 TREE_PRIVATE (decl) ? "@private" : "@protected");
		return 1;
	      }

	      error ("instance variable %qs is declared %s",
		     IDENTIFIER_POINTER (identifier),
		     TREE_PRIVATE (decl) ? "private" : "protected");
	      return 0;
	    }
	}
    }

  return 1;
}
/* APPLE LOCAL begin radar 4568791 */
/* This routine gets called when there is no implementation of method declared
   in protocol in current class. This used to cause a warning, but now rules
   are relaxed so if the method has been declared in an inherited class no warning
   will be issued. 
*/
static bool
objc_method_inherited (tree meth, int mtype, tree interface)
{
  tree list;
  tree inter = interface;

  while ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
    {
      list = (mtype == '+') ? CLASS_CLS_METHODS (inter) 
			    : CLASS_NST_METHODS (inter);
    if (lookup_method (list, meth))
      return true;
    }

  return false;
}
/* APPLE LOCAL end radar 4568791 */

/* APPLE LOCAL begin radar 4449535 */
/* This routine checks to see if class implements forwardInvocation method and objects 
   of this class are derived from 'NSProxy' so that to forward requests from one object 
   to another. It then returns 'true' or 'false' accordingly.
   Under such conditions, which means that every method possible is implemented in the class,
   gcc should not issue "Method definition not found" warnings.
*/
static bool
objc_impl_forwardInvocation (tree context)
{
  tree inherit;
  if (fast_lookup_method (false, context, get_identifier ("forwardInvocation:"))
      == NULL_TREE)
    return false;
  inherit = lookup_interface (CLASS_SUPER_NAME (context));
  while (inherit)
    {
      if (!strcmp (IDENTIFIER_POINTER (CLASS_NAME (inherit)), "NSProxy"))
	return true;
      inherit = lookup_interface (CLASS_SUPER_NAME (inherit));
    }
  return false;
}
/* APPLE LOCAL end radar 4449535 */

/* APPLE LOCAL begin radar 5453108 */
/* This routine checks to see if there is a setter/getter method declared in current
   class. If so, it returns 'true' so caller does not issue a warning. This is 
   the case of a method declared in class's protocol which matches class's getter/settter.
*/
static bool
property_method_in_class (tree meth, bool inst_method, tree interface)
{
  tree list, property_method;
  if (!interface || !inst_method)
    return false;
  list = CLASS_NST_METHODS (interface);

  property_method = lookup_method (list, meth);
  return (property_method && 
	  METHOD_PROPERTY_CONTEXT (property_method) != NULL); 
}
/* APPLE LOCAL end radar 5453108 */
/* Make sure all entries in CHAIN are also in LIST.  */

static int
/* APPLE LOCAL radar 4568791, 4359757 */
check_methods (tree chain, int mtype, tree interface)
{
  int first = 1;

  while (chain)
    {
      /* APPLE LOCAL begin radar 4359757 */
      if (!fast_lookup_method (mtype == (int)'+', 
			       objc_implementation_context, METHOD_SEL_NAME (chain)))
      /* APPLE LOCAL end radar 4359757 */
	{
	  /* APPLE LOCAL begin C* property metadata (Radar 4498373) */
	  /* APPLE LOCAL begin radar 5453108 */
	  if (chain != NULL && (METHOD_PROPERTY_CONTEXT (chain) != NULL_TREE ||
				property_method_in_class (chain, mtype == (int)'-', interface)))
	  /* APPLE LOCAL end radar 5453108 */
	    {
	      /* Case of instance method in interface not found in its implementation.
		 This is OK in case of instance method setter/getter declaration synthesized 
		 via property declaration in the interface. Happens for dynamic properties. */
	      gcc_assert (mtype == (int)'-');
	      chain = TREE_CHAIN (chain);
	      continue;
	    }
	  /* APPLE LOCAL end C* property metadata (Radar 4498373) */
	  /* APPLE LOCAL begin radar 4568791 */
	  else if (interface && objc_method_inherited (chain, mtype, interface))
	    {
	      /* Don't issue the warning if method declared in protocol has been
		 declared in the inheritance heirarchy. */
	      chain = TREE_CHAIN (chain);
	      continue;
	    }
	  /* APPLE LOCAL end radar 4568791 */
	  if (first)
	    {
	      if (TREE_CODE (objc_implementation_context)
		  == CLASS_IMPLEMENTATION_TYPE)
		warning (0, "incomplete implementation of class %qs",
			 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
	      else if (TREE_CODE (objc_implementation_context)
		       == CATEGORY_IMPLEMENTATION_TYPE)
		warning (0, "incomplete implementation of category %qs",
			 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
	      first = 0;
	    }

	  warning (0, "method definition for %<%c%s%> not found",
		   mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
	}

      chain = TREE_CHAIN (chain);
    }

    return first;
}

/* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL.  */

static int
conforms_to_protocol (tree class, tree protocol)
{
   if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
     {
       tree p = CLASS_PROTOCOL_LIST (class);
       while (p && TREE_VALUE (p) != protocol)
	 p = TREE_CHAIN (p);

       if (!p)
	 {
	   tree super = (CLASS_SUPER_NAME (class)
			 ? lookup_interface (CLASS_SUPER_NAME (class))
			 : NULL_TREE);
	   int tmp = super ? conforms_to_protocol (super, protocol) : 0;
	   if (!tmp)
	     return 0;
	 }
     }

   return 1;
}

/* Make sure all methods in CHAIN are accessible as MTYPE methods in
   CONTEXT.  This is one of two mechanisms to check protocol integrity.  */

static int
check_methods_accessible (tree chain, tree context, int mtype)
{
  int first = 1;
  tree list;
  tree base_context = context;

  while (chain)
    {
      /* APPLE LOCAL begin radar 4963113 */
      if (chain != NULL && METHOD_PROPERTY_CONTEXT (chain) != NULL_TREE)
	{
	  /* Case of an accessor in protocol not implemented in @implementation.
	     This is OK when property is declared dynamic. So, with -Wno-protocol
	     no warning must be issued. Cousin of radar 4498373 */
	  gcc_assert (mtype == (int)'-');
	  gcc_assert (TREE_CODE (METHOD_PROPERTY_CONTEXT (chain)) == PROPERTY_DECL);
	  chain = TREE_CHAIN (chain);
	  continue;
        }
      /* APPLE LOCAL end radar 4963113 */
      context = base_context;
      while (context)
	{
	  if (mtype == '+')
	    list = CLASS_CLS_METHODS (context);
	  else
	    list = CLASS_NST_METHODS (context);

	  if (lookup_method (list, chain))
	      break;

	  else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
		   || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
	    context = (CLASS_SUPER_NAME (context)
		       ? lookup_interface (CLASS_SUPER_NAME (context))
		       : NULL_TREE);

	  else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
		   || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
	    context = (CLASS_NAME (context)
		       ? lookup_interface (CLASS_NAME (context))
		       : NULL_TREE);
	  else
	    abort ();
	}

      if (context == NULL_TREE)
	{
	  if (first)
	    {
	      if (TREE_CODE (objc_implementation_context)
		  == CLASS_IMPLEMENTATION_TYPE)
		warning (0, "incomplete implementation of class %qs",
			 IDENTIFIER_POINTER
			   (CLASS_NAME (objc_implementation_context)));
	      else if (TREE_CODE (objc_implementation_context)
		       == CATEGORY_IMPLEMENTATION_TYPE)
		warning (0, "incomplete implementation of category %qs",
			 IDENTIFIER_POINTER
			   (CLASS_SUPER_NAME (objc_implementation_context)));
	      first = 0;
	    }
	  warning (0, "method definition for %<%c%s%> not found",
		   mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
	}

      chain = TREE_CHAIN (chain); /* next method...  */
    }
  return first;
}

/* Check whether the current interface (accessible via
   'objc_implementation_context') actually implements protocol P, along
   with any protocols that P inherits.  */

static void
/* APPLE LOCAL radar 4568791 */
check_protocol (tree p, const char *type, const char *name, tree interface)
{
  if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
    {
      /* APPLE LOCAL radar 4449535 */
      int f1, f2=1;

      /* Ensure that all protocols have bodies!  */
      if (warn_protocol)
	{
	  f1 = check_methods (PROTOCOL_CLS_METHODS (p),
			      /* APPLE LOCAL radar 4359757 */
			      /* argument removed */
			      /* APPLE LOCAL radar 4568791 */
			      '+', interface);
	  /* APPLE LOCAL begin radar 4449535 */
	  if (!objc_impl_forwardInvocation (objc_implementation_context))
	    f2 = check_methods (PROTOCOL_NST_METHODS (p),
			        /* APPLE LOCAL radar 4359757 */
			        /* argument removed */
			        /* APPLE LOCAL radar 4568791 */
			        '-', interface);
	  /* APPLE LOCAL end radar 4449535 */
	}
      else
	{
	  f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
					 objc_implementation_context,
					 '+');
 	  /* APPLE LOCAL begin radar 4449535 */
	  if (!objc_impl_forwardInvocation (objc_implementation_context))
	    f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
					   objc_implementation_context,
					   '-');
 	  /* APPLE LOCAL end radar 4449535 */
	}

      if (!f1 || !f2)
	warning (0, "%s %qs does not fully implement the %qs protocol",
		 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
    }

  /* Check protocols recursively.  */
  if (PROTOCOL_LIST (p))
    {
      tree subs = PROTOCOL_LIST (p);
      tree super_class =
	lookup_interface (CLASS_SUPER_NAME (implementation_template));

      while (subs)
	{
	  tree sub = TREE_VALUE (subs);

	  /* If the superclass does not conform to the protocols
	     inherited by P, then we must!  */
	  if (!super_class || !conforms_to_protocol (super_class, sub))
	    /* APPLE LOCAL radar 4568791 */
	    check_protocol (sub, type, name, interface);
	  subs = TREE_CHAIN (subs);
	}
    }
}

/* Check whether the current interface (accessible via
   'objc_implementation_context') actually implements the protocols listed
   in PROTO_LIST.  */

static void
/* APPLE LOCAL radar 4568791 */
check_protocols (tree proto_list, const char *type, const char *name, tree interface)
{
  for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
    {
      tree p = TREE_VALUE (proto_list);

      /* APPLE LOCAL radar 4568791 */
      check_protocol (p, type, name, interface);
    }
}

/* Make sure that the class CLASS_NAME is defined
   CODE says which kind of thing CLASS_NAME ought to be.
   It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
   CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.  */

static tree
start_class (enum tree_code code, tree class_name, tree super_name,
	     tree protocol_list)
{
  /* APPLE LOCAL radar 5835805 */
  tree class, decl, aliased_class_name;

#ifdef OBJCPLUS
  if (current_namespace != global_namespace) {
    error ("Objective-C declarations may only appear in global scope");
  }
#endif /* OBJCPLUS */

  if (objc_implementation_context)
    {
      warning (0, "%<@end%> missing in implementation context");
      finish_class (objc_implementation_context);
      objc_ivar_chain = NULL_TREE;
      objc_implementation_context = NULL_TREE;
    }

  class = make_node (code);
  TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);

  /* Check for existence of the super class, if one was specified.  Note
     that we must have seen an @interface, not just a @class.  If we
     are looking at a @compatibility_alias, traverse it first.  */
  if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
      && super_name)
    {
      tree super = objc_is_class_name (super_name);
      /* APPLE LOCAL begin radar 4548636 */
      tree super_interface = NULL_TREE;
      if (!super || !(super_interface = lookup_interface (super)))
	{
	  error ("cannot find interface declaration for %qs, superclass of %qs",
		 IDENTIFIER_POINTER (super ? super : super_name),
		 IDENTIFIER_POINTER (class_name));
	  super_name = NULL_TREE;
	}
      else
        {
	  objc_warn_on_class_attributes (super_interface, true);
	  super_name = super;
        }
      /* APPLE LOCAL end radar 4548636 */
    }
  /* APPLE LOCAL begin radar 5835805 */
  aliased_class_name = objc_is_class_name (class_name);
  if (aliased_class_name)
    class_name = aliased_class_name;
  /* APPLE LOCAL end radar 5835805 */
  CLASS_NAME (class) = class_name;
  CLASS_SUPER_NAME (class) = super_name;
  CLASS_CLS_METHODS (class) = NULL_TREE;

  /* APPLE LOCAL radar 4695109 */
  /* PROTOCOL_IMPLEMENTATION_TYPE removed */
  /* APPLE LOCAL radar 5835805 */
  if (!aliased_class_name 
      && (decl = lookup_name (class_name)))
    {
      error ("%qs redeclared as different kind of symbol",
	     IDENTIFIER_POINTER (class_name));
      error ("previous declaration of %q+D",
	     decl);
    }

  if (code == CLASS_IMPLEMENTATION_TYPE)
    {
      {
        tree chain;

        for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
           if (TREE_VALUE (chain) == class_name)
	     {
	       error ("reimplementation of class %qs",
		      IDENTIFIER_POINTER (class_name));
	       /* APPLE LOCAL radar 4689268 */
	       return class;
	     }
        implemented_classes = tree_cons (NULL_TREE, class_name,
					 implemented_classes);
      }

      /* Reset for multiple classes per file.  */
      method_slot = 0;

      objc_implementation_context = class;

      /* Lookup the interface for this implementation.  */

      if (!(implementation_template = lookup_interface (class_name)))
        {
	  warning (0, "cannot find interface declaration for %qs",
		   IDENTIFIER_POINTER (class_name));
	  add_class (implementation_template = objc_implementation_context,
		     class_name);
        }

      /* If a super class has been specified in the implementation,
	 insure it conforms to the one specified in the interface.  */

      if (super_name
	  && (super_name != CLASS_SUPER_NAME (implementation_template)))
        {
	  tree previous_name = CLASS_SUPER_NAME (implementation_template);
          const char *const name =
	    previous_name ? IDENTIFIER_POINTER (previous_name) : "";
          /* APPLE LOCAL begin radar 5835805 */
	  error ("conflicting super class name %qs in interface %qs and its implementation",
		 IDENTIFIER_POINTER (super_name), IDENTIFIER_POINTER (class_name));
          if (previous_name)
            error ("previous declaration of %qs", name);
          /* APPLE LOCAL end radar 5835805 */
        }

      else if (! super_name)
	{
	  CLASS_SUPER_NAME (objc_implementation_context)
	    = CLASS_SUPER_NAME (implementation_template);
	}
    }

  else if (code == CLASS_INTERFACE_TYPE)
    {
      if (lookup_interface (class_name))
        /* APPLE LOCAL begin radar 5835805 */
	error ("duplicate interface declaration for class %qs",
               IDENTIFIER_POINTER (class_name));
        /* APPLE LOCAL end radar 5835805 */
      else
        add_class (class, class_name);

      if (protocol_list)
	CLASS_PROTOCOL_LIST (class)
	    /* APPLE LOCAL radar 4398221 */
	  = lookup_and_install_protocols (protocol_list, true);
    }

  else if (code == CATEGORY_INTERFACE_TYPE)
    {
      tree class_category_is_assoc_with;

      /* For a category, class_name is really the name of the class that
	 the following set of methods will be associated with. We must
	 find the interface so that can derive the objects template.  */

      if (!(class_category_is_assoc_with = lookup_interface (class_name)))
	{
	  error ("cannot find interface declaration for %qs",
		 IDENTIFIER_POINTER (class_name));
	  exit (FATAL_EXIT_CODE);
	}
      else
        add_category (class_category_is_assoc_with, class);

      if (protocol_list)
	CLASS_PROTOCOL_LIST (class)
	    /* APPLE LOCAL radar 4398221 */	
	  = lookup_and_install_protocols (protocol_list, true);
    }

  else if (code == CATEGORY_IMPLEMENTATION_TYPE)
    {
      /* Reset for multiple classes per file.  */
      method_slot = 0;

      objc_implementation_context = class;

      /* For a category, class_name is really the name of the class that
	 the following set of methods will be associated with.  We must
	 find the interface so that can derive the objects template.  */

      if (!(implementation_template = lookup_interface (class_name)))
        {
	  error ("cannot find interface declaration for %qs",
		 IDENTIFIER_POINTER (class_name));
	  exit (FATAL_EXIT_CODE);
        }
    }
  return class;
}

static tree
continue_class (tree class)
{
  if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
      || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
    {
      struct imp_entry *imp_entry;

      /* Check consistency of the instance variables.  */

      if (CLASS_RAW_IVARS (class))
	check_ivars (implementation_template, class);

      /* code generation */

#ifdef OBJCPLUS
      push_lang_context (lang_name_c);
#endif

      build_private_template (implementation_template);
      uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
      objc_instance_type = build_pointer_type (uprivate_record);

      /* APPLE LOCAL radar 4551602 */
      imp_entry = (struct imp_entry *) ggc_alloc_cleared (sizeof (struct imp_entry));

      imp_entry->next = imp_list;
      imp_entry->imp_context = class;
      imp_entry->imp_template = implementation_template;

      /* APPLE LOCAL begin ObjC new abi */
      if (flag_objc_abi == 2)
	{
	  synth_v2_forward_declarations ();
      	  imp_entry->class_v2_decl = UOBJC_V2_CLASS_decl;
      	  imp_entry->meta_v2_decl = UOBJC_V2_METACLASS_decl;
	}
      else
	{
          synth_forward_declarations ();
          imp_entry->class_decl = UOBJC_CLASS_decl;
          imp_entry->meta_decl = UOBJC_METACLASS_decl;
	}
      /* APPLE LOCAL end ObjC new abi */
      imp_entry->has_cxx_cdtors = 0;

      /* Append to front and increment count.  */
      imp_list = imp_entry;
      if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
	imp_count++;
      else
	cat_count++;

#ifdef OBJCPLUS
      pop_lang_context ();
#endif /* OBJCPLUS */

      return get_class_ivars (implementation_template, true);
    }

  else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
    {
#ifdef OBJCPLUS
      push_lang_context (lang_name_c);
#endif /* OBJCPLUS */

      /* APPLE LOCAL radar 4291785 */
      objc_collecting_ivars = 1;
      build_private_template (class);
      /* APPLE LOCAL radar 4291785 */
      objc_collecting_ivars = 0;

#ifdef OBJCPLUS
      pop_lang_context ();
#endif /* OBJCPLUS */

      return NULL_TREE;
    }
  /* APPLE LOCAL radar 4695109 */
  /* PROTOCOL_IMPLEMENTATION_TYPE removed */

  else
    return error_mark_node;
}

/* APPLE LOCAL begin objc new property */
/* This routine issues diagnostics on two mismatched properties passed as argument. 
   - CL_PROP class property
   - PROPERTY is declared in 'super' class (SUPER is true) or protocol (SUPER is false).
   - MESS is the string attached to the diagnostic.
   - NAME property name.
*/
static void
/* APPLE LOCAL radar 5218071 */
diagnose_property_mismatch (tree cl_prop, bool super, tree property, const char *mess, tree name)
{
  /* Check that attributes and types match for protocol and its conforming class. */
  /* APPLE LOCAL begin radar 4815061 */
  if (PROPERTY_READONLY (cl_prop) == boolean_true_node 
      && PROPERTY_READWRITE (property) == boolean_true_node)
    warning (0, "attribute 'readonly' of property %qs restricts attribute 'readwrite' of %qs property in %s",
	   IDENTIFIER_POINTER (PROPERTY_NAME (cl_prop)), 
	   IDENTIFIER_POINTER (name), mess);
  /* APPLE LOCAL end radar 4815061 */
  if (PROPERTY_COPY (cl_prop) != PROPERTY_COPY (property))
    warning (0, "property %qs 'copy' attribute does not match %s %qs property",
	   IDENTIFIER_POINTER (PROPERTY_NAME (cl_prop)), mess,
	   IDENTIFIER_POINTER (name));
  else if (PROPERTY_RETAIN (cl_prop) != PROPERTY_RETAIN (property))
    warning (0, "property %qs 'retain' attribute does not match %s %qs property",
	   IDENTIFIER_POINTER (PROPERTY_NAME (cl_prop)), mess,
	   IDENTIFIER_POINTER (name));
  if (PROPERTY_SETTER_NAME (cl_prop) != PROPERTY_SETTER_NAME (property))
    warning (0, "property %qs 'setter' attribute does not match %s %qs property",
	   IDENTIFIER_POINTER (PROPERTY_NAME (cl_prop)), mess,
	   IDENTIFIER_POINTER (name));
  if (PROPERTY_GETTER_NAME (cl_prop) != PROPERTY_GETTER_NAME (property))
    warning (0, "property %qs 'getter' attribute does not match %s %qs property",
	   IDENTIFIER_POINTER (PROPERTY_NAME (cl_prop)), mess,
	   IDENTIFIER_POINTER (name));
  /* APPLE LOCAL begin radar 5218071 */
  if (comptypes (TREE_TYPE (cl_prop), TREE_TYPE (property)) != 1) {
    if (super && 
        PROPERTY_READONLY (cl_prop) == boolean_true_node &&
        PROPERTY_READONLY (property) == boolean_true_node &&
        objc_compare_types (TREE_TYPE (cl_prop), TREE_TYPE (property), 
			    /* APPLE LOCAL radar 6231433 */
                            -6, NULL_TREE, NULL))
      ;
    else
      warning (0, "property %qs type does not match %s %qs property type",
               IDENTIFIER_POINTER (PROPERTY_NAME (cl_prop)), mess,
               IDENTIFIER_POINTER (name));
  }
  /* APPLE LOCAL end radar 5218071 */
  if (flag_objc_gc &&
      objc_is_gcable_type (TREE_TYPE (cl_prop)) != objc_is_gcable_type (TREE_TYPE (property)))
    warning (0, "property %qs storage type does not match %s %qs property storage type",
	   IDENTIFIER_POINTER (PROPERTY_NAME (cl_prop)), mess,
	   IDENTIFIER_POINTER (name));
  /* APPLE LOCAL begin radar 4947014 - objc atomic property */
  if (IS_ATOMIC (cl_prop) != IS_ATOMIC (property))
    warning (0, "property %qs and its %s %qs don't have matching 'atomic' attribute",
	     IDENTIFIER_POINTER (PROPERTY_NAME (cl_prop)), mess,
	     IDENTIFIER_POINTER (name));
  /* APPLE LOCAL end radar 4947014 - objc atomic property */
}

/* This routine goes through list of 'super' class's property list and diagnoses attribute
   mismatch between those and the same properties declared in the class. */

static void
objc_compare_properties_with_super (tree class)
{
  tree super;
  tree property, cl_prop;

  if (CLASS_SUPER_NAME (class) == NULL_TREE)
    return;
  super = lookup_interface (CLASS_SUPER_NAME (class));
  if (super == NULL_TREE)
    return;
  for (property = CLASS_PROPERTY_DECL (super); property;
       property = TREE_CHAIN (property))
    if ((cl_prop = lookup_property_in_list (class, DECL_NAME (property))))
      /* APPLE LOCAL radar 5218071 */
      diagnose_property_mismatch (cl_prop, true, property, "super class", CLASS_NAME (super));
}
/* APPLE LOCAL end objc new property */

/* APPLE LOCAL begin radar 4564386 */
/* This routine merges all properties declared in protocol but not 
   in the class to the class. */

static void
objc_merge_proto_properties_in_class (tree class, tree rproto_list)
{
  tree rproto;
  for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
    {
      tree p = TREE_VALUE (rproto);
      if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
	{
	  /* APPLE LOCAL objc new property */
	  tree property, cl_prop;
	  for (property = CLASS_PROPERTY_DECL (p); property; 
	       property = TREE_CHAIN (property))
	    /* APPLE LOCAL objc new property */
	    if (!(cl_prop = lookup_property_in_list (class, DECL_NAME (property))))
	      {
		/* Add the property found in protocol but not in the class to
		   the class's list of properties. */
		tree x = copy_node (property);
	  	TREE_CHAIN (x) = IMPL_PROPERTY_DECL (class);
		IMPL_PROPERTY_DECL (class) = x;
	      }
	    /* APPLE LOCAL begin objc new property */
	    else
               /* APPLE LOCAL radar 5218071 */
	      diagnose_property_mismatch (cl_prop, false, property, "protocol", PROTOCOL_NAME (p));
	    /* APPLE LOCAL end objc new property */
	  /* Search in nested protocols also. */
	  objc_merge_proto_properties_in_class (class, PROTOCOL_LIST (p));
	}      
    }
}
/* APPLE LOCAL end radar 4564386 */

/* APPLE LOCAL begin C* language */
/* This routine builds a property ivar name. */

static char *
objc_build_property_ivar_name (tree property_decl)
{
  static char string[BUFSIZE];
  sprintf (string, "_%s", IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
  return string;
}

/* This routine builds name of the setter synthesized function. */

static char *
objc_build_property_setter_name (tree ident, bool delimit_colon)
{
  extern int toupper(int);
  static char string[BUFSIZE];
  if (delimit_colon)
    sprintf (string, "set%s:", IDENTIFIER_POINTER (ident));
  else
    sprintf (string, "set%s", IDENTIFIER_POINTER (ident));
  string[3] = toupper (string[3]);
  return string;
}

/* This routine does all the work for generting data and code per each 
   property declared in current implementation. */

static void
objc_gen_one_property_data (tree class, tree property, tree class_methods)
{
  /* If getter, check that it is already declared in user code. */
  if (PROPERTY_GETTER_NAME (property))
    {
      if (!lookup_method (CLASS_NST_METHODS (class_methods), 
			  PROPERTY_GETTER_NAME (property))
	  && !lookup_method_in_protocol_list (CLASS_PROTOCOL_LIST (class_methods),
					      PROPERTY_GETTER_NAME (property), 0))
	error ("property getter %qs not declared in class %qs",  
		IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property)), 
		IDENTIFIER_POINTER (CLASS_NAME (class_methods)));
    }
  /* If setter, check that it is already declared in user code. */
  if (PROPERTY_SETTER_NAME (property))
    {
      if (!lookup_method (CLASS_NST_METHODS (class_methods), 
			  PROPERTY_SETTER_NAME (property))
	  && !lookup_method_in_protocol_list (CLASS_PROTOCOL_LIST (class_methods),
					      PROPERTY_SETTER_NAME (property), 0))
	error ("property setter %qs not declared in class %qs",  
		IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property)), 
		IDENTIFIER_POINTER (CLASS_NAME (class_methods)));
    }
  /* If ivar attribute specified, check that it is already declared. */
  if (PROPERTY_IVAR_NAME (property) 
      && PROPERTY_IVAR_NAME (property) != boolean_true_node)
    {
      if (!nested_ivar_lookup (class, PROPERTY_IVAR_NAME (property)))
	error ("ivar %qs in property declaration must be an existing ivar", 
               IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property)));
    }
}

/* This routine processes an existing getter or setter attribute.
   It aliases internal property getter or setter to the user implemented 
   getter or setter.  */

static void 
objc_process_getter_setter (tree class, tree property, bool getter)
{
  tree prop_mth_decl;
  tree prop_getter_mth_decl;
  tree name_ident;

  if (getter)
    /* getter name is same as property name. */
    name_ident = PROPERTY_NAME (property);
  else
    /* Must synthesize setter name from property name. */
    name_ident = get_identifier (objc_build_property_setter_name (
				   PROPERTY_NAME (property), true));

  /* Find declaration of instance method for the property in its class. */
  prop_mth_decl = lookup_method (CLASS_NST_METHODS (class), name_ident);

  if (!prop_mth_decl)
    return;

  prop_getter_mth_decl = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
					getter ? PROPERTY_GETTER_NAME (property) 
					       : PROPERTY_SETTER_NAME (property));

  if (!prop_getter_mth_decl)
    return;

  /* APPLE LOCAL radar 5370783 */
  if (!match_proto_with_proto (prop_getter_mth_decl, prop_mth_decl, 2))
    {
      error ("User %s %qs does not match property %qs type", 
		getter ? "getter" : "setter",
		IDENTIFIER_POINTER (DECL_NAME (prop_getter_mth_decl)), 
		IDENTIFIER_POINTER (PROPERTY_NAME (property)));
      return;
    }
  /* We alias internal property getter to the user implemented getter by copying relevant
     entries from user's implementation to the internal one. */
  prop_mth_decl = copy_node (prop_mth_decl);
  METHOD_ENCODING (prop_mth_decl) = METHOD_ENCODING (prop_getter_mth_decl);
  METHOD_DEFINITION (prop_mth_decl) = METHOD_DEFINITION (prop_getter_mth_decl);
  objc_add_method (objc_implementation_context, prop_mth_decl, 0, 0);
}

/* This routine builds the return value of a synthesized getter in a variety
   of situations.
*/
static tree
objc_build_getter_retval (tree ivar_ident)
{
  tree ret_val;

  ret_val = objc_lookup_ivar (NULL_TREE, ivar_ident);

  return ret_val;
}

/* This routine synthesizes a 'getter' routine. */

static void
objc_synthesize_getter (tree class, tree class_method, tree property)
{
  tree fn, decl;
  tree body;
  tree ret_val;
  tree ivar_ident;

  /* No getter for a class with no 'ivar' attribute. */
  if (!PROPERTY_IVAR_NAME (property))
    {
      /* Issue a warning if there is no user-implemented getter. */
      if (!lookup_method (CLASS_NST_METHODS (
			  objc_implementation_context),PROPERTY_NAME (property)))
	{
          bool warn = true;
	  if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
	    {
	      tree category = lookup_category (class, 
				CLASS_SUPER_NAME (objc_implementation_context));
	      if (category 
		  && lookup_method (CLASS_NST_METHODS (
				    category),PROPERTY_NAME (property)))
	        warn = false;
	    }
	  if (warn)
	    warning (0, "no synthesized or user getter is available for property %qs",
		     IDENTIFIER_POINTER (DECL_NAME (property))); 
	}
      return;
    }

  /* If user has implemented a getter with same name then do nothing. */
  if (lookup_method (CLASS_NST_METHODS (
		     objc_implementation_context),PROPERTY_NAME (property)))
    return;
  /* Find declaration of the property in the interface. There must be one. */
  decl = lookup_method (CLASS_NST_METHODS (class_method),
                        PROPERTY_NAME (property));
  /* If one not declared in the inerface, this condition has already been reported
     as user error (because property was not declared in the interface. */
  if (!decl)
    return;

  objc_inherit_code = INSTANCE_METHOD_DECL;
  objc_start_method_definition (copy_node (decl), NULL_TREE);
  body = c_begin_compound_stmt (true);
  /* return self->_property_name; */
  /* If user specified an ivar, us it in generation of the getter. */
  ivar_ident = (PROPERTY_IVAR_NAME (property) != boolean_true_node)
	  	? PROPERTY_IVAR_NAME (property) 
	  	: get_identifier (objc_build_property_ivar_name (property));
  ret_val = objc_build_getter_retval (ivar_ident);

  if (ret_val)
    {
      /* APPLE LOCAL radar 5276085 */
      ret_val = objc_build_weak_reference_tree (ret_val);
#ifdef OBJCPLUS
      finish_return_stmt (ret_val);
#else
      (void)c_finish_return (ret_val);
#endif
    }
  add_stmt (c_end_compound_stmt (body, true));
  fn = current_function_decl;
#ifdef OBJCPLUS
  finish_function ();
#endif
  objc_finish_method_definition (fn);

}

/* This routine builds a single statement in a synthesized 'setter' function
   in a variety of situations. */

static tree
objc_build_setter_stmt (tree ivar_ident)
{
  tree lhs;

  lhs = objc_lookup_ivar (NULL_TREE, ivar_ident);
  /* If ivar attribute is not a user declared attribute, this condition has
     already been repored as error. */
  gcc_assert (lhs);

  if (lhs)
    {
      int save_flag_objc_gc = flag_objc_gc;
      tree store;
      tree rhs = lookup_name (get_identifier ("_value"));
      /* Recover when method does not have '_value' argument. This is because user
	 provided its own accessor and for which an error is already issued. */
      if (!rhs)
	rhs = lhs;
      /* For 'weak' property, must generate objc_assign_weak regardless of -fobjc-gc */
      flag_objc_gc = 1;
      store =  build_modify_expr (lhs, NOP_EXPR, rhs);
      flag_objc_gc = save_flag_objc_gc;
      return store;
    }
  return NULL_TREE;
}

/* This routine synthesizes a 'setter' routine. */

static void
objc_synthesize_setter (tree class, tree class_method, tree property)
{
  tree fn, decl, ivar_ident, stmt;
  tree body;
  char *setter_name;
  tree setter_ident;

  setter_name = objc_build_property_setter_name (
		  PROPERTY_NAME (property), true);
  setter_ident = get_identifier (setter_name);

  if (!PROPERTY_IVAR_NAME (property))
    {
      /* Issue a warning if there is no user-implemented getter. */
      if (!lookup_method (CLASS_NST_METHODS (
			  objc_implementation_context),setter_ident))
	{
          bool warn = true;
	  if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
	    {
	      tree category = lookup_category (class, 
				CLASS_SUPER_NAME (objc_implementation_context));
	      if (category
		  && lookup_method (CLASS_NST_METHODS (
				    category),setter_ident))
	        warn = false;
	    }
	  if (warn)
	    warning (0, "no synthesized or user setter is available for property %qs",
		     IDENTIFIER_POINTER (DECL_NAME (property))); 
	}
      return;
    }

  /* If user has implemented a setter with same name then do nothing. */
  if (lookup_method (CLASS_NST_METHODS (
		    objc_implementation_context),setter_ident))
    return;

  /* Find declaration of the property in the interface. There must be one. */
  decl = lookup_method (CLASS_NST_METHODS (class_method), setter_ident);
  /* If one not declared in the inerface, this condition has already been reported
     as user error (because property was not declared in the interface. */
  if (!decl)
    return;

  objc_inherit_code = INSTANCE_METHOD_DECL;
  objc_start_method_definition (copy_node (decl), NULL_TREE);
  body = c_begin_compound_stmt (true);
  /* _property_name = _value; */
  /* If user specified an ivar, us it in generation of the setter. */
  ivar_ident = (PROPERTY_IVAR_NAME (property) != boolean_true_node)
	  	? PROPERTY_IVAR_NAME (property) 
	  	: get_identifier (objc_build_property_ivar_name (property));
  stmt = objc_build_setter_stmt (ivar_ident);
  if (stmt)
    add_stmt (stmt);
  add_stmt (c_end_compound_stmt (body, true));
  fn = current_function_decl;
#ifdef OBJCPLUS
  finish_function ();
#endif
  objc_finish_method_definition (fn);
}

/* This routine synthesizes a 'getter' routine for new property. */
static void
objc_synthesize_new_getter (tree class, tree class_method, tree property)
{
  /* APPLE LOCAL radar 5839812 - location for synthesized methods  */
  location_t save_input_location;
  tree decl,body,ret_val,fn;
  /* APPLE LOCAL begin radar 5207415 */
  tree property_getter = PROPERTY_GETTER_NAME (property) 
			   ? PROPERTY_GETTER_NAME (property) 
			   : PROPERTY_NAME (property);
  /* APPLE LOCAL end radar 5207415 */
  /* If user has implemented a getter with same name then do nothing. */
  if (lookup_method (CLASS_NST_METHODS (
		     /* APPLE LOCAL radar 5207415 */
                     objc_implementation_context),property_getter))
    return;

  /* APPLE LOCAL begin radar 5839812 - location for synthesized methods  */
  save_input_location = input_location;
  input_location = DECL_SOURCE_LOCATION (property);
  /* APPLE LOCAL end radar 5839812 - location for synthesized methods  */

  /* APPLE LOCAL begin radar 5435299 */
  if (!flag_new_property_ivar_synthesis)
    objc_lookup_property_ivar (class, property);
  /* APPLE LOCAL end radar 5435299 */

  /* Find declaration of the property in the interface. There must be one. */
  /* APPLE LOCAL radar 5040740 - radar 5207415 */
  decl = lookup_nested_method (class_method, property_getter);
  /* If one not declared in the inerface, this condition has already been reported
     as user error (because property was not declared in the interface. */
  if (!decl)
    return;  

  /* APPLE LOCAL begin radar 4947014 - objc atomic property */
  if (!umsg_GetAtomicProperty || !umsg_CopyAtomicStruct)
    declare_atomic_property_api ();
  objc_inherit_code = INSTANCE_METHOD_DECL;
  /* APPLE LOCAL begin radar 5839812 - location for synthesized methods  */
  decl = copy_node (decl);
  DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (property);
  objc_start_method_definition (decl, NULL_TREE);
  /* APPLE LOCAL end radar 5839812 - location for synthesized methods  */
  body = c_begin_compound_stmt (true);
  if (!flag_objc_gc_only && IS_ATOMIC (property)
      && (PROPERTY_COPY (property) == boolean_true_node
          || PROPERTY_RETAIN (property) == boolean_true_node))
    {
      /* build call to:
	 id objc_getProperty (self, _cmd, offsetof (class, ivar), isAtomic) */
      tree cmd;
      /* APPLE LOCAL begin radar 5610134 */
      tree func_params, func;
      tree field_decl = nested_ivar_lookup (class, PROPERTY_IVAR_NAME (property));
      tree offset = flag_objc_abi <= 1 ? byte_position (field_decl) 
				       : ivar_offset_ref (CLASS_NAME (class), field_decl);
      /* APPLE LOCAL end radar 5610134 */
      gcc_assert (self_decl);
      cmd = TREE_CHAIN (self_decl);
      gcc_assert (cmd);
      func_params = tree_cons (NULL_TREE, self_decl,
                      tree_cons (NULL_TREE, cmd,
                        tree_cons (NULL_TREE, offset, 
			  tree_cons (NULL_TREE, boolean_true_node, NULL_TREE))));
      func = umsg_GetAtomicProperty;
      ret_val = build_function_call (func, func_params);
    }
    else
      {
 	bool isStrong = false;
        tree ret_type = TREE_TYPE (TREE_TYPE (current_function_decl));
        /* return self->ivar_name; */
        /* APPLE LOCAL begin radar 5376125 */
        int save_warn_direct_ivar_access = warn_direct_ivar_access;
        warn_direct_ivar_access = 0;
        ret_val = build_ivar_reference (PROPERTY_IVAR_NAME (property));
        warn_direct_ivar_access = save_warn_direct_ivar_access;
        /* APPLE LOCAL end radar 5376125 */

	/* Handle struct-valued functions */
	if ((TREE_CODE (ret_type) == RECORD_TYPE || TREE_CODE (ret_type) == UNION_TYPE)
            /* APPLE LOCAL radar 5080710 */
            && (TREE_ADDRESSABLE (ret_type) || targetm.calls.return_in_memory  (ret_type, 0))
	    && (IS_ATOMIC (property) || 
		(isStrong = ((flag_objc_gc || flag_objc_gc_only) 
			     && aggregate_contains_objc_pointer (ret_type)))))
	  {
	    /* struct something tmp; 
	       objc_copyStruct (&tmp, &structIvar, sizeof (struct something), isAtomic, false);
	       return tmp;
	    */
	    tree decl = create_tmp_var_raw (ret_type, NULL);
	    tree isAtomic = (IS_ATOMIC (property) ? boolean_true_node : boolean_false_node);
	    tree hasStrong = (isStrong ? boolean_true_node : boolean_false_node);
	    tree size_ret_val = build_int_cst_wide (NULL_TREE,
                                                    TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type)),
					            TREE_INT_CST_HIGH (TYPE_SIZE_UNIT (ret_type)));
	    tree func_params, stmt, tmp;
	    lang_hooks.decls.pushdecl (decl);
	    tmp = build_fold_addr_expr (decl);
	    ret_val = build_fold_addr_expr (ret_val);
	    func_params = tree_cons (NULL_TREE, tmp,
			    tree_cons (NULL_TREE, ret_val,
			      tree_cons (NULL_TREE, size_ret_val,
				tree_cons (NULL_TREE, isAtomic,
				  tree_cons (NULL_TREE, hasStrong, NULL_TREE)))));
	    stmt = build_function_call (umsg_CopyAtomicStruct, func_params);
	    add_stmt (stmt); 
	    ret_val = decl;
	  }
      }
  /* APPLE LOCAL end radar 4947014 - objc atomic property */

  if (ret_val)
    {
      /* APPLE LOCAL radar 5276085 */
      ret_val = objc_build_weak_reference_tree (ret_val);
#ifdef OBJCPLUS
      finish_return_stmt (ret_val);
#else
      (void)c_finish_return (ret_val);
#endif
    }
  add_stmt (c_end_compound_stmt (body, true));
  fn = current_function_decl;
#ifdef OBJCPLUS
  finish_function ();
#endif
  objc_finish_method_definition (fn);
  /* APPLE LOCAL radar 5839812 - location for synthesized methods  */
  input_location = save_input_location;
}

/* This routine synthesizes a 'setter' routine for new property. */
static void
objc_synthesize_new_setter (tree class, tree class_method, tree property)
{
  tree fn, decl, stmt;
  tree body, lhs;
  /* APPLE LOCAL begin radar 5207415 */
  tree setter_ident;
  /* APPLE LOCAL radar 5839812 - location for synthesized methods  */
  location_t save_input_location;

  if (PROPERTY_SETTER_NAME (property))
    setter_ident = PROPERTY_SETTER_NAME (property);
  else
    setter_ident = get_identifier (objc_build_property_setter_name (PROPERTY_NAME (property), true));
  /* APPLE LOCAL end radar 5207415 */ 

  /* If user has implemented a setter with same name then do nothing. */
  if (lookup_method (CLASS_NST_METHODS (
                     objc_implementation_context),setter_ident))
    return;

  /* APPLE LOCAL begin radar 5435299 */
  if (!flag_new_property_ivar_synthesis)
    objc_lookup_property_ivar (class, property);
  /* APPLE LOCAL end radar 5435299 */

  /* Find declaration of the property in the interface. There must be one. */
  /* APPLE LOCAL radar 5040740 */
  decl = lookup_nested_method (class_method, setter_ident);
  /* If not declared in the inerface, this condition has already been reported
     as user error (because property was not declared in the interface. */
  if (!decl)
    return;

  /* APPLE LOCAL begin radar 5839812 - location for synthesized methods  */
  save_input_location = input_location;
  input_location = DECL_SOURCE_LOCATION (property);
  /* APPLE LOCAL end radar 5839812 - location for synthesized methods  */

  /* APPLE LOCAL begin radar 4947014 - objc atomic property */
  if (!umsg_SetAtomicProperty || !umsg_CopyAtomicStruct)
    declare_atomic_property_api ();
  objc_inherit_code = INSTANCE_METHOD_DECL;
  /* APPLE LOCAL begin radar 5839812 - location for synthesized methods  */
  decl = copy_node (decl);
  DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (property);
  objc_start_method_definition (decl, NULL_TREE);
  /* APPLE LOCAL end radar 5839812 - location for synthesized methods  */
  body = c_begin_compound_stmt (true);
  /* property_name = _value; */
  stmt = NULL_TREE;
  if (PROPERTY_COPY (property) == boolean_true_node
      || (!flag_objc_gc_only && PROPERTY_RETAIN (property) == boolean_true_node))
    {
      /* build call to:
	 objc_setProperty (self, _cmd, offsetof (class, ivar), arg, [true|false], [true|false]) */
      tree cmd, arg;
      /* APPLE LOCAL begin radar 5610134 */
      tree func_params, func;
      tree field_decl = nested_ivar_lookup (class, PROPERTY_IVAR_NAME (property));
      tree offset = flag_objc_abi <= 1 ? byte_position (field_decl)
				       : ivar_offset_ref (CLASS_NAME (class), field_decl);
      /* APPLE LOCAL end radar 5610134 */
      tree shouldCopy = (PROPERTY_COPY (property) == boolean_true_node) 
		          ? boolean_true_node : boolean_false_node; 
      tree isAtomic = IS_ATOMIC (property) ? boolean_true_node : boolean_false_node;
      gcc_assert (self_decl);
      cmd = TREE_CHAIN (self_decl);
      gcc_assert (cmd);
      arg = TREE_CHAIN (cmd);
      gcc_assert (arg);
      /* APPLE LOCAL radar 5398274 */
      TREE_USED (arg) = 1;
      func_params = tree_cons (NULL_TREE, self_decl,
                      tree_cons (NULL_TREE, cmd,
                        tree_cons (NULL_TREE, offset,
                          tree_cons (NULL_TREE, arg,
                            tree_cons (NULL_TREE, isAtomic,
                              tree_cons (NULL_TREE, shouldCopy, NULL_TREE))))));
      func = umsg_SetAtomicProperty;
      stmt =  build_function_call (func, func_params);
    }
  else
    {
      tree ivar_type;
      /* APPLE LOCAL begin radar 5852190 */
      tree rhs = NULL_TREE;
      int save_warn_direct_ivar_access = warn_direct_ivar_access;
      
      if (current_function_decl && DECL_ARGUMENTS (current_function_decl))
        rhs = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)));
      /* APPLE LOCAL begin radar 5376125 */
      warn_direct_ivar_access = 0;
      lhs = build_ivar_reference (PROPERTY_IVAR_NAME (property));
      warn_direct_ivar_access = save_warn_direct_ivar_access;
      /* APPLE LOCAL end radar 5376125 */
      /* Recover when method does not have '_value' argument. This is because user
         provided its own accessor and for which an error is already issued. */
      if (!rhs) {
	fatal_error ("Failed to synthesize the setter - possibly due to earlier error");
        rhs = lhs;
      }
      /* APPLE LOCAL end radar 5852190 */
      /* APPLE LOCAL begin radar 5232840 */
      else
        TREE_USED (rhs) = 1;
      /* APPLE LOCAL end radar 5232840 */
      ivar_type = TREE_TYPE (lhs);
      if ((TREE_CODE (ivar_type) == RECORD_TYPE || TREE_CODE (ivar_type) == UNION_TYPE)
          /* APPLE LOCAL begin radar 5080710 */
          && IS_ATOMIC (property)
          && (TREE_ADDRESSABLE (ivar_type) || targetm.calls.return_in_memory  (ivar_type, 0)))
          /* APPLE LOCAL end radar 5080710 */
        {
	  /* objc_copyStruct (&structIvar, &value, sizeof (struct something), true, false); */
	  tree func_params;
	  tree isAtomic = boolean_true_node;
	  tree hasStrong = boolean_false_node;
	  tree addr_structIvar = build_fold_addr_expr (lhs);
	  tree size_struct = build_int_cst_wide (NULL_TREE,
                                                 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ivar_type)),
					         TREE_INT_CST_HIGH (TYPE_SIZE_UNIT (ivar_type)));
	  rhs = build_fold_addr_expr (rhs);
	  func_params = tree_cons (NULL_TREE, addr_structIvar,
			  tree_cons (NULL_TREE, rhs,
			    tree_cons (NULL_TREE, size_struct,
			      tree_cons (NULL_TREE, isAtomic,
				tree_cons (NULL_TREE, hasStrong, NULL_TREE)))));
	  stmt = build_function_call (umsg_CopyAtomicStruct, func_params);  
	}
      else
    	{
          /* Common case */
	  /* APPLE LOCAL 5675908 */
          stmt =  build_modify_expr (lhs, NOP_EXPR, rhs);
       }
    }
  /* APPLE LOCAL end radar 4947014 - objc atomic property */

  if (stmt)
    add_stmt (stmt);
  add_stmt (c_end_compound_stmt (body, true));
  fn = current_function_decl;
#ifdef OBJCPLUS
  finish_function ();
#endif
  objc_finish_method_definition (fn);
  /* APPLE LOCAL radar 5839812 - location for synthesized methods  */
  input_location = save_input_location;
}

/* APPLE LOCAL begin radar 4966565 */
/* This routine retrievs the base class implementation of the category implementation
   or NULL_TREE if one not found. CATEGORY_IMPL is to be CATEGORY_IMPLEMENTATION_TYPE
   and BASE_CLASS is CLASS_INTERFACE_TYPE of base class of this category. */

static tree
get_category_base_class_impl (tree category_impl, tree base_class)
{
  if (TREE_CODE  (category_impl) == CATEGORY_IMPLEMENTATION_TYPE
      && TREE_CODE (base_class) == CLASS_INTERFACE_TYPE)
    {
      struct imp_entry *impent;
      for (impent = imp_list; impent; impent = impent->next)
        {
          if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE
              && impent->imp_template == base_class)
            return impent->imp_context;
        }
    }
  return NULL_TREE;
}

/* This routine returns true, if accessor is implemenated in base @implementation of the given
   category @implementation; false otherwise. CATEGORY_IMPL is to be CATEGORY_IMPLEMENTATION_TYPE
   and BASE_CLASS is CLASS_INTERFACE_TYPE of base class of this category. */

static bool
lookup_accessor_in_base_class_impl (tree category_impl, tree base_class, tree method_ident)
{
  tree base_impl = get_category_base_class_impl (category_impl, base_class);
  return (base_impl != NULL_TREE) 
	 && lookup_method (CLASS_NST_METHODS (base_impl), method_ident);
}
/* APPLE LOCAL end radar 4966565 */

/* Main routine to generate code/data for all the property information for 
   current implemenation (class or category). CLASS is the interface where
   ivars are declared in. CLASS_METHODS is where methods are found which
   could be a class or a category depending on wheter we are implementing
   property of a class or a category.  */

static void
objc_gen_property_data (tree class, tree class_methods)
{
  tree x;
  /* Merge any property declared in interface but not in
     implementation to implementation. */
  objc_v2_merge_property ();
  
  /* Synthesize accessors for those properties specified an @synthesize */
  for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
    {
      /* Skip dynamic property. */
      if (PROPERTY_DYNAMIC (x) == boolean_true_node)
	continue;
      else if (PROPERTY_IVAR_NAME (x))
	{
	  /* property 'ivar' is set only when @synthesize is specified. */
	  objc_synthesize_new_getter (class, class_methods, x);
	  if (PROPERTY_READONLY (x) == boolean_false_node)
	    objc_synthesize_new_setter (class, class_methods, x);
	}
      else 
	{
	  if (PROPERTY_GETTER_NAME (x))
	    objc_process_getter_setter (class_methods, x, true);
	  /* APPLE LOCAL begin radar 4966565 - radar 4653422 */
	  else if (!lookup_method (CLASS_NST_METHODS (objc_implementation_context), PROPERTY_NAME (x))
	           && !lookup_accessor_in_base_class_impl (objc_implementation_context, class,
						           PROPERTY_NAME (x))
		   && !OPTIONAL_PROPERTY (x))
	  /* APPLE LOCAL end radar 4966565 - radar 4653422 */
	    warning (0, "property %qs requires method '-%s' to be defined - use @synthesize, "
			"@dynamic or provide a method implementation", 
		     IDENTIFIER_POINTER (PROPERTY_NAME (x)), IDENTIFIER_POINTER (PROPERTY_NAME (x)));
	  if (PROPERTY_READONLY (x) == boolean_false_node
	      && PROPERTY_SETTER_NAME (x))
	    objc_process_getter_setter (class_methods, x, false);
	  else if (PROPERTY_READONLY (x) == boolean_false_node)
	    {
	      char *setter_string_name = objc_build_property_setter_name (PROPERTY_NAME (x), true);
	      /* APPLE LOCAL begin radar 4966565 - radar 4653422 */
	      tree ident = get_identifier (setter_string_name);
	      if (!lookup_method (CLASS_NST_METHODS (objc_implementation_context), ident)
	          && !lookup_accessor_in_base_class_impl (objc_implementation_context, class, ident)
		  && !OPTIONAL_PROPERTY (x))
		warning (0, "property %qs requires the method '%s' to be defined - use @synthesize, "
			    "@dynamic or provide a method implementation",
			 IDENTIFIER_POINTER (PROPERTY_NAME (x)), setter_string_name);
	      /* APPLE LOCAL end radar 4966565 - radar 4653422 */
	    }
	}
      }
      return;

  for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
     objc_gen_one_property_data (class, x, class_methods);

  /* Synthesize all getters for properties. */
  for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
    {
     /* Skip dynamic property. */
     if (PROPERTY_DYNAMIC (x) == boolean_true_node)
       continue;
	
     /* Property has a getter attribute, no need to synthesize one. */
     if (PROPERTY_GETTER_NAME (x) == NULL_TREE)
       objc_synthesize_getter (class, class_methods, x);
     else
       objc_process_getter_setter (class_methods, x, true);

     if (PROPERTY_READONLY (x) == boolean_false_node)
       {
	 /* not a readonly property. */
	 if (PROPERTY_SETTER_NAME (x) == NULL_TREE)
	   objc_synthesize_setter (class, class_methods, x);
	 else
	   objc_process_getter_setter (class_methods, x, false);
       }
    }
}

/* This routine creates an ivar and adds it to current class's ivar list. */

static void
objc_add_internal_ivar (tree class, tree property, const char *ivar_name)
{
  tree record = CLASS_STATIC_TEMPLATE (class);
  tree type = TREE_TYPE (property);
  tree field_decl, field, nf;
  /* APPLE LOCAL begin radar 6029624 */
#ifdef OBJCPLUS
  if (TREE_CODE (type) == REFERENCE_TYPE)
    type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
#endif
  /* APPLE LOCAL end radar 6029624 */
  field_decl = create_field_decl (type,
                                  ivar_name ? ivar_name 
					    : objc_build_property_ivar_name (property));
  DECL_CONTEXT (field_decl) = record;
  /* APPLE LOCAL begin radar 5435299 */
  /* With -fnew-property-ivar_synthesis, synthesized 'ivar' is always private. */
  (void) add_instance_variable (class,
                                !flag_new_property_ivar_synthesis ? 1 : 2, field_decl);
  /* APPLE LOCAL end radar 5435299 */
  if (objc_is_strong_p (type) == -1)
    {
      tree attribute = tree_cons (NULL_TREE, get_identifier ("weak"), NULL_TREE);
      attribute = tree_cons (get_identifier ("objc_gc"), attribute, NULL_TREE);
      decl_attributes (&field_decl, attribute, 0);
    }
  /* APPLE LOCAL begin radar 5435299 */
  nf = copy_node (field_decl);
  if (flag_new_property_ivar_synthesis)
    {
      /* New field added to struct must not have ivar specific access info.
         This confuses c++'s side of its own access field checking. */
      TREE_PUBLIC (nf) = IVAR_PUBLIC_OR_PROTECTED (nf) = 1;
      TREE_PRIVATE (nf) = TREE_PROTECTED (nf) = 0;
    }
  /* APPLE LOCAL end radar 5435299 */
  /* Unfortunately, CLASS_IVARS is completed when interface is completed.
     Must add the new ivar by hand to its list here. */

#ifdef OBJCPLUS
  /* Must insert this field before the TYPE_DECL node in the chain of fields. */
  field = CLASS_IVARS (class);
  while (field && TREE_CHAIN (field)
	 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
    field = TREE_CHAIN (field);
  if (field && TREE_CHAIN (field)
      && TREE_CODE (TREE_CHAIN (field)) != FIELD_DECL)
    {
      TREE_CHAIN (nf) = TREE_CHAIN (field);
      TREE_CHAIN (field) = nf;
    }
  else
#endif /* OBJCPLUS */
  CLASS_IVARS (class) = chainon (CLASS_IVARS (class), nf);
  gcc_assert (record);
  /* Must also add this ivar to the end of list of fields for this class. */
  field = TYPE_FIELDS (record);
  if (field && field != CLASS_IVARS (class))
    /* class has a hidden field, attach ivar list after the hiddent field. */
    TREE_CHAIN (field) = CLASS_IVARS (class);
  else
    TYPE_FIELDS (record) = CLASS_IVARS (class);
  /* Ugh, must recalculate struct layout since an ivar was added. */
  TYPE_SIZE (record) = 0;
  layout_type (record);
  /* APPLE LOCAL begin radar 5435299 */
  if (flag_new_property_ivar_synthesis)
    objc_ivar_chain = CLASS_RAW_IVARS (class);
  /* APPLE LOCAL end radar 5435299 */
}

/* This routine looks up PROPERTY's 'ivar' in the CLASS. If one not found, it inserts one
   and may issue error for 32-bit abi (fragile 'ivar') in this case. */
static void
objc_lookup_property_ivar (tree class, tree property)
{
  /* Check for an existing or synthesized 'ivar' and diagnose as needed. */
  tree ivar_name = PROPERTY_IVAR_NAME (property);
  if (!nested_ivar_lookup (class, PROPERTY_IVAR_NAME (property)))
    {
      if (flag_objc_abi <= 1)
	error ("synthesized property %qs must either be named the same as a compatible ivar or must explicitly name an ivar",
	       IDENTIFIER_POINTER (PROPERTY_NAME (property)));
        objc_add_internal_ivar (class, property, IDENTIFIER_POINTER (ivar_name));
    }
}
/* APPLE LOCAL end C* language */

/* APPLE LOCAL begin radar 4965989 */
/* This routine merges all methods declared or synthesized in anonymous class
   into PRIMARY primary class. CHAIN is the list of methods in anonymous category.
   MTYPE is '+' for class methods and '-' for instance methods.
*/          
static void   
objc_merge_methods (tree primary, tree chain ,int mtype)
{     
  while (chain)
    {   
      tree method = chain; 
      chain = TREE_CHAIN (chain);
      objc_add_method (primary, method, mtype == '+', false);
      if (mtype == '-' && METHOD_PROPERTY_CONTEXT (method))
        {
          tree x;
          for (x = CLASS_PROPERTY_DECL (primary); x; x = TREE_CHAIN (x)) 
            {    
              if (PROPERTY_NAME (x) == PROPERTY_NAME (METHOD_PROPERTY_CONTEXT (method)))
                {
                  METHOD_PROPERTY_CONTEXT (method) = x;
                  break;
                }
            }
        }
    } 
}         
/* APPLE LOCAL end radar 4965989 */

/* APPLE LOCAL begin radar 4968128 */
static tree
strip_end_colon (tree ident)
{
    size_t pos = IDENTIFIER_LENGTH (ident) - 1;
    gcc_assert (IDENTIFIER_LENGTH (ident) > 0 && IDENTIFIER_POINTER (ident)[pos] == ':');
    return get_identifier_with_length (IDENTIFIER_POINTER (ident), pos);
}
/* APPLE LOCAL end radar 4968128 */

/* APPLE LOCAL begin radar 6017984 */
/* This routine merges all methods declared in the protocol-list
   into the current class. */
static void
objc_merge_protocol_methods (tree class, tree rproto_list)
{
  tree rproto;
  for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
    {
      tree p = TREE_VALUE (rproto);
      if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
        {
	  /* APPLE LOCAL begin radar 6370136 */
	  /* Call objc_merge_methods on copied list of methods, as insertion
	     of methods in class's method list has side-effect of modifying
	     protocol's method list which must not change. */
	  objc_merge_methods (class, copy_list (PROTOCOL_CLS_METHODS (p)), '+');
	  objc_merge_methods (class, copy_list (PROTOCOL_NST_METHODS (p)), '-');
	  /* APPLE LOCAL end radar 6370136 */
          /* Search in nested protocols also. */
          objc_merge_proto_properties_in_class (class, PROTOCOL_LIST (p));
        }
    }
}
/* APPLE LOCAL end radar 6017984 */

/* This is called once we see the "@end" in an interface/implementation.  */

static void
finish_class (tree class)
{
  if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
    {
      /* All code generation is done in finish_objc.  */

      /* APPLE LOCAL begin C* property (Radar 4436866) */
      /* Generate what needed for property; setters, getters, etc. */
      objc_gen_property_data (implementation_template, implementation_template);
      /* APPLE LOCAL end C* property (Radar 4436866) */
      if (implementation_template != objc_implementation_context)
	{
	  /* Ensure that all method listed in the interface contain bodies.  */
	  check_methods (CLASS_CLS_METHODS (implementation_template),
			 /* APPLE LOCAL radar 4568791, 4359757 */
			 '+', NULL_TREE);
	  check_methods (CLASS_NST_METHODS (implementation_template),
			 /* APPLE LOCAL radar 4568791, 4359757 */
			 '-', NULL_TREE);

	  if (CLASS_PROTOCOL_LIST (implementation_template))
	    check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
			     "class",
			     /* APPLE LOCAL begin radar 4568791 */
			     IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)),
			     implementation_template);
			     /* APPLE LOCAL end radar 4568791 */
	}
    }

  else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
    {
      tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));

      if (category)
	{
      	  /* APPLE LOCAL begin C* property (Radar 4436866) */
          /* Generate what needed for property; setters, getters, etc. */
          objc_gen_property_data (implementation_template, category);
	  /* APPLE LOCAL end C* property (Radar 4436866) */
	  /* Ensure all method listed in the interface contain bodies.  */
    /* APPLE LOCAL begin radar 4568791 */
	  check_methods (CLASS_CLS_METHODS (category),
		         /* APPLE LOCAL radar 4359757 */
			 '+', NULL_TREE);
	  check_methods (CLASS_NST_METHODS (category),
			 /* APPLE LOCAL radar 4359757 */
			 '-', NULL_TREE);

	  if (CLASS_PROTOCOL_LIST (category))
	    check_protocols (CLASS_PROTOCOL_LIST (category),
			     "category",
			     IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)),
			     implementation_template);
        }
    }
  /* APPLE LOCAL end radar 4568791 */
  /* APPLE LOCAL radar 4695109 */
  /* PROTOCOL_IMPLEMENTATION_TYPE removed */
  /* APPLE LOCAL begin objc new property */
  else
    {
      tree x;
      /* APPLE LOCAL radar 5962694 */
      if (TREE_CODE (class) == CLASS_INTERFACE_TYPE || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
	{
	  objc_compare_properties_with_super (class);
	  objc_merge_proto_properties_in_class (class, CLASS_PROTOCOL_LIST (class));
	}
      /* Process properties of the class. */
      for (x = CLASS_PROPERTY_DECL (class); x; x = TREE_CHAIN (x))
	{
	  tree getter_decl, setter_decl;
	  tree type = TREE_TYPE (x);
	  tree prop_name = PROPERTY_NAME (x);
	  if (PROPERTY_GETTER_NAME (x) == NULL_TREE)
	    {
	      /* No 'getter=name' attribute specified. Find the default getter and
		 if one not found, add one. */
	      getter_decl = lookup_method (CLASS_NST_METHODS (class), prop_name);
	      if (getter_decl)
	    	{
	          if (comptypes (type, TREE_VALUE (TREE_TYPE (getter_decl))) != 1)
		    /* APPLE LOCAL radar 4815054 */
	            error ("type of accessor does not match the type of property %qs",
		           IDENTIFIER_POINTER (prop_name));
		  if (METHOD_SEL_ARGS (getter_decl) != NULL_TREE)
		    error ("accessor %<%c%s%> cannot have any argument", 
		           '-', IDENTIFIER_POINTER (prop_name));	
	          METHOD_PROPERTY_CONTEXT (getter_decl) = x;
	          TREE_DEPRECATED (getter_decl) = TREE_DEPRECATED (x);
	    	}
	      /* APPLE LOCAL radar begin 4653422 */
	      else if (!OPTIONAL_PROPERTY (x) || TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE)
	        {
	          tree rettype = build_tree_list (NULL_TREE, type);
	          getter_decl = build_method_decl (INSTANCE_METHOD_DECL,
	     				           rettype, prop_name, NULL_TREE,
						   false);
		  /* APPLE LOCAL begin radar 5839812 - synthesized methods  */
		  DECL_SOURCE_LOCATION (getter_decl) = 
		                                      DECL_SOURCE_LOCATION (x);
		  /* APPLE LOCAL end radar 5839812 - synthesized methods  */
	  	  objc_add_method (class, getter_decl, false, OPTIONAL_PROPERTY (x));
	          METHOD_PROPERTY_CONTEXT (getter_decl) = x;
	          TREE_DEPRECATED (getter_decl) = TREE_DEPRECATED (x);
	        }
	      /* APPLE LOCAL radar end 4653422 */
	    }
	  else
	    {
	      /* getter = getter_name */
	      getter_decl = lookup_method (CLASS_NST_METHODS (class), PROPERTY_GETTER_NAME (x));
	      if (!getter_decl)
		{
		  /* getter in 'getter' declaration has no declaration in this class. Provide
		     one here. */
	          tree rettype = build_tree_list (NULL_TREE, type);
	          getter_decl = build_method_decl (INSTANCE_METHOD_DECL,
	     				           rettype, PROPERTY_GETTER_NAME (x), 
						   NULL_TREE, false);
		  /* APPLE LOCAL begin radar 5839812 - synthesized methods  */
		  DECL_SOURCE_LOCATION (getter_decl) = 
		                                      DECL_SOURCE_LOCATION (x);
		  /* APPLE LOCAL end radar 5839812 - synthesized methods  */
	  	  objc_add_method (class, getter_decl, false, false);
		  /* APPLE LOCAL radar 5390587 */
	          METHOD_PROPERTY_CONTEXT (getter_decl) = x;
		}
	      else
		{
		  if (comptypes (type, TREE_VALUE (TREE_TYPE (getter_decl))) != 1)
		    /* APPLE LOCAL radar 4815054 */
		    error ("type of existing accessor %<%c%s%> does not match the type of property %qs",
			   '-', IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (x)), IDENTIFIER_POINTER (prop_name));
		  if (METHOD_SEL_ARGS (getter_decl) != NULL_TREE)
		    error ("existing accessor %<%c%s%> cannot have any argument",
			   '-', IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (x)));	
		}
	     /* APPLE LOCAL radar 4712415 */
	     TREE_DEPRECATED (getter_decl) = TREE_DEPRECATED (x);
	    }
	  if (PROPERTY_SETTER_NAME (x) == NULL_TREE
	      && PROPERTY_READONLY (x) == boolean_false_node)
	    {
	      /* No setter is specified and it is not a 'readonly' property. Generate an instance
		 or find an existing one. */
	      tree setter_name = get_identifier (objc_build_property_setter_name (
				   prop_name, true)); 
	      setter_decl = lookup_method (CLASS_NST_METHODS (class), setter_name);
	      if (setter_decl)
		{
		  /* An eixsting setter must take a single argument of type matching the property's
		     type and must return 'void'. */
		  if (TREE_VALUE (TREE_TYPE (setter_decl)) != void_type_node)
		    error ("setter %<%c%s%>  type must be 'void'",
			   '-', IDENTIFIER_POINTER (prop_name));
		  if (!METHOD_SEL_ARGS (setter_decl))
		    error ("setter %<%c%s%> has no argument", '-', IDENTIFIER_POINTER (prop_name));
		  else
		    {
		      tree akey = METHOD_SEL_ARGS (setter_decl);
		      tree arg_type = TREE_VALUE (TREE_TYPE (akey));
		      if (comptypes (type, arg_type) != 1)
			error ("setter %<%c%s%> argument type does not match property type",
				'-', IDENTIFIER_POINTER (prop_name));
		      akey = TREE_CHAIN (akey);
		      if (akey)
			error ("setter %<%c%s%> has too many arguments",
				'-', IDENTIFIER_POINTER (prop_name));
		    }
	    	  /* APPLE LOCAL radar 4712415 */
	    	  TREE_DEPRECATED (setter_decl) = TREE_DEPRECATED (x);
		}
	      /* APPLE LOCAL radar begin 4653422 */
	      else if (!OPTIONAL_PROPERTY (x) 
		       || TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE)
		objc_add_property_setter_method (class, x);
	      /* APPLE LOCAL radar end 4653422 */
	    }
	  else if (PROPERTY_SETTER_NAME (x))
	    {
	      if (PROPERTY_READONLY (x) == boolean_true_node)
		error ("setter cannot be specified for a 'readonly' property %qs"
		       , IDENTIFIER_POINTER (PROPERTY_NAME (x)));
	      else
		{
		  /* User setter is specified in the attribute. See if it is of correct form. */
		  setter_decl = lookup_method (CLASS_NST_METHODS (class), PROPERTY_SETTER_NAME (x));
		  if (!setter_decl)
		    {
		      tree prop;
		      /* setter declared in 'setter' attribute has no declaration in current
			 class. Provide this declaration internally. */
		      tree arg_type = build_tree_list (NULL_TREE, type);
		      tree arg_name = get_identifier ("_value");
		      /* APPLE LOCAL radar 4968128 */
		      tree selector = objc_build_keyword_decl (strip_end_colon (PROPERTY_SETTER_NAME (x)),
							       /* APPLE LOCAL radar 4157812 */
							       arg_type, arg_name, NULL_TREE);
		      setter_decl = build_method_decl (INSTANCE_METHOD_DECL,
                                      build_tree_list (NULL_TREE, void_type_node), selector,
                                      build_tree_list (NULL_TREE, NULL_TREE), false);
		      /* APPLE LOCAL begin radar 5839812 - synthesized methods  */
		      DECL_SOURCE_LOCATION (setter_decl) = 
		                                      DECL_SOURCE_LOCATION (x);
		      /* APPLE LOCAL end radar 5839812 - synthesized methods  */
		      objc_add_method (class, setter_decl, false, false);
		      METHOD_PROPERTY_CONTEXT (setter_decl) = x;
		      /* Issue error if setter name matches a property name. */
		      for (prop = CLASS_PROPERTY_DECL (class); prop; prop = TREE_CHAIN (prop))
			{
			  /* APPLE LOCAL begin radar 5338634 */
			  const char *property_name = IDENTIFIER_POINTER (PROPERTY_NAME (prop));
			  const char *setter_name = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x));
			  size_t len = strlen (setter_name) - 1;
			  if (strlen (property_name) == len  && !strncmp (setter_name, property_name, len))
			    {
			      error ("setter name %qs matches property %qs name", 
				     setter_name, property_name);
			      break;
			    }
			  /* APPLE LOCAL end radar 5338634 */
			}
		    }
		  else
		    {
		      if (TREE_VALUE (TREE_TYPE (setter_decl)) != void_type_node)
			error ("user setter's type must be 'void' for property %qs",
			       IDENTIFIER_POINTER (PROPERTY_NAME (x)));
		      if (!METHOD_SEL_ARGS (setter_decl))
		    	error ("setter %<%c%s%> has no argument",
				'-', IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x)));
		      else
		    	{
		          tree akey = METHOD_SEL_ARGS (setter_decl);
			  if (akey)
			  {
		            tree arg_type = TREE_VALUE (TREE_TYPE (akey));
		            if (comptypes (type, arg_type) != 1)
			      /* APPLE LOCAL radar 4815054 */
			      error ("argument type of setter %<%c%s%> does not match the type of property %qs",
				     '-', IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x)), 
				     IDENTIFIER_POINTER (PROPERTY_NAME (x)));
		            akey = TREE_CHAIN (akey);
			    if (akey)
			      error ("specified setter %<%c%s%> has too many arguments",
				     '-', IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x)));
			  }
			  else
			    error ("specified setter %<%c%s%> has no argument",
				     '-', IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x)));
		    	}
		    }
	    	    /* APPLE LOCAL radar 4712415 */
	    	    TREE_DEPRECATED (setter_decl) = TREE_DEPRECATED (x);
		}	
	    }
	  if (PROPERTY_RETAIN (x) == boolean_true_node)
	    {
	      if (!objc_type_valid_for_messaging (type))
	        error ("property %qs with 'retain' attribute must be of object type",
		       IDENTIFIER_POINTER (PROPERTY_NAME (x)));
	      if (objc_is_gcable_type (type) == -1)
		error ("property %qs with 'retain' attribute cannot be used with __weak storage specifier",
		       IDENTIFIER_POINTER (PROPERTY_NAME (x)));
	    }
	  if (PROPERTY_COPY (x) == boolean_true_node)
	    {
	      if (!objc_type_valid_for_messaging (type))
	        error ("property %qs with 'copy' attribute must be of object type",
		       IDENTIFIER_POINTER (PROPERTY_NAME (x)));
	      if (objc_is_gcable_type (type) == -1)
		error ("property %qs with 'copy' attribute cannot be used with __weak storage specifier",
		       IDENTIFIER_POINTER (PROPERTY_NAME (x)));
	    }
	}
        /* APPLE LOCAL begin radar 4965989 */ 
        /* New anonymous category */
        if (ANONYMOUS_CATEGORY (class))
          {
            /* Merge all anonymous category's methods (including setter/getter) into its primary class. */
            tree primary = lookup_interface (CLASS_NAME (class));
            if (primary)
              {
                objc_merge_methods (primary, CLASS_NST_METHODS (class), '-');
                objc_merge_methods (primary, CLASS_CLS_METHODS (class), '+');
	        /* APPLE LOCAL begin radar 6017984 */
		/* Just as we are adding anonymous category's methods to the
		   primary class, must also add methods in anonymous category's protocols
		   to the class as well, */
		objc_merge_protocol_methods (primary, CLASS_PROTOCOL_LIST (class));
	        /* APPLE LOCAL end radar 6017984 */
              } 
          }
        /* APPLE LOCAL end radar 4965989 */
    }
  /* APPLE LOCAL end objc new property */
}

static tree
add_protocol (tree protocol)
{
  /* Put protocol on list in reverse order.  */
  TREE_CHAIN (protocol) = protocol_chain;
  protocol_chain = protocol;
  return protocol_chain;
}

static tree
lookup_protocol (tree ident)
{
  tree chain;

  for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
    if (ident == PROTOCOL_NAME (chain))
      return chain;

  return NULL_TREE;
}

/* This function forward declares the protocols named by NAMES.  If
   they are already declared or defined, the function has no effect.  */

void
/* APPLE LOCAL radar 4947311 - protocol attributes */
objc_declare_protocols (tree names, tree prefix_attrs)
{
  tree list;

#ifdef OBJCPLUS
  if (current_namespace != global_namespace) {
    error ("Objective-C declarations may only appear in global scope");
  }
#endif /* OBJCPLUS */

  for (list = names; list; list = TREE_CHAIN (list))
    {
      tree name = TREE_VALUE (list);

      if (lookup_protocol (name) == NULL_TREE)
	{
	  tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);

	  TYPE_LANG_SLOT_1 (protocol)
	    = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
	  PROTOCOL_NAME (protocol) = name;
	  PROTOCOL_LIST (protocol) = NULL_TREE;
	  add_protocol (protocol);
	  PROTOCOL_DEFINED (protocol) = 0;
	  PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
	  /* APPLE LOCAL ObjC abi v2 */
	  PROTOCOL_V2_FORWARD_DECL (protocol) = NULL_TREE;
	  /* APPLE LOCAL radar 4947311 - protocol attributes */
	  PROTOCOL_ATTRIBUTES (protocol) = prefix_attrs;
	}
    }
}

static tree
/* APPLE LOCAL radar 4947311 - protocol attributes */
start_protocol (tree name, tree list, tree prefix_attrs)
{
  tree protocol;

#ifdef OBJCPLUS
  if (current_namespace != global_namespace) {
    error ("Objective-C declarations may only appear in global scope");
  }
#endif /* OBJCPLUS */

  protocol = lookup_protocol (name);

  if (!protocol)
    {
      /* APPLE LOCAL radar 4947311 - protocol attributes */
      protocol = make_node (PROTOCOL_INTERFACE_TYPE);
      TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);

      PROTOCOL_NAME (protocol) = name;
      /* APPLE LOCAL radar 4398221 */
      PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list, false);
      add_protocol (protocol);
      PROTOCOL_DEFINED (protocol) = 1;
      PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
      /* APPLE LOCAL ObjC abi v2 */
      PROTOCOL_V2_FORWARD_DECL (protocol) = NULL_TREE;
      /* APPLE LOCAL radar 4947311 - protocol attributes */
      PROTOCOL_ATTRIBUTES (protocol) = prefix_attrs;
      check_protocol_recursively (protocol, list);
    }
  else if (! PROTOCOL_DEFINED (protocol))
    {
      PROTOCOL_DEFINED (protocol) = 1;
      /* APPLE LOCAL begin radar 4947311 - protocol attributes */
      PROTOCOL_ATTRIBUTES (protocol) = merge_attributes 
					 (PROTOCOL_ATTRIBUTES (protocol), 
					  prefix_attrs);
      /* APPLE LOCAL end radar 4947311 - protocol attributes */
      /* APPLE LOCAL radar 4398221 */
      PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list, false);

      check_protocol_recursively (protocol, list);
    }
  else
    {
      warning (0, "duplicate declaration for protocol %qs",
	       IDENTIFIER_POINTER (name));
    }
  return protocol;
}


/* "Encode" a data type into a string, which grows in util_obstack.
   ??? What is the FORMAT?  Someone please document this!  */

static void
encode_type_qualifiers (tree declspecs)
{
  tree spec;

  for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
    {
      if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
	obstack_1grow (&util_obstack, 'n');
      else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
	obstack_1grow (&util_obstack, 'N');
      else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
	obstack_1grow (&util_obstack, 'o');
      else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
	obstack_1grow (&util_obstack, 'O');
      else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
        obstack_1grow (&util_obstack, 'R');
      else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
	obstack_1grow (&util_obstack, 'V');
    }
}

/* APPLE LOCAL begin 4136935 */
/* Determine if a pointee is marked read-only.  */

static bool
pointee_is_readonly (tree pointee)
{
  while (POINTER_TYPE_P (pointee))
    pointee = TREE_TYPE (pointee);

  return TYPE_READONLY (pointee);
}

/* APPLE LOCAL end 4136935 */
/* APPLE LOCAL begin radar 4577849 */
static void encode_protocol_list (tree record, bool quote)
{
  tree p;
  bool firsttime = true;
  bool close_quote = false;
  for (p = TYPE_OBJC_PROTOCOL_LIST (record); p; p = TREE_CHAIN (p))
    {
      tree proto = TREE_VALUE (p);
      if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
	  && PROTOCOL_NAME (proto))
	{
	  const char *name = IDENTIFIER_POINTER (PROTOCOL_NAME (proto));
	  if (quote && firsttime)
	   {
	     obstack_1grow (&util_obstack, '"');
	     firsttime = false;
	     close_quote = true;
	   }
	  obstack_1grow (&util_obstack, '<');
	  obstack_grow (&util_obstack, name, strlen (name));
	  obstack_1grow (&util_obstack, '>');
	}
    }
  if (quote && close_quote)
    obstack_1grow (&util_obstack, '"');
}
/* APPLE LOCAL end radar 4577849 */

/* Encode a pointer type.  */

static void
encode_pointer (tree type, int curtype, int format)
{
  tree pointer_to = TREE_TYPE (type);

  /* APPLE LOCAL begin 4136935 */
  /* For historical/compatibility reasons, the read-only qualifier of the
     pointee gets emitted _before_ the '^'.  The read-only qualifier of
     the pointer itself gets ignored, _unless_ we are looking at a typedef!  
     Also, do not emit the 'r' for anything but the outermost type!  */
  if (!generating_instance_variables
      && (obstack_object_size (&util_obstack) - curtype <= 1)
      && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
	  ? TYPE_READONLY (type)
	  : pointee_is_readonly (pointer_to)))
    obstack_1grow (&util_obstack, 'r');

  /* APPLE LOCAL end 4136935 */
  if (TREE_CODE (pointer_to) == RECORD_TYPE)
    {
      /* APPLE LOCAL begin radar 5002848 */
      if (generating_property_type_encoding &&
          TYPE_NAME (pointer_to)
          && TREE_CODE (TYPE_NAME (pointer_to)) == TYPE_DECL
          && DECL_ORIGINAL_TYPE (TYPE_NAME (pointer_to)))
      pointer_to = DECL_ORIGINAL_TYPE (TYPE_NAME (pointer_to));
      /* APPLE LOCAL end radar 5002848 */

      if (OBJC_TYPE_NAME (pointer_to)
	  && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
	{
	  const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));

	  if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
	    {
	      obstack_1grow (&util_obstack, '@');
	      /* APPLE LOCAL begin radar 4577849 */
	      if (generating_instance_variables 
		  && TYPE_HAS_OBJC_INFO (pointer_to))
	        encode_protocol_list (pointer_to, true);
	      /* APPLE LOCAL end radar 4577849 */
	      return;
	    }
	  else if (TYPE_HAS_OBJC_INFO (pointer_to)
		   && TYPE_OBJC_INTERFACE (pointer_to))
	    {
              if (generating_instance_variables)
	        {
	          obstack_1grow (&util_obstack, '@');
	          obstack_1grow (&util_obstack, '"');
	          obstack_grow (&util_obstack, name, strlen (name));
		  /* APPLE LOCAL radar 4577849 */
		  encode_protocol_list (pointer_to, false);
	          obstack_1grow (&util_obstack, '"');
	          return;
		}
              else
	        {
	          obstack_1grow (&util_obstack, '@');
	          return;
		}
	    }
	  else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
	    {
	      obstack_1grow (&util_obstack, '#');
	      return;
	    }
	  else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
	    {
	      obstack_1grow (&util_obstack, ':');
	      return;
	    }
	}
    }
  else if (TREE_CODE (pointer_to) == INTEGER_TYPE
	   && TYPE_MODE (pointer_to) == QImode)
    {
      tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
	          ? OBJC_TYPE_NAME (pointer_to)
	          : DECL_NAME (OBJC_TYPE_NAME (pointer_to));

      if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
	{
	  /* APPLE LOCAL 4136935 */
	  /* The "r" is now generated above.  */

	  obstack_1grow (&util_obstack, '*');
	  return;
	}
    }

  /* We have a type that does not get special treatment.  */

  /* NeXT extension */
  /* APPLE LOCAL radar 5849129 */
  obstack_1grow (&util_obstack, TREE_CODE (type) == BLOCK_POINTER_TYPE ? '@' : '^');
  encode_type (pointer_to, curtype, format);
}

static void
encode_array (tree type, int curtype, int format)
{
  tree an_int_cst = TYPE_SIZE (type);
  tree array_of = TREE_TYPE (type);
  char buffer[40];

  /* An incomplete array is treated like a pointer.  */
  if (an_int_cst == NULL)
    {
      encode_pointer (type, curtype, format);
      return;
    }

  if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
   sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
  else
    sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
	     TREE_INT_CST_LOW (an_int_cst)
	      / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));

  obstack_grow (&util_obstack, buffer, strlen (buffer));
  encode_type (array_of, curtype, format);
  obstack_1grow (&util_obstack, ']');
  return;
}

static void
encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
{
  tree field = TYPE_FIELDS (type);

  for (; field; field = TREE_CHAIN (field))
    {
#ifdef OBJCPLUS
      /* C++ static members, and things that are not field at all,
	 should not appear in the encoding.  */
      if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
	continue;
#endif

      /* Recursively encode fields of embedded base classes.  */
      if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
	  && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
	{
	  encode_aggregate_fields (TREE_TYPE (field),
				   pointed_to, curtype, format);
	  continue;
	}

      if (generating_instance_variables && !pointed_to)
	{
	  tree fname = DECL_NAME (field);

	  obstack_1grow (&util_obstack, '"');

	  if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
	    obstack_grow (&util_obstack,
			  IDENTIFIER_POINTER (fname),
			  strlen (IDENTIFIER_POINTER (fname)));

	  obstack_1grow (&util_obstack, '"');
        }

      encode_field_decl (field, curtype, format);
    }
}

static void
encode_aggregate_within (tree type, int curtype, int format, int left,
			 int right)
{
  tree name;
  /* NB: aggregates that are pointed to have slightly different encoding
     rules in that you never encode the names of instance variables.  */
  /* APPLE LOCAL begin 4136935 */
  int ob_size = obstack_object_size (&util_obstack);
  int pointed_to = (ob_size > 0
		    ? *(obstack_next_free (&util_obstack) - 1) == '^'
		    : 0);
  int inline_contents
    = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
       && (!pointed_to
	   || ob_size - curtype == 1
	   || (ob_size - curtype == 2
	       && *(obstack_next_free (&util_obstack) - 2) == 'r')));
  /* APPLE LOCAL end 4136935 */

  /* Traverse struct aliases; it is important to get the
     original struct and its tag name (if any).  */
  type = TYPE_MAIN_VARIANT (type);
  name = OBJC_TYPE_NAME (type);
  /* Open parenth/bracket.  */
  obstack_1grow (&util_obstack, left);

  /* Encode the struct/union tag name, or '?' if a tag was
     not provided.  Typedef aliases do not qualify.  */
  if (name && TREE_CODE (name) == IDENTIFIER_NODE
#ifdef OBJCPLUS
      /* Did this struct have a tag?  */
      && !TYPE_WAS_ANONYMOUS (type)
#endif
      )
    obstack_grow (&util_obstack,
		  IDENTIFIER_POINTER (name),
		  strlen (IDENTIFIER_POINTER (name)));
  else
    obstack_1grow (&util_obstack, '?');

  /* Encode the types (and possibly names) of the inner fields,
     if required.  */
  if (inline_contents)
    {
      obstack_1grow (&util_obstack, '=');
      encode_aggregate_fields (type, pointed_to, curtype, format);
    }
  /* Close parenth/bracket.  */
  obstack_1grow (&util_obstack, right);
}

static void
encode_aggregate (tree type, int curtype, int format)
{
  enum tree_code code = TREE_CODE (type);

  switch (code)
    {
    case RECORD_TYPE:
      {
	encode_aggregate_within (type, curtype, format, '{', '}');
	break;
      }
    case UNION_TYPE:
      {
	encode_aggregate_within (type, curtype, format, '(', ')');
	break;
      }

    case ENUMERAL_TYPE:
      obstack_1grow (&util_obstack, 'i');
      break;

    default:
      break;
    }
}

/* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
   field type.  */

static void
encode_next_bitfield (int width)
{
  char buffer[40];
  sprintf (buffer, "b%d", width);
  obstack_grow (&util_obstack, buffer, strlen (buffer));
}

/* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS.  */
static void
encode_type (tree type, int curtype, int format)
{
  enum tree_code code = TREE_CODE (type);
  char c;
  /* APPLE LOCAL begin 4136935 */
  tree int_type;

  /* Ignore type qualifiers when encoding a type; see encode_pointer()
     for an exception to this rule.  */
  /* APPLE LOCAL end 4136935 */
  if (code == INTEGER_TYPE)
    {
      switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
	{
	case 8:  c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
	case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
	/* APPLE LOCAL begin 4136935 */
	case 32:
	  /* Another legacy kludge: 32-bit longs are encoded as 'l' or 'L',
	     but not always.  For typedefs, we need to use 'i' or 'I' instead
	     if encoding a struct field, or a pointer!  */
	  int_type =  ((!generating_instance_variables
			&& (obstack_object_size (&util_obstack)
			    == (unsigned) curtype))
		       ? TYPE_MAIN_VARIANT (type)
		       : type);

	  if (int_type == long_unsigned_type_node
	      || int_type == long_integer_type_node)
	  /* APPLE LOCAL end 4136935 */
	         c = TYPE_UNSIGNED (type) ? 'L' : 'l';
	  else
	         c = TYPE_UNSIGNED (type) ? 'I' : 'i';
	  break;
	case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
        /* APPLE LOCAL radar 5996271 */
	case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
	default: abort ();
	}
      obstack_1grow (&util_obstack, c);
    }

  else if (code == REAL_TYPE)
    {
      /* Floating point types.  */
      switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
	{
	case 32:  c = 'f'; break;
        /* APPLE LOCAL begin radar 4900615 */
	case 64:  c = 'd'; break;
	case 96:
	case 128: c = 'D'; break;
        /* APPLE LOCAL end radar 4900615 */
	default: abort ();
	}
      obstack_1grow (&util_obstack, c);
    }

  else if (code == VOID_TYPE)
    obstack_1grow (&util_obstack, 'v');

  else if (code == BOOLEAN_TYPE)
    obstack_1grow (&util_obstack, 'B');

  else if (code == ARRAY_TYPE)
    encode_array (type, curtype, format);

/* APPLE LOCAL begin radar 4476365 */
#ifdef OBJCPLUS
  else if (code == REFERENCE_TYPE)
    encode_pointer (type, curtype, format);
#endif
/* APPLE LOCAL end radar 4476365 */

  /* APPLE LOCAL radar 5849129 */
  else if (code == POINTER_TYPE || code == BLOCK_POINTER_TYPE)
    encode_pointer (type, curtype, format);

  else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
    encode_aggregate (type, curtype, format);

  else if (code == FUNCTION_TYPE) /* '?' */
    obstack_1grow (&util_obstack, '?');

  /* APPLE LOCAL begin 4136935 */
  /* Super-kludge.  Some ObjC qualifier and type combinations need to be
     rearranged for compatibility with gcc-3.3.  */
  if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
    {
      char *enc = obstack_base (&util_obstack) + curtype;

      /* Rewrite "in const" from "nr" to "rn".  */
      if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
        strncpy (enc - 1, "rn", 2);
      /* APPLE LOCAL begin radar 4301047 */
      /* code removed */
      /* APPLE LOCAL end radar 4301047 */
    }
  /* APPLE LOCAL end 4136935 */

  else if (code == COMPLEX_TYPE)
    {
      obstack_1grow (&util_obstack, 'j');
      encode_type (TREE_TYPE (type), curtype, format);
    }
}

static void
encode_gnu_bitfield (int position, tree type, int size)
{
  enum tree_code code = TREE_CODE (type);
  char buffer[40];
  char charType = '?';

  if (code == INTEGER_TYPE)
    {
      if (integer_zerop (TYPE_MIN_VALUE (type)))
	{
	  /* Unsigned integer types.  */

	  if (TYPE_MODE (type) == QImode)
	    charType = 'C';
	  else if (TYPE_MODE (type) == HImode)
	    charType = 'S';
	  else if (TYPE_MODE (type) == SImode)
	    {
	      if (type == long_unsigned_type_node)
		charType = 'L';
	      else
		charType = 'I';
	    }
	  else if (TYPE_MODE (type) == DImode)
	    charType = 'Q';
	}

      else
	/* Signed integer types.  */
	{
	  if (TYPE_MODE (type) == QImode)
	    charType = 'c';
	  else if (TYPE_MODE (type) == HImode)
	    charType = 's';
	  else if (TYPE_MODE (type) == SImode)
	    {
	      if (type == long_integer_type_node)
		charType = 'l';
	      else
		charType = 'i';
	    }

	  else if (TYPE_MODE (type) == DImode)
	    charType = 'q';
	}
    }
  else if (code == ENUMERAL_TYPE)
    charType = 'i';
  else
    abort ();

  sprintf (buffer, "b%d%c%d", position, charType, size);
  obstack_grow (&util_obstack, buffer, strlen (buffer));
}

static void
encode_field_decl (tree field_decl, int curtype, int format)
{
  tree type;

#ifdef OBJCPLUS
  /* C++ static members, and things that are not fields at all,
     should not appear in the encoding.  */
  if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
    return;
#endif

  type = TREE_TYPE (field_decl);

  /* Generate the bitfield typing information, if needed.  Note the difference
     between GNU and NeXT runtimes.  */
  if (DECL_BIT_FIELD_TYPE (field_decl))
    {
      int size = tree_low_cst (DECL_SIZE (field_decl), 1);

      if (flag_next_runtime)
	encode_next_bitfield (size);
      else
	encode_gnu_bitfield (int_bit_position (field_decl),
				  DECL_BIT_FIELD_TYPE (field_decl), size);
    }
  else
    encode_type (TREE_TYPE (field_decl), curtype, format);
}

/* APPLE LOCAL begin 4209854 */
/* Decay array and function parameters into pointers.  */

static tree
objc_decay_parm_type (tree type)
{
  if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == FUNCTION_TYPE)
    type = build_pointer_type (TREE_CODE (type) == ARRAY_TYPE
			       ? TREE_TYPE (type)
			       : type);

  return type;
}

/* APPLE LOCAL end 4209854 */
static GTY(()) tree objc_parmlist = NULL_TREE;

/* Append PARM to a list of formal parameters of a method, making a necessary
   array-to-pointer adjustment along the way.  */

static void
objc_push_parm (tree parm)
{
  /* APPLE LOCAL begin 4209854 */
  /* Decay arrays and functions into pointers.  */
  tree type = objc_decay_parm_type (TREE_TYPE (parm));

  /* If the parameter type has been decayed, a new PARM_DECL needs to be
     built as well.  */
  if (type != TREE_TYPE (parm))
    {
      TREE_TYPE (parm) = type;
      relayout_decl (parm);
    }
  /* APPLE LOCAL end 4209854 */

  DECL_ARG_TYPE (parm)
    = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));

  /* Record constancy and volatility.  */
  c_apply_type_quals_to_decl
  ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
   | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
   | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);

  objc_parmlist = chainon (objc_parmlist, parm);
}

/* Retrieve the formal parameter list constructed via preceding calls to
   objc_push_parm().  */

#ifdef OBJCPLUS
static tree
objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
#else
static struct c_arg_info *
objc_get_parm_info (int have_ellipsis)
#endif
{
#ifdef OBJCPLUS
  tree parm_info = objc_parmlist;
  objc_parmlist = NULL_TREE;

  return parm_info;
#else
  tree parm_info = objc_parmlist;
  struct c_arg_info *arg_info;
  /* The C front-end requires an elaborate song and dance at
     this point.  */
  push_scope ();
  declare_parm_level ();
  while (parm_info)
    {
      tree next = TREE_CHAIN (parm_info);

      TREE_CHAIN (parm_info) = NULL_TREE;
      parm_info = pushdecl (parm_info);
      finish_decl (parm_info, NULL_TREE, NULL_TREE);
      parm_info = next;
    }
  arg_info = get_parm_info (have_ellipsis);
  pop_scope ();
  objc_parmlist = NULL_TREE;
  return arg_info;
#endif
}

/* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
   method definitions.  In the case of instance methods, we can be more
   specific as to the type of 'self'.  */

static void
synth_self_and_ucmd_args (void)
{
  tree self_type;

  if (objc_method_context
      && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
    self_type = objc_instance_type;
  else
    /* Really a `struct objc_class *'. However, we allow people to
       assign to self, which changes its type midstream.  */
    self_type = objc_object_type;

  /* id self; */
  objc_push_parm (build_decl (PARM_DECL, self_id, self_type));

  /* SEL _cmd; */
  objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
}

/* Transform an Objective-C method definition into a static C function
   definition, synthesizing the first two arguments, "self" and "_cmd",
   in the process.  */

static void
start_method_def (tree method)
{
  tree parmlist;
#ifdef OBJCPLUS
  tree parm_info;
#else
  struct c_arg_info *parm_info;
#endif
  int have_ellipsis = 0;

  /* If we are defining a "dealloc" method in a non-root class, we
     will need to check if a [super dealloc] is missing, and warn if
     it is.  */
  if(CLASS_SUPER_NAME (objc_implementation_context)
     && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
    should_call_super_dealloc = 1;
  else
    should_call_super_dealloc = 0;
  /* APPLE LOCAL begin radar 4757423 */
  /* If we are defining a "finalize" method in a non-root class, we will need
     to check if a [super finalize] is missing, and warn if it is.  */
  should_call_super_finalize =
    CLASS_SUPER_NAME (objc_implementation_context)
    /* APPLE LOCAL radar 5424473 */
    && TREE_CODE (method) == INSTANCE_METHOD_DECL
    && !strcmp ("finalize", IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
  /* APPLE LOCAL end radar 4757423 */

  /* Required to implement _msgSuper.  */
  objc_method_context = method;
  UOBJC_SUPER_decl = NULL_TREE;

  /* Generate prototype declarations for arguments..."new-style".  */
  synth_self_and_ucmd_args ();

  /* Generate argument declarations if a keyword_decl.  */
  parmlist = METHOD_SEL_ARGS (method);
  while (parmlist)
    {
      tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;

      parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
      /* APPLE LOCAL radar 4157812 */
      decl_attributes (&parm, KEYWORD_ARG_ATTRIBUTE (parmlist), 0);
      objc_push_parm (parm);
      parmlist = TREE_CHAIN (parmlist);
    }

  if (METHOD_ADD_ARGS (method))
    {
      tree akey;

      for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
	   akey; akey = TREE_CHAIN (akey))
	{
	  objc_push_parm (TREE_VALUE (akey));
	}

      if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
	have_ellipsis = 1;
    }

  parm_info = objc_get_parm_info (have_ellipsis);

  really_start_method (objc_method_context, parm_info);
}

static void
warn_with_method (const char *message, int mtype, tree method)
{
  /* Add a readable method name to the warning.  */
  warning (0, "%J%s %<%c%s%>", method,
           message, mtype, gen_method_decl (method));
}

/* Return 1 if TYPE1 is equivalent to TYPE2
   for purposes of method overloading.  */

static int
objc_types_are_equivalent (tree type1, tree type2)
{
  if (type1 == type2)
    return 1;

  /* Strip away indirections.  */
  /* APPLE LOCAL begin radar 5795493 - blocks */
  while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE ||
          TREE_CODE (type1) == BLOCK_POINTER_TYPE)
  /* APPLE LOCAL end radar 5795493 - blocks */
	 && (TREE_CODE (type1) == TREE_CODE (type2)))
    type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
  if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
    return 0;

  type1 = (TYPE_HAS_OBJC_INFO (type1)
	   ? TYPE_OBJC_PROTOCOL_LIST (type1)
	   : NULL_TREE);
  type2 = (TYPE_HAS_OBJC_INFO (type2)
	   ? TYPE_OBJC_PROTOCOL_LIST (type2)
	   : NULL_TREE);

  if (list_length (type1) == list_length (type2))
    {
      for (; type2; type2 = TREE_CHAIN (type2))
	if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
	  return 0;
      return 1;
    }
  return 0;
}

/* Return 1 if TYPE1 has the same size and alignment as TYPE2.  */

static int
objc_types_share_size_and_alignment (tree type1, tree type2)
{
  return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
	  && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
}

/* Return 1 if PROTO1 is equivalent to PROTO2
   for purposes of method overloading.  Ordinarily, the type signatures
   should match up exactly, unless STRICT is zero, in which case we
   shall allow differences in which the size and alignment of a type
   // APPLE LOCAL radar 5370783
   is the same.  When STRICT is 1, we allow for valid object type comparisons. */

static int
comp_proto_with_proto (tree proto1, tree proto2, int strict)
{
  /* APPLE LOCAL C* property (Radar 4436866) */
  /* code removed */
  /* The following test is needed in case there are hashing
     collisions.  */
  if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
    return 0;
  /* APPLE LOCAL begin C* property (Radar 4436866) */
  return match_proto_with_proto (proto1, proto2, strict);
}

static int
match_proto_with_proto (tree proto1, tree proto2, int strict)
{
  tree type1, type2;
  /* APPLE LOCAL end C* property (Radar 4436866) */
  /* Compare return types.  */
  type1 = TREE_VALUE (TREE_TYPE (proto1));
  type2 = TREE_VALUE (TREE_TYPE (proto2));
  /* APPLE LOCAL begin radar 5370783 */
  if (!objc_types_are_equivalent (type1, type2)) {
    if (strict == 2)
      return 0;
    if (!objc_types_share_size_and_alignment (type1, type2))
      return 0;
    /* APPLE LOCAL radar 6231433 */
    if (strict == 1 && !objc_compare_types(type1, type2, -2, 0, NULL))
      return 0;
  }

  /* Compare argument types.  */
  /* APPLE LOCAL begin radar 6307941 */
  for (type1 = get_arg_type_list (METHOD_SEL_NAME (proto1), proto1, METHOD_REF, 0),
       type2 = get_arg_type_list (METHOD_SEL_NAME (proto2), proto2, METHOD_REF, 0);
  /* APPLE LOCAL end radar 6307941 */
       type1 && type2;
       type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
    {
      if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))) {
        if (strict == 2)
          return 0;
        if (!objc_types_share_size_and_alignment (TREE_VALUE (type1), TREE_VALUE (type2)))
          return 0;
        /* Note, order of type2 and type1 in argument call is intentional. */
	/* APPLE LOCAL radar 6231433 */
        if (strict == 1 && !objc_compare_types(TREE_VALUE (type2), TREE_VALUE (type1), -2, 0, NULL))
          return 0;
      }
    }
  /* APPLE LOCAL end radar 5370783 */

  return (!type1 && !type2);
}

/* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
   this occurs.  ObjC method dispatches are _not_ like C++ virtual
   member function dispatches, and we account for the difference here.  */
tree
#ifdef OBJCPLUS
objc_fold_obj_type_ref (tree ref, tree known_type)
#else
objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
			tree known_type ATTRIBUTE_UNUSED)
#endif
{
#ifdef OBJCPLUS
  tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));

  /* If the receiver does not have virtual member functions, there
     is nothing we can (or need to) do here.  */
  if (!v)
    return NULL_TREE;

  /* Let C++ handle C++ virtual functions.  */
  return cp_fold_obj_type_ref (ref, known_type);
#else
  /* For plain ObjC, we currently do not need to do anything.  */
  return NULL_TREE;
#endif
}

static void
objc_start_function (tree name, tree type, tree attrs,
/* APPLE LOCAL begin radar 5839812 - location for synthesized methods  */
#ifdef OBJCPLUS
		     tree params,
#else
		     struct c_arg_info *params,
#endif
		     tree method)
/* APPLE LOCAL end radar 5839812 - location for synthesized methods  */
{
  tree fndecl = build_decl (FUNCTION_DECL, name, type);

#ifdef OBJCPLUS
  /* APPLE LOCAL begin radar 5839812 - location for synthesized methods  */
  /* fndecl's source location is, by default, the current input location
     (build_decl automatically does that).  If the fndecl is for a synthesized
     property's getter or setter method, then the current input location will 
     be the '@end', rather than the '@property' or '@synthesize' statement.
     The following statement detects that situation and re-sets fndecl to
     the correct source location for the '@property' or '@synthesize' 
     statement.  */
  if (method
      && (strcmp (DECL_SOURCE_FILE (fndecl), DECL_SOURCE_FILE (method)) != 0
	  || DECL_SOURCE_LINE (fndecl) != DECL_SOURCE_LINE (method)))
    DECL_SOURCE_LOCATION (fndecl) = DECL_SOURCE_LOCATION (method);
  /* APPLE LOCAL end radar 5839812 - location for synthesized methods  */
  DECL_ARGUMENTS (fndecl) = params;
  DECL_INITIAL (fndecl) = error_mark_node;
  DECL_EXTERNAL (fndecl) = 0;
  TREE_STATIC (fndecl) = 1;
  retrofit_lang_decl (fndecl);
  cplus_decl_attributes (&fndecl, attrs, 0);
  /* APPLE LOCAL begin optimization pragmas 3124235/3420242 */
  /* Build a mapping between this decl and the per-function options in
     effect at this point.  */
  record_func_cl_pf_opts_mapping (fndecl);
  /* APPLE LOCAL end optimization pragmas 3124235/3420242 */
  start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
#else
  struct c_label_context_se *nstack_se;
  struct c_label_context_vm *nstack_vm;
  /* APPLE LOCAL begin radar 5839812 - location for synthesized methods  */
  /* fndecl's source location is, by default, the current input location
     (build_decl automatically does that).  If the fndecl is for a synthesized
     property's getter or setter method, then the current input location will 
     be the '@end', rather than the '@property' or '@synthesize' statement.
     The following statement detects that situation and re-sets fndecl to
     the correct source location for the '@property' or '@synthesize' 
     statement.  */
  if (method
      && (strcmp (DECL_SOURCE_FILE (fndecl), DECL_SOURCE_FILE (method)) != 0
	  || DECL_SOURCE_LINE (fndecl) != DECL_SOURCE_LINE (method)))
    DECL_SOURCE_LOCATION (fndecl) = DECL_SOURCE_LOCATION (method);
  /* APPLE LOCAL end radar 5839812 - location for synthesized methods  */
  nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
  nstack_se->labels_def = NULL;
  nstack_se->labels_used = NULL;
  nstack_se->next = label_context_stack_se;
  label_context_stack_se = nstack_se;
  nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
  nstack_vm->labels_def = NULL;
  nstack_vm->labels_used = NULL;
  nstack_vm->scope = 0;
  nstack_vm->next = label_context_stack_vm;
  label_context_stack_vm = nstack_vm;
  current_function_returns_value = 0;  /* Assume, until we see it does.  */
  current_function_returns_null = 0;

  decl_attributes (&fndecl, attrs, 0);
  announce_function (fndecl);
  DECL_INITIAL (fndecl) = error_mark_node;
  DECL_EXTERNAL (fndecl) = 0;
  TREE_STATIC (fndecl) = 1;
  current_function_decl = pushdecl (fndecl);
  /* APPLE LOCAL begin optimization pragmas 3124235/3420242 */
  /* Build a mapping between this decl and the per-function options in
     effect at this point.  */
  record_func_cl_pf_opts_mapping (fndecl);
  /* APPLE LOCAL end optimization pragmas 3124235/3420242 */
  push_scope ();
  declare_parm_level ();
  DECL_RESULT (current_function_decl)
    = build_decl (RESULT_DECL, NULL_TREE,
		  TREE_TYPE (TREE_TYPE (current_function_decl)));
  DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
  DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
  start_fname_decls ();
  store_parm_decls_from (params);
#endif

  TREE_USED (current_function_decl) = 1;
}

/* - Generate an identifier for the function. the format is "_n_cls",
     where 1 <= n <= nMethods, and cls is the name the implementation we
     are processing.
   - Install the return type from the method declaration.
   - If we have a prototype, check for type consistency.  */

static void
really_start_method (tree method,
#ifdef OBJCPLUS
		     tree parmlist
#else
		     struct c_arg_info *parmlist
#endif
		     )
{
  tree ret_type, meth_type;
  tree method_id;
  const char *sel_name, *class_name, *cat_name;
  char *buf;

  /* Synth the storage class & assemble the return type.  */
  ret_type = TREE_VALUE (TREE_TYPE (method));

  sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
  class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
  cat_name = ((TREE_CODE (objc_implementation_context)
	       == CLASS_IMPLEMENTATION_TYPE)
	      ? NULL
	      : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
  method_slot++;

  /* Make sure this is big enough for any plausible method label.  */
  buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
			 + (cat_name ? strlen (cat_name) : 0));

  OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
			 class_name, cat_name, sel_name, method_slot);

  method_id = get_identifier (buf);

#ifdef OBJCPLUS
  /* Objective-C methods cannot be overloaded, so we don't need
     the type encoding appended.  It looks bad anyway... */
  push_lang_context (lang_name_c);
#endif

  meth_type
    = build_function_type (ret_type,
		    	   /* APPLE LOCAL radar 6307941 */
			   get_arg_type_list (METHOD_SEL_NAME (method), method, METHOD_DEF, 0));
  /* APPLE LOCAL radar 5839812 - location for synthesized methods  */
  objc_start_function (method_id, meth_type, NULL_TREE, parmlist, method);
/* LLVM LOCAL begin prevent llvm from adding leading _ */
#ifdef ENABLE_LLVM
  set_user_assembler_name(current_function_decl, buf);
#endif
/* LLVM LOCAL end prevent llvm from adding leading _ */

  /* Set self_decl from the first argument.  */
  self_decl = DECL_ARGUMENTS (current_function_decl);

  /* Suppress unused warnings.  */
  TREE_USED (self_decl) = 1;
  TREE_USED (TREE_CHAIN (self_decl)) = 1;
#ifdef OBJCPLUS
  pop_lang_context ();
#endif

  METHOD_DEFINITION (method) = current_function_decl;
  /* APPLE LOCAL deprecated use in deprecated 6425499 */
  TREE_DEPRECATED (current_function_decl) = TREE_DEPRECATED (method);

  /* Check consistency...start_function, pushdecl, duplicate_decls.  */

  if (implementation_template != objc_implementation_context)
    {
      /* APPLE LOCAL begin radar 5370783 */
      tree proto
	= lookup_method_static (implementation_template,
				METHOD_SEL_NAME (method),
				(TREE_CODE (method) == CLASS_METHOD_DECL), 
				false, false);
      /* APPLE LOCAL end radar 5370783 */

      if (proto)
	{
	  /* APPLE LOCAL radar 4606233 */
	  /* code removed */
	  if (!comp_proto_with_proto (method, proto, 1))
	    {
	      char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');

	      warn_with_method ("conflicting types for", type, method);
	      warn_with_method ("previous declaration of", type, proto);
	    }
	  /* APPLE LOCAL begin radar 4727659 */
	  /* Move __attribute__ ((noreturn)) to DECL_FUNCTION definition node.
	     so warning may come out */
	  if (METHOD_DEFINITION (method))
            TREE_THIS_VOLATILE (METHOD_DEFINITION (method)) 
	      = TREE_THIS_VOLATILE (proto);
	  /* APPLE LOCAL end radar 4727659 */
	}
      else
	{
	  /* We have a method @implementation even though we did not
	     see a corresponding @interface declaration (which is allowed
	     by Objective-C rules).  Go ahead and place the method in
	     the @interface anyway, so that message dispatch lookups
	     will see it.  */
	  tree interface = implementation_template;

	  if (TREE_CODE (objc_implementation_context)
	      == CATEGORY_IMPLEMENTATION_TYPE)
	    interface = lookup_category
			(interface,
			 CLASS_SUPER_NAME (objc_implementation_context));

	  if (interface)
	    objc_add_method (interface, copy_node (method),
			     /* APPLE LOCAL C* language */
			     TREE_CODE (method) == CLASS_METHOD_DECL, 0);
	}
    }
}

static void *UOBJC_SUPER_scope = 0;

/* _n_Method (id self, SEL sel, ...)
     {
       struct objc_super _S;
       _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
     }  */

static tree
get_super_receiver (void)
{
  if (objc_method_context)
    {
      tree super_expr, super_expr_list;

      if (!UOBJC_SUPER_decl)
      {
	UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
				       objc_super_template);
	/* This prevents `unused variable' warnings when compiling with -Wall.  */
	TREE_USED (UOBJC_SUPER_decl) = 1;
	lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
        finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
	UOBJC_SUPER_scope = objc_get_current_scope ();
      }

      /* Set receiver to self.  */
      super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
      /* APPLE LOCAL begin radar 6230701 */
      if (cur_block)
      {
        tree local_self_decl = self_decl;
        access_block_ref_self_decl (&local_self_decl);
        super_expr = build_modify_expr (super_expr, NOP_EXPR, local_self_decl);
      }
      else
        super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
       /* APPLE LOCAL end radar 6230701 */
      super_expr_list = super_expr;

      /* Set class to begin searching.  */
      super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
      /* APPLE LOCAL ObjC abi v2 */
					     get_identifier ("cls"));

      if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
	{
          /* APPLE LOCAL begin ObjC abi v2 */
          if (flag_objc_abi == 2)
            {
              /* For new ObjC abi, "cls" is loaded from a __class_refs table entry. */
	      /* For super call in class method, must have super_t.cls point to its
		 metaclass. */
              tree class_expr;
	      /* APPLE LOCAL begin radar 4535676 */
	      class_expr = objc_v2_get_class_super_reference (
			     CLASS_NAME (objc_implementation_context),
			     (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL));
	      /* APPLE LOCAL end radar 4535676 */
              super_expr = build_modify_expr (super_expr, NOP_EXPR, class_expr);
            }
          else
            {
              /* [_cls, __cls]Super are "pre-built" in
                 synth_forward_declarations.  */

              super_expr = build_modify_expr (super_expr, NOP_EXPR,
                                              ((TREE_CODE (objc_method_context)
                                                == INSTANCE_METHOD_DECL)
                                               ? ucls_super_ref
                                               : uucls_super_ref));
            }
          /* APPLE LOCAL end ObjC abi v2 */
	}

      else
	/* We have a category.  */
	{
	  tree super_name = CLASS_SUPER_NAME (implementation_template);
	  tree super_class;

	  /* Barf if super used in a category of Object.  */
	  if (!super_name)
	    {
	      error ("no super class declared in interface for %qs",
		    IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
	      return error_mark_node;
	    }

	  if (flag_next_runtime && !flag_zero_link)
	    {
              /* APPLE LOCAL begin ObjC abi v2 */
              super_class = objc_get_class_reference ((flag_objc_abi == 2)
                                                      ? CLASS_NAME (implementation_template)
                                                      : super_name);
              /* APPLE LOCAL end ObjC abi v2 */
	      if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
		/* If we are in a class method, we must retrieve the
		   _metaclass_ for the current class, pointed at by
		   the class's "isa" pointer.  The following assumes that
		   "isa" is the first ivar in a class (which it must be).  */
		super_class
		  = build_indirect_ref
		    (build_c_cast (build_pointer_type (objc_class_type),
				   super_class), "unary *");
	    }
	  else
	    {
	      add_class_reference (super_name);
	      super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
			     ? objc_get_class_decl : objc_get_meta_class_decl);
	      assemble_external (super_class);
	      super_class
		= build_function_call
		  (super_class,
		   build_tree_list
		   (NULL_TREE,
		    my_build_string_pointer
		    (IDENTIFIER_LENGTH (super_name) + 1,
		     IDENTIFIER_POINTER (super_name))));
	    }

	  super_expr
	    = build_modify_expr (super_expr, NOP_EXPR,
				 build_c_cast (TREE_TYPE (super_expr),
					       super_class));
	}

      super_expr_list = build_compound_expr (super_expr_list, super_expr);

      super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
      super_expr_list = build_compound_expr (super_expr_list, super_expr);

      return super_expr_list;
    }
  else
    {
      error ("[super ...] must appear in a method context");
      return error_mark_node;
    }
}

/* When exiting a scope, sever links to a 'super' declaration (if any)
   therein contained.  */

void
objc_clear_super_receiver (void)
{
  if (objc_method_context
      && UOBJC_SUPER_scope == objc_get_current_scope ()) {
    UOBJC_SUPER_decl = 0;
    UOBJC_SUPER_scope = 0;
  }
}

void
objc_finish_method_definition (tree fndecl)
{
  /* We cannot validly inline ObjC methods, at least not without a language
     extension to declare that a method need not be dynamically
     dispatched, so suppress all thoughts of doing so.  */
  DECL_INLINE (fndecl) = 0;
  DECL_UNINLINABLE (fndecl) = 1;

#ifndef OBJCPLUS
  /* The C++ front-end will have called finish_function() for us.  */
  finish_function ();
#endif

  METHOD_ENCODING (objc_method_context)
    = encode_method_prototype (objc_method_context);

  /* Required to implement _msgSuper. This must be done AFTER finish_function,
     since the optimizer may find "may be used before set" errors.  */
  objc_method_context = NULL_TREE;

  if (should_call_super_dealloc)
    warning (0, "method possibly missing a [super dealloc] call");
  /* APPLE LOCAL begin radar 4757423 */
  if (should_call_super_finalize)
    warning (0, "method possibly missing a [super finalize] call");
  /* APPLE LOCAL end radar 4757423 */
}

#if 0
int
lang_report_error_function (tree decl)
{
  if (objc_method_context)
    {
      fprintf (stderr, "In method %qs\n",
	       IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
      return 1;
    }

  else
    return 0;
}
#endif

/* Given a tree DECL node, produce a printable description of it in the given
   buffer, overwriting the buffer.  */

static char *
gen_declaration (tree decl)
{
  errbuf[0] = '\0';

  if (DECL_P (decl))
    {
      gen_type_name_0 (TREE_TYPE (decl));

      if (DECL_NAME (decl))
	{
	  if (!POINTER_TYPE_P (TREE_TYPE (decl)))
	    strcat (errbuf, " ");

	  strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
	}

      if (DECL_INITIAL (decl)
	  && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
	sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
		 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
    }

  return errbuf;
}

/* Given a tree TYPE node, produce a printable description of it in the given
   buffer, overwriting the buffer.  */

static char *
gen_type_name_0 (tree type)
{
  tree orig = type, proto;

  if (TYPE_P (type) && TYPE_NAME (type))
    type = TYPE_NAME (type);
  else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
    {
      tree inner = TREE_TYPE (type);

      while (TREE_CODE (inner) == ARRAY_TYPE)
	inner = TREE_TYPE (inner);

      gen_type_name_0 (inner);

      if (!POINTER_TYPE_P (inner))
	strcat (errbuf, " ");

      if (POINTER_TYPE_P (type))
	strcat (errbuf, "*");
      else
	while (type != inner)
	  {
	    strcat (errbuf, "[");

	    if (TYPE_DOMAIN (type))
	      {
		char sz[20];

		sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
			 (TREE_INT_CST_LOW
			  (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
		strcat (errbuf, sz);
	      }

	    strcat (errbuf, "]");
	    type = TREE_TYPE (type);
	  }

      goto exit_function;
    }

  if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
    type = DECL_NAME (type);

  strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
	  	  ? IDENTIFIER_POINTER (type)
		  : "");

  /* For 'id' and 'Class', adopted protocols are stored in the pointee.  */
  if (objc_is_id (orig))
    orig = TREE_TYPE (orig);

  proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;

  if (proto)
    {
      strcat (errbuf, " <");

      while (proto) {
	strcat (errbuf,
		IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
	proto = TREE_CHAIN (proto);
	strcat (errbuf, proto ? ", " : ">");
      }
    }

 exit_function:
  return errbuf;
}

static char *
gen_type_name (tree type)
{
  errbuf[0] = '\0';

  return gen_type_name_0 (type);
}

/* Given a method tree, put a printable description into the given
   buffer (overwriting) and return a pointer to the buffer.  */

static char *
gen_method_decl (tree method)
{
  tree chain;

  strcpy (errbuf, "(");  /* NB: Do _not_ call strcat() here.  */
  gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
  strcat (errbuf, ")");
  chain = METHOD_SEL_ARGS (method);

  if (chain)
    {
      /* We have a chain of keyword_decls.  */
      do
        {
	  if (KEYWORD_KEY_NAME (chain))
	    strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));

	  strcat (errbuf, ":(");
	  gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
	  strcat (errbuf, ")");

	  strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
	  if ((chain = TREE_CHAIN (chain)))
	    strcat (errbuf, " ");
        }
      while (chain);

      if (METHOD_ADD_ARGS (method))
	{
	  chain = TREE_CHAIN (METHOD_ADD_ARGS (method));

	  /* Know we have a chain of parm_decls.  */
	  while (chain)
	    {
	      strcat (errbuf, ", ");
	      gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
	      chain = TREE_CHAIN (chain);
	    }

	  if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
	    strcat (errbuf, ", ...");
	}
    }

  else
    /* We have a unary selector.  */
    strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));

  return errbuf;
}

/* Debug info.  */


/* Dump an @interface declaration of the supplied class CHAIN to the
   supplied file FP.  Used to implement the -gen-decls option (which
   prints out an @interface declaration of all classes compiled in
   this run); potentially useful for debugging the compiler too.  */
static void
dump_interface (FILE *fp, tree chain)
{
  /* FIXME: A heap overflow here whenever a method (or ivar)
     declaration is so long that it doesn't fit in the buffer.  The
     code and all the related functions should be rewritten to avoid
     using fixed size buffers.  */
  const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
  tree ivar_decls = CLASS_RAW_IVARS (chain);
  tree nst_methods = CLASS_NST_METHODS (chain);
  tree cls_methods = CLASS_CLS_METHODS (chain);

  fprintf (fp, "\n@interface %s", my_name);

  /* CLASS_SUPER_NAME is used to store the superclass name for
     classes, and the category name for categories.  */
  if (CLASS_SUPER_NAME (chain))
    {
      const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));

      if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
	  || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
	{
	  fprintf (fp, " (%s)\n", name);
	}
      else
	{
	  fprintf (fp, " : %s\n", name);
	}
    }
  else
    fprintf (fp, "\n");

  /* FIXME - the following doesn't seem to work at the moment.  */
  if (ivar_decls)
    {
      fprintf (fp, "{\n");
      do
	{
	  fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
	  ivar_decls = TREE_CHAIN (ivar_decls);
	}
      while (ivar_decls);
      fprintf (fp, "}\n");
    }

  while (nst_methods)
    {
      fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
      nst_methods = TREE_CHAIN (nst_methods);
    }

  while (cls_methods)
    {
      fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
      cls_methods = TREE_CHAIN (cls_methods);
    }

  fprintf (fp, "@end\n");
}

/* Demangle function for Objective-C */
static const char *
/* APPLE LOCAL radar 4638467,4734562 */
objc_demangle (tree decl, int vrb)
{
  char *demangled, *cp;
  /* APPLE LOCAL radar 4638467 */
  const char *mangled = IDENTIFIER_POINTER (DECL_NAME (decl));

  if (mangled[0] == '_' &&
      (mangled[1] == 'i' || mangled[1] == 'c') &&
      mangled[2] == '_')
    {
      cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
      if (mangled[1] == 'i')
	*cp++ = '-';            /* for instance method */
      else
	*cp++ = '+';            /* for class method */
      *cp++ = '[';              /* opening left brace */
      strcpy(cp, mangled+3);    /* tack on the rest of the mangled name */
      while (*cp && *cp == '_')
	cp++;                   /* skip any initial underbars in class name */
      cp = strchr(cp, '_');     /* find first non-initial underbar */
      if (cp == NULL)
	{
	  free(demangled);      /* not mangled name */
	  return mangled;
	}
      if (cp[1] == '_')  /* easy case: no category name */
	{
	  *cp++ = ' ';            /* replace two '_' with one ' ' */
	  strcpy(cp, mangled + (cp - demangled) + 2);
	}
      else
	{
	  *cp++ = '(';            /* less easy case: category name */
	  cp = strchr(cp, '_');
	  if (cp == 0)
	    {
	      free(demangled);    /* not mangled name */
	      return mangled;
	    }
	  *cp++ = ')';
	  *cp++ = ' ';            /* overwriting 1st char of method name... */
	  strcpy(cp, mangled + (cp - demangled)); /* get it back */
	}
      while (*cp && *cp == '_')
	cp++;                   /* skip any initial underbars in method name */
      for (; *cp; cp++)
	if (*cp == '_')
	  *cp = ':';            /* replace remaining '_' with ':' */
      *cp++ = ']';              /* closing right brace */
      *cp++ = 0;                /* string terminator */
      return demangled;
    }
  else
/* APPLE LOCAL begin radar 4638467,4734562, 3904139 */
#ifdef OBJCPLUS
    return cxx_printable_name (decl, vrb);
#else
    return vrb == 2 ? mangled : mangled; /* not an objc mangled name */
#endif
/* APPLE LOCAL end radar 4638467,4734562, 3904139 */
}

const char *
/* APPLE LOCAL radar 4734562 */
objc_printable_name (tree decl, int vrb)
{
  /* APPLE LOCAL radar 4638467,4734562 */
  return objc_demangle (decl, vrb);
}

static void
init_objc (void)
{
  gcc_obstack_init (&util_obstack);
  util_firstobj = (char *) obstack_finish (&util_obstack);

  errbuf = XNEWVEC (char, 1024 * 10);
  hash_init ();
  synth_module_prologue ();
}

static void
finish_objc (void)
{
  struct imp_entry *impent;
  tree chain;
  /* The internally generated initializers appear to have missing braces.
     Don't warn about this.  */
  int save_warn_missing_braces = warn_missing_braces;
  warn_missing_braces = 0;

  /* A missing @end may not be detected by the parser.  */
  if (objc_implementation_context)
    {
      warning (0, "%<@end%> missing in implementation context");
      finish_class (objc_implementation_context);
      objc_ivar_chain = NULL_TREE;
      objc_implementation_context = NULL_TREE;
    }

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

  if (imp_list || class_names_chain
      /* APPLE LOCAL C* property metadata (Radar 4498373) */
      || prop_names_attr_chain
      || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
    generate_objc_symtab_decl ();

  for (impent = imp_list; impent; impent = impent->next)
    {
      objc_implementation_context = impent->imp_context;
      implementation_template = impent->imp_template;

      /* APPLE LOCAL begin ObjC new abi */
      if (flag_objc_abi == 2)
	{
      	  UOBJC_V2_CLASS_decl = impent->class_v2_decl;
      	  UOBJC_V2_METACLASS_decl = impent->meta_v2_decl;
	}
      else
	{
          UOBJC_CLASS_decl = impent->class_decl;
          UOBJC_METACLASS_decl = impent->meta_decl;
	}
      /* APPLE LOCAL end ObjC new abi */

      /* Dump the @interface of each class as we compile it, if the
	 -gen-decls option is in use.  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, objc_implementation_context);
	}

      if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
	{
	  /* all of the following reference the string pool...  */

	  /* APPLE LOCAL begin ObjC abi v2 */
	  if (flag_objc_abi == 2)
	    {
	      generate_v2_ivar_lists ();
	      generate_v2_dispatch_tables ();
	      /* APPLE LOCAL C* property metadata (Radar 4498373, 4559114) */
	      generate_v2_property_tables (NULL_TREE);
	      generate_v2_shared_structures (impent->has_cxx_cdtors
					     /* APPLE LOCAL radar 4923634 */
					     ? OBJC2_CLS_HAS_CXX_STRUCTORS
					     : 0);
	    }
          else
            {
              generate_ivar_lists ();
              generate_dispatch_tables ();
	      /* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
	      generate_v2_property_tables (NULL_TREE);
	      UOBJC_CLASS_EXT_decl = generate_objc_class_ext (UOBJC_V2_PROPERTY_decl);
	      /* APPLE LOCAL end radar 4585769 - Objective-C 1.0 extensions */	      

              generate_shared_structures (impent->has_cxx_cdtors
                                          ? CLS_HAS_CXX_STRUCTORS
                                          : 0);
            }
	}
          /* APPLE LOCAL end ObjC abi v2 */
      /* APPLE LOCAL radar 4695109 */
      /* PROTOCOL_IMPLEMENTATION_TYPE removed */
      else
	{
	  /* APPLE LOCAL begin ObjC abi v2 */
	  if (flag_objc_abi == 2)
	    {
	      generate_v2_dispatch_tables ();
	      /* APPLE LOCAL C* property metadata (Radar 4498373, 4559114) */
	      generate_v2_property_tables (NULL_TREE);
	      generate_v2_category (objc_implementation_context, impent);
	    }
	  else
	    {
	      generate_dispatch_tables ();
	      /* APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions */
	      generate_v2_property_tables (NULL_TREE);
	      /* APPLE LOCAL radar 4349690 */
	      generate_category (objc_implementation_context, impent);
	    }
	  /* APPLE LOCAL end ObjC abi v2 */
	}
    }

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

  /* APPLE LOCAL begin ObjC abi v2 */
  if (message_ref_chain)
    build_message_ref_translation_table ();
  if (classlist_ref_chain)
    build_classlist_translation_table (false);
  if (metaclasslist_ref_chain)
    build_classlist_translation_table (true);
  /* APPLE LOCAL begin radar 4535676 */
  if (classlist_super_ref_chain)
    build_classlist_super_translation_table (false);
  if (metaclasslist_super_ref_chain)
    build_classlist_super_translation_table (true);
  /* APPLE LOCAL end radar 4535676 */
  if (ivar_offset_ref_chain)
    generate_v2_ivar_offset_ref_lists ();
  if (protocol_chain)
    {
      if (flag_objc_abi == 2)
	{
          generate_v2_protocols ();
	}
      else
        generate_protocols ();
    }
  /* APPLE LOCAL begin radar 4533974 - ObjC new protocol */
  if (protocol_list_chain)
    build_protocol_list_address_table ();
  if (protocollist_ref_chain)
    build_protocollist_translation_table ();
  /* APPLE LOCAL end radar 4533974 - ObjC new protocol */
  if (class_list_chain)
    build_class_list_address_table (false);
  if (category_list_chain)
    build_category_list_address_table (false);
  if (nonlazy_class_list_chain)
    build_class_list_address_table (true);
  if (nonlazy_category_list_chain)
    build_category_list_address_table (true);
  /* APPLE LOCAL end ObjC abi v2 */

  /* APPLE LOCAL radar 4810587 */
  generate_objc_image_info ();

  /* Arrange for ObjC data structures to be initialized at run time.  */
  if (objc_implementation_context || class_names_chain || objc_static_instances
      || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
    {
      /* APPLE LOCAL begin ObjC abi v2 */
      /* APPLE LOCAL radar 4531482 */
      if (flag_objc_abi != 2)
        build_module_descriptor ();
      /* APPLE LOCAL end ObjC abi v2 */

      if (!flag_next_runtime)
	build_module_initializer_routine ();
    }

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

  for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
    {
      handle_class_ref (chain);
      /* LLVM LOCAL begin - radar 5676233 */
      if (TREE_PURPOSE (chain)) {
	generate_classref_translation_entry (chain);
#ifdef ENABLE_LLVM
        /* Reset the initializer for this reference as it most likely
           changed.  */
        reset_initializer_llvm(TREE_PURPOSE (chain));
#endif
      }
      /* LLVM LOCAL end - radar 5676233 */
    }

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

  if (warn_selector)
    {
      int slot;
      hash hsh;

      /* Run through the selector hash tables and print a warning for any
         selector which has multiple methods.  */

      for (slot = 0; slot < SIZEHASHTABLE; slot++)
	{
	  for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
	    check_duplicates (hsh, 0, 1);
	  for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
	    check_duplicates (hsh, 0, 1);
	}
    }

  warn_missing_braces = save_warn_missing_braces;
  /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
  {
    int i;
    for (i = 0; i < OCTI_MAX; i++)
      if (objc_global_trees[i] && DECL_P (objc_global_trees[i]))
        /* Let optimizer know that this decl is not removable.  */
        DECL_PRESERVE_P (objc_global_trees[i]) = 1;
  }
#endif
  /* LLVM LOCAL end */
}

/* Subroutines of finish_objc.  */

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

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

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

  /* The decl that is the one that we
     forward declared in build_class_reference.  */
  finish_var_decl (decl, expr);
  return;
}

static void
handle_class_ref (tree chain)
{
  const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
  char *string = (char *) alloca (strlen (name) + 30);
  tree decl;
  tree exp;

  sprintf (string, "%sobjc_class_name_%s",
	   (flag_next_runtime ? "." : "__"), name);

#ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
  if (flag_next_runtime)
    {
      ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
      return;
    }
#endif

  /* Make a decl for this name, so we can use its address in a tree.  */
  decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
  DECL_EXTERNAL (decl) = 1;
  TREE_PUBLIC (decl) = 1;
  /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
  /* This decl's name is special. Ask llvm to not add leading underscore by 
     setting it as a user supplied asm name.  */
  set_user_assembler_name(decl, string);
  /* Let optimizer know that this decl is not removable.  */
  DECL_PRESERVE_P (decl) = 1;
#endif
  /* LLVM LOCAL end */
  pushdecl (decl);
  rest_of_decl_compilation (decl, 0, 0);

  /* Make a decl for the address.  */
  sprintf (string, "%sobjc_class_ref_%s",
	   (flag_next_runtime ? "." : "__"), name);
  exp = build1 (ADDR_EXPR, string_type_node, decl);
  decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
  DECL_INITIAL (decl) = exp;
  TREE_STATIC (decl) = 1;
  TREE_USED (decl) = 1;
/* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
  /* This decl's name is special. Ask llvm to not add leading underscore by 
     setting it as a user supplied asm name.  */
  set_user_assembler_name(decl, string);
#endif
/* LLVM LOCAL end */
  /* Force the output of the decl as this forces the reference of the class.  */
  mark_decl_referenced (decl);

  pushdecl (decl);
  rest_of_decl_compilation (decl, 0, 0);
}

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

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

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

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

      sprintf (string, "%sobjc_class_name_%s",
               (flag_next_runtime ? "." : "__"), class_name);
    }
  /* APPLE LOCAL radar 5774213 */
  else if (flag_objc_abi <= 1 && TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
    {
      const char *const class_name =
	IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
      const char *const class_super_name =
        IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));

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

      /* Do the same for categories.  Even though no references to
         these symbols are generated automatically by the compiler, it
         gives you a handle to pull them into an archive by hand.  */
/* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
      /* The * is a sentinel for gcc's back end, but is not wanted by llvm. */
      sprintf (string, "%sobjc_category_name_%s_%s",
               (flag_next_runtime ? "." : "__"), class_name, class_super_name);
#else
      sprintf (string, "*%sobjc_category_name_%s_%s",
               (flag_next_runtime ? "." : "__"), class_name, class_super_name);
#endif
/* LLVM LOCAL end */
    }
  else
    return;

#ifdef ASM_DECLARE_CLASS_REFERENCE
  if (flag_next_runtime)
    {
      /* LLVM LOCAL begin - radar 5702446 */
#ifdef ENABLE_LLVM
      if (flag_objc_abi != 2)
#endif
      /* LLVM LOCAL end - radar 5702446 */
      ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
      return;
    }
  else
#endif
    {
      tree decl, init;

      init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
      decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
      TREE_PUBLIC (decl) = 1;
      TREE_READONLY (decl) = 1;
      TREE_USED (decl) = 1;
      TREE_CONSTANT (decl) = 1;
      DECL_CONTEXT (decl) = 0;
      DECL_ARTIFICIAL (decl) = 1;
      /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
      DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
      DECL_VISIBILITY_SPECIFIED (decl) = 1;
      set_user_assembler_name(decl, string);
      /* Let optimizer know that this decl is not removable.  */
      DECL_PRESERVE_P (decl) = 1;
#endif
      /* LLVM LOCAL end */
      DECL_INITIAL (decl) = init;
      assemble_variable (decl, 1, 0, 0);
    }
}

/* The Fix-and-Continue functionality available in Mac OS X 10.3 and
   later requires that ObjC translation units participating in F&C be
   specially marked.  The following routine accomplishes this.  */

/* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */

static void
generate_objc_image_info (void)
{
  tree decl, initlist;
  int flags
    = ((flag_replace_objc_classes && imp_list ? 1 : 0)
       | (flag_objc_gc ? 2 : 0));
  /* APPLE LOCAL begin radar 4810609 */
  if (flag_objc_gc_only)
    flags |= 6;
  /* APPLE LOCAL end radar 4810609 */

  /* APPLE LOCAL begin radar 4810587 */
  /* APPLE LOCAL begin LLVM */
#ifdef ENABLE_LLVM
  /* Darwin linker prefers to use 'L' as a prefix. GCC codegen handles this
     later while emitting symbols, but fix it here for llvm.  */
  decl = build_decl (VAR_DECL, get_identifier ("L_OBJC_IMAGE_INFO"),
                     build_array_type
                     (integer_type_node,
                      build_index_type (build_int_cst (NULL_TREE, 2 - 1))));
#else
  /* APPLE LOCAL end LLVM */
  decl = build_decl (VAR_DECL, get_identifier ("_OBJC_IMAGE_INFO"), 
		     build_array_type
		       (integer_type_node,
		  	build_index_type (build_int_cst (NULL_TREE, 2 - 1))));
   /* LLVM LOCAL */
#endif
  initlist = build_tree_list (NULL_TREE, integer_zero_node);
  initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
  initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
  TREE_TYPE (initlist) = TREE_TYPE (decl);
  /* APPLE LOCAL begin radar 4888238 */
  TREE_PUBLIC (decl) = 0;
  TREE_STATIC (decl) = 1;
  /* APPLE LOCAL end radar 4888238 */
  TREE_READONLY (decl) = 1;
  TREE_USED (decl) = 1;
  TREE_CONSTANT (decl) = 1;
  DECL_CONTEXT (decl) = 0;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_INITIAL (decl) = initlist;
  /* APPLE LOCAL begin LLVM */
#ifdef ENABLE_LLVM
  /* Let optimizer know that this decl is not removable.  */
  set_user_assembler_name(decl, IDENTIFIER_POINTER (DECL_NAME(decl)));
  DECL_PRESERVE_P (decl) = 1;
#endif
  /* APPLE LOCAL end LLVM */
  assemble_variable (decl, 1, 0, 0);
}
  /* APPLE LOCAL end radar 4810587 */

/* APPLE LOCAL begin radar 4133425 */
/* Routine is called to issue diagnostic when reference to a private 
   ivar is made and no other variable with same name is found in 
   current scope. */
bool
objc_diagnose_private_ivar (tree id)
{
  tree ivar;
  if (!objc_method_context)
    return false;
  ivar = is_ivar (objc_ivar_chain, id);
  if (ivar && is_private (ivar))
    {
      error ("instance variable %qs is declared private", 
	     IDENTIFIER_POINTER (id));
      return true;
    }
  return false;
}
/* APPLE LOCAL end radar 4133425 */

/* Look up ID as an instance variable.  OTHER contains the result of
   the C or C++ lookup, which we may want to use instead.  */
/* APPLE LOCAL begin C* property (Radar 4436866) */
/* APPLE LOCAL radar 4668023 */
/* Support for referencing property name without use of 'self' qualifier is removed */

tree
objc_lookup_ivar (tree other, tree id)
{
  tree ivar;

  /* If we are not inside of an ObjC method, ivar lookup makes no sense.  */
  if (!objc_method_context)
    return other;
  
  /* APPLE LOCAL begin radar 5796058 - blocks */
  /* Make a quick exit if variable is for a previously declared copied-in
     or byref variable used for an 'ivar' access. */
  if (other && TREE_CODE (other) == VAR_DECL &&
      (BLOCK_DECL_BYREF (other) || BLOCK_DECL_COPIED (other)))
    return other;
  /* APPLE LOCAL end radar 5796058 - blocks */
               
  if (!strcmp (IDENTIFIER_POINTER (id), "super"))
    /* We have a message to super.  */
    return get_super_receiver ();

  /* In a class method, look up an instance variable only as a last
     resort.  */
  if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
      && other && other != error_mark_node)
    return other;

  /* Look up the ivar, but do not use it if it is not accessible.  */
  ivar = is_ivar (objc_ivar_chain, id);

  if (!ivar || is_private (ivar))
    return other;

  /* In an instance method, a local variable (or parameter) may hide the
     instance variable.  */
  if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
      && other && other != error_mark_node
#ifdef OBJCPLUS
      && CP_DECL_CONTEXT (other) != global_namespace)
#else
      && !DECL_FILE_SCOPE_P (other))
#endif
    {
      warning (0, "local declaration of %qs hides instance variable",
               IDENTIFIER_POINTER (id));

      return other;
    }

  /* At this point, we are either in an instance method with no obscuring
     local definitions, or in a class method with no alternate definitions
     at all.  */
  return build_ivar_reference (id);
}
/* APPLE LOCAL end C* property (Radar 4436866) */

/* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression.  This
   needs to be done if we are calling a function through a cast.  */

tree
objc_rewrite_function_call (tree function, tree params)
{
  if (TREE_CODE (function) == NOP_EXPR
      && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
      && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
	 == FUNCTION_DECL)
    {
      function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
			 TREE_OPERAND (function, 0),
			 TREE_VALUE (params), size_zero_node);
    }

  return function;
}

/* APPLE LOCAL begin radar 5802025 */
tree objc_build_property_getter_func_call (tree pref_expr)
{
  tree getter_call;
  tree save_UOBJC_SUPER_decl = UOBJC_SUPER_decl;
  UOBJC_SUPER_decl = TREE_OPERAND (pref_expr, 2);
  getter_call = objc_build_getter_call (TREE_OPERAND (pref_expr, 0),
                                    TREE_OPERAND (pref_expr, 1));
  UOBJC_SUPER_decl = save_UOBJC_SUPER_decl;
  return getter_call;
}
/* APPLE LOCAL end radar 5802025 */
  
/* Look for the special case of OBJC_TYPE_REF with the address of
   a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
   of its cousins).  */

enum gimplify_status
objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
{
  enum gimplify_status r0, r1;
  if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
      && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
      && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
	 == FUNCTION_DECL)
    {
      /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
	 value of the OBJ_TYPE_REF, so force them to be emitted
	 during subexpression evaluation rather than after the
	 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
	 C to use direct rather than indirect calls when the
	 object expression has a postincrement.  */
      r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
			  is_gimple_val, fb_rvalue);
      r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
			  is_gimple_val, fb_rvalue);

      return MIN (r0, r1);
    }
  /* APPLE LOCAL begin radar 5276085 */
  else if (TREE_CODE (*expr_p) == OBJC_WEAK_REFERENCE_EXPR)
    {
      tree expr = TREE_OPERAND (*expr_p, 0);
      tree t = TREE_TYPE (expr);
      expr = objc_build_weak_read (expr);
      expr = convert (t, expr);
      *expr_p = expr;
    }
  /* APPLE LOCAL end radar 5276085 */
  /* APPLE LOCAL begin radar 5285911 5494488 */
  else if (objc_property_reference_expr (*expr_p))
    /* APPLE LOCAL radar 5802025 */
    *expr_p = objc_build_property_getter_func_call (*expr_p);
  /* APPLE LOCAL end radar 5285911 5494488 */

#ifdef OBJCPLUS
  return cp_gimplify_expr (expr_p, pre_p, post_p);
#else
  return c_gimplify_expr (expr_p, pre_p, post_p);
#endif
}

/* Given a CALL expression, find the function being called.  The ObjC
   version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend.  */

tree
objc_get_callee_fndecl (tree call_expr)
{
  tree addr = TREE_OPERAND (call_expr, 0);
  if (TREE_CODE (addr) != OBJ_TYPE_REF)
    return 0;

  addr = OBJ_TYPE_REF_EXPR (addr);

  /* If the address is just `&f' for some function `f', then we know
     that `f' is being called.  */
  if (TREE_CODE (addr) == ADDR_EXPR
      && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
    return TREE_OPERAND (addr, 0);

  return 0;
}

/* APPLE LOCAL begin C* language */

/* This routine builds the following type.

   struct __objcFastEnumerationState {
     unsigned long state;
     id *itemsPtr;
     unsigned long *mutationsPtr;
     unsigned long extra[5];
   };  */

static void
build_objc_fast_enum_state_type (void)
{
  tree field_decl, field_decl_chain;
  objc_fast_enum_state_type = start_struct (RECORD_TYPE, 
					    get_identifier ("__objcFastEnumerationState"));

  /* unsigned long state; */
  field_decl = create_field_decl (long_unsigned_type_node, "state");
  field_decl_chain = field_decl;

  /* id *itemsPtr; */
  field_decl = create_field_decl (build_pointer_type (objc_object_type), "itemsPtr");
  chainon (field_decl_chain, field_decl);
 
  /* unsigned long *mutationsPtr; */
  field_decl = create_field_decl (build_pointer_type (
				  long_unsigned_type_node), "mutationsPtr");
  chainon (field_decl_chain, field_decl);

  /* unsigned long extra[5]; */
  field_decl = create_field_decl (build_array_type
                                  (long_unsigned_type_node,
                                   build_index_type
                                   (build_int_cst (NULL_TREE, 5 - 1))),
                                   "extra");
  chainon (field_decl_chain, field_decl);

  finish_struct (objc_fast_enum_state_type, field_decl_chain, NULL_TREE);
}

/* This routine creates a named temporary local variable. */

static tree
objc_create_named_tmp_var (tree type, const char *prefix)
{
  tree decl = create_tmp_var_raw (type, prefix);
  DECL_CONTEXT (decl) = current_function_decl;
  return decl;
}

/* This routine builds and returns an assortment of objc components needed in
   synthesis of the foreach statement; including:

   __objcFastEnumerationState enumState = { 0 };
   id items[16];
   unsigned long limit; 
   unsigned long startMutations;
   unsigned long counter;
   [collection countByEnumeratingWithState:&enumState objects:items count:16];

   it returns expression for:
     objc_enumerationMutation (self)  */

tree
objc_build_foreach_components (tree receiver, tree *enumState_decl, 
		               tree *items_decl, 
			       tree *limit_decl,
			       tree *startMutations_decl,
			       tree *counter_decl,
			       tree *countByEnumeratingWithState)
{
  tree constructor_fields, initlist, init;
  tree type, exp;
  tree sel_name, method_params;

  tree fast_enum_state_type = objc_fast_enum_state_type;
  tree enum_st_type_decl = lookup_name (get_identifier ("NSFastEnumerationState"));
  /* APPLE LOCAL radar 4531086 */
  OBJC_WARN_OBJC2_FEATURES ("foreach-collection-statement");
  if (enum_st_type_decl && TREE_CODE (enum_st_type_decl) == TYPE_DECL)
    fast_enum_state_type = DECL_ORIGINAL_TYPE (enum_st_type_decl) 
			     ? DECL_ORIGINAL_TYPE (enum_st_type_decl)  
			     : TREE_TYPE (enum_st_type_decl);
  gcc_assert (fast_enum_state_type != NULL_TREE 
	      && TREE_CODE (fast_enum_state_type) == RECORD_TYPE);
  constructor_fields = TYPE_FIELDS (fast_enum_state_type);
  /* __objcFastEnumerationState enumState = { 0 }; */
  *enumState_decl = objc_create_named_tmp_var (fast_enum_state_type, "cstar");
  /* APPLE LOCAL begin radar 6285794 */
  initlist = build_tree_list (constructor_fields, 
                              convert (TREE_TYPE(constructor_fields),
                                       integer_zero_node));
  /* APPLE LOCAL end radar 6285794 */
  init = objc_build_constructor (fast_enum_state_type, initlist);
  DECL_INITIAL (*enumState_decl) = init;

  /* id items[16]; */
  type = build_array_type (objc_object_type,
			   build_index_type (build_int_cst (NULL_TREE, 16 - 1)));
  *items_decl = objc_create_named_tmp_var (type, "cstar");

  /* unsigned long limit */
  *limit_decl = objc_create_named_tmp_var (long_unsigned_type_node, "cstar");

  /* unsigned long startMutations */
  *startMutations_decl = objc_create_named_tmp_var (long_unsigned_type_node, "cstar");

  /* unsigned long counter */
  *counter_decl = objc_create_named_tmp_var (long_unsigned_type_node, "cstar");

  /* [collection countByEnumeratingWithState:&enumState objects:items count:16] */
  sel_name = get_identifier ("countByEnumeratingWithState:objects:count:");
  exp = build_fold_addr_expr (*enumState_decl);
  method_params = build_tree_list (NULL_TREE, exp);
/* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */
#ifndef OBJCPLUS
  {
    struct c_expr cexpr;
    /* In C need to decay array objects when passing to functions. */
    cexpr.value = *items_decl;
    chainon (method_params,
             build_tree_list (NULL_TREE, 
			      default_function_array_conversion (cexpr).value));
  }
#else
  chainon (method_params,
           build_tree_list (NULL_TREE, *items_decl));
#endif
/* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */
  chainon (method_params,
           build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 16)));

  exp = objc_finish_message_expr (receiver, sel_name, method_params);
  *countByEnumeratingWithState = exp;

  /* objc_enumerationMutation (self) */
  exp = build_function_call (objc_enum_mutation_decl,
                             build_tree_list (NULL_TREE, save_expr (receiver)));

  return exp;
}

/* This routine returns true if TYP is a valid objc object type, 
   suitable for messaging; false otherwise.  */

bool
objc_type_valid_for_messaging (tree typ)
{
  /* APPLE LOCAL begin radar 5831920 */
  if (TREE_CODE (typ) == BLOCK_POINTER_TYPE)
    return true;
  /* APPLE LOCAL end radar 5831920 */
  
  if (!POINTER_TYPE_P (typ))
    return false;

  /* APPLE LOCAL begin radar 5595325 */
  if (objc_nsobject_attribute_type (typ))
    return true;
  /* APPLE LOCAL end radar 5595325 */
  do
    typ = TREE_TYPE (typ);  /* Remove indirections.  */
  while (POINTER_TYPE_P (typ));

  if (TREE_CODE (typ) != RECORD_TYPE)
    return false;

  /* type 'Class' is OK */
  return objc_is_object_id (typ) 
	 || objc_is_class_id (typ) || TYPE_HAS_OBJC_INFO (typ);
}

#ifndef OBJCPLUS
/* Synthesizer routine for C*'s feareach statement. 

   It synthesizes:
   for ( type elem in collection) { stmts; }

   Into:
    {
    type elem;
    __objcFastEnumerationState enumState = { 0 };
    id items[16];

    unsigned long limit = [collection countByEnumeratingWithState:&enumState objects:items count:16];
    if (limit) {
      unsigned long startMutations = *enumState.mutationsPtr;
      do {
         unsigned long counter = 0;
         do {
           if (startMutations != *enumState.mutationsPtr) objc_enumerationMutation(collection);
           elem = enumState.itemsPtr[counter++];
           stmts;
         } while (counter < limit);
      } while (limit = [collection countByEnumeratingWithState:&enumState objects:items count:16]);
    }
    else
      elem = nil; radar 4854605, 5128402 */

void
objc_finish_foreach_loop (location_t location, tree cond, tree for_body, tree blab, tree clab)
{
  tree enumState_decl, items_decl, limit_decl, limit_decl_assign_expr; 
  tree startMutations_decl, counter_decl;
  tree enumerationMutation_call_exp, countByEnumeratingWithState;
  tree exp;
  tree receiver, elem_decl;
  tree bind;
  tree if_condition, do_condition;
  tree outer_if_body, inner_if_body;
  tree outer_if_block_start, inner_if_block_start;
  tree outer_do_body, inner_do_body;
  tree inner_do_block_start, outer_do_block_start;
  tree body;
  location_t save_input_location = input_location;
  tree exit_label;
  /* APPLE LOCAL radar 4854605 - radar 5128402 */
  tree outer_else_body;
 
  receiver = TREE_VALUE (cond);
  elem_decl = TREE_PURPOSE (cond);

  /* APPLE LOCAL begin radar 5130983 */
  if (!lvalue_or_else (&elem_decl, lv_foreach))
    return; 
  /* APPLE LOCAL end radar 5130983 */

  if (!objc_type_valid_for_messaging (TREE_TYPE (elem_decl)))
    {
      error ("selector element does not have a valid object type");
      return;
    }

  if (!objc_type_valid_for_messaging (TREE_TYPE (receiver)))
    {
      error ("expression does not have a valid object type");
      return;
    }

  input_location = location; 
  enumerationMutation_call_exp = objc_build_foreach_components  (receiver, &enumState_decl,
                                                                 &items_decl, &limit_decl,
                                                                 &startMutations_decl, &counter_decl,
                                                                 &countByEnumeratingWithState);

  /* __objcFastEnumerationState enumState = { 0 }; */
  exp = build_stmt (DECL_EXPR, enumState_decl);
  bind = build3 (BIND_EXPR, void_type_node, enumState_decl, exp, NULL);
  TREE_SIDE_EFFECTS (bind) = 1;
  add_stmt (bind);

  /* id items[16]; */
  bind = build3 (BIND_EXPR, void_type_node, items_decl, NULL, NULL);
  TREE_SIDE_EFFECTS (bind) = 1;
  add_stmt (bind);
  
  /* Generate this statement and add it to the list. */
  /* limit = [collection countByEnumeratingWithState:&enumState objects:items count:16] */
  limit_decl_assign_expr = build2 (MODIFY_EXPR, TREE_TYPE (limit_decl), limit_decl, 
				   countByEnumeratingWithState);
  bind = build3 (BIND_EXPR, void_type_node, limit_decl, NULL, NULL);
  TREE_SIDE_EFFECTS (bind) = 1;
  add_stmt (bind);

  outer_if_block_start = c_begin_compound_stmt (true);
  /* if (limit) { */
  outer_if_body = c_begin_compound_stmt (true);

  /* unsigned long startMutations = *enumState.mutationsPtr; */
  exp = objc_build_component_ref (enumState_decl, get_identifier("mutationsPtr"));
  exp = build_indirect_ref (exp, "unary *");
  exp = build2 (MODIFY_EXPR, void_type_node, startMutations_decl, exp);
  bind = build3 (BIND_EXPR, void_type_node, startMutations_decl, exp, NULL);
  TREE_SIDE_EFFECTS (bind) = 1;
  add_stmt (bind);

  outer_do_block_start = c_begin_compound_stmt (true);
  /* do { */
  outer_do_body = c_begin_compound_stmt (true);

  /* unsigned long counter = 0; */
  exp = build2 (MODIFY_EXPR, void_type_node, counter_decl, 
		fold_convert (TREE_TYPE (counter_decl), integer_zero_node)); 
  bind = build3 (BIND_EXPR, void_type_node, counter_decl, exp, NULL);
  TREE_SIDE_EFFECTS (bind) = 1;
  add_stmt (bind);
 
  inner_do_block_start = c_begin_compound_stmt (true);
  /*   do { */
  inner_do_body = c_begin_compound_stmt (true);
  
  inner_if_block_start = c_begin_compound_stmt (true);
  /* if (startMutations != *enumState.mutationsPtr) objc_enumerationMutation (collection); */
  inner_if_body = c_begin_compound_stmt (true);
  exp = objc_build_component_ref (enumState_decl,
				  get_identifier ("mutationsPtr"));
  exp = build_indirect_ref (exp, "unary *");
  if_condition = build_binary_op (NE_EXPR, startMutations_decl, exp, 1);
  body = build_function_call (objc_enum_mutation_decl, 
  			      build_tree_list (NULL_TREE, save_expr (receiver)));
  add_stmt (body);
  inner_if_body = c_end_compound_stmt (inner_if_body, true);
  c_finish_if_stmt (location, if_condition, inner_if_body, NULL, false);
  add_stmt (c_end_compound_stmt (inner_if_block_start, true));

  /* elem = enumState.itemsPtr [counter]; */
  exp = objc_build_component_ref (enumState_decl, get_identifier("itemsPtr")); 
  exp = build_array_ref (exp, counter_decl);
  add_stmt (build2 (MODIFY_EXPR, void_type_node, elem_decl, exp));
  TREE_USED (elem_decl) = 1;

  /* counter++; */
  exp = build2 (PLUS_EXPR, TREE_TYPE (counter_decl), counter_decl, 
		build_int_cst (NULL_TREE, 1));
  add_stmt (build2 (MODIFY_EXPR, void_type_node, counter_decl, exp)); 

  /* stmts; */
  add_stmt (for_body);

  /*   } while (counter < limit ); */
  do_condition  = build_binary_op (LT_EXPR, counter_decl, limit_decl, 1); 
  inner_do_body = c_end_compound_stmt (inner_do_body, true);
/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
  c_finish_loop (location, do_condition, NULL, inner_do_body, NULL_TREE, clab,
		 NULL_TREE, false); 
/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
  add_stmt (c_end_compound_stmt (inner_do_block_start, true));

  /* } while (limit = [collection countByEnumeratingWithState:&enumState objects:items count:16]);  */
  exp = unshare_expr (limit_decl_assign_expr);
  do_condition  = build_binary_op (NE_EXPR, exp, 
				   fold_convert (TREE_TYPE (limit_decl), integer_zero_node), 
				   1); 
  outer_do_body = c_end_compound_stmt (outer_do_body, true);
  /* New spec. requires that if no match was found; i.e. foreach exited with
     no match, 'elem' be set to nil. So, we use a new label for getting out of
     of the outer while loop and set 'elem=nill' after this label. */ 
  exit_label = create_artificial_label ();
/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
  c_finish_loop (location, do_condition, NULL, outer_do_body, exit_label,
		 NULL_TREE, NULL_TREE, false);
/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
  /* elem = nil */
  add_stmt (build2 (MODIFY_EXPR, void_type_node, elem_decl, 
		    fold_convert (TREE_TYPE (elem_decl), integer_zero_node)));
  if (blab)
    add_stmt (build1 (LABEL_EXPR, void_type_node, blab));
  add_stmt (c_end_compound_stmt (outer_do_block_start, true));

  /* } */
  if_condition = unshare_expr (do_condition);
  outer_if_body = c_end_compound_stmt (outer_if_body, true);
  /* APPLE LOCAL begin radar 4854605 - radar 5128402 */
  /* else {elem = nil; } */
  outer_else_body = c_begin_compound_stmt (true);
  add_stmt (build2 (MODIFY_EXPR, void_type_node, elem_decl,
            fold_convert (TREE_TYPE (elem_decl), integer_zero_node)));
  outer_else_body = c_end_compound_stmt (outer_else_body, true);
  c_finish_if_stmt (location, if_condition, outer_if_body, outer_else_body, false);
  /* APPLE LOCAL end radar 4854605 - radar 5128402 */
  add_stmt (c_end_compound_stmt (outer_if_block_start, true));
  input_location = save_input_location;
  return;
}
#endif

/* This routine issues a diagnostic if a @selector expression is
   type cast to anothing other than SEL. */
void
diagnose_selector_cast (tree cast_type, tree sel_exp)
{
  tree type = TREE_TYPE (sel_exp);
  if (type)
    {
      if (type == objc_selector_type && cast_type != objc_selector_type)
	/* @selector expression type cast to something other than a 
     	   matching type. */
	if (flag_objc_abi == 2 || flag_objc2_check)
	  warning (0, "type-cast of @selector expression won't be supported in future");
    }
}

bool 
objc_method_decl (enum tree_code opcode)
{
  return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
}

/* 
   This routine builds a comma-expr tree represents pre/post incr/decr expression
   tree of the a property (see below).

   CODE is one of POSTINCREMENT_EXPR (prop++), POSTDECREMENT_EXPR (prop--),
   PREINCREMENT_EXPR (++prop), PREDECREMENT_EXPR (--prop).
   GETTER_EXPR is the property in the form of a property getter call.
   INC is the amount property is incrmented or decremented by.

   for POSTINCREMENT_EXPR we generate: (tmp = prop, prop = tmp+1, tmp).
   for POSTDECREMENT_EXPR we generate: (tmp = prop, prop = tmp-1, tmp).
   for PREINCREMENT_EXPR we generate: (tmp = prop+1, prop = tmp, tmp).
   for PREDECREMENT_EXPR we generate: (tmp = prop-1, prop = tmp, tmp). 
   Function returns NULL_TREE (if not a valid property tree) or above
   comma-expression tree.
*/

static tree
objc_build_compound_incr_decr_setter_call (tree receiver, tree prop_ident,
	      				   enum tree_code code, tree getter_expr, 
					   tree inc)
{
  tree temp, bind, rhs, comma_exp;
  temp = objc_create_named_tmp_var (TREE_TYPE (inc), "prop");
  bind = build3 (BIND_EXPR, void_type_node, temp, NULL, NULL);
  TREE_SIDE_EFFECTS (bind) = 1;
  add_stmt (bind);
  /* build rhs expression of 'tmp = exp' statement. */
  if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
    rhs = getter_expr;
  else if (code == PREINCREMENT_EXPR)
    rhs = build2 (PLUS_EXPR, TREE_TYPE (inc), getter_expr, inc);
  else
    rhs = build2 (MINUS_EXPR, TREE_TYPE (inc), getter_expr, inc);
  /* tmp = rhs; */
  comma_exp = build_modify_expr (temp, NOP_EXPR, rhs);

  /* Now build rhs of 'prop = tmp' statement. */
  if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
    rhs = temp;
  else if (code == POSTINCREMENT_EXPR)
    rhs = build2 (PLUS_EXPR, TREE_TYPE (inc), temp, inc);
  else
    rhs = build2 (MINUS_EXPR, TREE_TYPE (inc), temp, inc);
  comma_exp = build_compound_expr (comma_exp,
                    objc_setter_func_call (receiver, prop_ident, rhs));
  /* Shut-off C++ warning on comma-expr with no side-effect. */
  TREE_NO_WARNING (temp) = 1;
  return build_compound_expr (comma_exp, temp);
}

/* APPLE LOCAL begin radar 5285911 */
/*
   global main routine to build property's version of pre/post incr/decr
   expression tree.

   CODE is one of POSTINCREMENT_EXPR (prop++), POSTDECREMENT_EXPR (prop--),
   PREINCREMENT_EXPR (++prop), PREDECREMENT_EXPR (--prop).
   LHS is the property in the form of OBJC_PROPERTY_REFERENCE_EXPR tree.
   INC is the amount property is incrmented or decremented by.
*/

tree
objc_build_incr_decr_setter_call (enum tree_code code, tree lhs, tree inc)
{
  if (objc_property_reference_expr (lhs))
    {
      tree expr = objc_build_getter_call (TREE_OPERAND (lhs, 0), TREE_OPERAND (lhs, 1));
      return objc_build_compound_incr_decr_setter_call 
	       (TREE_OPERAND (lhs, 0), TREE_OPERAND (lhs, 1), code, expr, inc);
    }
  return NULL_TREE;

}
/* APPLE LOCAL end radar 5285911 */

/* APPLE LOCAL begin radar 5040740 */
/* This routine looks up the PROPERTY in the INTERFACE_TYPE class or one of its
   super classes. */
static tree
lookup_nested_property (tree interface_type, tree property)
{
  tree inter = interface_type;
  while (inter)
    {
      tree x;
      if ((x = lookup_property_in_list (inter, property)))
        return x;
      /* Failing that, climb up the inheritance hierarchy.  */
      inter = lookup_interface (CLASS_SUPER_NAME (inter));
    }
  return NULL_TREE;
}

/* This routine looks up METHOD_NAME in the INTERFACE_TYPE class or one of its
   super class. */
static tree
lookup_nested_method (tree interface_type, tree method_name)
{
  tree inter = interface_type;
  while (inter)
    {
      tree x;
      /* APPLE LOCAL begin radar 5777307 */
      /* When property is declared as @optional in a protocol declaration,
         must also seach for the setter/getter method declarations in
         the protocols because they have no declaration in the 'inter'
         class. */
      if ((x = lookup_method (CLASS_NST_METHODS (inter), method_name)) ||
          (x = lookup_method_in_protocol_list 
                 (CLASS_PROTOCOL_LIST (inter), method_name, 0)))
      /* APPLE LOCAL end radar 5777307 */
        return x;
      /* Failing that, climb up the inheritance hierarchy.  */
      inter = lookup_interface (CLASS_SUPER_NAME (inter));
    }
  return NULL_TREE;
}

/* APPLE LOCAL end radar 5040740 */

/* APPLE LOCAL begin radar 5435299 */
/* lookup_property_impl_in_list - Look for an existing property
  @synthesize/@dynamic in current implementation.
*/
static tree
lookup_property_impl_in_list (tree chain, tree property)
{
  tree x;
  for (x = IMPL_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
    if (PROPERTY_NAME (x) == property)
      return x;
  return NULL_TREE;
}

/* lookup_ivar_in_property_list - Searches current property list looking for
   one which uses the given ivar_name. If found, it returns this property.
*/

static tree
lookup_ivar_in_property_list (tree chain, tree ivar_name)
{
  tree x;
  for (x = IMPL_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
    if (PROPERTY_IVAR_NAME (x) == ivar_name)
      return x;
  return NULL_TREE;
}

/* APPLE LOCAL end radar 5435299 */

/* APPLE LOCAL begin radar 6209554 */
static void error_previous_property_decl (tree x)
{ tree decl = build_decl (VAR_DECL, DECL_NAME (x), TREE_TYPE (x));
  DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (x);
  error ("previous property declaration of %q+D was here", decl);
}
/* APPLE LOCAL end radar 6209554 */
/* This routine declares a new property implementation. Triggered by a @synthesize or
   @dynamic declaration. */
void objc_declare_property_impl (int impl_code, tree tree_list)
{
  tree chain, interface, class;
  if (tree_list == error_mark_node 
      || TREE_PURPOSE (tree_list) == error_mark_node
      || TREE_VALUE (tree_list) == error_mark_node)
    return;
  /* Find the @interface for this @implementation. */
  /* APPLE LOCAL begin radar 5265608 */
  if (objc_implementation_context == NULL_TREE)
    {
      error ("@%s property must be in implementation context",
             impl_code == 1 ? "synthesize" : "dynamic");
      return;
    }
  /* APPLE LOCAL end radar 5265608 */
  interface = lookup_interface (CLASS_NAME (objc_implementation_context));
  if (!interface)
    {
      error ("%s property may not be specified in implementation without an interface", 
	     impl_code == 1 ? "synthesize" : "dynamic");
      return;
    }
  class = interface;
  if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
    {
      /* APPLE LOCAL begin radar 5180172 */
      if (impl_code == 1) /* @synthesize */
	error ("@synthesize not allowed in a category's implementation");
      interface = lookup_category (interface,
                                   CLASS_SUPER_NAME (objc_implementation_context));
      if (!interface && (impl_code == 2)) /* @dynamic */
        {
	  error ("@dynamic may not be specified in category without an interface");
          return;
        }
      /* APPLE LOCAL end radar 5180172 */
    }

  if (impl_code == 1 || impl_code == 2)
    {
      for (chain = tree_list; chain; chain = TREE_CHAIN (chain))
	{
	  tree property_name = TREE_VALUE (chain);
	  tree x;
	  if (!property_name)
	    continue;
	  /* APPLE LOCAL begin radar 5040740 */
          /* Look up this property in the @interface declaration or in its superclass(s). */
          x = lookup_nested_property (interface, property_name);
          /* APPLE LOCAL end radar 5040740 */
      	  if (!x)
              error ("no declaration of property %qs found in the interface",
                     IDENTIFIER_POINTER (property_name));
	  else
	    {
	      tree property_decl = copy_node (x);

	      /* APPLE LOCAL radar 5839812 location for synthesized methods  */
	      DECL_SOURCE_LOCATION (property_decl) = input_location;
	      
	      if (impl_code == 2)  /* @dynamic ... */
	        PROPERTY_DYNAMIC (property_decl) = boolean_true_node;
	      else
		{
		  /* @synthesize ... */
		  tree ivar_decl;
		  tree ivar_name = TREE_PURPOSE (chain);
		  /* If 'ivar' unspecified, then an instance variable with same name as 
		     property name must be used. */
		  if (!ivar_name)
		    ivar_name = property_name;
	   	  /* APPLE LOCAL radar 5435299 */
		  PROPERTY_IVAR_NAME (property_decl) = ivar_name;
		  ivar_decl = nested_ivar_lookup (class, ivar_name);
		  /* APPLE LOCAL begin radar 5847641 */
	          if (flag_objc_abi <= 1 && TREE_PURPOSE (chain) && !ivar_decl)
		    warning (0, "ivar name %qs specified on the synthesized property %qs not found",
                    	     IDENTIFIER_POINTER (ivar_name), IDENTIFIER_POINTER (property_name)) ;
		  /* APPLE LOCAL end radar 5847641 */
		  if (ivar_decl)
		    {
		    /* Check for semnatic correctness of the existing ivar. */
		      tree ivar_type = DECL_BIT_FIELD_TYPE (ivar_decl) 
					 ? DECL_BIT_FIELD_TYPE (ivar_decl) 
					 : TREE_TYPE (ivar_decl);
                      /* APPLE LOCAL begin radar 6029624 */
                      tree property_type = TREE_TYPE (property_decl);
		      bool comparison_result;
                      /* APPLE LOCAL begin radar 5435299 */
                      if (flag_new_property_ivar_synthesis && flag_objc_abi == 2 && 
			  !TREE_PURPOSE (chain)) {
                        /* In ObjC2 abi, it is illegal when a @synthesize with no named ivar
                           does not have a matching ivar in its class but some superclass ivar
                           already has the desired name */
                        tree record = CLASS_STATIC_TEMPLATE (class);
                        if (record && record != DECL_CONTEXT (ivar_decl))
                          error ("property %qs attempting to use ivar %qs in super class %qs",
                                 IDENTIFIER_POINTER (property_name),
                                 IDENTIFIER_POINTER (ivar_name),
                                 IDENTIFIER_POINTER (OBJC_TYPE_NAME (record)));
                      }
                      /* APPLE LOCAL end radar 5435299 */
		      /* APPLE LOCAL begin radar 5389292 */
#ifdef OBJCPLUS
                      if (TREE_CODE (property_type) == REFERENCE_TYPE)
			{
		          property_type = TREE_TYPE (property_type);
		          comparison_result = 
                            !objcp_reference_related_p (property_type, ivar_type);
		        }
		      else
#endif
		        comparison_result = comptypes (ivar_type, property_type) != 1;
		      if (comparison_result
			  /* APPLE LOCAL radar 6231433 */
			  && !objc_compare_types (property_type, ivar_type, -5, NULL_TREE, NULL))
                      /* APPLE LOCAL end radar 6029624 */
		      /* APPLE LOCAL end radar 5389292 */
			{
		          error ("type of property %qs does not match type of ivar %qs", 
			         IDENTIFIER_POINTER (property_name), IDENTIFIER_POINTER (ivar_name));
		          PROPERTY_DYNAMIC (property_decl) = boolean_true_node; /* recover */
		        }
		      if (flag_objc_gc)
			{
			  int strong = objc_is_gcable_type (property_type);
			  if (strong)
			    {
		              /* APPLE LOCAL radar 5389292 */
			      int gc_able = objc_is_gcable_type (ivar_type);
			      if (strong != gc_able)
				{
				  if (strong == -1)
	                	    error ("existing ivar %qs for the '__weak' property %qs must be __weak",
		          		   IDENTIFIER_POINTER (ivar_name),
					   IDENTIFIER_POINTER (property_name));
				  else /* strong == 1 */
	                	    error ("existing ivar %qs for a '__strong' property %qs must be garbage collectable",
					   IDENTIFIER_POINTER (ivar_name),
		          		   IDENTIFIER_POINTER (property_name));
				}
			    }
			}
		    }
                  /* APPLE LOCAL begin radar 5435299 - radar 6209554 */
                  else if (flag_new_property_ivar_synthesis)
                         objc_lookup_property_ivar (class, property_decl);
                  if (flag_new_property_ivar_synthesis &&
		      (x = lookup_ivar_in_property_list (objc_implementation_context,
                                                         ivar_name)))
		    {
                      error ("synthesized properties %qs and %qs both claim ivar %qs",
                             IDENTIFIER_POINTER (property_name),
                             IDENTIFIER_POINTER (DECL_NAME (x)),
                             IDENTIFIER_POINTER (ivar_name));
                      error_previous_property_decl (x);
		    }
                  /* APPLE LOCAL end radar 5435299 - radar 6209554 */
		}
              /* APPLE LOCAL begin radar 5435299 - radar 6209554 */
              if (flag_new_property_ivar_synthesis &&
		  (x = lookup_property_impl_in_list (objc_implementation_context, property_name)))
	        {
                  error ("property %qs is already implemented",
                         IDENTIFIER_POINTER (property_name));
		  error_previous_property_decl (x);
		}
              /* APPLE LOCAL end radar 5435299 - radar 6209554 */
	     /* Add the property to the list of properties for current implementation. */
             TREE_CHAIN (property_decl) = IMPL_PROPERTY_DECL (objc_implementation_context);
             IMPL_PROPERTY_DECL (objc_implementation_context) = property_decl;
	    }
	}
    }
  else
    gcc_assert (false);
}
/* APPLE LOCAL end C* language */

/* APPLE LOCAL begin radar 4985544 - 5195402 */
/* Check that TYPE is an "NSString *" type. */
bool
objc_check_nsstring_pointer_type (tree type)
{
  tree NSString_type;

  if (TREE_CODE (type) != POINTER_TYPE)
    return false;
  NSString_type = buildNSStringType();
  if (!NSString_type)
    return false;
  return (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == NSString_type);
}

/* This routine checks that FORMAT_NUM'th argument ARGUMENT has the 'NSString *' type. */
  
bool  
objc_check_format_nsstring (tree argument, 
                            unsigned HOST_WIDE_INT format_num,
                            bool *no_add_attrs)
{ 
  unsigned HOST_WIDE_INT i;
    
  for (i = 1; i != format_num; i++)
    {        
      if (argument == 0)
        break;
       argument = TREE_CHAIN (argument);
    }
  if (!argument || !objc_check_nsstring_pointer_type (TREE_VALUE (argument)))
    {
      error ("format NSString argument not an 'NSString *' type");
      *no_add_attrs = true;
      return false;
    }
  return true;
}
/* APPLE LOCAL end radar 4985544 - 5195402 */

/* APPLE LOCAL begin radar 5202926 */
/* This routine returns 'true' if given NAME is the special objective-c 
   anonymous file-scope static name. It accomodates c++'s mangling of such 
   symbols as a result of radar 5173149. */
bool
objc_anonymous_local_objc_name (const char * name)
{
  const char *p = name;
#ifdef OBJCPLUS
  if (!strncmp (p, "_ZL", 3))
    {
      p += 3;
      while (p && ISDIGIT (*p))
        p++;
    }
#endif
  return p && !strncmp (p, "_OBJC_", 6);
}
/* APPLE LOCAL end radar 5202926 */

/* APPLE LOCAL begin radar 5355344 */
/* Checks that list has nothing but protocols; returns TRUE or FALSE accordingly.
*/

bool
cp_objc_protocol_id_list (tree protocols)
{
  tree proto;
  if (!protocols)
    return false;
  for (proto = protocols; proto; proto = TREE_CHAIN (proto))
    {
      tree ident = TREE_VALUE (proto);
      tree p = lookup_protocol (ident);
      if (!p)
        return false;
    }
  return true;
}
/* APPLE LOCAL end radar 5355344 */
/* APPLE LOCAL begin radar 5376125 */
/* This routine checks for direct access to a pointer to object ivar and issues a warning
   if done so. */
static void
objc_warn_direct_ivar_access (tree basetype, tree component)
{
  while (basetype != NULL_TREE
         && TREE_CODE (basetype) == RECORD_TYPE && OBJC_TYPE_NAME (basetype)
         && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
         && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
    basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
  if (basetype != NULL_TREE && TYPED_OBJECT (basetype))
    {
      tree interface_type = TYPE_OBJC_INTERFACE (basetype);
      if (interface_type &&
          TREE_CODE (interface_type) == CLASS_INTERFACE_TYPE)
        {
          tree ivar = nested_ivar_lookup (interface_type, component);
          if (ivar && managed_objc_object_pointer (TREE_TYPE (ivar)))
            warning (0, "ivar %qs is being directly accessed", IDENTIFIER_POINTER (component));
        }
    }
  return;
}
/* APPLE LOCAL end radar 5376125 */
/* APPLE LOCAL begin radar 5782740 - blocks */
bool block_requires_copying (tree exp)
{
  return TREE_CODE (TREE_TYPE (exp)) == BLOCK_POINTER_TYPE ||
	 objc_is_object_ptr (TREE_TYPE (exp));
}
/* APPLE LOCAL end radar 5782740 - blocks */
#include "gt-objc-objc-act.h"
