/* Implement classes and message passing for Objective C.
   Copyright (C) 1992-2025 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 3, or (at your option)
any later version.

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "stringpool.h"
#include "stor-layout.h"
#include "attribs.h"

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

#include "c-family/c-objc.h"
#include "langhooks.h"
#include "objc-act.h"
#include "objc-map.h"
#include "function.h"
#include "toplev.h"
#include "debug.h"
#include "c-family/c-target.h"
#include "intl.h"
#include "cgraph.h"
#include "tree-iterator.h"
/* Different initialization, code gen and meta data generation for each
   runtime.  */
#include "objc-runtime-hooks.h"
/* Routines used mainly by the runtimes.  */
#include "objc-runtime-shared-support.h"
/* For default_tree_printer ().  */

/* For enum gimplify_status */
#include "gimple-expr.h"
#include "gimplify.h"

/* For encode_method_prototype().  */
#include "objc-encoding.h"

static unsigned int should_call_super_dealloc = 0;

/* 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.  */
/* This has the problem that "test_method:argument:" and
   "test:method_argument:" will generate the same name
   ("_i_Test__test_method_argument_" for an instance method of the
   class "Test"), so you can't have them both in the same class!
   Moreover, the demangling (going from
   "_i_Test__test_method_argument" back to the original name) is
   undefined because there are two correct ways of demangling the
   name.  */
#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

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

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

/* Init stuff.  */
static void synth_module_prologue (void);

/* Code generation.  */

static tree start_class (enum tree_code, tree, tree, tree, tree);
static tree continue_class (tree);
static void finish_class (tree);
static void start_method_def (tree, tree);

static tree start_protocol (enum tree_code, tree, tree, tree);
static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
static tree objc_add_method (tree, tree, int, bool);
static tree add_instance_variable (tree, objc_ivar_visibility_kind, tree);
static tree build_ivar_reference (tree);

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

/* Property.  */
static void objc_gen_property_data (tree, tree);
static void objc_synthesize_getter (tree, tree, tree);
static void objc_synthesize_setter (tree, tree, tree);
static tree lookup_property (tree, tree);
static tree lookup_property_in_list (tree, tree);
static tree lookup_property_in_protocol_list (tree, tree);
static void build_common_objc_property_accessor_helpers (void);

static void objc_xref_basetypes (tree, tree);

static tree get_class_ivars (tree, bool);

static void build_fast_enumeration_state_template (void);

#ifdef OBJCPLUS
static void objc_generate_cxx_cdtors (void);
#endif

/* objc attribute */
static void objc_decl_method_attributes (tree*, tree, int);
static tree build_keyword_selector (tree);

static void hash_init (void);

/* Hash tables to manage the global pool of method prototypes.  Each
   of these maps map a method name (selector) identifier to either a
   single tree (for methods with a single method prototype) or a
   TREE_VEC (for methods with multiple method prototypes).  */
static GTY(()) objc_map_t instance_method_map = 0;
static GTY(()) objc_map_t class_method_map = 0;

/* Hash tables to manage the global pool of class names.  */

static GTY(()) objc_map_t class_name_map = 0;
static GTY(()) objc_map_t alias_name_map = 0;

static tree lookup_method (tree, tree);
static tree lookup_method_static (tree, tree, int);

static void interface_hash_init (void);
static tree add_interface (tree, tree);
static void add_category (tree, tree);

/* Protocols.  */

static tree lookup_protocol (tree, bool, bool);
static tree lookup_and_install_protocols (tree, bool);

#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);
static tree objc_decay_parm_type (tree);

/* Utilities for debugging and error diagnostics.  */

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

static void generate_struct_by_value_array (void) ATTRIBUTE_NORETURN;

static void mark_referenced_methods (void);
static bool objc_type_valid_for_messaging (tree type, bool allow_classes);
static tree check_duplicates (tree, int, int);

/*** Private Interface (data) ***/
/* Flags for lookup_method_static().  */

/* Look for class methods.  */
#define OBJC_LOOKUP_CLASS	1
/* Do not examine superclasses.  */
#define OBJC_LOOKUP_NO_SUPER	2
/* Disable returning an instance method of a root class when a class
   method can't be found.  */
#define OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS 4

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

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

objc_ivar_visibility_kind objc_ivar_visibility, objc_default_ivar_visibility;

/* Use to generate method labels.  */
static int method_slot = 0;

/* Flag to say whether methods in a protocol are optional or
   required.  */
static bool objc_method_optional_flag = false;

static int objc_collecting_ivars = 0;

/* Flag that is set to 'true' while we are processing a class
   extension.  Since a class extension just "reopens" the main
   @interface, this can be used to determine if we are in the main
   @interface, or in a class extension.  */
static bool objc_in_class_extension = false;

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

/* An array of all the local variables in the current function that
   need to be marked as volatile.  */
vec<tree, va_gc> *local_variables_to_volatilize = NULL;

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

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

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

struct objc_string_hasher : ggc_ptr_hash<string_descriptor>
{
  static hashval_t hash (string_descriptor *);
  static bool equal (string_descriptor *, string_descriptor *);
};

static GTY(()) hash_table<objc_string_hasher> *string_htab;

FILE *gen_declaration_file;

/* Hooks for stuff that differs between runtimes.  */
objc_runtime_hooks runtime;

/* Create a temporary variable of type 'type'.  If 'name' is set, uses
   the specified name, else use no name.  Returns the declaration of
   the type.  The 'name' is mostly useful for debugging.
*/
tree
objc_create_temporary_var (tree type, const char *name)
{
  tree decl;

  if (name != NULL)
    {
      decl = build_decl (input_location,
			 VAR_DECL, get_identifier (name), type);
    }
  else
    {
      decl = build_decl (input_location,
			 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;
}

/* 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 decls;
  int i, j;
  int aggregate_in_mem[32];
  int found = 0;

  /* Presumably no platform passes 32 byte structures in a register.  */
  /* ??? As an example, m64/ppc/Darwin can pass up to 8*long+13*double
     in registers.  */
  for (i = 1; i < 32; i++)
    {
      char buffer[5];
      tree *chain = NULL;

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

      strcpy (buffer, "c1");
      decls = add_field_decl (char_type_node, buffer, &chain);

      for (j = 1; j < i; j++)
	{
	  sprintf (buffer, "c%d", j + 1);
	  add_field_decl (char_type_node, buffer, &chain);
	}
      objc_finish_struct (type, decls);

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

  exit (0);
}

bool
objc_init (void)
{
  bool ok;

  /* Set up stuff used by the preprocessor as well as FE parser.  */
  interface_hash_init ();
  hash_init ();

#ifdef OBJCPLUS
  if (cxx_init () == false)
#else
  if (c_objc_common_init () == false)
#endif
    return false;

  /* print_struct_values is triggered by -print-runtime-info (used
     when building libobjc, with an empty file as input).  It does not
     require any ObjC setup, and it never returns.

     -fcompare-debug is used to check the compiler output; we are
     executed twice, once with flag_compare_debug set, and once with
     it not set.  If the flag is used together with
     -print-runtime-info, we want to print the runtime info only once,
     else it would be output in duplicate.  So we check
     flag_compare_debug to output it in only one of the invocations.

     As a side effect, this also that means -fcompare-debug
     -print-runtime-info will run the compiler twice, and compare the
     generated assembler file; the first time the compiler exits
     immediately (producing no file), and the second time it compiles
     an empty file.  This checks, as a side effect, that compiling an
     empty file produces no assembler output.  */
  if (print_struct_values && !flag_compare_debug)
    generate_struct_by_value_array ();

  /* Set up stuff used by FE parser and all runtimes.  */
  errbuf = XNEWVEC (char, 1024 * 10);
  objc_encoding_init ();
  /* ... and then check flags and set-up for the selected runtime ... */
  if (flag_next_runtime && flag_objc_abi >= 2)
    ok = objc_next_runtime_abi_02_init (&runtime);
  else if (flag_next_runtime)
    ok = objc_next_runtime_abi_01_init (&runtime);
  else
    ok = objc_gnu_runtime_abi_01_init (&runtime);

  /* If that part of the setup failed - bail out immediately.  */
  if (!ok)
    return false;

  /* Determine the default visibility for instance variables. */
  switch (default_ivar_visibility)
    {
    case IVAR_VISIBILITY_PRIVATE:
        objc_default_ivar_visibility = OBJC_IVAR_VIS_PRIVATE;
        break;
    case IVAR_VISIBILITY_PUBLIC:
        objc_default_ivar_visibility = OBJC_IVAR_VIS_PUBLIC;
        break;
    case IVAR_VISIBILITY_PACKAGE:
        objc_default_ivar_visibility = OBJC_IVAR_VIS_PACKAGE;
        break;
    default:
        objc_default_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
    }

  /* Generate general types and push runtime-specific decls to file scope.  */
  synth_module_prologue ();

  return true;
}

/* This is called at the end of parsing by the C/C++ parsers.  */
void
objc_write_global_declarations (void)
{
  mark_referenced_methods ();

  /* A missing @end might 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;
    }

  if (warn_selector)
    {
      objc_map_iterator_t i;

      objc_map_iterator_initialize (class_method_map, &i);
      while (objc_map_iterator_move_to_next (class_method_map, &i))
	check_duplicates (objc_map_iterator_current_value (class_method_map, i), 0, 1);

      objc_map_iterator_initialize (instance_method_map, &i);
      while (objc_map_iterator_move_to_next (instance_method_map, &i))
	check_duplicates (objc_map_iterator_current_value (instance_method_map, i), 0, 0);
    }

  /* TODO: consider an early exit here if either errorcount or sorrycount
     is non-zero.  Not only is it wasting time to generate the metadata,
     it needlessly imposes need to re-check for things that are already
     determined to be errors.  */

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

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

      /* Set the input location to BUILTINS_LOCATION.  This is good
	 for error messages, in case any is generated while producing
	 the metadata, but it also silences warnings that would be
	 produced when compiling with -Wpadded in case when padding is
	 automatically added to the built-in runtime data structure
	 declarations.  We know about this padding, and it is fine; we
	 don't want users to see any warnings about it if they use
	 -Wpadded.  */
      saved_location = input_location;
      input_location = BUILTINS_LOCATION;

      /* Compute and emit the meta-data tables for this runtime.  */
      (*runtime.generate_metadata) ();

      /* Restore the original location, just in case it mattered.  */
      input_location = saved_location;

      /* ... and then close any declaration file we opened.  */
      if (gen_declaration_file)
	fclose (gen_declaration_file);
    }
}

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

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

	if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
	  {
	    /* First, search the @required protocol methods.  */
	    if (is_class)
	      m = lookup_method (PROTOCOL_CLS_METHODS (p),  sel_name);
	    else
	      m = lookup_method (PROTOCOL_NST_METHODS (p), sel_name);

	    if (m)
	      return m;

	    /* If still not found, search the @optional protocol methods.  */
	    if (is_class)
	      m = lookup_method (PROTOCOL_OPTIONAL_CLS_METHODS (p), sel_name);
	    else
	      m = lookup_method (PROTOCOL_OPTIONAL_NST_METHODS (p), sel_name);

	    if (m)
	      return m;

	    /* If still not found, search the attached protocols.  */
	    if (PROTOCOL_LIST (p))
	      m = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
						  sel_name, is_class);
	    if (m)
	      return m;
	  }
	else
          {
	    ; /* An identifier...if we could not find a protocol.  */
          }
     }

   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
objc_start_class_interface (tree klass, location_t name_loc, tree super_class,
			    tree protos, tree attributes)
{
  if (flag_objc1_only && attributes)
    error_at (name_loc, "class attributes are not available in Objective-C 1.0");

  objc_interface_context
    = objc_ivar_context
    = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos, attributes);
  objc_ivar_visibility = objc_default_ivar_visibility;
}

void
objc_start_category_interface (tree klass, tree categ,
			       tree protos, tree attributes)
{
  if (attributes)
    {
      if (flag_objc1_only)
	error_at (input_location, "category attributes are not available in Objective-C 1.0");
      else
	warning_at (input_location, OPT_Wattributes,
		    "category attributes are not available in this version"
		    " of the compiler, (ignored)");
    }
  if (categ == NULL_TREE)
    {
      if (flag_objc1_only)
	error_at (input_location, "class extensions are not available in Objective-C 1.0");
      else
	{
	  /* Iterate over all the classes and categories implemented
	     up to now in this compilation unit.  */
	  struct imp_entry *t;

	  for (t = imp_list; t; t = t->next)
	    {
	      /* If we find a class @implementation with the same name
		 as the one we are extending, produce an error.  */
	    if (TREE_CODE (t->imp_context) == CLASS_IMPLEMENTATION_TYPE
		&& IDENTIFIER_POINTER (CLASS_NAME (t->imp_context)) == IDENTIFIER_POINTER (klass))
	      error_at (input_location,
			"class extension for class %qE declared after its %<@implementation%>",
			klass);
	    }
	}
    }
  objc_interface_context
    = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos, NULL_TREE);
  objc_ivar_chain
    = continue_class (objc_interface_context);
}

void
objc_start_protocol (tree name, tree protos, tree attributes)
{
  if (flag_objc1_only && attributes)
    error_at (input_location, "protocol attributes are not available in Objective-C 1.0");

  objc_interface_context
    = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos, attributes);
  objc_method_optional_flag = false;
}

void
objc_continue_interface (void)
{
  objc_ivar_chain
    = continue_class (objc_interface_context);
}

void
objc_finish_interface (void)
{
  finish_class (objc_interface_context);
  objc_interface_context = NULL_TREE;
  objc_method_optional_flag = false;
  objc_in_class_extension = false;
}

void
objc_start_class_implementation (tree klass, tree super_class)
{
  objc_implementation_context
    = objc_ivar_context
    = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE,
		   NULL_TREE);
  objc_ivar_visibility = objc_default_ivar_visibility;
}

void
objc_start_category_implementation (tree klass, tree categ)
{
  objc_implementation_context
    = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE,
		   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 (objc_ivar_visibility_kind visibility)
{
  if (visibility == OBJC_IVAR_VIS_PACKAGE)
    {
      if (flag_objc1_only)
	error ("%<@package%> is not available in Objective-C 1.0");
      else
	warning (0, "%<@package%> presently has the same effect as %<@public%>");
    }
  objc_ivar_visibility = visibility;
}

void
objc_set_method_opt (bool optional)
{
  if (flag_objc1_only)
    {
      if (optional)
	error_at (input_location, "%<@optional%> is not available in Objective-C 1.0");
      else
	error_at (input_location, "%<@required%> is not available in Objective-C 1.0");
    }

  objc_method_optional_flag = optional;
  if (!objc_interface_context
      || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
    {
      if (optional)
	error ("%<@optional%> is allowed in @protocol context only");
      else
	error ("%<@required%> is allowed in @protocol context only");
      objc_method_optional_flag = false;
    }
}

/* 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))
	    return lookup_property_in_protocol_list (PROTOCOL_LIST (p), property);
	}
      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 ((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;

	  /* When checking a category, also check the protocols
	     attached with the category itself.  */
	  if (CLASS_PROTOCOL_LIST (category)
	      && (x = lookup_property_in_protocol_list
		  (CLASS_PROTOCOL_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;
}

/* This routine returns a PROPERTY_KIND for the front end RID code supplied.  */

enum objc_property_attribute_kind
objc_prop_attr_kind_for_rid (enum rid prop_rid)
{
  switch (prop_rid)
    {
      default:			return OBJC_PROPERTY_ATTR_UNKNOWN;
      case RID_GETTER:		return OBJC_PROPERTY_ATTR_GETTER;
      case RID_SETTER:		return OBJC_PROPERTY_ATTR_SETTER;

      case RID_READONLY:	return OBJC_PROPERTY_ATTR_READONLY;
      case RID_READWRITE:	return OBJC_PROPERTY_ATTR_READWRITE;

      case RID_ASSIGN:		return OBJC_PROPERTY_ATTR_ASSIGN;
      case RID_RETAIN:		return OBJC_PROPERTY_ATTR_RETAIN;
      case RID_COPY:		return OBJC_PROPERTY_ATTR_COPY;

      case RID_PROPATOMIC:	return OBJC_PROPERTY_ATTR_ATOMIC;
      case RID_NONATOMIC:	return OBJC_PROPERTY_ATTR_NONATOMIC;

      case RID_NULL_UNSPECIFIED:return OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED;
      case RID_NULLABLE:	return OBJC_PROPERTY_ATTR_NULLABLE;
      case RID_NONNULL:		return OBJC_PROPERTY_ATTR_NONNULL;
      case RID_NULL_RESETTABLE:	return OBJC_PROPERTY_ATTR_NULL_RESETTABLE;

      case RID_CLASS:		return OBJC_PROPERTY_ATTR_CLASS;
    }
}

/* This routine is called by the parser when a
   @property... declaration is found.  'decl' is the declaration of
   the property (type/identifier), and the other arguments represent
   property attributes that may have been specified in the Objective-C
   declaration.  'parsed_property_readonly' is 'true' if the attribute
   'readonly' was specified, and 'false' if not; similarly for the
   other bool parameters.  'property_getter_ident' is NULL_TREE
   if the attribute 'getter' was not specified, and is the identifier
   corresponding to the specified getter if it was; similarly for
   'property_setter_ident'.  */
void
objc_add_property_declaration (location_t location, tree decl,
			       vec<property_attribute_info *>& prop_attr_list)
{
  if (flag_objc1_only)
    /* FIXME: we probably ought to bail out at this point.  */
    error_at (location, "%<@property%> is not available in Objective-C 1.0");

  /* We must be in an interface, category, or protocol.  */
  if (!objc_interface_context)
    {
      error_at (location, "property declaration not in %<@interface%>,"
			  " %<@protocol%> or %<category%> context");
      return;
    }

  /* Do some spot-checks for the most obvious invalid cases.  */

  gcc_checking_assert (decl && TREE_CODE (decl) == FIELD_DECL);

  if (decl && !DECL_NAME (decl))
    {
      error_at (location, "properties must be named");
      return;
    }

  location_t decl_loc = DECL_SOURCE_LOCATION (decl);
  decl_loc = make_location (decl_loc, location, decl_loc);
  if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    {
      error_at (decl_loc, "property cannot be an array");
      return;
    }

  if (DECL_C_BIT_FIELD (decl))
    {
      /* A @property is not an actual variable, but it is a way to
	 describe a pair of accessor methods, so its type (which is
	 the type of the return value of the getter and the first
	 argument of the setter) can't be a bitfield (as return values
	 and arguments of functions cannot be bitfields).  The
	 underlying instance variable could be a bitfield, but that is
	 a different matter.  */
      error_at (decl_loc, "property cannot be a bit-field");
      return;
    }

  /* The final results of parsing the (growing number) of property
     attributes.  */
  property_attribute_info *attrs[OBJC_PROPATTR_GROUP_MAX] = { nullptr };

  tree property_getter_ident = NULL_TREE;
  tree property_setter_ident = NULL_TREE;
  for (unsigned pn = 0; pn < prop_attr_list.length (); ++pn)
    {
      if (prop_attr_list[pn]->parse_error)
	continue; /* Ignore attributes known to be wrongly parsed.  */

      switch (int g = (int) prop_attr_list[pn]->group())
	{
	case OBJC_PROPATTR_GROUP_UNKNOWN:
	  continue;
	case OBJC_PROPATTR_GROUP_SETTER:
	case OBJC_PROPATTR_GROUP_GETTER:
	  if (attrs[g])
	    {
	      warning_at (prop_attr_list[pn]->prop_loc, OPT_Wattributes,
			  "multiple property %qE methods specified, the latest"
			  " one will be used", attrs[g]->name);
	      inform (attrs[g]->prop_loc, "previous specification");
	    }
	  attrs[g] = prop_attr_list[pn];
	  if (g == OBJC_PROPATTR_GROUP_SETTER)
	    property_setter_ident = attrs[g]->ident;
	  else
	    property_getter_ident = attrs[g]->ident;
	  continue;
	default:
	  {
	    if (!attrs[g])
	      ;
	    else if (attrs[g]->prop_kind != prop_attr_list[pn]->prop_kind)
	      {
		error_at (prop_attr_list[pn]->prop_loc,
			  "%qE attribute conflicts with %qE attribute",
			  prop_attr_list[pn]->name, attrs[g]->name);
		inform (attrs[g]->prop_loc, "%qE specified here",
			attrs[g]->name );
	      }
	    else
	      {
		warning_at (prop_attr_list[pn]->prop_loc, OPT_Wattributes,
			    "duplicate %qE attribute", attrs[g]->name);
		inform (attrs[g]->prop_loc, "first specified here");
	      }
	    attrs[g] = prop_attr_list[pn];
	  }
	  continue;
	}
    }

  /* The defaults for atomicity (atomic) and write-ability (readwrite) apply
     even if the user provides no specified attributes.  */
  bool property_nonatomic = false;
  bool property_readonly = false;

  /* Set the values from any specified by the user; these are easy, only two
     states.  */
  if (attrs[OBJC_PROPATTR_GROUP_ATOMIC])
    property_nonatomic = attrs[OBJC_PROPATTR_GROUP_ATOMIC]->prop_kind
			 == OBJC_PROPERTY_ATTR_NONATOMIC;

  if (attrs[OBJC_PROPATTR_GROUP_READWRITE])
    property_readonly = attrs[OBJC_PROPATTR_GROUP_READWRITE]->prop_kind
			 == OBJC_PROPERTY_ATTR_READONLY;

  /* One can't set a readonly value; we issue an error, but force the property
     to readwrite as well.  */
  if (property_readonly && property_setter_ident)
    {
      error_at (attrs[OBJC_PROPATTR_GROUP_READWRITE]->prop_loc, "%<readonly%>"
		" attribute conflicts with %<setter%> attribute");
      gcc_checking_assert (attrs[OBJC_PROPATTR_GROUP_SETTER]);
      inform (attrs[OBJC_PROPATTR_GROUP_SETTER]->prop_loc, "%<setter%>"
	      " specified here");
      property_readonly = false;
    }

  /* Assign semantics is a tri-state property, and also needs some further
     checking against the object type.  */
  objc_property_assign_semantics property_assign_semantics
    = OBJC_PROPERTY_ASSIGN;

  if (attrs[OBJC_PROPATTR_GROUP_ASSIGN])
    {
      if (attrs[OBJC_PROPATTR_GROUP_ASSIGN]->prop_kind
	  == OBJC_PROPERTY_ATTR_ASSIGN)
	property_assign_semantics = OBJC_PROPERTY_ASSIGN;
      else if (attrs[OBJC_PROPATTR_GROUP_ASSIGN]->prop_kind
	       == OBJC_PROPERTY_ATTR_RETAIN)
	property_assign_semantics = OBJC_PROPERTY_RETAIN;
      else if (attrs[OBJC_PROPATTR_GROUP_ASSIGN]->prop_kind
	       == OBJC_PROPERTY_ATTR_COPY)
	property_assign_semantics = OBJC_PROPERTY_COPY;
      else
	gcc_unreachable ();
    }

  /* An attribute that indicates this property manipulates a class variable.
     In this case, both the variable and the getter/setter must be provided
     by the user.  */
  bool property_class = false;
  if (attrs[OBJC_PROPATTR_GROUP_CLASS])
    property_nonatomic = attrs[OBJC_PROPATTR_GROUP_CLASS]->prop_kind
			 == OBJC_PROPERTY_ATTR_CLASS;

  /* Nullability specifications for the property.  */
  enum objc_property_nullability property_nullability
    =  OBJC_PROPERTY_NULL_UNSET;
  if (attrs[OBJC_PROPATTR_GROUP_NULLABLE])
    {
      if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
	  == OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED)
	property_nullability = OBJC_PROPERTY_NULL_UNSPECIFIED;
      else if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
	  == OBJC_PROPERTY_ATTR_NULLABLE)
	property_nullability = OBJC_PROPERTY_NULLABLE;
      else if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
	  == OBJC_PROPERTY_ATTR_NONNULL)
	property_nullability = OBJC_PROPERTY_NONNULL;
      else if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
	  == OBJC_PROPERTY_ATTR_NULL_RESETTABLE)
	property_nullability = OBJC_PROPERTY_NULL_RESETTABLE;
      else
	gcc_unreachable ();
    }

  /* TODO: Check that the property type is an Objective-C object or a
     "POD".  */

  /* Implement -Wproperty-assign-default (which is enabled by default).  */
  if (warn_property_assign_default
      /* If garbage collection is not being used, then 'assign' is
	 valid for objects (and typically used for delegates) but it
	 is wrong in most cases (since most objects need to be
	 retained or copied in setters).  Warn users when 'assign' is
	 used implicitly.  */
      && property_assign_semantics == OBJC_PROPERTY_ASSIGN
      /* Read-only properties are never assigned, so the assignment
	 semantics do not matter in that case.  */
      && !property_readonly
      && !flag_objc_gc)
    {
      /* Please note that it would make sense to default to 'assign'
	 for non-{Objective-C objects}, and to 'retain' for
	 Objective-C objects.  But that would break compatibility with
	 other compilers.  */
      if (!attrs[OBJC_PROPATTR_GROUP_ASSIGN])
	{
	  /* Use 'false' so we do not warn for Class objects.  */
	  if (objc_type_valid_for_messaging (TREE_TYPE (decl), false))
	    {
	      warning_at (decl_loc, 0, "object property %qD has no %<assign%>,"
			  " %<retain%> or %<copy%> attribute; assuming"
			  " %<assign%>", decl);
	      inform (decl_loc, "%<assign%> can be unsafe for Objective-C"
		      " objects; please state explicitly if you need it");
	    }
	}
    }

  /* Some attributes make no sense unless applied to an Objective-C object.  */
  bool prop_objc_object_p
    = objc_type_valid_for_messaging (TREE_TYPE (decl), true);
  if (!prop_objc_object_p)
    {
      tree p_name = NULL_TREE;
      if (property_assign_semantics == OBJC_PROPERTY_RETAIN
	  || property_assign_semantics == OBJC_PROPERTY_COPY)
	p_name = attrs[OBJC_PROPATTR_GROUP_ASSIGN]->name;

      if (p_name)
	error_at (decl_loc, "%qE attribute is only valid for Objective-C"
		  " objects", p_name);
    }

  /* Now determine the final property getter and setter names.  They
     will be stored in the PROPERTY_DECL, from which they'll always be
     extracted and used.  */

  /* Adjust, or fill in, setter and getter names.  We overwrite the
     property_setter_ident and property_getter_ident
     with the final setter and getter identifiers that will be
     used.  */
  if (property_setter_ident)
    {
      /* The setter should be terminated by ':', but the parser only
	 gives us an identifier without ':'.  So, we need to add ':'
	 at the end.  */
      const char *parsed_setter = IDENTIFIER_POINTER (property_setter_ident);
      size_t length = strlen (parsed_setter);
      char *final_setter = (char *)alloca (length + 2);

      sprintf (final_setter, "%s:", parsed_setter);
      property_setter_ident = get_identifier (final_setter);
    }
  else
    {
      if (!property_readonly)
	property_setter_ident = get_identifier (objc_build_property_setter_name
						       (DECL_NAME (decl)));
    }

  if (!property_getter_ident)
    property_getter_ident = DECL_NAME (decl);

  /* Check for duplicate property declarations.  We first check the
     immediate context for a property with the same name.  Any such
     declarations are an error, unless this is a class extension and
     we are extending a property from readonly to readwrite.  */
  bool property_extension_in_class_extension = false;
  tree x = NULL_TREE;
  for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
    {
      if (PROPERTY_NAME (x) == DECL_NAME (decl))
	{
	  if (objc_in_class_extension
	      && !property_readonly
	      && PROPERTY_READONLY (x) == 1)
	    {
	      /* This is a class extension, and we are extending an
		 existing readonly property to a readwrite one.
		 That's fine.  :-) */
	      property_extension_in_class_extension = true;
	      break;
	    }
	  else
	    {
	      location_t original_location = DECL_SOURCE_LOCATION (x);

	      error_at (location, "redeclaration of property %qD", decl);

	      if (original_location != UNKNOWN_LOCATION)
		inform (original_location, "originally specified here");
	      return;
	    }
	}
    }

  /* If x is not NULL_TREE, we must be in a class extension and we're
     extending a readonly property.  In that case, no point in
     searching for another declaration.  */
  if (x == NULL_TREE)
    {
      /* We now need to check for existing property declarations (in
	 the superclass, other categories or protocols) and check that
	 the new declaration is not in conflict with existing
	 ones.  */

      /* Search for a previous, existing declaration of a property
	 with the same name in superclasses, protocols etc.  If one is
	 found, it will be in the 'x' variable.  */

      /* Note that, for simplicity, the following may search again the
	 local context.  That's Ok as nothing will be found (else we'd
	 have thrown an error above); it's only a little inefficient,
	 but the code is simpler.  */
      switch (TREE_CODE (objc_interface_context))
	{
	case CLASS_INTERFACE_TYPE:
	  /* Look up the property in the current @interface (which
	     will find nothing), then its protocols and categories and
	     superclasses.  */
	  x = lookup_property (objc_interface_context, DECL_NAME (decl));
	  break;
	case CATEGORY_INTERFACE_TYPE:
	  /* Look up the property in the main @interface, then
	     protocols and categories (one of them is ours, and will
	     find nothing) and superclasses.  */
	  x = lookup_property (lookup_interface (CLASS_NAME (objc_interface_context)),
			       DECL_NAME (decl));
	  break;
	case PROTOCOL_INTERFACE_TYPE:
	  /* Looks up the property in any protocols attached to the
	     current protocol.  */
	  if (PROTOCOL_LIST (objc_interface_context))
	    {
	      x = lookup_property_in_protocol_list (PROTOCOL_LIST (objc_interface_context),
						    DECL_NAME (decl));
	    }
	  break;
	default:
	  gcc_unreachable ();
	}
    }

  if (x != NULL_TREE)
    {
      /* An existing property was found; check that it has the same
	 types, or it is compatible.  */
      location_t original_location = DECL_SOURCE_LOCATION (x);

      if (PROPERTY_NONATOMIC (x) != property_nonatomic)
	{
	  warning_at (location, 0,
		      "%<nonatomic%> attribute of property %qD conflicts with "
		      "previous declaration", decl);

	  if (original_location != UNKNOWN_LOCATION)
	    inform (original_location, "originally specified here");
	  return;
	}

      if (PROPERTY_GETTER_NAME (x) != property_getter_ident)
	{
	  warning_at (location, 0,
		      "%<getter%> attribute of property %qD conflicts with "
		      "previous declaration", decl);

	  if (original_location != UNKNOWN_LOCATION)
	    inform (original_location, "originally specified here");
	  return;
	}

      /* We can only compare the setter names if both the old and new property have a setter.  */
      if (!property_readonly  &&  !PROPERTY_READONLY(x))
	{
	  if (PROPERTY_SETTER_NAME (x) != property_setter_ident)
	    {
	      warning_at (location, 0,
			  "%<setter%> attribute of property %qD conflicts with "
			  "previous declaration", decl);

	      if (original_location != UNKNOWN_LOCATION)
		inform (original_location, "originally specified here");
	      return;
	    }
	}

      if (PROPERTY_ASSIGN_SEMANTICS (x) != property_assign_semantics)
	{
	  warning_at (location, 0,
		      "assign semantics attributes of property %qD conflict with previous declaration", decl);

	  if (original_location != UNKNOWN_LOCATION)
	    inform (original_location, "originally specified here");
	  return;
	}

      /* It's ok to have a readonly property that becomes a readwrite, but not vice versa.  */
      if (PROPERTY_READONLY (x) == 0  &&  property_readonly == 1)
	{
	  warning_at (location, 0,
		      "%<readonly%> attribute of property %qD conflicts with "
		      "previous declaration", decl);

	  if (original_location != UNKNOWN_LOCATION)
	    inform (original_location, "originally specified here");
	  return;
	}

      /* We now check that the new and old property declarations have
	 the same types (or compatible one).  In the Objective-C
	 tradition of loose type checking, we do type-checking but
	 only generate warnings (not errors) if they do not match.
	 For non-readonly properties, the types must match exactly;
	 for readonly properties, it is allowed to use a "more
	 specialized" type in the new property declaration.  Eg, the
	 superclass has a getter returning (NSArray *) and the
	 subclass a getter returning (NSMutableArray *).  The object's
	 getter returns an (NSMutableArray *); but if you cast the
	 object to the superclass, which is allowed, you'd still
	 expect the getter to return an (NSArray *), which works since
	 an (NSMutableArray *) is an (NSArray *) too.  So, the set of
	 objects belonging to the type of the new @property should be
	 a subset of the set of objects belonging to the type of the
	 old @property.  This is what "specialization" means.  And the
	 reason it only applies to readonly properties is that for a
	 readwrite property the setter would have the opposite
	 requirement - ie that the superclass type is more specialized
	 then the subclass one; hence the only way to satisfy both
	 constraints is that the types match.  */

      /* If the types are not the same in the C sense, we warn ...  */
      if (!comptypes (TREE_TYPE (x), TREE_TYPE (decl))
	  /* ... unless the property is readonly, in which case we
	     allow a new, more specialized, declaration.  */
	  && (!property_readonly
	      || !objc_compare_types (TREE_TYPE (x),
				      TREE_TYPE (decl), -5, NULL_TREE)))
	{
	  warning_at (location, 0,
		      "type of property %qD conflicts with previous declaration", decl);
	  if (original_location != UNKNOWN_LOCATION)
	    inform (original_location, "originally specified here");
	  return;
	}

      /* If we are in a class extension and we're extending a readonly
	 property in the main @interface, we'll just update the
	 existing property with the readwrite flag and potentially the
	 new setter name.  */
      if (property_extension_in_class_extension)
	{
	  PROPERTY_READONLY (x) = 0;
	  PROPERTY_SETTER_NAME (x) = property_setter_ident;
	  return;
	}
    }

  /* Create a PROPERTY_DECL node.  */
  tree property_decl = make_node (PROPERTY_DECL);

  /* Copy the basic information from the original decl.  */
  tree p_type = TREE_TYPE (decl);
  TREE_TYPE (property_decl) = p_type;
  DECL_SOURCE_LOCATION (property_decl) = DECL_SOURCE_LOCATION (decl);
  TREE_DEPRECATED (property_decl) = TREE_DEPRECATED (decl);
  TREE_UNAVAILABLE (property_decl) = TREE_UNAVAILABLE (decl);

  /* Add property-specific information.  */
  PROPERTY_NAME (property_decl) = DECL_NAME (decl);
  PROPERTY_GETTER_NAME (property_decl) = property_getter_ident;
  PROPERTY_SETTER_NAME (property_decl) = property_setter_ident;
  PROPERTY_READONLY (property_decl) = property_readonly;
  PROPERTY_NONATOMIC (property_decl) = property_nonatomic;
  PROPERTY_CLASS (property_decl) = property_class;
  PROPERTY_ASSIGN_SEMANTICS (property_decl) = property_assign_semantics;
  PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
  PROPERTY_DYNAMIC (property_decl) = 0;

  /* FIXME: We seem to drop any existing DECL_ATTRIBUTES on the floor.  */
  if (property_nullability != OBJC_PROPERTY_NULL_UNSET)
    {
      if (p_type && !POINTER_TYPE_P (p_type))
	error_at (decl_loc, "nullability specifier %qE cannot be applied to"
		  " non-pointer type %qT",
		  attrs[OBJC_PROPATTR_GROUP_NULLABLE]->name, p_type);
      else if (p_type && POINTER_TYPE_P (p_type) && TREE_TYPE (p_type)
	       && POINTER_TYPE_P (TREE_TYPE (p_type)))
	error_at (decl_loc, "nullability specifier %qE cannot be applied to"
		  " multi-level pointer type %qT",
		  attrs[OBJC_PROPATTR_GROUP_NULLABLE]->name, p_type);
      else
	{
	  tree attr_name = get_identifier ("objc_nullability");
	  tree attr_value = build_int_cst (unsigned_type_node,
				       (unsigned)property_nullability);
	  tree nulla = build_tree_list (attr_name, attr_value);
	  DECL_ATTRIBUTES (property_decl) = nulla;
	}
    }

  /* Remember the fact that the property was found in the @optional
     section in a @protocol, or not.  */
  if (objc_method_optional_flag)
    PROPERTY_OPTIONAL (property_decl) = 1;
  else
    PROPERTY_OPTIONAL (property_decl) = 0;

  /* Note that PROPERTY_GETTER_NAME is always set for all
     PROPERTY_DECLs, and PROPERTY_SETTER_NAME is always set for all
     PROPERTY_DECLs where PROPERTY_READONLY == 0.  Any time we deal
     with a getter or setter, we should get the PROPERTY_DECL and use
     PROPERTY_GETTER_NAME and PROPERTY_SETTER_NAME to know the correct
     names.  */

  /* Add the PROPERTY_DECL to the list of properties for the class.  */
  TREE_CHAIN (property_decl) = CLASS_PROPERTY_DECL (objc_interface_context);
  CLASS_PROPERTY_DECL (objc_interface_context) = property_decl;
}

/* This is a subroutine of objc_maybe_build_component_ref.  Search the
   list of methods in the interface (and, failing that, the local list
   in the implementation, and failing that, the protocol list)
   provided for a 'setter' or 'getter' for 'component' with default
   names (ie, if 'component' is "name", then search for "name" and
   "setName:").  It is also possible to specify a different
   'getter_name' (this is used for @optional readonly properties).  If
   any is found, then create an artificial property that uses them.
   Return NULL_TREE if 'getter' or 'setter' could not be found.  */
static tree
maybe_make_artificial_property_decl (tree interface, tree implementation,
				     tree protocol_list, tree component, bool is_class,
				     tree getter_name)
{
  tree setter_name = get_identifier (objc_build_property_setter_name (component));
  tree getter = NULL_TREE;
  tree setter = NULL_TREE;

  if (getter_name == NULL_TREE)
    getter_name = component;

  /* First, check the @interface and all superclasses.  */
  if (interface)
    {
      int flags = 0;

      /* Using instance methods of the root class as accessors is most
	 likely unwanted and can be extremely confusing (and, most
	 importantly, other Objective-C 2.0 compilers do not do it).
	 Turn it off.  */
      if (is_class)
	flags = OBJC_LOOKUP_CLASS | OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS;

      getter = lookup_method_static (interface, getter_name, flags);
      setter = lookup_method_static (interface, setter_name, flags);
    }

  /* Second, check the local @implementation context.  */
  if (!getter && !setter)
    {
      if (implementation)
	{
	  if (is_class)
	    {
	      getter = lookup_method (CLASS_CLS_METHODS (implementation), getter_name);
	      setter = lookup_method (CLASS_CLS_METHODS (implementation), setter_name);
	    }
	  else
	    {
	      getter = lookup_method (CLASS_NST_METHODS (implementation), getter_name);
	      setter = lookup_method (CLASS_NST_METHODS (implementation), setter_name);
	    }
	}
    }

  /* Try the protocol_list if we didn't find anything in the
     @interface and in the @implementation.  */
  if (!getter && !setter)
    {
      getter = lookup_method_in_protocol_list (protocol_list, getter_name, is_class);
      setter = lookup_method_in_protocol_list (protocol_list, setter_name, is_class);
    }

  /* There needs to be at least a getter or setter for this to be a
     valid 'object.component' syntax.  */
  if (getter || setter)
    {
      /* Yes ... determine the type of the expression.  */
      tree property_decl;
      tree type;

      if (getter)
	type = TREE_VALUE (TREE_TYPE (getter));
      else
	type = TREE_VALUE (TREE_TYPE (METHOD_SEL_ARGS (setter)));

      /* Create an artificial property declaration with the
	 information we collected on the type and getter/setter
	 names.  */
      property_decl = make_node (PROPERTY_DECL);

      TREE_TYPE (property_decl) = type;
      DECL_SOURCE_LOCATION (property_decl) = input_location;
      TREE_DEPRECATED (property_decl) = 0;
      TREE_UNAVAILABLE (property_decl) = 0;
      DECL_ARTIFICIAL (property_decl) = 1;

      /* Add property-specific information.  Note that one of
	 PROPERTY_GETTER_NAME or PROPERTY_SETTER_NAME may refer to a
	 non-existing method; this will generate an error when the
	 expression is later compiled.  At this stage we don't know if
	 the getter or setter will be used, so we can't generate an
	 error.  */
      PROPERTY_NAME (property_decl) = component;
      PROPERTY_GETTER_NAME (property_decl) = getter_name;
      PROPERTY_SETTER_NAME (property_decl) = setter_name;
      PROPERTY_READONLY (property_decl) = 0;
      PROPERTY_NONATOMIC (property_decl) = 0;
      PROPERTY_ASSIGN_SEMANTICS (property_decl) = 0;
      PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
      PROPERTY_DYNAMIC (property_decl) = 0;
      PROPERTY_OPTIONAL (property_decl) = 0;

      if (!getter)
	PROPERTY_HAS_NO_GETTER (property_decl) = 1;

      /* The following is currently unused, but it's nice to have
	 there.  We may use it if we need in the future.  */
      if (!setter)
	PROPERTY_HAS_NO_SETTER (property_decl) = 1;

      return property_decl;
    }

  return NULL_TREE;
}

/* This hook routine is invoked by the parser when an expression such
   as 'xxx.yyy' is parsed.  We get a chance to process these
   expressions in a way that is specified to Objective-C (to implement
   the Objective-C 2.0 dot-syntax, properties, or non-fragile ivars).
   If the expression is not an Objective-C specified expression, we
   should return NULL_TREE; else we return the expression.

   At the moment this only implements dot-syntax and properties (not
   non-fragile ivars yet), ie 'object.property' or 'object.component'
   where 'component' is not a declared property, but a valid getter or
   setter for it could be found.  */
tree
objc_maybe_build_component_ref (tree object, tree property_ident)
{
  tree x = NULL_TREE;
  tree rtype;

  /* If we are in Objective-C 1.0 mode, dot-syntax and properties are
     not available.  */
  if (flag_objc1_only)
    return NULL_TREE;

  /* Try to determine if 'object' is an Objective-C object or not.  If
     not, return.  */
  if (object == NULL_TREE || object == error_mark_node
      || (rtype = TREE_TYPE (object)) == NULL_TREE)
    return NULL_TREE;

  if (property_ident == NULL_TREE || property_ident == error_mark_node
      || TREE_CODE (property_ident) != IDENTIFIER_NODE)
    return NULL_TREE;

  /* The following analysis of 'object' is similar to the one used for
     the 'receiver' of a method invocation.  We need to determine what
     'object' is and find the appropriate property (either declared,
     or artificial) for it (in the same way as we need to find the
     appropriate method prototype for a method invocation).  There are
     some simplifications here though: "object.property" is invalid if
     "object" has a type of "id" or "Class"; it must at least have a
     protocol attached to it, and "object" is never a class name as
     that is done by objc_build_class_component_ref.  Finally, we
     don't know if this really is a dot-syntax expression, so we want
     to make a quick exit if it is not; for this reason, we try to
     postpone checks after determining that 'object' looks like an
     Objective-C object.  */

  if (objc_is_id (rtype))
    {
      /* This is the case that the 'object' is of type 'id' or
	 'Class'.  */

      /* Check if at least it is of type 'id <Protocol>' or 'Class
	 <Protocol>'; if so, look the property up in the
	 protocols.  */
      if (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype)))
	{
	  tree rprotos = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype));

	  if (rprotos)
	    {
	      /* No point looking up declared @properties if we are
		 dealing with a class.  Classes have no declared
		 properties.  */
	      if (!IS_CLASS (rtype))
		x = lookup_property_in_protocol_list (rprotos, property_ident);

	      if (x == NULL_TREE)
		{
		  /* Ok, no property.  Maybe it was an
		     object.component dot-syntax without a declared
		     property (this is valid for classes too).  Look
		     for getter/setter methods and internally declare
		     an artificial property based on them if found.  */
		  x = maybe_make_artificial_property_decl (NULL_TREE,
							   NULL_TREE,
							   rprotos,
							   property_ident,
							   IS_CLASS (rtype),
							   NULL_TREE);
		}
	      else if (PROPERTY_OPTIONAL (x) && PROPERTY_READONLY (x))
		{
		  /* This is a special, complicated case.  If the
		     property is optional, and is read-only, then the
		     property is always used for reading, but an
		     eventual existing non-property setter can be used
		     for writing.  We create an artificial property
		     decl copying the getter from the optional
		     property, and looking up the setter in the
		     interface.  */
		  x = maybe_make_artificial_property_decl (NULL_TREE,
							   NULL_TREE,
							   rprotos,
							   property_ident,
							   false,
							   PROPERTY_GETTER_NAME (x));
		}
	    }
	}
      else if (objc_method_context)
	{
	  /* Else, if we are inside a method it could be the case of
	     'super' or 'self'.  */
	  tree interface_type = NULL_TREE;
	  tree t = object;
	  while (TREE_CODE (t) == COMPOUND_EXPR
		 || TREE_CODE (t) == MODIFY_EXPR
		 || CONVERT_EXPR_P (t)
		 || TREE_CODE (t) == COMPONENT_REF)
	    t = TREE_OPERAND (t, 0);

	  STRIP_ANY_LOCATION_WRAPPER (t);

	  if (t == UOBJC_SUPER_decl)
	    interface_type = lookup_interface (CLASS_SUPER_NAME (implementation_template));
	  else if (t == self_decl)
	    interface_type = lookup_interface (CLASS_NAME (implementation_template));

	  if (interface_type)
	    {
	      if (TREE_CODE (objc_method_context) != CLASS_METHOD_DECL)
		x = lookup_property (interface_type, property_ident);

	      if (x == NULL_TREE)
		{
		  /* Try the dot-syntax without a declared property.
		     If this is an access to 'self', it is possible
		     that they may refer to a setter/getter that is
		     not declared in the interface, but exists locally
		     in the implementation.  In that case, get the
		     implementation context and use it.  */
		  tree implementation = NULL_TREE;

		  if (t == self_decl)
		    implementation = objc_implementation_context;

		  x = maybe_make_artificial_property_decl
		    (interface_type, implementation, NULL_TREE,
		     property_ident,
		     (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL),
		     NULL_TREE);
		}
	      else if (PROPERTY_OPTIONAL (x) && PROPERTY_READONLY (x))
		{
		  tree implementation = NULL_TREE;

		  if (t == self_decl)
		    implementation = objc_implementation_context;

		  x = maybe_make_artificial_property_decl (interface_type,
							   implementation,
							   NULL_TREE,
							   property_ident,
							   false,
							   PROPERTY_GETTER_NAME (x));
		}
	    }
	}
    }
  else
    {
      /* This is the case where we have more information on 'rtype'.  */
      tree basetype = TYPE_MAIN_VARIANT (rtype);

      /* Skip the pointer - if none, it's not an Objective-C object or
	 class.  */
      if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE)
	basetype = TREE_TYPE (basetype);
      else
	return NULL_TREE;

      /* Traverse typedefs.  */
      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);
	  tree protocol_list = TYPE_OBJC_PROTOCOL_LIST (basetype);

	  if (interface_type
	      && (TREE_CODE (interface_type) == CLASS_INTERFACE_TYPE
		  || TREE_CODE (interface_type) == CATEGORY_INTERFACE_TYPE
		  || TREE_CODE (interface_type) == PROTOCOL_INTERFACE_TYPE))
	    {
	      /* Not sure 'rtype' could ever be a class here!  Just
		 for safety we keep the checks.  */
	      if (!IS_CLASS (rtype))
		{
		  x = lookup_property (interface_type, property_ident);

		  if (x == NULL_TREE)
		    x = lookup_property_in_protocol_list (protocol_list,
							  property_ident);
		}

	      if (x == NULL_TREE)
		{
		  /* Try the dot-syntax without a declared property.
		     If we are inside a method implementation, it is
		     possible that they may refer to a setter/getter
		     that is not declared in the interface, but exists
		     locally in the implementation.  In that case, get
		     the implementation context and use it.  */
		  tree implementation = NULL_TREE;

		  if (objc_implementation_context
		      && CLASS_NAME (objc_implementation_context)
		      == OBJC_TYPE_NAME (interface_type))
		    implementation = objc_implementation_context;

		  x = maybe_make_artificial_property_decl (interface_type,
							   implementation,
							   protocol_list,
							   property_ident,
							   IS_CLASS (rtype),
							   NULL_TREE);
		}
	      else if (PROPERTY_OPTIONAL (x) && PROPERTY_READONLY (x))
		{
		  tree implementation = NULL_TREE;

		  if (objc_implementation_context
		      && CLASS_NAME (objc_implementation_context)
		      == OBJC_TYPE_NAME (interface_type))
		    implementation = objc_implementation_context;

		  x = maybe_make_artificial_property_decl (interface_type,
							   implementation,
							   protocol_list,
							   property_ident,
							   false,
							   PROPERTY_GETTER_NAME (x));
		}
	    }
	}
    }

  if (x)
    {
      tree expression;
      tree getter_call;
      tree method_prototype_avail = NULL_TREE;

      /* We have an additional nasty problem here; if this
	 PROPERTY_REF needs to become a 'getter', then the conversion
	 from PROPERTY_REF into a getter call happens in gimplify,
	 after the selector table has already been generated and when
	 it is too late to add another selector to it.  To work around
	 the problem, we always create the getter call at this stage,
	 which puts the selector in the table.  Note that if the
	 PROPERTY_REF becomes a 'setter' instead of a 'getter', then
	 we have added a selector too many to the selector table.
	 This is a little inefficient.

	 Also note that method calls to 'self' and 'super' require the
	 context (self_decl, UOBJS_SUPER_decl,
	 objc_implementation_context etc) to be built correctly; this
	 is yet another reason why building the call at the gimplify
	 stage (when this context has been lost) is not very
	 practical.  If we build it at this stage, we know it will
	 always be built correctly.

	 If the PROPERTY_HAS_NO_GETTER() (ie, it is an artificial
	 property decl created to deal with a dotsyntax not really
	 referring to an existing property) then do not try to build a
	 call to the getter as there is no getter.  */
      if (PROPERTY_HAS_NO_GETTER (x))
	getter_call = NULL_TREE;
      else
	getter_call = objc_finish_message_expr
	  (object, PROPERTY_GETTER_NAME (x), NULL_TREE,
	   /* Disable the immediate deprecation warning if the getter
	      is deprecated, but record the fact that the getter is
	      deprecated by setting PROPERTY_REF_DEPRECATED_GETTER to
	      the method prototype.  */
	   &method_prototype_avail);

      expression = build4 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call,
			   method_prototype_avail);
      SET_EXPR_LOCATION (expression, input_location);
      TREE_SIDE_EFFECTS (expression) = 1;

      return expression;
    }

  return NULL_TREE;
}

/* This hook routine is invoked by the parser when an expression such
   as 'xxx.yyy' is parsed, and 'xxx' is a class name.  This is the
   Objective-C 2.0 dot-syntax applied to classes, so we need to
   convert it into a setter/getter call on the class.  */
tree
objc_build_class_component_ref (tree class_name, tree property_ident)
{
  tree x = NULL_TREE;
  tree object, rtype;

  if (flag_objc1_only)
    error_at (input_location, "the dot syntax is not available in Objective-C 1.0");

  if (class_name == NULL_TREE || class_name == error_mark_node
      || TREE_CODE (class_name) != IDENTIFIER_NODE)
    return error_mark_node;

  if (property_ident == NULL_TREE || property_ident == error_mark_node
      || TREE_CODE (property_ident) != IDENTIFIER_NODE)
    return NULL_TREE;

  object = objc_get_class_reference (class_name);
  if (!object)
    {
      /* We know that 'class_name' is an Objective-C class name as the
	 parser won't call this function if it is not.  This is only a
	 double-check for safety.  */
      error_at (input_location, "could not find class %qE", class_name);
      return error_mark_node;
    }

  rtype = lookup_interface (class_name);
  if (!rtype)
    {
      /* Again, this should never happen, but we do check.  */
      error_at (input_location, "could not find interface for class %qE", class_name);
      return error_mark_node;
    }
  else
    {
      if (TREE_UNAVAILABLE (rtype))
	error ("class %qE is unavailable", class_name);
      else if (TREE_DEPRECATED (rtype))
	warning (OPT_Wdeprecated_declarations, "class %qE is deprecated", class_name);
    }

  x = maybe_make_artificial_property_decl (rtype, NULL_TREE, NULL_TREE,
					   property_ident,
					   true, NULL_TREE);

  if (x)
    {
      tree expression;
      tree getter_call;
      tree method_prototype_avail = NULL_TREE;

      if (PROPERTY_HAS_NO_GETTER (x))
	getter_call = NULL_TREE;
      else
	getter_call = objc_finish_message_expr
	  (object, PROPERTY_GETTER_NAME (x), NULL_TREE,
	   &method_prototype_avail);

      expression = build4 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call,
			   method_prototype_avail);
      SET_EXPR_LOCATION (expression, input_location);
      TREE_SIDE_EFFECTS (expression) = 1;

      return expression;
    }
  else
    {
      error_at (input_location, "could not find setter/getter for %qE in class %qE",
		property_ident,	class_name);
      return error_mark_node;
    }

  return NULL_TREE;
}


/* This is used because we don't want to expose PROPERTY_REF to the
   C/C++ frontends.  Maybe we should!  */
bool
objc_is_property_ref (tree node)
{
  if (node  &&  TREE_CODE (node) == PROPERTY_REF)
    return true;
  else
    return false;
}

/* We use this to report tree codes that are known to be invalid in const-
   expression contexts.  */
bool
objc_non_constant_expr_p (tree node)
{
  switch (TREE_CODE (node))
    {
      default:
	return false;
      case MESSAGE_SEND_EXPR:
      case PROPERTY_REF:
	return true;
    }
}

/* This function builds a setter call for a PROPERTY_REF (real, for a
   declared property, or artificial, for a dot-syntax accessor which
   is not corresponding to a property).  'lhs' must be a PROPERTY_REF
   (the caller must check this beforehand).  'rhs' is the value to
   assign to the property.  A plain setter call is returned, or
   error_mark_node if the property is readonly.  */

static tree
objc_build_setter_call (tree lhs, tree rhs)
{
  tree object_expr = PROPERTY_REF_OBJECT (lhs);
  tree property_decl = PROPERTY_REF_PROPERTY_DECL (lhs);

  if (PROPERTY_READONLY (property_decl))
    {
      error ("%qs property cannot be set", "readonly");
      return error_mark_node;
    }
  else
    {
      tree setter_argument = build_tree_list (NULL_TREE, rhs);
      tree setter;

      /* TODO: Check that the setter return type is 'void'.  */

      /* TODO: Decay arguments in C.  */
      setter = objc_finish_message_expr (object_expr,
					 PROPERTY_SETTER_NAME (property_decl),
					 setter_argument, NULL);
      return setter;
    }
}

/* This hook routine is called when a MODIFY_EXPR is being built.  We
   check what is being modified; if it is a PROPERTY_REF, we need to
   generate a 'setter' function call for the property.  If this is not
   a PROPERTY_REF, we return NULL_TREE and the C/C++ frontend will go
   on creating their MODIFY_EXPR.

   This is used for example if you write

   object.count = 1;

   where 'count' is a property.  The left-hand side creates a
   PROPERTY_REF, and then the compiler tries to generate a MODIFY_EXPR
   to assign something to it.  We intercept that here, and generate a
   call to the 'setter' method instead.  */
tree
objc_maybe_build_modify_expr (tree lhs, tree rhs)
{
  if (lhs && TREE_CODE (lhs) == PROPERTY_REF)
    {
      /* Building a simple call to the setter method would work for cases such as

      object.count = 1;

      but wouldn't work for cases such as

      count = object2.count = 1;

      to get these to work with very little effort, we build a
      compound statement which does the setter call (to set the
      property to 'rhs'), but which can also be evaluated returning
      the 'rhs'.  If the 'rhs' has no side effects, we can simply
      evaluate it twice, building

      ([object setProperty: rhs]; rhs)

      If it has side effects, we put it in a temporary variable first,
      so we create the following:

      (temp = rhs; [object setProperty: temp]; temp)

      setter_argument is rhs in the first case, and temp in the second
      case.
      */
      tree setter_argument;

      /* s1, s2 and s3 are the tree statements that we need in the
	 compound expression.  */
      tree s1, s2, s3, compound_expr;

      if (TREE_SIDE_EFFECTS (rhs))
	{
	  tree bind;

	  /* Declare __objc_property_temp in a local bind.  */
	  setter_argument = objc_create_temporary_var (TREE_TYPE (rhs), "__objc_property_temp");
	  DECL_SOURCE_LOCATION (setter_argument) = input_location;
	  bind = build3 (BIND_EXPR, void_type_node, setter_argument, NULL, NULL);
	  SET_EXPR_LOCATION (bind, input_location);
	  TREE_SIDE_EFFECTS (bind) = 1;
	  add_stmt (bind);

	  /* s1: x = rhs */
	  s1 = build_modify_expr (input_location, setter_argument, NULL_TREE,
				  NOP_EXPR,
				  input_location, rhs, NULL_TREE);
	  SET_EXPR_LOCATION (s1, input_location);
	}
      else
	{
	  /* No s1.  */
	  setter_argument = rhs;
	  s1 = NULL_TREE;
	}

      /* Now build the compound statement.  */

      /* s2: [object setProperty: x] */
      s2 = objc_build_setter_call (lhs, setter_argument);

      /* This happens if building the setter failed because the
	 property is readonly.  */
      if (s2 == error_mark_node)
	return error_mark_node;

      SET_EXPR_LOCATION (s2, input_location);

      /* s3: x */
      s3 = convert (TREE_TYPE (lhs), setter_argument);

      /* Now build the compound statement (s1, s2, s3) or (s2, s3) as
	 appropriate.  */
      if (s1)
	compound_expr = build_compound_expr (input_location, build_compound_expr (input_location, s1, s2), s3);
      else
	compound_expr = build_compound_expr (input_location, s2, s3);

      /* Without this, with -Wall you get a 'valued computed is not
	 used' every time there is a "object.property = x" where the
	 value of the resulting MODIFY_EXPR is not used.  That is
	 correct (maybe a more sophisticated implementation could
	 avoid generating the compound expression if not needed), but
	 we need to turn it off.  */
      suppress_warning (compound_expr, OPT_Wunused);
      return compound_expr;
    }
  else
    return NULL_TREE;
}

/* This hook is called by the frontend when one of the four unary
   expressions PREINCREMENT_EXPR, POSTINCREMENT_EXPR,
   PREDECREMENT_EXPR and POSTDECREMENT_EXPR is being built with an
   argument which is a PROPERTY_REF.  For example, this happens if you have

   object.count++;

   where 'count' is a property.  We need to use the 'getter' and
   'setter' for the property in an appropriate way to build the
   appropriate expression.  'code' is the code for the expression (one
   of the four mentioned above); 'argument' is the PROPERTY_REF, and
   'increment' is how much we need to add or subtract.  */
tree
objc_build_incr_expr_for_property_ref (location_t location,
				       enum tree_code code,
				       tree argument, tree increment)
{
  /* Here are the expressions that we want to build:

     For PREINCREMENT_EXPR / PREDECREMENT_EXPR:
    (temp = [object property] +/- increment, [object setProperty: temp], temp)

    For POSTINCREMENT_EXPR / POSTECREMENT_EXPR:
    (temp = [object property], [object setProperty: temp +/- increment], temp) */

  tree temp_variable_decl, bind;
  /* s1, s2 and s3 are the tree statements that we need in the
     compound expression.  */
  tree s1, s2, s3, compound_expr;

  /* Safety check.  */
  if (!argument || TREE_CODE (argument) != PROPERTY_REF)
    return error_mark_node;

  /* Declare __objc_property_temp in a local bind.  */
  temp_variable_decl = objc_create_temporary_var (TREE_TYPE (argument), "__objc_property_temp");
  DECL_SOURCE_LOCATION (temp_variable_decl) = location;
  bind = build3 (BIND_EXPR, void_type_node, temp_variable_decl, NULL, NULL);
  SET_EXPR_LOCATION (bind, location);
  TREE_SIDE_EFFECTS (bind) = 1;
  add_stmt (bind);

  /* Now build the compound statement.  */

  /* Note that the 'getter' is generated at gimplify time; at this
     time, we can simply put the property_ref (ie, argument) wherever
     we want the getter ultimately to be.  */

  /* s1: __objc_property_temp = [object property] <+/- increment> */
  switch (code)
    {
    case PREINCREMENT_EXPR:
      /* __objc_property_temp = [object property] + increment */
      s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
			      NOP_EXPR,
			      location, build2 (PLUS_EXPR, TREE_TYPE (argument),
						argument, increment), NULL_TREE);
      break;
    case PREDECREMENT_EXPR:
      /* __objc_property_temp = [object property] - increment */
      s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
			      NOP_EXPR,
			      location, build2 (MINUS_EXPR, TREE_TYPE (argument),
						argument, increment), NULL_TREE);
      break;
    case POSTINCREMENT_EXPR:
    case POSTDECREMENT_EXPR:
      /* __objc_property_temp = [object property] */
      s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
			      NOP_EXPR,
			      location, argument, NULL_TREE);
      break;
    default:
      gcc_unreachable ();
    }

  /* s2: [object setProperty: __objc_property_temp <+/- increment>] */
  switch (code)
    {
    case PREINCREMENT_EXPR:
    case PREDECREMENT_EXPR:
      /* [object setProperty: __objc_property_temp] */
      s2 = objc_build_setter_call (argument, temp_variable_decl);
      break;
    case POSTINCREMENT_EXPR:
      /* [object setProperty: __objc_property_temp + increment] */
      s2 = objc_build_setter_call (argument,
				   build2 (PLUS_EXPR, TREE_TYPE (argument),
					   temp_variable_decl, increment));
      break;
    case POSTDECREMENT_EXPR:
      /* [object setProperty: __objc_property_temp - increment] */
      s2 = objc_build_setter_call (argument,
				   build2 (MINUS_EXPR, TREE_TYPE (argument),
					   temp_variable_decl, increment));
      break;
    default:
      gcc_unreachable ();
    }

  /* This happens if building the setter failed because the property
     is readonly.  */
  if (s2 == error_mark_node)
    return error_mark_node;

  SET_EXPR_LOCATION (s2, location);

  /* s3: __objc_property_temp */
  s3 = convert (TREE_TYPE (argument), temp_variable_decl);

  /* Now build the compound statement (s1, s2, s3) */
  compound_expr = build_compound_expr (location, build_compound_expr (location, s1, s2), s3);

  /* Prevent C++ from warning with -Wall that "right operand of comma
     operator has no effect".  */
  suppress_warning (compound_expr, OPT_Wunused);
  return compound_expr;
}

tree
objc_build_method_signature (bool is_class_method, tree rettype, tree selector,
			     tree optparms, bool ellipsis)
{
  if (is_class_method)
    return build_method_decl (CLASS_METHOD_DECL, rettype, selector,
			      optparms, ellipsis);
  else
    return build_method_decl (INSTANCE_METHOD_DECL, rettype, selector,
			      optparms, ellipsis);
}

void
objc_add_method_declaration (bool is_class_method, tree decl, tree attributes)
{
  if (!objc_interface_context)
    {
      /* PS: At the moment, due to how the parser works, it should be
	 impossible to get here.  But it's good to have the check in
	 case the parser changes.
      */
      fatal_error (input_location,
		   "method declaration not in @interface context");
    }

  if (flag_objc1_only && attributes)
    error_at (input_location, "method attributes are not available in Objective-C 1.0");

  objc_decl_method_attributes (&decl, attributes, 0);
  objc_add_method (objc_interface_context,
		   decl,
		   is_class_method,
		   objc_method_optional_flag);
}

/* Return 'true' if the method definition could be started, and
   'false' if not (because we are outside an @implementation context).
   EXPR is NULL or an expression that needs to be evaluated for the
   side effects of array size expressions in the parameters.
*/
bool
objc_start_method_definition (bool is_class_method, tree decl, tree attributes,
			      tree expr)
{
  if (!objc_implementation_context)
    {
      error ("method definition not in @implementation context");
      return false;
    }

  if (decl != NULL_TREE  && METHOD_SEL_NAME (decl) == error_mark_node)
    return false;

#ifndef OBJCPLUS
  /* Indicate no valid break/continue context.  */
  in_statement = 0;
#endif

  if (attributes)
    warning_at (input_location, 0, "method attributes cannot be specified in @implementation context");
  else
    objc_decl_method_attributes (&decl, attributes, 0);

  objc_add_method (objc_implementation_context,
		   decl,
		   is_class_method,
		   /* is optional */ false);
  start_method_def (decl, expr);
  return true;
}

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

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

static tree
objc_build_struct (tree klass, tree fields, tree super_name)
{
  tree name = CLASS_NAME (klass);
  tree s = objc_start_struct (name);
  tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
  tree t;
  vec<tree> objc_info = vNULL;
  int i;

  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 (input_location,
			      FIELD_DECL, NULL_TREE, super);
      tree field = TYPE_FIELDS (super);

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

      /* For ObjC ABI purposes, the "packed" size of a base class is
	 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;
      SET_DECL_ALIGN (base, 1);
      DECL_FIELD_CONTEXT (base) = s;
#ifdef OBJCPLUS
      DECL_FIELD_IS_BASE (base) = 1;

      if (fields)
	/* Suppress C++ ABI warnings: we are following the ObjC ABI here.  */
	suppress_warning (fields, OPT_Wabi);
#endif
      DECL_CHAIN (base) = fields;
      fields = base;
    }

  /* NB: Calling finish_struct() may cause type TYPE_OBJC_INFO
     information in all variants of this RECORD_TYPE to be destroyed
     (this is because the C frontend manipulates TYPE_LANG_SPECIFIC
     for something else and then will change all variants to use the
     same resulting TYPE_LANG_SPECIFIC, ignoring the fact that we use
     it for ObjC protocols and that such propagation will make all
     variants use the same objc_info), but it is therein that we store
     protocol conformance info (e.g., 'NSObject <MyProtocol>').
     Hence, we must save the ObjC-specific information before calling
     finish_struct(), and then reinstate it afterwards.  */

  for (t = TYPE_MAIN_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
    {
      INIT_TYPE_OBJC_INFO (t);
      objc_info.safe_push (TYPE_OBJC_INFO (t));
    }

  s = objc_finish_struct (s, fields);

  for (i = 0, t = TYPE_MAIN_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
    {
      /* We now want to restore the different TYPE_OBJC_INFO, but we
	 have the additional problem that the C frontend doesn't just
	 copy TYPE_LANG_SPECIFIC from one variant to the other; it
	 actually makes all of them the *same* TYPE_LANG_SPECIFIC.  As
	 we need a different TYPE_OBJC_INFO for each (and
	 TYPE_OBJC_INFO is a field in TYPE_LANG_SPECIFIC), we need to
	 make a copy of each TYPE_LANG_SPECIFIC before we modify
	 TYPE_OBJC_INFO.  */
      if (TYPE_LANG_SPECIFIC (t))
	{
	  /* Create a copy of TYPE_LANG_SPECIFIC.  */
	  struct lang_type *old_lang_type = TYPE_LANG_SPECIFIC (t);
	  ALLOC_OBJC_TYPE_LANG_SPECIFIC (t);
	  memcpy (TYPE_LANG_SPECIFIC (t), old_lang_type,
		  SIZEOF_OBJC_TYPE_LANG_SPECIFIC);
	}
      else
	{
	  /* Just create a new one.  */
	  ALLOC_OBJC_TYPE_LANG_SPECIFIC (t);
	}
      /* Replace TYPE_OBJC_INFO with the saved one.  This restores any
	 protocol information that may have been associated with the
	 type.  */
      TYPE_OBJC_INFO (t) = objc_info[i];
      /* Replace the IDENTIFIER_NODE with an actual @interface now
	 that we have it.  */
      TYPE_OBJC_INTERFACE (t) = klass;
    }
  objc_info.release ();

  /* 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 (klass) = s;

  return s;
}

/* 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)
      && (VAR_P (decl)
	  || TREE_CODE (decl) == PARM_DECL))
    {
      if (local_variables_to_volatilize == NULL)
	vec_alloc (local_variables_to_volatilize, 8);

      vec_safe_push (local_variables_to_volatilize, decl);
    }
}

/* Called when parsing of a function completes; if any local variables
   in the function were marked as variables to volatilize, change them
   to volatile.  We do this at the end of the function when the
   warnings about discarding 'volatile' have already been produced.
   We are making the variables as volatile just to force the compiler
   to preserve them between setjmp/longjmp, but we don't want warnings
   for them as they aren't really volatile.  */
void
objc_finish_function (void)
{
  /* If there are any local variables to volatilize, volatilize them.  */
  if (local_variables_to_volatilize)
    {
      int i;
      tree decl;
      FOR_EACH_VEC_ELT (*local_variables_to_volatilize, i, decl)
	{
	  tree t = TREE_TYPE (decl);

	  t = build_qualified_type (t, TYPE_QUALS (t) | TYPE_QUAL_VOLATILE);
	  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
	}

      /* Now we delete the vector.  This sets it to NULL as well.  */
      vec_free (local_variables_to_volatilize);
    }
}

/* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
   (including its categories 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)
    {
      *errbuf = 0;
      gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
      /* NB: Types 'id' and 'Class' cannot reasonably be described as
	 "implementing" a given protocol, since they do not have an
	 implementation.  */
      if (class_type)
	warning (0, "class %qs does not implement the %qE protocol",
		 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
      else
	warning (0, "type %qs does not conform to the %qE protocol",
		 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
    }

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

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

/* 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;
     -3		Comparison (LTYP and RTYP may match in either direction);
     -4		Silent comparison (for C++ overload resolution);
     -5		Silent "specialization" comparison for RTYP to be a "specialization"
                of LTYP (a specialization means that RTYP is LTYP plus some constraints,
                so that each object of type RTYP is also of type LTYP).  This is used
                when comparing property types.  */

bool
objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
{
  tree lcls, rcls, lproto, rproto;
  bool pointers_compatible;

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

  tree ltyp_attr, rtyp_attr;
  do
    {
      /* Remove indirections, but keep the type attributes from the innermost
	 pointer type, to check for NSObject.  */
      ltyp_attr = TYPE_ATTRIBUTES (ltyp);
      ltyp = TREE_TYPE (ltyp);
      rtyp_attr = TYPE_ATTRIBUTES (rtyp);
      rtyp = TREE_TYPE (rtyp);
    }
  while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));

  /* 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)
    {
      function_args_iterator liter, riter;

      /* Return types must be covariant.  */
      if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
	  && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
				  argno, callee))
      return false;

      /* Argument types must be contravariant.  */
      function_args_iter_init (&liter, ltyp);
      function_args_iter_init (&riter, rtyp);

      while (1)
	{
	  ltyp = function_args_iter_cond (&liter);
	  rtyp = function_args_iter_cond (&riter);

	  /* If we've exhaused both lists simulateously, we're done.  */
	  if (ltyp == NULL_TREE && rtyp == NULL_TREE)
	    break;

	  /* If one list is shorter than the other, they fail to match.  */
	  if (ltyp == NULL_TREE || rtyp == NULL_TREE)
	    return false;

	  if (!comptypes (rtyp, ltyp)
	      && !objc_compare_types (rtyp, ltyp, argno, callee))
	    return false;

	  function_args_iter_next (&liter);
	  function_args_iter_next (&riter);
	}

      return true;
    }

  /* We might have void * with NSObject type attr.  */
  bool l_NSObject_p = ltyp_attr && lookup_attribute ("NSObject", ltyp_attr);
  bool r_NSObject_p = rtyp_attr && lookup_attribute ("NSObject", rtyp_attr);

  /* Past this point, we are only interested in ObjC class instances,
     or 'id' or 'Class' (except if the user applied the NSObject type
     attribute).  */
  if ((TREE_CODE (ltyp) != RECORD_TYPE && !l_NSObject_p)
      || (TREE_CODE (rtyp) != RECORD_TYPE && !r_NSObject_p))
    return false;

  if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
      && !TYPE_HAS_OBJC_INFO (ltyp) && !l_NSObject_p)
    return false;

  if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
      && !TYPE_HAS_OBJC_INFO (rtyp) && !r_NSObject_p)
    return false;

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

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

  if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
    lcls = NULL_TREE;

  if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
    rcls = NULL_TREE;

  /* If either type is an unqualified 'id', we're done.  This is because
     an 'id' can be assigned to or from any type with no warnings.  When
     the pointer has NSObject attribute, consider that to be equivalent.  */
  if (argno != -5)
    {
      if ((!lproto && objc_is_object_id (ltyp))
	  || (!rproto && objc_is_object_id (rtyp)))
	return true;
      if (l_NSObject_p || r_NSObject_p)
	return true;
    }
  else
    {
      /* For property checks, though, an 'id' is considered the most
	 general type of object, hence if you try to specialize an
	 'NSArray *' (ltyp) property with an 'id' (rtyp) one, we need
	 to warn.  */
      if (!lproto && (objc_is_object_id (ltyp) || l_NSObject_p))
	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)
	{
	  /* Again, if any of the two is an 'id', we're satisfied,
	     unless we're comparing properties, in which case only an
	     'id' on the left-hand side (old property) is good
	     enough.  */
	  if (argno != -5)
	    pointers_compatible
	      = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
	  else
	    pointers_compatible = objc_is_object_id (ltyp);
	}

      if (!pointers_compatible)
	pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);

      if (!pointers_compatible && (argno == -3 || argno == -4))
	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,
						    argno != -3);

      if (!pointers_compatible && argno == -3)
	pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
						      argno != -3);
    }

  if (!pointers_compatible)
    {
      /* The two pointers are not exactly compatible.  Issue a warning, unless
	 we are performing a silent comparison, in which case return 'false'
	 instead.  */
      /* NB: For the time being, we shall make our warnings look like their
	 C counterparts.  In the future, we may wish to make them more
	 ObjC-specific.  */
      switch (argno)
	{
	case -5:
	case -4:
	  return false;

	case -3:
	  warning (0, "comparison of distinct Objective-C types lacks a cast");
	  break;

	case -2:
	  warning (0, "initialization from distinct Objective-C type");
	  break;

	case -1:
	  warning (0, "assignment from distinct Objective-C type");
	  break;

	case 0:
	  warning (0, "distinct Objective-C type in return");
	  break;

	default:
	  warning (0, "passing argument %d of %qE from distinct "
		   "Objective-C type", argno, callee);
	  break;
	}
    }

  return true;
}

/* 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)
{
  if (objc_compare_types (ltyp, rtyp, argno, callee))
    {
      /* 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;
}

#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

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,
                                          tf_warning_or_error);
#else
  return build_component_ref (input_location, datum, component,
			      UNKNOWN_LOCATION, UNKNOWN_LOCATION);
#endif
}

/* Recursively copy inheritance information rooted at BINFO.  To do this,
   we emulate the song and dance performed by cp/tree.cc: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.cc:xref_basetypes().  */

static void
objc_xref_basetypes (tree ref, tree basetype)
{
  tree variant;
  tree binfo = make_tree_binfo (basetype ? 1 : 0);
  TYPE_BINFO (ref) = binfo;
  BINFO_OFFSET (binfo) = size_zero_node;
  BINFO_TYPE (binfo) = ref;

  gcc_assert (TYPE_MAIN_VARIANT (ref) == ref);
  for (variant = ref; variant; variant = TYPE_NEXT_VARIANT (variant))
    TYPE_BINFO (variant) = binfo;

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

      BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
      vec_alloc (BINFO_BASE_ACCESSES (binfo), 1);
      BINFO_BASE_APPEND (binfo, base_binfo);
      BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
    }
}

/* Called from finish_decl.  */

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

  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 %qE",
	   type);
}

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

/* 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.  This function is often called when
   PROTOCOLS is NULL_TREE, in which case we simply look up the
   appropriate INTERFACE.  */

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)
	{
	  /* 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));
	}
      else
	{
	  /* This case happens when we are given an 'interface' which
	     is not a valid class name.  For example if a typedef was
	     used, and 'interface' really is the identifier of the
	     typedef, but when you resolve it you don't get an
	     Objective-C class, but something else, such as 'int'.
	     This is an error; protocols make no sense unless you use
	     them with Objective-C objects.  */
	  error_at (input_location, "only Objective-C object types can be qualified with a protocol");

	  /* Try to recover.  Ignore the invalid class name, and treat
	     the object as an 'id' to silence further warnings about
	     the class.  */
	  type = objc_object_type;
	  is_ptr = true;
	}
    }

  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 orig_pointee_type = TREE_TYPE (type);
	  TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);

	  /* Set up the canonical type information. */
	  TYPE_CANONICAL (type)
	    = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_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));
      TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols
	(protocols, /* definition_required */ 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, /* warn if deprecated */ false,
			      /* definition_required */ false);

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

/* Look up PROTOCOLS, and return a list of those that are found.  If
   none are found, return NULL.  Note that this function will emit a
   warning if a protocol is found and is deprecated.  If
   'definition_required', then warn if the protocol is found but is
   not defined (ie, if we only saw a forward-declaration of the
   protocol (as in "@protocol NSObject;") not a real definition with
   the list of methods).  */
static tree
lookup_and_install_protocols (tree protocols, bool definition_required)
{
  tree proto;
  tree return_value = NULL_TREE;

  if (protocols == error_mark_node)
    return NULL;

  for (proto = protocols; proto; proto = TREE_CHAIN (proto))
    {
      tree ident = TREE_VALUE (proto);
      tree p = lookup_protocol (ident, /* warn_if_deprecated */ true,
				definition_required);

      if (p)
	return_value = chainon (return_value,
				build_tree_list (NULL_TREE, p));
      else if (ident != error_mark_node)
	error ("cannot find protocol declaration for %qE",
	       ident);
    }

  return return_value;
}

static void
build_common_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_list (void_type_node,
                                        objc_object_type,
                                        NULL_TREE);
  objc_exception_throw_decl
    = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
			    noreturn_list);
  /* Make sure that objc_exception_throw (id) claims that it may throw an
     exception. */
  TREE_NOTHROW (objc_exception_throw_decl) = 0;

  objc_sync_enter_decl
    = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
			    NULL, nothrow_list);

  objc_sync_exit_decl
    = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
			    NULL, nothrow_list);
}

/* 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;
  uint32_t save_write_symbols = write_symbols;
  const struct gcc_debug_hooks *const save_hooks = debug_hooks;

  /* Suppress outputting debug symbols, because
     dbxout_init hasn't 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_instancetype_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_instancetype_name = get_identifier (INSTANCE_TYPEDEF_NAME);
  objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
  objc_selector_name = get_identifier (SEL_TYPEDEF_NAME);

  /* Declare the 'id', 'instancetype' and 'Class' typedefs.  */
  type = lang_hooks.decls.pushdecl (build_decl (input_location,
						TYPE_DECL,
						objc_object_name,
						objc_object_type));
  suppress_warning (type);

  type = lang_hooks.decls.pushdecl (build_decl (input_location,
						TYPE_DECL,
						objc_instancetype_name,
						objc_instancetype_type));
  suppress_warning (type);

  type = lang_hooks.decls.pushdecl (build_decl (input_location,
						TYPE_DECL,
						objc_class_name,
						objc_class_type));
  suppress_warning (type);

  /* Forward-declare '@interface Protocol'.  */
  type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
  objc_declare_class (type);
  objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE, type));

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

  build_common_objc_exception_stuff ();

  /* Set-up runtime-specific templates, message and exception stuff.  */
  (*runtime.initialize) ();

  /* Declare objc_getProperty, object_setProperty and other property
     accessor helpers.  */
  build_common_objc_property_accessor_helpers ();

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

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

  /* Declare struct _objc_fast_enumeration_state { ... };  */
  build_fast_enumeration_state_template ();

  /* void objc_enumeration_mutation (id) */
  type = build_function_type_list (void_type_node,
				   objc_object_type, NULL_TREE);
  objc_enumeration_mutation_decl
    = add_builtin_function (TAG_ENUMERATION_MUTATION, type, 0, NOT_BUILT_IN,
			    NULL, NULL_TREE);
  TREE_NOTHROW (objc_enumeration_mutation_decl) = 0;

#ifdef OBJCPLUS
  pop_lang_context ();
#endif

  write_symbols = save_write_symbols;
  debug_hooks = save_hooks;
}

/* --- const strings --- */

/* 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 = DECL_CHAIN (field_decl);
  if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
    return 0;

  field_decl = DECL_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 (input_location,
			    FIELD_DECL, NULL_TREE, ptr_type_node);
  tree field = build_decl (input_location,
			   FIELD_DECL, NULL_TREE, ptr_type_node);

  DECL_CHAIN (field) = fields; fields = field;
  field = build_decl (input_location,
		      FIELD_DECL, NULL_TREE, unsigned_type_node);
  DECL_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!  */

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

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

hashval_t
objc_string_hasher::hash (string_descriptor *ptr)
{
  const_tree const str = 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;
}

bool
objc_string_hasher::equal (string_descriptor *ptr1, string_descriptor *ptr2)
{
  const_tree const str1 = ptr1->literal;
  const_tree const str2 = ptr2->literal;
  int len1 = TREE_STRING_LENGTH (str1);

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

/* 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 constant_string_class;
  int length;
  tree addr;
  struct string_descriptor *desc, key;

  /* We should be passed a STRING_CST.  */
  gcc_checking_assert (TREE_CODE (string) == STRING_CST);
  length = TREE_STRING_LENGTH (string) - 1;

  /* The target may have different ideas on how to construct an ObjC string
     literal.  On Darwin / macOS, for example, we may wish to obtain a
     constant CFString reference instead.
     At present, this is only supported for the NeXT runtime.  */
  if (flag_next_runtime
      && targetcm.objc_construct_string_object)
    {
      tree constructor = (*targetcm.objc_construct_string_object) (string);
      if (constructor)
	return build1 (NOP_EXPR, objc_object_type, constructor);
    }

  /* 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 %qE",
	       constant_string_id);
      /* The NSConstantString/NXConstantString ivar layout is now known.  */
      else if (!check_string_class_template ())
	error ("interface %qE does not have valid constant string layout",
	       constant_string_id);
      /* If the runtime can generate a literal reference to the string class,
	 don't need to run a constructor.  */
      else if (!(*runtime.setup_const_string_class_decl)())
	error ("cannot find reference tag for class %qE", 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;
  string_descriptor **loc = string_htab->find_slot (&key, INSERT);
  desc = *loc;

  if (!desc)
    {
      *loc = desc = ggc_alloc<string_descriptor> ();
      desc->literal = string;
      desc->constructor =
	(*runtime.build_const_string_constructor) (input_location, string, length);
    }

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

  return addr;
}

/* Build a static constant CONSTRUCTOR with type TYPE and elements ELTS.
   We might be presented with a NULL for ELTS, which means 'empty ctor'
   which will subsequently be converted into a zero initializer in the
   middle end.  */

tree
objc_build_constructor (tree type, vec<constructor_elt, va_gc> *elts)
{
  tree constructor = build_constructor (type, elts);

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

#ifdef OBJCPLUS
  /* If we know the initializer, then set the type to what C++ expects.  */
  if (elts && !(*elts)[0].index)
    TREE_TYPE (constructor) = init_list_type_node;
#endif
  return constructor;
}

/* Return the DECL of the string IDENT in the SECTION.  */

tree
get_objc_string_decl (tree ident, enum string_section section)
{
  tree chain;

  switch (section)
    {
    case class_names:
      chain = class_names_chain;
      break;
    case meth_var_names:
      chain = meth_var_names_chain;
      break;
    case meth_var_types:
      chain = meth_var_types_chain;
      break;
    case prop_names_attr:
      chain = prop_names_attr_chain;
      break;
    default:
      gcc_unreachable ();
    }

  for (; chain != 0; chain = TREE_CHAIN (chain))
    if (TREE_VALUE (chain) == ident)
      return (TREE_PURPOSE (chain));

  /* We didn't find the entry.  */
  return NULL_TREE;
}

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

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

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

#ifdef OBJCPLUS
  if (processing_template_decl)
    /* Must wait until template instantiation time.  */
    return build_min_nt_loc (UNKNOWN_LOCATION, 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)
      && CP_TYPE_CONTEXT (ident) != global_namespace)
    local_scope = true;
#endif

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

  return (*runtime.get_class_reference) (ident);
}

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 %qE", class_ident);
  else if (objc_is_class_name (alias_ident))
    warning (0, "class %qE already exists", 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
				 (input_location,
				  TYPE_DECL,
				  alias_ident,
				  xref_tag (RECORD_TYPE, underlying_class)));
#ifdef OBJCPLUS
      pop_lang_context ();
#endif
      objc_map_put (alias_name_map, alias_ident, underlying_class);
    }
}

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

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

      if (record)
	{
	  if (TREE_CODE (record) == TYPE_DECL)
	    type = DECL_ORIGINAL_TYPE (record)
	      ? DECL_ORIGINAL_TYPE (record)
	      : TREE_TYPE (record);

	  if (!TYPE_HAS_OBJC_INFO (type)
	      || !TYPE_OBJC_INTERFACE (type))
	    {
	      error ("%qE redeclared as different kind of symbol",
		     identifier);
	      error ("previous declaration of %q+D",
		     record);
	    }
	}

      record = xref_tag (RECORD_TYPE, identifier);
      INIT_TYPE_OBJC_INFO (record);
      /* In the case of a @class declaration, we store the ident in
	 the TYPE_OBJC_INTERFACE.  If later an @interface is found,
	 we'll replace the ident with the interface.  */
      TYPE_OBJC_INTERFACE (record) = identifier;
      objc_map_put (class_name_map, identifier, NULL_TREE);
    }
}

tree
objc_is_class_name (tree ident)
{
  if (ident && TREE_CODE (ident) == IDENTIFIER_NODE)
    {
      tree t = identifier_global_value (ident);
      if (t)
	ident = t;
    }

  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)
    {
      tree type = TREE_TYPE (ident);
      if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
        return NULL_TREE;
      ident = DECL_NAME (ident);
    }
#endif
  if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
    return NULL_TREE;

  if (lookup_interface (ident))
    return ident;

  {
    tree target;

    target = objc_map_get (class_name_map, ident);
    if (target != OBJC_MAP_NOT_FOUND)
      return ident;

    target = objc_map_get (alias_name_map, ident);
    if (target != OBJC_MAP_NOT_FOUND)
      return target;
  }

  return 0;
}

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

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

  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;

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

  ret = objc_is_id (type);
  if (!ret)
    ret = objc_is_class_name (TREE_TYPE (type));

  return ret;
}

static int
objc_is_gcable_type (tree type, int or_strong_p)
{
  tree name;

  if (!TYPE_P (type))
    return 0;
  if (objc_is_id (TYPE_MAIN_VARIANT (type)))
    return 1;
  if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
    return 1;
  if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
    return 0;
  type = TREE_TYPE (type);
  if (TREE_CODE (type) != RECORD_TYPE)
    return 0;
  name = TYPE_NAME (type);
  return (objc_is_class_name (name) != NULL_TREE);
}

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)));
    case ARRAY_REF:
      return build_array_ref (input_location,
			      objc_substitute_decl (TREE_OPERAND (expr, 0),
						    oldexpr,
						    newexpr),
			      TREE_OPERAND (expr, 1));
    case INDIRECT_REF:
      return build_indirect_ref (input_location,
				 objc_substitute_decl (TREE_OPERAND (expr, 0),
						       oldexpr,
						       newexpr), RO_ARROW);
    default:
      return expr;
    }
}

static tree
objc_build_ivar_assignment (tree outervar, 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]').
  */
  tree offs
    = objc_substitute_decl
      (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
  tree func
    = (flag_objc_direct_dispatch
       ? objc_assign_ivar_fast_decl
       : objc_assign_ivar_decl);

  offs = convert (integer_type_node, build_unary_op (input_location,
						     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)));

  return build_function_call (input_location, func, func_params);
}

static tree
objc_build_global_assignment (tree lhs, tree rhs)
{
  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 (input_location, ADDR_EXPR, lhs, 0)),
		    NULL_TREE));

  return build_function_call (input_location,
			      objc_assign_global_decl, func_params);
}

static tree
objc_build_strong_cast_assignment (tree lhs, tree rhs)
{
  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 (input_location, ADDR_EXPR, lhs, 0)),
		    NULL_TREE));

  return build_function_call (input_location,
			      objc_assign_strong_cast_decl, func_params);
}

static int
objc_is_gcable_p (tree expr)
{
  return (TREE_CODE (expr) == COMPONENT_REF
	  ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
	  : TREE_CODE (expr) == ARRAY_REF
	  ? (objc_is_gcable_p (TREE_TYPE (expr))
	     || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
	  : TREE_CODE (expr) == ARRAY_TYPE
	  ? objc_is_gcable_p (TREE_TYPE (expr))
	  : TYPE_P (expr)
	  ? objc_is_gcable_type (expr, 1)
	  : (objc_is_gcable_p (TREE_TYPE (expr))
	     || (DECL_P (expr)
		 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
}

static int
objc_is_ivar_reference_p (tree expr)
{
  return (TREE_CODE (expr) == ARRAY_REF
	  ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
	  : TREE_CODE (expr) == COMPONENT_REF
	  ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
	  : 0);
}

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

tree
objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
{
  tree result = NULL_TREE, outer;
  int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;

  /* This function is currently only used with the next runtime with
     garbage collection enabled (-fobjc-gc).  */
  gcc_assert (flag_next_runtime);

  /* See if we have any lhs casts, and strip them out.  NB: The lvalue casts
     will have been transformed to the form '*(type *)&expr'.  */
  if (INDIRECT_REF_P (lhs))
    {
      outer = TREE_OPERAND (lhs, 0);

      while (!strong_cast_p
	     && (CONVERT_EXPR_P (outer)
		 || TREE_CODE (outer) == NON_LVALUE_EXPR))
	{
	  tree lhstype = TREE_TYPE (outer);

	  /* Descend down the cast chain, and record the first objc_gc
	     attribute found.  */
	  if (POINTER_TYPE_P (lhstype))
	    {
	      tree attr
		= lookup_attribute ("objc_gc",
				    TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));

	      if (attr)
		strong_cast_p = 1;
	    }

	  outer = TREE_OPERAND (outer, 0);
	}
    }

  /* If we have a __strong cast, it trumps all else.  */
  if (strong_cast_p)
    {
      if (modifycode != NOP_EXPR)
        goto invalid_pointer_arithmetic;

      if (warn_assign_intercept)
	warning (0, "strong-cast assignment has been intercepted");

      result = objc_build_strong_cast_assignment (lhs, rhs);

      goto exit_point;
    }

  /* the lhs must be of a suitable type, regardless of its underlying
     structure.  */
  if (!objc_is_gcable_p (lhs))
    goto exit_point;

  outer = lhs;

  while (outer
	 && (TREE_CODE (outer) == COMPONENT_REF
	     || TREE_CODE (outer) == ARRAY_REF))
    outer = TREE_OPERAND (outer, 0);

  if (INDIRECT_REF_P (outer))
    {
      outer = TREE_OPERAND (outer, 0);
      indirect_p = 1;
    }

  outer_gc_p = objc_is_gcable_p (outer);

  /* Handle ivar assignments. */
  if (objc_is_ivar_reference_p (lhs))
    {
      /* if the struct to the left of the ivar is not an Objective-C object (__strong
	 doesn't cut it here), the best we can do here is suggest a cast.  */
      if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
	{
	  /* We may still be able to use the global write barrier... */
	  if (!indirect_p && objc_is_global_reference_p (outer))
	    goto global_reference;

	 suggest_cast:
	  if (modifycode == NOP_EXPR)
	    {
	      if (warn_assign_intercept)
		warning (0, "strong-cast may possibly be needed");
	    }

	  goto exit_point;
	}

      if (modifycode != NOP_EXPR)
        goto invalid_pointer_arithmetic;

      if (warn_assign_intercept)
	warning (0, "instance variable assignment has been intercepted");

      result = objc_build_ivar_assignment (outer, lhs, rhs);

      goto exit_point;
    }

  /* Likewise, intercept assignment to global/static variables if their type is
     GC-marked.  */
  if (objc_is_global_reference_p (outer))
    {
      if (indirect_p)
	goto suggest_cast;

     global_reference:
      if (modifycode != NOP_EXPR)
	{
	 invalid_pointer_arithmetic:
	  if (outer_gc_p)
	    warning (0, "pointer arithmetic for garbage-collected objects not allowed");

	  goto exit_point;
	}

      if (warn_assign_intercept)
	warning (0, "global/static variable assignment has been intercepted");

      result = objc_build_global_assignment (lhs, rhs);
    }

  /* In all other cases, fall back to the normal mechanism.  */
 exit_point:
  return result;
}

/* Implementation of the table mapping a class name (as an identifier)
   to a class node.  The two public functions for it are
   lookup_interface() and add_interface().  add_interface() is only
   used in this file, so we can make it static.  */

static GTY(()) objc_map_t interface_map;

static void
interface_hash_init (void)
{
  interface_map = objc_map_alloc_ggc (200);
}

static tree
add_interface (tree class_name, tree name)
{
  /* Put interfaces on list in reverse order.  */
  TREE_CHAIN (class_name) = interface_chain;
  interface_chain = class_name;

  /* Add it to the map.  */
  objc_map_put (interface_map, name, class_name);

  return interface_chain;
}

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;

  {
    tree interface = objc_map_get (interface_map, ident);

    if (interface == OBJC_MAP_NOT_FOUND)
      return NULL_TREE;
    else
      return interface;
  }
}



/* 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 %qE",
	 class_name);

  return error_mark_node;
}


/* Functions used by the hashtable for field duplicates in
   objc_detect_field_duplicates().  Ideally, we'd use a standard
   key-value dictionary hashtable , and store as keys the field names,
   and as values the actual declarations (used to print nice error
   messages with the locations).  But, the hashtable we are using only
   allows us to store keys in the hashtable, without values (it looks
   more like a set).  So, we store the DECLs, but define equality as
   DECLs having the same name, and hash as the hash of the name.  */

struct decl_name_hash : nofree_ptr_hash <tree_node>
{
  static inline hashval_t hash (const tree_node *);
  static inline bool equal (const tree_node *, const tree_node *);
};

inline hashval_t
decl_name_hash::hash (const tree_node *q)
{
  return (hashval_t) ((intptr_t)(DECL_NAME (q)) >> 3);
}

inline bool
decl_name_hash::equal (const tree_node *a, const tree_node *b)
{
  return DECL_NAME (a) == DECL_NAME (b);
}

/* Called when checking the variables in a struct.  If we are not
   doing the ivars list inside an @interface context, then return
   false.  Else, perform the check for duplicate ivars, then return
   true.  The check for duplicates checks if an instance variable with
   the same name exists in the class or in a superclass.  If
   'check_superclasses_only' is set to true, then it is assumed that
   checks for instance variables in the same class has already been
   performed (this is the case for ObjC++) and only the instance
   variables of superclasses are checked.  */
bool
objc_detect_field_duplicates (bool check_superclasses_only)
{
  if (!objc_collecting_ivars || !objc_interface_context
      || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE)
    return false;

  /* We have two ways of doing this check:

  "direct comparison": we iterate over the instance variables and
  compare them directly.  This works great for small numbers of
  instance variables (such as 10 or 20), which are extremely common.
  But it will potentially take forever for the pathological case with
  a huge number (eg, 10k) of instance variables.

  "hashtable": we use a hashtable, which requires a single sweep
  through the list of instances variables.  This is much slower for a
  small number of variables, and we only use it for large numbers.

  To decide which one to use, we need to get an idea of how many
  instance variables we have to compare.  */
  {
    unsigned int number_of_ivars_to_check = 0;
    {
      tree ivar;
      for (ivar = CLASS_RAW_IVARS (objc_interface_context);
	   ivar; ivar = DECL_CHAIN (ivar))
	{
	  /* Ignore anonymous ivars.  */
	  if (DECL_NAME (ivar))
	    number_of_ivars_to_check++;
	}
    }

    /* Exit if there is nothing to do.  */
    if (number_of_ivars_to_check == 0)
      return true;

    /* In case that there are only 1 or 2 instance variables to check,
       we always use direct comparison.  If there are more, it is
       worth iterating over the instance variables in the superclass
       to count how many there are (note that this has the same cost
       as checking 1 instance variable by direct comparison, which is
       why we skip this check in the case of 1 or 2 ivars and just do
       the direct comparison) and then decide if it worth using a
       hashtable.  */
    if (number_of_ivars_to_check > 2)
      {
	unsigned int number_of_superclass_ivars = 0;
	{
	  tree interface;
	  for (interface = lookup_interface (CLASS_SUPER_NAME (objc_interface_context));
	       interface; interface = lookup_interface (CLASS_SUPER_NAME (interface)))
	    {
	      tree ivar;
	      for (ivar = CLASS_RAW_IVARS (interface);
		   ivar; ivar = DECL_CHAIN (ivar))
		number_of_superclass_ivars++;
	    }
	}

	/* We use a hashtable if we have over 10k comparisons.  */
	if (number_of_ivars_to_check * (number_of_superclass_ivars
					+ (number_of_ivars_to_check / 2))
	    > 10000)
	  {
	    /* First, build the hashtable by putting all the instance
	       variables of superclasses in it.  */
	    hash_table<decl_name_hash> htab (37);
	    tree interface;
	    for (interface = lookup_interface (CLASS_SUPER_NAME
					       (objc_interface_context));
		 interface; interface = lookup_interface
		   (CLASS_SUPER_NAME (interface)))
	      {
		tree ivar;
		for (ivar = CLASS_RAW_IVARS (interface); ivar;
		     ivar = DECL_CHAIN (ivar))
		  {
		    if (DECL_NAME (ivar) != NULL_TREE)
		      {
			tree_node **slot = htab.find_slot (ivar, INSERT);
			/* Do not check for duplicate instance
			   variables in superclasses.  Errors have
			   already been generated.  */
			*slot = ivar;
		      }
		  }
	      }

	    /* Now, we go through all the instance variables in the
	       class, and check that they are not in the
	       hashtable.  */
	    if (check_superclasses_only)
	      {
		tree ivar;
		for (ivar = CLASS_RAW_IVARS (objc_interface_context); ivar;
		     ivar = DECL_CHAIN (ivar))
		  {
		    if (DECL_NAME (ivar) != NULL_TREE)
		      {
			tree duplicate_ivar = htab.find (ivar);
			if (duplicate_ivar != HTAB_EMPTY_ENTRY)
			  {
			    error_at (DECL_SOURCE_LOCATION (ivar),
				      "duplicate instance variable %q+D",
				      ivar);
			    inform (DECL_SOURCE_LOCATION (duplicate_ivar),
				    "previous declaration of %q+D",
				    duplicate_ivar);
			    /* FIXME: Do we need the following ?  */
			    /* DECL_NAME (ivar) = NULL_TREE; */
			  }
		      }
		  }
	      }
	    else
	      {
		/* If we're checking for duplicates in the class as
		   well, we insert variables in the hashtable as we
		   check them, so if a duplicate follows, it will be
		   caught.  */
		tree ivar;
		for (ivar = CLASS_RAW_IVARS (objc_interface_context); ivar;
		     ivar = DECL_CHAIN (ivar))
		  {
		    if (DECL_NAME (ivar) != NULL_TREE)
		      {
			tree_node **slot = htab.find_slot (ivar, INSERT);
			if (*slot)
			  {
			    tree duplicate_ivar = (tree)(*slot);
			    error_at (DECL_SOURCE_LOCATION (ivar),
				      "duplicate instance variable %q+D",
				      ivar);
			    inform (DECL_SOURCE_LOCATION (duplicate_ivar),
				    "previous declaration of %q+D",
				    duplicate_ivar);
			    /* FIXME: Do we need the following ?  */
			    /* DECL_NAME (ivar) = NULL_TREE; */
			  }
			*slot = ivar;
		      }
		  }
	      }
	    return true;
	  }
      }
  }

  /* This is the "direct comparison" approach, which is used in most
     non-pathological cases.  */
  {
    /* Walk up to class hierarchy, starting with this class (this is
       the external loop, because lookup_interface() is expensive, and
       we want to do it few times).  */
    tree interface = objc_interface_context;

    if (check_superclasses_only)
      interface = lookup_interface (CLASS_SUPER_NAME (interface));

    for ( ; interface; interface = lookup_interface
	    (CLASS_SUPER_NAME (interface)))
      {
	tree ivar_being_checked;

	for (ivar_being_checked = CLASS_RAW_IVARS (objc_interface_context);
	     ivar_being_checked;
	     ivar_being_checked = DECL_CHAIN (ivar_being_checked))
	  {
	    tree decl;

	    /* Ignore anonymous ivars.  */
	    if (DECL_NAME (ivar_being_checked) == NULL_TREE)
	      continue;

	    /* Note how we stop when we find the ivar we are checking
	       (this can only happen in the main class, not
	       superclasses), to avoid comparing things twice
	       (otherwise, for each ivar, you'd compare A to B then B
	       to A, and get duplicated error messages).  */
	    for (decl = CLASS_RAW_IVARS (interface);
		 decl && decl != ivar_being_checked;
		 decl = DECL_CHAIN (decl))
	      {
		if (DECL_NAME (ivar_being_checked) == DECL_NAME (decl))
		  {
		    error_at (DECL_SOURCE_LOCATION (ivar_being_checked),
			      "duplicate instance variable %q+D",
			      ivar_being_checked);
		    inform (DECL_SOURCE_LOCATION (decl),
			    "previous declaration of %q+D",
			    decl);
		    /* FIXME: Do we need the following ?  */
		    /* DECL_NAME (ivar_being_checked) = NULL_TREE; */
		  }
	      }
	  }
      }
  }
  return true;
}

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

void
objc_maybe_warn_exceptions (location_t loc)
{
  /* -fobjc-exceptions is required to enable Objective-C exceptions.
     For example, on Darwin, ObjC exceptions require a sufficiently
     recent version of the runtime, so the user must ask for them
     explicitly.  On other platforms, at the moment -fobjc-exceptions
     triggers -fexceptions which again is required for exceptions to
     work.  */
  if (!flag_objc_exceptions)
    {
      /* Warn only once per compilation unit.  */
      static bool warned = false;

      if (!warned)
	{
	  error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
	  warned = true;
	}
    }
}

static struct objc_try_context *cur_try_context;

/* 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 = XCNEW (struct objc_try_context);
  c->outer = cur_try_context;
  c->try_body = body;
  c->try_locus = try_locus;
  c->end_try_locus = input_location;
  cur_try_context = c;

  /* Collect the list of local variables.  We'll mark them as volatile
     at the end of compilation of this function to prevent them being
     clobbered by setjmp/longjmp.  */
  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.  If DECL is NULL_TREE, then we are compiling "@catch(...)"
   which we compile as "@catch(id tmp_variable)".  */

void
objc_begin_catch_clause (tree decl)
{
  tree compound, type, t;
  bool ellipsis = false;

  /* Begin a new scope that the entire catch clause will live in.  */
  compound = c_begin_compound_stmt (true);

  /* Create the appropriate declaration for the argument.  */
 if (decl == error_mark_node)
   type = error_mark_node;
 else
   {
     if (decl == NULL_TREE)
       {
	 /* If @catch(...) was specified, create a temporary variable of
	    type 'id' and use it.  */
	 decl = objc_create_temporary_var (objc_object_type, "__objc_generic_catch_var");
	 DECL_SOURCE_LOCATION (decl) = input_location;
	 /* ... but allow the runtime to differentiate between ellipsis and the
	    case of @catch (id xyz).  */
	 ellipsis = true;
       }
     else
       {
	 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL.  */
	 decl = build_decl (input_location,
			    VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
       }
     lang_hooks.decls.pushdecl (decl);

     /* Mark the declaration as used so you never any warnings whether
	you use the exception argument or not.  TODO: Implement a
	-Wunused-exception-parameter flag, which would cause warnings
	if exception parameter is not used.  */
     TREE_USED (decl) = 1;
     DECL_READ_P (decl) = 1;

     type = TREE_TYPE (decl);
   }

  /* 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).  */
  if (type == error_mark_node)
    {
      ;/* Just keep going.  */
    }
  else if (!objc_type_valid_for_messaging (type, false))
    {
      error ("%<@catch%> parameter is not a known Objective-C class type");
      type = error_mark_node;
    }
  else if (TYPE_HAS_OBJC_INFO (TREE_TYPE (type))
	   && TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (type)))
    {
      error ("%<@catch%> parameter cannot be protocol-qualified");
      type = error_mark_node;
    }
  else if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
    /* @catch (id xyz) or @catch (...) but we note this for runtimes that
       identify 'id'.  */
    ;
  else
    {
      /* If 'type' was built using typedefs, we need to get rid of
	 them and get a simple pointer to the class.  */
      bool is_typedef = false;
      tree x = TYPE_MAIN_VARIANT (type);

      /* Skip from the pointer to the pointee.  */
      if (TREE_CODE (x) == POINTER_TYPE)
	x = TREE_TYPE (x);

      /* Traverse typedef aliases */
      while (TREE_CODE (x) == RECORD_TYPE && OBJC_TYPE_NAME (x)
	     && TREE_CODE (OBJC_TYPE_NAME (x)) == TYPE_DECL
	     && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (x)))
	{
	  is_typedef = true;
	  x = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (x));
	}

      /* If it was a typedef, build a pointer to the final, original
	 class.  */
      if (is_typedef)
	type = build_pointer_type (x);

      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_at  (EXPR_LOCATION (stmt), 0, "   by earlier handler for %<%T%>",
			       TREE_TYPE (t ? t : objc_object_type));
		  break;
		}
	    }
	}
    }

  t = (*runtime.begin_catch) (&cur_try_context, type, decl, compound, ellipsis);
  add_stmt (t);
}

/* 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 (input_location, CATCH_BODY (c), 1);

  (*runtime.finish_catch) (&cur_try_context, c);
}

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

  stmt = (*runtime.finish_try_stmt) (&cur_try_context);
  add_stmt (stmt);

  cur_try_context = c->outer;
  free (c);
  return stmt;
}

tree
objc_build_throw_stmt (location_t loc, tree throw_expr)
{
  bool rethrown = false;

  objc_maybe_warn_exceptions (loc);

  /* Don't waste time trying to build something if we're already dead.  */
  if (throw_expr == error_mark_node)
    return error_mark_node;

  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_at (loc,
		    "%<@throw%> (rethrow) used outside of a %<@catch%> block");
	  return error_mark_node;
	}

      /* Otherwise the object is still sitting in the EXC_PTR_EXPR
	 value that we get from the runtime.  */
      throw_expr = (*runtime.build_exc_ptr) (&cur_try_context);
      rethrown = true;
    }
  else
    {
      if (!objc_type_valid_for_messaging (TREE_TYPE (throw_expr), true))
	{
	  error_at (loc, "%<@throw%> argument is not an object");
	  return error_mark_node;
	}
    }

  return (*runtime.build_throw_stmt) (loc, throw_expr, rethrown);
}

tree
objc_build_synchronized (location_t start_locus, tree object_expr, tree body)
{
  /* object_expr should never be NULL; but in case it is, convert it to
     error_mark_node.  */
  if (object_expr == NULL)
    object_expr = error_mark_node;

  /* Validate object_expr.  If not valid, set it to error_mark_node.  */
  if (object_expr != error_mark_node)
    {
      if (!objc_type_valid_for_messaging (TREE_TYPE (object_expr), true))
	{
	  error_at (start_locus, "%<@synchronized%> argument is not an object");
	  object_expr = error_mark_node;
	}
    }

  if (object_expr == error_mark_node)
    {
      /* If we found an error, we simply ignore the '@synchronized'.
	 Compile the body so we can keep going with minimal
	 casualties.  */
      return add_stmt (body);
    }
  else
    {
      tree call;
      tree args;

      /* objc_sync_enter (object_expr); */
      object_expr = save_expr (object_expr);
      args = tree_cons (NULL, object_expr, NULL);
      call = build_function_call (input_location,
				  objc_sync_enter_decl, args);
      SET_EXPR_LOCATION (call, start_locus);
      add_stmt (call);

      /* Build "objc_sync_exit (object_expr);" but do not add it yet;
	 it goes inside the @finalize() clause.  */
      args = tree_cons (NULL, object_expr, NULL);
      call = build_function_call (input_location,
				  objc_sync_exit_decl, args);
      SET_EXPR_LOCATION (call, input_location);

      /* @try { body; } */
      objc_begin_try_stmt (start_locus, body);

      /* @finally { objc_sync_exit (object_expr); } */
      objc_build_finally_clause (input_location, call);

      /* End of try statement.  */
      return objc_finish_try_stmt ();
    }
}

/* 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 klass)
{
  if (!CLASS_STATIC_TEMPLATE (klass))
    {
      tree record = objc_build_struct (klass,
				       get_class_ivars (klass, false),
				       CLASS_SUPER_NAME (klass));

      /* Set the TREE_USED bit for this struct, so that stab generator
	 can emit stabs for this struct type.  */
      if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
	TREE_USED (TYPE_STUB_DECL (record)) = 1;

      /* Copy the attributes from the class to the type.  */
      if (TREE_DEPRECATED (klass))
	TREE_DEPRECATED (record) = 1;
      if (TREE_UNAVAILABLE (klass))
	TREE_UNAVAILABLE (record) = 1;
    }
}

/* 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_start_method_definition
    (false /* is_class_method */,
     objc_build_method_signature (false /* is_class_method */,
				  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),
				  false), NULL, 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 (MAYBE_CLASS_TYPE_P (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, type, LOOKUP_NORMAL, tf_warning_or_error));
	}
    }

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

  /* Error case, due to possibly an extra @end. */
  if (!objc_implementation_context)
    return;

  /* 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 (MAYBE_CLASS_TYPE_P (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 the runtime needs it.  */
  imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
}
#endif

static void
error_with_ivar (const char *message, tree decl)
{
  error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
	    message, identifier_to_locale (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)
#ifdef OBJCPLUS
	  || !tree_int_cst_equal (DECL_BIT_FIELD_REPRESENTATIVE (intdecls),
				  DECL_BIT_FIELD_REPRESENTATIVE (impdecls))
#else
	  || !tree_int_cst_equal (DECL_INITIAL (intdecls),
				  DECL_INITIAL (impdecls))
#endif
	 )
	{
	  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 = DECL_CHAIN (intdecls);
      impdecls = DECL_CHAIN (impdecls);
    }
}


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_node::get_create (METHOD_DEFINITION (chain))->mark_force_output ();
	  chain = DECL_CHAIN (chain);
	}

      chain = CLASS_NST_METHODS (impent->imp_context);
      while (chain)
	{
	  cgraph_node::get_create (METHOD_DEFINITION (chain))->mark_force_output ();
	  chain = DECL_CHAIN (chain);
	}
    }
}

/* If type is empty or only type qualifiers are present, add default
   type of id (otherwise grokdeclarator will default to int).  */
static inline 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 ("cannot use an object as parameter to a method");

  return type;
}

/* Return a KEYWORD_DECL built using the specified key_name, arg_type,
   arg_name and attributes. (TODO: Rename KEYWORD_DECL to
   OBJC_METHOD_PARM_DECL ?)

   A KEYWORD_DECL is a tree representing the declaration of a
   parameter of an Objective-C method.  It is produced when parsing a
   fragment of Objective-C method declaration of the form

   keyworddecl:
     selector ':' '(' typename ')' identifier

   For example, take the Objective-C method

   -(NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type;

   the two fragments "pathForResource:(NSString *)resource" and
   "ofType:(NSString *)type" will generate a KEYWORD_DECL each.  The
   KEYWORD_DECL stores the 'key_name' (eg, identifier for
   "pathForResource"), the 'arg_type' (eg, tree representing a
   NSString *), the 'arg_name' (eg identifier for "resource") and
   potentially some attributes (for example, a tree representing
   __attribute__ ((unused)) if such an attribute was attached to a
   certain parameter).  You can access this information using the
   TREE_TYPE (for arg_type), KEYWORD_ARG_NAME (for arg_name),
   KEYWORD_KEY_NAME (for key_name), DECL_ATTRIBUTES (for attributes).

   'key_name' is an identifier node (and is optional as you can omit
   it in Objective-C methods).
   'arg_type' is a tree list (and is optional too if no parameter type
   was specified).
   'arg_name' is an identifier node and is required.
   'attributes' is an optional tree containing parameter attributes.  */
tree
objc_build_keyword_decl (tree key_name, tree arg_type,
			 tree arg_name, tree attributes)
{
  tree keyword_decl;

  if (flag_objc1_only && attributes)
    error_at (input_location, "method argument attributes are not available in Objective-C 1.0");

  /* 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;
  KEYWORD_KEY_NAME (keyword_decl) = key_name;
  DECL_ATTRIBUTES (keyword_decl) = attributes;

  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))
    {
      switch (TREE_CODE (selector))
	{
	case KEYWORD_DECL:
	  key_name = KEYWORD_KEY_NAME (key_chain);
	  break;
	case TREE_LIST:
	  key_name = TREE_PURPOSE (key_chain);
	  break;
	default:
	  gcc_unreachable ();
	}

      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))
    {
      switch (TREE_CODE (selector))
	{
	case KEYWORD_DECL:
	  key_name = KEYWORD_KEY_NAME (key_chain);
	  break;
	case 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;
	  break;
	default:
	  gcc_unreachable ();
	}

      if (key_name)
	strcat (buf, IDENTIFIER_POINTER (key_name));
      strcat (buf, ":");
    }

  return get_identifier_with_length (buf, len);
}

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

  /* Note how a method_decl has a TREE_TYPE which is not the function
     type of the function implementing the method, but only the return
     type of the method.  We may want to change this, and store the
     entire function type in there (eg, it may be used to simplify
     dealing with attributes below).  */
  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;
}

/* This routine processes objective-c method attributes. */

static void
objc_decl_method_attributes (tree *node, tree attributes, int flags)
{
  /* TODO: Replace the hackery below.  An idea would be to store the
     full function type in the method declaration (for example in
     TREE_TYPE) and then expose ObjC method declarations to c-family
     and they could deal with them by simply treating them as
     functions.  */

  /* Because of the dangers in the hackery below, we filter out any
     attribute that we do not know about.  For the ones we know about,
     we know that they work with the hackery.  For the other ones,
     there is no guarantee, so we have to filter them out.  */
  tree filtered_attributes = NULL_TREE;

  if (attributes)
    {
      tree attribute;
      for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
	{
	  tree name = TREE_PURPOSE (attribute);

	  if (is_attribute_p  ("deprecated", name)
	      || is_attribute_p ("unavailable", name)
	      || is_attribute_p ("sentinel", name)
	      || is_attribute_p ("noreturn", name))
	    {
	      /* An attribute that we support; add it to the filtered
		 attributes.  */
	      filtered_attributes = chainon (filtered_attributes,
					     copy_node (attribute));
	    }
	  else if (is_attribute_p ("format", name))
	    {
	      /* "format" is special because before adding it to the
		 filtered attributes we need to adjust the specified
		 format by adding the hidden function parameters for
		 an Objective-C method (self, _cmd).  */
	      tree new_attribute = copy_node (attribute);

	      /* Check the arguments specified with the attribute, and
		 modify them adding 2 for the two hidden arguments.
		 Note how this differs from C++; according to the
		 specs, C++ does not do it so you have to add the +1
		 yourself.  For Objective-C, instead, the compiler
		 adds the +2 for you.  */

	      /* The attribute arguments have not been checked yet, so
		 we need to be careful as they could be missing or
		 invalid.  If anything looks wrong, we skip the
		 process and the compiler will complain about it later
		 when it validates the attribute.  */
	      /* Check that we have at least three arguments.  */
	      if (TREE_VALUE (new_attribute)
		  && TREE_CHAIN (TREE_VALUE (new_attribute))
		  && TREE_CHAIN (TREE_CHAIN (TREE_VALUE (new_attribute))))
		{
		  tree second_argument = TREE_CHAIN (TREE_VALUE (new_attribute));
		  tree third_argument = TREE_CHAIN (second_argument);
		  tree number;

		  /* This is the second argument, the "string-index",
		     which specifies the index of the format string
		     argument.  Add 2.  */
		  number = TREE_VALUE (second_argument);
		  if (number
		      && TREE_CODE (number) == INTEGER_CST
		      && wi::to_wide (number) != 0)
		    TREE_VALUE (second_argument)
		      = wide_int_to_tree (TREE_TYPE (number),
					  wi::to_wide (number) + 2);

		  /* This is the third argument, the "first-to-check",
		     which specifies the index of the first argument to
		     check.  This could be 0, meaning it is not available,
		     in which case we don't need to add 2.  Add 2 if not
		     0.  */
		  number = TREE_VALUE (third_argument);
		  if (number
		      && TREE_CODE (number) == INTEGER_CST
		      && wi::to_wide (number) != 0)
		    TREE_VALUE (third_argument)
		      = wide_int_to_tree (TREE_TYPE (number),
					  wi::to_wide (number) + 2);
		}
	      filtered_attributes = chainon (filtered_attributes,
					     new_attribute);
	    }
	  else if (is_attribute_p ("nonnull", name))
	    {
	      /* We need to fixup all the argument indexes by adding 2
		 for the two hidden arguments of an Objective-C method
		 invocation, similat to what we do above for the
		 "format" attribute.  */
	      /* FIXME: This works great in terms of implementing the
		 functionality, but the warnings that are produced by
		 nonnull do mention the argument index (while the
		 format ones don't).  For example, you could get
		 "warning: null argument where non-null required
		 (argument 3)".  Now in that message, "argument 3"
		 includes the 2 hidden arguments; it would be much
		 more friendly to call it "argument 1", as that would
		 be consistent with __attribute__ ((nonnnull (1))).
		 To do this, we'd need to have the C family code that
		 checks the arguments know about adding/removing 2 to
		 the argument index ... or alternatively we could
		 maybe store the "printable" argument index in
		 addition to the actual argument index ?  Some
		 refactoring is needed to do this elegantly.  */
	      tree new_attribute = copy_node (attribute);
	      tree argument = TREE_VALUE (attribute);
	      while (argument != NULL_TREE)
		{
		  /* Get the value of the argument and add 2.  */
		  tree number = TREE_VALUE (argument);
		  if (number && TREE_CODE (number) == INTEGER_CST
		      && wi::to_wide (number) != 0)
		    TREE_VALUE (argument)
		      = wide_int_to_tree (TREE_TYPE (number),
					  wi::to_wide (number) + 2);
		  argument = TREE_CHAIN (argument);
		}

	      filtered_attributes = chainon (filtered_attributes,
					     new_attribute);
	    }
	  else
	    warning (OPT_Wattributes, "%qE attribute directive ignored", name);
	}
    }

  if (filtered_attributes)
    {
      /* This hackery changes the TREE_TYPE of the ObjC method
	 declaration to be a function type, so that decl_attributes
	 will treat the ObjC method as if it was a function.  Some
	 attributes (sentinel, format) will be applied to the function
	 type, changing it in place; so after calling decl_attributes,
	 we extract the function type attributes and store them in
	 METHOD_TYPE_ATTRIBUTES.  Some other attributes (noreturn,
	 deprecated) are applied directly to the method declaration
	 (by setting TREE_DEPRECATED and TREE_THIS_VOLATILE) so there
	 is nothing to do.  */
      tree saved_type = TREE_TYPE (*node);
      TREE_TYPE (*node)
	= build_function_type_for_method (TREE_VALUE (saved_type), *node,
					  METHOD_REF, 0);
      decl_attributes (node, filtered_attributes, flags);
      METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
      TREE_TYPE (*node) = saved_type;
    }
}

bool
objc_method_decl (enum tree_code opcode)
{
  return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
}

/* Return a function type for METHOD with RETURN_TYPE.  CONTEXT is
   either METHOD_DEF or METHOD_REF, indicating whether we are defining a
   method or calling one.  SUPER_FLAG indicates whether this is 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 METHOD is
   NULL, user-defined arguments (i.e., beyond self and _cmd) shall be
   represented as varargs.  */

tree
build_function_type_for_method (tree return_type, tree method,
				int context, bool super_flag)
{
  vec<tree, va_gc> *argtypes = make_tree_vector ();
  tree t, ftype;
  bool is_varargs = false;

  (*runtime.get_arg_type_list_base) (&argtypes, method, context, super_flag);

  /* No actual method prototype given; remaining args passed as varargs.  */
  if (method == NULL_TREE)
    {
      is_varargs = true;
      goto build_ftype;
    }

  for (t = METHOD_SEL_ARGS (method); t; t = DECL_CHAIN (t))
    {
      tree arg_type = TREE_VALUE (TREE_TYPE (t));

      /* Decay argument types for the underlying C function as
         appropriate.  */
      arg_type = objc_decay_parm_type (arg_type);

      vec_safe_push (argtypes, arg_type);
    }

  if (METHOD_ADD_ARGS (method))
    {
      for (t = TREE_CHAIN (METHOD_ADD_ARGS (method));
	   t; t = TREE_CHAIN (t))
	{
	  tree arg_type = TREE_TYPE (TREE_VALUE (t));

	  arg_type = objc_decay_parm_type (arg_type);

	  vec_safe_push (argtypes, arg_type);
	}

      if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
	is_varargs = true;
    }

 build_ftype:
  if (is_varargs)
    ftype = build_varargs_function_type_vec (return_type, argtypes);
  else
    ftype = build_function_type_vec (return_type, argtypes);

  release_tree_vector (argtypes);
  return ftype;
}

/* The 'method' argument is a tree; this tree could either be a single
   method, which is returned, or could be a TREE_VEC containing a list
   of methods.  In that case, the first one is returned, and warnings
   are issued as appropriate.  */
static tree
check_duplicates (tree method, int methods, int is_class)
{
  tree first_method;
  size_t i;

  if (method == NULL_TREE)
    return NULL_TREE;

  if (TREE_CODE (method) != TREE_VEC)
    return method;

  /* We have two or more methods with the same name but different
     types.  */
  first_method = TREE_VEC_ELT (method, 0);

  /* 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 (i = 0; i < (size_t) TREE_VEC_LENGTH (method); i++)
	if (!comp_proto_with_proto (first_method, TREE_VEC_ELT (method, i), 0))
	  goto issue_warning;

      return first_method;
    }

 issue_warning:
  if (methods)
    {
      bool type = TREE_CODE (first_method) == INSTANCE_METHOD_DECL;

      warning_at (input_location, 0,
		  "multiple methods named %<%c%E%> found",
		  (is_class ? '+' : '-'),
		  METHOD_SEL_NAME (first_method));
      inform (DECL_SOURCE_LOCATION (first_method), "using %<%c%s%>",
	      (type ? '-' : '+'),
	      identifier_to_locale (gen_method_decl (first_method)));
    }
  else
    {
      bool type = TREE_CODE (first_method) == INSTANCE_METHOD_DECL;

      warning_at (input_location, 0,
		  "multiple selectors named %<%c%E%> found",
		  (is_class ? '+' : '-'),
		  METHOD_SEL_NAME (first_method));
      inform (DECL_SOURCE_LOCATION (first_method), "found %<%c%s%>",
	      (type ? '-' : '+'),
	      identifier_to_locale (gen_method_decl (first_method)));
    }

  for (i = 0; i < (size_t) TREE_VEC_LENGTH (method); i++)
    {
      bool type = TREE_CODE (TREE_VEC_ELT (method, i)) == INSTANCE_METHOD_DECL;

      inform (DECL_SOURCE_LOCATION (TREE_VEC_ELT (method, i)), "also found %<%c%s%>",
	      (type ? '-' : '+'),
	      identifier_to_locale (gen_method_decl (TREE_VEC_ELT (method, i))));
    }

  return first_method;
}

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

  /* The runtime might encapsulate things its own way.  */
  exp = (*runtime.receiver_is_class_object) (receiver);
  if (exp)
    return exp;

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

     This is required by the GNU runtime, which compiles

       [NSObject alloc]

     into

       [objc_get_class ("NSObject") alloc];

     and then, to check that the receiver responds to the +alloc
     method, needs to be able to determine that the objc_get_class()
     call returns the NSObject class and not just a generic Class
     pointer.

     But, traditionally this is enabled for all runtimes, not just the
     GNU one, which means that the compiler is smarter than you'd
     expect when dealing with objc_getClass().  For example, with the
     Apple runtime, in the code

       [objc_getClass ("NSObject")  alloc];

     the compiler will recognize the objc_getClass() call as special
     (due to the code below) and so will know that +alloc is called on
     the 'NSObject' class, and can perform the corresponding checks.

     Programmers can disable this behavior by casting the results of
     objc_getClass() to 'Class' (this may seem weird because
     objc_getClass() is already declared to return 'Class', but the
     compiler treats it as a special function).  This may be useful if
     the class is never declared, and the compiler would complain
     about a missing @interface for it.  Then, you can do

       [(Class)objc_getClass ("MyClassNeverDeclared")  alloc];

     to silence the warnings.  */
  if (TREE_CODE (receiver) == CALL_EXPR
      && (exp = CALL_EXPR_FN (receiver))
      && 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)), runtime.tag_getclass)
      /* We have a call to objc_get_class/objc_getClass!  */
      && (arg = CALL_EXPR_ARG (receiver, 0)))
    {
      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 receiver, tree message_args)
{
  tree sel_name;
#ifdef OBJCPLUS
  tree args = TREE_PURPOSE (message_args);
#else
  tree args = message_args;
#endif
  tree method_params = NULL_TREE;

  if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
    return error_mark_node;

  /* Obtain the full selector name.  */
  switch (TREE_CODE (args))
    {
    case IDENTIFIER_NODE:
      /* A unary selector.  */
      sel_name = args;
      break;
    case TREE_LIST:
      sel_name = build_keyword_selector (args);
      break;
    default:
      gcc_unreachable ();
    }

  /* Build the parameter list to give to the method.  */
  if (TREE_CODE (args) == TREE_LIST)
#ifdef OBJCPLUS
    method_params = chainon (args, TREE_VALUE (message_args));
#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_loc (UNKNOWN_LOCATION, MESSAGE_SEND_EXPR, receiver,
			     sel_name, method_params);
#endif

  return objc_finish_message_expr (receiver, sel_name, method_params, NULL);
}

/* 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)
{
  tree method_prototype = OBJC_MAP_NOT_FOUND;

  if (!is_class)
    method_prototype = objc_map_get (instance_method_map, sel_name);

  if (method_prototype == OBJC_MAP_NOT_FOUND)
    {
      method_prototype = objc_map_get (class_method_map, sel_name);
      is_class = 1;

      if (method_prototype == OBJC_MAP_NOT_FOUND)
	return NULL_TREE;
    }

  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.cc) after RECEIVER and METHOD_PARAMS have been expanded.

   If the method_prototype_avail argument is NULL, then we warn
   if the method being used is deprecated.  If it is not NULL, instead
   of deprecating, we set *method_prototype_avail to the method
   prototype that was used and is deprecated.  This is useful for
   getter calls that are always generated when compiling dot-syntax
   expressions, even if they may not be used.  In that case, we don't
   want the warning immediately; we produce it (if needed) at gimplify
   stage when we are sure that the deprecated getter is being
   used.  */
tree
objc_finish_message_expr (tree receiver, tree sel_name, tree method_params,
			  tree *method_prototype_avail)
{
  tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
  tree retval, class_tree;
  int self, super, have_cast;

  STRIP_ANY_LOCATION_WRAPPER (receiver);

  /* We have used the receiver, so mark it as read.  */
  mark_exp_read (receiver);

  /* 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).  */
  rtype = receiver;
  while (TREE_CODE (rtype) == COMPOUND_EXPR
	 || TREE_CODE (rtype) == MODIFY_EXPR
	 || CONVERT_EXPR_P (rtype)
	 || TREE_CODE (rtype) == COMPONENT_REF)
    rtype = TREE_OPERAND (rtype, 0);

  /* self is 1 if this is a message to self, 0 otherwise  */
  self = (rtype == self_decl);

  /* super is 1 if this is a message to super, 0 otherwise.  */
  super = (rtype == UOBJC_SUPER_decl);

  /* rtype is the type of the receiver.  */
  rtype = TREE_TYPE (receiver);

  /* have_cast is 1 if the receiver is casted.  */
  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;

  /* If the receiver is a class object, retrieve the corresponding
     @interface, if one exists.  class_tree is the class name
     identifier, or NULL_TREE if this is not a class method or the
     class name could not be determined (as in the case "Class c; [c
     method];").  */
  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)
	{
	  /* We are here when we have no cast, and we have a class
	     name.  So, this is a plain method to a class object, as
	     in [NSObject alloc].  Find the interface corresponding to
	     the class name.  */
	  rtype = lookup_interface (class_tree);

	  if (rtype == NULL_TREE)
	    {
	      /* If 'rtype' is NULL_TREE at this point it means that
		 we have seen no @interface corresponding to that
		 class name, only a @class declaration (alternatively,
		 this was a call such as [objc_getClass("SomeClass")
		 alloc], where we've never seen the @interface of
		 SomeClass).  So, we have a class name (class_tree)
		 but no actual details of the class methods.  We won't
		 be able to check that the class responds to the
		 method, and we will have to guess the method
		 prototype.  Emit a warning, then keep going (this
		 will use any method with a matching name, as if the
		 receiver was of type 'Class').  */
	      warning (0, "%<@interface%> of class %qE not found",
		       class_tree);
	    }
	}
      /* Handle `self' and `super'.  */
      else if (super)
	{
	  if (!CLASS_SUPER_NAME (implementation_template))
	    {
	      error ("no super class declared in @interface for %qE",
		     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 (objc_is_id (rtype))
    {
      /* The receiver is of type 'id' or 'Class' (with or without some
	 protocols attached to it).  */

      /* We set class_tree to the identifier for 'Class' if this is a
	 class method, and to NULL_TREE if not.  */
      class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);

      /* 'rprotos' is the list of protocols that the receiver
	 supports.  */
      rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
		 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
		 : NULL_TREE);

      /* We have no information on the type, and we set it to
	 NULL_TREE.  */
      rtype = NULL_TREE;

      /* If there are any protocols, check that the method we are
	 calling appears in the protocol list.  If there are no
	 protocols, this is a message to 'id' or 'Class' and we accept
	 any method that exists.  */
      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 %<-%E%> instead of %<+%E%> in protocol(s)",
			 sel_name, sel_name);
	    }
	}
    }
  else if (rtype)
    {
      /* We have a receiver type which is more specific than 'id' or
	 'Class'.  */
      tree orig_rtype = 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));
      if (TYPED_OBJECT (rtype))
	{
	  rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
	  rtype = TYPE_OBJC_INTERFACE (rtype);
	}
      if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
	{
	  /* 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.  Note that this only happens
	     for instance methods; for class methods to a class where
	     we have only seen a @class declaration,
	     lookup_interface() above would have set rtype to
	     NULL_TREE.  */
	  if (rprotos)
	    {
	      /* We could not find an @interface declaration, yet, if
		 there are protocols attached to the type, we can
		 still look up the method in the protocols.  Ie, we
		 are in the following case:

		 @class MyClass;
		 MyClass<MyProtocol> *x;
		 [x method];

		 If 'MyProtocol' has the method 'method', we can check
		 and retrieve the method prototype.  */
	      method_prototype
		= lookup_method_in_protocol_list (rprotos, sel_name, 0);

	      /* At this point, if we have found the method_prototype,
		 we are quite happy.  The details of the class are
		 irrelevant.  If we haven't found it, a warning will
		 have been produced that the method could not be found
		 in the protocol, and we won't produce further
		 warnings (please note that this means that "@class
		 MyClass; MyClass <MyProtocol> *x;" is exactly
		 equivalent to "id <MyProtocol> x", which isn't too
		 satisfactory but it's not easy to see how to do
		 better).  */
	    }
	  else
	    {
	      if (rtype)
		{
		  /* We could not find an @interface declaration, and
		     there are no protocols attached to the receiver,
		     so we can't complete the check that the receiver
		     responds to the method, and we can't retrieve the
		     method prototype.  But, because the receiver has
		     a well-specified class, the programmer did want
		     this check to be performed.  Emit a warning, then
		     keep going as if it was an 'id'.  To remove the
		     warning, either include an @interface for the
		     class, or cast the receiver to 'id'.  Note that
		     rtype is an IDENTIFIER_NODE at this point.  */
		  warning (0, "%<@interface%> of class %qE not found", rtype);
		}
	    }

	  rtype = NULL_TREE;
	}
      else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
	  || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
	{
	  /* We have a valid ObjC class name with an associated
	     @interface.  Look up the method name in the published
	     @interface for the class (and its superclasses).  */
	  method_prototype
	    = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);

	  /* 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
	{
	  /* We have a type, but it's not an Objective-C type (!).  */
	  warning (0, "invalid receiver type %qs",
		   identifier_to_locale (gen_type_name (orig_rtype)));
	  /* After issuing the "invalid receiver" warning, perform method
	     lookup as if we were messaging 'id'.  */
	  rtype = rprotos = NULL_TREE;
	}
    }
  /* Note that rtype could also be NULL_TREE.  This happens if we are
     messaging a class by name, but the class was only
     forward-declared using @class.  */

  /* 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%E%> not found in protocol(s)",
		 (class_tree ? '+' : '-'),
		 sel_name);

      if (!rtype)
	method_prototype
	  = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
    }

  if (!method_prototype)
    {
      static bool warn_missing_methods = false;

      if (rtype)
	warning (0, "%qE may not respond to %<%c%E%>",
		 OBJC_TYPE_NAME (rtype),
		 (class_tree ? '+' : '-'),
		 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.  */
      else
	warning (0, "no %<%c%E%> method found",
		 (class_tree ? '+' : '-'),
		 sel_name);

      if (!warn_missing_methods)
	{
	  warning_at (input_location,
		      0, "(messages without a matching method signature "
		      "will be assumed to return %<id%> and accept "
		      "%<...%> as arguments)");
	  warn_missing_methods = true;
	}
    }
  else
    {
      /* Warn if the method is deprecated, but not if the receiver is
	 a generic 'id'.  'id' is used to cast an object to a generic
	 object of an unspecified class; in that case, we'll use
	 whatever method prototype we can find to get the method
	 argument and return types, but it is not appropriate to
	 produce deprecation warnings since we don't know the class
	 that the object will be of at runtime.  The @interface(s) for
	 that class may not even be available to the compiler right
	 now, and it is perfectly possible that the method is marked
	 as non-deprecated in such @interface(s).

	 In practice this makes sense since casting an object to 'id'
	 is often used precisely to turn off warnings associated with
	 the object being of a particular class.  */
      if (TREE_UNAVAILABLE (method_prototype) && rtype != NULL_TREE)
	{
	  if (method_prototype_avail)
	    *method_prototype_avail = method_prototype;
	  else
	    error_unavailable_use (method_prototype, NULL_TREE);
	}
      else if (TREE_DEPRECATED (method_prototype) && rtype != NULL_TREE)
	{
	  if (method_prototype_avail)
	    *method_prototype_avail = method_prototype;
	  else
	    warn_deprecated_use (method_prototype, NULL_TREE);
	}
    }

  /* Save the selector name for printing error messages.  */
  current_objc_message_selector = sel_name;

  /* Build the method call.
     TODO: Get the location from somewhere that will work for delayed
	   expansion.  */

  retval = (*runtime.build_objc_method_call) (input_location, method_prototype,
					      receiver, rtype, sel_name,
					      method_params, super);

  current_objc_message_selector = 0;

  return retval;
}


/* This routine creates a static variable used to implement @protocol(MyProtocol)
   expression. This variable will be initialized to global protocol_t meta-data
   pointer. */

/* 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 p = lookup_protocol (protoname, /* warn if deprecated */ true,
			    /* definition_required */ false);

  if (!p)
    {
      error ("cannot find protocol declaration for %qE", protoname);
      return error_mark_node;
    }

  return (*runtime.get_protocol_reference) (input_location, p);
}

/* 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().  LOC is the location of the
   @selector.  */
tree
objc_build_selector_expr (location_t loc, tree selnamelist)
{
  tree selname;

  /* Obtain the full selector name.  */
  switch (TREE_CODE (selnamelist))
    {
    case IDENTIFIER_NODE:
      /* A unary selector.  */
      selname = selnamelist;
      break;
    case TREE_LIST:
      selname = build_keyword_selector (selnamelist);
      break;
    default:
      gcc_unreachable ();
    }

  /* 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.  */
      tree method;

      /* First try with instance methods.  */
      method = objc_map_get (instance_method_map, selname);

      /* If not found, try with class methods.  */
      if (method == OBJC_MAP_NOT_FOUND)
	{
	  method = objc_map_get (class_method_map, selname);

	  /* If still not found, print out a warning.  */
	  if (method == OBJC_MAP_NOT_FOUND)
	    warning (0, "undeclared selector %qE", selname);
	}
    }

  /* The runtimes do this differently, most particularly, GNU has typed
     selectors, whilst NeXT does not.  */
  return (*runtime.build_selector_reference) (loc, selname, NULL_TREE);
}

static tree
build_ivar_reference (tree id)
{
  tree 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 %qE accessed in class method",
	       id);
      self_decl = convert (objc_instance_type, self_decl); /* cast */
    }

  base = build_indirect_ref (input_location, self_decl, RO_ARROW);
  return (*runtime.build_ivar_reference) (input_location, base, id);
}

static void
hash_init (void)
{
  instance_method_map = objc_map_alloc_ggc (1000);
  class_method_map = objc_map_alloc_ggc (1000);

  class_name_map = objc_map_alloc_ggc (200);
  alias_name_map = objc_map_alloc_ggc (200);

  /* Initialize the hash table used to hold the constant string objects.  */
  string_htab = hash_table<objc_string_hasher>::create_ggc (31);
}

/* Use the following to add a method to class_method_map or
   instance_method_map.  It will add the method, keyed by the
   METHOD_SEL_NAME.  If the method already exists, but with one or
   more different prototypes, it will store a TREE_VEC in the map,
   with the method prototypes in the vector.  */
static void
insert_method_into_method_map (bool class_method, tree method)
{
  tree method_name = METHOD_SEL_NAME (method);
  tree existing_entry;
  objc_map_t map;

  if (class_method)
    map = class_method_map;
  else
    map = instance_method_map;

  /* Check if the method already exists in the map.  */
  existing_entry = objc_map_get (map, method_name);

  /* If not, we simply add it to the map.  */
  if (existing_entry == OBJC_MAP_NOT_FOUND)
    objc_map_put (map, method_name, method);
  else
    {
      tree new_entry;

      /* If an entry already exists, it's more complicated.  We'll
	 have to check whether the method prototype is the same or
	 not.  */
      if (TREE_CODE (existing_entry) != TREE_VEC)
	{
	  /* If the method prototypes are the same, there is nothing
	     to do.  */
	  if (comp_proto_with_proto (method, existing_entry, 1))
	    return;

	  /* If not, create a vector to store both the method already
	     in the map, and the new one that we are adding.  */
	  new_entry = make_tree_vec (2);

	  TREE_VEC_ELT (new_entry, 0) = existing_entry;
	  TREE_VEC_ELT (new_entry, 1) = method;
	}
      else
	{
	  /* An entry already exists, and it's already a vector.  This
	     means that at least 2 different method prototypes were
	     already found, and we're considering registering yet
	     another one.  */
	  size_t i;

	  /* Check all the existing prototypes.  If any matches the
	     one we need to add, there is nothing to do because it's
	     already there.  */
	  for (i = 0; i < (size_t) TREE_VEC_LENGTH (existing_entry); i++)
	    if (comp_proto_with_proto (method, TREE_VEC_ELT (existing_entry, i), 1))
	      return;

	  /* Else, create a new, bigger vector and add the new method
	     at the end of it.  This is inefficient but extremely
	     rare; in any sane program most methods have a single
	     prototype, and very few, if any, will have more than
	     2!  */
	  new_entry = make_tree_vec (TREE_VEC_LENGTH (existing_entry) + 1);

	  /* Copy the methods from the existing vector.  */
	  for (i = 0; i < (size_t) TREE_VEC_LENGTH (existing_entry); i++)
	    TREE_VEC_ELT (new_entry, i) = TREE_VEC_ELT (existing_entry, i);

	  /* Add the new method at the end.  */
	  TREE_VEC_ELT (new_entry, i) = method;
	}

      /* Store the new vector in the map.  */
      objc_map_put (map, method_name, new_entry);
    }
}


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 = DECL_CHAIN (mchain);
    }
  return NULL_TREE;
}

/* 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 clear, 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.  This behavior can be turned off by using
   OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS.

   If a suitable method cannot be found, return NULL_TREE.  */

static tree
lookup_method_static (tree interface, tree ident, int flags)
{
  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);
  int no_instance_methods_of_root_class = (flags & OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS);

  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.  */
      if ((meth = lookup_method (chain, ident)))
	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.  */
	  if ((meth = lookup_method (chain, ident)))
	    return meth;

	  /* Failing that, check in each category's protocols.  */
	  if (CLASS_PROTOCOL_LIST (category))
	    {
	      if ((meth = (lookup_method_in_protocol_list
			   (CLASS_PROTOCOL_LIST (category), ident, is_class))))
		return meth;
	    }
	}

      /* If not found in categories, check in protocols of the main class.  */
      if (CLASS_PROTOCOL_LIST (inter))
	{
	  if ((meth = (lookup_method_in_protocol_list
		       (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
	    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 (is_class && !no_instance_methods_of_root_class)
    {
      /* 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.  */
      return lookup_method_static (root_inter, ident, 0);
    }
  else
    {
      /* If an instance method was not found, return 0.  */
      return NULL_TREE;
    }
}

static tree
objc_add_method (tree klass, tree method, int is_class, bool is_optional)
{
  tree existing_method = NULL_TREE;

  /* The first thing we do is look up the method in the list of
     methods already defined in the interface (or implementation).  */
  if (is_class)
    existing_method = lookup_method (CLASS_CLS_METHODS (klass), method);
  else
    existing_method = lookup_method (CLASS_NST_METHODS (klass), method);

  /* In the case of protocols, we have a second list of methods to
     consider, the list of optional ones.  */
  if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE)
    {
      /* @required methods are added to the protocol's normal list.
	 @optional methods are added to the protocol's OPTIONAL lists.
	 Note that adding the methods to the optional lists disables
	 checking that the methods are implemented by classes
	 implementing the protocol, since these checks only use the
	 CLASS_CLS_METHODS and CLASS_NST_METHODS.  */

      /* First of all, if the method to add is @optional, and we found
	 it already existing as @required, emit an error.  */
      if (is_optional && existing_method)
	{
	  error ("method %<%c%E%> declared %<@optional%> and %<@required%> at the same time",
		 (is_class ? '+' : '-'),
		 METHOD_SEL_NAME (existing_method));
	  inform (DECL_SOURCE_LOCATION (existing_method),
		  "previous declaration of %<%c%E%> as %<@required%>",
		  (is_class ? '+' : '-'),
		  METHOD_SEL_NAME (existing_method));
	}

      /* Now check the list of @optional methods if we didn't find the
	 method in the @required list.  */
      if (!existing_method)
	{
	  if (is_class)
	    existing_method = lookup_method (PROTOCOL_OPTIONAL_CLS_METHODS (klass), method);
	  else
	    existing_method = lookup_method (PROTOCOL_OPTIONAL_NST_METHODS (klass), method);

	  if (!is_optional && existing_method)
	    {
	      error ("method %<%c%E%> declared %<@optional%> and %<@required%> at the same time",
		     (is_class ? '+' : '-'),
		     METHOD_SEL_NAME (existing_method));
	      inform (DECL_SOURCE_LOCATION (existing_method),
		      "previous declaration of %<%c%E%> as %<@optional%>",
		      (is_class ? '+' : '-'),
		      METHOD_SEL_NAME (existing_method));
	    }
	}
    }

  /* If the method didn't exist already, add it.  */
  if (!existing_method)
    {
      if (is_optional)
	{
	  if (is_class)
	    {
	      /* Put the method on the list in reverse order.  */
	      TREE_CHAIN (method) = PROTOCOL_OPTIONAL_CLS_METHODS (klass);
	      PROTOCOL_OPTIONAL_CLS_METHODS (klass) = method;
	    }
	  else
	    {
	      TREE_CHAIN (method) = PROTOCOL_OPTIONAL_NST_METHODS (klass);
	      PROTOCOL_OPTIONAL_NST_METHODS (klass) = method;
	    }
	}
      else
	{
	  if (is_class)
	    {
	      DECL_CHAIN (method) = CLASS_CLS_METHODS (klass);
	      CLASS_CLS_METHODS (klass) = method;
	    }
	  else
	    {
	      DECL_CHAIN (method) = CLASS_NST_METHODS (klass);
	      CLASS_NST_METHODS (klass) = method;
	    }
	}
    }
  else
    {
      /* The method was already defined.  Check that the types match
	 for an @interface for a class or category, or for a
	 @protocol.  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 (klass) == CLASS_INTERFACE_TYPE
	   || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
	   /* Starting with GCC 4.6, we emit the same error for
	      protocols too.  The situation is identical to
	      @interfaces as there is no possible meaningful reason
	      for defining the same method with different signatures
	      in the very same @protocol.  If that was allowed,
	      whenever the protocol is used (both at compile and run
	      time) there wouldn't be any meaningful way to decide
	      which of the two method signatures should be used.  */
	   || TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE)
	  && !comp_proto_with_proto (method, existing_method, 1))
	{
	  error ("duplicate declaration of method %<%c%E%> with conflicting types",
		 (is_class ? '+' : '-'),
		 METHOD_SEL_NAME (existing_method));
	  inform (DECL_SOURCE_LOCATION (existing_method),
		  "previous declaration of %<%c%E%>",
		  (is_class ? '+' : '-'),
		  METHOD_SEL_NAME (existing_method));
	}
    }

  if (is_class)
    insert_method_into_method_map (true, method);
  else
    {
      insert_method_into_method_map (false, 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 (klass) == CATEGORY_INTERFACE_TYPE
	  || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
	klass = lookup_interface (CLASS_NAME (klass));

      if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
	  || !CLASS_SUPER_NAME (klass))
	insert_method_into_method_map (true, method);
    }

  return method;
}

static void
add_category (tree klass, tree category)
{
  /* Put categories on list in reverse order.  */
  tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));

  if (cat)
    {
      warning (0, "duplicate interface declaration for category %<%E(%E)%>",
	       CLASS_NAME (klass),
	       CLASS_SUPER_NAME (category));
    }
  else
    {
      CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
      CLASS_CATEGORY_LIST (klass) = category;
    }
}

#ifndef OBJCPLUS
/* A flexible array member is a C99 extension where you can use
   "type[]" at the end of a struct to mean a variable-length array.

   In Objective-C, instance variables are fundamentally members of a
   struct, but the struct can always be extended by subclassing; hence
   we need to detect and forbid all instance variables declared using
   flexible array members.

   No check for this is needed in Objective-C++, since C++ does not
   have flexible array members.  */

/* Determine whether TYPE is a structure with a flexible array member,
   a union containing such a structure (possibly recursively) or an
   array of such structures or unions.  These are all invalid as
   instance variable.  */
static bool
flexible_array_type_p (tree type)
{
  tree x;
  switch (TREE_CODE (type))
    {
    case RECORD_TYPE:
      x = TYPE_FIELDS (type);
      if (x == NULL_TREE)
	return false;
      while (DECL_CHAIN (x) != NULL_TREE)
	x = DECL_CHAIN (x);
      if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
	  && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
	  && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE
	  && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
	return true;
      return false;
    case UNION_TYPE:
      for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x))
	{
	  if (flexible_array_type_p (TREE_TYPE (x)))
	    return true;
	}
      return false;
    /* Note that we also check for arrays of something that uses a flexible array member.  */
    case ARRAY_TYPE:
      if (flexible_array_type_p (TREE_TYPE (type)))
	return true;
      return false;
    default:
    return false;
  }
}
#endif

/* Produce a printable version of an ivar name.  This is only used
   inside add_instance_variable.  */
static const char *
printable_ivar_name (tree field_decl)
{
  if (DECL_NAME (field_decl))
    return identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)));
  else
    return _("<unnamed>");
}

/* Called after parsing each instance variable declaration. Necessary to
   preserve typedefs and implement public/private...

   VISIBILITY is 1 for public, 0 for protected, and 2 for private.  */

static tree
add_instance_variable (tree klass, objc_ivar_visibility_kind visibility,
		       tree field_decl)
{
  tree field_type = TREE_TYPE (field_decl);

#ifdef OBJCPLUS
  if (TREE_CODE (field_type) == REFERENCE_TYPE)
    {
      error ("illegal reference type specified for instance variable %qs",
	     printable_ivar_name (field_decl));
      /* Return class as is without adding this ivar.  */
      return klass;
    }
#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",
	     printable_ivar_name (field_decl));
      /* Return class as is without adding this ivar.  */
      return klass;
    }

#ifndef OBJCPLUS
  /* Also, in C reject a struct with a flexible array member.  Ie,

       struct A { int x; int[] y; };

       @interface X
       {
         struct A instance_variable;
       }
       @end

       is not valid because if the class is subclassed, we wouldn't be able
       to calculate the offset of the next instance variable.  */
  if (flexible_array_type_p (field_type))
    {
      error ("instance variable %qs uses flexible array member",
	     printable_ivar_name (field_decl));
      /* Return class as is without adding this ivar.  */
      return klass;
    }
#endif

#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 (MAYBE_CLASS_TYPE_P (field_type)
      && (TYPE_NEEDS_CONSTRUCTING (field_type)
	  || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
	  || TYPE_POLYMORPHIC_P (field_type)))
    {
      tree type_name = 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 %qE 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 %qE 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 %qE has virtual member functions", type_name);
	      error ("illegal aggregate type %qE specified "
		     "for instance variable %qs",
		     type_name, printable_ivar_name (field_decl));
	      /* Return class as is without adding this ivar.  */
	      return klass;
	    }

	  /* 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 %qE has a user-defined constructor", type_name);
	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
	    warning (0, "type %qE 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 (visibility)
    {
    case OBJC_IVAR_VIS_PROTECTED:
      TREE_PUBLIC (field_decl) = 0;
      TREE_PRIVATE (field_decl) = 0;
      TREE_PROTECTED (field_decl) = 1;
      break;

    case OBJC_IVAR_VIS_PACKAGE:
    /* TODO: Implement the package variant.  */
    case OBJC_IVAR_VIS_PUBLIC:
      TREE_PUBLIC (field_decl) = 1;
      TREE_PRIVATE (field_decl) = 0;
      TREE_PROTECTED (field_decl) = 0;
      break;

    case OBJC_IVAR_VIS_PRIVATE:
      TREE_PUBLIC (field_decl) = 0;
      TREE_PRIVATE (field_decl) = 1;
      TREE_PROTECTED (field_decl) = 0;
      break;

    }

  CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);

  return klass;
}

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

/* Searches all the instance variables of 'klass' and of its
   superclasses for an instance variable whose name (identifier) is
   'ivar_name_ident'.  Return the declaration (DECL) of the instance
   variable, if found, or NULL_TREE, if not found.  */
static inline tree
ivar_of_class (tree klass, tree ivar_name_ident)
{
  /* First, look up the ivar in CLASS_RAW_IVARS.  */
  tree decl_chain = CLASS_RAW_IVARS (klass);

  for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
    if (DECL_NAME (decl_chain) == ivar_name_ident)
      return decl_chain;

  /* If not found, search up the class hierarchy.  */
  while (CLASS_SUPER_NAME (klass))
    {
      klass = lookup_interface (CLASS_SUPER_NAME (klass));

      decl_chain = CLASS_RAW_IVARS (klass);

      for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
	if (DECL_NAME (decl_chain) == ivar_name_ident)
	  return decl_chain;
    }

  return NULL_TREE;
}

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

  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 klass = lookup_interface (OBJC_TYPE_NAME (basetype));

	  if (!klass)
	    {
	      error ("cannot find interface declaration for %qE",
		     OBJC_TYPE_NAME (basetype));
	      return 0;
	    }

	  if ((decl = ivar_of_class (klass, 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 priv = is_private (decl);

		      if (priv)
			error ("instance variable %qE is declared private",
			       DECL_NAME (decl));

		      return !priv;
		    }
		}

	      /* 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)
	      {
		warning (0, "instance variable %qE is %s; "
			 "this will be a hard error in the future",
			 identifier,
			 TREE_PRIVATE (decl) ? "@private" : "@protected");
		return 1;
	      }

	      error ("instance variable %qE is declared %s",
		     identifier,
		     TREE_PRIVATE (decl) ? "private" : "protected");
	      return 0;
	    }
	}
    }

  return 1;
}

/* Make sure all methods in CHAIN (a list of method declarations from
   an @interface or a @protocol) are in IMPLEMENTATION (the
   implementation context).  This is used to check for example that
   all methods declared in an @interface were implemented in an
   @implementation.

   Some special methods (property setters/getters) are special and if
   they are not found in IMPLEMENTATION, we look them up in its
   superclasses.  */

static int
check_methods (tree chain, tree implementation, int mtype)
{
  int first = 1;
  tree list;

  if (mtype == (int)'+')
    list = CLASS_CLS_METHODS (implementation);
  else
    list = CLASS_NST_METHODS (implementation);

  while (chain)
    {
      /* If the method is associated with a dynamic property, then it
	 is Ok not to have the method implementation, as it will be
	 generated dynamically at runtime.  To decide if the method is
	 associated with a @dynamic property, we search the list of
	 @synthesize and @dynamic for this implementation, and look
	 for any @dynamic property with the same setter or getter name
	 as this method.  */
      tree x;
      for (x = IMPL_PROPERTY_DECL (implementation); x; x = TREE_CHAIN (x))
	if (PROPERTY_DYNAMIC (x)
	    && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
		|| PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
	  break;

      if (x != NULL_TREE)
	{
	  chain = TREE_CHAIN (chain); /* next method...  */
	  continue;
	}

      if (!lookup_method (list, chain))
	{
	  /* If the method is a property setter/getter, we'll still
	     allow it to be missing if it is implemented by
	     'interface' or any of its superclasses.  */
	  tree property = METHOD_PROPERTY_CONTEXT (chain);
	  if (property)
	    {
	      /* Note that since this is a property getter/setter, it
		 is obviously an instance method.  */
	      tree interface = NULL_TREE;

	      /* For a category, first check the main class
		 @interface.  */
	      if (TREE_CODE (implementation) == CATEGORY_IMPLEMENTATION_TYPE)
		{
		  interface = lookup_interface (CLASS_NAME (implementation));

		  /* If the method is found in the main class, it's Ok.  */
		  if (lookup_method (CLASS_NST_METHODS (interface), chain))
		    {
		      chain = DECL_CHAIN (chain);
		      continue;
		    }

		  /* Else, get the superclass.  */
		  if (CLASS_SUPER_NAME (interface))
		    interface = lookup_interface (CLASS_SUPER_NAME (interface));
		  else
		    interface = NULL_TREE;
		}

	      /* Get the superclass for classes.  */
	      if (TREE_CODE (implementation) == CLASS_IMPLEMENTATION_TYPE)
		{
		  if (CLASS_SUPER_NAME (implementation))
		    interface = lookup_interface (CLASS_SUPER_NAME (implementation));
		  else
		    interface = NULL_TREE;
		}

	      /* Now, interface is the superclass, if any; go check it.  */
	      if (interface)
		{
		  if (lookup_method_static (interface, chain, 0))
		    {
		      chain = DECL_CHAIN (chain);
		      continue;
		    }
		}
	      /* Else, fall through - warn.  */
	    }
	  if (first)
	    {
	      switch (TREE_CODE (implementation))
		{
		case CLASS_IMPLEMENTATION_TYPE:
		  warning (0, "incomplete implementation of class %qE",
			   CLASS_NAME (implementation));
		  break;
		case CATEGORY_IMPLEMENTATION_TYPE:
		  warning (0, "incomplete implementation of category %qE",
			   CLASS_SUPER_NAME (implementation));
		  break;
		default:
		  gcc_unreachable ();
		}
	      first = 0;
	    }

	  warning (0, "method definition for %<%c%E%> not found",
		   mtype, METHOD_SEL_NAME (chain));
	}

      chain = DECL_CHAIN (chain);
    }

    return first;
}

/* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL.  */

static int
conforms_to_protocol (tree klass, tree protocol)
{
   if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
     {
       tree p = CLASS_PROTOCOL_LIST (klass);
       while (p && TREE_VALUE (p) != protocol)
	 p = TREE_CHAIN (p);

       if (!p)
	 {
	   tree super = (CLASS_SUPER_NAME (klass)
			 ? lookup_interface (CLASS_SUPER_NAME (klass))
			 : 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)
    {
      /* If the method is associated with a dynamic property, then it
	 is Ok not to have the method implementation, as it will be
	 generated dynamically at runtime.  Search for any @dynamic
	 property with the same setter or getter name as this
	 method.  TODO: Use a hashtable lookup.  */
      tree x;
      for (x = IMPL_PROPERTY_DECL (base_context); x; x = TREE_CHAIN (x))
	if (PROPERTY_DYNAMIC (x)
	    && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
		|| PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
	  break;

      if (x != NULL_TREE)
	{
	  chain = TREE_CHAIN (chain); /* next method...  */
	  continue;
	}

      context = base_context;
      while (context)
	{
	  if (mtype == '+')
	    list = CLASS_CLS_METHODS (context);
	  else
	    list = CLASS_NST_METHODS (context);

	  if (lookup_method (list, chain))
	      break;

	  switch (TREE_CODE (context))
	    {
	    case CLASS_IMPLEMENTATION_TYPE:
	    case CLASS_INTERFACE_TYPE:
	      context = (CLASS_SUPER_NAME (context)
			 ? lookup_interface (CLASS_SUPER_NAME (context))
			 : NULL_TREE);
	      break;
	    case CATEGORY_IMPLEMENTATION_TYPE:
	    case CATEGORY_INTERFACE_TYPE:
	      context = (CLASS_NAME (context)
			 ? lookup_interface (CLASS_NAME (context))
			 : NULL_TREE);
	      break;
	    default:
	      gcc_unreachable ();
	    }
	}

      if (context == NULL_TREE)
	{
	  if (first)
	    {
	      switch (TREE_CODE (objc_implementation_context))
		{
		case CLASS_IMPLEMENTATION_TYPE:
		  warning (0, "incomplete implementation of class %qE",
			   CLASS_NAME (objc_implementation_context));
		  break;
		case CATEGORY_IMPLEMENTATION_TYPE:
		  warning (0, "incomplete implementation of category %qE",
			   CLASS_SUPER_NAME (objc_implementation_context));
		  break;
		default:
		  gcc_unreachable ();
		}
	      first = 0;
	    }
	  warning (0, "method definition for %<%c%E%> not found",
		   mtype, 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
check_protocol (tree p, const char *type, tree name)
{
  if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
    {
      int f1, f2;

      /* Ensure that all protocols have bodies!  */
      if (warn_protocol)
	{
	  f1 = check_methods (PROTOCOL_CLS_METHODS (p),
			      objc_implementation_context,
			      '+');
	  f2 = check_methods (PROTOCOL_NST_METHODS (p),
			      objc_implementation_context,
			      '-');
	}
      else
	{
	  f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
					 objc_implementation_context,
					 '+');
	  f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
					 objc_implementation_context,
					 '-');
	}

      if (!f1 || !f2)
	warning (0, "%s %qE does not fully implement the %qE protocol",
		 type, name, 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))
	    check_protocol (sub, type, name);
	  subs = TREE_CHAIN (subs);
	}
    }
}

/* Check whether the current interface (accessible via
   'objc_implementation_context') actually implements the protocols listed
   in PROTO_LIST.  */

static void
check_protocols (tree proto_list, const char *type, tree name)
{
  for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
    {
      tree p = TREE_VALUE (proto_list);

      check_protocol (p, type, name);
    }
}

/* 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.  For a CATEGORY_INTERFACE_TYPE,
   SUPER_NAME is the name of the category.  For a class extension,
   CODE is CATEGORY_INTERFACE_TYPE and SUPER_NAME is NULL_TREE.  */
static tree
start_class (enum tree_code code, tree class_name, tree super_name,
	     tree protocol_list, tree attributes)
{
  tree klass = NULL_TREE;
  tree decl;

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

  /* If this is a class extension, we'll be "reopening" the existing
     CLASS_INTERFACE_TYPE, so in that case there is no need to create
     a new node.  */
  if (code != CATEGORY_INTERFACE_TYPE || super_name != NULL_TREE)
    {
      klass = make_node (code);
      TYPE_LANG_SLOT_1 (klass) = 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);
      tree super_interface = NULL_TREE;

      if (super)
	super_interface = lookup_interface (super);

      if (!super_interface)
	{
	  error ("cannot find interface declaration for %qE, superclass of %qE",
		 super ? super : super_name,
		 class_name);
	  super_name = NULL_TREE;
	}
      else
	{
	  if (TREE_UNAVAILABLE (super_interface))
	    error ("class %qE is not available", super);
	  else if (TREE_DEPRECATED (super_interface))
	    warning (OPT_Wdeprecated_declarations, "class %qE is deprecated",
		     super);
	  super_name = super;
	}
    }

  if (code != CATEGORY_INTERFACE_TYPE || super_name != NULL_TREE)
    {
      CLASS_NAME (klass) = class_name;
      CLASS_SUPER_NAME (klass) = super_name;
      CLASS_CLS_METHODS (klass) = NULL_TREE;
    }

  if (! objc_is_class_name (class_name)
      && (decl = lookup_name (class_name)))
    {
      error ("%qE redeclared as different kind of symbol",
	     class_name);
      error ("previous declaration of %q+D",
	     decl);
    }

  switch (code)
    {
    case CLASS_IMPLEMENTATION_TYPE:
      {
	tree chain;

	for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
	  if (TREE_VALUE (chain) == class_name)
	    {
	      error ("reimplementation of class %qE",
		     class_name);
	      /* TODO: error message saying where it was previously
		 implemented.  */
	      break;
	    }
	if (chain == NULL_TREE)
	  implemented_classes = tree_cons (NULL_TREE, class_name,
					   implemented_classes);
      }

      /* Reset for multiple classes per file.  */
      method_slot = 0;

      objc_implementation_context = klass;

      /* Lookup the interface for this implementation.  */

      if (!(implementation_template = lookup_interface (class_name)))
        {
	  warning (0, "cannot find interface declaration for %qE",
		   class_name);
	  add_interface (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);
	  error ("conflicting super class name %qE",
		 super_name);
	  if (previous_name)
	    error ("previous declaration of %qE", previous_name);
	  else
	    error ("previous declaration");
	}

      else if (! super_name)
	{
	  CLASS_SUPER_NAME (objc_implementation_context)
	    = CLASS_SUPER_NAME (implementation_template);
	}

      if (!CLASS_SUPER_NAME (objc_implementation_context)
	  && !lookup_attribute ("objc_root_class",
				TYPE_ATTRIBUTES (implementation_template)))
	  warning (OPT_Wobjc_root_class, "class %qE defined without"
		      " specifying a base class", class_name);
      break;

    case CLASS_INTERFACE_TYPE:
      if (lookup_interface (class_name))
#ifdef OBJCPLUS
	error ("duplicate interface declaration for class %qE", class_name);
#else
        warning (0, "duplicate interface declaration for class %qE", class_name);
#endif
      else
	add_interface (klass, class_name);

      if (protocol_list)
	CLASS_PROTOCOL_LIST (klass)
	  = lookup_and_install_protocols (protocol_list, /* definition_required */ true);

      if (attributes)
	{
	  tree attribute;
	  for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
	    {
	      tree name = TREE_PURPOSE (attribute);

	      /* TODO: Document what the objc_exception attribute is/does.  */
	      /* We handle the 'deprecated', 'visibility' and (undocumented)
		 'objc_exception' attributes.  */
	      if (is_attribute_p  ("unavailable", name))
		TREE_UNAVAILABLE (klass) = 1;
	      else if (is_attribute_p  ("deprecated", name))
		TREE_DEPRECATED (klass) = 1;
	      else if (is_attribute_p  ("objc_exception", name))
		CLASS_HAS_EXCEPTION_ATTR (klass) = 1;
	      else if (is_attribute_p  ("objc_root_class", name))
		;
	      else if (is_attribute_p  ("visibility", name))
		;
	      else
		/* Warn about and ignore all others for now, but store them.  */
		warning (OPT_Wattributes, "%qE attribute directive ignored", name);
	    }
	  TYPE_ATTRIBUTES (klass) = attributes;
	}
      break;

    case 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 %qE",
		   class_name);
	    exit (FATAL_EXIT_CODE);
	  }
	else
	  {
	    if (TREE_UNAVAILABLE (class_category_is_assoc_with))
	      error ("class %qE is unavailable", class_name);
	    else if (TREE_DEPRECATED (class_category_is_assoc_with))
	      warning (OPT_Wdeprecated_declarations, "class %qE is deprecated",
		       class_name);

	    if (super_name == NULL_TREE)
	      {
		/* This is a class extension.  Get the original
		   interface, and continue working on it.  */
		objc_in_class_extension = true;
		klass = class_category_is_assoc_with;

		if (protocol_list)
		  {
		    /* Append protocols to the original protocol
		       list.  */
		    CLASS_PROTOCOL_LIST (klass)
		      = chainon (CLASS_PROTOCOL_LIST (klass),
				 lookup_and_install_protocols
				 (protocol_list,
				  /* definition_required */ true));
		  }
	      }
	    else
	      {
		add_category (class_category_is_assoc_with, klass);

		if (protocol_list)
		  CLASS_PROTOCOL_LIST (klass)
		    = lookup_and_install_protocols
		    (protocol_list, /* definition_required */ true);
	      }
	  }
      }
      break;

    case CATEGORY_IMPLEMENTATION_TYPE:
      /* Reset for multiple classes per file.  */
      method_slot = 0;

      objc_implementation_context = klass;

      /* 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 %qE",
		 class_name);
	  exit (FATAL_EXIT_CODE);
        }
      break;
    default:
      gcc_unreachable ();
    }
  return klass;
}

static tree
continue_class (tree klass)
{
  switch (TREE_CODE (klass))
    {
    case CLASS_IMPLEMENTATION_TYPE:
    case CATEGORY_IMPLEMENTATION_TYPE:
      {
	struct imp_entry *imp_entry;

        /* Check consistency of the instance variables.  */

	if (CLASS_RAW_IVARS (klass))
	  check_ivars (implementation_template, klass);

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

	imp_entry = ggc_alloc<struct imp_entry> ();

	imp_entry->next = imp_list;
	imp_entry->imp_context = klass;
	imp_entry->imp_template = implementation_template;
	ucls_super_ref = uucls_super_ref = NULL;
	if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
	  {
	    imp_entry->class_decl = (*runtime.class_decl) (klass);
	    imp_entry->meta_decl = (*runtime.metaclass_decl) (klass);
	  }
	else
	  {
	    imp_entry->class_decl = (*runtime.category_decl) (klass);
	    imp_entry->meta_decl = NULL;
	  }
	imp_entry->has_cxx_cdtors = 0;

	/* Append to front and increment count.  */
	imp_list = imp_entry;
	if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
	  imp_count++;
	else
	  cat_count++;
#ifdef OBJCPLUS
	pop_lang_context ();
#endif /* OBJCPLUS */

	return get_class_ivars (implementation_template, true);
      }
    case CLASS_INTERFACE_TYPE:
      {
	if (objc_in_class_extension)
	  return NULL_TREE;
#ifdef OBJCPLUS
	push_lang_context (lang_name_c);
#endif /* OBJCPLUS */
	objc_collecting_ivars = 1;
	build_private_template (klass);
	objc_collecting_ivars = 0;
#ifdef OBJCPLUS
	pop_lang_context ();
#endif /* OBJCPLUS */
	return NULL_TREE;
      }
    default:
      return error_mark_node;
    }
}

/* This routine builds name of the setter synthesized function. */
char *
objc_build_property_setter_name (tree ident)
{
  /* TODO: Use alloca to allocate buffer of appropriate size.  */
  static char string[BUFSIZE];
  sprintf (string, "set%s:", IDENTIFIER_POINTER (ident));
  string[3] = TOUPPER (string[3]);
  return string;
}

/* This routine prepares the declarations of the property accessor
   helper functions (objc_getProperty(), etc) that are used when
   @synthesize is used.

   runtime-specific routines are built in the respective runtime
   initialize functions.  */
static void
build_common_objc_property_accessor_helpers (void)
{
  tree type;

  /* Declare the following function:
     id
     objc_getProperty (id self, SEL _cmd,
                       ptrdiff_t offset, BOOL is_atomic);  */
  type = build_function_type_list (objc_object_type,
				   objc_object_type,
				   objc_selector_type,
				   ptrdiff_type_node,
				   boolean_type_node,
				   NULL_TREE);
  objc_getProperty_decl = add_builtin_function ("objc_getProperty",
						type, 0, NOT_BUILT_IN,
						NULL, NULL_TREE);
  TREE_NOTHROW (objc_getProperty_decl) = 0;

  /* Declare the following function:
     void
     objc_setProperty (id self, SEL _cmd,
                       ptrdiff_t offset, id new_value,
                       BOOL is_atomic, BOOL should_copy);  */
  type = build_function_type_list (void_type_node,
				   objc_object_type,
				   objc_selector_type,
				   ptrdiff_type_node,
				   objc_object_type,
				   boolean_type_node,
				   boolean_type_node,
				   NULL_TREE);
  objc_setProperty_decl = add_builtin_function ("objc_setProperty",
						type, 0, NOT_BUILT_IN,
						NULL, NULL_TREE);
  TREE_NOTHROW (objc_setProperty_decl) = 0;
}

/* This looks up an ivar in a class (including superclasses).  */
static tree
lookup_ivar (tree interface, tree instance_variable_name)
{
  while (interface)
    {
      tree decl_chain;

      for (decl_chain = CLASS_IVARS (interface); decl_chain; decl_chain = DECL_CHAIN (decl_chain))
	if (DECL_NAME (decl_chain) == instance_variable_name)
	  return decl_chain;

      /* Not found.  Search superclass if any.  */
      if (CLASS_SUPER_NAME (interface))
	interface = lookup_interface (CLASS_SUPER_NAME (interface));
    }

  return NULL_TREE;
}

/* This routine synthesizes a 'getter' method.  This is only called
   for @synthesize properties.  */
static void
objc_synthesize_getter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
{
  location_t location = DECL_SOURCE_LOCATION (property);
  tree fn, decl;
  tree body;
  tree ret_val;

  /* If user has implemented a getter with same name then do nothing.  */
  if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
		     PROPERTY_GETTER_NAME (property)))
    return;

  /* Find declaration of the property getter in the interface (or
     superclass, or protocol). There must be one.  */
  decl = lookup_method_static (klass, PROPERTY_GETTER_NAME (property), 0);

  /* If one not declared in the interface, this condition has already
     been reported as user error (because property was not declared in
     the interface).  */
  if (!decl)
    return;

  /* Adapt the 'decl'.  Use the source location of the @synthesize
     statement for error messages.  */
  decl = copy_node (decl);
  DECL_SOURCE_LOCATION (decl) = location;

  objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE,
				NULL_TREE);
  body = c_begin_compound_stmt (true);

  /* Now we need to decide how we build the getter.  There are three
     cases:

     for 'copy' or 'retain' properties we need to use the
     objc_getProperty() accessor helper which knows about retain and
     copy.  It supports both 'nonatomic' and 'atomic' access.

     for 'nonatomic, assign' properties we can access the instance
     variable directly.  'nonatomic' means we don't have to use locks,
     and 'assign' means we don't have to worry about retain or copy.
     If you combine the two, it means we can just access the instance
     variable directly.

     for 'atomic, assign' properties we use objc_copyStruct() (for the
     next runtime) or objc_getPropertyStruct() (for the GNU runtime).  */
  switch (PROPERTY_ASSIGN_SEMANTICS (property))
    {
    case OBJC_PROPERTY_RETAIN:
    case OBJC_PROPERTY_COPY:
      {
	/* We build "return objc_getProperty (self, _cmd, offset, is_atomic);"  */
	tree cmd, ivar, offset, is_atomic;
	cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));

	/* Find the ivar to compute the offset.  */
	ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
	if (!ivar || is_private (ivar))
	  {
	    /* This should never happen.  */
	    error_at (location,
		      "cannot find instance variable associated with property");
	    ret_val = error_mark_node;
	    break;
	  }
	offset = byte_position (ivar);

	if (PROPERTY_NONATOMIC (property))
	  is_atomic = boolean_false_node;
	else
	  is_atomic = boolean_true_node;

	ret_val = build_function_call
	  (location,
	   /* Function prototype.  */
	   objc_getProperty_decl,
	   /* Parameters.  */
	   tree_cons    /* self */
	   (NULL_TREE, self_decl,
	    tree_cons   /* _cmd */
	    (NULL_TREE, cmd,
	     tree_cons  /* offset */
	     (NULL_TREE, offset,
	      tree_cons /* is_atomic */
	      (NULL_TREE, is_atomic, NULL_TREE)))));
      }
      break;
    case OBJC_PROPERTY_ASSIGN:
      if (PROPERTY_NONATOMIC (property))
	{
	  /* We build "return self->PROPERTY_IVAR_NAME;"  */
	  ret_val = objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property));
	  break;
	}
      else
	{
	  /* We build
	       <property type> __objc_property_temp;
	       objc_getPropertyStruct (&__objc_property_temp,
	                               &(self->PROPERTY_IVAR_NAME),
	                               sizeof (type of self->PROPERTY_IVAR_NAME),
				       is_atomic,
				       false)
	       return __objc_property_temp;

	     For the NeXT runtime, we need to use objc_copyStruct
	     instead of objc_getPropertyStruct.  */
	  tree objc_property_temp_decl, function_decl, function_call;
	  tree size_of, is_atomic;

	  objc_property_temp_decl = objc_create_temporary_var (TREE_TYPE (property), "__objc_property_temp");
	  DECL_SOURCE_LOCATION (objc_property_temp_decl) = location;
	  objc_property_temp_decl = lang_hooks.decls.pushdecl (objc_property_temp_decl);

	  /* sizeof (ivar type).  Since the ivar and the property have
	     the same type, there is no need to lookup the ivar.  */
	  size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
					      true /* is_sizeof */,
					      false /* min_alignof */,
					      false /* complain */);

	  if (PROPERTY_NONATOMIC (property))
	    is_atomic = boolean_false_node;
	  else
	    is_atomic = boolean_true_node;

	  if (objc_copyStruct_decl)
	    function_decl = objc_copyStruct_decl;
	  else
	    function_decl = objc_getPropertyStruct_decl;

	  function_call = build_function_call
	    (location,
	     /* Function prototype.  */
	     function_decl,
	     /* Parameters.  */
	     tree_cons /* &__objc_property_temp_decl */
	     /* Warning: note that using build_fold_addr_expr_loc()
		here causes invalid code to be generated.  */
	     (NULL_TREE, build_unary_op (location, ADDR_EXPR, objc_property_temp_decl, 0),
	      tree_cons /* &(self->PROPERTY_IVAR_NAME); */
	      (NULL_TREE, build_fold_addr_expr_loc (location,
						    objc_lookup_ivar
						    (NULL_TREE, PROPERTY_IVAR_NAME (property))),
	       tree_cons /* sizeof (PROPERTY_IVAR) */
	       (NULL_TREE, size_of,
		tree_cons /* is_atomic */
		(NULL_TREE, is_atomic,
		 /* TODO: This is currently ignored by the GNU
		    runtime, but what about the next one ? */
		 tree_cons /* has_strong */
		 (NULL_TREE, boolean_true_node, NULL_TREE))))));

	  add_stmt (function_call);

	  ret_val = objc_property_temp_decl;
	}
      break;
    default:
      gcc_unreachable ();
    }

  gcc_assert (ret_val);

#ifdef OBJCPLUS
  finish_return_stmt (ret_val);
#else
  c_finish_return (location, ret_val, NULL_TREE);
#endif

  add_stmt (c_end_compound_stmt (location, body, true));
  fn = current_function_decl;
#ifdef OBJCPLUS
  finish_function ();
#endif
  objc_finish_method_definition (fn);
}

/* This routine synthesizes a 'setter' method.  */

static void
objc_synthesize_setter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
{
  location_t location = DECL_SOURCE_LOCATION (property);
  tree fn, decl;
  tree body;
  tree new_value, statement;

  /* If user has implemented a setter with same name then do nothing.  */
  if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
		     PROPERTY_SETTER_NAME (property)))
    return;

  /* Find declaration of the property setter in the interface (or
     superclass, or protocol). There must be one.  */
  decl = lookup_method_static (klass, PROPERTY_SETTER_NAME (property), 0);

  /* If one not declared in the interface, this condition has already
     been reported as user error (because property was not declared in
     the interface).  */
  if (!decl)
    return;

  /* Adapt the 'decl'.  Use the source location of the @synthesize
     statement for error messages.  */
  decl = copy_node (decl);
  DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (property);

  objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE,
				NULL_TREE);

  body = c_begin_compound_stmt (true);

  /* The 'new_value' is the only argument to the method, which is the
     3rd argument of the function, after self and _cmd.  We use twice
     TREE_CHAIN to move forward two arguments.  */
  new_value = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)));

  /* This would presumably happen if the user has specified a
     prototype for the setter that does not have an argument!  */
  if (new_value == NULL_TREE)
    {
      /* TODO: This should be caught much earlier than this.  */
      error_at (DECL_SOURCE_LOCATION (decl), "invalid setter, it must have one argument");
      /* Try to recover somehow.  */
      new_value = error_mark_node;
    }

  /* Now we need to decide how we build the setter.  There are three
     cases:

     for 'copy' or 'retain' properties we need to use the
     objc_setProperty() accessor helper which knows about retain and
     copy.  It supports both 'nonatomic' and 'atomic' access.

     for 'nonatomic, assign' properties we can access the instance
     variable directly.  'nonatomic' means we don't have to use locks,
     and 'assign' means we don't have to worry about retain or copy.
     If you combine the two, it means we can just access the instance
     variable directly.

     for 'atomic, assign' properties we use objc_copyStruct() (for the
     next runtime) or objc_setPropertyStruct() (for the GNU runtime).  */
  switch (PROPERTY_ASSIGN_SEMANTICS (property))
    {
    case OBJC_PROPERTY_RETAIN:
    case OBJC_PROPERTY_COPY:
      {
	/* We build "objc_setProperty (self, _cmd, new_value, offset, is_atomic, should_copy);"  */
	tree cmd, ivar, offset, is_atomic, should_copy;
	cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));

	/* Find the ivar to compute the offset.  */
	ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
	if (!ivar || is_private (ivar))
	  {
	    error_at (location,
		      "cannot find instance variable associated with property");
	    statement = error_mark_node;
	    break;
	  }
	offset = byte_position (ivar);

	if (PROPERTY_NONATOMIC (property))
	  is_atomic = boolean_false_node;
	else
	  is_atomic = boolean_true_node;

	if (PROPERTY_ASSIGN_SEMANTICS (property) == OBJC_PROPERTY_COPY)
	  should_copy = boolean_true_node;
	else
	  should_copy = boolean_false_node;

	statement = build_function_call
	  (location,
	   /* Function prototype.  */
	   objc_setProperty_decl,
	   /* Parameters.  */
	   tree_cons    /* self */
	   (NULL_TREE, self_decl,
	    tree_cons   /* _cmd */
	    (NULL_TREE, cmd,
	     tree_cons  /* offset */
	     (NULL_TREE, offset,
	      tree_cons /* new_value */
	      (NULL_TREE, new_value,
	       tree_cons /* is_atomic */
	       (NULL_TREE, is_atomic,
		tree_cons /* should_copy */
		(NULL_TREE, should_copy, NULL_TREE)))))));
      }
      break;
    case OBJC_PROPERTY_ASSIGN:
      if (PROPERTY_NONATOMIC (property))
	{
	  /* We build "self->PROPERTY_IVAR_NAME = new_value;"  */
	  statement = build_modify_expr
	    (location,
	     objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property)),
	     NULL_TREE, NOP_EXPR,
	     location, new_value, NULL_TREE);
	  break;
	}
      else
	{
	  /* We build
	       objc_setPropertyStruct (&(self->PROPERTY_IVAR_NAME),
	                               &new_value,
	                               sizeof (type of self->PROPERTY_IVAR_NAME),
				       is_atomic,
				       false)

	     For the NeXT runtime, we need to use objc_copyStruct
	     instead of objc_getPropertyStruct.  */
	  tree function_decl, size_of, is_atomic;

	  /* sizeof (ivar type).  Since the ivar and the property have
	     the same type, there is no need to lookup the ivar.  */
	  size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
					      true /* is_sizeof */,
					      false /* min_alignof */,
					      false /* complain */);

	  if (PROPERTY_NONATOMIC (property))
	    is_atomic = boolean_false_node;
	  else
	    is_atomic = boolean_true_node;

	  if (objc_copyStruct_decl)
	    function_decl = objc_copyStruct_decl;
	  else
	    function_decl = objc_setPropertyStruct_decl;

	  statement = build_function_call
	    (location,
	     /* Function prototype.  */
	     function_decl,
	     /* Parameters.  */
	     tree_cons /* &(self->PROPERTY_IVAR_NAME); */
	     (NULL_TREE, build_fold_addr_expr_loc (location,
						   objc_lookup_ivar
						   (NULL_TREE, PROPERTY_IVAR_NAME (property))),
	      tree_cons /* &new_value */
	      (NULL_TREE, build_fold_addr_expr_loc (location, new_value),
	       tree_cons /* sizeof (PROPERTY_IVAR) */
	       (NULL_TREE, size_of,
		tree_cons /* is_atomic */
		(NULL_TREE, is_atomic,
		 /* TODO: This is currently ignored by the GNU
		    runtime, but what about the next one ? */
		 tree_cons /* has_strong */
		 (NULL_TREE, boolean_true_node, NULL_TREE))))));
	}
      break;
    default:
      gcc_unreachable ();
    }
  gcc_assert (statement);

  add_stmt (statement);
  add_stmt (c_end_compound_stmt (location, body, true));
  fn = current_function_decl;
#ifdef OBJCPLUS
  finish_function ();
#endif
  objc_finish_method_definition (fn);
}

/* This function is a sub-routine of objc_add_synthesize_declaration.
   It is called for each property to synthesize once we have
   determined that the context is Ok.  */
static void
objc_add_synthesize_declaration_for_property (location_t location, tree interface,
					      tree property_name, tree ivar_name)
{
  /* Find the @property declaration.  */
  tree property;
  tree x;

  /* Check that synthesize or dynamic has not already been used for
     the same property.  */
  for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
    if (PROPERTY_NAME (property) == property_name)
      {
	location_t original_location = DECL_SOURCE_LOCATION (property);

	if (PROPERTY_DYNAMIC (property))
	  error_at (location, "property %qs already specified in %<@dynamic%>",
		    IDENTIFIER_POINTER (property_name));
	else
	  error_at (location, "property %qs already specified in %<@synthesize%>",
		    IDENTIFIER_POINTER (property_name));

	if (original_location != UNKNOWN_LOCATION)
	  inform (original_location, "originally specified here");
	return;
      }

  /* Check that the property is declared in the interface.  It could
     also be declared in a superclass or protocol.  */
  property = lookup_property (interface, property_name);

  if (!property)
    {
      error_at (location, "no declaration of property %qs found in the interface",
		IDENTIFIER_POINTER (property_name));
      return;
    }
  else
    {
      /* We have to copy the property, because we want to chain it to
	 the implementation context, and we want to store the source
	 location of the @synthesize, not of the original
	 @property.  */
      property = copy_node (property);
      DECL_SOURCE_LOCATION (property) = location;
    }

  /* Determine PROPERTY_IVAR_NAME.  */
  if (ivar_name == NULL_TREE)
    ivar_name = property_name;

  /* Check that the instance variable exists.  You can only use an
     instance variable from the same class, not one from the
     superclass (this makes sense as it allows us to check that an
     instance variable is only used in one synthesized property).  */
  {
    tree ivar = is_ivar (CLASS_IVARS (interface), ivar_name);
    tree type_of_ivar;
    if (!ivar)
      {
	error_at (location, "ivar %qs used by %<@synthesize%> declaration must be an existing ivar",
		  IDENTIFIER_POINTER (property_name));
	return;
      }

    if (DECL_BIT_FIELD_TYPE (ivar))
      type_of_ivar = DECL_BIT_FIELD_TYPE (ivar);
    else
      type_of_ivar = TREE_TYPE (ivar);

    /* If the instance variable has a different C type, we throw an error ...  */
    if (!comptypes (TREE_TYPE (property), type_of_ivar)
	/* ... unless the property is readonly, in which case we allow
	   the instance variable to be more specialized (this means we
	   can generate the getter all right and it works).  */
	&& (!PROPERTY_READONLY (property)
	    || !objc_compare_types (TREE_TYPE (property),
				    type_of_ivar, -5, NULL_TREE)))
      {
	location_t original_location = DECL_SOURCE_LOCATION (ivar);

	error_at (location, "property %qs is using instance variable %qs of incompatible type",
		  IDENTIFIER_POINTER (property_name),
		  IDENTIFIER_POINTER (ivar_name));

	if (original_location != UNKNOWN_LOCATION)
	  inform (original_location, "originally specified here");
      }

    /* If the instance variable is a bitfield, the property must be
       'assign', 'nonatomic' because the runtime getter/setter helper
       do not work with bitfield instance variables.  */
    if (DECL_BIT_FIELD_TYPE (ivar))
      {
	/* If there is an error, we return and not generate any
	   getter/setter because trying to set up the runtime
	   getter/setter helper calls with bitfields is at high risk
	   of ICE.  */

	if (PROPERTY_ASSIGN_SEMANTICS (property) != OBJC_PROPERTY_ASSIGN)
	  {
	    location_t original_location = DECL_SOURCE_LOCATION (ivar);

	    error_at (location, "%<assign%> property %qs is using bit-field "
		      "instance variable %qs",
		      IDENTIFIER_POINTER (property_name),
		      IDENTIFIER_POINTER (ivar_name));

	    if (original_location != UNKNOWN_LOCATION)
	      inform (original_location, "originally specified here");
	    return;
	  }

	if (!PROPERTY_NONATOMIC (property))
	  {
	    location_t original_location = DECL_SOURCE_LOCATION (ivar);

	    error_at (location, "%<atomic%> property %qs is using bit-field "
		      "instance variable %qs",
		      IDENTIFIER_POINTER (property_name),
		      IDENTIFIER_POINTER (ivar_name));

	    if (original_location != UNKNOWN_LOCATION)
	      inform (original_location, "originally specified here");
	    return;
	  }
      }
  }

  /* Check that no other property is using the same instance
     variable.  */
  for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
    if (PROPERTY_IVAR_NAME (x) == ivar_name)
      {
	location_t original_location = DECL_SOURCE_LOCATION (x);

	error_at (location, "property %qs is using the same instance variable as property %qs",
		  IDENTIFIER_POINTER (property_name),
		  IDENTIFIER_POINTER (PROPERTY_NAME (x)));

	if (original_location != UNKNOWN_LOCATION)
	  inform (original_location, "originally specified here");

	/* We keep going on.  This won't cause the compiler to fail;
	   the failure would most likely be at runtime.  */
      }

  /* Note that a @synthesize (and only a @synthesize) always sets
     PROPERTY_IVAR_NAME to a non-NULL_TREE.  You can recognize a
     @synthesize by that.  */
  PROPERTY_IVAR_NAME (property) = ivar_name;

  /* PROPERTY_SETTER_NAME and PROPERTY_GETTER_NAME are copied from the
     original declaration; they are always set (with the exception of
     PROPERTY_SETTER_NAME not being set if PROPERTY_READONLY == 1).  */

  /* Add the property to the list of properties for current implementation. */
  TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
  IMPL_PROPERTY_DECL (objc_implementation_context) = property;

  /* Note how we don't actually synthesize the getter/setter here; it
     would be very natural, but we may miss the fact that the user has
     implemented his own getter/setter later on in the @implementation
     (in which case we shouldn't generate getter/setter).  We wait
     until we have parsed it all before generating the code.  */
}

/* This function is called by the parser after a @synthesize
   expression is parsed.  'location' is the location of the
   @synthesize expression, and 'property_and_ivar_list' is a chained
   list of the property and ivar names.  */
void
objc_add_synthesize_declaration (location_t location, tree property_and_ivar_list)
{
  tree interface, chain;

  if (flag_objc1_only)
    error_at (input_location, "%<@synthesize%> is not available in Objective-C 1.0");

  if (property_and_ivar_list == error_mark_node)
    return;

  if (!objc_implementation_context)
    {
      /* We can get here only in Objective-C; the Objective-C++ parser
	 detects the problem while parsing, outputs the error
	 "misplaced '@synthesize' Objective-C++ construct" and skips
	 the declaration.  */
      error_at (location, "%<@synthesize%> not in @implementation context");
      return;
    }

  if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
    {
      error_at (location, "%<@synthesize%> cannot be used in categories");
      return;
    }

  interface = lookup_interface (CLASS_NAME (objc_implementation_context));
  if (!interface)
    {
      /* I can't see how this could happen, but it is good as a safety check.  */
      error_at (location,
		"%<@synthesize%> requires the @interface of the class to be available");
      return;
    }

  /* Now, iterate over the properties and do each of them.  */
  for (chain = property_and_ivar_list; chain; chain = TREE_CHAIN (chain))
    {
      objc_add_synthesize_declaration_for_property (location, interface, TREE_VALUE (chain),
						    TREE_PURPOSE (chain));
    }
}

/* This function is a sub-routine of objc_add_dynamic_declaration.  It
   is called for each property to mark as dynamic once we have
   determined that the context is Ok.  */
static void
objc_add_dynamic_declaration_for_property (location_t location, tree interface,
					   tree property_name)
{
  /* Find the @property declaration.  */
  tree property;

  /* Check that synthesize or dynamic has not already been used for
     the same property.  */
  for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
    if (PROPERTY_NAME (property) == property_name)
      {
	location_t original_location = DECL_SOURCE_LOCATION (property);

	if (PROPERTY_DYNAMIC (property))
	  error_at (location, "property %qs already specified in %<@dynamic%>",
		    IDENTIFIER_POINTER (property_name));
	else
	  error_at (location, "property %qs already specified in %<@synthesize%>",
		    IDENTIFIER_POINTER (property_name));

	if (original_location != UNKNOWN_LOCATION)
	  inform (original_location, "originally specified here");
	return;
      }

  /* Check that the property is declared in the interface.  It could
     also be declared in a superclass or protocol.  */
  property = lookup_property (interface, property_name);

  if (!property)
    {
      error_at (location, "no declaration of property %qs found in the interface",
		IDENTIFIER_POINTER (property_name));
      return;
    }
  else
    {
      /* We have to copy the property, because we want to chain it to
	 the implementation context, and we want to store the source
	 location of the @synthesize, not of the original
	 @property.  */
      property = copy_node (property);
      DECL_SOURCE_LOCATION (property) = location;
    }

  /* Note that a @dynamic (and only a @dynamic) always sets
     PROPERTY_DYNAMIC to 1.  You can recognize a @dynamic by that.
     (actually, as explained above, PROPERTY_DECL generated by
     @property and associated with a @dynamic property are also marked
     as PROPERTY_DYNAMIC).  */
  PROPERTY_DYNAMIC (property) = 1;

  /* Add the property to the list of properties for current implementation. */
  TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
  IMPL_PROPERTY_DECL (objc_implementation_context) = property;
}

/* This function is called by the parser after a @dynamic expression
   is parsed.  'location' is the location of the @dynamic expression,
   and 'property_list' is a chained list of all the property
   names.  */
void
objc_add_dynamic_declaration (location_t location, tree property_list)
{
  tree interface, chain;

  if (flag_objc1_only)
    error_at (input_location, "%<@dynamic%> is not available in Objective-C 1.0");

  if (property_list == error_mark_node)
    return;

  if (!objc_implementation_context)
    {
      /* We can get here only in Objective-C; the Objective-C++ parser
	 detects the problem while parsing, outputs the error
	 "misplaced '@dynamic' Objective-C++ construct" and skips the
	 declaration.  */
      error_at (location, "%<@dynamic%> not in @implementation context");
      return;
    }

  /* @dynamic is allowed in categories.  */
  switch (TREE_CODE (objc_implementation_context))
    {
    case CLASS_IMPLEMENTATION_TYPE:
      interface = lookup_interface (CLASS_NAME (objc_implementation_context));
      break;
    case CATEGORY_IMPLEMENTATION_TYPE:
      interface = lookup_category (implementation_template,
				   CLASS_SUPER_NAME (objc_implementation_context));
      break;
    default:
      gcc_unreachable ();
    }

  if (!interface)
    {
      /* I can't see how this could happen, but it is good as a safety check.  */
      error_at (location,
		"%<@dynamic%> requires the @interface of the class to be available");
      return;
    }

  /* Now, iterate over the properties and do each of them.  */
  for (chain = property_list; chain; chain = TREE_CHAIN (chain))
    {
      objc_add_dynamic_declaration_for_property (location, interface, TREE_VALUE (chain));
    }
}

/* Main routine to generate code/data for all the property information for
   current implementation (class or category). CLASS is the interface where
   ivars are declared.  CLASS_METHODS is where methods are found which
   could be a class or a category depending on whether we are implementing
   property of a class or a category.  */

static void
objc_gen_property_data (tree klass, tree class_methods)
{
  tree x;

  for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
    {
      /* @dynamic property - nothing to check or synthesize.  */
      if (PROPERTY_DYNAMIC (x))
	continue;

      /* @synthesize property - need to synthesize the accessors.  */
      if (PROPERTY_IVAR_NAME (x))
	{
	  objc_synthesize_getter (klass, class_methods, x);

	  if (PROPERTY_READONLY (x) == 0)
	    objc_synthesize_setter (klass, class_methods, x);

	  continue;
	}

      gcc_unreachable ();
    }
}

/* This is called once we see the "@end" in an interface/implementation.  */

static void
finish_class (tree klass)
{
  switch (TREE_CODE (klass))
    {
    case CLASS_IMPLEMENTATION_TYPE:
      {
	/* All metadata generation is done in runtime.generate_metadata().  */

	/* Generate what needed for property; setters, getters, etc. */
	objc_gen_property_data (implementation_template, implementation_template);

	if (implementation_template != objc_implementation_context)
	  {
	    /* Ensure that all method listed in the interface contain bodies.  */
	    check_methods (CLASS_CLS_METHODS (implementation_template),
			   objc_implementation_context, '+');
	    check_methods (CLASS_NST_METHODS (implementation_template),
			   objc_implementation_context, '-');

	    if (CLASS_PROTOCOL_LIST (implementation_template))
	      check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
			       "class",
			       CLASS_NAME (objc_implementation_context));
	  }
	break;
      }
    case CATEGORY_IMPLEMENTATION_TYPE:
      {
	tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));

	if (category)
	  {
	    /* Generate what needed for property; setters, getters, etc. */
	    objc_gen_property_data (implementation_template, category);

	    /* Ensure all method listed in the interface contain bodies.  */
	    check_methods (CLASS_CLS_METHODS (category),
			   objc_implementation_context, '+');
	    check_methods (CLASS_NST_METHODS (category),
			   objc_implementation_context, '-');

	    if (CLASS_PROTOCOL_LIST (category))
	      check_protocols (CLASS_PROTOCOL_LIST (category),
			       "category",
			       CLASS_SUPER_NAME (objc_implementation_context));
	  }
	break;
      }
    case CLASS_INTERFACE_TYPE:
    case CATEGORY_INTERFACE_TYPE:
    case PROTOCOL_INTERFACE_TYPE:
      {
	/* Process properties of the class. */
	tree x;
	for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
	  {
	    /* Now we check that the appropriate getter is declared,
	       and if not, we declare one ourselves.  */
	    tree getter_decl = lookup_method (CLASS_NST_METHODS (klass),
					      PROPERTY_GETTER_NAME (x));

	    if (getter_decl)
	      {
		/* TODO: Check that the declaration is consistent with the property.  */
		;
	      }
	    else
	      {
		/* Generate an instance method declaration for the
		   getter; for example "- (id) name;".  In general it
		   will be of the form
		   -(type)property_getter_name;  */
		tree rettype = build_tree_list (NULL_TREE, TREE_TYPE (x));
		getter_decl = build_method_decl (INSTANCE_METHOD_DECL,
						 rettype, PROPERTY_GETTER_NAME (x),
						 NULL_TREE, false);
		if (PROPERTY_OPTIONAL (x))
		  objc_add_method (objc_interface_context, getter_decl, false, true);
		else
		  objc_add_method (objc_interface_context, getter_decl, false, false);
		TREE_DEPRECATED (getter_decl) = TREE_DEPRECATED (x);
		TREE_UNAVAILABLE (getter_decl) = TREE_UNAVAILABLE (x);
		METHOD_PROPERTY_CONTEXT (getter_decl) = x;
	      }

	    if (PROPERTY_READONLY (x) == 0)
	      {
		/* Now we check that the appropriate setter is declared,
		   and if not, we declare on ourselves.  */
		tree setter_decl = lookup_method (CLASS_NST_METHODS (klass),
						  PROPERTY_SETTER_NAME (x));

		if (setter_decl)
		  {
		    /* TODO: Check that the declaration is consistent with the property.  */
		    ;
		  }
		else
		  {
		    /* The setter name is something like 'setName:'.
		       We need the substring 'setName' to build the
		       method declaration due to how the declaration
		       works.  TODO: build_method_decl() will then
		       generate back 'setName:' from 'setName'; it
		       would be more efficient to hook into there.  */
		    const char *full_setter_name = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x));
		    size_t length = strlen (full_setter_name);
		    char *setter_name = (char *) alloca (length);
		    tree ret_type, selector, arg_type, arg_name;

		    memcpy (setter_name, full_setter_name, length - 1);
		    setter_name[length - 1] = '\0';
		    ret_type = build_tree_list (NULL_TREE, void_type_node);
		    arg_type = build_tree_list (NULL_TREE, TREE_TYPE (x));
		    arg_name = get_identifier ("_value");
		    selector = objc_build_keyword_decl (get_identifier (setter_name),
							arg_type, arg_name, NULL);
		    setter_decl = build_method_decl (INSTANCE_METHOD_DECL,
						     ret_type, selector,
						     build_tree_list (NULL_TREE, NULL_TREE),
						     false);
		    if (PROPERTY_OPTIONAL (x))
		      objc_add_method (objc_interface_context, setter_decl, false, true);
		    else
		      objc_add_method (objc_interface_context, setter_decl, false, false);
		    TREE_DEPRECATED (setter_decl) = TREE_DEPRECATED (x);
		    TREE_UNAVAILABLE (setter_decl) = TREE_UNAVAILABLE (x);
		    METHOD_PROPERTY_CONTEXT (setter_decl) = x;
		  }
	      }
	  }
	break;
      }
    default:
      gcc_unreachable ();
      break;
    }
}

static tree
add_protocol (tree protocol)
{
  /* Put protocol on list in reverse order.  */
  TREE_CHAIN (protocol) = protocol_chain;
  protocol_chain = protocol;
  return protocol_chain;
}

/* Check that a protocol is defined, and, recursively, that all
   protocols that this protocol conforms to are defined too.  */
static void
check_that_protocol_is_defined (tree protocol)
{
  if (!PROTOCOL_DEFINED (protocol))
    warning (0, "definition of protocol %qE not found",
	     PROTOCOL_NAME (protocol));

  /* If the protocol itself conforms to other protocols, check them
     too, recursively.  */
  if (PROTOCOL_LIST (protocol))
    {
      tree p;

      for (p = PROTOCOL_LIST (protocol); p; p = TREE_CHAIN (p))
	check_that_protocol_is_defined (TREE_VALUE (p));
    }
}

/* Looks up a protocol.  If 'warn_if_deprecated' is true, a warning is
   emitted if the protocol is deprecated.  If 'definition_required' is
   true, a warning is emitted if a full @protocol definition has not
   been seen.  */
static tree
lookup_protocol (tree ident, bool warn_if_deprecated, bool definition_required)
{
  tree chain;

  for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
    if (ident == PROTOCOL_NAME (chain))
      {
	if (TREE_UNAVAILABLE (chain))
	  error ("protocol %qE is unavailable", PROTOCOL_NAME (chain));
	else if (warn_if_deprecated && TREE_DEPRECATED (chain))
	  {
	    /* It would be nice to use warn_deprecated_use() here, but
	       we are using TREE_CHAIN (which is supposed to be the
	       TYPE_STUB_DECL for a TYPE) for something different.  */
	    warning (OPT_Wdeprecated_declarations, "protocol %qE is deprecated",
		     PROTOCOL_NAME (chain));
	  }

	if (definition_required)
	  check_that_protocol_is_defined (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
objc_declare_protocol (tree name, tree attributes)
{
  bool deprecated = false;
  bool unavailable = false;

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

  /* Determine if 'deprecated', the only attribute we recognize for
     protocols, was used.  Ignore all other attributes.  */
  if (attributes)
    {
      tree attribute;
      for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
	{
	  tree name = TREE_PURPOSE (attribute);

	  if (is_attribute_p  ("deprecated", name))
	    deprecated = true;
	  else if (is_attribute_p  ("unavailable", name))
	    unavailable = true;
	  else
	    warning (OPT_Wattributes, "%qE attribute directive ignored", name);
	}
    }

  if (lookup_protocol (name, /* warn if deprecated */ false,
		       /* definition_required */ false) == 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;

      if (attributes)
	{
	  /* TODO: Do we need to store the attributes here ? */
	  TYPE_ATTRIBUTES (protocol) = attributes;
	  if (deprecated)
	    TREE_DEPRECATED (protocol) = 1;
	  if (unavailable)
	    TREE_UNAVAILABLE (protocol) = 1;
	}
    }
}

static tree
start_protocol (enum tree_code code, tree name, tree list, tree attributes)
{
  tree protocol;
  bool deprecated = false;
  bool unavailable = false;

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

  /* Determine if 'deprecated', the only attribute we recognize for
     protocols, was used.  Ignore all other attributes.  */
  if (attributes)
    {
      tree attribute;
      for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
	{
	  tree name = TREE_PURPOSE (attribute);

	  if (is_attribute_p  ("deprecated", name))
	    deprecated = true;
	  else if (is_attribute_p  ("unavailable", name))
	    unavailable = true;
	  else
	    warning (OPT_Wattributes, "%qE attribute directive ignored", name);
	}
    }

  protocol = lookup_protocol (name, /* warn_if_deprecated */ false,
			      /* definition_required */ false);

  if (!protocol)
    {
      protocol = make_node (code);
      TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);

      PROTOCOL_NAME (protocol) = name;
      PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list, /* definition_required */ false);
      add_protocol (protocol);
      PROTOCOL_DEFINED (protocol) = 1;
      PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;

      check_protocol_recursively (protocol, list);
    }
  else if (! PROTOCOL_DEFINED (protocol))
    {
      PROTOCOL_DEFINED (protocol) = 1;
      PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list, /* definition_required */ false);

      check_protocol_recursively (protocol, list);
    }
  else
    {
      warning (0, "duplicate declaration for protocol %qE",
	       name);
    }

  if (attributes)
    {
      TYPE_ATTRIBUTES (protocol) = attributes;
      if (deprecated)
	TREE_DEPRECATED (protocol) = 1;
      if (unavailable)
	TREE_UNAVAILABLE (protocol) = 1;
    }

  return protocol;
}

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

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

void
objc_push_parm (tree parm)
{
  tree type;

  if (TREE_TYPE (parm) == error_mark_node)
    {
      objc_parmlist = chainon (objc_parmlist, parm);
      return;
    }

  /* Decay arrays and functions into pointers.  */
  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))
    parm = build_decl (input_location, PARM_DECL, DECL_NAME (parm), type);

  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_ATOMIC (TREE_TYPE (parm)) ? TYPE_QUAL_ATOMIC : 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
tree
objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED,
		    tree expr ATTRIBUTE_UNUSED)
{
  tree parm_info = objc_parmlist;
  objc_parmlist = NULL_TREE;

  return parm_info;
}
#else
struct c_arg_info *
objc_get_parm_info (int have_ellipsis, tree expr)
{
  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 = DECL_CHAIN (parm_info);

      DECL_CHAIN (parm_info) = NULL_TREE;
      parm_info = pushdecl (parm_info);
      finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
      parm_info = next;
    }
  arg_info = get_parm_info (have_ellipsis, expr);
  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 (input_location,
			      PARM_DECL, self_id, self_type));

  /* SEL _cmd; */
  objc_push_parm (build_decl (input_location,
			      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.  EXPR is NULL or an expression that needs to be
   evaluated for the side effects of array size expressions in the
   parameters.  */

static void
start_method_def (tree method, tree expr)
{
  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;

  /* 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)
    {
      /* parmlist is a KEYWORD_DECL.  */
      tree type = TREE_VALUE (TREE_TYPE (parmlist));
      tree parm;

      parm = build_decl (input_location,
			 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
      decl_attributes (&parm, DECL_ATTRIBUTES (parmlist), 0);
      objc_push_parm (parm);
      parmlist = DECL_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, expr);

  really_start_method (objc_method_context, parm_info);
}

/* 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.  */
  while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
	 && (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;

  /* Compare the protocol lists.  */
  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 there are no protocols (most common case), the types are
     identical.  */
  if (type1 == NULL_TREE && type2 == NULL_TREE)
    return 1;

  /* If one has protocols, and the other one hasn't, they are not
     identical.  */
  if ((type1 == NULL_TREE && type2 != NULL_TREE)
      || (type1 != NULL_TREE && type2 == NULL_TREE))
    return 0;
  else
    {
      /* Else, both have protocols, and we need to do the full
	 comparison.  It is possible that either type1 or type2
	 contain some duplicate protocols in the list, so we can't
	 even just compare list_length as a first check.  */
      tree t;

      for (t = type2; t; t = TREE_CHAIN (t))
	if (!lookup_protocol_in_reflist (type1, TREE_VALUE (t)))
	  return 0;

      for (t = type1; t; t = TREE_CHAIN (t))
	if (!lookup_protocol_in_reflist (type2, TREE_VALUE (t)))
	  return 0;

      return 1;
    }
}

/* 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
   is the same.  */

static int
comp_proto_with_proto (tree proto1, tree proto2, int strict)
{
  tree type1, type2;

  /* The following test is needed in case there are hashing
     collisions.  */
  if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
    return 0;

  /* Compare return types.  */
  type1 = TREE_VALUE (TREE_TYPE (proto1));
  type2 = TREE_VALUE (TREE_TYPE (proto2));

  if (!objc_types_are_equivalent (type1, type2)
      && (strict || !objc_types_share_size_and_alignment (type1, type2)))
    return 0;

  /* Compare argument types.  */

  /* The first argument (objc_object_type) is always the same, no need
     to compare.  */

  /* The second argument (objc_selector_type) is always the same, no
     need to compare.  */

  /* Compare the other arguments.  */
  {
    tree arg1, arg2;

    /* Compare METHOD_SEL_ARGS.  */
    for (arg1 = METHOD_SEL_ARGS (proto1), arg2 = METHOD_SEL_ARGS (proto2);
	 arg1 && arg2;
	 arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2))
      {
	type1 = TREE_VALUE (TREE_TYPE (arg1));
	type2 = TREE_VALUE (TREE_TYPE (arg2));

	/* FIXME: Do we need to decay argument types to compare them ?  */
	type1 = objc_decay_parm_type (type1);
	type2 = objc_decay_parm_type (type2);

	if (!objc_types_are_equivalent (type1, type2)
	    && (strict || !objc_types_share_size_and_alignment (type1, type2)))
	  return 0;
      }

    /* The loop ends when arg1 or arg2 are NULL.  Make sure they are
       both NULL.  */
    if (arg1 != arg2)
      return 0;

    /* Compare METHOD_ADD_ARGS.  */
    if ((METHOD_ADD_ARGS (proto1) && !METHOD_ADD_ARGS (proto2))
	|| (METHOD_ADD_ARGS (proto2) && !METHOD_ADD_ARGS (proto1)))
      return 0;

    if (METHOD_ADD_ARGS (proto1))
      {
	for (arg1 = TREE_CHAIN (METHOD_ADD_ARGS (proto1)), arg2 = TREE_CHAIN (METHOD_ADD_ARGS (proto2));
	     arg1 && arg2;
	     arg1 = TREE_CHAIN (arg1), arg2 = TREE_CHAIN (arg2))
	  {
	    type1 = TREE_TYPE (TREE_VALUE (arg1));
	    type2 = TREE_TYPE (TREE_VALUE (arg2));

	    /* FIXME: Do we need to decay argument types to compare them ?  */
	    type1 = objc_decay_parm_type (type1);
	    type2 = objc_decay_parm_type (type2);

	    if (!objc_types_are_equivalent (type1, type2)
		&& (strict || !objc_types_share_size_and_alignment (type1, type2)))
	      return 0;
	  }
      }

    /* The loop ends when arg1 or arg2 are NULL.  Make sure they are
       both NULL.  */
    if (arg1 != arg2)
      return 0;

    /* Compare METHOD_ADD_ARGS_ELLIPSIS_P.  */
    if (METHOD_ADD_ARGS_ELLIPSIS_P (proto1) != METHOD_ADD_ARGS_ELLIPSIS_P (proto2))
      return 0;
  }

  /* Success.  */
  return 1;
}

/* This routine returns true if TYPE is a valid objc object type,
   suitable for messaging; false otherwise.  If 'accept_class' is
   'true', then a Class object is considered valid for messaging and
   'true' is returned if 'type' refers to a Class.  If 'accept_class'
   is 'false', then a Class object is not considered valid for
   messaging and 'false' is returned in that case.  */

static bool
objc_type_valid_for_messaging (tree type, bool accept_classes)
{
  if (!POINTER_TYPE_P (type))
    return false;

  /* We will check for an NSObject type attribute  on the pointer if other
     tests fail.  */
  tree type_attr = TYPE_ATTRIBUTES (type);

  /* Remove the pointer indirection; don't remove more than one
     otherwise we'd consider "NSObject **" a valid type for messaging,
     which it isn't.  */
  type = TREE_TYPE (type);

  /* We allow void * to have an NSObject type attr.  */
  if (VOID_TYPE_P (type) && type_attr)
    return lookup_attribute ("NSObject", type_attr) != NULL_TREE;

  if (TREE_CODE (type) != RECORD_TYPE)
    return false;

  if (objc_is_object_id (type))
    return true;

  if (objc_is_class_id (type))
    return accept_classes;

  if (TYPE_HAS_OBJC_INFO (type))
    return true;

  if (type_attr)
    return lookup_attribute ("NSObject", type_attr) != NULL_TREE;

  return false;
}

void
objc_start_function (tree name, tree type, tree attrs,
#ifdef OBJCPLUS
		     tree params
#else
		     struct c_arg_info *params
#endif
		     )
{
  tree fndecl = build_decl (input_location,
			    FUNCTION_DECL, name, type);

#ifdef OBJCPLUS
  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);
  start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
#else
  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);
  push_scope ();
  declare_parm_level ();
  DECL_RESULT (current_function_decl)
    = build_decl (input_location,
		  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_for_method (ret_type, method, METHOD_DEF, 0);
  objc_start_function (method_id, meth_type, NULL_TREE, parmlist);

  /* Set self_decl from the first argument.  */
  self_decl = DECL_ARGUMENTS (current_function_decl);

  /* Suppress unused warnings.  */
  TREE_USED (self_decl) = 1;
  DECL_READ_P (self_decl) = 1;
  TREE_USED (DECL_CHAIN (self_decl)) = 1;
  DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
#ifdef OBJCPLUS
  pop_lang_context ();
#endif

  METHOD_DEFINITION (method) = current_function_decl;

  /* Check consistency...start_function, pushdecl, duplicate_decls.  */

  if (implementation_template != objc_implementation_context)
    {
      tree proto
	= lookup_method_static (implementation_template,
				METHOD_SEL_NAME (method),
				((TREE_CODE (method) == CLASS_METHOD_DECL)
				 | OBJC_LOOKUP_NO_SUPER));

      if (proto)
	{
	  if (!comp_proto_with_proto (method, proto, 1))
	    {
	      bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;

	      warning_at (DECL_SOURCE_LOCATION (method), 0,
			  "conflicting types for %<%c%s%>",
			  (type ? '-' : '+'),
			  identifier_to_locale (gen_method_decl (method)));
	      inform (DECL_SOURCE_LOCATION (proto),
		      "previous declaration of %<%c%s%>",
		      (type ? '-' : '+'),
		      identifier_to_locale (gen_method_decl (proto)));
	    }
	  else
	    {
	      /* If the method in the @interface was deprecated, mark
		 the implemented method as deprecated too.  It should
		 never be used for messaging (when the deprecation
		 warnings are produced), but just in case.  */
	      if (TREE_DEPRECATED (proto))
		TREE_DEPRECATED (method) = 1;
	      if (TREE_UNAVAILABLE (proto))
		TREE_UNAVAILABLE (method) = 1;

	      /* If the method in the @interface was marked as
		 'noreturn', mark the function implementing the method
		 as 'noreturn' too.  */
	      TREE_THIS_VOLATILE (current_function_decl) = TREE_THIS_VOLATILE (proto);
	    }
	}
      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),
			     TREE_CODE (method) == CLASS_METHOD_DECL,
			     /* is_optional= */ false);
	}
    }
}

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, class_expr;
      bool inst_meth;
      if (!UOBJC_SUPER_decl)
      {
	UOBJC_SUPER_decl = build_decl (input_location,
				       VAR_DECL, get_identifier (TAG_SUPER),
				       objc_super_template);
	/* This prevents `unused variable' warnings when compiling with -Wall.  */
	TREE_USED (UOBJC_SUPER_decl) = 1;
	DECL_READ_P (UOBJC_SUPER_decl) = 1;
	lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
        finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, 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);
      super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
				      NOP_EXPR, input_location, self_decl,
				      NULL_TREE);
      super_expr_list = super_expr;

      /* Set class to begin searching.  */
      /* Get the ident for the superclass class field & build a ref to it.
         ??? maybe we should just name the field the same for all runtimes.  */
      super_expr = (*runtime.super_superclassfield_ident) ();
      super_expr = objc_build_component_ref (UOBJC_SUPER_decl, super_expr);

      gcc_assert (imp_list->imp_context == objc_implementation_context
		  && imp_list->imp_template == implementation_template);
      inst_meth = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL);

      if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
	class_expr =  (*runtime.get_class_super_ref) (input_location,
						      imp_list, inst_meth);
      else
	/* We have a category.  */
	{
	  tree super_name = CLASS_SUPER_NAME (imp_list->imp_template);
	  tree super_class;

	  /* Barf if super used in a category of a root object.  */
	  if (!super_name)
	    {
	      error ("no super class declared in interface for %qE",
		     CLASS_NAME (imp_list->imp_template));
	      return error_mark_node;
	    }

	  super_class = (*runtime.get_category_super_ref) (input_location,
							   imp_list, inst_meth);
	  class_expr = build_c_cast (input_location,
				     TREE_TYPE (super_expr), super_class);
	}

      super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
				      NOP_EXPR,
				      input_location, class_expr, NULL_TREE);

      super_expr_list = build_compound_expr (input_location,
					     super_expr_list, super_expr);

      super_expr = build_unary_op (input_location,
				   ADDR_EXPR, UOBJC_SUPER_decl, 0);
      super_expr_list = build_compound_expr (input_location,
					     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_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");
}

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

#ifdef OBJCPLUS
      tree w = DECL_BIT_FIELD_REPRESENTATIVE (decl);
#else
      tree w = DECL_INITIAL (decl);
#endif
      if (w)
	{
	  STRIP_ANY_LOCATION_WRAPPER (w);
	  if (TREE_CODE (w) == INTEGER_CST)
	    sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
		     TREE_INT_CST_LOW (w));
	}
    }

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

      switch (TREE_CODE (chain))
	{
	case CATEGORY_IMPLEMENTATION_TYPE:
	case CATEGORY_INTERFACE_TYPE:
	  fprintf (fp, " (%s)\n", name);
	  break;
	default:
	  fprintf (fp, " : %s\n", name);
	  break;
	}
    }
  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");
}

#if 0
/* Produce the pretty printing for an Objective-C method.  This is
   currently unused, but could be handy while reorganizing the pretty
   printing to be more robust.  */
static const char *
objc_pretty_print_method (bool is_class_method,
			  const char *class_name,
			  const char *category_name,
			  const char *selector)
{
  if (category_name)
    {
      char *result = XNEWVEC (char, strlen (class_name) + strlen (category_name)
			      + strlen (selector) + 7);

      if (is_class_method)
	sprintf (result, "+[%s(%s) %s]", class_name, category_name, selector);
      else
	sprintf (result, "-[%s(%s) %s]", class_name, category_name, selector);

      return result;
    }
  else
    {
      char *result = XNEWVEC (char, strlen (class_name)
			      + strlen (selector) + 5);

      if (is_class_method)
	sprintf (result, "+[%s %s]", class_name, selector);
      else
	sprintf (result, "-[%s %s]", class_name, selector);

      return result;
    }
}
#endif

/* Demangle function for Objective-C.  Attempt to demangle the
   function name associated with a method (eg, going from
   "_i_NSObject__class" to "-[NSObject class]"); usually for the
   purpose of pretty printing or error messages.  Return the demangled
   name, or NULL if the string is not an Objective-C mangled method
   name.

   Because of how the mangling is done, any method that has a '_' in
   its original name is at risk of being demangled incorrectly.  In
   some cases there are multiple valid ways to demangle a method name
   and there is no way we can decide.

   TODO: objc_demangle() can't always get it right; the right way to
   get this correct for all method names would be to store the
   Objective-C method name somewhere in the function decl.  Then,
   there is no demangling to do; we'd just pull the method name out of
   the decl.  As an additional bonus, when printing error messages we
   could check for such a method name, and if we find it, we know the
   function is actually an Objective-C method and we could print error
   messages saying "In method '+[NSObject class]" instead of "In
   function '+[NSObject class]" as we do now.  */
static const char *
objc_demangle (const char *mangled)
{
  char *demangled, *cp;

  /* First of all, if the name is too short it can't be an Objective-C
     mangled method name.  */
  if (mangled[0] == '\0' || mangled[1] == '\0' || mangled[2] == '\0')
    return NULL;

  /* If the name looks like an already demangled one, return it
     unchanged.  This should only happen on Darwin, where method names
     are mangled differently into a pretty-print form (such as
     '+[NSObject class]', see darwin.h).  In that case, demangling is
     a no-op, but we need to return the demangled name if it was an
     ObjC one, and return NULL if not.  We should be safe as no C/C++
     function can start with "-[" or "+[".  */
  if ((mangled[0] == '-' || mangled[0] == '+')
      && (mangled[1] == '['))
    return mangled;

  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 NULL;
	}
      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 NULL;
	    }
	  *cp++ = ')';
	  *cp++ = ' ';            /* overwriting 1st char of method name... */
	  strcpy(cp, mangled + (cp - demangled)); /* get it back */
	}
      /* Now we have the method name.  We need to generally replace
	 '_' with ':' but trying to preserve '_' if it could only have
	 been in the mangled string because it was already in the
	 original name.  In cases where it's ambiguous, we assume that
	 any '_' originated from a ':'.  */

      /* Initial '_'s in method name can't have been generating by
	 converting ':'s.  Skip them.  */
      while (*cp && *cp == '_')
	cp++;

      /* If the method name does not end with '_', then it has no
	 arguments and there was no replacement of ':'s with '_'s
	 during mangling.  Check for that case, and skip any
	 replacement if so.  This at least guarantees that methods
	 with no arguments are always demangled correctly (unless the
	 original name ends with '_').  */
      if (*(mangled + strlen (mangled) - 1) != '_')
	{
	  /* Skip to the end.  */
	  for (; *cp; cp++)
	    ;
	}
      else
	{
	  /* Replace remaining '_' with ':'.  This may get it wrong if
	     there were '_'s in the original name.  In most cases it
	     is impossible to disambiguate.  */
	  for (; *cp; cp++)
	    if (*cp == '_')
	      *cp = ':';
	}
      *cp++ = ']';              /* closing right brace */
      *cp++ = 0;                /* string terminator */
      return demangled;
    }
  else
    return NULL;             /* not an objc mangled name */
}

/* Try to pretty-print a decl.  If the 'decl' is an Objective-C
   specific decl, return the printable name for it.  If not, return
   NULL.  */
const char *
objc_maybe_printable_name (tree decl, int v ATTRIBUTE_UNUSED)
{
  switch (TREE_CODE (decl))
    {
    case FUNCTION_DECL:
      return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));

      /* The following happens when we are printing a deprecation
	 warning for a method.  The warn_deprecation() will end up
	 trying to print the decl for INSTANCE_METHOD_DECL or
	 CLASS_METHOD_DECL.  It would be nice to be able to print
	 "-[NSObject autorelease] is deprecated", but to do that, we'd
	 need to store the class and method name in the method decl,
	 which we currently don't do.  For now, just return the name
	 of the method.  We don't return NULL, because that may
	 trigger further attempts to pretty-print the decl in C/C++,
	 but they wouldn't know how to pretty-print it.  */
    case INSTANCE_METHOD_DECL:
    case CLASS_METHOD_DECL:
      return IDENTIFIER_POINTER (DECL_NAME (decl));
      /* This happens when printing a deprecation warning for a
	 property.  We may want to consider some sort of pretty
	 printing (eg, include the class name where it was declared
	 ?).  */
    case PROPERTY_DECL:
      return IDENTIFIER_POINTER (PROPERTY_NAME (decl));
    default:
      return NULL;
    }
}

/* Return a printable name for 'decl'.  This first tries
   objc_maybe_printable_name(), and if that fails, it returns the name
   in the decl.  This is used as LANG_HOOKS_DECL_PRINTABLE_NAME for
   Objective-C; in Objective-C++, setting the hook is not enough
   because lots of C++ Front-End code calls cxx_printable_name,
   dump_decl and other C++ functions directly.  So instead we have
   modified dump_decl to call objc_maybe_printable_name directly.  */
const char *
objc_printable_name (tree decl, int v)
{
  const char *demangled_name = objc_maybe_printable_name (decl, v);

  if (demangled_name != NULL)
    return demangled_name;
  else
    return IDENTIFIER_POINTER (DECL_NAME (decl));
}

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

/* Look up ID as an instance variable.  OTHER contains the result of
   the C or C++ lookup, which we may want to use instead.  */
/* To use properties inside an instance method, use self.property.  */
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;

  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;

  /* Don't look up the ivar if the user has explicitly advised against
     it with -fno-local-ivars.  */

  if (!flag_local_ivars)
    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
    {
      if (warn_shadow_ivar == 1 || (warn_shadow && warn_shadow_ivar != 0)) {
          warning (warn_shadow_ivar ? OPT_Wshadow_ivar : OPT_Wshadow,
                   "local declaration of %qE hides instance variable", 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);
}

/* 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 first_param)
{
  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), first_param,
		       build_int_cst (TREE_TYPE (first_param), 0));

  return function;
}

/* This is called to "gimplify" a PROPERTY_REF node.  It builds the
   corresponding 'getter' function call.  Note that we assume the
   PROPERTY_REF to be valid since we generated it while parsing.  */
static void
objc_gimplify_property_ref (tree *expr_p)
{
  tree getter = PROPERTY_REF_GETTER_CALL (*expr_p);
  tree call_exp;

  if (getter == NULL_TREE)
    {
      tree property_decl = PROPERTY_REF_PROPERTY_DECL (*expr_p);
      /* This can happen if DECL_ARTIFICIAL (*expr_p), but
	 should be impossible for real properties, which always
	 have a getter.  */
      error_at (EXPR_LOCATION (*expr_p), "no %qs getter found",
		IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
      /* Try to recover from the error to prevent an ICE.  We take
	 zero and cast it to the type of the property.  */
      *expr_p = convert (TREE_TYPE (property_decl),
			 integer_zero_node);
      return;
    }

  /* FIXME, this should be a label indicating availability in general.  */
  if (PROPERTY_REF_DEPRECATED_GETTER (*expr_p))
    {
      if (TREE_UNAVAILABLE (PROPERTY_REF_DEPRECATED_GETTER (*expr_p)))
	error_unavailable_use (PROPERTY_REF_DEPRECATED_GETTER (*expr_p),
			       NULL_TREE);
      else
	/* PROPERTY_REF_DEPRECATED_GETTER contains the method prototype
	 that is deprecated.  */
	warn_deprecated_use (PROPERTY_REF_DEPRECATED_GETTER (*expr_p),
			     NULL_TREE);
    }

  call_exp = getter;
#ifdef OBJCPLUS
  /* In C++, a getter which returns an aggregate value results in a
     target_expr which initializes a temporary to the call
     expression.  */
  if (TREE_CODE (getter) == TARGET_EXPR)
    {
      gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter)));
      gcc_assert (VAR_P (TREE_OPERAND (getter, 0)));
      call_exp = TREE_OPERAND (getter, 1);
    }
#endif
  gcc_checking_assert ((flag_objc_nilcheck
			&& TREE_CODE (call_exp) == COND_EXPR)
		       || TREE_CODE (call_exp) == CALL_EXPR);

  *expr_p = call_exp;
}

/* This is called when "gimplifying" the trees.  We need to gimplify
   the Objective-C/Objective-C++ specific trees, then hand over the
   process to C/C++.  */
int
objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
  enum tree_code code = TREE_CODE (*expr_p);
  switch (code)
    {
      /* 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).  */
    case OBJ_TYPE_REF:
      if (TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
	  && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
	  == FUNCTION_DECL)
	{
	  enum gimplify_status r0, r1;

	  /* 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);
	}
      break;
    case PROPERTY_REF:
      objc_gimplify_property_ref (expr_p);
      /* Do not return yet; let C/C++ gimplify the resulting expression.  */
      break;
    default:
      break;
    }

#ifdef OBJCPLUS
  return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
#else
  return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
#endif
}

/* --- FAST ENUMERATION --- */
/* Begin code generation for fast enumeration (foreach) ... */

/* Defines

  struct __objcFastEnumerationState
   {
     unsigned long state;
     id            *itemsPtr;
     unsigned long *mutationsPtr;
     unsigned long extra[5];
   };

   Confusingly enough, NSFastEnumeration is then defined by libraries
   to be the same structure.
*/

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

  /* { */
  objc_fast_enumeration_state_template = objc_start_struct (get_identifier
							    (TAG_FAST_ENUMERATION_STATE));

  /* unsigned long state; */
  decls = add_field_decl (long_unsigned_type_node, "state", &chain);

  /* id            *itemsPtr; */
  add_field_decl (build_pointer_type (objc_object_type),
		  "itemsPtr", &chain);

  /* unsigned long *mutationsPtr; */
  add_field_decl (build_pointer_type (long_unsigned_type_node),
		  "mutationsPtr", &chain);

  /* unsigned long extra[5]; */
  add_field_decl (build_sized_array_type (long_unsigned_type_node, 5),
		  "extra", &chain);

  /* } */
  objc_finish_struct (objc_fast_enumeration_state_template, decls);
}

/*
  'objc_finish_foreach_loop()' generates the code for an Objective-C
  foreach loop.  The 'location' argument is the location of the 'for'
  that starts the loop.  The 'object_expression' is the expression of
  the 'object' that iterates; the 'collection_expression' is the
  expression of the collection that we iterate over (we need to make
  sure we evaluate this only once); the 'for_body' is the set of
  statements to be executed in each iteration; 'break_label' and
  'continue_label' are the break and continue labels which we need to
  emit since the <statements> may be jumping to 'break_label' (if they
  contain 'break') or to 'continue_label' (if they contain
  'continue').

  The syntax is

  for (<object expression> in <collection expression>)
    <statements>

  which is compiled into the following blurb:

  {
    id __objc_foreach_collection;
    __objc_fast_enumeration_state __objc_foreach_enum_state;
    unsigned long __objc_foreach_batchsize;
    id __objc_foreach_items[16];
    __objc_foreach_collection = <collection expression>;
    __objc_foreach_enum_state = { 0 };
    __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16];

    if (__objc_foreach_batchsize == 0)
      <object expression> = nil;
    else
      {
	unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
        next_batch:
	  {
	    unsigned long __objc_foreach_index;
            __objc_foreach_index = 0;

            next_object:
	    if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
	    <object expression> = enumState.itemsPtr[__objc_foreach_index];
	    <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]

            continue_label:
            __objc_foreach_index++;
            if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
	    __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16];
         }
       if (__objc_foreach_batchsize != 0) goto next_batch;
       <object expression> = nil;
       break_label:
      }
  }

  'statements' may contain a 'continue' or 'break' instruction, which
  the user expects to 'continue' or 'break' the entire foreach loop.
  We are provided the labels that 'break' and 'continue' jump to, so
  we place them where we want them to jump to when they pick them.

  Optimization TODO: we could cache the IMP of
  countByEnumeratingWithState:objects:count:.
*/

/* If you need to debug objc_finish_foreach_loop(), uncomment the following line.  */
/* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */

#ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
#include "tree-pretty-print.h"
#endif

void
objc_finish_foreach_loop (location_t location, tree object_expression, tree collection_expression, tree for_body,
			  tree break_label, tree continue_label)
{
  /* A tree representing the __objcFastEnumerationState struct type,
     or NSFastEnumerationState struct, whatever we are using.  */
  tree objc_fast_enumeration_state_type;

  /* The trees representing the declarations of each of the local variables.  */
  tree objc_foreach_collection_decl;
  tree objc_foreach_enum_state_decl;
  tree objc_foreach_items_decl;
  tree objc_foreach_batchsize_decl;
  tree objc_foreach_mutations_pointer_decl;
  tree objc_foreach_index_decl;

  /* A tree representing the selector countByEnumeratingWithState:objects:count:.  */
  tree selector_name;

  /* A tree representing the local bind.  */
  tree bind;

  /* A tree representing the external 'if (__objc_foreach_batchsize)' */
  tree first_if;

  /* A tree representing the 'else' part of 'first_if'  */
  tree first_else;

  /* A tree representing the 'next_batch' label.  */
  tree next_batch_label_decl;

  /* A tree representing the binding after the 'next_batch' label.  */
  tree next_batch_bind;

  /* A tree representing the 'next_object' label.  */
  tree next_object_label_decl;

  /* Temporary variables.  */
  tree t;
  int i;

  if (flag_objc1_only)
    error_at (location, "fast enumeration is not available in Objective-C 1.0");

  if (object_expression == error_mark_node)
    return;

  if (collection_expression == error_mark_node)
    return;

  if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression), true))
    {
      error_at (location, "iterating variable in fast enumeration is not an object");
      return;
    }

  if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression), true))
    {
      error_at (location, "collection in fast enumeration is not an object");
      return;
    }

  /* TODO: Check that object_expression is either a variable
     declaration, or an lvalue.  */

  /* This kludge is an idea from apple.  We use the
     __objcFastEnumerationState struct implicitly defined by the
     compiler, unless a NSFastEnumerationState struct has been defined
     (by a Foundation library such as GNUstep Base) in which case, we
     use that one.
  */
  objc_fast_enumeration_state_type = objc_fast_enumeration_state_template;
  {
    tree objc_NSFastEnumeration_type = lookup_name (get_identifier ("NSFastEnumerationState"));

    if (objc_NSFastEnumeration_type)
      {
	/* TODO: We really need to check that
	   objc_NSFastEnumeration_type is the same as ours!  */
	if (TREE_CODE (objc_NSFastEnumeration_type) == TYPE_DECL)
	  {
	    /* If it's a typedef, use the original type.  */
	    if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type))
	      objc_fast_enumeration_state_type = DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type);
	    else
	      objc_fast_enumeration_state_type = TREE_TYPE (objc_NSFastEnumeration_type);
	  }
      }
  }

  /* { */
  /* Done by c-parser.cc.  */

  /* type object; */
  /* Done by c-parser.cc.  */

  /* Disable warnings that 'object' is unused.  For example the code

     for (id object in collection)
       i++;

     which can be used to count how many objects there are in the
     collection is fine and should generate no warnings even if
     'object' is technically unused.  */
  TREE_USED (object_expression) = 1;
  if (DECL_P (object_expression))
    DECL_READ_P (object_expression) = 1;

  /*  id __objc_foreach_collection */
  objc_foreach_collection_decl = objc_create_temporary_var (objc_object_type, "__objc_foreach_collection");

  /*  __objcFastEnumerationState __objc_foreach_enum_state; */
  objc_foreach_enum_state_decl = objc_create_temporary_var (objc_fast_enumeration_state_type, "__objc_foreach_enum_state");
  TREE_CHAIN (objc_foreach_enum_state_decl) = objc_foreach_collection_decl;

  /* id __objc_foreach_items[16]; */
  objc_foreach_items_decl = objc_create_temporary_var (build_sized_array_type (objc_object_type, 16), "__objc_foreach_items");
  TREE_CHAIN (objc_foreach_items_decl) = objc_foreach_enum_state_decl;

  /* unsigned long __objc_foreach_batchsize; */
  objc_foreach_batchsize_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_batchsize");
  TREE_CHAIN (objc_foreach_batchsize_decl) = objc_foreach_items_decl;

  /* Generate the local variable binding.  */
  bind = build3 (BIND_EXPR, void_type_node, objc_foreach_batchsize_decl, NULL, NULL);
  SET_EXPR_LOCATION (bind, location);
  TREE_SIDE_EFFECTS (bind) = 1;

  /*  __objc_foreach_collection = <collection expression>; */
  t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_collection_decl, collection_expression);
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (bind));
  /* We have used 'collection_expression'.  */
  mark_exp_read (collection_expression);

  /*  __objc_foreach_enum_state.state = 0; */
  t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
								     get_identifier ("state")),
	      build_int_cst (long_unsigned_type_node, 0));
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (bind));

  /*  __objc_foreach_enum_state.itemsPtr = NULL; */
  t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
								     get_identifier ("itemsPtr")),
	      null_pointer_node);
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (bind));

  /*  __objc_foreach_enum_state.mutationsPtr = NULL; */
  t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
								     get_identifier ("mutationsPtr")),
	      null_pointer_node);
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (bind));

  /*  __objc_foreach_enum_state.extra[0] = 0; */
  /*  __objc_foreach_enum_state.extra[1] = 0; */
  /*  __objc_foreach_enum_state.extra[2] = 0; */
  /*  __objc_foreach_enum_state.extra[3] = 0; */
  /*  __objc_foreach_enum_state.extra[4] = 0; */
  for (i = 0; i < 5 ; i++)
    {
      t = build2 (MODIFY_EXPR, void_type_node,
		  build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
								       get_identifier ("extra")),
				   build_int_cst (NULL_TREE, i)),
		  build_int_cst (long_unsigned_type_node, 0));
      SET_EXPR_LOCATION (t, location);
      append_to_statement_list (t, &BIND_EXPR_BODY (bind));
    }

  /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16]; */
  selector_name = get_identifier ("countByEnumeratingWithState:objects:count:");
#ifdef OBJCPLUS
  t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
				/* Parameters.  */
				tree_cons    /* &__objc_foreach_enum_state */
				(NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
				 tree_cons   /* __objc_foreach_items  */
				 (NULL_TREE, objc_foreach_items_decl,
				  tree_cons  /* 16 */
				  (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL);
#else
  /* In C, we need to decay the __objc_foreach_items array that we are passing.  */
  {
    struct c_expr array;
    array.value = objc_foreach_items_decl;
    t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
				  /* Parameters.  */
				  tree_cons    /* &__objc_foreach_enum_state */
				  (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
				   tree_cons   /* __objc_foreach_items  */
				   (NULL_TREE, default_function_array_conversion (location, array).value,
				    tree_cons  /* 16 */
				    (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL);
  }
#endif
  t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
	      convert (long_unsigned_type_node, t));
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (bind));

  /* if (__objc_foreach_batchsize == 0) */
  first_if = build3 (COND_EXPR, void_type_node,
		     /* Condition.  */
		     c_fully_fold
		     (c_common_truthvalue_conversion
		      (location,
		       build_binary_op (location,
					EQ_EXPR,
					objc_foreach_batchsize_decl,
					build_int_cst (long_unsigned_type_node, 0), 1)),
		      false, NULL),
		     /* Then block (we fill it in later).  */
		     NULL_TREE,
		     /* Else block (we fill it in later).  */
		     NULL_TREE);
  SET_EXPR_LOCATION (first_if, location);
  append_to_statement_list (first_if, &BIND_EXPR_BODY (bind));

  /* then <object expression> = nil; */
  t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
  SET_EXPR_LOCATION (t, location);
  COND_EXPR_THEN (first_if) = t;

  /* Now we build the 'else' part of the if; once we finish building
     it, we attach it to first_if as the 'else' part.  */

  /* else */
  /* { */

  /* unsigned long __objc_foreach_mutations_pointer; */
  objc_foreach_mutations_pointer_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_mutations_pointer");

  /* Generate the local variable binding.  */
  first_else = build3 (BIND_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, NULL, NULL);
  SET_EXPR_LOCATION (first_else, location);
  TREE_SIDE_EFFECTS (first_else) = 1;

  /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
  t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_mutations_pointer_decl,
	      build_indirect_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
								      get_identifier ("mutationsPtr")),
				  RO_UNARY_STAR));
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (first_else));

  /* next_batch: */
  next_batch_label_decl = create_artificial_label (location);
  t = build1 (LABEL_EXPR, void_type_node, next_batch_label_decl);
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (first_else));

  /* { */

  /* unsigned long __objc_foreach_index; */
  objc_foreach_index_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_index");

  /* Generate the local variable binding.  */
  next_batch_bind = build3 (BIND_EXPR, void_type_node, objc_foreach_index_decl, NULL, NULL);
  SET_EXPR_LOCATION (next_batch_bind, location);
  TREE_SIDE_EFFECTS (next_batch_bind) = 1;
  append_to_statement_list (next_batch_bind, &BIND_EXPR_BODY (first_else));

  /* __objc_foreach_index = 0; */
  t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
	      build_int_cst (long_unsigned_type_node, 0));
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));

  /* next_object: */
  next_object_label_decl = create_artificial_label (location);
  t = build1 (LABEL_EXPR, void_type_node, next_object_label_decl);
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));

  /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
  t = build3 (COND_EXPR, void_type_node,
	      /* Condition.  */
	      c_fully_fold
	      (c_common_truthvalue_conversion
	       (location,
		build_binary_op
		(location,
		 NE_EXPR,
		 objc_foreach_mutations_pointer_decl,
		 build_indirect_ref (location,
				     objc_build_component_ref (objc_foreach_enum_state_decl,
							       get_identifier ("mutationsPtr")),
				     RO_UNARY_STAR), 1)),
	       false, NULL),
	      /* Then block.  */
	      build_function_call (input_location,
				   objc_enumeration_mutation_decl,
				   tree_cons (NULL, collection_expression, NULL)),
	      /* Else block.  */
	      NULL_TREE);
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));

  /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
  t = build2 (MODIFY_EXPR, void_type_node, object_expression,
	      build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
								   get_identifier ("itemsPtr")),
			       objc_foreach_index_decl));
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));

  /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
  append_to_statement_list (for_body, &BIND_EXPR_BODY (next_batch_bind));

  /* continue_label: */
  if (continue_label)
    {
      t = build1 (LABEL_EXPR, void_type_node, continue_label);
      SET_EXPR_LOCATION (t, location);
      append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
    }

  /* __objc_foreach_index++; */
  t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
	      build_binary_op (location,
			       PLUS_EXPR,
			       objc_foreach_index_decl,
			       build_int_cst (long_unsigned_type_node, 1), 1));
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));

  /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
  t = build3 (COND_EXPR, void_type_node,
	      /* Condition.  */
	      c_fully_fold
	      (c_common_truthvalue_conversion
	       (location,
		build_binary_op (location,
				 LT_EXPR,
				 objc_foreach_index_decl,
				 objc_foreach_batchsize_decl, 1)),
	       false, NULL),
	      /* Then block.  */
	      build1 (GOTO_EXPR, void_type_node, next_object_label_decl),
	      /* Else block.  */
	      NULL_TREE);
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));

  /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16]; */
#ifdef OBJCPLUS
  t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
				/* Parameters.  */
				tree_cons    /* &__objc_foreach_enum_state */
				(NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
				 tree_cons   /* __objc_foreach_items  */
				 (NULL_TREE, objc_foreach_items_decl,
				  tree_cons  /* 16 */
				  (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL);
#else
  /* In C, we need to decay the __objc_foreach_items array that we are passing.  */
  {
    struct c_expr array;
    array.value = objc_foreach_items_decl;
    t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
				  /* Parameters.  */
				  tree_cons    /* &__objc_foreach_enum_state */
				  (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
				   tree_cons   /* __objc_foreach_items  */
				   (NULL_TREE, default_function_array_conversion (location, array).value,
				    tree_cons  /* 16 */
				    (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL);
  }
#endif
  t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
	      convert (long_unsigned_type_node, t));
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));

  /* } */

  /* if (__objc_foreach_batchsize != 0) goto next_batch; */
  t = build3 (COND_EXPR, void_type_node,
	      /* Condition.  */
	      c_fully_fold
	      (c_common_truthvalue_conversion
	       (location,
		build_binary_op (location,
				 NE_EXPR,
				 objc_foreach_batchsize_decl,
				 build_int_cst (long_unsigned_type_node, 0), 1)),
	       false, NULL),
	      /* Then block.  */
	      build1 (GOTO_EXPR, void_type_node, next_batch_label_decl),
	      /* Else block.  */
	      NULL_TREE);
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (first_else));

  /* <object expression> = nil; */
  t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
  SET_EXPR_LOCATION (t, location);
  append_to_statement_list (t, &BIND_EXPR_BODY (first_else));

  /* break_label: */
  if (break_label)
    {
      t = build1 (LABEL_EXPR, void_type_node, break_label);
      SET_EXPR_LOCATION (t, location);
      append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
    }

  /* } */
  COND_EXPR_ELSE (first_if) = first_else;

  /* Do the whole thing.  */
  add_stmt (bind);

#ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
  /* This will print to stderr the whole blurb generated by the
     compiler while compiling (assuming the compiler doesn't crash
     before getting here).
   */
  debug_generic_stmt (bind);
#endif

  /* } */
  /* Done by c-parser.cc  */
}

/* --- SUPPORT FOR FORMAT ARG CHECKING --- */
/* Return true if we have an NxString object pointer.  */

bool
objc_string_ref_type_p (tree strp)
{
  tree tmv;
  if (!strp || TREE_CODE (strp) != POINTER_TYPE)
    return false;

  tmv = TYPE_MAIN_VARIANT (TREE_TYPE (strp));
  tmv = OBJC_TYPE_NAME (tmv);
  return (tmv
	  && TREE_CODE (tmv) == IDENTIFIER_NODE
	  && IDENTIFIER_POINTER (tmv)
	  && startswith (IDENTIFIER_POINTER (tmv), "NSString"));
}

/* At present the behavior of this is undefined and it does nothing.  */
void
objc_check_format_arg (tree ARG_UNUSED (format_arg),
		       tree ARG_UNUSED (args_list))
{
}

void
objc_common_init_ts (void)
{
  c_common_init_ts ();

  MARK_TS_DECL_NON_COMMON (CLASS_METHOD_DECL);
  MARK_TS_DECL_NON_COMMON (INSTANCE_METHOD_DECL);
  MARK_TS_DECL_NON_COMMON (KEYWORD_DECL);
  MARK_TS_DECL_NON_COMMON (PROPERTY_DECL);

  MARK_TS_COMMON (CLASS_INTERFACE_TYPE);
  MARK_TS_COMMON (PROTOCOL_INTERFACE_TYPE);
  MARK_TS_COMMON (CLASS_IMPLEMENTATION_TYPE);

  MARK_TS_TYPED (MESSAGE_SEND_EXPR);
  MARK_TS_TYPED (PROPERTY_REF);
}

/* Information for Objective-C-specific features known to __has_feature.  */

struct objc_feature_info
{
  typedef bool (*predicate_t) ();

  const char *ident;
  predicate_t predicate;

  constexpr objc_feature_info (const char *name)
    : ident (name), predicate (nullptr) {}
  constexpr objc_feature_info (const char *name, predicate_t p)
    : ident (name), predicate (p) {}

  bool has_feature () const
    {
      return predicate ? predicate () : true;
    }
};

static bool objc_nonfragile_abi_p ()
{
  return flag_next_runtime && flag_objc_abi >= 2;
}

static constexpr objc_feature_info objc_features[] =
{
  { "objc_default_synthesize_properties" },
  { "objc_instancetype" },
  { "objc_nonfragile_abi", objc_nonfragile_abi_p }
};

/* Register Objective-C-specific features for __has_feature.  */

void
objc_common_register_features ()
{
  for (unsigned i = 0; i < ARRAY_SIZE (objc_features); i++)
    {
      const objc_feature_info *info = objc_features + i;
      if (!info->has_feature ())
	continue;

      c_common_register_feature (info->ident, true);
    }
}

#include "gt-objc-objc-act.h"
