Home | History | Annotate | Line # | Download | only in objc
objc-act.cc revision 1.1.1.1
      1 /* Implement classes and message passing for Objective C.
      2    Copyright (C) 1992-2022 Free Software Foundation, Inc.
      3    Contributed by Steve Naroff.
      4 
      5 This file is part of GCC.
      6 
      7 GCC is free software; you can redistribute it and/or modify
      8 it under the terms of the GNU General Public License as published by
      9 the Free Software Foundation; either version 3, or (at your option)
     10 any later version.
     11 
     12 GCC is distributed in the hope that it will be useful,
     13 but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with GCC; see the file COPYING3.  If not see
     19 <http://www.gnu.org/licenses/>.  */
     20 
     21 #include "config.h"
     22 #include "system.h"
     23 #include "coretypes.h"
     24 #include "tm.h"
     25 #include "tree.h"
     26 #include "stringpool.h"
     27 #include "stor-layout.h"
     28 #include "attribs.h"
     29 
     30 #ifdef OBJCPLUS
     31 #include "cp/cp-tree.h"
     32 #else
     33 #include "c/c-tree.h"
     34 #include "c/c-lang.h"
     35 #endif
     36 
     37 #include "c-family/c-objc.h"
     38 #include "langhooks.h"
     39 #include "objc-act.h"
     40 #include "objc-map.h"
     41 #include "function.h"
     42 #include "toplev.h"
     43 #include "debug.h"
     44 #include "c-family/c-target.h"
     45 #include "intl.h"
     46 #include "cgraph.h"
     47 #include "tree-iterator.h"
     48 /* Different initialization, code gen and meta data generation for each
     49    runtime.  */
     50 #include "objc-runtime-hooks.h"
     51 /* Routines used mainly by the runtimes.  */
     52 #include "objc-runtime-shared-support.h"
     53 /* For default_tree_printer ().  */
     54 
     55 /* For enum gimplify_status */
     56 #include "gimple-expr.h"
     57 #include "gimplify.h"
     58 
     59 /* For encode_method_prototype().  */
     60 #include "objc-encoding.h"
     61 
     62 static unsigned int should_call_super_dealloc = 0;
     63 
     64 /* When building Objective-C++, we are not linking against the C front-end
     65    and so need to replicate the C tree-construction functions in some way.  */
     66 #ifdef OBJCPLUS
     67 #define OBJCP_REMAP_FUNCTIONS
     68 #include "objcp-decl.h"
     69 #endif  /* OBJCPLUS */
     70 
     71 /* This is the default way of generating a method name.  */
     72 /* This has the problem that "test_method:argument:" and
     73    "test:method_argument:" will generate the same name
     74    ("_i_Test__test_method_argument_" for an instance method of the
     75    class "Test"), so you can't have them both in the same class!
     76    Moreover, the demangling (going from
     77    "_i_Test__test_method_argument" back to the original name) is
     78    undefined because there are two correct ways of demangling the
     79    name.  */
     80 #ifndef OBJC_GEN_METHOD_LABEL
     81 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
     82   do {					    \
     83     char *temp;				    \
     84     sprintf ((BUF), "_%s_%s_%s_%s",	    \
     85 	     ((IS_INST) ? "i" : "c"),	    \
     86 	     (CLASS_NAME),		    \
     87 	     ((CAT_NAME)? (CAT_NAME) : ""), \
     88 	     (SEL_NAME));		    \
     89     for (temp = (BUF); *temp; temp++)	    \
     90       if (*temp == ':') *temp = '_';	    \
     91   } while (0)
     92 #endif
     93 
     94 /* These need specifying.  */
     95 #ifndef OBJC_FORWARDING_STACK_OFFSET
     96 #define OBJC_FORWARDING_STACK_OFFSET 0
     97 #endif
     98 
     99 #ifndef OBJC_FORWARDING_MIN_OFFSET
    100 #define OBJC_FORWARDING_MIN_OFFSET 0
    101 #endif
    102 
    103 /*** Private Interface (procedures) ***/
    104 
    105 /* Init stuff.  */
    106 static void synth_module_prologue (void);
    107 
    108 /* Code generation.  */
    109 
    110 static tree start_class (enum tree_code, tree, tree, tree, tree);
    111 static tree continue_class (tree);
    112 static void finish_class (tree);
    113 static void start_method_def (tree, tree);
    114 
    115 static tree start_protocol (enum tree_code, tree, tree, tree);
    116 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
    117 static tree objc_add_method (tree, tree, int, bool);
    118 static tree add_instance_variable (tree, objc_ivar_visibility_kind, tree);
    119 static tree build_ivar_reference (tree);
    120 static tree is_ivar (tree, tree);
    121 
    122 /* We only need the following for ObjC; ObjC++ will use C++'s definition
    123    of DERIVED_FROM_P.  */
    124 #ifndef OBJCPLUS
    125 static bool objc_derived_from_p (tree, tree);
    126 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
    127 #endif
    128 
    129 /* Property.  */
    130 static void objc_gen_property_data (tree, tree);
    131 static void objc_synthesize_getter (tree, tree, tree);
    132 static void objc_synthesize_setter (tree, tree, tree);
    133 static tree lookup_property (tree, tree);
    134 static tree lookup_property_in_list (tree, tree);
    135 static tree lookup_property_in_protocol_list (tree, tree);
    136 static void build_common_objc_property_accessor_helpers (void);
    137 
    138 static void objc_xref_basetypes (tree, tree);
    139 
    140 static tree get_class_ivars (tree, bool);
    141 
    142 static void build_fast_enumeration_state_template (void);
    143 
    144 #ifdef OBJCPLUS
    145 static void objc_generate_cxx_cdtors (void);
    146 #endif
    147 
    148 /* objc attribute */
    149 static void objc_decl_method_attributes (tree*, tree, int);
    150 static tree build_keyword_selector (tree);
    151 
    152 static void hash_init (void);
    153 
    154 /* Hash tables to manage the global pool of method prototypes.  Each
    155    of these maps map a method name (selector) identifier to either a
    156    single tree (for methods with a single method prototype) or a
    157    TREE_VEC (for methods with multiple method prototypes).  */
    158 static GTY(()) objc_map_t instance_method_map = 0;
    159 static GTY(()) objc_map_t class_method_map = 0;
    160 
    161 /* Hash tables to manage the global pool of class names.  */
    162 
    163 static GTY(()) objc_map_t class_name_map = 0;
    164 static GTY(()) objc_map_t alias_name_map = 0;
    165 
    166 static tree lookup_method (tree, tree);
    167 static tree lookup_method_static (tree, tree, int);
    168 
    169 static void interface_hash_init (void);
    170 static tree add_interface (tree, tree);
    171 static void add_category (tree, tree);
    172 static inline tree lookup_category (tree, tree);
    173 
    174 /* Protocols.  */
    175 
    176 static tree lookup_protocol (tree, bool, bool);
    177 static tree lookup_and_install_protocols (tree, bool);
    178 
    179 #ifdef OBJCPLUS
    180 static void really_start_method (tree, tree);
    181 #else
    182 static void really_start_method (tree, struct c_arg_info *);
    183 #endif
    184 static int comp_proto_with_proto (tree, tree, int);
    185 static tree objc_decay_parm_type (tree);
    186 
    187 /* Utilities for debugging and error diagnostics.  */
    188 
    189 static char *gen_type_name (tree);
    190 static char *gen_type_name_0 (tree);
    191 static char *gen_method_decl (tree);
    192 static char *gen_declaration (tree);
    193 
    194 /* Everything else.  */
    195 
    196 static void generate_struct_by_value_array (void) ATTRIBUTE_NORETURN;
    197 
    198 static void mark_referenced_methods (void);
    199 static bool objc_type_valid_for_messaging (tree type, bool allow_classes);
    200 static tree check_duplicates (tree, int, int);
    201 
    202 /*** Private Interface (data) ***/
    203 /* Flags for lookup_method_static().  */
    204 
    205 /* Look for class methods.  */
    206 #define OBJC_LOOKUP_CLASS	1
    207 /* Do not examine superclasses.  */
    208 #define OBJC_LOOKUP_NO_SUPER	2
    209 /* Disable returning an instance method of a root class when a class
    210    method can't be found.  */
    211 #define OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS 4
    212 
    213 /* The OCTI_... enumeration itself is in objc/objc-act.h.  */
    214 tree objc_global_trees[OCTI_MAX];
    215 
    216 struct imp_entry *imp_list = 0;
    217 int imp_count = 0;	/* `@implementation' */
    218 int cat_count = 0;	/* `@category' */
    219 
    220 objc_ivar_visibility_kind objc_ivar_visibility, objc_default_ivar_visibility;
    221 
    222 /* Use to generate method labels.  */
    223 static int method_slot = 0;
    224 
    225 /* Flag to say whether methods in a protocol are optional or
    226    required.  */
    227 static bool objc_method_optional_flag = false;
    228 
    229 static int objc_collecting_ivars = 0;
    230 
    231 /* Flag that is set to 'true' while we are processing a class
    232    extension.  Since a class extension just "reopens" the main
    233    @interface, this can be used to determine if we are in the main
    234    @interface, or in a class extension.  */
    235 static bool objc_in_class_extension = false;
    236 
    237 static char *errbuf;	/* Buffer for error diagnostics */
    238 
    239 /* An array of all the local variables in the current function that
    240    need to be marked as volatile.  */
    241 vec<tree, va_gc> *local_variables_to_volatilize = NULL;
    242 
    243 /* Store all constructed constant strings in a hash table so that
    244    they get uniqued properly.  */
    245 
    246 struct GTY((for_user)) string_descriptor {
    247   /* The literal argument .  */
    248   tree literal;
    249 
    250   /* The resulting constant string.  */
    251   tree constructor;
    252 };
    253 
    254 struct objc_string_hasher : ggc_ptr_hash<string_descriptor>
    255 {
    256   static hashval_t hash (string_descriptor *);
    257   static bool equal (string_descriptor *, string_descriptor *);
    258 };
    259 
    260 static GTY(()) hash_table<objc_string_hasher> *string_htab;
    261 
    262 FILE *gen_declaration_file;
    263 
    264 /* Hooks for stuff that differs between runtimes.  */
    265 objc_runtime_hooks runtime;
    266 
    267 /* Create a temporary variable of type 'type'.  If 'name' is set, uses
    268    the specified name, else use no name.  Returns the declaration of
    269    the type.  The 'name' is mostly useful for debugging.
    270 */
    271 tree
    272 objc_create_temporary_var (tree type, const char *name)
    273 {
    274   tree decl;
    275 
    276   if (name != NULL)
    277     {
    278       decl = build_decl (input_location,
    279 			 VAR_DECL, get_identifier (name), type);
    280     }
    281   else
    282     {
    283       decl = build_decl (input_location,
    284 			 VAR_DECL, NULL_TREE, type);
    285     }
    286   TREE_USED (decl) = 1;
    287   DECL_ARTIFICIAL (decl) = 1;
    288   DECL_IGNORED_P (decl) = 1;
    289   DECL_CONTEXT (decl) = current_function_decl;
    290 
    291   return decl;
    292 }
    293 
    294 /* Some platforms pass small structures through registers versus
    295    through an invisible pointer.  Determine at what size structure is
    296    the transition point between the two possibilities.  */
    297 
    298 static void
    299 generate_struct_by_value_array (void)
    300 {
    301   tree type;
    302   tree decls;
    303   int i, j;
    304   int aggregate_in_mem[32];
    305   int found = 0;
    306 
    307   /* Presumably no platform passes 32 byte structures in a register.  */
    308   /* ??? As an example, m64/ppc/Darwin can pass up to 8*long+13*double
    309      in registers.  */
    310   for (i = 1; i < 32; i++)
    311     {
    312       char buffer[5];
    313       tree *chain = NULL;
    314 
    315       /* Create an unnamed struct that has `i' character components */
    316       type = objc_start_struct (NULL_TREE);
    317 
    318       strcpy (buffer, "c1");
    319       decls = add_field_decl (char_type_node, buffer, &chain);
    320 
    321       for (j = 1; j < i; j++)
    322 	{
    323 	  sprintf (buffer, "c%d", j + 1);
    324 	  add_field_decl (char_type_node, buffer, &chain);
    325 	}
    326       objc_finish_struct (type, decls);
    327 
    328       aggregate_in_mem[i] = aggregate_value_p (type, 0);
    329       if (!aggregate_in_mem[i])
    330 	found = 1;
    331     }
    332 
    333   /* We found some structures that are returned in registers instead of memory
    334      so output the necessary data.  */
    335   if (found)
    336     {
    337       for (i = 31; i >= 0;  i--)
    338 	if (!aggregate_in_mem[i])
    339 	  break;
    340       printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n", i);
    341     }
    342 
    343   exit (0);
    344 }
    345 
    346 bool
    347 objc_init (void)
    348 {
    349   bool ok;
    350 
    351   /* Set up stuff used by the preprocessor as well as FE parser.  */
    352   interface_hash_init ();
    353   hash_init ();
    354 
    355 #ifdef OBJCPLUS
    356   if (cxx_init () == false)
    357 #else
    358   if (c_objc_common_init () == false)
    359 #endif
    360     return false;
    361 
    362   /* print_struct_values is triggered by -print-runtime-info (used
    363      when building libobjc, with an empty file as input).  It does not
    364      require any ObjC setup, and it never returns.
    365 
    366      -fcompare-debug is used to check the compiler output; we are
    367      executed twice, once with flag_compare_debug set, and once with
    368      it not set.  If the flag is used together with
    369      -print-runtime-info, we want to print the runtime info only once,
    370      else it would be output in duplicate.  So we check
    371      flag_compare_debug to output it in only one of the invocations.
    372 
    373      As a side effect, this also that means -fcompare-debug
    374      -print-runtime-info will run the compiler twice, and compare the
    375      generated assembler file; the first time the compiler exits
    376      immediately (producing no file), and the second time it compiles
    377      an empty file.  This checks, as a side effect, that compiling an
    378      empty file produces no assembler output.  */
    379   if (print_struct_values && !flag_compare_debug)
    380     generate_struct_by_value_array ();
    381 
    382   /* Set up stuff used by FE parser and all runtimes.  */
    383   errbuf = XNEWVEC (char, 1024 * 10);
    384   objc_encoding_init ();
    385   /* ... and then check flags and set-up for the selected runtime ... */
    386   if (flag_next_runtime && flag_objc_abi >= 2)
    387     ok = objc_next_runtime_abi_02_init (&runtime);
    388   else if (flag_next_runtime)
    389     ok = objc_next_runtime_abi_01_init (&runtime);
    390   else
    391     ok = objc_gnu_runtime_abi_01_init (&runtime);
    392 
    393   /* If that part of the setup failed - bail out immediately.  */
    394   if (!ok)
    395     return false;
    396 
    397   /* Determine the default visibility for instance variables. */
    398   switch (default_ivar_visibility)
    399     {
    400     case IVAR_VISIBILITY_PRIVATE:
    401         objc_default_ivar_visibility = OBJC_IVAR_VIS_PRIVATE;
    402         break;
    403     case IVAR_VISIBILITY_PUBLIC:
    404         objc_default_ivar_visibility = OBJC_IVAR_VIS_PUBLIC;
    405         break;
    406     case IVAR_VISIBILITY_PACKAGE:
    407         objc_default_ivar_visibility = OBJC_IVAR_VIS_PACKAGE;
    408         break;
    409     default:
    410         objc_default_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
    411     }
    412 
    413   /* Generate general types and push runtime-specific decls to file scope.  */
    414   synth_module_prologue ();
    415 
    416   return true;
    417 }
    418 
    419 /* This is called at the end of parsing by the C/C++ parsers.  */
    420 void
    421 objc_write_global_declarations (void)
    422 {
    423   mark_referenced_methods ();
    424 
    425   /* A missing @end might not be detected by the parser.  */
    426   if (objc_implementation_context)
    427     {
    428       warning (0, "%<@end%> missing in implementation context");
    429       finish_class (objc_implementation_context);
    430       objc_ivar_chain = NULL_TREE;
    431       objc_implementation_context = NULL_TREE;
    432     }
    433 
    434   if (warn_selector)
    435     {
    436       objc_map_iterator_t i;
    437 
    438       objc_map_iterator_initialize (class_method_map, &i);
    439       while (objc_map_iterator_move_to_next (class_method_map, &i))
    440 	check_duplicates (objc_map_iterator_current_value (class_method_map, i), 0, 1);
    441 
    442       objc_map_iterator_initialize (instance_method_map, &i);
    443       while (objc_map_iterator_move_to_next (instance_method_map, &i))
    444 	check_duplicates (objc_map_iterator_current_value (instance_method_map, i), 0, 0);
    445     }
    446 
    447   /* TODO: consider an early exit here if either errorcount or sorrycount
    448      is non-zero.  Not only is it wasting time to generate the metadata,
    449      it needlessly imposes need to re-check for things that are already
    450      determined to be errors.  */
    451 
    452   /* Finalize Objective-C runtime data.  No need to generate tables
    453      and code if only checking syntax, or if generating a PCH file.  */
    454   if (!flag_syntax_only && !pch_file)
    455     {
    456       location_t saved_location;
    457 
    458       /* If gen_declaration desired, open the output file.  */
    459       if (flag_gen_declaration)
    460 	{
    461 	  char * const dumpname = concat (dump_base_name, ".decl", NULL);
    462 	  gen_declaration_file = fopen (dumpname, "w");
    463 	  if (gen_declaration_file == 0)
    464 	    fatal_error (input_location, "cannot open %s: %m", dumpname);
    465 	  free (dumpname);
    466 	}
    467 
    468       /* Set the input location to BUILTINS_LOCATION.  This is good
    469 	 for error messages, in case any is generated while producing
    470 	 the metadata, but it also silences warnings that would be
    471 	 produced when compiling with -Wpadded in case when padding is
    472 	 automatically added to the built-in runtime data structure
    473 	 declarations.  We know about this padding, and it is fine; we
    474 	 don't want users to see any warnings about it if they use
    475 	 -Wpadded.  */
    476       saved_location = input_location;
    477       input_location = BUILTINS_LOCATION;
    478 
    479       /* Compute and emit the meta-data tables for this runtime.  */
    480       (*runtime.generate_metadata) ();
    481 
    482       /* Restore the original location, just in case it mattered.  */
    483       input_location = saved_location;
    484 
    485       /* ... and then close any declaration file we opened.  */
    486       if (gen_declaration_file)
    487 	fclose (gen_declaration_file);
    488     }
    489 }
    490 
    491 /* Return the first occurrence of a method declaration corresponding
    492    to sel_name in rproto_list.  Search rproto_list recursively.
    493    If is_class is 0, search for instance methods, otherwise for class
    494    methods.  */
    495 static tree
    496 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
    497 				int is_class)
    498 {
    499   tree rproto, p, m;
    500 
    501    for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
    502      {
    503        p = TREE_VALUE (rproto);
    504        m = NULL_TREE;
    505 
    506 	if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
    507 	  {
    508 	    /* First, search the @required protocol methods.  */
    509 	    if (is_class)
    510 	      m = lookup_method (PROTOCOL_CLS_METHODS (p),  sel_name);
    511 	    else
    512 	      m = lookup_method (PROTOCOL_NST_METHODS (p), sel_name);
    513 
    514 	    if (m)
    515 	      return m;
    516 
    517 	    /* If still not found, search the @optional protocol methods.  */
    518 	    if (is_class)
    519 	      m = lookup_method (PROTOCOL_OPTIONAL_CLS_METHODS (p), sel_name);
    520 	    else
    521 	      m = lookup_method (PROTOCOL_OPTIONAL_NST_METHODS (p), sel_name);
    522 
    523 	    if (m)
    524 	      return m;
    525 
    526 	    /* If still not found, search the attached protocols.  */
    527 	    if (PROTOCOL_LIST (p))
    528 	      m = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
    529 						  sel_name, is_class);
    530 	    if (m)
    531 	      return m;
    532 	  }
    533 	else
    534           {
    535 	    ; /* An identifier...if we could not find a protocol.  */
    536           }
    537      }
    538 
    539    return 0;
    540 }
    541 
    542 static tree
    543 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
    544 {
    545   tree rproto, p;
    546 
    547   /* Make sure the protocol is supported by the object on the rhs.  */
    548   if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
    549     {
    550       tree fnd = 0;
    551       for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
    552 	{
    553 	  p = TREE_VALUE (rproto);
    554 
    555 	  if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
    556 	    {
    557 	      if (lproto == p)
    558 		fnd = lproto;
    559 
    560 	      else if (PROTOCOL_LIST (p))
    561 		fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
    562 	    }
    563 
    564 	  if (fnd)
    565 	    return fnd;
    566 	}
    567     }
    568   else
    569     {
    570       ; /* An identifier...if we could not find a protocol.  */
    571     }
    572 
    573   return 0;
    574 }
    575 
    576 void
    577 objc_start_class_interface (tree klass, location_t name_loc, tree super_class,
    578 			    tree protos, tree attributes)
    579 {
    580   if (flag_objc1_only && attributes)
    581     error_at (name_loc, "class attributes are not available in Objective-C 1.0");
    582 
    583   objc_interface_context
    584     = objc_ivar_context
    585     = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos, attributes);
    586   objc_ivar_visibility = objc_default_ivar_visibility;
    587 }
    588 
    589 void
    590 objc_start_category_interface (tree klass, tree categ,
    591 			       tree protos, tree attributes)
    592 {
    593   if (attributes)
    594     {
    595       if (flag_objc1_only)
    596 	error_at (input_location, "category attributes are not available in Objective-C 1.0");
    597       else
    598 	warning_at (input_location, OPT_Wattributes,
    599 		    "category attributes are not available in this version"
    600 		    " of the compiler, (ignored)");
    601     }
    602   if (categ == NULL_TREE)
    603     {
    604       if (flag_objc1_only)
    605 	error_at (input_location, "class extensions are not available in Objective-C 1.0");
    606       else
    607 	{
    608 	  /* Iterate over all the classes and categories implemented
    609 	     up to now in this compilation unit.  */
    610 	  struct imp_entry *t;
    611 
    612 	  for (t = imp_list; t; t = t->next)
    613 	    {
    614 	      /* If we find a class @implementation with the same name
    615 		 as the one we are extending, produce an error.  */
    616 	    if (TREE_CODE (t->imp_context) == CLASS_IMPLEMENTATION_TYPE
    617 		&& IDENTIFIER_POINTER (CLASS_NAME (t->imp_context)) == IDENTIFIER_POINTER (klass))
    618 	      error_at (input_location,
    619 			"class extension for class %qE declared after its %<@implementation%>",
    620 			klass);
    621 	    }
    622 	}
    623     }
    624   objc_interface_context
    625     = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos, NULL_TREE);
    626   objc_ivar_chain
    627     = continue_class (objc_interface_context);
    628 }
    629 
    630 void
    631 objc_start_protocol (tree name, tree protos, tree attributes)
    632 {
    633   if (flag_objc1_only && attributes)
    634     error_at (input_location, "protocol attributes are not available in Objective-C 1.0");
    635 
    636   objc_interface_context
    637     = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos, attributes);
    638   objc_method_optional_flag = false;
    639 }
    640 
    641 void
    642 objc_continue_interface (void)
    643 {
    644   objc_ivar_chain
    645     = continue_class (objc_interface_context);
    646 }
    647 
    648 void
    649 objc_finish_interface (void)
    650 {
    651   finish_class (objc_interface_context);
    652   objc_interface_context = NULL_TREE;
    653   objc_method_optional_flag = false;
    654   objc_in_class_extension = false;
    655 }
    656 
    657 void
    658 objc_start_class_implementation (tree klass, tree super_class)
    659 {
    660   objc_implementation_context
    661     = objc_ivar_context
    662     = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE,
    663 		   NULL_TREE);
    664   objc_ivar_visibility = objc_default_ivar_visibility;
    665 }
    666 
    667 void
    668 objc_start_category_implementation (tree klass, tree categ)
    669 {
    670   objc_implementation_context
    671     = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE,
    672 		   NULL_TREE);
    673   objc_ivar_chain
    674     = continue_class (objc_implementation_context);
    675 }
    676 
    677 void
    678 objc_continue_implementation (void)
    679 {
    680   objc_ivar_chain
    681     = continue_class (objc_implementation_context);
    682 }
    683 
    684 void
    685 objc_finish_implementation (void)
    686 {
    687 #ifdef OBJCPLUS
    688   if (flag_objc_call_cxx_cdtors)
    689     objc_generate_cxx_cdtors ();
    690 #endif
    691 
    692   if (objc_implementation_context)
    693     {
    694       finish_class (objc_implementation_context);
    695       objc_ivar_chain = NULL_TREE;
    696       objc_implementation_context = NULL_TREE;
    697     }
    698   else
    699     warning (0, "%<@end%> must appear in an @implementation context");
    700 }
    701 
    702 void
    703 objc_set_visibility (objc_ivar_visibility_kind visibility)
    704 {
    705   if (visibility == OBJC_IVAR_VIS_PACKAGE)
    706     {
    707       if (flag_objc1_only)
    708 	error ("%<@package%> is not available in Objective-C 1.0");
    709       else
    710 	warning (0, "%<@package%> presently has the same effect as %<@public%>");
    711     }
    712   objc_ivar_visibility = visibility;
    713 }
    714 
    715 void
    716 objc_set_method_opt (bool optional)
    717 {
    718   if (flag_objc1_only)
    719     {
    720       if (optional)
    721 	error_at (input_location, "%<@optional%> is not available in Objective-C 1.0");
    722       else
    723 	error_at (input_location, "%<@required%> is not available in Objective-C 1.0");
    724     }
    725 
    726   objc_method_optional_flag = optional;
    727   if (!objc_interface_context
    728       || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
    729     {
    730       if (optional)
    731 	error ("%<@optional%> is allowed in @protocol context only");
    732       else
    733 	error ("%<@required%> is allowed in @protocol context only");
    734       objc_method_optional_flag = false;
    735     }
    736 }
    737 
    738 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
    739    PROTOCOL.  */
    740 static tree
    741 lookup_property_in_list (tree chain, tree property)
    742 {
    743   tree x;
    744   for (x = CLASS_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
    745     if (PROPERTY_NAME (x) == property)
    746       return x;
    747   return NULL_TREE;
    748 }
    749 
    750 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
    751 static tree lookup_property_in_protocol_list (tree rproto_list, tree property)
    752 {
    753   tree rproto, x;
    754   for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
    755     {
    756       tree p = TREE_VALUE (rproto);
    757       if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
    758 	{
    759 	  if ((x = lookup_property_in_list (p, property)))
    760 	    return x;
    761 	  if (PROTOCOL_LIST (p))
    762 	    return lookup_property_in_protocol_list (PROTOCOL_LIST (p), property);
    763 	}
    764       else
    765 	{
    766 	  ; /* An identifier...if we could not find a protocol.  */
    767 	}
    768     }
    769   return NULL_TREE;
    770 }
    771 
    772 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
    773    chain of interface hierarchy.  */
    774 static tree
    775 lookup_property (tree interface_type, tree property)
    776 {
    777   tree inter = interface_type;
    778   while (inter)
    779     {
    780       tree x, category;
    781       if ((x = lookup_property_in_list (inter, property)))
    782 	return x;
    783       /* Failing that, look for the property in each category of the class.  */
    784       category = inter;
    785       while ((category = CLASS_CATEGORY_LIST (category)))
    786 	{
    787 	  if ((x = lookup_property_in_list (category, property)))
    788 	    return x;
    789 
    790 	  /* When checking a category, also check the protocols
    791 	     attached with the category itself.  */
    792 	  if (CLASS_PROTOCOL_LIST (category)
    793 	      && (x = lookup_property_in_protocol_list
    794 		  (CLASS_PROTOCOL_LIST (category), property)))
    795 	    return x;
    796 	}
    797 
    798       /*  Failing to find in categories, look for property in protocol list. */
    799       if (CLASS_PROTOCOL_LIST (inter)
    800 	  && (x = lookup_property_in_protocol_list
    801 	      (CLASS_PROTOCOL_LIST (inter), property)))
    802 	return x;
    803 
    804       /* Failing that, climb up the inheritance hierarchy.  */
    805       inter = lookup_interface (CLASS_SUPER_NAME (inter));
    806     }
    807   return inter;
    808 }
    809 
    810 /* This routine returns a PROPERTY_KIND for the front end RID code supplied.  */
    811 
    812 enum objc_property_attribute_kind
    813 objc_prop_attr_kind_for_rid (enum rid prop_rid)
    814 {
    815   switch (prop_rid)
    816     {
    817       default:			return OBJC_PROPERTY_ATTR_UNKNOWN;
    818       case RID_GETTER:		return OBJC_PROPERTY_ATTR_GETTER;
    819       case RID_SETTER:		return OBJC_PROPERTY_ATTR_SETTER;
    820 
    821       case RID_READONLY:	return OBJC_PROPERTY_ATTR_READONLY;
    822       case RID_READWRITE:	return OBJC_PROPERTY_ATTR_READWRITE;
    823 
    824       case RID_ASSIGN:		return OBJC_PROPERTY_ATTR_ASSIGN;
    825       case RID_RETAIN:		return OBJC_PROPERTY_ATTR_RETAIN;
    826       case RID_COPY:		return OBJC_PROPERTY_ATTR_COPY;
    827 
    828       case RID_PROPATOMIC:	return OBJC_PROPERTY_ATTR_ATOMIC;
    829       case RID_NONATOMIC:	return OBJC_PROPERTY_ATTR_NONATOMIC;
    830 
    831       case RID_NULL_UNSPECIFIED:return OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED;
    832       case RID_NULLABLE:	return OBJC_PROPERTY_ATTR_NULLABLE;
    833       case RID_NONNULL:		return OBJC_PROPERTY_ATTR_NONNULL;
    834       case RID_NULL_RESETTABLE:	return OBJC_PROPERTY_ATTR_NULL_RESETTABLE;
    835 
    836       case RID_CLASS:		return OBJC_PROPERTY_ATTR_CLASS;
    837     }
    838 }
    839 
    840 /* This routine is called by the parser when a
    841    @property... declaration is found.  'decl' is the declaration of
    842    the property (type/identifier), and the other arguments represent
    843    property attributes that may have been specified in the Objective-C
    844    declaration.  'parsed_property_readonly' is 'true' if the attribute
    845    'readonly' was specified, and 'false' if not; similarly for the
    846    other bool parameters.  'property_getter_ident' is NULL_TREE
    847    if the attribute 'getter' was not specified, and is the identifier
    848    corresponding to the specified getter if it was; similarly for
    849    'property_setter_ident'.  */
    850 void
    851 objc_add_property_declaration (location_t location, tree decl,
    852 			       vec<property_attribute_info *>& prop_attr_list)
    853 {
    854   if (flag_objc1_only)
    855     /* FIXME: we probably ought to bail out at this point.  */
    856     error_at (location, "%<@property%> is not available in Objective-C 1.0");
    857 
    858   /* We must be in an interface, category, or protocol.  */
    859   if (!objc_interface_context)
    860     {
    861       error_at (location, "property declaration not in %<@interface%>,"
    862 			  " %<@protocol%> or %<category%> context");
    863       return;
    864     }
    865 
    866   /* Do some spot-checks for the most obvious invalid cases.  */
    867 
    868   gcc_checking_assert (decl && TREE_CODE (decl) == FIELD_DECL);
    869 
    870   if (decl && !DECL_NAME (decl))
    871     {
    872       error_at (location, "properties must be named");
    873       return;
    874     }
    875 
    876   location_t decl_loc = DECL_SOURCE_LOCATION (decl);
    877   decl_loc = make_location (decl_loc, location, decl_loc);
    878   if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    879     {
    880       error_at (decl_loc, "property cannot be an array");
    881       return;
    882     }
    883 
    884   if (DECL_C_BIT_FIELD (decl))
    885     {
    886       /* A @property is not an actual variable, but it is a way to
    887 	 describe a pair of accessor methods, so its type (which is
    888 	 the type of the return value of the getter and the first
    889 	 argument of the setter) can't be a bitfield (as return values
    890 	 and arguments of functions cannot be bitfields).  The
    891 	 underlying instance variable could be a bitfield, but that is
    892 	 a different matter.  */
    893       error_at (decl_loc, "property cannot be a bit-field");
    894       return;
    895     }
    896 
    897   /* The final results of parsing the (growing number) of property
    898      attributes.  */
    899   property_attribute_info *attrs[OBJC_PROPATTR_GROUP_MAX] = { nullptr };
    900 
    901   tree property_getter_ident = NULL_TREE;
    902   tree property_setter_ident = NULL_TREE;
    903   for (unsigned pn = 0; pn < prop_attr_list.length (); ++pn)
    904     {
    905       if (prop_attr_list[pn]->parse_error)
    906 	continue; /* Ignore attributes known to be wrongly parsed.  */
    907 
    908       switch (int g = (int) prop_attr_list[pn]->group())
    909 	{
    910 	case OBJC_PROPATTR_GROUP_UNKNOWN:
    911 	  continue;
    912 	case OBJC_PROPATTR_GROUP_SETTER:
    913 	case OBJC_PROPATTR_GROUP_GETTER:
    914 	  if (attrs[g])
    915 	    {
    916 	      warning_at (prop_attr_list[pn]->prop_loc, OPT_Wattributes,
    917 			  "multiple property %qE methods specified, the latest"
    918 			  " one will be used", attrs[g]->name);
    919 	      inform (attrs[g]->prop_loc, "previous specification");
    920 	    }
    921 	  attrs[g] = prop_attr_list[pn];
    922 	  if (g == OBJC_PROPATTR_GROUP_SETTER)
    923 	    property_setter_ident = attrs[g]->ident;
    924 	  else
    925 	    property_getter_ident = attrs[g]->ident;
    926 	  continue;
    927 	default:
    928 	  {
    929 	    if (!attrs[g])
    930 	      ;
    931 	    else if (attrs[g]->prop_kind != prop_attr_list[pn]->prop_kind)
    932 	      {
    933 		error_at (prop_attr_list[pn]->prop_loc,
    934 			  "%qE attribute conflicts with %qE attribute",
    935 			  prop_attr_list[pn]->name, attrs[g]->name);
    936 		inform (attrs[g]->prop_loc, "%qE specified here",
    937 			attrs[g]->name );
    938 	      }
    939 	    else
    940 	      {
    941 		warning_at (prop_attr_list[pn]->prop_loc, OPT_Wattributes,
    942 			    "duplicate %qE attribute", attrs[g]->name);
    943 		inform (attrs[g]->prop_loc, "first specified here");
    944 	      }
    945 	    attrs[g] = prop_attr_list[pn];
    946 	  }
    947 	  continue;
    948 	}
    949     }
    950 
    951   /* The defaults for atomicity (atomic) and write-ability (readwrite) apply
    952      even if the user provides no specified attributes.  */
    953   bool property_nonatomic = false;
    954   bool property_readonly = false;
    955 
    956   /* Set the values from any specified by the user; these are easy, only two
    957      states.  */
    958   if (attrs[OBJC_PROPATTR_GROUP_ATOMIC])
    959     property_nonatomic = attrs[OBJC_PROPATTR_GROUP_ATOMIC]->prop_kind
    960 			 == OBJC_PROPERTY_ATTR_NONATOMIC;
    961 
    962   if (attrs[OBJC_PROPATTR_GROUP_READWRITE])
    963     property_readonly = attrs[OBJC_PROPATTR_GROUP_READWRITE]->prop_kind
    964 			 == OBJC_PROPERTY_ATTR_READONLY;
    965 
    966   /* One can't set a readonly value; we issue an error, but force the property
    967      to readwrite as well.  */
    968   if (property_readonly && property_setter_ident)
    969     {
    970       error_at (attrs[OBJC_PROPATTR_GROUP_READWRITE]->prop_loc, "%<readonly%>"
    971 		" attribute conflicts with %<setter%> attribute");
    972       gcc_checking_assert (attrs[OBJC_PROPATTR_GROUP_SETTER]);
    973       inform (attrs[OBJC_PROPATTR_GROUP_SETTER]->prop_loc, "%<setter%>"
    974 	      " specified here");
    975       property_readonly = false;
    976     }
    977 
    978   /* Assign semantics is a tri-state property, and also needs some further
    979      checking against the object type.  */
    980   objc_property_assign_semantics property_assign_semantics
    981     = OBJC_PROPERTY_ASSIGN;
    982 
    983   if (attrs[OBJC_PROPATTR_GROUP_ASSIGN])
    984     {
    985       if (attrs[OBJC_PROPATTR_GROUP_ASSIGN]->prop_kind
    986 	  == OBJC_PROPERTY_ATTR_ASSIGN)
    987 	property_assign_semantics = OBJC_PROPERTY_ASSIGN;
    988       else if (attrs[OBJC_PROPATTR_GROUP_ASSIGN]->prop_kind
    989 	       == OBJC_PROPERTY_ATTR_RETAIN)
    990 	property_assign_semantics = OBJC_PROPERTY_RETAIN;
    991       else if (attrs[OBJC_PROPATTR_GROUP_ASSIGN]->prop_kind
    992 	       == OBJC_PROPERTY_ATTR_COPY)
    993 	property_assign_semantics = OBJC_PROPERTY_COPY;
    994       else
    995 	gcc_unreachable ();
    996     }
    997 
    998   /* An attribute that indicates this property manipulates a class variable.
    999      In this case, both the variable and the getter/setter must be provided
   1000      by the user.  */
   1001   bool property_class = false;
   1002   if (attrs[OBJC_PROPATTR_GROUP_CLASS])
   1003     property_nonatomic = attrs[OBJC_PROPATTR_GROUP_CLASS]->prop_kind
   1004 			 == OBJC_PROPERTY_ATTR_CLASS;
   1005 
   1006   /* Nullability specifications for the property.  */
   1007   enum objc_property_nullability property_nullability
   1008     =  OBJC_PROPERTY_NULL_UNSET;
   1009   if (attrs[OBJC_PROPATTR_GROUP_NULLABLE])
   1010     {
   1011       if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
   1012 	  == OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED)
   1013 	property_nullability = OBJC_PROPERTY_NULL_UNSPECIFIED;
   1014       else if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
   1015 	  == OBJC_PROPERTY_ATTR_NULLABLE)
   1016 	property_nullability = OBJC_PROPERTY_NULLABLE;
   1017       else if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
   1018 	  == OBJC_PROPERTY_ATTR_NONNULL)
   1019 	property_nullability = OBJC_PROPERTY_NONNULL;
   1020       else if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
   1021 	  == OBJC_PROPERTY_ATTR_NULL_RESETTABLE)
   1022 	property_nullability = OBJC_PROPERTY_NULL_RESETTABLE;
   1023       else
   1024 	gcc_unreachable ();
   1025     }
   1026 
   1027   /* TODO: Check that the property type is an Objective-C object or a
   1028      "POD".  */
   1029 
   1030   /* Implement -Wproperty-assign-default (which is enabled by default).  */
   1031   if (warn_property_assign_default
   1032       /* If garbage collection is not being used, then 'assign' is
   1033 	 valid for objects (and typically used for delegates) but it
   1034 	 is wrong in most cases (since most objects need to be
   1035 	 retained or copied in setters).  Warn users when 'assign' is
   1036 	 used implicitly.  */
   1037       && property_assign_semantics == OBJC_PROPERTY_ASSIGN
   1038       /* Read-only properties are never assigned, so the assignment
   1039 	 semantics do not matter in that case.  */
   1040       && !property_readonly
   1041       && !flag_objc_gc)
   1042     {
   1043       /* Please note that it would make sense to default to 'assign'
   1044 	 for non-{Objective-C objects}, and to 'retain' for
   1045 	 Objective-C objects.  But that would break compatibility with
   1046 	 other compilers.  */
   1047       if (!attrs[OBJC_PROPATTR_GROUP_ASSIGN])
   1048 	{
   1049 	  /* Use 'false' so we do not warn for Class objects.  */
   1050 	  if (objc_type_valid_for_messaging (TREE_TYPE (decl), false))
   1051 	    {
   1052 	      warning_at (decl_loc, 0, "object property %qD has no %<assign%>,"
   1053 			  " %<retain%> or %<copy%> attribute; assuming"
   1054 			  " %<assign%>", decl);
   1055 	      inform (decl_loc, "%<assign%> can be unsafe for Objective-C"
   1056 		      " objects; please state explicitly if you need it");
   1057 	    }
   1058 	}
   1059     }
   1060 
   1061   /* Some attributes make no sense unless applied to an Objective-C object.  */
   1062   bool prop_objc_object_p
   1063     = objc_type_valid_for_messaging (TREE_TYPE (decl), true);
   1064   if (!prop_objc_object_p)
   1065     {
   1066       tree p_name = NULL_TREE;
   1067       if (property_assign_semantics == OBJC_PROPERTY_RETAIN
   1068 	  || property_assign_semantics == OBJC_PROPERTY_COPY)
   1069 	p_name = attrs[OBJC_PROPATTR_GROUP_ASSIGN]->name;
   1070 
   1071       if (p_name)
   1072 	error_at (decl_loc, "%qE attribute is only valid for Objective-C"
   1073 		  " objects", p_name);
   1074     }
   1075 
   1076   /* Now determine the final property getter and setter names.  They
   1077      will be stored in the PROPERTY_DECL, from which they'll always be
   1078      extracted and used.  */
   1079 
   1080   /* Adjust, or fill in, setter and getter names.  We overwrite the
   1081      property_setter_ident and property_getter_ident
   1082      with the final setter and getter identifiers that will be
   1083      used.  */
   1084   if (property_setter_ident)
   1085     {
   1086       /* The setter should be terminated by ':', but the parser only
   1087 	 gives us an identifier without ':'.  So, we need to add ':'
   1088 	 at the end.  */
   1089       const char *parsed_setter = IDENTIFIER_POINTER (property_setter_ident);
   1090       size_t length = strlen (parsed_setter);
   1091       char *final_setter = (char *)alloca (length + 2);
   1092 
   1093       sprintf (final_setter, "%s:", parsed_setter);
   1094       property_setter_ident = get_identifier (final_setter);
   1095     }
   1096   else
   1097     {
   1098       if (!property_readonly)
   1099 	property_setter_ident = get_identifier (objc_build_property_setter_name
   1100 						       (DECL_NAME (decl)));
   1101     }
   1102 
   1103   if (!property_getter_ident)
   1104     property_getter_ident = DECL_NAME (decl);
   1105 
   1106   /* Check for duplicate property declarations.  We first check the
   1107      immediate context for a property with the same name.  Any such
   1108      declarations are an error, unless this is a class extension and
   1109      we are extending a property from readonly to readwrite.  */
   1110   bool property_extension_in_class_extension = false;
   1111   tree x = NULL_TREE;
   1112   for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
   1113     {
   1114       if (PROPERTY_NAME (x) == DECL_NAME (decl))
   1115 	{
   1116 	  if (objc_in_class_extension
   1117 	      && !property_readonly
   1118 	      && PROPERTY_READONLY (x) == 1)
   1119 	    {
   1120 	      /* This is a class extension, and we are extending an
   1121 		 existing readonly property to a readwrite one.
   1122 		 That's fine.  :-) */
   1123 	      property_extension_in_class_extension = true;
   1124 	      break;
   1125 	    }
   1126 	  else
   1127 	    {
   1128 	      location_t original_location = DECL_SOURCE_LOCATION (x);
   1129 
   1130 	      error_at (location, "redeclaration of property %qD", decl);
   1131 
   1132 	      if (original_location != UNKNOWN_LOCATION)
   1133 		inform (original_location, "originally specified here");
   1134 	      return;
   1135 	    }
   1136 	}
   1137     }
   1138 
   1139   /* If x is not NULL_TREE, we must be in a class extension and we're
   1140      extending a readonly property.  In that case, no point in
   1141      searching for another declaration.  */
   1142   if (x == NULL_TREE)
   1143     {
   1144       /* We now need to check for existing property declarations (in
   1145 	 the superclass, other categories or protocols) and check that
   1146 	 the new declaration is not in conflict with existing
   1147 	 ones.  */
   1148 
   1149       /* Search for a previous, existing declaration of a property
   1150 	 with the same name in superclasses, protocols etc.  If one is
   1151 	 found, it will be in the 'x' variable.  */
   1152 
   1153       /* Note that, for simplicity, the following may search again the
   1154 	 local context.  That's Ok as nothing will be found (else we'd
   1155 	 have thrown an error above); it's only a little inefficient,
   1156 	 but the code is simpler.  */
   1157       switch (TREE_CODE (objc_interface_context))
   1158 	{
   1159 	case CLASS_INTERFACE_TYPE:
   1160 	  /* Look up the property in the current @interface (which
   1161 	     will find nothing), then its protocols and categories and
   1162 	     superclasses.  */
   1163 	  x = lookup_property (objc_interface_context, DECL_NAME (decl));
   1164 	  break;
   1165 	case CATEGORY_INTERFACE_TYPE:
   1166 	  /* Look up the property in the main @interface, then
   1167 	     protocols and categories (one of them is ours, and will
   1168 	     find nothing) and superclasses.  */
   1169 	  x = lookup_property (lookup_interface (CLASS_NAME (objc_interface_context)),
   1170 			       DECL_NAME (decl));
   1171 	  break;
   1172 	case PROTOCOL_INTERFACE_TYPE:
   1173 	  /* Looks up the property in any protocols attached to the
   1174 	     current protocol.  */
   1175 	  if (PROTOCOL_LIST (objc_interface_context))
   1176 	    {
   1177 	      x = lookup_property_in_protocol_list (PROTOCOL_LIST (objc_interface_context),
   1178 						    DECL_NAME (decl));
   1179 	    }
   1180 	  break;
   1181 	default:
   1182 	  gcc_unreachable ();
   1183 	}
   1184     }
   1185 
   1186   if (x != NULL_TREE)
   1187     {
   1188       /* An existing property was found; check that it has the same
   1189 	 types, or it is compatible.  */
   1190       location_t original_location = DECL_SOURCE_LOCATION (x);
   1191 
   1192       if (PROPERTY_NONATOMIC (x) != property_nonatomic)
   1193 	{
   1194 	  warning_at (location, 0,
   1195 		      "%<nonatomic%> attribute of property %qD conflicts with "
   1196 		      "previous declaration", decl);
   1197 
   1198 	  if (original_location != UNKNOWN_LOCATION)
   1199 	    inform (original_location, "originally specified here");
   1200 	  return;
   1201 	}
   1202 
   1203       if (PROPERTY_GETTER_NAME (x) != property_getter_ident)
   1204 	{
   1205 	  warning_at (location, 0,
   1206 		      "%<getter%> attribute of property %qD conflicts with "
   1207 		      "previous declaration", decl);
   1208 
   1209 	  if (original_location != UNKNOWN_LOCATION)
   1210 	    inform (original_location, "originally specified here");
   1211 	  return;
   1212 	}
   1213 
   1214       /* We can only compare the setter names if both the old and new property have a setter.  */
   1215       if (!property_readonly  &&  !PROPERTY_READONLY(x))
   1216 	{
   1217 	  if (PROPERTY_SETTER_NAME (x) != property_setter_ident)
   1218 	    {
   1219 	      warning_at (location, 0,
   1220 			  "%<setter%> attribute of property %qD conflicts with "
   1221 			  "previous declaration", decl);
   1222 
   1223 	      if (original_location != UNKNOWN_LOCATION)
   1224 		inform (original_location, "originally specified here");
   1225 	      return;
   1226 	    }
   1227 	}
   1228 
   1229       if (PROPERTY_ASSIGN_SEMANTICS (x) != property_assign_semantics)
   1230 	{
   1231 	  warning_at (location, 0,
   1232 		      "assign semantics attributes of property %qD conflict with previous declaration", decl);
   1233 
   1234 	  if (original_location != UNKNOWN_LOCATION)
   1235 	    inform (original_location, "originally specified here");
   1236 	  return;
   1237 	}
   1238 
   1239       /* It's ok to have a readonly property that becomes a readwrite, but not vice versa.  */
   1240       if (PROPERTY_READONLY (x) == 0  &&  property_readonly == 1)
   1241 	{
   1242 	  warning_at (location, 0,
   1243 		      "%<readonly%> attribute of property %qD conflicts with "
   1244 		      "previous declaration", decl);
   1245 
   1246 	  if (original_location != UNKNOWN_LOCATION)
   1247 	    inform (original_location, "originally specified here");
   1248 	  return;
   1249 	}
   1250 
   1251       /* We now check that the new and old property declarations have
   1252 	 the same types (or compatible one).  In the Objective-C
   1253 	 tradition of loose type checking, we do type-checking but
   1254 	 only generate warnings (not errors) if they do not match.
   1255 	 For non-readonly properties, the types must match exactly;
   1256 	 for readonly properties, it is allowed to use a "more
   1257 	 specialized" type in the new property declaration.  Eg, the
   1258 	 superclass has a getter returning (NSArray *) and the
   1259 	 subclass a getter returning (NSMutableArray *).  The object's
   1260 	 getter returns an (NSMutableArray *); but if you cast the
   1261 	 object to the superclass, which is allowed, you'd still
   1262 	 expect the getter to return an (NSArray *), which works since
   1263 	 an (NSMutableArray *) is an (NSArray *) too.  So, the set of
   1264 	 objects belonging to the type of the new @property should be
   1265 	 a subset of the set of objects belonging to the type of the
   1266 	 old @property.  This is what "specialization" means.  And the
   1267 	 reason it only applies to readonly properties is that for a
   1268 	 readwrite property the setter would have the opposite
   1269 	 requirement - ie that the superclass type is more specialized
   1270 	 then the subclass one; hence the only way to satisfy both
   1271 	 constraints is that the types match.  */
   1272 
   1273       /* If the types are not the same in the C sense, we warn ...  */
   1274       if (!comptypes (TREE_TYPE (x), TREE_TYPE (decl))
   1275 	  /* ... unless the property is readonly, in which case we
   1276 	     allow a new, more specialized, declaration.  */
   1277 	  && (!property_readonly
   1278 	      || !objc_compare_types (TREE_TYPE (x),
   1279 				      TREE_TYPE (decl), -5, NULL_TREE)))
   1280 	{
   1281 	  warning_at (location, 0,
   1282 		      "type of property %qD conflicts with previous declaration", decl);
   1283 	  if (original_location != UNKNOWN_LOCATION)
   1284 	    inform (original_location, "originally specified here");
   1285 	  return;
   1286 	}
   1287 
   1288       /* If we are in a class extension and we're extending a readonly
   1289 	 property in the main @interface, we'll just update the
   1290 	 existing property with the readwrite flag and potentially the
   1291 	 new setter name.  */
   1292       if (property_extension_in_class_extension)
   1293 	{
   1294 	  PROPERTY_READONLY (x) = 0;
   1295 	  PROPERTY_SETTER_NAME (x) = property_setter_ident;
   1296 	  return;
   1297 	}
   1298     }
   1299 
   1300   /* Create a PROPERTY_DECL node.  */
   1301   tree property_decl = make_node (PROPERTY_DECL);
   1302 
   1303   /* Copy the basic information from the original decl.  */
   1304   tree p_type = TREE_TYPE (decl);
   1305   TREE_TYPE (property_decl) = p_type;
   1306   DECL_SOURCE_LOCATION (property_decl) = DECL_SOURCE_LOCATION (decl);
   1307   TREE_DEPRECATED (property_decl) = TREE_DEPRECATED (decl);
   1308   TREE_UNAVAILABLE (property_decl) = TREE_UNAVAILABLE (decl);
   1309 
   1310   /* Add property-specific information.  */
   1311   PROPERTY_NAME (property_decl) = DECL_NAME (decl);
   1312   PROPERTY_GETTER_NAME (property_decl) = property_getter_ident;
   1313   PROPERTY_SETTER_NAME (property_decl) = property_setter_ident;
   1314   PROPERTY_READONLY (property_decl) = property_readonly;
   1315   PROPERTY_NONATOMIC (property_decl) = property_nonatomic;
   1316   PROPERTY_CLASS (property_decl) = property_class;
   1317   PROPERTY_ASSIGN_SEMANTICS (property_decl) = property_assign_semantics;
   1318   PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
   1319   PROPERTY_DYNAMIC (property_decl) = 0;
   1320 
   1321   /* FIXME: We seem to drop any existing DECL_ATTRIBUTES on the floor.  */
   1322   if (property_nullability != OBJC_PROPERTY_NULL_UNSET)
   1323     {
   1324       if (p_type && !POINTER_TYPE_P (p_type))
   1325 	error_at (decl_loc, "nullability specifier %qE cannot be applied to"
   1326 		  " non-pointer type %qT",
   1327 		  attrs[OBJC_PROPATTR_GROUP_NULLABLE]->name, p_type);
   1328       else if (p_type && POINTER_TYPE_P (p_type) && TREE_TYPE (p_type)
   1329 	       && POINTER_TYPE_P (TREE_TYPE (p_type)))
   1330 	error_at (decl_loc, "nullability specifier %qE cannot be applied to"
   1331 		  " multi-level pointer type %qT",
   1332 		  attrs[OBJC_PROPATTR_GROUP_NULLABLE]->name, p_type);
   1333       else
   1334 	{
   1335 	  tree attr_name = get_identifier ("objc_nullability");
   1336 	  tree attr_value = build_int_cst (unsigned_type_node,
   1337 				       (unsigned)property_nullability);
   1338 	  tree nulla = build_tree_list (attr_name, attr_value);
   1339 	  DECL_ATTRIBUTES (property_decl) = nulla;
   1340 	}
   1341     }
   1342 
   1343   /* Remember the fact that the property was found in the @optional
   1344      section in a @protocol, or not.  */
   1345   if (objc_method_optional_flag)
   1346     PROPERTY_OPTIONAL (property_decl) = 1;
   1347   else
   1348     PROPERTY_OPTIONAL (property_decl) = 0;
   1349 
   1350   /* Note that PROPERTY_GETTER_NAME is always set for all
   1351      PROPERTY_DECLs, and PROPERTY_SETTER_NAME is always set for all
   1352      PROPERTY_DECLs where PROPERTY_READONLY == 0.  Any time we deal
   1353      with a getter or setter, we should get the PROPERTY_DECL and use
   1354      PROPERTY_GETTER_NAME and PROPERTY_SETTER_NAME to know the correct
   1355      names.  */
   1356 
   1357   /* Add the PROPERTY_DECL to the list of properties for the class.  */
   1358   TREE_CHAIN (property_decl) = CLASS_PROPERTY_DECL (objc_interface_context);
   1359   CLASS_PROPERTY_DECL (objc_interface_context) = property_decl;
   1360 }
   1361 
   1362 /* This is a subroutine of objc_maybe_build_component_ref.  Search the
   1363    list of methods in the interface (and, failing that, the local list
   1364    in the implementation, and failing that, the protocol list)
   1365    provided for a 'setter' or 'getter' for 'component' with default
   1366    names (ie, if 'component' is "name", then search for "name" and
   1367    "setName:").  It is also possible to specify a different
   1368    'getter_name' (this is used for @optional readonly properties).  If
   1369    any is found, then create an artificial property that uses them.
   1370    Return NULL_TREE if 'getter' or 'setter' could not be found.  */
   1371 static tree
   1372 maybe_make_artificial_property_decl (tree interface, tree implementation,
   1373 				     tree protocol_list, tree component, bool is_class,
   1374 				     tree getter_name)
   1375 {
   1376   tree setter_name = get_identifier (objc_build_property_setter_name (component));
   1377   tree getter = NULL_TREE;
   1378   tree setter = NULL_TREE;
   1379 
   1380   if (getter_name == NULL_TREE)
   1381     getter_name = component;
   1382 
   1383   /* First, check the @interface and all superclasses.  */
   1384   if (interface)
   1385     {
   1386       int flags = 0;
   1387 
   1388       /* Using instance methods of the root class as accessors is most
   1389 	 likely unwanted and can be extremely confusing (and, most
   1390 	 importantly, other Objective-C 2.0 compilers do not do it).
   1391 	 Turn it off.  */
   1392       if (is_class)
   1393 	flags = OBJC_LOOKUP_CLASS | OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS;
   1394 
   1395       getter = lookup_method_static (interface, getter_name, flags);
   1396       setter = lookup_method_static (interface, setter_name, flags);
   1397     }
   1398 
   1399   /* Second, check the local @implementation context.  */
   1400   if (!getter && !setter)
   1401     {
   1402       if (implementation)
   1403 	{
   1404 	  if (is_class)
   1405 	    {
   1406 	      getter = lookup_method (CLASS_CLS_METHODS (implementation), getter_name);
   1407 	      setter = lookup_method (CLASS_CLS_METHODS (implementation), setter_name);
   1408 	    }
   1409 	  else
   1410 	    {
   1411 	      getter = lookup_method (CLASS_NST_METHODS (implementation), getter_name);
   1412 	      setter = lookup_method (CLASS_NST_METHODS (implementation), setter_name);
   1413 	    }
   1414 	}
   1415     }
   1416 
   1417   /* Try the protocol_list if we didn't find anything in the
   1418      @interface and in the @implementation.  */
   1419   if (!getter && !setter)
   1420     {
   1421       getter = lookup_method_in_protocol_list (protocol_list, getter_name, is_class);
   1422       setter = lookup_method_in_protocol_list (protocol_list, setter_name, is_class);
   1423     }
   1424 
   1425   /* There needs to be at least a getter or setter for this to be a
   1426      valid 'object.component' syntax.  */
   1427   if (getter || setter)
   1428     {
   1429       /* Yes ... determine the type of the expression.  */
   1430       tree property_decl;
   1431       tree type;
   1432 
   1433       if (getter)
   1434 	type = TREE_VALUE (TREE_TYPE (getter));
   1435       else
   1436 	type = TREE_VALUE (TREE_TYPE (METHOD_SEL_ARGS (setter)));
   1437 
   1438       /* Create an artificial property declaration with the
   1439 	 information we collected on the type and getter/setter
   1440 	 names.  */
   1441       property_decl = make_node (PROPERTY_DECL);
   1442 
   1443       TREE_TYPE (property_decl) = type;
   1444       DECL_SOURCE_LOCATION (property_decl) = input_location;
   1445       TREE_DEPRECATED (property_decl) = 0;
   1446       TREE_UNAVAILABLE (property_decl) = 0;
   1447       DECL_ARTIFICIAL (property_decl) = 1;
   1448 
   1449       /* Add property-specific information.  Note that one of
   1450 	 PROPERTY_GETTER_NAME or PROPERTY_SETTER_NAME may refer to a
   1451 	 non-existing method; this will generate an error when the
   1452 	 expression is later compiled.  At this stage we don't know if
   1453 	 the getter or setter will be used, so we can't generate an
   1454 	 error.  */
   1455       PROPERTY_NAME (property_decl) = component;
   1456       PROPERTY_GETTER_NAME (property_decl) = getter_name;
   1457       PROPERTY_SETTER_NAME (property_decl) = setter_name;
   1458       PROPERTY_READONLY (property_decl) = 0;
   1459       PROPERTY_NONATOMIC (property_decl) = 0;
   1460       PROPERTY_ASSIGN_SEMANTICS (property_decl) = 0;
   1461       PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
   1462       PROPERTY_DYNAMIC (property_decl) = 0;
   1463       PROPERTY_OPTIONAL (property_decl) = 0;
   1464 
   1465       if (!getter)
   1466 	PROPERTY_HAS_NO_GETTER (property_decl) = 1;
   1467 
   1468       /* The following is currently unused, but it's nice to have
   1469 	 there.  We may use it if we need in the future.  */
   1470       if (!setter)
   1471 	PROPERTY_HAS_NO_SETTER (property_decl) = 1;
   1472 
   1473       return property_decl;
   1474     }
   1475 
   1476   return NULL_TREE;
   1477 }
   1478 
   1479 /* This hook routine is invoked by the parser when an expression such
   1480    as 'xxx.yyy' is parsed.  We get a chance to process these
   1481    expressions in a way that is specified to Objective-C (to implement
   1482    the Objective-C 2.0 dot-syntax, properties, or non-fragile ivars).
   1483    If the expression is not an Objective-C specified expression, we
   1484    should return NULL_TREE; else we return the expression.
   1485 
   1486    At the moment this only implements dot-syntax and properties (not
   1487    non-fragile ivars yet), ie 'object.property' or 'object.component'
   1488    where 'component' is not a declared property, but a valid getter or
   1489    setter for it could be found.  */
   1490 tree
   1491 objc_maybe_build_component_ref (tree object, tree property_ident)
   1492 {
   1493   tree x = NULL_TREE;
   1494   tree rtype;
   1495 
   1496   /* If we are in Objective-C 1.0 mode, dot-syntax and properties are
   1497      not available.  */
   1498   if (flag_objc1_only)
   1499     return NULL_TREE;
   1500 
   1501   /* Try to determine if 'object' is an Objective-C object or not.  If
   1502      not, return.  */
   1503   if (object == NULL_TREE || object == error_mark_node
   1504       || (rtype = TREE_TYPE (object)) == NULL_TREE)
   1505     return NULL_TREE;
   1506 
   1507   if (property_ident == NULL_TREE || property_ident == error_mark_node
   1508       || TREE_CODE (property_ident) != IDENTIFIER_NODE)
   1509     return NULL_TREE;
   1510 
   1511   /* The following analysis of 'object' is similar to the one used for
   1512      the 'receiver' of a method invocation.  We need to determine what
   1513      'object' is and find the appropriate property (either declared,
   1514      or artificial) for it (in the same way as we need to find the
   1515      appropriate method prototype for a method invocation).  There are
   1516      some simplifications here though: "object.property" is invalid if
   1517      "object" has a type of "id" or "Class"; it must at least have a
   1518      protocol attached to it, and "object" is never a class name as
   1519      that is done by objc_build_class_component_ref.  Finally, we
   1520      don't know if this really is a dot-syntax expression, so we want
   1521      to make a quick exit if it is not; for this reason, we try to
   1522      postpone checks after determining that 'object' looks like an
   1523      Objective-C object.  */
   1524 
   1525   if (objc_is_id (rtype))
   1526     {
   1527       /* This is the case that the 'object' is of type 'id' or
   1528 	 'Class'.  */
   1529 
   1530       /* Check if at least it is of type 'id <Protocol>' or 'Class
   1531 	 <Protocol>'; if so, look the property up in the
   1532 	 protocols.  */
   1533       if (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype)))
   1534 	{
   1535 	  tree rprotos = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype));
   1536 
   1537 	  if (rprotos)
   1538 	    {
   1539 	      /* No point looking up declared @properties if we are
   1540 		 dealing with a class.  Classes have no declared
   1541 		 properties.  */
   1542 	      if (!IS_CLASS (rtype))
   1543 		x = lookup_property_in_protocol_list (rprotos, property_ident);
   1544 
   1545 	      if (x == NULL_TREE)
   1546 		{
   1547 		  /* Ok, no property.  Maybe it was an
   1548 		     object.component dot-syntax without a declared
   1549 		     property (this is valid for classes too).  Look
   1550 		     for getter/setter methods and internally declare
   1551 		     an artificial property based on them if found.  */
   1552 		  x = maybe_make_artificial_property_decl (NULL_TREE,
   1553 							   NULL_TREE,
   1554 							   rprotos,
   1555 							   property_ident,
   1556 							   IS_CLASS (rtype),
   1557 							   NULL_TREE);
   1558 		}
   1559 	      else if (PROPERTY_OPTIONAL (x) && PROPERTY_READONLY (x))
   1560 		{
   1561 		  /* This is a special, complicated case.  If the
   1562 		     property is optional, and is read-only, then the
   1563 		     property is always used for reading, but an
   1564 		     eventual existing non-property setter can be used
   1565 		     for writing.  We create an artificial property
   1566 		     decl copying the getter from the optional
   1567 		     property, and looking up the setter in the
   1568 		     interface.  */
   1569 		  x = maybe_make_artificial_property_decl (NULL_TREE,
   1570 							   NULL_TREE,
   1571 							   rprotos,
   1572 							   property_ident,
   1573 							   false,
   1574 							   PROPERTY_GETTER_NAME (x));
   1575 		}
   1576 	    }
   1577 	}
   1578       else if (objc_method_context)
   1579 	{
   1580 	  /* Else, if we are inside a method it could be the case of
   1581 	     'super' or 'self'.  */
   1582 	  tree interface_type = NULL_TREE;
   1583 	  tree t = object;
   1584 	  while (TREE_CODE (t) == COMPOUND_EXPR
   1585 		 || TREE_CODE (t) == MODIFY_EXPR
   1586 		 || CONVERT_EXPR_P (t)
   1587 		 || TREE_CODE (t) == COMPONENT_REF)
   1588 	    t = TREE_OPERAND (t, 0);
   1589 
   1590 	  STRIP_ANY_LOCATION_WRAPPER (t);
   1591 
   1592 	  if (t == UOBJC_SUPER_decl)
   1593 	    interface_type = lookup_interface (CLASS_SUPER_NAME (implementation_template));
   1594 	  else if (t == self_decl)
   1595 	    interface_type = lookup_interface (CLASS_NAME (implementation_template));
   1596 
   1597 	  if (interface_type)
   1598 	    {
   1599 	      if (TREE_CODE (objc_method_context) != CLASS_METHOD_DECL)
   1600 		x = lookup_property (interface_type, property_ident);
   1601 
   1602 	      if (x == NULL_TREE)
   1603 		{
   1604 		  /* Try the dot-syntax without a declared property.
   1605 		     If this is an access to 'self', it is possible
   1606 		     that they may refer to a setter/getter that is
   1607 		     not declared in the interface, but exists locally
   1608 		     in the implementation.  In that case, get the
   1609 		     implementation context and use it.  */
   1610 		  tree implementation = NULL_TREE;
   1611 
   1612 		  if (t == self_decl)
   1613 		    implementation = objc_implementation_context;
   1614 
   1615 		  x = maybe_make_artificial_property_decl
   1616 		    (interface_type, implementation, NULL_TREE,
   1617 		     property_ident,
   1618 		     (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL),
   1619 		     NULL_TREE);
   1620 		}
   1621 	      else if (PROPERTY_OPTIONAL (x) && PROPERTY_READONLY (x))
   1622 		{
   1623 		  tree implementation = NULL_TREE;
   1624 
   1625 		  if (t == self_decl)
   1626 		    implementation = objc_implementation_context;
   1627 
   1628 		  x = maybe_make_artificial_property_decl (interface_type,
   1629 							   implementation,
   1630 							   NULL_TREE,
   1631 							   property_ident,
   1632 							   false,
   1633 							   PROPERTY_GETTER_NAME (x));
   1634 		}
   1635 	    }
   1636 	}
   1637     }
   1638   else
   1639     {
   1640       /* This is the case where we have more information on 'rtype'.  */
   1641       tree basetype = TYPE_MAIN_VARIANT (rtype);
   1642 
   1643       /* Skip the pointer - if none, it's not an Objective-C object or
   1644 	 class.  */
   1645       if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE)
   1646 	basetype = TREE_TYPE (basetype);
   1647       else
   1648 	return NULL_TREE;
   1649 
   1650       /* Traverse typedefs.  */
   1651       while (basetype != NULL_TREE
   1652 	     && TREE_CODE (basetype) == RECORD_TYPE
   1653 	     && OBJC_TYPE_NAME (basetype)
   1654 	     && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
   1655 	     && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
   1656 	basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
   1657 
   1658       if (basetype != NULL_TREE && TYPED_OBJECT (basetype))
   1659 	{
   1660 	  tree interface_type = TYPE_OBJC_INTERFACE (basetype);
   1661 	  tree protocol_list = TYPE_OBJC_PROTOCOL_LIST (basetype);
   1662 
   1663 	  if (interface_type
   1664 	      && (TREE_CODE (interface_type) == CLASS_INTERFACE_TYPE
   1665 		  || TREE_CODE (interface_type) == CATEGORY_INTERFACE_TYPE
   1666 		  || TREE_CODE (interface_type) == PROTOCOL_INTERFACE_TYPE))
   1667 	    {
   1668 	      /* Not sure 'rtype' could ever be a class here!  Just
   1669 		 for safety we keep the checks.  */
   1670 	      if (!IS_CLASS (rtype))
   1671 		{
   1672 		  x = lookup_property (interface_type, property_ident);
   1673 
   1674 		  if (x == NULL_TREE)
   1675 		    x = lookup_property_in_protocol_list (protocol_list,
   1676 							  property_ident);
   1677 		}
   1678 
   1679 	      if (x == NULL_TREE)
   1680 		{
   1681 		  /* Try the dot-syntax without a declared property.
   1682 		     If we are inside a method implementation, it is
   1683 		     possible that they may refer to a setter/getter
   1684 		     that is not declared in the interface, but exists
   1685 		     locally in the implementation.  In that case, get
   1686 		     the implementation context and use it.  */
   1687 		  tree implementation = NULL_TREE;
   1688 
   1689 		  if (objc_implementation_context
   1690 		      && CLASS_NAME (objc_implementation_context)
   1691 		      == OBJC_TYPE_NAME (interface_type))
   1692 		    implementation = objc_implementation_context;
   1693 
   1694 		  x = maybe_make_artificial_property_decl (interface_type,
   1695 							   implementation,
   1696 							   protocol_list,
   1697 							   property_ident,
   1698 							   IS_CLASS (rtype),
   1699 							   NULL_TREE);
   1700 		}
   1701 	      else if (PROPERTY_OPTIONAL (x) && PROPERTY_READONLY (x))
   1702 		{
   1703 		  tree implementation = NULL_TREE;
   1704 
   1705 		  if (objc_implementation_context
   1706 		      && CLASS_NAME (objc_implementation_context)
   1707 		      == OBJC_TYPE_NAME (interface_type))
   1708 		    implementation = objc_implementation_context;
   1709 
   1710 		  x = maybe_make_artificial_property_decl (interface_type,
   1711 							   implementation,
   1712 							   protocol_list,
   1713 							   property_ident,
   1714 							   false,
   1715 							   PROPERTY_GETTER_NAME (x));
   1716 		}
   1717 	    }
   1718 	}
   1719     }
   1720 
   1721   if (x)
   1722     {
   1723       tree expression;
   1724       tree getter_call;
   1725       tree method_prototype_avail = NULL_TREE;
   1726 
   1727       /* We have an additional nasty problem here; if this
   1728 	 PROPERTY_REF needs to become a 'getter', then the conversion
   1729 	 from PROPERTY_REF into a getter call happens in gimplify,
   1730 	 after the selector table has already been generated and when
   1731 	 it is too late to add another selector to it.  To work around
   1732 	 the problem, we always create the getter call at this stage,
   1733 	 which puts the selector in the table.  Note that if the
   1734 	 PROPERTY_REF becomes a 'setter' instead of a 'getter', then
   1735 	 we have added a selector too many to the selector table.
   1736 	 This is a little inefficient.
   1737 
   1738 	 Also note that method calls to 'self' and 'super' require the
   1739 	 context (self_decl, UOBJS_SUPER_decl,
   1740 	 objc_implementation_context etc) to be built correctly; this
   1741 	 is yet another reason why building the call at the gimplify
   1742 	 stage (when this context has been lost) is not very
   1743 	 practical.  If we build it at this stage, we know it will
   1744 	 always be built correctly.
   1745 
   1746 	 If the PROPERTY_HAS_NO_GETTER() (ie, it is an artificial
   1747 	 property decl created to deal with a dotsyntax not really
   1748 	 referring to an existing property) then do not try to build a
   1749 	 call to the getter as there is no getter.  */
   1750       if (PROPERTY_HAS_NO_GETTER (x))
   1751 	getter_call = NULL_TREE;
   1752       else
   1753 	getter_call = objc_finish_message_expr
   1754 	  (object, PROPERTY_GETTER_NAME (x), NULL_TREE,
   1755 	   /* Disable the immediate deprecation warning if the getter
   1756 	      is deprecated, but record the fact that the getter is
   1757 	      deprecated by setting PROPERTY_REF_DEPRECATED_GETTER to
   1758 	      the method prototype.  */
   1759 	   &method_prototype_avail);
   1760 
   1761       expression = build4 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call,
   1762 			   method_prototype_avail);
   1763       SET_EXPR_LOCATION (expression, input_location);
   1764       TREE_SIDE_EFFECTS (expression) = 1;
   1765 
   1766       return expression;
   1767     }
   1768 
   1769   return NULL_TREE;
   1770 }
   1771 
   1772 /* This hook routine is invoked by the parser when an expression such
   1773    as 'xxx.yyy' is parsed, and 'xxx' is a class name.  This is the
   1774    Objective-C 2.0 dot-syntax applied to classes, so we need to
   1775    convert it into a setter/getter call on the class.  */
   1776 tree
   1777 objc_build_class_component_ref (tree class_name, tree property_ident)
   1778 {
   1779   tree x = NULL_TREE;
   1780   tree object, rtype;
   1781 
   1782   if (flag_objc1_only)
   1783     error_at (input_location, "the dot syntax is not available in Objective-C 1.0");
   1784 
   1785   if (class_name == NULL_TREE || class_name == error_mark_node
   1786       || TREE_CODE (class_name) != IDENTIFIER_NODE)
   1787     return error_mark_node;
   1788 
   1789   if (property_ident == NULL_TREE || property_ident == error_mark_node
   1790       || TREE_CODE (property_ident) != IDENTIFIER_NODE)
   1791     return NULL_TREE;
   1792 
   1793   object = objc_get_class_reference (class_name);
   1794   if (!object)
   1795     {
   1796       /* We know that 'class_name' is an Objective-C class name as the
   1797 	 parser won't call this function if it is not.  This is only a
   1798 	 double-check for safety.  */
   1799       error_at (input_location, "could not find class %qE", class_name);
   1800       return error_mark_node;
   1801     }
   1802 
   1803   rtype = lookup_interface (class_name);
   1804   if (!rtype)
   1805     {
   1806       /* Again, this should never happen, but we do check.  */
   1807       error_at (input_location, "could not find interface for class %qE", class_name);
   1808       return error_mark_node;
   1809     }
   1810   else
   1811     {
   1812       if (TREE_UNAVAILABLE (rtype))
   1813 	error ("class %qE is unavailable", class_name);
   1814       else if (TREE_DEPRECATED (rtype))
   1815 	warning (OPT_Wdeprecated_declarations, "class %qE is deprecated", class_name);
   1816     }
   1817 
   1818   x = maybe_make_artificial_property_decl (rtype, NULL_TREE, NULL_TREE,
   1819 					   property_ident,
   1820 					   true, NULL_TREE);
   1821 
   1822   if (x)
   1823     {
   1824       tree expression;
   1825       tree getter_call;
   1826       tree method_prototype_avail = NULL_TREE;
   1827 
   1828       if (PROPERTY_HAS_NO_GETTER (x))
   1829 	getter_call = NULL_TREE;
   1830       else
   1831 	getter_call = objc_finish_message_expr
   1832 	  (object, PROPERTY_GETTER_NAME (x), NULL_TREE,
   1833 	   &method_prototype_avail);
   1834 
   1835       expression = build4 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call,
   1836 			   method_prototype_avail);
   1837       SET_EXPR_LOCATION (expression, input_location);
   1838       TREE_SIDE_EFFECTS (expression) = 1;
   1839 
   1840       return expression;
   1841     }
   1842   else
   1843     {
   1844       error_at (input_location, "could not find setter/getter for %qE in class %qE",
   1845 		property_ident,	class_name);
   1846       return error_mark_node;
   1847     }
   1848 
   1849   return NULL_TREE;
   1850 }
   1851 
   1852 
   1853 /* This is used because we don't want to expose PROPERTY_REF to the
   1854    C/C++ frontends.  Maybe we should!  */
   1855 bool
   1856 objc_is_property_ref (tree node)
   1857 {
   1858   if (node  &&  TREE_CODE (node) == PROPERTY_REF)
   1859     return true;
   1860   else
   1861     return false;
   1862 }
   1863 
   1864 /* We use this to report tree codes that are known to be invalid in const-
   1865    expression contexts.  */
   1866 bool
   1867 objc_non_constant_expr_p (tree node)
   1868 {
   1869   switch (TREE_CODE (node))
   1870     {
   1871       default:
   1872 	return false;
   1873       case MESSAGE_SEND_EXPR:
   1874       case PROPERTY_REF:
   1875 	return true;
   1876     }
   1877 }
   1878 
   1879 /* This function builds a setter call for a PROPERTY_REF (real, for a
   1880    declared property, or artificial, for a dot-syntax accessor which
   1881    is not corresponding to a property).  'lhs' must be a PROPERTY_REF
   1882    (the caller must check this beforehand).  'rhs' is the value to
   1883    assign to the property.  A plain setter call is returned, or
   1884    error_mark_node if the property is readonly.  */
   1885 
   1886 static tree
   1887 objc_build_setter_call (tree lhs, tree rhs)
   1888 {
   1889   tree object_expr = PROPERTY_REF_OBJECT (lhs);
   1890   tree property_decl = PROPERTY_REF_PROPERTY_DECL (lhs);
   1891 
   1892   if (PROPERTY_READONLY (property_decl))
   1893     {
   1894       error ("%qs property cannot be set", "readonly");
   1895       return error_mark_node;
   1896     }
   1897   else
   1898     {
   1899       tree setter_argument = build_tree_list (NULL_TREE, rhs);
   1900       tree setter;
   1901 
   1902       /* TODO: Check that the setter return type is 'void'.  */
   1903 
   1904       /* TODO: Decay arguments in C.  */
   1905       setter = objc_finish_message_expr (object_expr,
   1906 					 PROPERTY_SETTER_NAME (property_decl),
   1907 					 setter_argument, NULL);
   1908       return setter;
   1909     }
   1910 }
   1911 
   1912 /* This hook routine is called when a MODIFY_EXPR is being built.  We
   1913    check what is being modified; if it is a PROPERTY_REF, we need to
   1914    generate a 'setter' function call for the property.  If this is not
   1915    a PROPERTY_REF, we return NULL_TREE and the C/C++ frontend will go
   1916    on creating their MODIFY_EXPR.
   1917 
   1918    This is used for example if you write
   1919 
   1920    object.count = 1;
   1921 
   1922    where 'count' is a property.  The left-hand side creates a
   1923    PROPERTY_REF, and then the compiler tries to generate a MODIFY_EXPR
   1924    to assign something to it.  We intercept that here, and generate a
   1925    call to the 'setter' method instead.  */
   1926 tree
   1927 objc_maybe_build_modify_expr (tree lhs, tree rhs)
   1928 {
   1929   if (lhs && TREE_CODE (lhs) == PROPERTY_REF)
   1930     {
   1931       /* Building a simple call to the setter method would work for cases such as
   1932 
   1933       object.count = 1;
   1934 
   1935       but wouldn't work for cases such as
   1936 
   1937       count = object2.count = 1;
   1938 
   1939       to get these to work with very little effort, we build a
   1940       compound statement which does the setter call (to set the
   1941       property to 'rhs'), but which can also be evaluated returning
   1942       the 'rhs'.  If the 'rhs' has no side effects, we can simply
   1943       evaluate it twice, building
   1944 
   1945       ([object setProperty: rhs]; rhs)
   1946 
   1947       If it has side effects, we put it in a temporary variable first,
   1948       so we create the following:
   1949 
   1950       (temp = rhs; [object setProperty: temp]; temp)
   1951 
   1952       setter_argument is rhs in the first case, and temp in the second
   1953       case.
   1954       */
   1955       tree setter_argument;
   1956 
   1957       /* s1, s2 and s3 are the tree statements that we need in the
   1958 	 compound expression.  */
   1959       tree s1, s2, s3, compound_expr;
   1960 
   1961       if (TREE_SIDE_EFFECTS (rhs))
   1962 	{
   1963 	  tree bind;
   1964 
   1965 	  /* Declare __objc_property_temp in a local bind.  */
   1966 	  setter_argument = objc_create_temporary_var (TREE_TYPE (rhs), "__objc_property_temp");
   1967 	  DECL_SOURCE_LOCATION (setter_argument) = input_location;
   1968 	  bind = build3 (BIND_EXPR, void_type_node, setter_argument, NULL, NULL);
   1969 	  SET_EXPR_LOCATION (bind, input_location);
   1970 	  TREE_SIDE_EFFECTS (bind) = 1;
   1971 	  add_stmt (bind);
   1972 
   1973 	  /* s1: x = rhs */
   1974 	  s1 = build_modify_expr (input_location, setter_argument, NULL_TREE,
   1975 				  NOP_EXPR,
   1976 				  input_location, rhs, NULL_TREE);
   1977 	  SET_EXPR_LOCATION (s1, input_location);
   1978 	}
   1979       else
   1980 	{
   1981 	  /* No s1.  */
   1982 	  setter_argument = rhs;
   1983 	  s1 = NULL_TREE;
   1984 	}
   1985 
   1986       /* Now build the compound statement.  */
   1987 
   1988       /* s2: [object setProperty: x] */
   1989       s2 = objc_build_setter_call (lhs, setter_argument);
   1990 
   1991       /* This happens if building the setter failed because the
   1992 	 property is readonly.  */
   1993       if (s2 == error_mark_node)
   1994 	return error_mark_node;
   1995 
   1996       SET_EXPR_LOCATION (s2, input_location);
   1997 
   1998       /* s3: x */
   1999       s3 = convert (TREE_TYPE (lhs), setter_argument);
   2000 
   2001       /* Now build the compound statement (s1, s2, s3) or (s2, s3) as
   2002 	 appropriate.  */
   2003       if (s1)
   2004 	compound_expr = build_compound_expr (input_location, build_compound_expr (input_location, s1, s2), s3);
   2005       else
   2006 	compound_expr = build_compound_expr (input_location, s2, s3);
   2007 
   2008       /* Without this, with -Wall you get a 'valued computed is not
   2009 	 used' every time there is a "object.property = x" where the
   2010 	 value of the resulting MODIFY_EXPR is not used.  That is
   2011 	 correct (maybe a more sophisticated implementation could
   2012 	 avoid generating the compound expression if not needed), but
   2013 	 we need to turn it off.  */
   2014       suppress_warning (compound_expr, OPT_Wunused);
   2015       return compound_expr;
   2016     }
   2017   else
   2018     return NULL_TREE;
   2019 }
   2020 
   2021 /* This hook is called by the frontend when one of the four unary
   2022    expressions PREINCREMENT_EXPR, POSTINCREMENT_EXPR,
   2023    PREDECREMENT_EXPR and POSTDECREMENT_EXPR is being built with an
   2024    argument which is a PROPERTY_REF.  For example, this happens if you have
   2025 
   2026    object.count++;
   2027 
   2028    where 'count' is a property.  We need to use the 'getter' and
   2029    'setter' for the property in an appropriate way to build the
   2030    appropriate expression.  'code' is the code for the expression (one
   2031    of the four mentioned above); 'argument' is the PROPERTY_REF, and
   2032    'increment' is how much we need to add or subtract.  */
   2033 tree
   2034 objc_build_incr_expr_for_property_ref (location_t location,
   2035 				       enum tree_code code,
   2036 				       tree argument, tree increment)
   2037 {
   2038   /* Here are the expressions that we want to build:
   2039 
   2040      For PREINCREMENT_EXPR / PREDECREMENT_EXPR:
   2041     (temp = [object property] +/- increment, [object setProperty: temp], temp)
   2042 
   2043     For POSTINCREMENT_EXPR / POSTECREMENT_EXPR:
   2044     (temp = [object property], [object setProperty: temp +/- increment], temp) */
   2045 
   2046   tree temp_variable_decl, bind;
   2047   /* s1, s2 and s3 are the tree statements that we need in the
   2048      compound expression.  */
   2049   tree s1, s2, s3, compound_expr;
   2050 
   2051   /* Safety check.  */
   2052   if (!argument || TREE_CODE (argument) != PROPERTY_REF)
   2053     return error_mark_node;
   2054 
   2055   /* Declare __objc_property_temp in a local bind.  */
   2056   temp_variable_decl = objc_create_temporary_var (TREE_TYPE (argument), "__objc_property_temp");
   2057   DECL_SOURCE_LOCATION (temp_variable_decl) = location;
   2058   bind = build3 (BIND_EXPR, void_type_node, temp_variable_decl, NULL, NULL);
   2059   SET_EXPR_LOCATION (bind, location);
   2060   TREE_SIDE_EFFECTS (bind) = 1;
   2061   add_stmt (bind);
   2062 
   2063   /* Now build the compound statement.  */
   2064 
   2065   /* Note that the 'getter' is generated at gimplify time; at this
   2066      time, we can simply put the property_ref (ie, argument) wherever
   2067      we want the getter ultimately to be.  */
   2068 
   2069   /* s1: __objc_property_temp = [object property] <+/- increment> */
   2070   switch (code)
   2071     {
   2072     case PREINCREMENT_EXPR:
   2073       /* __objc_property_temp = [object property] + increment */
   2074       s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
   2075 			      NOP_EXPR,
   2076 			      location, build2 (PLUS_EXPR, TREE_TYPE (argument),
   2077 						argument, increment), NULL_TREE);
   2078       break;
   2079     case PREDECREMENT_EXPR:
   2080       /* __objc_property_temp = [object property] - increment */
   2081       s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
   2082 			      NOP_EXPR,
   2083 			      location, build2 (MINUS_EXPR, TREE_TYPE (argument),
   2084 						argument, increment), NULL_TREE);
   2085       break;
   2086     case POSTINCREMENT_EXPR:
   2087     case POSTDECREMENT_EXPR:
   2088       /* __objc_property_temp = [object property] */
   2089       s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
   2090 			      NOP_EXPR,
   2091 			      location, argument, NULL_TREE);
   2092       break;
   2093     default:
   2094       gcc_unreachable ();
   2095     }
   2096 
   2097   /* s2: [object setProperty: __objc_property_temp <+/- increment>] */
   2098   switch (code)
   2099     {
   2100     case PREINCREMENT_EXPR:
   2101     case PREDECREMENT_EXPR:
   2102       /* [object setProperty: __objc_property_temp] */
   2103       s2 = objc_build_setter_call (argument, temp_variable_decl);
   2104       break;
   2105     case POSTINCREMENT_EXPR:
   2106       /* [object setProperty: __objc_property_temp + increment] */
   2107       s2 = objc_build_setter_call (argument,
   2108 				   build2 (PLUS_EXPR, TREE_TYPE (argument),
   2109 					   temp_variable_decl, increment));
   2110       break;
   2111     case POSTDECREMENT_EXPR:
   2112       /* [object setProperty: __objc_property_temp - increment] */
   2113       s2 = objc_build_setter_call (argument,
   2114 				   build2 (MINUS_EXPR, TREE_TYPE (argument),
   2115 					   temp_variable_decl, increment));
   2116       break;
   2117     default:
   2118       gcc_unreachable ();
   2119     }
   2120 
   2121   /* This happens if building the setter failed because the property
   2122      is readonly.  */
   2123   if (s2 == error_mark_node)
   2124     return error_mark_node;
   2125 
   2126   SET_EXPR_LOCATION (s2, location);
   2127 
   2128   /* s3: __objc_property_temp */
   2129   s3 = convert (TREE_TYPE (argument), temp_variable_decl);
   2130 
   2131   /* Now build the compound statement (s1, s2, s3) */
   2132   compound_expr = build_compound_expr (location, build_compound_expr (location, s1, s2), s3);
   2133 
   2134   /* Prevent C++ from warning with -Wall that "right operand of comma
   2135      operator has no effect".  */
   2136   suppress_warning (compound_expr, OPT_Wunused);
   2137   return compound_expr;
   2138 }
   2139 
   2140 tree
   2141 objc_build_method_signature (bool is_class_method, tree rettype, tree selector,
   2142 			     tree optparms, bool ellipsis)
   2143 {
   2144   if (is_class_method)
   2145     return build_method_decl (CLASS_METHOD_DECL, rettype, selector,
   2146 			      optparms, ellipsis);
   2147   else
   2148     return build_method_decl (INSTANCE_METHOD_DECL, rettype, selector,
   2149 			      optparms, ellipsis);
   2150 }
   2151 
   2152 void
   2153 objc_add_method_declaration (bool is_class_method, tree decl, tree attributes)
   2154 {
   2155   if (!objc_interface_context)
   2156     {
   2157       /* PS: At the moment, due to how the parser works, it should be
   2158 	 impossible to get here.  But it's good to have the check in
   2159 	 case the parser changes.
   2160       */
   2161       fatal_error (input_location,
   2162 		   "method declaration not in @interface context");
   2163     }
   2164 
   2165   if (flag_objc1_only && attributes)
   2166     error_at (input_location, "method attributes are not available in Objective-C 1.0");
   2167 
   2168   objc_decl_method_attributes (&decl, attributes, 0);
   2169   objc_add_method (objc_interface_context,
   2170 		   decl,
   2171 		   is_class_method,
   2172 		   objc_method_optional_flag);
   2173 }
   2174 
   2175 /* Return 'true' if the method definition could be started, and
   2176    'false' if not (because we are outside an @implementation context).
   2177    EXPR is NULL or an expression that needs to be evaluated for the
   2178    side effects of array size expressions in the parameters.
   2179 */
   2180 bool
   2181 objc_start_method_definition (bool is_class_method, tree decl, tree attributes,
   2182 			      tree expr)
   2183 {
   2184   if (!objc_implementation_context)
   2185     {
   2186       error ("method definition not in @implementation context");
   2187       return false;
   2188     }
   2189 
   2190   if (decl != NULL_TREE  && METHOD_SEL_NAME (decl) == error_mark_node)
   2191     return false;
   2192 
   2193 #ifndef OBJCPLUS
   2194   /* Indicate no valid break/continue context.  */
   2195   in_statement = 0;
   2196 #endif
   2197 
   2198   if (attributes)
   2199     warning_at (input_location, 0, "method attributes cannot be specified in @implementation context");
   2200   else
   2201     objc_decl_method_attributes (&decl, attributes, 0);
   2202 
   2203   objc_add_method (objc_implementation_context,
   2204 		   decl,
   2205 		   is_class_method,
   2206 		   /* is optional */ false);
   2207   start_method_def (decl, expr);
   2208   return true;
   2209 }
   2210 
   2211 void
   2212 objc_add_instance_variable (tree decl)
   2213 {
   2214   (void) add_instance_variable (objc_ivar_context,
   2215 				objc_ivar_visibility,
   2216 				decl);
   2217 }
   2218 
   2219 /* Construct a C struct with same name as KLASS, a base struct with tag
   2220    SUPER_NAME (if any), and FIELDS indicated.  */
   2221 
   2222 static tree
   2223 objc_build_struct (tree klass, tree fields, tree super_name)
   2224 {
   2225   tree name = CLASS_NAME (klass);
   2226   tree s = objc_start_struct (name);
   2227   tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
   2228   tree t;
   2229   vec<tree> objc_info = vNULL;
   2230   int i;
   2231 
   2232   if (super)
   2233     {
   2234       /* Prepend a packed variant of the base class into the layout.  This
   2235 	 is necessary to preserve ObjC ABI compatibility.  */
   2236       tree base = build_decl (input_location,
   2237 			      FIELD_DECL, NULL_TREE, super);
   2238       tree field = TYPE_FIELDS (super);
   2239 
   2240       while (field && DECL_CHAIN (field)
   2241 	     && TREE_CODE (DECL_CHAIN (field)) == FIELD_DECL)
   2242 	field = DECL_CHAIN (field);
   2243 
   2244       /* For ObjC ABI purposes, the "packed" size of a base class is
   2245 	 the sum of the offset and the size (in bits) of the last field
   2246 	 in the class.  */
   2247       DECL_SIZE (base)
   2248 	= (field && TREE_CODE (field) == FIELD_DECL
   2249 	   ? size_binop (PLUS_EXPR,
   2250 			 size_binop (PLUS_EXPR,
   2251 				     size_binop
   2252 				     (MULT_EXPR,
   2253 				      convert (bitsizetype,
   2254 					       DECL_FIELD_OFFSET (field)),
   2255 				      bitsize_int (BITS_PER_UNIT)),
   2256 				     DECL_FIELD_BIT_OFFSET (field)),
   2257 			 DECL_SIZE (field))
   2258 	   : bitsize_zero_node);
   2259       DECL_SIZE_UNIT (base)
   2260 	= size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
   2261 		      size_int (BITS_PER_UNIT));
   2262       DECL_ARTIFICIAL (base) = 1;
   2263       SET_DECL_ALIGN (base, 1);
   2264       DECL_FIELD_CONTEXT (base) = s;
   2265 #ifdef OBJCPLUS
   2266       DECL_FIELD_IS_BASE (base) = 1;
   2267 
   2268       if (fields)
   2269 	/* Suppress C++ ABI warnings: we are following the ObjC ABI here.  */
   2270 	suppress_warning (fields, OPT_Wabi);
   2271 #endif
   2272       DECL_CHAIN (base) = fields;
   2273       fields = base;
   2274     }
   2275 
   2276   /* NB: Calling finish_struct() may cause type TYPE_OBJC_INFO
   2277      information in all variants of this RECORD_TYPE to be destroyed
   2278      (this is because the C frontend manipulates TYPE_LANG_SPECIFIC
   2279      for something else and then will change all variants to use the
   2280      same resulting TYPE_LANG_SPECIFIC, ignoring the fact that we use
   2281      it for ObjC protocols and that such propagation will make all
   2282      variants use the same objc_info), but it is therein that we store
   2283      protocol conformance info (e.g., 'NSObject <MyProtocol>').
   2284      Hence, we must save the ObjC-specific information before calling
   2285      finish_struct(), and then reinstate it afterwards.  */
   2286 
   2287   for (t = TYPE_MAIN_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
   2288     {
   2289       INIT_TYPE_OBJC_INFO (t);
   2290       objc_info.safe_push (TYPE_OBJC_INFO (t));
   2291     }
   2292 
   2293   s = objc_finish_struct (s, fields);
   2294 
   2295   for (i = 0, t = TYPE_MAIN_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
   2296     {
   2297       /* We now want to restore the different TYPE_OBJC_INFO, but we
   2298 	 have the additional problem that the C frontend doesn't just
   2299 	 copy TYPE_LANG_SPECIFIC from one variant to the other; it
   2300 	 actually makes all of them the *same* TYPE_LANG_SPECIFIC.  As
   2301 	 we need a different TYPE_OBJC_INFO for each (and
   2302 	 TYPE_OBJC_INFO is a field in TYPE_LANG_SPECIFIC), we need to
   2303 	 make a copy of each TYPE_LANG_SPECIFIC before we modify
   2304 	 TYPE_OBJC_INFO.  */
   2305       if (TYPE_LANG_SPECIFIC (t))
   2306 	{
   2307 	  /* Create a copy of TYPE_LANG_SPECIFIC.  */
   2308 	  struct lang_type *old_lang_type = TYPE_LANG_SPECIFIC (t);
   2309 	  ALLOC_OBJC_TYPE_LANG_SPECIFIC (t);
   2310 	  memcpy (TYPE_LANG_SPECIFIC (t), old_lang_type,
   2311 		  SIZEOF_OBJC_TYPE_LANG_SPECIFIC);
   2312 	}
   2313       else
   2314 	{
   2315 	  /* Just create a new one.  */
   2316 	  ALLOC_OBJC_TYPE_LANG_SPECIFIC (t);
   2317 	}
   2318       /* Replace TYPE_OBJC_INFO with the saved one.  This restores any
   2319 	 protocol information that may have been associated with the
   2320 	 type.  */
   2321       TYPE_OBJC_INFO (t) = objc_info[i];
   2322       /* Replace the IDENTIFIER_NODE with an actual @interface now
   2323 	 that we have it.  */
   2324       TYPE_OBJC_INTERFACE (t) = klass;
   2325     }
   2326   objc_info.release ();
   2327 
   2328   /* Use TYPE_BINFO structures to point at the super class, if any.  */
   2329   objc_xref_basetypes (s, super);
   2330 
   2331   /* Mark this struct as a class template.  */
   2332   CLASS_STATIC_TEMPLATE (klass) = s;
   2333 
   2334   return s;
   2335 }
   2336 
   2337 /* Mark DECL as being 'volatile' for purposes of Darwin
   2338    _setjmp()/_longjmp() exception handling.  Called from
   2339    objc_mark_locals_volatile().  */
   2340 void
   2341 objc_volatilize_decl (tree decl)
   2342 {
   2343   /* Do not mess with variables that are 'static' or (already)
   2344      'volatile'.  */
   2345   if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
   2346       && (TREE_CODE (decl) == VAR_DECL
   2347 	  || TREE_CODE (decl) == PARM_DECL))
   2348     {
   2349       if (local_variables_to_volatilize == NULL)
   2350 	vec_alloc (local_variables_to_volatilize, 8);
   2351 
   2352       vec_safe_push (local_variables_to_volatilize, decl);
   2353     }
   2354 }
   2355 
   2356 /* Called when parsing of a function completes; if any local variables
   2357    in the function were marked as variables to volatilize, change them
   2358    to volatile.  We do this at the end of the function when the
   2359    warnings about discarding 'volatile' have already been produced.
   2360    We are making the variables as volatile just to force the compiler
   2361    to preserve them between setjmp/longjmp, but we don't want warnings
   2362    for them as they aren't really volatile.  */
   2363 void
   2364 objc_finish_function (void)
   2365 {
   2366   /* If there are any local variables to volatilize, volatilize them.  */
   2367   if (local_variables_to_volatilize)
   2368     {
   2369       int i;
   2370       tree decl;
   2371       FOR_EACH_VEC_ELT (*local_variables_to_volatilize, i, decl)
   2372 	{
   2373 	  tree t = TREE_TYPE (decl);
   2374 
   2375 	  t = build_qualified_type (t, TYPE_QUALS (t) | TYPE_QUAL_VOLATILE);
   2376 	  TREE_TYPE (decl) = t;
   2377 	  TREE_THIS_VOLATILE (decl) = 1;
   2378 	  TREE_SIDE_EFFECTS (decl) = 1;
   2379 	  DECL_REGISTER (decl) = 0;
   2380 #ifndef OBJCPLUS
   2381 	  C_DECL_REGISTER (decl) = 0;
   2382 #endif
   2383 	}
   2384 
   2385       /* Now we delete the vector.  This sets it to NULL as well.  */
   2386       vec_free (local_variables_to_volatilize);
   2387     }
   2388 }
   2389 
   2390 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
   2391    (including its categories and superclasses) or by object type TYP.
   2392    Issue a warning if PROTO is not adopted anywhere and WARN is set.  */
   2393 
   2394 static bool
   2395 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
   2396 {
   2397   bool class_type = (cls != NULL_TREE);
   2398 
   2399   while (cls)
   2400     {
   2401       tree c;
   2402 
   2403       /* Check protocols adopted by the class and its categories.  */
   2404       for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
   2405 	{
   2406 	  if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
   2407 	    return true;
   2408 	}
   2409 
   2410       /* Repeat for superclasses.  */
   2411       cls = lookup_interface (CLASS_SUPER_NAME (cls));
   2412     }
   2413 
   2414   /* Check for any protocols attached directly to the object type.  */
   2415   if (TYPE_HAS_OBJC_INFO (typ))
   2416     {
   2417       if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
   2418 	return true;
   2419     }
   2420 
   2421   if (warn)
   2422     {
   2423       *errbuf = 0;
   2424       gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
   2425       /* NB: Types 'id' and 'Class' cannot reasonably be described as
   2426 	 "implementing" a given protocol, since they do not have an
   2427 	 implementation.  */
   2428       if (class_type)
   2429 	warning (0, "class %qs does not implement the %qE protocol",
   2430 		 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
   2431       else
   2432 	warning (0, "type %qs does not conform to the %qE protocol",
   2433 		 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
   2434     }
   2435 
   2436   return false;
   2437 }
   2438 
   2439 /* Check if class RCLS and instance struct type RTYP conform to at least the
   2440    same protocols that LCLS and LTYP conform to.  */
   2441 
   2442 static bool
   2443 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
   2444 {
   2445   tree p;
   2446   bool have_lproto = false;
   2447 
   2448   while (lcls)
   2449     {
   2450       /* NB: We do _not_ look at categories defined for LCLS; these may or
   2451 	 may not get loaded in, and therefore it is unreasonable to require
   2452 	 that RCLS/RTYP must implement any of their protocols.  */
   2453       for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
   2454 	{
   2455 	  have_lproto = true;
   2456 
   2457 	  if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
   2458 	    return warn;
   2459 	}
   2460 
   2461       /* Repeat for superclasses.  */
   2462       lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
   2463     }
   2464 
   2465   /* Check for any protocols attached directly to the object type.  */
   2466   if (TYPE_HAS_OBJC_INFO (ltyp))
   2467     {
   2468       for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
   2469 	{
   2470 	  have_lproto = true;
   2471 
   2472 	  if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
   2473 	    return warn;
   2474 	}
   2475     }
   2476 
   2477   /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
   2478      vacuously, _unless_ RTYP is a protocol-qualified 'id'.  We can get
   2479      away with simply checking for 'id' or 'Class' (!RCLS), since this
   2480      routine will not get called in other cases.  */
   2481   return have_lproto || (rcls != NULL_TREE);
   2482 }
   2483 
   2484 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
   2485    Both TYPE1 and TYPE2 must be pointers, and already determined to be
   2486    compatible by objc_compare_types() below.  */
   2487 
   2488 tree
   2489 objc_common_type (tree type1, tree type2)
   2490 {
   2491   tree inner1 = TREE_TYPE (type1), inner2 = TREE_TYPE (type2);
   2492 
   2493   while (POINTER_TYPE_P (inner1))
   2494     {
   2495       inner1 = TREE_TYPE (inner1);
   2496       inner2 = TREE_TYPE (inner2);
   2497     }
   2498 
   2499   /* If one type is derived from another, return the base type.  */
   2500   if (DERIVED_FROM_P (inner1, inner2))
   2501     return type1;
   2502   else if (DERIVED_FROM_P (inner2, inner1))
   2503     return type2;
   2504 
   2505   /* If both types are 'Class', return 'Class'.  */
   2506   if (objc_is_class_id (inner1) && objc_is_class_id (inner2))
   2507     return objc_class_type;
   2508 
   2509   /* Otherwise, return 'id'.  */
   2510   return objc_object_type;
   2511 }
   2512 
   2513 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
   2514    an instance of RTYP to an instance of LTYP or to compare the two
   2515    (if ARGNO is equal to -3), per ObjC type system rules.  Before
   2516    returning 'true', this routine may issue warnings related to, e.g.,
   2517    protocol conformance.  When returning 'false', the routine must
   2518    produce absolutely no warnings; the C or C++ front-end will do so
   2519    instead, if needed.  If either LTYP or RTYP is not an Objective-C
   2520    type, the routine must return 'false'.
   2521 
   2522    The ARGNO parameter is encoded as follows:
   2523      >= 1	Parameter number (CALLEE contains function being called);
   2524      0		Return value;
   2525      -1		Assignment;
   2526      -2		Initialization;
   2527      -3		Comparison (LTYP and RTYP may match in either direction);
   2528      -4		Silent comparison (for C++ overload resolution);
   2529      -5		Silent "specialization" comparison for RTYP to be a "specialization"
   2530                 of LTYP (a specialization means that RTYP is LTYP plus some constraints,
   2531                 so that each object of type RTYP is also of type LTYP).  This is used
   2532                 when comparing property types.  */
   2533 
   2534 bool
   2535 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
   2536 {
   2537   tree lcls, rcls, lproto, rproto;
   2538   bool pointers_compatible;
   2539 
   2540   /* We must be dealing with pointer types */
   2541   if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
   2542     return false;
   2543 
   2544   tree ltyp_attr, rtyp_attr;
   2545   do
   2546     {
   2547       /* Remove indirections, but keep the type attributes from the innermost
   2548 	 pointer type, to check for NSObject.  */
   2549       ltyp_attr = TYPE_ATTRIBUTES (ltyp);
   2550       ltyp = TREE_TYPE (ltyp);
   2551       rtyp_attr = TYPE_ATTRIBUTES (rtyp);
   2552       rtyp = TREE_TYPE (rtyp);
   2553     }
   2554   while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
   2555 
   2556   /* We must also handle function pointers, since ObjC is a bit more
   2557      lenient than C or C++ on this.  */
   2558   if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
   2559     {
   2560       function_args_iterator liter, riter;
   2561 
   2562       /* Return types must be covariant.  */
   2563       if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
   2564 	  && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
   2565 				  argno, callee))
   2566       return false;
   2567 
   2568       /* Argument types must be contravariant.  */
   2569       function_args_iter_init (&liter, ltyp);
   2570       function_args_iter_init (&riter, rtyp);
   2571 
   2572       while (1)
   2573 	{
   2574 	  ltyp = function_args_iter_cond (&liter);
   2575 	  rtyp = function_args_iter_cond (&riter);
   2576 
   2577 	  /* If we've exhaused both lists simulateously, we're done.  */
   2578 	  if (ltyp == NULL_TREE && rtyp == NULL_TREE)
   2579 	    break;
   2580 
   2581 	  /* If one list is shorter than the other, they fail to match.  */
   2582 	  if (ltyp == NULL_TREE || rtyp == NULL_TREE)
   2583 	    return false;
   2584 
   2585 	  if (!comptypes (rtyp, ltyp)
   2586 	      && !objc_compare_types (rtyp, ltyp, argno, callee))
   2587 	    return false;
   2588 
   2589 	  function_args_iter_next (&liter);
   2590 	  function_args_iter_next (&riter);
   2591 	}
   2592 
   2593       return true;
   2594     }
   2595 
   2596   /* We might have void * with NSObject type attr.  */
   2597   bool l_NSObject_p = ltyp_attr && lookup_attribute ("NSObject", ltyp_attr);
   2598   bool r_NSObject_p = rtyp_attr && lookup_attribute ("NSObject", rtyp_attr);
   2599 
   2600   /* Past this point, we are only interested in ObjC class instances,
   2601      or 'id' or 'Class' (except if the user applied the NSObject type
   2602      attribute).  */
   2603   if ((TREE_CODE (ltyp) != RECORD_TYPE && !l_NSObject_p)
   2604       || (TREE_CODE (rtyp) != RECORD_TYPE && !r_NSObject_p))
   2605     return false;
   2606 
   2607   if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
   2608       && !TYPE_HAS_OBJC_INFO (ltyp) && !l_NSObject_p)
   2609     return false;
   2610 
   2611   if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
   2612       && !TYPE_HAS_OBJC_INFO (rtyp) && !r_NSObject_p)
   2613     return false;
   2614 
   2615   /* Past this point, we are committed to returning 'true' to the caller
   2616      (unless performing a silent comparison; see below).  However, we can
   2617      still warn about type and/or protocol mismatches.  */
   2618 
   2619   if (TYPE_HAS_OBJC_INFO (ltyp))
   2620     {
   2621       lcls = TYPE_OBJC_INTERFACE (ltyp);
   2622       lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
   2623     }
   2624   else
   2625     lcls = lproto = NULL_TREE;
   2626 
   2627   if (TYPE_HAS_OBJC_INFO (rtyp))
   2628     {
   2629       rcls = TYPE_OBJC_INTERFACE (rtyp);
   2630       rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
   2631     }
   2632   else
   2633     rcls = rproto = NULL_TREE;
   2634 
   2635   /* If we could not find an @interface declaration, we must have
   2636      only seen a @class declaration; for purposes of type comparison,
   2637      treat it as a stand-alone (root) class.  */
   2638 
   2639   if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
   2640     lcls = NULL_TREE;
   2641 
   2642   if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
   2643     rcls = NULL_TREE;
   2644 
   2645   /* If either type is an unqualified 'id', we're done.  This is because
   2646      an 'id' can be assigned to or from any type with no warnings.  When
   2647      the pointer has NSObject attribute, consider that to be equivalent.  */
   2648   if (argno != -5)
   2649     {
   2650       if ((!lproto && objc_is_object_id (ltyp))
   2651 	  || (!rproto && objc_is_object_id (rtyp)))
   2652 	return true;
   2653       if (l_NSObject_p || r_NSObject_p)
   2654 	return true;
   2655     }
   2656   else
   2657     {
   2658       /* For property checks, though, an 'id' is considered the most
   2659 	 general type of object, hence if you try to specialize an
   2660 	 'NSArray *' (ltyp) property with an 'id' (rtyp) one, we need
   2661 	 to warn.  */
   2662       if (!lproto && (objc_is_object_id (ltyp) || l_NSObject_p))
   2663 	return true;
   2664     }
   2665 
   2666   pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
   2667 
   2668   /* If the underlying types are the same, and at most one of them has
   2669      a protocol list, we do not need to issue any diagnostics.  */
   2670   if (pointers_compatible && (!lproto || !rproto))
   2671     return true;
   2672 
   2673   /* If exactly one of the types is 'Class', issue a diagnostic; any
   2674      exceptions of this rule have already been handled.  */
   2675   if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
   2676     pointers_compatible = false;
   2677   /* Otherwise, check for inheritance relations.  */
   2678   else
   2679     {
   2680       if (!pointers_compatible)
   2681 	{
   2682 	  /* Again, if any of the two is an 'id', we're satisfied,
   2683 	     unless we're comparing properties, in which case only an
   2684 	     'id' on the left-hand side (old property) is good
   2685 	     enough.  */
   2686 	  if (argno != -5)
   2687 	    pointers_compatible
   2688 	      = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
   2689 	  else
   2690 	    pointers_compatible = objc_is_object_id (ltyp);
   2691 	}
   2692 
   2693       if (!pointers_compatible)
   2694 	pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
   2695 
   2696       if (!pointers_compatible && (argno == -3 || argno == -4))
   2697 	pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
   2698     }
   2699 
   2700   /* If the pointers match modulo protocols, check for protocol conformance
   2701      mismatches.  */
   2702   if (pointers_compatible)
   2703     {
   2704       pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
   2705 						    argno != -3);
   2706 
   2707       if (!pointers_compatible && argno == -3)
   2708 	pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
   2709 						      argno != -3);
   2710     }
   2711 
   2712   if (!pointers_compatible)
   2713     {
   2714       /* The two pointers are not exactly compatible.  Issue a warning, unless
   2715 	 we are performing a silent comparison, in which case return 'false'
   2716 	 instead.  */
   2717       /* NB: For the time being, we shall make our warnings look like their
   2718 	 C counterparts.  In the future, we may wish to make them more
   2719 	 ObjC-specific.  */
   2720       switch (argno)
   2721 	{
   2722 	case -5:
   2723 	case -4:
   2724 	  return false;
   2725 
   2726 	case -3:
   2727 	  warning (0, "comparison of distinct Objective-C types lacks a cast");
   2728 	  break;
   2729 
   2730 	case -2:
   2731 	  warning (0, "initialization from distinct Objective-C type");
   2732 	  break;
   2733 
   2734 	case -1:
   2735 	  warning (0, "assignment from distinct Objective-C type");
   2736 	  break;
   2737 
   2738 	case 0:
   2739 	  warning (0, "distinct Objective-C type in return");
   2740 	  break;
   2741 
   2742 	default:
   2743 	  warning (0, "passing argument %d of %qE from distinct "
   2744 		   "Objective-C type", argno, callee);
   2745 	  break;
   2746 	}
   2747     }
   2748 
   2749   return true;
   2750 }
   2751 
   2752 /* This routine is similar to objc_compare_types except that function-pointers are
   2753    excluded. This is because, caller assumes that common types are of (id, Object*)
   2754    variety and calls objc_common_type to obtain a common type. There is no commonolty
   2755    between two function-pointers in this regard. */
   2756 
   2757 bool
   2758 objc_have_common_type (tree ltyp, tree rtyp, int argno, tree callee)
   2759 {
   2760   if (objc_compare_types (ltyp, rtyp, argno, callee))
   2761     {
   2762       /* exclude function-pointer types. */
   2763       do
   2764         {
   2765           ltyp = TREE_TYPE (ltyp);  /* Remove indirections.  */
   2766           rtyp = TREE_TYPE (rtyp);
   2767         }
   2768       while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
   2769       return !(TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE);
   2770     }
   2771   return false;
   2772 }
   2773 
   2774 #ifndef OBJCPLUS
   2775 /* Determine if CHILD is derived from PARENT.  The routine assumes that
   2776    both parameters are RECORD_TYPEs, and is non-reflexive.  */
   2777 
   2778 static bool
   2779 objc_derived_from_p (tree parent, tree child)
   2780 {
   2781   parent = TYPE_MAIN_VARIANT (parent);
   2782 
   2783   for (child = TYPE_MAIN_VARIANT (child);
   2784        TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
   2785     {
   2786       child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
   2787 					     (TYPE_BINFO (child),
   2788 					      0)));
   2789 
   2790       if (child == parent)
   2791 	return true;
   2792     }
   2793 
   2794   return false;
   2795 }
   2796 #endif
   2797 
   2798 tree
   2799 objc_build_component_ref (tree datum, tree component)
   2800 {
   2801   /* If COMPONENT is NULL, the caller is referring to the anonymous
   2802      base class field.  */
   2803   if (!component)
   2804     {
   2805       tree base = TYPE_FIELDS (TREE_TYPE (datum));
   2806 
   2807       return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
   2808     }
   2809 
   2810   /* The 'build_component_ref' routine has been removed from the C++
   2811      front-end, but 'finish_class_member_access_expr' seems to be
   2812      a worthy substitute.  */
   2813 #ifdef OBJCPLUS
   2814   return finish_class_member_access_expr (datum, component, false,
   2815                                           tf_warning_or_error);
   2816 #else
   2817   return build_component_ref (input_location, datum, component,
   2818 			      UNKNOWN_LOCATION);
   2819 #endif
   2820 }
   2821 
   2822 /* Recursively copy inheritance information rooted at BINFO.  To do this,
   2823    we emulate the song and dance performed by cp/tree.cc:copy_binfo().  */
   2824 
   2825 static tree
   2826 objc_copy_binfo (tree binfo)
   2827 {
   2828   tree btype = BINFO_TYPE (binfo);
   2829   tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
   2830   tree base_binfo;
   2831   int ix;
   2832 
   2833   BINFO_TYPE (binfo2) = btype;
   2834   BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
   2835   BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
   2836 
   2837   /* Recursively copy base binfos of BINFO.  */
   2838   for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
   2839     {
   2840       tree base_binfo2 = objc_copy_binfo (base_binfo);
   2841 
   2842       BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
   2843       BINFO_BASE_APPEND (binfo2, base_binfo2);
   2844     }
   2845 
   2846   return binfo2;
   2847 }
   2848 
   2849 /* Record superclass information provided in BASETYPE for ObjC class REF.
   2850    This is loosely based on cp/decl.cc:xref_basetypes().  */
   2851 
   2852 static void
   2853 objc_xref_basetypes (tree ref, tree basetype)
   2854 {
   2855   tree variant;
   2856   tree binfo = make_tree_binfo (basetype ? 1 : 0);
   2857   TYPE_BINFO (ref) = binfo;
   2858   BINFO_OFFSET (binfo) = size_zero_node;
   2859   BINFO_TYPE (binfo) = ref;
   2860 
   2861   gcc_assert (TYPE_MAIN_VARIANT (ref) == ref);
   2862   for (variant = ref; variant; variant = TYPE_NEXT_VARIANT (variant))
   2863     TYPE_BINFO (variant) = binfo;
   2864 
   2865   if (basetype)
   2866     {
   2867       tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
   2868 
   2869       BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
   2870       vec_alloc (BINFO_BASE_ACCESSES (binfo), 1);
   2871       BINFO_BASE_APPEND (binfo, base_binfo);
   2872       BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
   2873     }
   2874 }
   2875 
   2876 /* Called from finish_decl.  */
   2877 
   2878 void
   2879 objc_check_decl (tree decl)
   2880 {
   2881   tree type = TREE_TYPE (decl);
   2882 
   2883   if (TREE_CODE (type) != RECORD_TYPE)
   2884     return;
   2885   if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
   2886     error ("statically allocated instance of Objective-C class %qE",
   2887 	   type);
   2888 }
   2889 
   2890 void
   2891 objc_check_global_decl (tree decl)
   2892 {
   2893   tree id = DECL_NAME (decl);
   2894   if (objc_is_class_name (id) && global_bindings_p())
   2895     error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
   2896 }
   2897 
   2898 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where
   2899    INTERFACE may either name an Objective-C class, or refer to the
   2900    special 'id' or 'Class' types.  If INTERFACE is not a valid ObjC
   2901    type, just return it unchanged.  This function is often called when
   2902    PROTOCOLS is NULL_TREE, in which case we simply look up the
   2903    appropriate INTERFACE.  */
   2904 
   2905 tree
   2906 objc_get_protocol_qualified_type (tree interface, tree protocols)
   2907 {
   2908   /* If INTERFACE is not provided, default to 'id'.  */
   2909   tree type = (interface ? objc_is_id (interface) : objc_object_type);
   2910   bool is_ptr = (type != NULL_TREE);
   2911 
   2912   if (!is_ptr)
   2913     {
   2914       type = objc_is_class_name (interface);
   2915 
   2916       if (type)
   2917 	{
   2918 	  /* If looking at a typedef, retrieve the precise type it
   2919 	     describes.  */
   2920 	  if (TREE_CODE (interface) == IDENTIFIER_NODE)
   2921 	    interface = identifier_global_value (interface);
   2922 
   2923 	  type = ((interface && TREE_CODE (interface) == TYPE_DECL
   2924 		   && DECL_ORIGINAL_TYPE (interface))
   2925 		  ? DECL_ORIGINAL_TYPE (interface)
   2926 		  : xref_tag (RECORD_TYPE, type));
   2927 	}
   2928       else
   2929 	{
   2930 	  /* This case happens when we are given an 'interface' which
   2931 	     is not a valid class name.  For example if a typedef was
   2932 	     used, and 'interface' really is the identifier of the
   2933 	     typedef, but when you resolve it you don't get an
   2934 	     Objective-C class, but something else, such as 'int'.
   2935 	     This is an error; protocols make no sense unless you use
   2936 	     them with Objective-C objects.  */
   2937 	  error_at (input_location, "only Objective-C object types can be qualified with a protocol");
   2938 
   2939 	  /* Try to recover.  Ignore the invalid class name, and treat
   2940 	     the object as an 'id' to silence further warnings about
   2941 	     the class.  */
   2942 	  type = objc_object_type;
   2943 	  is_ptr = true;
   2944 	}
   2945     }
   2946 
   2947   if (protocols)
   2948     {
   2949       type = build_variant_type_copy (type);
   2950 
   2951       /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
   2952 	 to the pointee.  */
   2953       if (is_ptr)
   2954 	{
   2955 	  tree orig_pointee_type = TREE_TYPE (type);
   2956 	  TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
   2957 
   2958 	  /* Set up the canonical type information. */
   2959 	  TYPE_CANONICAL (type)
   2960 	    = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
   2961 
   2962 	  TYPE_POINTER_TO (TREE_TYPE (type)) = type;
   2963 	  type = TREE_TYPE (type);
   2964 	}
   2965 
   2966       /* Look up protocols and install in lang specific list.  */
   2967       DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
   2968       TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols
   2969 	(protocols, /* definition_required */ false);
   2970 
   2971       /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
   2972 	 return the pointer to the new pointee variant.  */
   2973       if (is_ptr)
   2974 	type = TYPE_POINTER_TO (type);
   2975       else
   2976 	TYPE_OBJC_INTERFACE (type)
   2977 	  = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
   2978     }
   2979 
   2980   return type;
   2981 }
   2982 
   2983 /* Check for circular dependencies in protocols.  The arguments are
   2984    PROTO, the protocol to check, and LIST, a list of protocol it
   2985    conforms to.  */
   2986 
   2987 static void
   2988 check_protocol_recursively (tree proto, tree list)
   2989 {
   2990   tree p;
   2991 
   2992   for (p = list; p; p = TREE_CHAIN (p))
   2993     {
   2994       tree pp = TREE_VALUE (p);
   2995 
   2996       if (TREE_CODE (pp) == IDENTIFIER_NODE)
   2997 	pp = lookup_protocol (pp, /* warn if deprecated */ false,
   2998 			      /* definition_required */ false);
   2999 
   3000       if (pp == proto)
   3001 	fatal_error (input_location, "protocol %qE has circular dependency",
   3002 		     PROTOCOL_NAME (pp));
   3003       if (pp)
   3004 	check_protocol_recursively (proto, PROTOCOL_LIST (pp));
   3005     }
   3006 }
   3007 
   3008 /* Look up PROTOCOLS, and return a list of those that are found.  If
   3009    none are found, return NULL.  Note that this function will emit a
   3010    warning if a protocol is found and is deprecated.  If
   3011    'definition_required', then warn if the protocol is found but is
   3012    not defined (ie, if we only saw a forward-declaration of the
   3013    protocol (as in "@protocol NSObject;") not a real definition with
   3014    the list of methods).  */
   3015 static tree
   3016 lookup_and_install_protocols (tree protocols, bool definition_required)
   3017 {
   3018   tree proto;
   3019   tree return_value = NULL_TREE;
   3020 
   3021   if (protocols == error_mark_node)
   3022     return NULL;
   3023 
   3024   for (proto = protocols; proto; proto = TREE_CHAIN (proto))
   3025     {
   3026       tree ident = TREE_VALUE (proto);
   3027       tree p = lookup_protocol (ident, /* warn_if_deprecated */ true,
   3028 				definition_required);
   3029 
   3030       if (p)
   3031 	return_value = chainon (return_value,
   3032 				build_tree_list (NULL_TREE, p));
   3033       else if (ident != error_mark_node)
   3034 	error ("cannot find protocol declaration for %qE",
   3035 	       ident);
   3036     }
   3037 
   3038   return return_value;
   3039 }
   3040 
   3041 static void
   3042 build_common_objc_exception_stuff (void)
   3043 {
   3044   tree noreturn_list, nothrow_list, temp_type;
   3045 
   3046   noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
   3047   nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
   3048 
   3049   /* void objc_exception_throw(id) __attribute__((noreturn)); */
   3050   /* void objc_sync_enter(id); */
   3051   /* void objc_sync_exit(id); */
   3052   temp_type = build_function_type_list (void_type_node,
   3053                                         objc_object_type,
   3054                                         NULL_TREE);
   3055   objc_exception_throw_decl
   3056     = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
   3057 			    noreturn_list);
   3058   /* Make sure that objc_exception_throw (id) claims that it may throw an
   3059      exception. */
   3060   TREE_NOTHROW (objc_exception_throw_decl) = 0;
   3061 
   3062   objc_sync_enter_decl
   3063     = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
   3064 			    NULL, nothrow_list);
   3065 
   3066   objc_sync_exit_decl
   3067     = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
   3068 			    NULL, nothrow_list);
   3069 }
   3070 
   3071 /* Purpose: "play" parser, creating/installing representations
   3072    of the declarations that are required by Objective-C.
   3073 
   3074    Model:
   3075 
   3076 	type_spec--------->sc_spec
   3077 	(tree_list)        (tree_list)
   3078 	    |                  |
   3079 	    |                  |
   3080 	identifier_node    identifier_node  */
   3081 
   3082 static void
   3083 synth_module_prologue (void)
   3084 {
   3085   tree type;
   3086   uint32_t save_write_symbols = write_symbols;
   3087   const struct gcc_debug_hooks *const save_hooks = debug_hooks;
   3088 
   3089   /* Suppress outputting debug symbols, because
   3090      dbxout_init hasn't been called yet.  */
   3091   write_symbols = NO_DEBUG;
   3092   debug_hooks = &do_nothing_debug_hooks;
   3093 
   3094 #ifdef OBJCPLUS
   3095   push_lang_context (lang_name_c); /* extern "C" */
   3096 #endif
   3097 
   3098   /* The following are also defined in <objc/objc.h> and friends.  */
   3099 
   3100   objc_object_id = get_identifier (TAG_OBJECT);
   3101   objc_class_id = get_identifier (TAG_CLASS);
   3102 
   3103   objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
   3104   objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
   3105 
   3106   objc_object_type = build_pointer_type (objc_object_reference);
   3107   objc_instancetype_type = build_pointer_type (objc_object_reference);
   3108   objc_class_type = build_pointer_type (objc_class_reference);
   3109 
   3110   objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
   3111   objc_instancetype_name = get_identifier (INSTANCE_TYPEDEF_NAME);
   3112   objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
   3113   objc_selector_name = get_identifier (SEL_TYPEDEF_NAME);
   3114 
   3115   /* Declare the 'id', 'instancetype' and 'Class' typedefs.  */
   3116   type = lang_hooks.decls.pushdecl (build_decl (input_location,
   3117 						TYPE_DECL,
   3118 						objc_object_name,
   3119 						objc_object_type));
   3120   suppress_warning (type);
   3121 
   3122   type = lang_hooks.decls.pushdecl (build_decl (input_location,
   3123 						TYPE_DECL,
   3124 						objc_instancetype_name,
   3125 						objc_instancetype_type));
   3126   suppress_warning (type);
   3127 
   3128   type = lang_hooks.decls.pushdecl (build_decl (input_location,
   3129 						TYPE_DECL,
   3130 						objc_class_name,
   3131 						objc_class_type));
   3132   suppress_warning (type);
   3133 
   3134   /* Forward-declare '@interface Protocol'.  */
   3135   type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
   3136   objc_declare_class (type);
   3137   objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE, type));
   3138 
   3139   /* Declare receiver type used for dispatching messages to 'super'.  */
   3140   /* `struct objc_super *' */
   3141   objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
   3142 						  get_identifier (TAG_SUPER)));
   3143 
   3144   /* Declare pointers to method and ivar lists.  */
   3145   objc_method_list_ptr = build_pointer_type
   3146 			 (xref_tag (RECORD_TYPE,
   3147 				    get_identifier (UTAG_METHOD_LIST)));
   3148   objc_method_proto_list_ptr
   3149     = build_pointer_type (xref_tag (RECORD_TYPE,
   3150 				    get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
   3151   objc_ivar_list_ptr = build_pointer_type
   3152 		       (xref_tag (RECORD_TYPE,
   3153 				  get_identifier (UTAG_IVAR_LIST)));
   3154 
   3155   build_common_objc_exception_stuff ();
   3156 
   3157   /* Set-up runtime-specific templates, message and exception stuff.  */
   3158   (*runtime.initialize) ();
   3159 
   3160   /* Declare objc_getProperty, object_setProperty and other property
   3161      accessor helpers.  */
   3162   build_common_objc_property_accessor_helpers ();
   3163 
   3164   /* Forward declare constant_string_id and constant_string_type.  */
   3165   if (!constant_string_class_name)
   3166     constant_string_class_name = runtime.default_constant_string_class_name;
   3167   constant_string_id = get_identifier (constant_string_class_name);
   3168   objc_declare_class (constant_string_id);
   3169 
   3170   /* Pre-build the following entities - for speed/convenience.  */
   3171   self_id = get_identifier ("self");
   3172   ucmd_id = get_identifier ("_cmd");
   3173 
   3174   /* Declare struct _objc_fast_enumeration_state { ... };  */
   3175   build_fast_enumeration_state_template ();
   3176 
   3177   /* void objc_enumeration_mutation (id) */
   3178   type = build_function_type_list (void_type_node,
   3179 				   objc_object_type, NULL_TREE);
   3180   objc_enumeration_mutation_decl
   3181     = add_builtin_function (TAG_ENUMERATION_MUTATION, type, 0, NOT_BUILT_IN,
   3182 			    NULL, NULL_TREE);
   3183   TREE_NOTHROW (objc_enumeration_mutation_decl) = 0;
   3184 
   3185 #ifdef OBJCPLUS
   3186   pop_lang_context ();
   3187 #endif
   3188 
   3189   write_symbols = save_write_symbols;
   3190   debug_hooks = save_hooks;
   3191 }
   3192 
   3193 /* --- const strings --- */
   3194 
   3195 /* Ensure that the ivar list for NSConstantString/NXConstantString
   3196    (or whatever was specified via `-fconstant-string-class')
   3197    contains fields at least as large as the following three, so that
   3198    the runtime can stomp on them with confidence:
   3199 
   3200    struct STRING_OBJECT_CLASS_NAME
   3201    {
   3202      Object isa;
   3203      char *cString;
   3204      unsigned int length;
   3205    }; */
   3206 
   3207 static int
   3208 check_string_class_template (void)
   3209 {
   3210   tree field_decl = objc_get_class_ivars (constant_string_id);
   3211 
   3212 #define AT_LEAST_AS_LARGE_AS(F, T) \
   3213   (F && TREE_CODE (F) == FIELD_DECL \
   3214      && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
   3215 	 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
   3216 
   3217   if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
   3218     return 0;
   3219 
   3220   field_decl = DECL_CHAIN (field_decl);
   3221   if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
   3222     return 0;
   3223 
   3224   field_decl = DECL_CHAIN (field_decl);
   3225   return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
   3226 
   3227 #undef AT_LEAST_AS_LARGE_AS
   3228 }
   3229 
   3230 /* Avoid calling `check_string_class_template ()' more than once.  */
   3231 static GTY(()) int string_layout_checked;
   3232 
   3233 /* Construct an internal string layout to be used as a template for
   3234    creating NSConstantString/NXConstantString instances.  */
   3235 
   3236 static tree
   3237 objc_build_internal_const_str_type (void)
   3238 {
   3239   tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
   3240   tree fields = build_decl (input_location,
   3241 			    FIELD_DECL, NULL_TREE, ptr_type_node);
   3242   tree field = build_decl (input_location,
   3243 			   FIELD_DECL, NULL_TREE, ptr_type_node);
   3244 
   3245   DECL_CHAIN (field) = fields; fields = field;
   3246   field = build_decl (input_location,
   3247 		      FIELD_DECL, NULL_TREE, unsigned_type_node);
   3248   DECL_CHAIN (field) = fields; fields = field;
   3249   /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
   3250      reverse order!  */
   3251   finish_builtin_struct (type, "__builtin_ObjCString",
   3252 			 fields, NULL_TREE);
   3253 
   3254   return type;
   3255 }
   3256 
   3257 /* Custom build_string which sets TREE_TYPE!  */
   3258 
   3259 tree
   3260 my_build_string (int len, const char *str)
   3261 {
   3262   return fix_string_type (build_string (len, str));
   3263 }
   3264 
   3265 /* Build a string with contents STR and length LEN and convert it to a
   3266    pointer.  */
   3267 
   3268 tree
   3269 my_build_string_pointer (int len, const char *str)
   3270 {
   3271   tree string = my_build_string (len, str);
   3272   tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
   3273   return build1 (ADDR_EXPR, ptrtype, string);
   3274 }
   3275 
   3276 hashval_t
   3277 objc_string_hasher::hash (string_descriptor *ptr)
   3278 {
   3279   const_tree const str = ptr->literal;
   3280   const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
   3281   int i, len = TREE_STRING_LENGTH (str);
   3282   hashval_t h = len;
   3283 
   3284   for (i = 0; i < len; i++)
   3285     h = ((h * 613) + p[i]);
   3286 
   3287   return h;
   3288 }
   3289 
   3290 bool
   3291 objc_string_hasher::equal (string_descriptor *ptr1, string_descriptor *ptr2)
   3292 {
   3293   const_tree const str1 = ptr1->literal;
   3294   const_tree const str2 = ptr2->literal;
   3295   int len1 = TREE_STRING_LENGTH (str1);
   3296 
   3297   return (len1 == TREE_STRING_LENGTH (str2)
   3298 	  && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
   3299 		      len1));
   3300 }
   3301 
   3302 /* Given a chain of STRING_CST's, build a static instance of
   3303    NXConstantString which points at the concatenation of those
   3304    strings.  We place the string object in the __string_objects
   3305    section of the __OBJC segment.  The Objective-C runtime will
   3306    initialize the isa pointers of the string objects to point at the
   3307    NXConstantString class object.  */
   3308 
   3309 tree
   3310 objc_build_string_object (tree string)
   3311 {
   3312   tree constant_string_class;
   3313   int length;
   3314   tree addr;
   3315   struct string_descriptor *desc, key;
   3316 
   3317   /* We should be passed a STRING_CST.  */
   3318   gcc_checking_assert (TREE_CODE (string) == STRING_CST);
   3319   length = TREE_STRING_LENGTH (string) - 1;
   3320 
   3321   /* The target may have different ideas on how to construct an ObjC string
   3322      literal.  On Darwin (Mac OS X), for example, we may wish to obtain a
   3323      constant CFString reference instead.
   3324      At present, this is only supported for the NeXT runtime.  */
   3325   if (flag_next_runtime
   3326       && targetcm.objc_construct_string_object)
   3327     {
   3328       tree constructor = (*targetcm.objc_construct_string_object) (string);
   3329       if (constructor)
   3330 	return build1 (NOP_EXPR, objc_object_type, constructor);
   3331     }
   3332 
   3333   /* Check whether the string class being used actually exists and has the
   3334      correct ivar layout.  */
   3335   if (!string_layout_checked)
   3336     {
   3337       string_layout_checked = -1;
   3338       constant_string_class = lookup_interface (constant_string_id);
   3339       internal_const_str_type = objc_build_internal_const_str_type ();
   3340 
   3341       if (!constant_string_class
   3342 	  || !(constant_string_type
   3343 	       = CLASS_STATIC_TEMPLATE (constant_string_class)))
   3344 	error ("cannot find interface declaration for %qE",
   3345 	       constant_string_id);
   3346       /* The NSConstantString/NXConstantString ivar layout is now known.  */
   3347       else if (!check_string_class_template ())
   3348 	error ("interface %qE does not have valid constant string layout",
   3349 	       constant_string_id);
   3350       /* If the runtime can generate a literal reference to the string class,
   3351 	 don't need to run a constructor.  */
   3352       else if (!(*runtime.setup_const_string_class_decl)())
   3353 	error ("cannot find reference tag for class %qE", constant_string_id);
   3354       else
   3355 	{
   3356 	  string_layout_checked = 1;  /* Success!  */
   3357 	  add_class_reference (constant_string_id);
   3358 	}
   3359     }
   3360 
   3361   if (string_layout_checked == -1)
   3362     return error_mark_node;
   3363 
   3364   /* Perhaps we already constructed a constant string just like this one? */
   3365   key.literal = string;
   3366   string_descriptor **loc = string_htab->find_slot (&key, INSERT);
   3367   desc = *loc;
   3368 
   3369   if (!desc)
   3370     {
   3371       *loc = desc = ggc_alloc<string_descriptor> ();
   3372       desc->literal = string;
   3373       desc->constructor =
   3374 	(*runtime.build_const_string_constructor) (input_location, string, length);
   3375     }
   3376 
   3377   addr = convert (build_pointer_type (constant_string_type),
   3378 		  build_unary_op (input_location,
   3379 				  ADDR_EXPR, desc->constructor, 1));
   3380 
   3381   return addr;
   3382 }
   3383 
   3384 /* Build a static constant CONSTRUCTOR with type TYPE and elements ELTS.
   3385    We might be presented with a NULL for ELTS, which means 'empty ctor'
   3386    which will subsequently be converted into a zero initializer in the
   3387    middle end.  */
   3388 
   3389 tree
   3390 objc_build_constructor (tree type, vec<constructor_elt, va_gc> *elts)
   3391 {
   3392   tree constructor = build_constructor (type, elts);
   3393 
   3394   TREE_CONSTANT (constructor) = 1;
   3395   TREE_STATIC (constructor) = 1;
   3396   TREE_READONLY (constructor) = 1;
   3397 
   3398 #ifdef OBJCPLUS
   3399   /* If we know the initializer, then set the type to what C++ expects.  */
   3400   if (elts && !(*elts)[0].index)
   3401     TREE_TYPE (constructor) = init_list_type_node;
   3402 #endif
   3403   return constructor;
   3404 }
   3405 
   3406 /* Return the DECL of the string IDENT in the SECTION.  */
   3407 
   3408 tree
   3409 get_objc_string_decl (tree ident, enum string_section section)
   3410 {
   3411   tree chain;
   3412 
   3413   switch (section)
   3414     {
   3415     case class_names:
   3416       chain = class_names_chain;
   3417       break;
   3418     case meth_var_names:
   3419       chain = meth_var_names_chain;
   3420       break;
   3421     case meth_var_types:
   3422       chain = meth_var_types_chain;
   3423       break;
   3424     case prop_names_attr:
   3425       chain = prop_names_attr_chain;
   3426       break;
   3427     default:
   3428       gcc_unreachable ();
   3429     }
   3430 
   3431   for (; chain != 0; chain = TREE_CHAIN (chain))
   3432     if (TREE_VALUE (chain) == ident)
   3433       return (TREE_PURPOSE (chain));
   3434 
   3435   /* We didn't find the entry.  */
   3436   return NULL_TREE;
   3437 }
   3438 
   3439 /* Create a class reference, but don't create a variable to reference
   3440    it.  */
   3441 
   3442 void
   3443 add_class_reference (tree ident)
   3444 {
   3445   tree chain;
   3446 
   3447   if ((chain = cls_ref_chain))
   3448     {
   3449       tree tail;
   3450       do
   3451         {
   3452 	  if (ident == TREE_VALUE (chain))
   3453 	    return;
   3454 
   3455 	  tail = chain;
   3456 	  chain = TREE_CHAIN (chain);
   3457         }
   3458       while (chain);
   3459 
   3460       /* Append to the end of the list */
   3461       TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
   3462     }
   3463   else
   3464     cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
   3465 }
   3466 
   3467 /* Get a class reference, creating it if necessary.  Also create the
   3468    reference variable.  */
   3469 tree
   3470 objc_get_class_reference (tree ident)
   3471 {
   3472   tree orig_ident = (DECL_P (ident)
   3473 		     ? DECL_NAME (ident)
   3474 		     : TYPE_P (ident)
   3475 		     ? OBJC_TYPE_NAME (ident)
   3476 		     : ident);
   3477   bool local_scope = false;
   3478 
   3479 #ifdef OBJCPLUS
   3480   if (processing_template_decl)
   3481     /* Must wait until template instantiation time.  */
   3482     return build_min_nt_loc (UNKNOWN_LOCATION, CLASS_REFERENCE_EXPR, ident);
   3483 #endif
   3484 
   3485   if (TREE_CODE (ident) == TYPE_DECL)
   3486     ident = (DECL_ORIGINAL_TYPE (ident)
   3487 	     ? DECL_ORIGINAL_TYPE (ident)
   3488 	     : TREE_TYPE (ident));
   3489 
   3490 #ifdef OBJCPLUS
   3491   if (TYPE_P (ident)
   3492       && CP_TYPE_CONTEXT (ident) != global_namespace)
   3493     local_scope = true;
   3494 #endif
   3495 
   3496   if (local_scope || !(ident = objc_is_class_name (ident)))
   3497     {
   3498       error ("%qE is not an Objective-C class name or alias",
   3499 	     orig_ident);
   3500       return error_mark_node;
   3501     }
   3502 
   3503   return (*runtime.get_class_reference) (ident);
   3504 }
   3505 
   3506 void
   3507 objc_declare_alias (tree alias_ident, tree class_ident)
   3508 {
   3509   tree underlying_class;
   3510 
   3511 #ifdef OBJCPLUS
   3512   if (current_namespace != global_namespace) {
   3513     error ("Objective-C declarations may only appear in global scope");
   3514   }
   3515 #endif /* OBJCPLUS */
   3516 
   3517   if (!(underlying_class = objc_is_class_name (class_ident)))
   3518     warning (0, "cannot find class %qE", class_ident);
   3519   else if (objc_is_class_name (alias_ident))
   3520     warning (0, "class %qE already exists", alias_ident);
   3521   else
   3522     {
   3523       /* Implement @compatibility_alias as a typedef.  */
   3524 #ifdef OBJCPLUS
   3525       push_lang_context (lang_name_c); /* extern "C" */
   3526 #endif
   3527       lang_hooks.decls.pushdecl (build_decl
   3528 				 (input_location,
   3529 				  TYPE_DECL,
   3530 				  alias_ident,
   3531 				  xref_tag (RECORD_TYPE, underlying_class)));
   3532 #ifdef OBJCPLUS
   3533       pop_lang_context ();
   3534 #endif
   3535       objc_map_put (alias_name_map, alias_ident, underlying_class);
   3536     }
   3537 }
   3538 
   3539 void
   3540 objc_declare_class (tree identifier)
   3541 {
   3542 #ifdef OBJCPLUS
   3543   if (current_namespace != global_namespace) {
   3544     error ("Objective-C declarations may only appear in global scope");
   3545   }
   3546 #endif /* OBJCPLUS */
   3547 
   3548   if (! objc_is_class_name (identifier))
   3549     {
   3550       tree record = lookup_name (identifier), type = record;
   3551 
   3552       if (record)
   3553 	{
   3554 	  if (TREE_CODE (record) == TYPE_DECL)
   3555 	    type = DECL_ORIGINAL_TYPE (record)
   3556 	      ? DECL_ORIGINAL_TYPE (record)
   3557 	      : TREE_TYPE (record);
   3558 
   3559 	  if (!TYPE_HAS_OBJC_INFO (type)
   3560 	      || !TYPE_OBJC_INTERFACE (type))
   3561 	    {
   3562 	      error ("%qE redeclared as different kind of symbol",
   3563 		     identifier);
   3564 	      error ("previous declaration of %q+D",
   3565 		     record);
   3566 	    }
   3567 	}
   3568 
   3569       record = xref_tag (RECORD_TYPE, identifier);
   3570       INIT_TYPE_OBJC_INFO (record);
   3571       /* In the case of a @class declaration, we store the ident in
   3572 	 the TYPE_OBJC_INTERFACE.  If later an @interface is found,
   3573 	 we'll replace the ident with the interface.  */
   3574       TYPE_OBJC_INTERFACE (record) = identifier;
   3575       objc_map_put (class_name_map, identifier, NULL_TREE);
   3576     }
   3577 }
   3578 
   3579 tree
   3580 objc_is_class_name (tree ident)
   3581 {
   3582   if (ident && TREE_CODE (ident) == IDENTIFIER_NODE)
   3583     {
   3584       tree t = identifier_global_value (ident);
   3585       if (t)
   3586 	ident = t;
   3587     }
   3588 
   3589   while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
   3590     ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
   3591 
   3592   if (ident && TREE_CODE (ident) == RECORD_TYPE)
   3593     ident = OBJC_TYPE_NAME (ident);
   3594 #ifdef OBJCPLUS
   3595   if (ident && TREE_CODE (ident) == TYPE_DECL)
   3596     {
   3597       tree type = TREE_TYPE (ident);
   3598       if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
   3599         return NULL_TREE;
   3600       ident = DECL_NAME (ident);
   3601     }
   3602 #endif
   3603   if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
   3604     return NULL_TREE;
   3605 
   3606   if (lookup_interface (ident))
   3607     return ident;
   3608 
   3609   {
   3610     tree target;
   3611 
   3612     target = objc_map_get (class_name_map, ident);
   3613     if (target != OBJC_MAP_NOT_FOUND)
   3614       return ident;
   3615 
   3616     target = objc_map_get (alias_name_map, ident);
   3617     if (target != OBJC_MAP_NOT_FOUND)
   3618       return target;
   3619   }
   3620 
   3621   return 0;
   3622 }
   3623 
   3624 /* Check whether TYPE is either 'id' or 'Class'.  */
   3625 
   3626 tree
   3627 objc_is_id (tree type)
   3628 {
   3629   if (type && TREE_CODE (type) == IDENTIFIER_NODE)
   3630     {
   3631       tree t = identifier_global_value (type);
   3632       if (t)
   3633 	type = t;
   3634     }
   3635 
   3636   if (type && TREE_CODE (type) == TYPE_DECL)
   3637     type = TREE_TYPE (type);
   3638 
   3639   /* NB: This function may be called before the ObjC front-end has
   3640      been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL.  */
   3641   return (objc_object_type && type
   3642 	  && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
   3643 	  ? type
   3644 	  : NULL_TREE);
   3645 }
   3646 
   3647 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
   3648    class instance.  This is needed by other parts of the compiler to
   3649    handle ObjC types gracefully.  */
   3650 
   3651 tree
   3652 objc_is_object_ptr (tree type)
   3653 {
   3654   tree ret;
   3655 
   3656   type = TYPE_MAIN_VARIANT (type);
   3657   if (!POINTER_TYPE_P (type))
   3658     return 0;
   3659 
   3660   ret = objc_is_id (type);
   3661   if (!ret)
   3662     ret = objc_is_class_name (TREE_TYPE (type));
   3663 
   3664   return ret;
   3665 }
   3666 
   3667 static int
   3668 objc_is_gcable_type (tree type, int or_strong_p)
   3669 {
   3670   tree name;
   3671 
   3672   if (!TYPE_P (type))
   3673     return 0;
   3674   if (objc_is_id (TYPE_MAIN_VARIANT (type)))
   3675     return 1;
   3676   if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
   3677     return 1;
   3678   if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
   3679     return 0;
   3680   type = TREE_TYPE (type);
   3681   if (TREE_CODE (type) != RECORD_TYPE)
   3682     return 0;
   3683   name = TYPE_NAME (type);
   3684   return (objc_is_class_name (name) != NULL_TREE);
   3685 }
   3686 
   3687 static tree
   3688 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
   3689 {
   3690   if (expr == oldexpr)
   3691     return newexpr;
   3692 
   3693   switch (TREE_CODE (expr))
   3694     {
   3695     case COMPONENT_REF:
   3696       return objc_build_component_ref
   3697 	     (objc_substitute_decl (TREE_OPERAND (expr, 0),
   3698 				    oldexpr,
   3699 				    newexpr),
   3700 	      DECL_NAME (TREE_OPERAND (expr, 1)));
   3701     case ARRAY_REF:
   3702       return build_array_ref (input_location,
   3703 			      objc_substitute_decl (TREE_OPERAND (expr, 0),
   3704 						    oldexpr,
   3705 						    newexpr),
   3706 			      TREE_OPERAND (expr, 1));
   3707     case INDIRECT_REF:
   3708       return build_indirect_ref (input_location,
   3709 				 objc_substitute_decl (TREE_OPERAND (expr, 0),
   3710 						       oldexpr,
   3711 						       newexpr), RO_ARROW);
   3712     default:
   3713       return expr;
   3714     }
   3715 }
   3716 
   3717 static tree
   3718 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
   3719 {
   3720   tree func_params;
   3721   /* The LHS parameter contains the expression 'outervar->memberspec';
   3722      we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
   3723      where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
   3724   */
   3725   tree offs
   3726     = objc_substitute_decl
   3727       (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
   3728   tree func
   3729     = (flag_objc_direct_dispatch
   3730        ? objc_assign_ivar_fast_decl
   3731        : objc_assign_ivar_decl);
   3732 
   3733   offs = convert (integer_type_node, build_unary_op (input_location,
   3734 						     ADDR_EXPR, offs, 0));
   3735   offs = fold (offs);
   3736   func_params = tree_cons (NULL_TREE,
   3737 	convert (objc_object_type, rhs),
   3738 	    tree_cons (NULL_TREE, convert (objc_object_type, outervar),
   3739 		tree_cons (NULL_TREE, offs,
   3740 		    NULL_TREE)));
   3741 
   3742   return build_function_call (input_location, func, func_params);
   3743 }
   3744 
   3745 static tree
   3746 objc_build_global_assignment (tree lhs, tree rhs)
   3747 {
   3748   tree func_params = tree_cons (NULL_TREE,
   3749 	convert (objc_object_type, rhs),
   3750 	    tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
   3751 		      build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
   3752 		    NULL_TREE));
   3753 
   3754   return build_function_call (input_location,
   3755 			      objc_assign_global_decl, func_params);
   3756 }
   3757 
   3758 static tree
   3759 objc_build_strong_cast_assignment (tree lhs, tree rhs)
   3760 {
   3761   tree func_params = tree_cons (NULL_TREE,
   3762 	convert (objc_object_type, rhs),
   3763 	    tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
   3764 		      build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
   3765 		    NULL_TREE));
   3766 
   3767   return build_function_call (input_location,
   3768 			      objc_assign_strong_cast_decl, func_params);
   3769 }
   3770 
   3771 static int
   3772 objc_is_gcable_p (tree expr)
   3773 {
   3774   return (TREE_CODE (expr) == COMPONENT_REF
   3775 	  ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
   3776 	  : TREE_CODE (expr) == ARRAY_REF
   3777 	  ? (objc_is_gcable_p (TREE_TYPE (expr))
   3778 	     || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
   3779 	  : TREE_CODE (expr) == ARRAY_TYPE
   3780 	  ? objc_is_gcable_p (TREE_TYPE (expr))
   3781 	  : TYPE_P (expr)
   3782 	  ? objc_is_gcable_type (expr, 1)
   3783 	  : (objc_is_gcable_p (TREE_TYPE (expr))
   3784 	     || (DECL_P (expr)
   3785 		 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
   3786 }
   3787 
   3788 static int
   3789 objc_is_ivar_reference_p (tree expr)
   3790 {
   3791   return (TREE_CODE (expr) == ARRAY_REF
   3792 	  ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
   3793 	  : TREE_CODE (expr) == COMPONENT_REF
   3794 	  ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
   3795 	  : 0);
   3796 }
   3797 
   3798 static int
   3799 objc_is_global_reference_p (tree expr)
   3800 {
   3801   return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
   3802 	  ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
   3803 	  : DECL_P (expr)
   3804 	  ? (DECL_FILE_SCOPE_P (expr) || TREE_STATIC (expr))
   3805 	  : 0);
   3806 }
   3807 
   3808 tree
   3809 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
   3810 {
   3811   tree result = NULL_TREE, outer;
   3812   int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
   3813 
   3814   /* This function is currently only used with the next runtime with
   3815      garbage collection enabled (-fobjc-gc).  */
   3816   gcc_assert (flag_next_runtime);
   3817 
   3818   /* See if we have any lhs casts, and strip them out.  NB: The lvalue casts
   3819      will have been transformed to the form '*(type *)&expr'.  */
   3820   if (TREE_CODE (lhs) == INDIRECT_REF)
   3821     {
   3822       outer = TREE_OPERAND (lhs, 0);
   3823 
   3824       while (!strong_cast_p
   3825 	     && (CONVERT_EXPR_P (outer)
   3826 		 || TREE_CODE (outer) == NON_LVALUE_EXPR))
   3827 	{
   3828 	  tree lhstype = TREE_TYPE (outer);
   3829 
   3830 	  /* Descend down the cast chain, and record the first objc_gc
   3831 	     attribute found.  */
   3832 	  if (POINTER_TYPE_P (lhstype))
   3833 	    {
   3834 	      tree attr
   3835 		= lookup_attribute ("objc_gc",
   3836 				    TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
   3837 
   3838 	      if (attr)
   3839 		strong_cast_p = 1;
   3840 	    }
   3841 
   3842 	  outer = TREE_OPERAND (outer, 0);
   3843 	}
   3844     }
   3845 
   3846   /* If we have a __strong cast, it trumps all else.  */
   3847   if (strong_cast_p)
   3848     {
   3849       if (modifycode != NOP_EXPR)
   3850         goto invalid_pointer_arithmetic;
   3851 
   3852       if (warn_assign_intercept)
   3853 	warning (0, "strong-cast assignment has been intercepted");
   3854 
   3855       result = objc_build_strong_cast_assignment (lhs, rhs);
   3856 
   3857       goto exit_point;
   3858     }
   3859 
   3860   /* the lhs must be of a suitable type, regardless of its underlying
   3861      structure.  */
   3862   if (!objc_is_gcable_p (lhs))
   3863     goto exit_point;
   3864 
   3865   outer = lhs;
   3866 
   3867   while (outer
   3868 	 && (TREE_CODE (outer) == COMPONENT_REF
   3869 	     || TREE_CODE (outer) == ARRAY_REF))
   3870     outer = TREE_OPERAND (outer, 0);
   3871 
   3872   if (TREE_CODE (outer) == INDIRECT_REF)
   3873     {
   3874       outer = TREE_OPERAND (outer, 0);
   3875       indirect_p = 1;
   3876     }
   3877 
   3878   outer_gc_p = objc_is_gcable_p (outer);
   3879 
   3880   /* Handle ivar assignments. */
   3881   if (objc_is_ivar_reference_p (lhs))
   3882     {
   3883       /* if the struct to the left of the ivar is not an Objective-C object (__strong
   3884 	 doesn't cut it here), the best we can do here is suggest a cast.  */
   3885       if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
   3886 	{
   3887 	  /* We may still be able to use the global write barrier... */
   3888 	  if (!indirect_p && objc_is_global_reference_p (outer))
   3889 	    goto global_reference;
   3890 
   3891 	 suggest_cast:
   3892 	  if (modifycode == NOP_EXPR)
   3893 	    {
   3894 	      if (warn_assign_intercept)
   3895 		warning (0, "strong-cast may possibly be needed");
   3896 	    }
   3897 
   3898 	  goto exit_point;
   3899 	}
   3900 
   3901       if (modifycode != NOP_EXPR)
   3902         goto invalid_pointer_arithmetic;
   3903 
   3904       if (warn_assign_intercept)
   3905 	warning (0, "instance variable assignment has been intercepted");
   3906 
   3907       result = objc_build_ivar_assignment (outer, lhs, rhs);
   3908 
   3909       goto exit_point;
   3910     }
   3911 
   3912   /* Likewise, intercept assignment to global/static variables if their type is
   3913      GC-marked.  */
   3914   if (objc_is_global_reference_p (outer))
   3915     {
   3916       if (indirect_p)
   3917 	goto suggest_cast;
   3918 
   3919      global_reference:
   3920       if (modifycode != NOP_EXPR)
   3921 	{
   3922 	 invalid_pointer_arithmetic:
   3923 	  if (outer_gc_p)
   3924 	    warning (0, "pointer arithmetic for garbage-collected objects not allowed");
   3925 
   3926 	  goto exit_point;
   3927 	}
   3928 
   3929       if (warn_assign_intercept)
   3930 	warning (0, "global/static variable assignment has been intercepted");
   3931 
   3932       result = objc_build_global_assignment (lhs, rhs);
   3933     }
   3934 
   3935   /* In all other cases, fall back to the normal mechanism.  */
   3936  exit_point:
   3937   return result;
   3938 }
   3939 
   3940 /* Implementation of the table mapping a class name (as an identifier)
   3941    to a class node.  The two public functions for it are
   3942    lookup_interface() and add_interface().  add_interface() is only
   3943    used in this file, so we can make it static.  */
   3944 
   3945 static GTY(()) objc_map_t interface_map;
   3946 
   3947 static void
   3948 interface_hash_init (void)
   3949 {
   3950   interface_map = objc_map_alloc_ggc (200);
   3951 }
   3952 
   3953 static tree
   3954 add_interface (tree class_name, tree name)
   3955 {
   3956   /* Put interfaces on list in reverse order.  */
   3957   TREE_CHAIN (class_name) = interface_chain;
   3958   interface_chain = class_name;
   3959 
   3960   /* Add it to the map.  */
   3961   objc_map_put (interface_map, name, class_name);
   3962 
   3963   return interface_chain;
   3964 }
   3965 
   3966 tree
   3967 lookup_interface (tree ident)
   3968 {
   3969 #ifdef OBJCPLUS
   3970   if (ident && TREE_CODE (ident) == TYPE_DECL)
   3971     ident = DECL_NAME (ident);
   3972 #endif
   3973 
   3974   if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
   3975     return NULL_TREE;
   3976 
   3977   {
   3978     tree interface = objc_map_get (interface_map, ident);
   3979 
   3980     if (interface == OBJC_MAP_NOT_FOUND)
   3981       return NULL_TREE;
   3982     else
   3983       return interface;
   3984   }
   3985 }
   3986 
   3987 
   3988 
   3989 /* Implement @defs (<classname>) within struct bodies.  */
   3990 
   3991 tree
   3992 objc_get_class_ivars (tree class_name)
   3993 {
   3994   tree interface = lookup_interface (class_name);
   3995 
   3996   if (interface)
   3997     return get_class_ivars (interface, true);
   3998 
   3999   error ("cannot find interface declaration for %qE",
   4000 	 class_name);
   4001 
   4002   return error_mark_node;
   4003 }
   4004 
   4005 
   4006 /* Functions used by the hashtable for field duplicates in
   4007    objc_detect_field_duplicates().  Ideally, we'd use a standard
   4008    key-value dictionary hashtable , and store as keys the field names,
   4009    and as values the actual declarations (used to print nice error
   4010    messages with the locations).  But, the hashtable we are using only
   4011    allows us to store keys in the hashtable, without values (it looks
   4012    more like a set).  So, we store the DECLs, but define equality as
   4013    DECLs having the same name, and hash as the hash of the name.  */
   4014 
   4015 struct decl_name_hash : nofree_ptr_hash <tree_node>
   4016 {
   4017   static inline hashval_t hash (const tree_node *);
   4018   static inline bool equal (const tree_node *, const tree_node *);
   4019 };
   4020 
   4021 inline hashval_t
   4022 decl_name_hash::hash (const tree_node *q)
   4023 {
   4024   return (hashval_t) ((intptr_t)(DECL_NAME (q)) >> 3);
   4025 }
   4026 
   4027 inline bool
   4028 decl_name_hash::equal (const tree_node *a, const tree_node *b)
   4029 {
   4030   return DECL_NAME (a) == DECL_NAME (b);
   4031 }
   4032 
   4033 /* Called when checking the variables in a struct.  If we are not
   4034    doing the ivars list inside an @interface context, then return
   4035    false.  Else, perform the check for duplicate ivars, then return
   4036    true.  The check for duplicates checks if an instance variable with
   4037    the same name exists in the class or in a superclass.  If
   4038    'check_superclasses_only' is set to true, then it is assumed that
   4039    checks for instance variables in the same class has already been
   4040    performed (this is the case for ObjC++) and only the instance
   4041    variables of superclasses are checked.  */
   4042 bool
   4043 objc_detect_field_duplicates (bool check_superclasses_only)
   4044 {
   4045   if (!objc_collecting_ivars || !objc_interface_context
   4046       || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE)
   4047     return false;
   4048 
   4049   /* We have two ways of doing this check:
   4050 
   4051   "direct comparison": we iterate over the instance variables and
   4052   compare them directly.  This works great for small numbers of
   4053   instance variables (such as 10 or 20), which are extremely common.
   4054   But it will potentially take forever for the pathological case with
   4055   a huge number (eg, 10k) of instance variables.
   4056 
   4057   "hashtable": we use a hashtable, which requires a single sweep
   4058   through the list of instances variables.  This is much slower for a
   4059   small number of variables, and we only use it for large numbers.
   4060 
   4061   To decide which one to use, we need to get an idea of how many
   4062   instance variables we have to compare.  */
   4063   {
   4064     unsigned int number_of_ivars_to_check = 0;
   4065     {
   4066       tree ivar;
   4067       for (ivar = CLASS_RAW_IVARS (objc_interface_context);
   4068 	   ivar; ivar = DECL_CHAIN (ivar))
   4069 	{
   4070 	  /* Ignore anonymous ivars.  */
   4071 	  if (DECL_NAME (ivar))
   4072 	    number_of_ivars_to_check++;
   4073 	}
   4074     }
   4075 
   4076     /* Exit if there is nothing to do.  */
   4077     if (number_of_ivars_to_check == 0)
   4078       return true;
   4079 
   4080     /* In case that there are only 1 or 2 instance variables to check,
   4081        we always use direct comparison.  If there are more, it is
   4082        worth iterating over the instance variables in the superclass
   4083        to count how many there are (note that this has the same cost
   4084        as checking 1 instance variable by direct comparison, which is
   4085        why we skip this check in the case of 1 or 2 ivars and just do
   4086        the direct comparison) and then decide if it worth using a
   4087        hashtable.  */
   4088     if (number_of_ivars_to_check > 2)
   4089       {
   4090 	unsigned int number_of_superclass_ivars = 0;
   4091 	{
   4092 	  tree interface;
   4093 	  for (interface = lookup_interface (CLASS_SUPER_NAME (objc_interface_context));
   4094 	       interface; interface = lookup_interface (CLASS_SUPER_NAME (interface)))
   4095 	    {
   4096 	      tree ivar;
   4097 	      for (ivar = CLASS_RAW_IVARS (interface);
   4098 		   ivar; ivar = DECL_CHAIN (ivar))
   4099 		number_of_superclass_ivars++;
   4100 	    }
   4101 	}
   4102 
   4103 	/* We use a hashtable if we have over 10k comparisons.  */
   4104 	if (number_of_ivars_to_check * (number_of_superclass_ivars
   4105 					+ (number_of_ivars_to_check / 2))
   4106 	    > 10000)
   4107 	  {
   4108 	    /* First, build the hashtable by putting all the instance
   4109 	       variables of superclasses in it.  */
   4110 	    hash_table<decl_name_hash> htab (37);
   4111 	    tree interface;
   4112 	    for (interface = lookup_interface (CLASS_SUPER_NAME
   4113 					       (objc_interface_context));
   4114 		 interface; interface = lookup_interface
   4115 		   (CLASS_SUPER_NAME (interface)))
   4116 	      {
   4117 		tree ivar;
   4118 		for (ivar = CLASS_RAW_IVARS (interface); ivar;
   4119 		     ivar = DECL_CHAIN (ivar))
   4120 		  {
   4121 		    if (DECL_NAME (ivar) != NULL_TREE)
   4122 		      {
   4123 			tree_node **slot = htab.find_slot (ivar, INSERT);
   4124 			/* Do not check for duplicate instance
   4125 			   variables in superclasses.  Errors have
   4126 			   already been generated.  */
   4127 			*slot = ivar;
   4128 		      }
   4129 		  }
   4130 	      }
   4131 
   4132 	    /* Now, we go through all the instance variables in the
   4133 	       class, and check that they are not in the
   4134 	       hashtable.  */
   4135 	    if (check_superclasses_only)
   4136 	      {
   4137 		tree ivar;
   4138 		for (ivar = CLASS_RAW_IVARS (objc_interface_context); ivar;
   4139 		     ivar = DECL_CHAIN (ivar))
   4140 		  {
   4141 		    if (DECL_NAME (ivar) != NULL_TREE)
   4142 		      {
   4143 			tree duplicate_ivar = htab.find (ivar);
   4144 			if (duplicate_ivar != HTAB_EMPTY_ENTRY)
   4145 			  {
   4146 			    error_at (DECL_SOURCE_LOCATION (ivar),
   4147 				      "duplicate instance variable %q+D",
   4148 				      ivar);
   4149 			    inform (DECL_SOURCE_LOCATION (duplicate_ivar),
   4150 				    "previous declaration of %q+D",
   4151 				    duplicate_ivar);
   4152 			    /* FIXME: Do we need the following ?  */
   4153 			    /* DECL_NAME (ivar) = NULL_TREE; */
   4154 			  }
   4155 		      }
   4156 		  }
   4157 	      }
   4158 	    else
   4159 	      {
   4160 		/* If we're checking for duplicates in the class as
   4161 		   well, we insert variables in the hashtable as we
   4162 		   check them, so if a duplicate follows, it will be
   4163 		   caught.  */
   4164 		tree ivar;
   4165 		for (ivar = CLASS_RAW_IVARS (objc_interface_context); ivar;
   4166 		     ivar = DECL_CHAIN (ivar))
   4167 		  {
   4168 		    if (DECL_NAME (ivar) != NULL_TREE)
   4169 		      {
   4170 			tree_node **slot = htab.find_slot (ivar, INSERT);
   4171 			if (*slot)
   4172 			  {
   4173 			    tree duplicate_ivar = (tree)(*slot);
   4174 			    error_at (DECL_SOURCE_LOCATION (ivar),
   4175 				      "duplicate instance variable %q+D",
   4176 				      ivar);
   4177 			    inform (DECL_SOURCE_LOCATION (duplicate_ivar),
   4178 				    "previous declaration of %q+D",
   4179 				    duplicate_ivar);
   4180 			    /* FIXME: Do we need the following ?  */
   4181 			    /* DECL_NAME (ivar) = NULL_TREE; */
   4182 			  }
   4183 			*slot = ivar;
   4184 		      }
   4185 		  }
   4186 	      }
   4187 	    return true;
   4188 	  }
   4189       }
   4190   }
   4191 
   4192   /* This is the "direct comparison" approach, which is used in most
   4193      non-pathological cases.  */
   4194   {
   4195     /* Walk up to class hierarchy, starting with this class (this is
   4196        the external loop, because lookup_interface() is expensive, and
   4197        we want to do it few times).  */
   4198     tree interface = objc_interface_context;
   4199 
   4200     if (check_superclasses_only)
   4201       interface = lookup_interface (CLASS_SUPER_NAME (interface));
   4202 
   4203     for ( ; interface; interface = lookup_interface
   4204 	    (CLASS_SUPER_NAME (interface)))
   4205       {
   4206 	tree ivar_being_checked;
   4207 
   4208 	for (ivar_being_checked = CLASS_RAW_IVARS (objc_interface_context);
   4209 	     ivar_being_checked;
   4210 	     ivar_being_checked = DECL_CHAIN (ivar_being_checked))
   4211 	  {
   4212 	    tree decl;
   4213 
   4214 	    /* Ignore anonymous ivars.  */
   4215 	    if (DECL_NAME (ivar_being_checked) == NULL_TREE)
   4216 	      continue;
   4217 
   4218 	    /* Note how we stop when we find the ivar we are checking
   4219 	       (this can only happen in the main class, not
   4220 	       superclasses), to avoid comparing things twice
   4221 	       (otherwise, for each ivar, you'd compare A to B then B
   4222 	       to A, and get duplicated error messages).  */
   4223 	    for (decl = CLASS_RAW_IVARS (interface);
   4224 		 decl && decl != ivar_being_checked;
   4225 		 decl = DECL_CHAIN (decl))
   4226 	      {
   4227 		if (DECL_NAME (ivar_being_checked) == DECL_NAME (decl))
   4228 		  {
   4229 		    error_at (DECL_SOURCE_LOCATION (ivar_being_checked),
   4230 			      "duplicate instance variable %q+D",
   4231 			      ivar_being_checked);
   4232 		    inform (DECL_SOURCE_LOCATION (decl),
   4233 			    "previous declaration of %q+D",
   4234 			    decl);
   4235 		    /* FIXME: Do we need the following ?  */
   4236 		    /* DECL_NAME (ivar_being_checked) = NULL_TREE; */
   4237 		  }
   4238 	      }
   4239 	  }
   4240       }
   4241   }
   4242   return true;
   4243 }
   4244 
   4245 /* Used by: build_private_template, continue_class,
   4246    and for @defs constructs.  */
   4247 
   4248 static tree
   4249 get_class_ivars (tree interface, bool inherited)
   4250 {
   4251   tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
   4252 
   4253   /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
   4254      by the current class (i.e., they do not include super-class ivars).
   4255      However, the CLASS_IVARS list will be side-effected by a call to
   4256      finish_struct(), which will fill in field offsets.  */
   4257   if (!CLASS_IVARS (interface))
   4258     CLASS_IVARS (interface) = ivar_chain;
   4259 
   4260   if (!inherited)
   4261     return ivar_chain;
   4262 
   4263   while (CLASS_SUPER_NAME (interface))
   4264     {
   4265       /* Prepend super-class ivars.  */
   4266       interface = lookup_interface (CLASS_SUPER_NAME (interface));
   4267       ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
   4268 			    ivar_chain);
   4269     }
   4270 
   4271   return ivar_chain;
   4272 }
   4273 
   4274 void
   4275 objc_maybe_warn_exceptions (location_t loc)
   4276 {
   4277   /* -fobjc-exceptions is required to enable Objective-C exceptions.
   4278      For example, on Darwin, ObjC exceptions require a sufficiently
   4279      recent version of the runtime, so the user must ask for them
   4280      explicitly.  On other platforms, at the moment -fobjc-exceptions
   4281      triggers -fexceptions which again is required for exceptions to
   4282      work.  */
   4283   if (!flag_objc_exceptions)
   4284     {
   4285       /* Warn only once per compilation unit.  */
   4286       static bool warned = false;
   4287 
   4288       if (!warned)
   4289 	{
   4290 	  error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
   4291 	  warned = true;
   4292 	}
   4293     }
   4294 }
   4295 
   4296 static struct objc_try_context *cur_try_context;
   4297 
   4298 /* Called just after parsing the @try and its associated BODY.  We now
   4299    must prepare for the tricky bits -- handling the catches and finally.  */
   4300 
   4301 void
   4302 objc_begin_try_stmt (location_t try_locus, tree body)
   4303 {
   4304   struct objc_try_context *c = XCNEW (struct objc_try_context);
   4305   c->outer = cur_try_context;
   4306   c->try_body = body;
   4307   c->try_locus = try_locus;
   4308   c->end_try_locus = input_location;
   4309   cur_try_context = c;
   4310 
   4311   /* Collect the list of local variables.  We'll mark them as volatile
   4312      at the end of compilation of this function to prevent them being
   4313      clobbered by setjmp/longjmp.  */
   4314   if (flag_objc_sjlj_exceptions)
   4315     objc_mark_locals_volatile (NULL);
   4316 }
   4317 
   4318 /* Called just after parsing "@catch (parm)".  Open a binding level,
   4319    enter DECL into the binding level, and initialize it.  Leave the
   4320    binding level open while the body of the compound statement is
   4321    parsed.  If DECL is NULL_TREE, then we are compiling "@catch(...)"
   4322    which we compile as "@catch(id tmp_variable)".  */
   4323 
   4324 void
   4325 objc_begin_catch_clause (tree decl)
   4326 {
   4327   tree compound, type, t;
   4328   bool ellipsis = false;
   4329 
   4330   /* Begin a new scope that the entire catch clause will live in.  */
   4331   compound = c_begin_compound_stmt (true);
   4332 
   4333   /* Create the appropriate declaration for the argument.  */
   4334  if (decl == error_mark_node)
   4335    type = error_mark_node;
   4336  else
   4337    {
   4338      if (decl == NULL_TREE)
   4339        {
   4340 	 /* If @catch(...) was specified, create a temporary variable of
   4341 	    type 'id' and use it.  */
   4342 	 decl = objc_create_temporary_var (objc_object_type, "__objc_generic_catch_var");
   4343 	 DECL_SOURCE_LOCATION (decl) = input_location;
   4344 	 /* ... but allow the runtime to differentiate between ellipsis and the
   4345 	    case of @catch (id xyz).  */
   4346 	 ellipsis = true;
   4347        }
   4348      else
   4349        {
   4350 	 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL.  */
   4351 	 decl = build_decl (input_location,
   4352 			    VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
   4353        }
   4354      lang_hooks.decls.pushdecl (decl);
   4355 
   4356      /* Mark the declaration as used so you never any warnings whether
   4357 	you use the exception argument or not.  TODO: Implement a
   4358 	-Wunused-exception-parameter flag, which would cause warnings
   4359 	if exception parameter is not used.  */
   4360      TREE_USED (decl) = 1;
   4361      DECL_READ_P (decl) = 1;
   4362 
   4363      type = TREE_TYPE (decl);
   4364    }
   4365 
   4366   /* Verify that the type of the catch is valid.  It must be a pointer
   4367      to an Objective-C class, or "id" (which is catch-all).  */
   4368   if (type == error_mark_node)
   4369     {
   4370       ;/* Just keep going.  */
   4371     }
   4372   else if (!objc_type_valid_for_messaging (type, false))
   4373     {
   4374       error ("%<@catch%> parameter is not a known Objective-C class type");
   4375       type = error_mark_node;
   4376     }
   4377   else if (TYPE_HAS_OBJC_INFO (TREE_TYPE (type))
   4378 	   && TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (type)))
   4379     {
   4380       error ("%<@catch%> parameter cannot be protocol-qualified");
   4381       type = error_mark_node;
   4382     }
   4383   else if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
   4384     /* @catch (id xyz) or @catch (...) but we note this for runtimes that
   4385        identify 'id'.  */
   4386     ;
   4387   else
   4388     {
   4389       /* If 'type' was built using typedefs, we need to get rid of
   4390 	 them and get a simple pointer to the class.  */
   4391       bool is_typedef = false;
   4392       tree x = TYPE_MAIN_VARIANT (type);
   4393 
   4394       /* Skip from the pointer to the pointee.  */
   4395       if (TREE_CODE (x) == POINTER_TYPE)
   4396 	x = TREE_TYPE (x);
   4397 
   4398       /* Traverse typedef aliases */
   4399       while (TREE_CODE (x) == RECORD_TYPE && OBJC_TYPE_NAME (x)
   4400 	     && TREE_CODE (OBJC_TYPE_NAME (x)) == TYPE_DECL
   4401 	     && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (x)))
   4402 	{
   4403 	  is_typedef = true;
   4404 	  x = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (x));
   4405 	}
   4406 
   4407       /* If it was a typedef, build a pointer to the final, original
   4408 	 class.  */
   4409       if (is_typedef)
   4410 	type = build_pointer_type (x);
   4411 
   4412       if (cur_try_context->catch_list)
   4413 	{
   4414 	  /* Examine previous @catch clauses and see if we've already
   4415 	     caught the type in question.  */
   4416 	  tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
   4417 	  for (; !tsi_end_p (i); tsi_next (&i))
   4418 	    {
   4419 	      tree stmt = tsi_stmt (i);
   4420 	      t = CATCH_TYPES (stmt);
   4421 	      if (t == error_mark_node)
   4422 		continue;
   4423 	      if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
   4424 		{
   4425 		  warning (0, "exception of type %<%T%> will be caught",
   4426 			   TREE_TYPE (type));
   4427 		  warning_at  (EXPR_LOCATION (stmt), 0, "   by earlier handler for %<%T%>",
   4428 			       TREE_TYPE (t ? t : objc_object_type));
   4429 		  break;
   4430 		}
   4431 	    }
   4432 	}
   4433     }
   4434 
   4435   t = (*runtime.begin_catch) (&cur_try_context, type, decl, compound, ellipsis);
   4436   add_stmt (t);
   4437 }
   4438 
   4439 /* Called just after parsing the closing brace of a @catch clause.  Close
   4440    the open binding level, and record a CATCH_EXPR for it.  */
   4441 
   4442 void
   4443 objc_finish_catch_clause (void)
   4444 {
   4445   tree c = cur_try_context->current_catch;
   4446   cur_try_context->current_catch = NULL;
   4447   cur_try_context->end_catch_locus = input_location;
   4448 
   4449   CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
   4450 
   4451   (*runtime.finish_catch) (&cur_try_context, c);
   4452 }
   4453 
   4454 /* Called after parsing a @finally clause and its associated BODY.
   4455    Record the body for later placement.  */
   4456 
   4457 void
   4458 objc_build_finally_clause (location_t finally_locus, tree body)
   4459 {
   4460   cur_try_context->finally_body = body;
   4461   cur_try_context->finally_locus = finally_locus;
   4462   cur_try_context->end_finally_locus = input_location;
   4463 }
   4464 
   4465 /* Called to finalize a @try construct.  */
   4466 
   4467 tree
   4468 objc_finish_try_stmt (void)
   4469 {
   4470   struct objc_try_context *c = cur_try_context;
   4471   tree stmt;
   4472 
   4473   if (c->catch_list == NULL && c->finally_body == NULL)
   4474     error ("%<@try%> without %<@catch%> or %<@finally%>");
   4475 
   4476   stmt = (*runtime.finish_try_stmt) (&cur_try_context);
   4477   add_stmt (stmt);
   4478 
   4479   cur_try_context = c->outer;
   4480   free (c);
   4481   return stmt;
   4482 }
   4483 
   4484 tree
   4485 objc_build_throw_stmt (location_t loc, tree throw_expr)
   4486 {
   4487   bool rethrown = false;
   4488 
   4489   objc_maybe_warn_exceptions (loc);
   4490 
   4491   /* Don't waste time trying to build something if we're already dead.  */
   4492   if (throw_expr == error_mark_node)
   4493     return error_mark_node;
   4494 
   4495   if (throw_expr == NULL)
   4496     {
   4497       /* If we're not inside a @catch block, there is no "current
   4498 	 exception" to be rethrown.  */
   4499       if (cur_try_context == NULL
   4500           || cur_try_context->current_catch == NULL)
   4501 	{
   4502 	  error_at (loc,
   4503 		    "%<@throw%> (rethrow) used outside of a %<@catch%> block");
   4504 	  return error_mark_node;
   4505 	}
   4506 
   4507       /* Otherwise the object is still sitting in the EXC_PTR_EXPR
   4508 	 value that we get from the runtime.  */
   4509       throw_expr = (*runtime.build_exc_ptr) (&cur_try_context);
   4510       rethrown = true;
   4511     }
   4512   else
   4513     {
   4514       if (!objc_type_valid_for_messaging (TREE_TYPE (throw_expr), true))
   4515 	{
   4516 	  error_at (loc, "%<@throw%> argument is not an object");
   4517 	  return error_mark_node;
   4518 	}
   4519     }
   4520 
   4521   return (*runtime.build_throw_stmt) (loc, throw_expr, rethrown);
   4522 }
   4523 
   4524 tree
   4525 objc_build_synchronized (location_t start_locus, tree object_expr, tree body)
   4526 {
   4527   /* object_expr should never be NULL; but in case it is, convert it to
   4528      error_mark_node.  */
   4529   if (object_expr == NULL)
   4530     object_expr = error_mark_node;
   4531 
   4532   /* Validate object_expr.  If not valid, set it to error_mark_node.  */
   4533   if (object_expr != error_mark_node)
   4534     {
   4535       if (!objc_type_valid_for_messaging (TREE_TYPE (object_expr), true))
   4536 	{
   4537 	  error_at (start_locus, "%<@synchronized%> argument is not an object");
   4538 	  object_expr = error_mark_node;
   4539 	}
   4540     }
   4541 
   4542   if (object_expr == error_mark_node)
   4543     {
   4544       /* If we found an error, we simply ignore the '@synchronized'.
   4545 	 Compile the body so we can keep going with minimal
   4546 	 casualties.  */
   4547       return add_stmt (body);
   4548     }
   4549   else
   4550     {
   4551       tree call;
   4552       tree args;
   4553 
   4554       /* objc_sync_enter (object_expr); */
   4555       object_expr = save_expr (object_expr);
   4556       args = tree_cons (NULL, object_expr, NULL);
   4557       call = build_function_call (input_location,
   4558 				  objc_sync_enter_decl, args);
   4559       SET_EXPR_LOCATION (call, start_locus);
   4560       add_stmt (call);
   4561 
   4562       /* Build "objc_sync_exit (object_expr);" but do not add it yet;
   4563 	 it goes inside the @finalize() clause.  */
   4564       args = tree_cons (NULL, object_expr, NULL);
   4565       call = build_function_call (input_location,
   4566 				  objc_sync_exit_decl, args);
   4567       SET_EXPR_LOCATION (call, input_location);
   4568 
   4569       /* @try { body; } */
   4570       objc_begin_try_stmt (start_locus, body);
   4571 
   4572       /* @finally { objc_sync_exit (object_expr); } */
   4573       objc_build_finally_clause (input_location, call);
   4574 
   4575       /* End of try statement.  */
   4576       return objc_finish_try_stmt ();
   4577     }
   4578 }
   4579 
   4580 /* Construct a C struct corresponding to ObjC class CLASS, with the same
   4581    name as the class:
   4582 
   4583    struct <classname> {
   4584      struct _objc_class *isa;
   4585      ...
   4586    };  */
   4587 
   4588 static void
   4589 build_private_template (tree klass)
   4590 {
   4591   if (!CLASS_STATIC_TEMPLATE (klass))
   4592     {
   4593       tree record = objc_build_struct (klass,
   4594 				       get_class_ivars (klass, false),
   4595 				       CLASS_SUPER_NAME (klass));
   4596 
   4597       /* Set the TREE_USED bit for this struct, so that stab generator
   4598 	 can emit stabs for this struct type.  */
   4599       if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
   4600 	TREE_USED (TYPE_STUB_DECL (record)) = 1;
   4601 
   4602       /* Copy the attributes from the class to the type.  */
   4603       if (TREE_DEPRECATED (klass))
   4604 	TREE_DEPRECATED (record) = 1;
   4605       if (TREE_UNAVAILABLE (klass))
   4606 	TREE_UNAVAILABLE (record) = 1;
   4607     }
   4608 }
   4609 
   4610 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
   4611    current class.  */
   4612 #ifdef OBJCPLUS
   4613 static void
   4614 objc_generate_cxx_ctor_or_dtor (bool dtor)
   4615 {
   4616   tree fn, body, compound_stmt, ivar;
   4617 
   4618   /* - (id) .cxx_construct { ... return self; } */
   4619   /* - (void) .cxx_construct { ... }            */
   4620 
   4621   objc_start_method_definition
   4622     (false /* is_class_method */,
   4623      objc_build_method_signature (false /* is_class_method */,
   4624 				  build_tree_list (NULL_TREE,
   4625 						   dtor
   4626 						   ? void_type_node
   4627 						   : objc_object_type),
   4628 				  get_identifier (dtor
   4629 						  ? TAG_CXX_DESTRUCT
   4630 						  : TAG_CXX_CONSTRUCT),
   4631 				  make_node (TREE_LIST),
   4632 				  false), NULL, NULL_TREE);
   4633   body = begin_function_body ();
   4634   compound_stmt = begin_compound_stmt (0);
   4635 
   4636   ivar = CLASS_IVARS (implementation_template);
   4637   /* Destroy ivars in reverse order.  */
   4638   if (dtor)
   4639     ivar = nreverse (copy_list (ivar));
   4640 
   4641   for (; ivar; ivar = TREE_CHAIN (ivar))
   4642     {
   4643       if (TREE_CODE (ivar) == FIELD_DECL)
   4644 	{
   4645 	  tree type = TREE_TYPE (ivar);
   4646 
   4647 	  /* Call the ivar's default constructor or destructor.  Do not
   4648 	     call the destructor unless a corresponding constructor call
   4649 	     has also been made (or is not needed).  */
   4650 	  if (MAYBE_CLASS_TYPE_P (type)
   4651 	      && (dtor
   4652 		  ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
   4653 		     && (!TYPE_NEEDS_CONSTRUCTING (type)
   4654 			 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
   4655 		  : (TYPE_NEEDS_CONSTRUCTING (type)
   4656 		     && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
   4657 	    finish_expr_stmt
   4658 	     (build_special_member_call
   4659 	      (build_ivar_reference (DECL_NAME (ivar)),
   4660 	       dtor ? complete_dtor_identifier : complete_ctor_identifier,
   4661 	       NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
   4662 	}
   4663     }
   4664 
   4665   /* The constructor returns 'self'.  */
   4666   if (!dtor)
   4667     finish_return_stmt (self_decl);
   4668 
   4669   finish_compound_stmt (compound_stmt);
   4670   finish_function_body (body);
   4671   fn = current_function_decl;
   4672   finish_function ();
   4673   objc_finish_method_definition (fn);
   4674 }
   4675 
   4676 /* The following routine will examine the current @interface for any
   4677    non-POD C++ ivars requiring non-trivial construction and/or
   4678    destruction, and then synthesize special '- .cxx_construct' and/or
   4679    '- .cxx_destruct' methods which will run the appropriate
   4680    construction or destruction code.  Note that ivars inherited from
   4681    super-classes are _not_ considered.  */
   4682 static void
   4683 objc_generate_cxx_cdtors (void)
   4684 {
   4685   bool need_ctor = false, need_dtor = false;
   4686   tree ivar;
   4687 
   4688   /* Error case, due to possibly an extra @end. */
   4689   if (!objc_implementation_context)
   4690     return;
   4691 
   4692   /* We do not want to do this for categories, since they do not have
   4693      their own ivars.  */
   4694 
   4695   if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
   4696     return;
   4697 
   4698   /* First, determine if we even need a constructor and/or destructor.  */
   4699 
   4700   for (ivar = CLASS_IVARS (implementation_template); ivar;
   4701        ivar = TREE_CHAIN (ivar))
   4702     {
   4703       if (TREE_CODE (ivar) == FIELD_DECL)
   4704 	{
   4705 	  tree type = TREE_TYPE (ivar);
   4706 
   4707 	  if (MAYBE_CLASS_TYPE_P (type))
   4708 	    {
   4709 	      if (TYPE_NEEDS_CONSTRUCTING (type)
   4710 		  && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
   4711 		/* NB: If a default constructor is not available, we will not
   4712 		   be able to initialize this ivar; the add_instance_variable()
   4713 		   routine will already have warned about this.  */
   4714 		need_ctor = true;
   4715 
   4716 	      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
   4717 		  && (!TYPE_NEEDS_CONSTRUCTING (type)
   4718 		      || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
   4719 		/* NB: If a default constructor is not available, we will not
   4720 		   call the destructor either, for symmetry.  */
   4721 		need_dtor = true;
   4722 	    }
   4723 	}
   4724     }
   4725 
   4726   /* Generate '- .cxx_construct' if needed.  */
   4727 
   4728   if (need_ctor)
   4729     objc_generate_cxx_ctor_or_dtor (false);
   4730 
   4731   /* Generate '- .cxx_destruct' if needed.  */
   4732 
   4733   if (need_dtor)
   4734     objc_generate_cxx_ctor_or_dtor (true);
   4735 
   4736   /* The 'imp_list' variable points at an imp_entry record for the current
   4737      @implementation.  Record the existence of '- .cxx_construct' and/or
   4738      '- .cxx_destruct' methods therein; it will be included in the
   4739      metadata for the class if the runtime needs it.  */
   4740   imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
   4741 }
   4742 #endif
   4743 
   4744 static void
   4745 error_with_ivar (const char *message, tree decl)
   4746 {
   4747   error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
   4748 	    message, identifier_to_locale (gen_declaration (decl)));
   4749 
   4750 }
   4751 
   4752 static void
   4753 check_ivars (tree inter, tree imp)
   4754 {
   4755   tree intdecls = CLASS_RAW_IVARS (inter);
   4756   tree impdecls = CLASS_RAW_IVARS (imp);
   4757 
   4758   while (1)
   4759     {
   4760       tree t1, t2;
   4761 
   4762 #ifdef OBJCPLUS
   4763       if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
   4764 	intdecls = TREE_CHAIN (intdecls);
   4765 #endif
   4766       if (intdecls == 0 && impdecls == 0)
   4767 	break;
   4768       if (intdecls == 0 || impdecls == 0)
   4769 	{
   4770 	  error ("inconsistent instance variable specification");
   4771 	  break;
   4772 	}
   4773 
   4774       t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
   4775 
   4776       if (!comptypes (t1, t2)
   4777 #ifdef OBJCPLUS
   4778 	  || !tree_int_cst_equal (DECL_BIT_FIELD_REPRESENTATIVE (intdecls),
   4779 				  DECL_BIT_FIELD_REPRESENTATIVE (impdecls))
   4780 #else
   4781 	  || !tree_int_cst_equal (DECL_INITIAL (intdecls),
   4782 				  DECL_INITIAL (impdecls))
   4783 #endif
   4784 	 )
   4785 	{
   4786 	  if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
   4787 	    {
   4788 	      error_with_ivar ("conflicting instance variable type",
   4789 			       impdecls);
   4790 	      error_with_ivar ("previous declaration of",
   4791 			       intdecls);
   4792 	    }
   4793 	  else			/* both the type and the name don't match */
   4794 	    {
   4795 	      error ("inconsistent instance variable specification");
   4796 	      break;
   4797 	    }
   4798 	}
   4799 
   4800       else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
   4801 	{
   4802 	  error_with_ivar ("conflicting instance variable name",
   4803 			   impdecls);
   4804 	  error_with_ivar ("previous declaration of",
   4805 			   intdecls);
   4806 	}
   4807 
   4808       intdecls = DECL_CHAIN (intdecls);
   4809       impdecls = DECL_CHAIN (impdecls);
   4810     }
   4811 }
   4812 
   4813 
   4814 static void
   4815 mark_referenced_methods (void)
   4816 {
   4817   struct imp_entry *impent;
   4818   tree chain;
   4819 
   4820   for (impent = imp_list; impent; impent = impent->next)
   4821     {
   4822       chain = CLASS_CLS_METHODS (impent->imp_context);
   4823       while (chain)
   4824 	{
   4825 	  cgraph_node::get_create (METHOD_DEFINITION (chain))->mark_force_output ();
   4826 	  chain = DECL_CHAIN (chain);
   4827 	}
   4828 
   4829       chain = CLASS_NST_METHODS (impent->imp_context);
   4830       while (chain)
   4831 	{
   4832 	  cgraph_node::get_create (METHOD_DEFINITION (chain))->mark_force_output ();
   4833 	  chain = DECL_CHAIN (chain);
   4834 	}
   4835     }
   4836 }
   4837 
   4838 /* If type is empty or only type qualifiers are present, add default
   4839    type of id (otherwise grokdeclarator will default to int).  */
   4840 static inline tree
   4841 adjust_type_for_id_default (tree type)
   4842 {
   4843   if (!type)
   4844     type = make_node (TREE_LIST);
   4845 
   4846   if (!TREE_VALUE (type))
   4847     TREE_VALUE (type) = objc_object_type;
   4848   else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
   4849 	   && TYPED_OBJECT (TREE_VALUE (type)))
   4850     error ("cannot use an object as parameter to a method");
   4851 
   4852   return type;
   4853 }
   4854 
   4855 /* Return a KEYWORD_DECL built using the specified key_name, arg_type,
   4856    arg_name and attributes. (TODO: Rename KEYWORD_DECL to
   4857    OBJC_METHOD_PARM_DECL ?)
   4858 
   4859    A KEYWORD_DECL is a tree representing the declaration of a
   4860    parameter of an Objective-C method.  It is produced when parsing a
   4861    fragment of Objective-C method declaration of the form
   4862 
   4863    keyworddecl:
   4864      selector ':' '(' typename ')' identifier
   4865 
   4866    For example, take the Objective-C method
   4867 
   4868    -(NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type;
   4869 
   4870    the two fragments "pathForResource:(NSString *)resource" and
   4871    "ofType:(NSString *)type" will generate a KEYWORD_DECL each.  The
   4872    KEYWORD_DECL stores the 'key_name' (eg, identifier for
   4873    "pathForResource"), the 'arg_type' (eg, tree representing a
   4874    NSString *), the 'arg_name' (eg identifier for "resource") and
   4875    potentially some attributes (for example, a tree representing
   4876    __attribute__ ((unused)) if such an attribute was attached to a
   4877    certain parameter).  You can access this information using the
   4878    TREE_TYPE (for arg_type), KEYWORD_ARG_NAME (for arg_name),
   4879    KEYWORD_KEY_NAME (for key_name), DECL_ATTRIBUTES (for attributes).
   4880 
   4881    'key_name' is an identifier node (and is optional as you can omit
   4882    it in Objective-C methods).
   4883    'arg_type' is a tree list (and is optional too if no parameter type
   4884    was specified).
   4885    'arg_name' is an identifier node and is required.
   4886    'attributes' is an optional tree containing parameter attributes.  */
   4887 tree
   4888 objc_build_keyword_decl (tree key_name, tree arg_type,
   4889 			 tree arg_name, tree attributes)
   4890 {
   4891   tree keyword_decl;
   4892 
   4893   if (flag_objc1_only && attributes)
   4894     error_at (input_location, "method argument attributes are not available in Objective-C 1.0");
   4895 
   4896   /* If no type is specified, default to "id".  */
   4897   arg_type = adjust_type_for_id_default (arg_type);
   4898 
   4899   keyword_decl = make_node (KEYWORD_DECL);
   4900 
   4901   TREE_TYPE (keyword_decl) = arg_type;
   4902   KEYWORD_ARG_NAME (keyword_decl) = arg_name;
   4903   KEYWORD_KEY_NAME (keyword_decl) = key_name;
   4904   DECL_ATTRIBUTES (keyword_decl) = attributes;
   4905 
   4906   return keyword_decl;
   4907 }
   4908 
   4909 /* Given a chain of keyword_decl's, synthesize the full keyword selector.  */
   4910 static tree
   4911 build_keyword_selector (tree selector)
   4912 {
   4913   int len = 0;
   4914   tree key_chain, key_name;
   4915   char *buf;
   4916 
   4917   /* Scan the selector to see how much space we'll need.  */
   4918   for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
   4919     {
   4920       switch (TREE_CODE (selector))
   4921 	{
   4922 	case KEYWORD_DECL:
   4923 	  key_name = KEYWORD_KEY_NAME (key_chain);
   4924 	  break;
   4925 	case TREE_LIST:
   4926 	  key_name = TREE_PURPOSE (key_chain);
   4927 	  break;
   4928 	default:
   4929 	  gcc_unreachable ();
   4930 	}
   4931 
   4932       if (key_name)
   4933 	len += IDENTIFIER_LENGTH (key_name) + 1;
   4934       else
   4935 	/* Just a ':' arg.  */
   4936 	len++;
   4937     }
   4938 
   4939   buf = (char *) alloca (len + 1);
   4940   /* Start the buffer out as an empty string.  */
   4941   buf[0] = '\0';
   4942 
   4943   for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
   4944     {
   4945       switch (TREE_CODE (selector))
   4946 	{
   4947 	case KEYWORD_DECL:
   4948 	  key_name = KEYWORD_KEY_NAME (key_chain);
   4949 	  break;
   4950 	case TREE_LIST:
   4951 	  key_name = TREE_PURPOSE (key_chain);
   4952 	  /* The keyword decl chain will later be used as a function
   4953 	     argument chain.  Unhook the selector itself so as to not
   4954 	     confuse other parts of the compiler.  */
   4955 	  TREE_PURPOSE (key_chain) = NULL_TREE;
   4956 	  break;
   4957 	default:
   4958 	  gcc_unreachable ();
   4959 	}
   4960 
   4961       if (key_name)
   4962 	strcat (buf, IDENTIFIER_POINTER (key_name));
   4963       strcat (buf, ":");
   4964     }
   4965 
   4966   return get_identifier_with_length (buf, len);
   4967 }
   4968 
   4969 /* Used for declarations and definitions.  */
   4970 
   4971 static tree
   4972 build_method_decl (enum tree_code code, tree ret_type, tree selector,
   4973 		   tree add_args, bool ellipsis)
   4974 {
   4975   tree method_decl;
   4976 
   4977   /* If no type is specified, default to "id".  */
   4978   ret_type = adjust_type_for_id_default (ret_type);
   4979 
   4980   /* Note how a method_decl has a TREE_TYPE which is not the function
   4981      type of the function implementing the method, but only the return
   4982      type of the method.  We may want to change this, and store the
   4983      entire function type in there (eg, it may be used to simplify
   4984      dealing with attributes below).  */
   4985   method_decl = make_node (code);
   4986   TREE_TYPE (method_decl) = ret_type;
   4987 
   4988   /* If we have a keyword selector, create an identifier_node that
   4989      represents the full selector name (`:' included)...  */
   4990   if (TREE_CODE (selector) == KEYWORD_DECL)
   4991     {
   4992       METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
   4993       METHOD_SEL_ARGS (method_decl) = selector;
   4994       METHOD_ADD_ARGS (method_decl) = add_args;
   4995       METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
   4996     }
   4997   else
   4998     {
   4999       METHOD_SEL_NAME (method_decl) = selector;
   5000       METHOD_SEL_ARGS (method_decl) = NULL_TREE;
   5001       METHOD_ADD_ARGS (method_decl) = NULL_TREE;
   5002     }
   5003 
   5004   return method_decl;
   5005 }
   5006 
   5007 /* This routine processes objective-c method attributes. */
   5008 
   5009 static void
   5010 objc_decl_method_attributes (tree *node, tree attributes, int flags)
   5011 {
   5012   /* TODO: Replace the hackery below.  An idea would be to store the
   5013      full function type in the method declaration (for example in
   5014      TREE_TYPE) and then expose ObjC method declarations to c-family
   5015      and they could deal with them by simply treating them as
   5016      functions.  */
   5017 
   5018   /* Because of the dangers in the hackery below, we filter out any
   5019      attribute that we do not know about.  For the ones we know about,
   5020      we know that they work with the hackery.  For the other ones,
   5021      there is no guarantee, so we have to filter them out.  */
   5022   tree filtered_attributes = NULL_TREE;
   5023 
   5024   if (attributes)
   5025     {
   5026       tree attribute;
   5027       for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
   5028 	{
   5029 	  tree name = TREE_PURPOSE (attribute);
   5030 
   5031 	  if (is_attribute_p  ("deprecated", name)
   5032 	      || is_attribute_p ("unavailable", name)
   5033 	      || is_attribute_p ("sentinel", name)
   5034 	      || is_attribute_p ("noreturn", name))
   5035 	    {
   5036 	      /* An attribute that we support; add it to the filtered
   5037 		 attributes.  */
   5038 	      filtered_attributes = chainon (filtered_attributes,
   5039 					     copy_node (attribute));
   5040 	    }
   5041 	  else if (is_attribute_p ("format", name))
   5042 	    {
   5043 	      /* "format" is special because before adding it to the
   5044 		 filtered attributes we need to adjust the specified
   5045 		 format by adding the hidden function parameters for
   5046 		 an Objective-C method (self, _cmd).  */
   5047 	      tree new_attribute = copy_node (attribute);
   5048 
   5049 	      /* Check the arguments specified with the attribute, and
   5050 		 modify them adding 2 for the two hidden arguments.
   5051 		 Note how this differs from C++; according to the
   5052 		 specs, C++ does not do it so you have to add the +1
   5053 		 yourself.  For Objective-C, instead, the compiler
   5054 		 adds the +2 for you.  */
   5055 
   5056 	      /* The attribute arguments have not been checked yet, so
   5057 		 we need to be careful as they could be missing or
   5058 		 invalid.  If anything looks wrong, we skip the
   5059 		 process and the compiler will complain about it later
   5060 		 when it validates the attribute.  */
   5061 	      /* Check that we have at least three arguments.  */
   5062 	      if (TREE_VALUE (new_attribute)
   5063 		  && TREE_CHAIN (TREE_VALUE (new_attribute))
   5064 		  && TREE_CHAIN (TREE_CHAIN (TREE_VALUE (new_attribute))))
   5065 		{
   5066 		  tree second_argument = TREE_CHAIN (TREE_VALUE (new_attribute));
   5067 		  tree third_argument = TREE_CHAIN (second_argument);
   5068 		  tree number;
   5069 
   5070 		  /* This is the second argument, the "string-index",
   5071 		     which specifies the index of the format string
   5072 		     argument.  Add 2.  */
   5073 		  number = TREE_VALUE (second_argument);
   5074 		  if (number
   5075 		      && TREE_CODE (number) == INTEGER_CST
   5076 		      && wi::to_wide (number) != 0)
   5077 		    TREE_VALUE (second_argument)
   5078 		      = wide_int_to_tree (TREE_TYPE (number),
   5079 					  wi::to_wide (number) + 2);
   5080 
   5081 		  /* This is the third argument, the "first-to-check",
   5082 		     which specifies the index of the first argument to
   5083 		     check.  This could be 0, meaning it is not available,
   5084 		     in which case we don't need to add 2.  Add 2 if not
   5085 		     0.  */
   5086 		  number = TREE_VALUE (third_argument);
   5087 		  if (number
   5088 		      && TREE_CODE (number) == INTEGER_CST
   5089 		      && wi::to_wide (number) != 0)
   5090 		    TREE_VALUE (third_argument)
   5091 		      = wide_int_to_tree (TREE_TYPE (number),
   5092 					  wi::to_wide (number) + 2);
   5093 		}
   5094 	      filtered_attributes = chainon (filtered_attributes,
   5095 					     new_attribute);
   5096 	    }
   5097 	  else if (is_attribute_p ("nonnull", name))
   5098 	    {
   5099 	      /* We need to fixup all the argument indexes by adding 2
   5100 		 for the two hidden arguments of an Objective-C method
   5101 		 invocation, similat to what we do above for the
   5102 		 "format" attribute.  */
   5103 	      /* FIXME: This works great in terms of implementing the
   5104 		 functionality, but the warnings that are produced by
   5105 		 nonnull do mention the argument index (while the
   5106 		 format ones don't).  For example, you could get
   5107 		 "warning: null argument where non-null required
   5108 		 (argument 3)".  Now in that message, "argument 3"
   5109 		 includes the 2 hidden arguments; it would be much
   5110 		 more friendly to call it "argument 1", as that would
   5111 		 be consistent with __attribute__ ((nonnnull (1))).
   5112 		 To do this, we'd need to have the C family code that
   5113 		 checks the arguments know about adding/removing 2 to
   5114 		 the argument index ... or alternatively we could
   5115 		 maybe store the "printable" argument index in
   5116 		 addition to the actual argument index ?  Some
   5117 		 refactoring is needed to do this elegantly.  */
   5118 	      tree new_attribute = copy_node (attribute);
   5119 	      tree argument = TREE_VALUE (attribute);
   5120 	      while (argument != NULL_TREE)
   5121 		{
   5122 		  /* Get the value of the argument and add 2.  */
   5123 		  tree number = TREE_VALUE (argument);
   5124 		  if (number && TREE_CODE (number) == INTEGER_CST
   5125 		      && wi::to_wide (number) != 0)
   5126 		    TREE_VALUE (argument)
   5127 		      = wide_int_to_tree (TREE_TYPE (number),
   5128 					  wi::to_wide (number) + 2);
   5129 		  argument = TREE_CHAIN (argument);
   5130 		}
   5131 
   5132 	      filtered_attributes = chainon (filtered_attributes,
   5133 					     new_attribute);
   5134 	    }
   5135 	  else
   5136 	    warning (OPT_Wattributes, "%qE attribute directive ignored", name);
   5137 	}
   5138     }
   5139 
   5140   if (filtered_attributes)
   5141     {
   5142       /* This hackery changes the TREE_TYPE of the ObjC method
   5143 	 declaration to be a function type, so that decl_attributes
   5144 	 will treat the ObjC method as if it was a function.  Some
   5145 	 attributes (sentinel, format) will be applied to the function
   5146 	 type, changing it in place; so after calling decl_attributes,
   5147 	 we extract the function type attributes and store them in
   5148 	 METHOD_TYPE_ATTRIBUTES.  Some other attributes (noreturn,
   5149 	 deprecated) are applied directly to the method declaration
   5150 	 (by setting TREE_DEPRECATED and TREE_THIS_VOLATILE) so there
   5151 	 is nothing to do.  */
   5152       tree saved_type = TREE_TYPE (*node);
   5153       TREE_TYPE (*node)
   5154 	= build_function_type_for_method (TREE_VALUE (saved_type), *node,
   5155 					  METHOD_REF, 0);
   5156       decl_attributes (node, filtered_attributes, flags);
   5157       METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
   5158       TREE_TYPE (*node) = saved_type;
   5159     }
   5160 }
   5161 
   5162 bool
   5163 objc_method_decl (enum tree_code opcode)
   5164 {
   5165   return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
   5166 }
   5167 
   5168 /* Return a function type for METHOD with RETURN_TYPE.  CONTEXT is
   5169    either METHOD_DEF or METHOD_REF, indicating whether we are defining a
   5170    method or calling one.  SUPER_FLAG indicates whether this is a send
   5171    to super; this makes a difference for the NeXT calling sequence in
   5172    which the lookup and the method call are done together.  If METHOD is
   5173    NULL, user-defined arguments (i.e., beyond self and _cmd) shall be
   5174    represented as varargs.  */
   5175 
   5176 tree
   5177 build_function_type_for_method (tree return_type, tree method,
   5178 				int context, bool super_flag)
   5179 {
   5180   vec<tree, va_gc> *argtypes = make_tree_vector ();
   5181   tree t, ftype;
   5182   bool is_varargs = false;
   5183 
   5184   (*runtime.get_arg_type_list_base) (&argtypes, method, context, super_flag);
   5185 
   5186   /* No actual method prototype given; remaining args passed as varargs.  */
   5187   if (method == NULL_TREE)
   5188     {
   5189       is_varargs = true;
   5190       goto build_ftype;
   5191     }
   5192 
   5193   for (t = METHOD_SEL_ARGS (method); t; t = DECL_CHAIN (t))
   5194     {
   5195       tree arg_type = TREE_VALUE (TREE_TYPE (t));
   5196 
   5197       /* Decay argument types for the underlying C function as
   5198          appropriate.  */
   5199       arg_type = objc_decay_parm_type (arg_type);
   5200 
   5201       vec_safe_push (argtypes, arg_type);
   5202     }
   5203 
   5204   if (METHOD_ADD_ARGS (method))
   5205     {
   5206       for (t = TREE_CHAIN (METHOD_ADD_ARGS (method));
   5207 	   t; t = TREE_CHAIN (t))
   5208 	{
   5209 	  tree arg_type = TREE_TYPE (TREE_VALUE (t));
   5210 
   5211 	  arg_type = objc_decay_parm_type (arg_type);
   5212 
   5213 	  vec_safe_push (argtypes, arg_type);
   5214 	}
   5215 
   5216       if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
   5217 	is_varargs = true;
   5218     }
   5219 
   5220  build_ftype:
   5221   if (is_varargs)
   5222     ftype = build_varargs_function_type_vec (return_type, argtypes);
   5223   else
   5224     ftype = build_function_type_vec (return_type, argtypes);
   5225 
   5226   release_tree_vector (argtypes);
   5227   return ftype;
   5228 }
   5229 
   5230 /* The 'method' argument is a tree; this tree could either be a single
   5231    method, which is returned, or could be a TREE_VEC containing a list
   5232    of methods.  In that case, the first one is returned, and warnings
   5233    are issued as appropriate.  */
   5234 static tree
   5235 check_duplicates (tree method, int methods, int is_class)
   5236 {
   5237   tree first_method;
   5238   size_t i;
   5239 
   5240   if (method == NULL_TREE)
   5241     return NULL_TREE;
   5242 
   5243   if (TREE_CODE (method) != TREE_VEC)
   5244     return method;
   5245 
   5246   /* We have two or more methods with the same name but different
   5247      types.  */
   5248   first_method = TREE_VEC_ELT (method, 0);
   5249 
   5250   /* But just how different are those types?  If
   5251      -Wno-strict-selector-match is specified, we shall not complain if
   5252      the differences are solely among types with identical size and
   5253      alignment.  */
   5254   if (!warn_strict_selector_match)
   5255     {
   5256       for (i = 0; i < (size_t) TREE_VEC_LENGTH (method); i++)
   5257 	if (!comp_proto_with_proto (first_method, TREE_VEC_ELT (method, i), 0))
   5258 	  goto issue_warning;
   5259 
   5260       return first_method;
   5261     }
   5262 
   5263  issue_warning:
   5264   if (methods)
   5265     {
   5266       bool type = TREE_CODE (first_method) == INSTANCE_METHOD_DECL;
   5267 
   5268       warning_at (input_location, 0,
   5269 		  "multiple methods named %<%c%E%> found",
   5270 		  (is_class ? '+' : '-'),
   5271 		  METHOD_SEL_NAME (first_method));
   5272       inform (DECL_SOURCE_LOCATION (first_method), "using %<%c%s%>",
   5273 	      (type ? '-' : '+'),
   5274 	      identifier_to_locale (gen_method_decl (first_method)));
   5275     }
   5276   else
   5277     {
   5278       bool type = TREE_CODE (first_method) == INSTANCE_METHOD_DECL;
   5279 
   5280       warning_at (input_location, 0,
   5281 		  "multiple selectors named %<%c%E%> found",
   5282 		  (is_class ? '+' : '-'),
   5283 		  METHOD_SEL_NAME (first_method));
   5284       inform (DECL_SOURCE_LOCATION (first_method), "found %<%c%s%>",
   5285 	      (type ? '-' : '+'),
   5286 	      identifier_to_locale (gen_method_decl (first_method)));
   5287     }
   5288 
   5289   for (i = 0; i < (size_t) TREE_VEC_LENGTH (method); i++)
   5290     {
   5291       bool type = TREE_CODE (TREE_VEC_ELT (method, i)) == INSTANCE_METHOD_DECL;
   5292 
   5293       inform (DECL_SOURCE_LOCATION (TREE_VEC_ELT (method, i)), "also found %<%c%s%>",
   5294 	      (type ? '-' : '+'),
   5295 	      identifier_to_locale (gen_method_decl (TREE_VEC_ELT (method, i))));
   5296     }
   5297 
   5298   return first_method;
   5299 }
   5300 
   5301 /* If RECEIVER is a class reference, return the identifier node for
   5302    the referenced class.  RECEIVER is created by objc_get_class_reference,
   5303    so we check the exact form created depending on which runtimes are
   5304    used.  */
   5305 
   5306 static tree
   5307 receiver_is_class_object (tree receiver, int self, int super)
   5308 {
   5309   tree exp, arg;
   5310 
   5311   /* The receiver is 'self' or 'super' in the context of a class method.  */
   5312   if (objc_method_context
   5313       && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
   5314       && (self || super))
   5315     return (super
   5316 	    ? CLASS_SUPER_NAME (implementation_template)
   5317 	    : CLASS_NAME (implementation_template));
   5318 
   5319   /* The runtime might encapsulate things its own way.  */
   5320   exp = (*runtime.receiver_is_class_object) (receiver);
   5321   if (exp)
   5322     return exp;
   5323 
   5324   /* The receiver is a function call that returns an id.  Check if
   5325      it is a call to objc_getClass, if so, pick up the class name.
   5326 
   5327      This is required by the GNU runtime, which compiles
   5328 
   5329        [NSObject alloc]
   5330 
   5331      into
   5332 
   5333        [objc_get_class ("NSObject") alloc];
   5334 
   5335      and then, to check that the receiver responds to the +alloc
   5336      method, needs to be able to determine that the objc_get_class()
   5337      call returns the NSObject class and not just a generic Class
   5338      pointer.
   5339 
   5340      But, traditionally this is enabled for all runtimes, not just the
   5341      GNU one, which means that the compiler is smarter than you'd
   5342      expect when dealing with objc_getClass().  For example, with the
   5343      Apple runtime, in the code
   5344 
   5345        [objc_getClass ("NSObject")  alloc];
   5346 
   5347      the compiler will recognize the objc_getClass() call as special
   5348      (due to the code below) and so will know that +alloc is called on
   5349      the 'NSObject' class, and can perform the corresponding checks.
   5350 
   5351      Programmers can disable this behavior by casting the results of
   5352      objc_getClass() to 'Class' (this may seem weird because
   5353      objc_getClass() is already declared to return 'Class', but the
   5354      compiler treats it as a special function).  This may be useful if
   5355      the class is never declared, and the compiler would complain
   5356      about a missing @interface for it.  Then, you can do
   5357 
   5358        [(Class)objc_getClass ("MyClassNeverDeclared")  alloc];
   5359 
   5360      to silence the warnings.  */
   5361   if (TREE_CODE (receiver) == CALL_EXPR
   5362       && (exp = CALL_EXPR_FN (receiver))
   5363       && TREE_CODE (exp) == ADDR_EXPR
   5364       && (exp = TREE_OPERAND (exp, 0))
   5365       && TREE_CODE (exp) == FUNCTION_DECL
   5366       /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
   5367 	 prototypes for objc_get_class().  Thankfully, they seem to share the
   5368 	 same function type.  */
   5369       && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
   5370       && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), runtime.tag_getclass)
   5371       /* We have a call to objc_get_class/objc_getClass!  */
   5372       && (arg = CALL_EXPR_ARG (receiver, 0)))
   5373     {
   5374       STRIP_NOPS (arg);
   5375       if (TREE_CODE (arg) == ADDR_EXPR
   5376 	  && (arg = TREE_OPERAND (arg, 0))
   5377 	  && TREE_CODE (arg) == STRING_CST)
   5378 	/* Finally, we have the class name.  */
   5379 	return get_identifier (TREE_STRING_POINTER (arg));
   5380     }
   5381   return 0;
   5382 }
   5383 
   5384 /* If we are currently building a message expr, this holds
   5385    the identifier of the selector of the message.  This is
   5386    used when printing warnings about argument mismatches.  */
   5387 
   5388 static tree current_objc_message_selector = 0;
   5389 
   5390 tree
   5391 objc_message_selector (void)
   5392 {
   5393   return current_objc_message_selector;
   5394 }
   5395 
   5396 /* Construct an expression for sending a message.
   5397    MESS has the object to send to in TREE_PURPOSE
   5398    and the argument list (including selector) in TREE_VALUE.
   5399 
   5400    (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
   5401    (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...);  */
   5402 
   5403 tree
   5404 objc_build_message_expr (tree receiver, tree message_args)
   5405 {
   5406   tree sel_name;
   5407 #ifdef OBJCPLUS
   5408   tree args = TREE_PURPOSE (message_args);
   5409 #else
   5410   tree args = message_args;
   5411 #endif
   5412   tree method_params = NULL_TREE;
   5413 
   5414   if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
   5415     return error_mark_node;
   5416 
   5417   /* Obtain the full selector name.  */
   5418   switch (TREE_CODE (args))
   5419     {
   5420     case IDENTIFIER_NODE:
   5421       /* A unary selector.  */
   5422       sel_name = args;
   5423       break;
   5424     case TREE_LIST:
   5425       sel_name = build_keyword_selector (args);
   5426       break;
   5427     default:
   5428       gcc_unreachable ();
   5429     }
   5430 
   5431   /* Build the parameter list to give to the method.  */
   5432   if (TREE_CODE (args) == TREE_LIST)
   5433 #ifdef OBJCPLUS
   5434     method_params = chainon (args, TREE_VALUE (message_args));
   5435 #else
   5436     {
   5437       tree chain = args, prev = NULL_TREE;
   5438 
   5439       /* We have a keyword selector--check for comma expressions.  */
   5440       while (chain)
   5441 	{
   5442 	  tree element = TREE_VALUE (chain);
   5443 
   5444 	  /* We have a comma expression, must collapse...  */
   5445 	  if (TREE_CODE (element) == TREE_LIST)
   5446 	    {
   5447 	      if (prev)
   5448 		TREE_CHAIN (prev) = element;
   5449 	      else
   5450 		args = element;
   5451 	    }
   5452 	  prev = chain;
   5453 	  chain = TREE_CHAIN (chain);
   5454         }
   5455       method_params = args;
   5456     }
   5457 #endif
   5458 
   5459 #ifdef OBJCPLUS
   5460   if (processing_template_decl)
   5461     /* Must wait until template instantiation time.  */
   5462     return build_min_nt_loc (UNKNOWN_LOCATION, MESSAGE_SEND_EXPR, receiver,
   5463 			     sel_name, method_params);
   5464 #endif
   5465 
   5466   return objc_finish_message_expr (receiver, sel_name, method_params, NULL);
   5467 }
   5468 
   5469 /* Look up method SEL_NAME that would be suitable for receiver
   5470    of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
   5471    nonzero), and report on any duplicates.  */
   5472 
   5473 static tree
   5474 lookup_method_in_hash_lists (tree sel_name, int is_class)
   5475 {
   5476   tree method_prototype = OBJC_MAP_NOT_FOUND;
   5477 
   5478   if (!is_class)
   5479     method_prototype = objc_map_get (instance_method_map, sel_name);
   5480 
   5481   if (method_prototype == OBJC_MAP_NOT_FOUND)
   5482     {
   5483       method_prototype = objc_map_get (class_method_map, sel_name);
   5484       is_class = 1;
   5485 
   5486       if (method_prototype == OBJC_MAP_NOT_FOUND)
   5487 	return NULL_TREE;
   5488     }
   5489 
   5490   return check_duplicates (method_prototype, 1, is_class);
   5491 }
   5492 
   5493 /* The 'objc_finish_message_expr' routine is called from within
   5494    'objc_build_message_expr' for non-template functions.  In the case of
   5495    C++ template functions, it is called from 'build_expr_from_tree'
   5496    (in decl2.cc) after RECEIVER and METHOD_PARAMS have been expanded.
   5497 
   5498    If the method_prototype_avail argument is NULL, then we warn
   5499    if the method being used is deprecated.  If it is not NULL, instead
   5500    of deprecating, we set *method_prototype_avail to the method
   5501    prototype that was used and is deprecated.  This is useful for
   5502    getter calls that are always generated when compiling dot-syntax
   5503    expressions, even if they may not be used.  In that case, we don't
   5504    want the warning immediately; we produce it (if needed) at gimplify
   5505    stage when we are sure that the deprecated getter is being
   5506    used.  */
   5507 tree
   5508 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params,
   5509 			  tree *method_prototype_avail)
   5510 {
   5511   tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
   5512   tree retval, class_tree;
   5513   int self, super, have_cast;
   5514 
   5515   STRIP_ANY_LOCATION_WRAPPER (receiver);
   5516 
   5517   /* We have used the receiver, so mark it as read.  */
   5518   mark_exp_read (receiver);
   5519 
   5520   /* Extract the receiver of the message, as well as its type
   5521      (where the latter may take the form of a cast or be inferred
   5522      from the implementation context).  */
   5523   rtype = receiver;
   5524   while (TREE_CODE (rtype) == COMPOUND_EXPR
   5525 	 || TREE_CODE (rtype) == MODIFY_EXPR
   5526 	 || CONVERT_EXPR_P (rtype)
   5527 	 || TREE_CODE (rtype) == COMPONENT_REF)
   5528     rtype = TREE_OPERAND (rtype, 0);
   5529 
   5530   /* self is 1 if this is a message to self, 0 otherwise  */
   5531   self = (rtype == self_decl);
   5532 
   5533   /* super is 1 if this is a message to super, 0 otherwise.  */
   5534   super = (rtype == UOBJC_SUPER_decl);
   5535 
   5536   /* rtype is the type of the receiver.  */
   5537   rtype = TREE_TYPE (receiver);
   5538 
   5539   /* have_cast is 1 if the receiver is casted.  */
   5540   have_cast = (TREE_CODE (receiver) == NOP_EXPR
   5541 	       || (TREE_CODE (receiver) == COMPOUND_EXPR
   5542 		   && !IS_SUPER (rtype)));
   5543 
   5544   /* If we are calling [super dealloc], reset our warning flag.  */
   5545   if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
   5546     should_call_super_dealloc = 0;
   5547 
   5548   /* If the receiver is a class object, retrieve the corresponding
   5549      @interface, if one exists.  class_tree is the class name
   5550      identifier, or NULL_TREE if this is not a class method or the
   5551      class name could not be determined (as in the case "Class c; [c
   5552      method];").  */
   5553   class_tree = receiver_is_class_object (receiver, self, super);
   5554 
   5555   /* Now determine the receiver type (if an explicit cast has not been
   5556      provided).  */
   5557   if (!have_cast)
   5558     {
   5559       if (class_tree)
   5560 	{
   5561 	  /* We are here when we have no cast, and we have a class
   5562 	     name.  So, this is a plain method to a class object, as
   5563 	     in [NSObject alloc].  Find the interface corresponding to
   5564 	     the class name.  */
   5565 	  rtype = lookup_interface (class_tree);
   5566 
   5567 	  if (rtype == NULL_TREE)
   5568 	    {
   5569 	      /* If 'rtype' is NULL_TREE at this point it means that
   5570 		 we have seen no @interface corresponding to that
   5571 		 class name, only a @class declaration (alternatively,
   5572 		 this was a call such as [objc_getClass("SomeClass")
   5573 		 alloc], where we've never seen the @interface of
   5574 		 SomeClass).  So, we have a class name (class_tree)
   5575 		 but no actual details of the class methods.  We won't
   5576 		 be able to check that the class responds to the
   5577 		 method, and we will have to guess the method
   5578 		 prototype.  Emit a warning, then keep going (this
   5579 		 will use any method with a matching name, as if the
   5580 		 receiver was of type 'Class').  */
   5581 	      warning (0, "%<@interface%> of class %qE not found",
   5582 		       class_tree);
   5583 	    }
   5584 	}
   5585       /* Handle `self' and `super'.  */
   5586       else if (super)
   5587 	{
   5588 	  if (!CLASS_SUPER_NAME (implementation_template))
   5589 	    {
   5590 	      error ("no super class declared in @interface for %qE",
   5591 		     CLASS_NAME (implementation_template));
   5592 	      return error_mark_node;
   5593 	    }
   5594 	  rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
   5595 	}
   5596       else if (self)
   5597 	rtype = lookup_interface (CLASS_NAME (implementation_template));
   5598     }
   5599 
   5600   if (objc_is_id (rtype))
   5601     {
   5602       /* The receiver is of type 'id' or 'Class' (with or without some
   5603 	 protocols attached to it).  */
   5604 
   5605       /* We set class_tree to the identifier for 'Class' if this is a
   5606 	 class method, and to NULL_TREE if not.  */
   5607       class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
   5608 
   5609       /* 'rprotos' is the list of protocols that the receiver
   5610 	 supports.  */
   5611       rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
   5612 		 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
   5613 		 : NULL_TREE);
   5614 
   5615       /* We have no information on the type, and we set it to
   5616 	 NULL_TREE.  */
   5617       rtype = NULL_TREE;
   5618 
   5619       /* If there are any protocols, check that the method we are
   5620 	 calling appears in the protocol list.  If there are no
   5621 	 protocols, this is a message to 'id' or 'Class' and we accept
   5622 	 any method that exists.  */
   5623       if (rprotos)
   5624 	{
   5625 	  /* If messaging 'id <Protos>' or 'Class <Proto>', first
   5626 	     search in protocols themselves for the method
   5627 	     prototype.  */
   5628 	  method_prototype
   5629 	    = lookup_method_in_protocol_list (rprotos, sel_name,
   5630 					      class_tree != NULL_TREE);
   5631 
   5632 	  /* If messaging 'Class <Proto>' but did not find a class
   5633 	     method prototype, search for an instance method instead,
   5634 	     and warn about having done so.  */
   5635 	  if (!method_prototype && !rtype && class_tree != NULL_TREE)
   5636 	    {
   5637 	      method_prototype
   5638 		= lookup_method_in_protocol_list (rprotos, sel_name, 0);
   5639 
   5640 	      if (method_prototype)
   5641 		warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
   5642 			 sel_name, sel_name);
   5643 	    }
   5644 	}
   5645     }
   5646   else if (rtype)
   5647     {
   5648       /* We have a receiver type which is more specific than 'id' or
   5649 	 'Class'.  */
   5650       tree orig_rtype = rtype;
   5651 
   5652       if (TREE_CODE (rtype) == POINTER_TYPE)
   5653 	rtype = TREE_TYPE (rtype);
   5654       /* Traverse typedef aliases */
   5655       while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
   5656 	     && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
   5657 	     && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
   5658 	rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
   5659       if (TYPED_OBJECT (rtype))
   5660 	{
   5661 	  rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
   5662 	  rtype = TYPE_OBJC_INTERFACE (rtype);
   5663 	}
   5664       if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
   5665 	{
   5666 	  /* If we could not find an @interface declaration, we must
   5667 	     have only seen a @class declaration; so, we cannot say
   5668 	     anything more intelligent about which methods the
   5669 	     receiver will understand.  Note that this only happens
   5670 	     for instance methods; for class methods to a class where
   5671 	     we have only seen a @class declaration,
   5672 	     lookup_interface() above would have set rtype to
   5673 	     NULL_TREE.  */
   5674 	  if (rprotos)
   5675 	    {
   5676 	      /* We could not find an @interface declaration, yet, if
   5677 		 there are protocols attached to the type, we can
   5678 		 still look up the method in the protocols.  Ie, we
   5679 		 are in the following case:
   5680 
   5681 		 @class MyClass;
   5682 		 MyClass<MyProtocol> *x;
   5683 		 [x method];
   5684 
   5685 		 If 'MyProtocol' has the method 'method', we can check
   5686 		 and retrieve the method prototype.  */
   5687 	      method_prototype
   5688 		= lookup_method_in_protocol_list (rprotos, sel_name, 0);
   5689 
   5690 	      /* At this point, if we have found the method_prototype,
   5691 		 we are quite happy.  The details of the class are
   5692 		 irrelevant.  If we haven't found it, a warning will
   5693 		 have been produced that the method could not be found
   5694 		 in the protocol, and we won't produce further
   5695 		 warnings (please note that this means that "@class
   5696 		 MyClass; MyClass <MyProtocol> *x;" is exactly
   5697 		 equivalent to "id <MyProtocol> x", which isn't too
   5698 		 satisfactory but it's not easy to see how to do
   5699 		 better).  */
   5700 	    }
   5701 	  else
   5702 	    {
   5703 	      if (rtype)
   5704 		{
   5705 		  /* We could not find an @interface declaration, and
   5706 		     there are no protocols attached to the receiver,
   5707 		     so we can't complete the check that the receiver
   5708 		     responds to the method, and we can't retrieve the
   5709 		     method prototype.  But, because the receiver has
   5710 		     a well-specified class, the programmer did want
   5711 		     this check to be performed.  Emit a warning, then
   5712 		     keep going as if it was an 'id'.  To remove the
   5713 		     warning, either include an @interface for the
   5714 		     class, or cast the receiver to 'id'.  Note that
   5715 		     rtype is an IDENTIFIER_NODE at this point.  */
   5716 		  warning (0, "%<@interface%> of class %qE not found", rtype);
   5717 		}
   5718 	    }
   5719 
   5720 	  rtype = NULL_TREE;
   5721 	}
   5722       else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
   5723 	  || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
   5724 	{
   5725 	  /* We have a valid ObjC class name with an associated
   5726 	     @interface.  Look up the method name in the published
   5727 	     @interface for the class (and its superclasses).  */
   5728 	  method_prototype
   5729 	    = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
   5730 
   5731 	  /* If the method was not found in the @interface, it may still
   5732 	     exist locally as part of the @implementation.  */
   5733 	  if (!method_prototype && objc_implementation_context
   5734 	     && CLASS_NAME (objc_implementation_context)
   5735 		== OBJC_TYPE_NAME (rtype))
   5736 	    method_prototype
   5737 	      = lookup_method
   5738 		((class_tree
   5739 		  ? CLASS_CLS_METHODS (objc_implementation_context)
   5740 		  : CLASS_NST_METHODS (objc_implementation_context)),
   5741 		  sel_name);
   5742 
   5743 	  /* If we haven't found a candidate method by now, try looking for
   5744 	     it in the protocol list.  */
   5745 	  if (!method_prototype && rprotos)
   5746 	    method_prototype
   5747 	      = lookup_method_in_protocol_list (rprotos, sel_name,
   5748 						class_tree != NULL_TREE);
   5749 	}
   5750       else
   5751 	{
   5752 	  /* We have a type, but it's not an Objective-C type (!).  */
   5753 	  warning (0, "invalid receiver type %qs",
   5754 		   identifier_to_locale (gen_type_name (orig_rtype)));
   5755 	  /* After issuing the "invalid receiver" warning, perform method
   5756 	     lookup as if we were messaging 'id'.  */
   5757 	  rtype = rprotos = NULL_TREE;
   5758 	}
   5759     }
   5760   /* Note that rtype could also be NULL_TREE.  This happens if we are
   5761      messaging a class by name, but the class was only
   5762      forward-declared using @class.  */
   5763 
   5764   /* For 'id' or 'Class' receivers, search in the global hash table as
   5765      a last resort.  For all receivers, warn if protocol searches have
   5766      failed.  */
   5767   if (!method_prototype)
   5768     {
   5769       if (rprotos)
   5770 	warning (0, "%<%c%E%> not found in protocol(s)",
   5771 		 (class_tree ? '+' : '-'),
   5772 		 sel_name);
   5773 
   5774       if (!rtype)
   5775 	method_prototype
   5776 	  = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
   5777     }
   5778 
   5779   if (!method_prototype)
   5780     {
   5781       static bool warn_missing_methods = false;
   5782 
   5783       if (rtype)
   5784 	warning (0, "%qE may not respond to %<%c%E%>",
   5785 		 OBJC_TYPE_NAME (rtype),
   5786 		 (class_tree ? '+' : '-'),
   5787 		 sel_name);
   5788       /* If we are messaging an 'id' or 'Class' object and made it here,
   5789 	 then we have failed to find _any_ instance or class method,
   5790 	 respectively.  */
   5791       else
   5792 	warning (0, "no %<%c%E%> method found",
   5793 		 (class_tree ? '+' : '-'),
   5794 		 sel_name);
   5795 
   5796       if (!warn_missing_methods)
   5797 	{
   5798 	  warning_at (input_location,
   5799 		      0, "(messages without a matching method signature "
   5800 		      "will be assumed to return %<id%> and accept "
   5801 		      "%<...%> as arguments)");
   5802 	  warn_missing_methods = true;
   5803 	}
   5804     }
   5805   else
   5806     {
   5807       /* Warn if the method is deprecated, but not if the receiver is
   5808 	 a generic 'id'.  'id' is used to cast an object to a generic
   5809 	 object of an unspecified class; in that case, we'll use
   5810 	 whatever method prototype we can find to get the method
   5811 	 argument and return types, but it is not appropriate to
   5812 	 produce deprecation warnings since we don't know the class
   5813 	 that the object will be of at runtime.  The @interface(s) for
   5814 	 that class may not even be available to the compiler right
   5815 	 now, and it is perfectly possible that the method is marked
   5816 	 as non-deprecated in such @interface(s).
   5817 
   5818 	 In practice this makes sense since casting an object to 'id'
   5819 	 is often used precisely to turn off warnings associated with
   5820 	 the object being of a particular class.  */
   5821       if (TREE_UNAVAILABLE (method_prototype) && rtype != NULL_TREE)
   5822 	{
   5823 	  if (method_prototype_avail)
   5824 	    *method_prototype_avail = method_prototype;
   5825 	  else
   5826 	    error_unavailable_use (method_prototype, NULL_TREE);
   5827 	}
   5828       else if (TREE_DEPRECATED (method_prototype) && rtype != NULL_TREE)
   5829 	{
   5830 	  if (method_prototype_avail)
   5831 	    *method_prototype_avail = method_prototype;
   5832 	  else
   5833 	    warn_deprecated_use (method_prototype, NULL_TREE);
   5834 	}
   5835     }
   5836 
   5837   /* Save the selector name for printing error messages.  */
   5838   current_objc_message_selector = sel_name;
   5839 
   5840   /* Build the method call.
   5841      TODO: Get the location from somewhere that will work for delayed
   5842 	   expansion.  */
   5843 
   5844   retval = (*runtime.build_objc_method_call) (input_location, method_prototype,
   5845 					      receiver, rtype, sel_name,
   5846 					      method_params, super);
   5847 
   5848   current_objc_message_selector = 0;
   5849 
   5850   return retval;
   5851 }
   5852 
   5853 
   5855 /* This routine creates a static variable used to implement @protocol(MyProtocol)
   5856    expression. This variable will be initialized to global protocol_t meta-data
   5857    pointer. */
   5858 
   5859 /* This function is called by the parser when (and only when) a
   5860    @protocol() expression is found, in order to compile it.  */
   5861 tree
   5862 objc_build_protocol_expr (tree protoname)
   5863 {
   5864   tree p = lookup_protocol (protoname, /* warn if deprecated */ true,
   5865 			    /* definition_required */ false);
   5866 
   5867   if (!p)
   5868     {
   5869       error ("cannot find protocol declaration for %qE", protoname);
   5870       return error_mark_node;
   5871     }
   5872 
   5873   return (*runtime.get_protocol_reference) (input_location, p);
   5874 }
   5875 
   5876 /* This function is called by the parser when a @selector() expression
   5877    is found, in order to compile it.  It is only called by the parser
   5878    and only to compile a @selector().  LOC is the location of the
   5879    @selector.  */
   5880 tree
   5881 objc_build_selector_expr (location_t loc, tree selnamelist)
   5882 {
   5883   tree selname;
   5884 
   5885   /* Obtain the full selector name.  */
   5886   switch (TREE_CODE (selnamelist))
   5887     {
   5888     case IDENTIFIER_NODE:
   5889       /* A unary selector.  */
   5890       selname = selnamelist;
   5891       break;
   5892     case TREE_LIST:
   5893       selname = build_keyword_selector (selnamelist);
   5894       break;
   5895     default:
   5896       gcc_unreachable ();
   5897     }
   5898 
   5899   /* If we are required to check @selector() expressions as they
   5900      are found, check that the selector has been declared.  */
   5901   if (warn_undeclared_selector)
   5902     {
   5903       /* Look the selector up in the list of all known class and
   5904          instance methods (up to this line) to check that the selector
   5905          exists.  */
   5906       tree method;
   5907 
   5908       /* First try with instance methods.  */
   5909       method = objc_map_get (instance_method_map, selname);
   5910 
   5911       /* If not found, try with class methods.  */
   5912       if (method == OBJC_MAP_NOT_FOUND)
   5913 	{
   5914 	  method = objc_map_get (class_method_map, selname);
   5915 
   5916 	  /* If still not found, print out a warning.  */
   5917 	  if (method == OBJC_MAP_NOT_FOUND)
   5918 	    warning (0, "undeclared selector %qE", selname);
   5919 	}
   5920     }
   5921 
   5922   /* The runtimes do this differently, most particularly, GNU has typed
   5923      selectors, whilst NeXT does not.  */
   5924   return (*runtime.build_selector_reference) (loc, selname, NULL_TREE);
   5925 }
   5926 
   5927 static tree
   5928 build_ivar_reference (tree id)
   5929 {
   5930   tree base;
   5931   if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
   5932     {
   5933       /* Historically, a class method that produced objects (factory
   5934 	 method) would assign `self' to the instance that it
   5935 	 allocated.  This would effectively turn the class method into
   5936 	 an instance method.  Following this assignment, the instance
   5937 	 variables could be accessed.  That practice, while safe,
   5938 	 violates the simple rule that a class method should not refer
   5939 	 to an instance variable.  It's better to catch the cases
   5940 	 where this is done unknowingly than to support the above
   5941 	 paradigm.  */
   5942       warning (0, "instance variable %qE accessed in class method",
   5943 	       id);
   5944       self_decl = convert (objc_instance_type, self_decl); /* cast */
   5945     }
   5946 
   5947   base = build_indirect_ref (input_location, self_decl, RO_ARROW);
   5948   return (*runtime.build_ivar_reference) (input_location, base, id);
   5949 }
   5950 
   5951 static void
   5952 hash_init (void)
   5953 {
   5954   instance_method_map = objc_map_alloc_ggc (1000);
   5955   class_method_map = objc_map_alloc_ggc (1000);
   5956 
   5957   class_name_map = objc_map_alloc_ggc (200);
   5958   alias_name_map = objc_map_alloc_ggc (200);
   5959 
   5960   /* Initialize the hash table used to hold the constant string objects.  */
   5961   string_htab = hash_table<objc_string_hasher>::create_ggc (31);
   5962 }
   5963 
   5964 /* Use the following to add a method to class_method_map or
   5965    instance_method_map.  It will add the method, keyed by the
   5966    METHOD_SEL_NAME.  If the method already exists, but with one or
   5967    more different prototypes, it will store a TREE_VEC in the map,
   5968    with the method prototypes in the vector.  */
   5969 static void
   5970 insert_method_into_method_map (bool class_method, tree method)
   5971 {
   5972   tree method_name = METHOD_SEL_NAME (method);
   5973   tree existing_entry;
   5974   objc_map_t map;
   5975 
   5976   if (class_method)
   5977     map = class_method_map;
   5978   else
   5979     map = instance_method_map;
   5980 
   5981   /* Check if the method already exists in the map.  */
   5982   existing_entry = objc_map_get (map, method_name);
   5983 
   5984   /* If not, we simply add it to the map.  */
   5985   if (existing_entry == OBJC_MAP_NOT_FOUND)
   5986     objc_map_put (map, method_name, method);
   5987   else
   5988     {
   5989       tree new_entry;
   5990 
   5991       /* If an entry already exists, it's more complicated.  We'll
   5992 	 have to check whether the method prototype is the same or
   5993 	 not.  */
   5994       if (TREE_CODE (existing_entry) != TREE_VEC)
   5995 	{
   5996 	  /* If the method prototypes are the same, there is nothing
   5997 	     to do.  */
   5998 	  if (comp_proto_with_proto (method, existing_entry, 1))
   5999 	    return;
   6000 
   6001 	  /* If not, create a vector to store both the method already
   6002 	     in the map, and the new one that we are adding.  */
   6003 	  new_entry = make_tree_vec (2);
   6004 
   6005 	  TREE_VEC_ELT (new_entry, 0) = existing_entry;
   6006 	  TREE_VEC_ELT (new_entry, 1) = method;
   6007 	}
   6008       else
   6009 	{
   6010 	  /* An entry already exists, and it's already a vector.  This
   6011 	     means that at least 2 different method prototypes were
   6012 	     already found, and we're considering registering yet
   6013 	     another one.  */
   6014 	  size_t i;
   6015 
   6016 	  /* Check all the existing prototypes.  If any matches the
   6017 	     one we need to add, there is nothing to do because it's
   6018 	     already there.  */
   6019 	  for (i = 0; i < (size_t) TREE_VEC_LENGTH (existing_entry); i++)
   6020 	    if (comp_proto_with_proto (method, TREE_VEC_ELT (existing_entry, i), 1))
   6021 	      return;
   6022 
   6023 	  /* Else, create a new, bigger vector and add the new method
   6024 	     at the end of it.  This is inefficient but extremely
   6025 	     rare; in any sane program most methods have a single
   6026 	     prototype, and very few, if any, will have more than
   6027 	     2!  */
   6028 	  new_entry = make_tree_vec (TREE_VEC_LENGTH (existing_entry) + 1);
   6029 
   6030 	  /* Copy the methods from the existing vector.  */
   6031 	  for (i = 0; i < (size_t) TREE_VEC_LENGTH (existing_entry); i++)
   6032 	    TREE_VEC_ELT (new_entry, i) = TREE_VEC_ELT (existing_entry, i);
   6033 
   6034 	  /* Add the new method at the end.  */
   6035 	  TREE_VEC_ELT (new_entry, i) = method;
   6036 	}
   6037 
   6038       /* Store the new vector in the map.  */
   6039       objc_map_put (map, method_name, new_entry);
   6040     }
   6041 }
   6042 
   6043 
   6044 static tree
   6046 lookup_method (tree mchain, tree method)
   6047 {
   6048   tree key;
   6049 
   6050   if (TREE_CODE (method) == IDENTIFIER_NODE)
   6051     key = method;
   6052   else
   6053     key = METHOD_SEL_NAME (method);
   6054 
   6055   while (mchain)
   6056     {
   6057       if (METHOD_SEL_NAME (mchain) == key)
   6058 	return mchain;
   6059 
   6060       mchain = DECL_CHAIN (mchain);
   6061     }
   6062   return NULL_TREE;
   6063 }
   6064 
   6065 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance
   6066    method in INTERFACE, along with any categories and protocols
   6067    attached thereto.  If method is not found, and the
   6068    OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS, recursively examine the
   6069    INTERFACE's superclass.  If OBJC_LOOKUP_CLASS is set,
   6070    OBJC_LOOKUP_NO_SUPER is clear, and no suitable class method could
   6071    be found in INTERFACE or any of its superclasses, look for an
   6072    _instance_ method of the same name in the root class as a last
   6073    resort.  This behavior can be turned off by using
   6074    OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS.
   6075 
   6076    If a suitable method cannot be found, return NULL_TREE.  */
   6077 
   6078 static tree
   6079 lookup_method_static (tree interface, tree ident, int flags)
   6080 {
   6081   tree meth = NULL_TREE, root_inter = NULL_TREE;
   6082   tree inter = interface;
   6083   int is_class = (flags & OBJC_LOOKUP_CLASS);
   6084   int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
   6085   int no_instance_methods_of_root_class = (flags & OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS);
   6086 
   6087   while (inter)
   6088     {
   6089       tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
   6090       tree category = inter;
   6091 
   6092       /* First, look up the method in the class itself.  */
   6093       if ((meth = lookup_method (chain, ident)))
   6094 	return meth;
   6095 
   6096       /* Failing that, look for the method in each category of the class.  */
   6097       while ((category = CLASS_CATEGORY_LIST (category)))
   6098 	{
   6099 	  chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
   6100 
   6101 	  /* Check directly in each category.  */
   6102 	  if ((meth = lookup_method (chain, ident)))
   6103 	    return meth;
   6104 
   6105 	  /* Failing that, check in each category's protocols.  */
   6106 	  if (CLASS_PROTOCOL_LIST (category))
   6107 	    {
   6108 	      if ((meth = (lookup_method_in_protocol_list
   6109 			   (CLASS_PROTOCOL_LIST (category), ident, is_class))))
   6110 		return meth;
   6111 	    }
   6112 	}
   6113 
   6114       /* If not found in categories, check in protocols of the main class.  */
   6115       if (CLASS_PROTOCOL_LIST (inter))
   6116 	{
   6117 	  if ((meth = (lookup_method_in_protocol_list
   6118 		       (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
   6119 	    return meth;
   6120 	}
   6121 
   6122       /* If we were instructed not to look in superclasses, don't.  */
   6123       if (no_superclasses)
   6124 	return NULL_TREE;
   6125 
   6126       /* Failing that, climb up the inheritance hierarchy.  */
   6127       root_inter = inter;
   6128       inter = lookup_interface (CLASS_SUPER_NAME (inter));
   6129     }
   6130   while (inter);
   6131 
   6132   if (is_class && !no_instance_methods_of_root_class)
   6133     {
   6134       /* If no class (factory) method was found, check if an _instance_
   6135 	 method of the same name exists in the root class.  This is what
   6136 	 the Objective-C runtime will do.  */
   6137       return lookup_method_static (root_inter, ident, 0);
   6138     }
   6139   else
   6140     {
   6141       /* If an instance method was not found, return 0.  */
   6142       return NULL_TREE;
   6143     }
   6144 }
   6145 
   6146 static tree
   6147 objc_add_method (tree klass, tree method, int is_class, bool is_optional)
   6148 {
   6149   tree existing_method = NULL_TREE;
   6150 
   6151   /* The first thing we do is look up the method in the list of
   6152      methods already defined in the interface (or implementation).  */
   6153   if (is_class)
   6154     existing_method = lookup_method (CLASS_CLS_METHODS (klass), method);
   6155   else
   6156     existing_method = lookup_method (CLASS_NST_METHODS (klass), method);
   6157 
   6158   /* In the case of protocols, we have a second list of methods to
   6159      consider, the list of optional ones.  */
   6160   if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE)
   6161     {
   6162       /* @required methods are added to the protocol's normal list.
   6163 	 @optional methods are added to the protocol's OPTIONAL lists.
   6164 	 Note that adding the methods to the optional lists disables
   6165 	 checking that the methods are implemented by classes
   6166 	 implementing the protocol, since these checks only use the
   6167 	 CLASS_CLS_METHODS and CLASS_NST_METHODS.  */
   6168 
   6169       /* First of all, if the method to add is @optional, and we found
   6170 	 it already existing as @required, emit an error.  */
   6171       if (is_optional && existing_method)
   6172 	{
   6173 	  error ("method %<%c%E%> declared %<@optional%> and %<@required%> at the same time",
   6174 		 (is_class ? '+' : '-'),
   6175 		 METHOD_SEL_NAME (existing_method));
   6176 	  inform (DECL_SOURCE_LOCATION (existing_method),
   6177 		  "previous declaration of %<%c%E%> as %<@required%>",
   6178 		  (is_class ? '+' : '-'),
   6179 		  METHOD_SEL_NAME (existing_method));
   6180 	}
   6181 
   6182       /* Now check the list of @optional methods if we didn't find the
   6183 	 method in the @required list.  */
   6184       if (!existing_method)
   6185 	{
   6186 	  if (is_class)
   6187 	    existing_method = lookup_method (PROTOCOL_OPTIONAL_CLS_METHODS (klass), method);
   6188 	  else
   6189 	    existing_method = lookup_method (PROTOCOL_OPTIONAL_NST_METHODS (klass), method);
   6190 
   6191 	  if (!is_optional && existing_method)
   6192 	    {
   6193 	      error ("method %<%c%E%> declared %<@optional%> and %<@required%> at the same time",
   6194 		     (is_class ? '+' : '-'),
   6195 		     METHOD_SEL_NAME (existing_method));
   6196 	      inform (DECL_SOURCE_LOCATION (existing_method),
   6197 		      "previous declaration of %<%c%E%> as %<@optional%>",
   6198 		      (is_class ? '+' : '-'),
   6199 		      METHOD_SEL_NAME (existing_method));
   6200 	    }
   6201 	}
   6202     }
   6203 
   6204   /* If the method didn't exist already, add it.  */
   6205   if (!existing_method)
   6206     {
   6207       if (is_optional)
   6208 	{
   6209 	  if (is_class)
   6210 	    {
   6211 	      /* Put the method on the list in reverse order.  */
   6212 	      TREE_CHAIN (method) = PROTOCOL_OPTIONAL_CLS_METHODS (klass);
   6213 	      PROTOCOL_OPTIONAL_CLS_METHODS (klass) = method;
   6214 	    }
   6215 	  else
   6216 	    {
   6217 	      TREE_CHAIN (method) = PROTOCOL_OPTIONAL_NST_METHODS (klass);
   6218 	      PROTOCOL_OPTIONAL_NST_METHODS (klass) = method;
   6219 	    }
   6220 	}
   6221       else
   6222 	{
   6223 	  if (is_class)
   6224 	    {
   6225 	      DECL_CHAIN (method) = CLASS_CLS_METHODS (klass);
   6226 	      CLASS_CLS_METHODS (klass) = method;
   6227 	    }
   6228 	  else
   6229 	    {
   6230 	      DECL_CHAIN (method) = CLASS_NST_METHODS (klass);
   6231 	      CLASS_NST_METHODS (klass) = method;
   6232 	    }
   6233 	}
   6234     }
   6235   else
   6236     {
   6237       /* The method was already defined.  Check that the types match
   6238 	 for an @interface for a class or category, or for a
   6239 	 @protocol.  Give hard errors on methods with identical
   6240 	 selectors but differing argument and/or return types.  We do
   6241 	 not do this for @implementations, because C/C++ will do it
   6242 	 for us (i.e., there will be duplicate function definition
   6243 	 errors).  */
   6244       if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
   6245 	   || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
   6246 	   /* Starting with GCC 4.6, we emit the same error for
   6247 	      protocols too.  The situation is identical to
   6248 	      @interfaces as there is no possible meaningful reason
   6249 	      for defining the same method with different signatures
   6250 	      in the very same @protocol.  If that was allowed,
   6251 	      whenever the protocol is used (both at compile and run
   6252 	      time) there wouldn't be any meaningful way to decide
   6253 	      which of the two method signatures should be used.  */
   6254 	   || TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE)
   6255 	  && !comp_proto_with_proto (method, existing_method, 1))
   6256 	{
   6257 	  error ("duplicate declaration of method %<%c%E%> with conflicting types",
   6258 		 (is_class ? '+' : '-'),
   6259 		 METHOD_SEL_NAME (existing_method));
   6260 	  inform (DECL_SOURCE_LOCATION (existing_method),
   6261 		  "previous declaration of %<%c%E%>",
   6262 		  (is_class ? '+' : '-'),
   6263 		  METHOD_SEL_NAME (existing_method));
   6264 	}
   6265     }
   6266 
   6267   if (is_class)
   6268     insert_method_into_method_map (true, method);
   6269   else
   6270     {
   6271       insert_method_into_method_map (false, method);
   6272 
   6273       /* Instance methods in root classes (and categories thereof)
   6274 	 may act as class methods as a last resort.  We also add
   6275 	 instance methods listed in @protocol declarations to
   6276 	 the class hash table, on the assumption that @protocols
   6277 	 may be adopted by root classes or categories.  */
   6278       if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
   6279 	  || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
   6280 	klass = lookup_interface (CLASS_NAME (klass));
   6281 
   6282       if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
   6283 	  || !CLASS_SUPER_NAME (klass))
   6284 	insert_method_into_method_map (true, method);
   6285     }
   6286 
   6287   return method;
   6288 }
   6289 
   6290 static void
   6291 add_category (tree klass, tree category)
   6292 {
   6293   /* Put categories on list in reverse order.  */
   6294   tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
   6295 
   6296   if (cat)
   6297     {
   6298       warning (0, "duplicate interface declaration for category %<%E(%E)%>",
   6299 	       CLASS_NAME (klass),
   6300 	       CLASS_SUPER_NAME (category));
   6301     }
   6302   else
   6303     {
   6304       CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
   6305       CLASS_CATEGORY_LIST (klass) = category;
   6306     }
   6307 }
   6308 
   6309 #ifndef OBJCPLUS
   6310 /* A flexible array member is a C99 extension where you can use
   6311    "type[]" at the end of a struct to mean a variable-length array.
   6312 
   6313    In Objective-C, instance variables are fundamentally members of a
   6314    struct, but the struct can always be extended by subclassing; hence
   6315    we need to detect and forbid all instance variables declared using
   6316    flexible array members.
   6317 
   6318    No check for this is needed in Objective-C++, since C++ does not
   6319    have flexible array members.  */
   6320 
   6321 /* Determine whether TYPE is a structure with a flexible array member,
   6322    a union containing such a structure (possibly recursively) or an
   6323    array of such structures or unions.  These are all invalid as
   6324    instance variable.  */
   6325 static bool
   6326 flexible_array_type_p (tree type)
   6327 {
   6328   tree x;
   6329   switch (TREE_CODE (type))
   6330     {
   6331     case RECORD_TYPE:
   6332       x = TYPE_FIELDS (type);
   6333       if (x == NULL_TREE)
   6334 	return false;
   6335       while (DECL_CHAIN (x) != NULL_TREE)
   6336 	x = DECL_CHAIN (x);
   6337       if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
   6338 	  && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
   6339 	  && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE
   6340 	  && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
   6341 	return true;
   6342       return false;
   6343     case UNION_TYPE:
   6344       for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x))
   6345 	{
   6346 	  if (flexible_array_type_p (TREE_TYPE (x)))
   6347 	    return true;
   6348 	}
   6349       return false;
   6350     /* Note that we also check for arrays of something that uses a flexible array member.  */
   6351     case ARRAY_TYPE:
   6352       if (flexible_array_type_p (TREE_TYPE (type)))
   6353 	return true;
   6354       return false;
   6355     default:
   6356     return false;
   6357   }
   6358 }
   6359 #endif
   6360 
   6361 /* Produce a printable version of an ivar name.  This is only used
   6362    inside add_instance_variable.  */
   6363 static const char *
   6364 printable_ivar_name (tree field_decl)
   6365 {
   6366   if (DECL_NAME (field_decl))
   6367     return identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)));
   6368   else
   6369     return _("<unnamed>");
   6370 }
   6371 
   6372 /* Called after parsing each instance variable declaration. Necessary to
   6373    preserve typedefs and implement public/private...
   6374 
   6375    VISIBILITY is 1 for public, 0 for protected, and 2 for private.  */
   6376 
   6377 static tree
   6378 add_instance_variable (tree klass, objc_ivar_visibility_kind visibility,
   6379 		       tree field_decl)
   6380 {
   6381   tree field_type = TREE_TYPE (field_decl);
   6382 
   6383 #ifdef OBJCPLUS
   6384   if (TREE_CODE (field_type) == REFERENCE_TYPE)
   6385     {
   6386       error ("illegal reference type specified for instance variable %qs",
   6387 	     printable_ivar_name (field_decl));
   6388       /* Return class as is without adding this ivar.  */
   6389       return klass;
   6390     }
   6391 #endif
   6392 
   6393   if (field_type == error_mark_node || !TYPE_SIZE (field_type)
   6394       || TYPE_SIZE (field_type) == error_mark_node)
   6395       /* 'type[0]' is allowed, but 'type[]' is not! */
   6396     {
   6397       error ("instance variable %qs has unknown size",
   6398 	     printable_ivar_name (field_decl));
   6399       /* Return class as is without adding this ivar.  */
   6400       return klass;
   6401     }
   6402 
   6403 #ifndef OBJCPLUS
   6404   /* Also, in C reject a struct with a flexible array member.  Ie,
   6405 
   6406        struct A { int x; int[] y; };
   6407 
   6408        @interface X
   6409        {
   6410          struct A instance_variable;
   6411        }
   6412        @end
   6413 
   6414        is not valid because if the class is subclassed, we wouldn't be able
   6415        to calculate the offset of the next instance variable.  */
   6416   if (flexible_array_type_p (field_type))
   6417     {
   6418       error ("instance variable %qs uses flexible array member",
   6419 	     printable_ivar_name (field_decl));
   6420       /* Return class as is without adding this ivar.  */
   6421       return klass;
   6422     }
   6423 #endif
   6424 
   6425 #ifdef OBJCPLUS
   6426   /* Check if the ivar being added has a non-POD C++ type.   If so, we will
   6427      need to either (1) warn the user about it or (2) generate suitable
   6428      constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
   6429      methods (if '-fobjc-call-cxx-cdtors' was specified).  */
   6430   if (MAYBE_CLASS_TYPE_P (field_type)
   6431       && (TYPE_NEEDS_CONSTRUCTING (field_type)
   6432 	  || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
   6433 	  || TYPE_POLYMORPHIC_P (field_type)))
   6434     {
   6435       tree type_name = OBJC_TYPE_NAME (field_type);
   6436 
   6437       if (flag_objc_call_cxx_cdtors)
   6438         {
   6439 	  /* Since the ObjC runtime will be calling the constructors and
   6440 	     destructors for us, the only thing we can't handle is the lack
   6441 	     of a default constructor.  */
   6442 	  if (TYPE_NEEDS_CONSTRUCTING (field_type)
   6443 	      && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
   6444 	    {
   6445 	      warning (0, "type %qE has no default constructor to call",
   6446 		       type_name);
   6447 
   6448 	      /* If we cannot call a constructor, we should also avoid
   6449 		 calling the destructor, for symmetry.  */
   6450 	      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
   6451 		warning (0, "destructor for %qE shall not be run either",
   6452 			 type_name);
   6453 	    }
   6454         }
   6455       else
   6456 	{
   6457 	  static bool warn_cxx_ivars = false;
   6458 
   6459 	  if (TYPE_POLYMORPHIC_P (field_type))
   6460 	    {
   6461 	      /* Vtable pointers are Real Bad(tm), since Obj-C cannot
   6462 		 initialize them.  */
   6463 	      error ("type %qE has virtual member functions", type_name);
   6464 	      error ("illegal aggregate type %qE specified "
   6465 		     "for instance variable %qs",
   6466 		     type_name, printable_ivar_name (field_decl));
   6467 	      /* Return class as is without adding this ivar.  */
   6468 	      return klass;
   6469 	    }
   6470 
   6471 	  /* User-defined constructors and destructors are not known to Obj-C
   6472 	     and hence will not be called.  This may or may not be a problem. */
   6473 	  if (TYPE_NEEDS_CONSTRUCTING (field_type))
   6474 	    warning (0, "type %qE has a user-defined constructor", type_name);
   6475 	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
   6476 	    warning (0, "type %qE has a user-defined destructor", type_name);
   6477 
   6478 	  if (!warn_cxx_ivars)
   6479 	    {
   6480 	      warning (0, "C++ constructors and destructors will not "
   6481 		       "be invoked for Objective-C fields");
   6482 	      warn_cxx_ivars = true;
   6483 	    }
   6484 	}
   6485     }
   6486 #endif
   6487 
   6488   /* Overload the public attribute, it is not used for FIELD_DECLs.  */
   6489   switch (visibility)
   6490     {
   6491     case OBJC_IVAR_VIS_PROTECTED:
   6492       TREE_PUBLIC (field_decl) = 0;
   6493       TREE_PRIVATE (field_decl) = 0;
   6494       TREE_PROTECTED (field_decl) = 1;
   6495       break;
   6496 
   6497     case OBJC_IVAR_VIS_PACKAGE:
   6498     /* TODO: Implement the package variant.  */
   6499     case OBJC_IVAR_VIS_PUBLIC:
   6500       TREE_PUBLIC (field_decl) = 1;
   6501       TREE_PRIVATE (field_decl) = 0;
   6502       TREE_PROTECTED (field_decl) = 0;
   6503       break;
   6504 
   6505     case OBJC_IVAR_VIS_PRIVATE:
   6506       TREE_PUBLIC (field_decl) = 0;
   6507       TREE_PRIVATE (field_decl) = 1;
   6508       TREE_PROTECTED (field_decl) = 0;
   6509       break;
   6510 
   6511     }
   6512 
   6513   CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
   6514 
   6515   return klass;
   6516 }
   6517 
   6518 /* True if the ivar is private and we are not in its implementation.  */
   6519 
   6520 static int
   6521 is_private (tree decl)
   6522 {
   6523   return (TREE_PRIVATE (decl)
   6524 	  && ! is_ivar (CLASS_IVARS (implementation_template),
   6525 			DECL_NAME (decl)));
   6526 }
   6527 
   6528 /* Searches all the instance variables of 'klass' and of its
   6529    superclasses for an instance variable whose name (identifier) is
   6530    'ivar_name_ident'.  Return the declaration (DECL) of the instance
   6531    variable, if found, or NULL_TREE, if not found.  */
   6532 static inline tree
   6533 ivar_of_class (tree klass, tree ivar_name_ident)
   6534 {
   6535   /* First, look up the ivar in CLASS_RAW_IVARS.  */
   6536   tree decl_chain = CLASS_RAW_IVARS (klass);
   6537 
   6538   for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
   6539     if (DECL_NAME (decl_chain) == ivar_name_ident)
   6540       return decl_chain;
   6541 
   6542   /* If not found, search up the class hierarchy.  */
   6543   while (CLASS_SUPER_NAME (klass))
   6544     {
   6545       klass = lookup_interface (CLASS_SUPER_NAME (klass));
   6546 
   6547       decl_chain = CLASS_RAW_IVARS (klass);
   6548 
   6549       for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
   6550 	if (DECL_NAME (decl_chain) == ivar_name_ident)
   6551 	  return decl_chain;
   6552     }
   6553 
   6554   return NULL_TREE;
   6555 }
   6556 
   6557 /* We have an instance variable reference;, check to see if it is public.  */
   6558 
   6559 int
   6560 objc_is_public (tree expr, tree identifier)
   6561 {
   6562   tree basetype, decl;
   6563 
   6564 #ifdef OBJCPLUS
   6565   if (processing_template_decl)
   6566     return 1;
   6567 #endif
   6568 
   6569   if (TREE_TYPE (expr) == error_mark_node)
   6570     return 1;
   6571 
   6572   basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
   6573 
   6574   if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
   6575     {
   6576       if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
   6577 	{
   6578 	  tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
   6579 
   6580 	  if (!klass)
   6581 	    {
   6582 	      error ("cannot find interface declaration for %qE",
   6583 		     OBJC_TYPE_NAME (basetype));
   6584 	      return 0;
   6585 	    }
   6586 
   6587 	  if ((decl = ivar_of_class (klass, identifier)))
   6588 	    {
   6589 	      if (TREE_PUBLIC (decl))
   6590 		return 1;
   6591 
   6592 	      /* Important difference between the Stepstone translator:
   6593 		 all instance variables should be public within the context
   6594 		 of the implementation.  */
   6595 	      if (objc_implementation_context
   6596 		 && ((TREE_CODE (objc_implementation_context)
   6597 		      == CLASS_IMPLEMENTATION_TYPE)
   6598 		     || (TREE_CODE (objc_implementation_context)
   6599 			 == CATEGORY_IMPLEMENTATION_TYPE)))
   6600 		{
   6601 		  tree curtype = TYPE_MAIN_VARIANT
   6602 				 (CLASS_STATIC_TEMPLATE
   6603 				  (implementation_template));
   6604 
   6605 		  if (basetype == curtype
   6606 		      || DERIVED_FROM_P (basetype, curtype))
   6607 		    {
   6608 		      int priv = is_private (decl);
   6609 
   6610 		      if (priv)
   6611 			error ("instance variable %qE is declared private",
   6612 			       DECL_NAME (decl));
   6613 
   6614 		      return !priv;
   6615 		    }
   6616 		}
   6617 
   6618 	      /* The 2.95.2 compiler sometimes allowed C functions to access
   6619 		 non-@public ivars.  We will let this slide for now...  */
   6620 	      if (!objc_method_context)
   6621 	      {
   6622 		warning (0, "instance variable %qE is %s; "
   6623 			 "this will be a hard error in the future",
   6624 			 identifier,
   6625 			 TREE_PRIVATE (decl) ? "@private" : "@protected");
   6626 		return 1;
   6627 	      }
   6628 
   6629 	      error ("instance variable %qE is declared %s",
   6630 		     identifier,
   6631 		     TREE_PRIVATE (decl) ? "private" : "protected");
   6632 	      return 0;
   6633 	    }
   6634 	}
   6635     }
   6636 
   6637   return 1;
   6638 }
   6639 
   6640 /* Make sure all methods in CHAIN (a list of method declarations from
   6642    an @interface or a @protocol) are in IMPLEMENTATION (the
   6643    implementation context).  This is used to check for example that
   6644    all methods declared in an @interface were implemented in an
   6645    @implementation.
   6646 
   6647    Some special methods (property setters/getters) are special and if
   6648    they are not found in IMPLEMENTATION, we look them up in its
   6649    superclasses.  */
   6650 
   6651 static int
   6652 check_methods (tree chain, tree implementation, int mtype)
   6653 {
   6654   int first = 1;
   6655   tree list;
   6656 
   6657   if (mtype == (int)'+')
   6658     list = CLASS_CLS_METHODS (implementation);
   6659   else
   6660     list = CLASS_NST_METHODS (implementation);
   6661 
   6662   while (chain)
   6663     {
   6664       /* If the method is associated with a dynamic property, then it
   6665 	 is Ok not to have the method implementation, as it will be
   6666 	 generated dynamically at runtime.  To decide if the method is
   6667 	 associated with a @dynamic property, we search the list of
   6668 	 @synthesize and @dynamic for this implementation, and look
   6669 	 for any @dynamic property with the same setter or getter name
   6670 	 as this method.  */
   6671       tree x;
   6672       for (x = IMPL_PROPERTY_DECL (implementation); x; x = TREE_CHAIN (x))
   6673 	if (PROPERTY_DYNAMIC (x)
   6674 	    && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
   6675 		|| PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
   6676 	  break;
   6677 
   6678       if (x != NULL_TREE)
   6679 	{
   6680 	  chain = TREE_CHAIN (chain); /* next method...  */
   6681 	  continue;
   6682 	}
   6683 
   6684       if (!lookup_method (list, chain))
   6685 	{
   6686 	  /* If the method is a property setter/getter, we'll still
   6687 	     allow it to be missing if it is implemented by
   6688 	     'interface' or any of its superclasses.  */
   6689 	  tree property = METHOD_PROPERTY_CONTEXT (chain);
   6690 	  if (property)
   6691 	    {
   6692 	      /* Note that since this is a property getter/setter, it
   6693 		 is obviously an instance method.  */
   6694 	      tree interface = NULL_TREE;
   6695 
   6696 	      /* For a category, first check the main class
   6697 		 @interface.  */
   6698 	      if (TREE_CODE (implementation) == CATEGORY_IMPLEMENTATION_TYPE)
   6699 		{
   6700 		  interface = lookup_interface (CLASS_NAME (implementation));
   6701 
   6702 		  /* If the method is found in the main class, it's Ok.  */
   6703 		  if (lookup_method (CLASS_NST_METHODS (interface), chain))
   6704 		    {
   6705 		      chain = DECL_CHAIN (chain);
   6706 		      continue;
   6707 		    }
   6708 
   6709 		  /* Else, get the superclass.  */
   6710 		  if (CLASS_SUPER_NAME (interface))
   6711 		    interface = lookup_interface (CLASS_SUPER_NAME (interface));
   6712 		  else
   6713 		    interface = NULL_TREE;
   6714 		}
   6715 
   6716 	      /* Get the superclass for classes.  */
   6717 	      if (TREE_CODE (implementation) == CLASS_IMPLEMENTATION_TYPE)
   6718 		{
   6719 		  if (CLASS_SUPER_NAME (implementation))
   6720 		    interface = lookup_interface (CLASS_SUPER_NAME (implementation));
   6721 		  else
   6722 		    interface = NULL_TREE;
   6723 		}
   6724 
   6725 	      /* Now, interface is the superclass, if any; go check it.  */
   6726 	      if (interface)
   6727 		{
   6728 		  if (lookup_method_static (interface, chain, 0))
   6729 		    {
   6730 		      chain = DECL_CHAIN (chain);
   6731 		      continue;
   6732 		    }
   6733 		}
   6734 	      /* Else, fall through - warn.  */
   6735 	    }
   6736 	  if (first)
   6737 	    {
   6738 	      switch (TREE_CODE (implementation))
   6739 		{
   6740 		case CLASS_IMPLEMENTATION_TYPE:
   6741 		  warning (0, "incomplete implementation of class %qE",
   6742 			   CLASS_NAME (implementation));
   6743 		  break;
   6744 		case CATEGORY_IMPLEMENTATION_TYPE:
   6745 		  warning (0, "incomplete implementation of category %qE",
   6746 			   CLASS_SUPER_NAME (implementation));
   6747 		  break;
   6748 		default:
   6749 		  gcc_unreachable ();
   6750 		}
   6751 	      first = 0;
   6752 	    }
   6753 
   6754 	  warning (0, "method definition for %<%c%E%> not found",
   6755 		   mtype, METHOD_SEL_NAME (chain));
   6756 	}
   6757 
   6758       chain = DECL_CHAIN (chain);
   6759     }
   6760 
   6761     return first;
   6762 }
   6763 
   6764 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL.  */
   6765 
   6766 static int
   6767 conforms_to_protocol (tree klass, tree protocol)
   6768 {
   6769    if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
   6770      {
   6771        tree p = CLASS_PROTOCOL_LIST (klass);
   6772        while (p && TREE_VALUE (p) != protocol)
   6773 	 p = TREE_CHAIN (p);
   6774 
   6775        if (!p)
   6776 	 {
   6777 	   tree super = (CLASS_SUPER_NAME (klass)
   6778 			 ? lookup_interface (CLASS_SUPER_NAME (klass))
   6779 			 : NULL_TREE);
   6780 	   int tmp = super ? conforms_to_protocol (super, protocol) : 0;
   6781 	   if (!tmp)
   6782 	     return 0;
   6783 	 }
   6784      }
   6785 
   6786    return 1;
   6787 }
   6788 
   6789 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
   6790    CONTEXT.  This is one of two mechanisms to check protocol integrity.  */
   6791 
   6792 static int
   6793 check_methods_accessible (tree chain, tree context, int mtype)
   6794 {
   6795   int first = 1;
   6796   tree list;
   6797   tree base_context = context;
   6798 
   6799   while (chain)
   6800     {
   6801       /* If the method is associated with a dynamic property, then it
   6802 	 is Ok not to have the method implementation, as it will be
   6803 	 generated dynamically at runtime.  Search for any @dynamic
   6804 	 property with the same setter or getter name as this
   6805 	 method.  TODO: Use a hashtable lookup.  */
   6806       tree x;
   6807       for (x = IMPL_PROPERTY_DECL (base_context); x; x = TREE_CHAIN (x))
   6808 	if (PROPERTY_DYNAMIC (x)
   6809 	    && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
   6810 		|| PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
   6811 	  break;
   6812 
   6813       if (x != NULL_TREE)
   6814 	{
   6815 	  chain = TREE_CHAIN (chain); /* next method...  */
   6816 	  continue;
   6817 	}
   6818 
   6819       context = base_context;
   6820       while (context)
   6821 	{
   6822 	  if (mtype == '+')
   6823 	    list = CLASS_CLS_METHODS (context);
   6824 	  else
   6825 	    list = CLASS_NST_METHODS (context);
   6826 
   6827 	  if (lookup_method (list, chain))
   6828 	      break;
   6829 
   6830 	  switch (TREE_CODE (context))
   6831 	    {
   6832 	    case CLASS_IMPLEMENTATION_TYPE:
   6833 	    case CLASS_INTERFACE_TYPE:
   6834 	      context = (CLASS_SUPER_NAME (context)
   6835 			 ? lookup_interface (CLASS_SUPER_NAME (context))
   6836 			 : NULL_TREE);
   6837 	      break;
   6838 	    case CATEGORY_IMPLEMENTATION_TYPE:
   6839 	    case CATEGORY_INTERFACE_TYPE:
   6840 	      context = (CLASS_NAME (context)
   6841 			 ? lookup_interface (CLASS_NAME (context))
   6842 			 : NULL_TREE);
   6843 	      break;
   6844 	    default:
   6845 	      gcc_unreachable ();
   6846 	    }
   6847 	}
   6848 
   6849       if (context == NULL_TREE)
   6850 	{
   6851 	  if (first)
   6852 	    {
   6853 	      switch (TREE_CODE (objc_implementation_context))
   6854 		{
   6855 		case CLASS_IMPLEMENTATION_TYPE:
   6856 		  warning (0, "incomplete implementation of class %qE",
   6857 			   CLASS_NAME (objc_implementation_context));
   6858 		  break;
   6859 		case CATEGORY_IMPLEMENTATION_TYPE:
   6860 		  warning (0, "incomplete implementation of category %qE",
   6861 			   CLASS_SUPER_NAME (objc_implementation_context));
   6862 		  break;
   6863 		default:
   6864 		  gcc_unreachable ();
   6865 		}
   6866 	      first = 0;
   6867 	    }
   6868 	  warning (0, "method definition for %<%c%E%> not found",
   6869 		   mtype, METHOD_SEL_NAME (chain));
   6870 	}
   6871 
   6872       chain = TREE_CHAIN (chain); /* next method...  */
   6873     }
   6874   return first;
   6875 }
   6876 
   6877 /* Check whether the current interface (accessible via
   6878    'objc_implementation_context') actually implements protocol P, along
   6879    with any protocols that P inherits.  */
   6880 
   6881 static void
   6882 check_protocol (tree p, const char *type, tree name)
   6883 {
   6884   if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
   6885     {
   6886       int f1, f2;
   6887 
   6888       /* Ensure that all protocols have bodies!  */
   6889       if (warn_protocol)
   6890 	{
   6891 	  f1 = check_methods (PROTOCOL_CLS_METHODS (p),
   6892 			      objc_implementation_context,
   6893 			      '+');
   6894 	  f2 = check_methods (PROTOCOL_NST_METHODS (p),
   6895 			      objc_implementation_context,
   6896 			      '-');
   6897 	}
   6898       else
   6899 	{
   6900 	  f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
   6901 					 objc_implementation_context,
   6902 					 '+');
   6903 	  f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
   6904 					 objc_implementation_context,
   6905 					 '-');
   6906 	}
   6907 
   6908       if (!f1 || !f2)
   6909 	warning (0, "%s %qE does not fully implement the %qE protocol",
   6910 		 type, name, PROTOCOL_NAME (p));
   6911     }
   6912 
   6913   /* Check protocols recursively.  */
   6914   if (PROTOCOL_LIST (p))
   6915     {
   6916       tree subs = PROTOCOL_LIST (p);
   6917       tree super_class =
   6918 	lookup_interface (CLASS_SUPER_NAME (implementation_template));
   6919 
   6920       while (subs)
   6921 	{
   6922 	  tree sub = TREE_VALUE (subs);
   6923 
   6924 	  /* If the superclass does not conform to the protocols
   6925 	     inherited by P, then we must!  */
   6926 	  if (!super_class || !conforms_to_protocol (super_class, sub))
   6927 	    check_protocol (sub, type, name);
   6928 	  subs = TREE_CHAIN (subs);
   6929 	}
   6930     }
   6931 }
   6932 
   6933 /* Check whether the current interface (accessible via
   6934    'objc_implementation_context') actually implements the protocols listed
   6935    in PROTO_LIST.  */
   6936 
   6937 static void
   6938 check_protocols (tree proto_list, const char *type, tree name)
   6939 {
   6940   for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
   6941     {
   6942       tree p = TREE_VALUE (proto_list);
   6943 
   6944       check_protocol (p, type, name);
   6945     }
   6946 }
   6947 
   6948 /* Make sure that the class CLASS_NAME is defined CODE says which kind
   6950    of thing CLASS_NAME ought to be.  It can be CLASS_INTERFACE_TYPE,
   6951    CLASS_IMPLEMENTATION_TYPE, CATEGORY_INTERFACE_TYPE, or
   6952    CATEGORY_IMPLEMENTATION_TYPE.  For a CATEGORY_INTERFACE_TYPE,
   6953    SUPER_NAME is the name of the category.  For a class extension,
   6954    CODE is CATEGORY_INTERFACE_TYPE and SUPER_NAME is NULL_TREE.  */
   6955 static tree
   6956 start_class (enum tree_code code, tree class_name, tree super_name,
   6957 	     tree protocol_list, tree attributes)
   6958 {
   6959   tree klass = NULL_TREE;
   6960   tree decl;
   6961 
   6962 #ifdef OBJCPLUS
   6963   if (current_namespace != global_namespace)
   6964     {
   6965       error ("Objective-C declarations may only appear in global scope");
   6966     }
   6967 #endif /* OBJCPLUS */
   6968 
   6969   if (objc_implementation_context)
   6970     {
   6971       warning (0, "%<@end%> missing in implementation context");
   6972       finish_class (objc_implementation_context);
   6973       objc_ivar_chain = NULL_TREE;
   6974       objc_implementation_context = NULL_TREE;
   6975     }
   6976 
   6977   /* If this is a class extension, we'll be "reopening" the existing
   6978      CLASS_INTERFACE_TYPE, so in that case there is no need to create
   6979      a new node.  */
   6980   if (code != CATEGORY_INTERFACE_TYPE || super_name != NULL_TREE)
   6981     {
   6982       klass = make_node (code);
   6983       TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
   6984     }
   6985 
   6986   /* Check for existence of the super class, if one was specified.  Note
   6987      that we must have seen an @interface, not just a @class.  If we
   6988      are looking at a @compatibility_alias, traverse it first.  */
   6989   if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
   6990       && super_name)
   6991     {
   6992       tree super = objc_is_class_name (super_name);
   6993       tree super_interface = NULL_TREE;
   6994 
   6995       if (super)
   6996 	super_interface = lookup_interface (super);
   6997 
   6998       if (!super_interface)
   6999 	{
   7000 	  error ("cannot find interface declaration for %qE, superclass of %qE",
   7001 		 super ? super : super_name,
   7002 		 class_name);
   7003 	  super_name = NULL_TREE;
   7004 	}
   7005       else
   7006 	{
   7007 	  if (TREE_UNAVAILABLE (super_interface))
   7008 	    error ("class %qE is not available", super);
   7009 	  else if (TREE_DEPRECATED (super_interface))
   7010 	    warning (OPT_Wdeprecated_declarations, "class %qE is deprecated",
   7011 		     super);
   7012 	  super_name = super;
   7013 	}
   7014     }
   7015 
   7016   if (code != CATEGORY_INTERFACE_TYPE || super_name != NULL_TREE)
   7017     {
   7018       CLASS_NAME (klass) = class_name;
   7019       CLASS_SUPER_NAME (klass) = super_name;
   7020       CLASS_CLS_METHODS (klass) = NULL_TREE;
   7021     }
   7022 
   7023   if (! objc_is_class_name (class_name)
   7024       && (decl = lookup_name (class_name)))
   7025     {
   7026       error ("%qE redeclared as different kind of symbol",
   7027 	     class_name);
   7028       error ("previous declaration of %q+D",
   7029 	     decl);
   7030     }
   7031 
   7032   switch (code)
   7033     {
   7034     case CLASS_IMPLEMENTATION_TYPE:
   7035       {
   7036 	tree chain;
   7037 
   7038 	for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
   7039 	  if (TREE_VALUE (chain) == class_name)
   7040 	    {
   7041 	      error ("reimplementation of class %qE",
   7042 		     class_name);
   7043 	      /* TODO: error message saying where it was previously
   7044 		 implemented.  */
   7045 	      break;
   7046 	    }
   7047 	if (chain == NULL_TREE)
   7048 	  implemented_classes = tree_cons (NULL_TREE, class_name,
   7049 					   implemented_classes);
   7050       }
   7051 
   7052       /* Reset for multiple classes per file.  */
   7053       method_slot = 0;
   7054 
   7055       objc_implementation_context = klass;
   7056 
   7057       /* Lookup the interface for this implementation.  */
   7058 
   7059       if (!(implementation_template = lookup_interface (class_name)))
   7060         {
   7061 	  warning (0, "cannot find interface declaration for %qE",
   7062 		   class_name);
   7063 	  add_interface (implementation_template = objc_implementation_context,
   7064 			 class_name);
   7065         }
   7066 
   7067       /* If a super class has been specified in the implementation,
   7068 	 insure it conforms to the one specified in the interface.  */
   7069 
   7070       if (super_name
   7071 	  && (super_name != CLASS_SUPER_NAME (implementation_template)))
   7072 	{
   7073 	  tree previous_name = CLASS_SUPER_NAME (implementation_template);
   7074 	  error ("conflicting super class name %qE",
   7075 		 super_name);
   7076 	  if (previous_name)
   7077 	    error ("previous declaration of %qE", previous_name);
   7078 	  else
   7079 	    error ("previous declaration");
   7080 	}
   7081 
   7082       else if (! super_name)
   7083 	{
   7084 	  CLASS_SUPER_NAME (objc_implementation_context)
   7085 	    = CLASS_SUPER_NAME (implementation_template);
   7086 	}
   7087 
   7088       if (!CLASS_SUPER_NAME (objc_implementation_context)
   7089 	  && !lookup_attribute ("objc_root_class",
   7090 				TYPE_ATTRIBUTES (implementation_template)))
   7091 	  warning (OPT_Wobjc_root_class, "class %qE defined without"
   7092 		      " specifying a base class", class_name);
   7093       break;
   7094 
   7095     case CLASS_INTERFACE_TYPE:
   7096       if (lookup_interface (class_name))
   7097 #ifdef OBJCPLUS
   7098 	error ("duplicate interface declaration for class %qE", class_name);
   7099 #else
   7100         warning (0, "duplicate interface declaration for class %qE", class_name);
   7101 #endif
   7102       else
   7103 	add_interface (klass, class_name);
   7104 
   7105       if (protocol_list)
   7106 	CLASS_PROTOCOL_LIST (klass)
   7107 	  = lookup_and_install_protocols (protocol_list, /* definition_required */ true);
   7108 
   7109       if (attributes)
   7110 	{
   7111 	  tree attribute;
   7112 	  for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
   7113 	    {
   7114 	      tree name = TREE_PURPOSE (attribute);
   7115 
   7116 	      /* TODO: Document what the objc_exception attribute is/does.  */
   7117 	      /* We handle the 'deprecated', 'visibility' and (undocumented)
   7118 		 'objc_exception' attributes.  */
   7119 	      if (is_attribute_p  ("unavailable", name))
   7120 		TREE_UNAVAILABLE (klass) = 1;
   7121 	      else if (is_attribute_p  ("deprecated", name))
   7122 		TREE_DEPRECATED (klass) = 1;
   7123 	      else if (is_attribute_p  ("objc_exception", name))
   7124 		CLASS_HAS_EXCEPTION_ATTR (klass) = 1;
   7125 	      else if (is_attribute_p  ("objc_root_class", name))
   7126 		;
   7127 	      else if (is_attribute_p  ("visibility", name))
   7128 		;
   7129 	      else
   7130 		/* Warn about and ignore all others for now, but store them.  */
   7131 		warning (OPT_Wattributes, "%qE attribute directive ignored", name);
   7132 	    }
   7133 	  TYPE_ATTRIBUTES (klass) = attributes;
   7134 	}
   7135       break;
   7136 
   7137     case CATEGORY_INTERFACE_TYPE:
   7138       {
   7139 	tree class_category_is_assoc_with;
   7140 
   7141 	/* For a category, class_name is really the name of the class that
   7142 	   the following set of methods will be associated with. We must
   7143 	   find the interface so that can derive the objects template.  */
   7144 	if (!(class_category_is_assoc_with = lookup_interface (class_name)))
   7145 	  {
   7146 	    error ("cannot find interface declaration for %qE",
   7147 		   class_name);
   7148 	    exit (FATAL_EXIT_CODE);
   7149 	  }
   7150 	else
   7151 	  {
   7152 	    if (TREE_UNAVAILABLE (class_category_is_assoc_with))
   7153 	      error ("class %qE is unavailable", class_name);
   7154 	    else if (TREE_DEPRECATED (class_category_is_assoc_with))
   7155 	      warning (OPT_Wdeprecated_declarations, "class %qE is deprecated",
   7156 		       class_name);
   7157 
   7158 	    if (super_name == NULL_TREE)
   7159 	      {
   7160 		/* This is a class extension.  Get the original
   7161 		   interface, and continue working on it.  */
   7162 		objc_in_class_extension = true;
   7163 		klass = class_category_is_assoc_with;
   7164 
   7165 		if (protocol_list)
   7166 		  {
   7167 		    /* Append protocols to the original protocol
   7168 		       list.  */
   7169 		    CLASS_PROTOCOL_LIST (klass)
   7170 		      = chainon (CLASS_PROTOCOL_LIST (klass),
   7171 				 lookup_and_install_protocols
   7172 				 (protocol_list,
   7173 				  /* definition_required */ true));
   7174 		  }
   7175 	      }
   7176 	    else
   7177 	      {
   7178 		add_category (class_category_is_assoc_with, klass);
   7179 
   7180 		if (protocol_list)
   7181 		  CLASS_PROTOCOL_LIST (klass)
   7182 		    = lookup_and_install_protocols
   7183 		    (protocol_list, /* definition_required */ true);
   7184 	      }
   7185 	  }
   7186       }
   7187       break;
   7188 
   7189     case CATEGORY_IMPLEMENTATION_TYPE:
   7190       /* Reset for multiple classes per file.  */
   7191       method_slot = 0;
   7192 
   7193       objc_implementation_context = klass;
   7194 
   7195       /* For a category, class_name is really the name of the class that
   7196 	 the following set of methods will be associated with.  We must
   7197 	 find the interface so that can derive the objects template.  */
   7198 
   7199       if (!(implementation_template = lookup_interface (class_name)))
   7200         {
   7201 	  error ("cannot find interface declaration for %qE",
   7202 		 class_name);
   7203 	  exit (FATAL_EXIT_CODE);
   7204         }
   7205       break;
   7206     default:
   7207       gcc_unreachable ();
   7208     }
   7209   return klass;
   7210 }
   7211 
   7212 static tree
   7213 continue_class (tree klass)
   7214 {
   7215   switch (TREE_CODE (klass))
   7216     {
   7217     case CLASS_IMPLEMENTATION_TYPE:
   7218     case CATEGORY_IMPLEMENTATION_TYPE:
   7219       {
   7220 	struct imp_entry *imp_entry;
   7221 
   7222         /* Check consistency of the instance variables.  */
   7223 
   7224 	if (CLASS_RAW_IVARS (klass))
   7225 	  check_ivars (implementation_template, klass);
   7226 
   7227 	/* code generation */
   7228 #ifdef OBJCPLUS
   7229 	push_lang_context (lang_name_c);
   7230 #endif
   7231 	build_private_template (implementation_template);
   7232 	uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
   7233 	objc_instance_type = build_pointer_type (uprivate_record);
   7234 
   7235 	imp_entry = ggc_alloc<struct imp_entry> ();
   7236 
   7237 	imp_entry->next = imp_list;
   7238 	imp_entry->imp_context = klass;
   7239 	imp_entry->imp_template = implementation_template;
   7240 	ucls_super_ref = uucls_super_ref = NULL;
   7241 	if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
   7242 	  {
   7243 	    imp_entry->class_decl = (*runtime.class_decl) (klass);
   7244 	    imp_entry->meta_decl = (*runtime.metaclass_decl) (klass);
   7245 	  }
   7246 	else
   7247 	  {
   7248 	    imp_entry->class_decl = (*runtime.category_decl) (klass);
   7249 	    imp_entry->meta_decl = NULL;
   7250 	  }
   7251 	imp_entry->has_cxx_cdtors = 0;
   7252 
   7253 	/* Append to front and increment count.  */
   7254 	imp_list = imp_entry;
   7255 	if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
   7256 	  imp_count++;
   7257 	else
   7258 	  cat_count++;
   7259 #ifdef OBJCPLUS
   7260 	pop_lang_context ();
   7261 #endif /* OBJCPLUS */
   7262 
   7263 	return get_class_ivars (implementation_template, true);
   7264       }
   7265     case CLASS_INTERFACE_TYPE:
   7266       {
   7267 	if (objc_in_class_extension)
   7268 	  return NULL_TREE;
   7269 #ifdef OBJCPLUS
   7270 	push_lang_context (lang_name_c);
   7271 #endif /* OBJCPLUS */
   7272 	objc_collecting_ivars = 1;
   7273 	build_private_template (klass);
   7274 	objc_collecting_ivars = 0;
   7275 #ifdef OBJCPLUS
   7276 	pop_lang_context ();
   7277 #endif /* OBJCPLUS */
   7278 	return NULL_TREE;
   7279       }
   7280     default:
   7281       return error_mark_node;
   7282     }
   7283 }
   7284 
   7285 /* This routine builds name of the setter synthesized function. */
   7286 char *
   7287 objc_build_property_setter_name (tree ident)
   7288 {
   7289   /* TODO: Use alloca to allocate buffer of appropriate size.  */
   7290   static char string[BUFSIZE];
   7291   sprintf (string, "set%s:", IDENTIFIER_POINTER (ident));
   7292   string[3] = TOUPPER (string[3]);
   7293   return string;
   7294 }
   7295 
   7296 /* This routine prepares the declarations of the property accessor
   7297    helper functions (objc_getProperty(), etc) that are used when
   7298    @synthesize is used.
   7299 
   7300    runtime-specific routines are built in the respective runtime
   7301    initialize functions.  */
   7302 static void
   7303 build_common_objc_property_accessor_helpers (void)
   7304 {
   7305   tree type;
   7306 
   7307   /* Declare the following function:
   7308      id
   7309      objc_getProperty (id self, SEL _cmd,
   7310                        ptrdiff_t offset, BOOL is_atomic);  */
   7311   type = build_function_type_list (objc_object_type,
   7312 				   objc_object_type,
   7313 				   objc_selector_type,
   7314 				   ptrdiff_type_node,
   7315 				   boolean_type_node,
   7316 				   NULL_TREE);
   7317   objc_getProperty_decl = add_builtin_function ("objc_getProperty",
   7318 						type, 0, NOT_BUILT_IN,
   7319 						NULL, NULL_TREE);
   7320   TREE_NOTHROW (objc_getProperty_decl) = 0;
   7321 
   7322   /* Declare the following function:
   7323      void
   7324      objc_setProperty (id self, SEL _cmd,
   7325                        ptrdiff_t offset, id new_value,
   7326                        BOOL is_atomic, BOOL should_copy);  */
   7327   type = build_function_type_list (void_type_node,
   7328 				   objc_object_type,
   7329 				   objc_selector_type,
   7330 				   ptrdiff_type_node,
   7331 				   objc_object_type,
   7332 				   boolean_type_node,
   7333 				   boolean_type_node,
   7334 				   NULL_TREE);
   7335   objc_setProperty_decl = add_builtin_function ("objc_setProperty",
   7336 						type, 0, NOT_BUILT_IN,
   7337 						NULL, NULL_TREE);
   7338   TREE_NOTHROW (objc_setProperty_decl) = 0;
   7339 }
   7340 
   7341 /* This looks up an ivar in a class (including superclasses).  */
   7342 static tree
   7343 lookup_ivar (tree interface, tree instance_variable_name)
   7344 {
   7345   while (interface)
   7346     {
   7347       tree decl_chain;
   7348 
   7349       for (decl_chain = CLASS_IVARS (interface); decl_chain; decl_chain = DECL_CHAIN (decl_chain))
   7350 	if (DECL_NAME (decl_chain) == instance_variable_name)
   7351 	  return decl_chain;
   7352 
   7353       /* Not found.  Search superclass if any.  */
   7354       if (CLASS_SUPER_NAME (interface))
   7355 	interface = lookup_interface (CLASS_SUPER_NAME (interface));
   7356     }
   7357 
   7358   return NULL_TREE;
   7359 }
   7360 
   7361 /* This routine synthesizes a 'getter' method.  This is only called
   7362    for @synthesize properties.  */
   7363 static void
   7364 objc_synthesize_getter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
   7365 {
   7366   location_t location = DECL_SOURCE_LOCATION (property);
   7367   tree fn, decl;
   7368   tree body;
   7369   tree ret_val;
   7370 
   7371   /* If user has implemented a getter with same name then do nothing.  */
   7372   if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
   7373 		     PROPERTY_GETTER_NAME (property)))
   7374     return;
   7375 
   7376   /* Find declaration of the property getter in the interface (or
   7377      superclass, or protocol). There must be one.  */
   7378   decl = lookup_method_static (klass, PROPERTY_GETTER_NAME (property), 0);
   7379 
   7380   /* If one not declared in the interface, this condition has already
   7381      been reported as user error (because property was not declared in
   7382      the interface).  */
   7383   if (!decl)
   7384     return;
   7385 
   7386   /* Adapt the 'decl'.  Use the source location of the @synthesize
   7387      statement for error messages.  */
   7388   decl = copy_node (decl);
   7389   DECL_SOURCE_LOCATION (decl) = location;
   7390 
   7391   objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE,
   7392 				NULL_TREE);
   7393   body = c_begin_compound_stmt (true);
   7394 
   7395   /* Now we need to decide how we build the getter.  There are three
   7396      cases:
   7397 
   7398      for 'copy' or 'retain' properties we need to use the
   7399      objc_getProperty() accessor helper which knows about retain and
   7400      copy.  It supports both 'nonatomic' and 'atomic' access.
   7401 
   7402      for 'nonatomic, assign' properties we can access the instance
   7403      variable directly.  'nonatomic' means we don't have to use locks,
   7404      and 'assign' means we don't have to worry about retain or copy.
   7405      If you combine the two, it means we can just access the instance
   7406      variable directly.
   7407 
   7408      for 'atomic, assign' properties we use objc_copyStruct() (for the
   7409      next runtime) or objc_getPropertyStruct() (for the GNU runtime).  */
   7410   switch (PROPERTY_ASSIGN_SEMANTICS (property))
   7411     {
   7412     case OBJC_PROPERTY_RETAIN:
   7413     case OBJC_PROPERTY_COPY:
   7414       {
   7415 	/* We build "return objc_getProperty (self, _cmd, offset, is_atomic);"  */
   7416 	tree cmd, ivar, offset, is_atomic;
   7417 	cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
   7418 
   7419 	/* Find the ivar to compute the offset.  */
   7420 	ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
   7421 	if (!ivar || is_private (ivar))
   7422 	  {
   7423 	    /* This should never happen.  */
   7424 	    error_at (location,
   7425 		      "cannot find instance variable associated with property");
   7426 	    ret_val = error_mark_node;
   7427 	    break;
   7428 	  }
   7429 	offset = byte_position (ivar);
   7430 
   7431 	if (PROPERTY_NONATOMIC (property))
   7432 	  is_atomic = boolean_false_node;
   7433 	else
   7434 	  is_atomic = boolean_true_node;
   7435 
   7436 	ret_val = build_function_call
   7437 	  (location,
   7438 	   /* Function prototype.  */
   7439 	   objc_getProperty_decl,
   7440 	   /* Parameters.  */
   7441 	   tree_cons    /* self */
   7442 	   (NULL_TREE, self_decl,
   7443 	    tree_cons   /* _cmd */
   7444 	    (NULL_TREE, cmd,
   7445 	     tree_cons  /* offset */
   7446 	     (NULL_TREE, offset,
   7447 	      tree_cons /* is_atomic */
   7448 	      (NULL_TREE, is_atomic, NULL_TREE)))));
   7449       }
   7450       break;
   7451     case OBJC_PROPERTY_ASSIGN:
   7452       if (PROPERTY_NONATOMIC (property))
   7453 	{
   7454 	  /* We build "return self->PROPERTY_IVAR_NAME;"  */
   7455 	  ret_val = objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property));
   7456 	  break;
   7457 	}
   7458       else
   7459 	{
   7460 	  /* We build
   7461 	       <property type> __objc_property_temp;
   7462 	       objc_getPropertyStruct (&__objc_property_temp,
   7463 	                               &(self->PROPERTY_IVAR_NAME),
   7464 	                               sizeof (type of self->PROPERTY_IVAR_NAME),
   7465 				       is_atomic,
   7466 				       false)
   7467 	       return __objc_property_temp;
   7468 
   7469 	     For the NeXT runtime, we need to use objc_copyStruct
   7470 	     instead of objc_getPropertyStruct.  */
   7471 	  tree objc_property_temp_decl, function_decl, function_call;
   7472 	  tree size_of, is_atomic;
   7473 
   7474 	  objc_property_temp_decl = objc_create_temporary_var (TREE_TYPE (property), "__objc_property_temp");
   7475 	  DECL_SOURCE_LOCATION (objc_property_temp_decl) = location;
   7476 	  objc_property_temp_decl = lang_hooks.decls.pushdecl (objc_property_temp_decl);
   7477 
   7478 	  /* sizeof (ivar type).  Since the ivar and the property have
   7479 	     the same type, there is no need to lookup the ivar.  */
   7480 	  size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
   7481 					      true /* is_sizeof */,
   7482 					      false /* min_alignof */,
   7483 					      false /* complain */);
   7484 
   7485 	  if (PROPERTY_NONATOMIC (property))
   7486 	    is_atomic = boolean_false_node;
   7487 	  else
   7488 	    is_atomic = boolean_true_node;
   7489 
   7490 	  if (objc_copyStruct_decl)
   7491 	    function_decl = objc_copyStruct_decl;
   7492 	  else
   7493 	    function_decl = objc_getPropertyStruct_decl;
   7494 
   7495 	  function_call = build_function_call
   7496 	    (location,
   7497 	     /* Function prototype.  */
   7498 	     function_decl,
   7499 	     /* Parameters.  */
   7500 	     tree_cons /* &__objc_property_temp_decl */
   7501 	     /* Warning: note that using build_fold_addr_expr_loc()
   7502 		here causes invalid code to be generated.  */
   7503 	     (NULL_TREE, build_unary_op (location, ADDR_EXPR, objc_property_temp_decl, 0),
   7504 	      tree_cons /* &(self->PROPERTY_IVAR_NAME); */
   7505 	      (NULL_TREE, build_fold_addr_expr_loc (location,
   7506 						    objc_lookup_ivar
   7507 						    (NULL_TREE, PROPERTY_IVAR_NAME (property))),
   7508 	       tree_cons /* sizeof (PROPERTY_IVAR) */
   7509 	       (NULL_TREE, size_of,
   7510 		tree_cons /* is_atomic */
   7511 		(NULL_TREE, is_atomic,
   7512 		 /* TODO: This is currently ignored by the GNU
   7513 		    runtime, but what about the next one ? */
   7514 		 tree_cons /* has_strong */
   7515 		 (NULL_TREE, boolean_true_node, NULL_TREE))))));
   7516 
   7517 	  add_stmt (function_call);
   7518 
   7519 	  ret_val = objc_property_temp_decl;
   7520 	}
   7521       break;
   7522     default:
   7523       gcc_unreachable ();
   7524     }
   7525 
   7526   gcc_assert (ret_val);
   7527 
   7528 #ifdef OBJCPLUS
   7529   finish_return_stmt (ret_val);
   7530 #else
   7531   c_finish_return (location, ret_val, NULL_TREE);
   7532 #endif
   7533 
   7534   add_stmt (c_end_compound_stmt (location, body, true));
   7535   fn = current_function_decl;
   7536 #ifdef OBJCPLUS
   7537   finish_function ();
   7538 #endif
   7539   objc_finish_method_definition (fn);
   7540 }
   7541 
   7542 /* This routine synthesizes a 'setter' method.  */
   7543 
   7544 static void
   7545 objc_synthesize_setter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
   7546 {
   7547   location_t location = DECL_SOURCE_LOCATION (property);
   7548   tree fn, decl;
   7549   tree body;
   7550   tree new_value, statement;
   7551 
   7552   /* If user has implemented a setter with same name then do nothing.  */
   7553   if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
   7554 		     PROPERTY_SETTER_NAME (property)))
   7555     return;
   7556 
   7557   /* Find declaration of the property setter in the interface (or
   7558      superclass, or protocol). There must be one.  */
   7559   decl = lookup_method_static (klass, PROPERTY_SETTER_NAME (property), 0);
   7560 
   7561   /* If one not declared in the interface, this condition has already
   7562      been reported as user error (because property was not declared in
   7563      the interface).  */
   7564   if (!decl)
   7565     return;
   7566 
   7567   /* Adapt the 'decl'.  Use the source location of the @synthesize
   7568      statement for error messages.  */
   7569   decl = copy_node (decl);
   7570   DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (property);
   7571 
   7572   objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE,
   7573 				NULL_TREE);
   7574 
   7575   body = c_begin_compound_stmt (true);
   7576 
   7577   /* The 'new_value' is the only argument to the method, which is the
   7578      3rd argument of the function, after self and _cmd.  We use twice
   7579      TREE_CHAIN to move forward two arguments.  */
   7580   new_value = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)));
   7581 
   7582   /* This would presumably happen if the user has specified a
   7583      prototype for the setter that does not have an argument!  */
   7584   if (new_value == NULL_TREE)
   7585     {
   7586       /* TODO: This should be caught much earlier than this.  */
   7587       error_at (DECL_SOURCE_LOCATION (decl), "invalid setter, it must have one argument");
   7588       /* Try to recover somehow.  */
   7589       new_value = error_mark_node;
   7590     }
   7591 
   7592   /* Now we need to decide how we build the setter.  There are three
   7593      cases:
   7594 
   7595      for 'copy' or 'retain' properties we need to use the
   7596      objc_setProperty() accessor helper which knows about retain and
   7597      copy.  It supports both 'nonatomic' and 'atomic' access.
   7598 
   7599      for 'nonatomic, assign' properties we can access the instance
   7600      variable directly.  'nonatomic' means we don't have to use locks,
   7601      and 'assign' means we don't have to worry about retain or copy.
   7602      If you combine the two, it means we can just access the instance
   7603      variable directly.
   7604 
   7605      for 'atomic, assign' properties we use objc_copyStruct() (for the
   7606      next runtime) or objc_setPropertyStruct() (for the GNU runtime).  */
   7607   switch (PROPERTY_ASSIGN_SEMANTICS (property))
   7608     {
   7609     case OBJC_PROPERTY_RETAIN:
   7610     case OBJC_PROPERTY_COPY:
   7611       {
   7612 	/* We build "objc_setProperty (self, _cmd, new_value, offset, is_atomic, should_copy);"  */
   7613 	tree cmd, ivar, offset, is_atomic, should_copy;
   7614 	cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
   7615 
   7616 	/* Find the ivar to compute the offset.  */
   7617 	ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
   7618 	if (!ivar || is_private (ivar))
   7619 	  {
   7620 	    error_at (location,
   7621 		      "cannot find instance variable associated with property");
   7622 	    statement = error_mark_node;
   7623 	    break;
   7624 	  }
   7625 	offset = byte_position (ivar);
   7626 
   7627 	if (PROPERTY_NONATOMIC (property))
   7628 	  is_atomic = boolean_false_node;
   7629 	else
   7630 	  is_atomic = boolean_true_node;
   7631 
   7632 	if (PROPERTY_ASSIGN_SEMANTICS (property) == OBJC_PROPERTY_COPY)
   7633 	  should_copy = boolean_true_node;
   7634 	else
   7635 	  should_copy = boolean_false_node;
   7636 
   7637 	statement = build_function_call
   7638 	  (location,
   7639 	   /* Function prototype.  */
   7640 	   objc_setProperty_decl,
   7641 	   /* Parameters.  */
   7642 	   tree_cons    /* self */
   7643 	   (NULL_TREE, self_decl,
   7644 	    tree_cons   /* _cmd */
   7645 	    (NULL_TREE, cmd,
   7646 	     tree_cons  /* offset */
   7647 	     (NULL_TREE, offset,
   7648 	      tree_cons /* new_value */
   7649 	      (NULL_TREE, new_value,
   7650 	       tree_cons /* is_atomic */
   7651 	       (NULL_TREE, is_atomic,
   7652 		tree_cons /* should_copy */
   7653 		(NULL_TREE, should_copy, NULL_TREE)))))));
   7654       }
   7655       break;
   7656     case OBJC_PROPERTY_ASSIGN:
   7657       if (PROPERTY_NONATOMIC (property))
   7658 	{
   7659 	  /* We build "self->PROPERTY_IVAR_NAME = new_value;"  */
   7660 	  statement = build_modify_expr
   7661 	    (location,
   7662 	     objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property)),
   7663 	     NULL_TREE, NOP_EXPR,
   7664 	     location, new_value, NULL_TREE);
   7665 	  break;
   7666 	}
   7667       else
   7668 	{
   7669 	  /* We build
   7670 	       objc_setPropertyStruct (&(self->PROPERTY_IVAR_NAME),
   7671 	                               &new_value,
   7672 	                               sizeof (type of self->PROPERTY_IVAR_NAME),
   7673 				       is_atomic,
   7674 				       false)
   7675 
   7676 	     For the NeXT runtime, we need to use objc_copyStruct
   7677 	     instead of objc_getPropertyStruct.  */
   7678 	  tree function_decl, size_of, is_atomic;
   7679 
   7680 	  /* sizeof (ivar type).  Since the ivar and the property have
   7681 	     the same type, there is no need to lookup the ivar.  */
   7682 	  size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
   7683 					      true /* is_sizeof */,
   7684 					      false /* min_alignof */,
   7685 					      false /* complain */);
   7686 
   7687 	  if (PROPERTY_NONATOMIC (property))
   7688 	    is_atomic = boolean_false_node;
   7689 	  else
   7690 	    is_atomic = boolean_true_node;
   7691 
   7692 	  if (objc_copyStruct_decl)
   7693 	    function_decl = objc_copyStruct_decl;
   7694 	  else
   7695 	    function_decl = objc_setPropertyStruct_decl;
   7696 
   7697 	  statement = build_function_call
   7698 	    (location,
   7699 	     /* Function prototype.  */
   7700 	     function_decl,
   7701 	     /* Parameters.  */
   7702 	     tree_cons /* &(self->PROPERTY_IVAR_NAME); */
   7703 	     (NULL_TREE, build_fold_addr_expr_loc (location,
   7704 						   objc_lookup_ivar
   7705 						   (NULL_TREE, PROPERTY_IVAR_NAME (property))),
   7706 	      tree_cons /* &new_value */
   7707 	      (NULL_TREE, build_fold_addr_expr_loc (location, new_value),
   7708 	       tree_cons /* sizeof (PROPERTY_IVAR) */
   7709 	       (NULL_TREE, size_of,
   7710 		tree_cons /* is_atomic */
   7711 		(NULL_TREE, is_atomic,
   7712 		 /* TODO: This is currently ignored by the GNU
   7713 		    runtime, but what about the next one ? */
   7714 		 tree_cons /* has_strong */
   7715 		 (NULL_TREE, boolean_true_node, NULL_TREE))))));
   7716 	}
   7717       break;
   7718     default:
   7719       gcc_unreachable ();
   7720     }
   7721   gcc_assert (statement);
   7722 
   7723   add_stmt (statement);
   7724   add_stmt (c_end_compound_stmt (location, body, true));
   7725   fn = current_function_decl;
   7726 #ifdef OBJCPLUS
   7727   finish_function ();
   7728 #endif
   7729   objc_finish_method_definition (fn);
   7730 }
   7731 
   7732 /* This function is a sub-routine of objc_add_synthesize_declaration.
   7733    It is called for each property to synthesize once we have
   7734    determined that the context is Ok.  */
   7735 static void
   7736 objc_add_synthesize_declaration_for_property (location_t location, tree interface,
   7737 					      tree property_name, tree ivar_name)
   7738 {
   7739   /* Find the @property declaration.  */
   7740   tree property;
   7741   tree x;
   7742 
   7743   /* Check that synthesize or dynamic has not already been used for
   7744      the same property.  */
   7745   for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
   7746     if (PROPERTY_NAME (property) == property_name)
   7747       {
   7748 	location_t original_location = DECL_SOURCE_LOCATION (property);
   7749 
   7750 	if (PROPERTY_DYNAMIC (property))
   7751 	  error_at (location, "property %qs already specified in %<@dynamic%>",
   7752 		    IDENTIFIER_POINTER (property_name));
   7753 	else
   7754 	  error_at (location, "property %qs already specified in %<@synthesize%>",
   7755 		    IDENTIFIER_POINTER (property_name));
   7756 
   7757 	if (original_location != UNKNOWN_LOCATION)
   7758 	  inform (original_location, "originally specified here");
   7759 	return;
   7760       }
   7761 
   7762   /* Check that the property is declared in the interface.  It could
   7763      also be declared in a superclass or protocol.  */
   7764   property = lookup_property (interface, property_name);
   7765 
   7766   if (!property)
   7767     {
   7768       error_at (location, "no declaration of property %qs found in the interface",
   7769 		IDENTIFIER_POINTER (property_name));
   7770       return;
   7771     }
   7772   else
   7773     {
   7774       /* We have to copy the property, because we want to chain it to
   7775 	 the implementation context, and we want to store the source
   7776 	 location of the @synthesize, not of the original
   7777 	 @property.  */
   7778       property = copy_node (property);
   7779       DECL_SOURCE_LOCATION (property) = location;
   7780     }
   7781 
   7782   /* Determine PROPERTY_IVAR_NAME.  */
   7783   if (ivar_name == NULL_TREE)
   7784     ivar_name = property_name;
   7785 
   7786   /* Check that the instance variable exists.  You can only use an
   7787      instance variable from the same class, not one from the
   7788      superclass (this makes sense as it allows us to check that an
   7789      instance variable is only used in one synthesized property).  */
   7790   {
   7791     tree ivar = is_ivar (CLASS_IVARS (interface), ivar_name);
   7792     tree type_of_ivar;
   7793     if (!ivar)
   7794       {
   7795 	error_at (location, "ivar %qs used by %<@synthesize%> declaration must be an existing ivar",
   7796 		  IDENTIFIER_POINTER (property_name));
   7797 	return;
   7798       }
   7799 
   7800     if (DECL_BIT_FIELD_TYPE (ivar))
   7801       type_of_ivar = DECL_BIT_FIELD_TYPE (ivar);
   7802     else
   7803       type_of_ivar = TREE_TYPE (ivar);
   7804 
   7805     /* If the instance variable has a different C type, we throw an error ...  */
   7806     if (!comptypes (TREE_TYPE (property), type_of_ivar)
   7807 	/* ... unless the property is readonly, in which case we allow
   7808 	   the instance variable to be more specialized (this means we
   7809 	   can generate the getter all right and it works).  */
   7810 	&& (!PROPERTY_READONLY (property)
   7811 	    || !objc_compare_types (TREE_TYPE (property),
   7812 				    type_of_ivar, -5, NULL_TREE)))
   7813       {
   7814 	location_t original_location = DECL_SOURCE_LOCATION (ivar);
   7815 
   7816 	error_at (location, "property %qs is using instance variable %qs of incompatible type",
   7817 		  IDENTIFIER_POINTER (property_name),
   7818 		  IDENTIFIER_POINTER (ivar_name));
   7819 
   7820 	if (original_location != UNKNOWN_LOCATION)
   7821 	  inform (original_location, "originally specified here");
   7822       }
   7823 
   7824     /* If the instance variable is a bitfield, the property must be
   7825        'assign', 'nonatomic' because the runtime getter/setter helper
   7826        do not work with bitfield instance variables.  */
   7827     if (DECL_BIT_FIELD_TYPE (ivar))
   7828       {
   7829 	/* If there is an error, we return and not generate any
   7830 	   getter/setter because trying to set up the runtime
   7831 	   getter/setter helper calls with bitfields is at high risk
   7832 	   of ICE.  */
   7833 
   7834 	if (PROPERTY_ASSIGN_SEMANTICS (property) != OBJC_PROPERTY_ASSIGN)
   7835 	  {
   7836 	    location_t original_location = DECL_SOURCE_LOCATION (ivar);
   7837 
   7838 	    error_at (location, "%<assign%> property %qs is using bit-field "
   7839 		      "instance variable %qs",
   7840 		      IDENTIFIER_POINTER (property_name),
   7841 		      IDENTIFIER_POINTER (ivar_name));
   7842 
   7843 	    if (original_location != UNKNOWN_LOCATION)
   7844 	      inform (original_location, "originally specified here");
   7845 	    return;
   7846 	  }
   7847 
   7848 	if (!PROPERTY_NONATOMIC (property))
   7849 	  {
   7850 	    location_t original_location = DECL_SOURCE_LOCATION (ivar);
   7851 
   7852 	    error_at (location, "%<atomic%> property %qs is using bit-field "
   7853 		      "instance variable %qs",
   7854 		      IDENTIFIER_POINTER (property_name),
   7855 		      IDENTIFIER_POINTER (ivar_name));
   7856 
   7857 	    if (original_location != UNKNOWN_LOCATION)
   7858 	      inform (original_location, "originally specified here");
   7859 	    return;
   7860 	  }
   7861       }
   7862   }
   7863 
   7864   /* Check that no other property is using the same instance
   7865      variable.  */
   7866   for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
   7867     if (PROPERTY_IVAR_NAME (x) == ivar_name)
   7868       {
   7869 	location_t original_location = DECL_SOURCE_LOCATION (x);
   7870 
   7871 	error_at (location, "property %qs is using the same instance variable as property %qs",
   7872 		  IDENTIFIER_POINTER (property_name),
   7873 		  IDENTIFIER_POINTER (PROPERTY_NAME (x)));
   7874 
   7875 	if (original_location != UNKNOWN_LOCATION)
   7876 	  inform (original_location, "originally specified here");
   7877 
   7878 	/* We keep going on.  This won't cause the compiler to fail;
   7879 	   the failure would most likely be at runtime.  */
   7880       }
   7881 
   7882   /* Note that a @synthesize (and only a @synthesize) always sets
   7883      PROPERTY_IVAR_NAME to a non-NULL_TREE.  You can recognize a
   7884      @synthesize by that.  */
   7885   PROPERTY_IVAR_NAME (property) = ivar_name;
   7886 
   7887   /* PROPERTY_SETTER_NAME and PROPERTY_GETTER_NAME are copied from the
   7888      original declaration; they are always set (with the exception of
   7889      PROPERTY_SETTER_NAME not being set if PROPERTY_READONLY == 1).  */
   7890 
   7891   /* Add the property to the list of properties for current implementation. */
   7892   TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
   7893   IMPL_PROPERTY_DECL (objc_implementation_context) = property;
   7894 
   7895   /* Note how we don't actually synthesize the getter/setter here; it
   7896      would be very natural, but we may miss the fact that the user has
   7897      implemented his own getter/setter later on in the @implementation
   7898      (in which case we shouldn't generate getter/setter).  We wait
   7899      until we have parsed it all before generating the code.  */
   7900 }
   7901 
   7902 /* This function is called by the parser after a @synthesize
   7903    expression is parsed.  'location' is the location of the
   7904    @synthesize expression, and 'property_and_ivar_list' is a chained
   7905    list of the property and ivar names.  */
   7906 void
   7907 objc_add_synthesize_declaration (location_t location, tree property_and_ivar_list)
   7908 {
   7909   tree interface, chain;
   7910 
   7911   if (flag_objc1_only)
   7912     error_at (input_location, "%<@synthesize%> is not available in Objective-C 1.0");
   7913 
   7914   if (property_and_ivar_list == error_mark_node)
   7915     return;
   7916 
   7917   if (!objc_implementation_context)
   7918     {
   7919       /* We can get here only in Objective-C; the Objective-C++ parser
   7920 	 detects the problem while parsing, outputs the error
   7921 	 "misplaced '@synthesize' Objective-C++ construct" and skips
   7922 	 the declaration.  */
   7923       error_at (location, "%<@synthesize%> not in @implementation context");
   7924       return;
   7925     }
   7926 
   7927   if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
   7928     {
   7929       error_at (location, "%<@synthesize%> cannot be used in categories");
   7930       return;
   7931     }
   7932 
   7933   interface = lookup_interface (CLASS_NAME (objc_implementation_context));
   7934   if (!interface)
   7935     {
   7936       /* I can't see how this could happen, but it is good as a safety check.  */
   7937       error_at (location,
   7938 		"%<@synthesize%> requires the @interface of the class to be available");
   7939       return;
   7940     }
   7941 
   7942   /* Now, iterate over the properties and do each of them.  */
   7943   for (chain = property_and_ivar_list; chain; chain = TREE_CHAIN (chain))
   7944     {
   7945       objc_add_synthesize_declaration_for_property (location, interface, TREE_VALUE (chain),
   7946 						    TREE_PURPOSE (chain));
   7947     }
   7948 }
   7949 
   7950 /* This function is a sub-routine of objc_add_dynamic_declaration.  It
   7951    is called for each property to mark as dynamic once we have
   7952    determined that the context is Ok.  */
   7953 static void
   7954 objc_add_dynamic_declaration_for_property (location_t location, tree interface,
   7955 					   tree property_name)
   7956 {
   7957   /* Find the @property declaration.  */
   7958   tree property;
   7959 
   7960   /* Check that synthesize or dynamic has not already been used for
   7961      the same property.  */
   7962   for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
   7963     if (PROPERTY_NAME (property) == property_name)
   7964       {
   7965 	location_t original_location = DECL_SOURCE_LOCATION (property);
   7966 
   7967 	if (PROPERTY_DYNAMIC (property))
   7968 	  error_at (location, "property %qs already specified in %<@dynamic%>",
   7969 		    IDENTIFIER_POINTER (property_name));
   7970 	else
   7971 	  error_at (location, "property %qs already specified in %<@synthesize%>",
   7972 		    IDENTIFIER_POINTER (property_name));
   7973 
   7974 	if (original_location != UNKNOWN_LOCATION)
   7975 	  inform (original_location, "originally specified here");
   7976 	return;
   7977       }
   7978 
   7979   /* Check that the property is declared in the interface.  It could
   7980      also be declared in a superclass or protocol.  */
   7981   property = lookup_property (interface, property_name);
   7982 
   7983   if (!property)
   7984     {
   7985       error_at (location, "no declaration of property %qs found in the interface",
   7986 		IDENTIFIER_POINTER (property_name));
   7987       return;
   7988     }
   7989   else
   7990     {
   7991       /* We have to copy the property, because we want to chain it to
   7992 	 the implementation context, and we want to store the source
   7993 	 location of the @synthesize, not of the original
   7994 	 @property.  */
   7995       property = copy_node (property);
   7996       DECL_SOURCE_LOCATION (property) = location;
   7997     }
   7998 
   7999   /* Note that a @dynamic (and only a @dynamic) always sets
   8000      PROPERTY_DYNAMIC to 1.  You can recognize a @dynamic by that.
   8001      (actually, as explained above, PROPERTY_DECL generated by
   8002      @property and associated with a @dynamic property are also marked
   8003      as PROPERTY_DYNAMIC).  */
   8004   PROPERTY_DYNAMIC (property) = 1;
   8005 
   8006   /* Add the property to the list of properties for current implementation. */
   8007   TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
   8008   IMPL_PROPERTY_DECL (objc_implementation_context) = property;
   8009 }
   8010 
   8011 /* This function is called by the parser after a @dynamic expression
   8012    is parsed.  'location' is the location of the @dynamic expression,
   8013    and 'property_list' is a chained list of all the property
   8014    names.  */
   8015 void
   8016 objc_add_dynamic_declaration (location_t location, tree property_list)
   8017 {
   8018   tree interface, chain;
   8019 
   8020   if (flag_objc1_only)
   8021     error_at (input_location, "%<@dynamic%> is not available in Objective-C 1.0");
   8022 
   8023   if (property_list == error_mark_node)
   8024     return;
   8025 
   8026   if (!objc_implementation_context)
   8027     {
   8028       /* We can get here only in Objective-C; the Objective-C++ parser
   8029 	 detects the problem while parsing, outputs the error
   8030 	 "misplaced '@dynamic' Objective-C++ construct" and skips the
   8031 	 declaration.  */
   8032       error_at (location, "%<@dynamic%> not in @implementation context");
   8033       return;
   8034     }
   8035 
   8036   /* @dynamic is allowed in categories.  */
   8037   switch (TREE_CODE (objc_implementation_context))
   8038     {
   8039     case CLASS_IMPLEMENTATION_TYPE:
   8040       interface = lookup_interface (CLASS_NAME (objc_implementation_context));
   8041       break;
   8042     case CATEGORY_IMPLEMENTATION_TYPE:
   8043       interface = lookup_category (implementation_template,
   8044 				   CLASS_SUPER_NAME (objc_implementation_context));
   8045       break;
   8046     default:
   8047       gcc_unreachable ();
   8048     }
   8049 
   8050   if (!interface)
   8051     {
   8052       /* I can't see how this could happen, but it is good as a safety check.  */
   8053       error_at (location,
   8054 		"%<@dynamic%> requires the @interface of the class to be available");
   8055       return;
   8056     }
   8057 
   8058   /* Now, iterate over the properties and do each of them.  */
   8059   for (chain = property_list; chain; chain = TREE_CHAIN (chain))
   8060     {
   8061       objc_add_dynamic_declaration_for_property (location, interface, TREE_VALUE (chain));
   8062     }
   8063 }
   8064 
   8065 /* Main routine to generate code/data for all the property information for
   8066    current implementation (class or category). CLASS is the interface where
   8067    ivars are declared.  CLASS_METHODS is where methods are found which
   8068    could be a class or a category depending on whether we are implementing
   8069    property of a class or a category.  */
   8070 
   8071 static void
   8072 objc_gen_property_data (tree klass, tree class_methods)
   8073 {
   8074   tree x;
   8075 
   8076   for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
   8077     {
   8078       /* @dynamic property - nothing to check or synthesize.  */
   8079       if (PROPERTY_DYNAMIC (x))
   8080 	continue;
   8081 
   8082       /* @synthesize property - need to synthesize the accessors.  */
   8083       if (PROPERTY_IVAR_NAME (x))
   8084 	{
   8085 	  objc_synthesize_getter (klass, class_methods, x);
   8086 
   8087 	  if (PROPERTY_READONLY (x) == 0)
   8088 	    objc_synthesize_setter (klass, class_methods, x);
   8089 
   8090 	  continue;
   8091 	}
   8092 
   8093       gcc_unreachable ();
   8094     }
   8095 }
   8096 
   8097 /* This is called once we see the "@end" in an interface/implementation.  */
   8098 
   8099 static void
   8100 finish_class (tree klass)
   8101 {
   8102   switch (TREE_CODE (klass))
   8103     {
   8104     case CLASS_IMPLEMENTATION_TYPE:
   8105       {
   8106 	/* All metadata generation is done in runtime.generate_metadata().  */
   8107 
   8108 	/* Generate what needed for property; setters, getters, etc. */
   8109 	objc_gen_property_data (implementation_template, implementation_template);
   8110 
   8111 	if (implementation_template != objc_implementation_context)
   8112 	  {
   8113 	    /* Ensure that all method listed in the interface contain bodies.  */
   8114 	    check_methods (CLASS_CLS_METHODS (implementation_template),
   8115 			   objc_implementation_context, '+');
   8116 	    check_methods (CLASS_NST_METHODS (implementation_template),
   8117 			   objc_implementation_context, '-');
   8118 
   8119 	    if (CLASS_PROTOCOL_LIST (implementation_template))
   8120 	      check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
   8121 			       "class",
   8122 			       CLASS_NAME (objc_implementation_context));
   8123 	  }
   8124 	break;
   8125       }
   8126     case CATEGORY_IMPLEMENTATION_TYPE:
   8127       {
   8128 	tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
   8129 
   8130 	if (category)
   8131 	  {
   8132 	    /* Generate what needed for property; setters, getters, etc. */
   8133 	    objc_gen_property_data (implementation_template, category);
   8134 
   8135 	    /* Ensure all method listed in the interface contain bodies.  */
   8136 	    check_methods (CLASS_CLS_METHODS (category),
   8137 			   objc_implementation_context, '+');
   8138 	    check_methods (CLASS_NST_METHODS (category),
   8139 			   objc_implementation_context, '-');
   8140 
   8141 	    if (CLASS_PROTOCOL_LIST (category))
   8142 	      check_protocols (CLASS_PROTOCOL_LIST (category),
   8143 			       "category",
   8144 			       CLASS_SUPER_NAME (objc_implementation_context));
   8145 	  }
   8146 	break;
   8147       }
   8148     case CLASS_INTERFACE_TYPE:
   8149     case CATEGORY_INTERFACE_TYPE:
   8150     case PROTOCOL_INTERFACE_TYPE:
   8151       {
   8152 	/* Process properties of the class. */
   8153 	tree x;
   8154 	for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
   8155 	  {
   8156 	    /* Now we check that the appropriate getter is declared,
   8157 	       and if not, we declare one ourselves.  */
   8158 	    tree getter_decl = lookup_method (CLASS_NST_METHODS (klass),
   8159 					      PROPERTY_GETTER_NAME (x));
   8160 
   8161 	    if (getter_decl)
   8162 	      {
   8163 		/* TODO: Check that the declaration is consistent with the property.  */
   8164 		;
   8165 	      }
   8166 	    else
   8167 	      {
   8168 		/* Generate an instance method declaration for the
   8169 		   getter; for example "- (id) name;".  In general it
   8170 		   will be of the form
   8171 		   -(type)property_getter_name;  */
   8172 		tree rettype = build_tree_list (NULL_TREE, TREE_TYPE (x));
   8173 		getter_decl = build_method_decl (INSTANCE_METHOD_DECL,
   8174 						 rettype, PROPERTY_GETTER_NAME (x),
   8175 						 NULL_TREE, false);
   8176 		if (PROPERTY_OPTIONAL (x))
   8177 		  objc_add_method (objc_interface_context, getter_decl, false, true);
   8178 		else
   8179 		  objc_add_method (objc_interface_context, getter_decl, false, false);
   8180 		TREE_DEPRECATED (getter_decl) = TREE_DEPRECATED (x);
   8181 		TREE_UNAVAILABLE (getter_decl) = TREE_UNAVAILABLE (x);
   8182 		METHOD_PROPERTY_CONTEXT (getter_decl) = x;
   8183 	      }
   8184 
   8185 	    if (PROPERTY_READONLY (x) == 0)
   8186 	      {
   8187 		/* Now we check that the appropriate setter is declared,
   8188 		   and if not, we declare on ourselves.  */
   8189 		tree setter_decl = lookup_method (CLASS_NST_METHODS (klass),
   8190 						  PROPERTY_SETTER_NAME (x));
   8191 
   8192 		if (setter_decl)
   8193 		  {
   8194 		    /* TODO: Check that the declaration is consistent with the property.  */
   8195 		    ;
   8196 		  }
   8197 		else
   8198 		  {
   8199 		    /* The setter name is something like 'setName:'.
   8200 		       We need the substring 'setName' to build the
   8201 		       method declaration due to how the declaration
   8202 		       works.  TODO: build_method_decl() will then
   8203 		       generate back 'setName:' from 'setName'; it
   8204 		       would be more efficient to hook into there.  */
   8205 		    const char *full_setter_name = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x));
   8206 		    size_t length = strlen (full_setter_name);
   8207 		    char *setter_name = (char *) alloca (length);
   8208 		    tree ret_type, selector, arg_type, arg_name;
   8209 
   8210 		    memcpy (setter_name, full_setter_name, length - 1);
   8211 		    setter_name[length - 1] = '\0';
   8212 		    ret_type = build_tree_list (NULL_TREE, void_type_node);
   8213 		    arg_type = build_tree_list (NULL_TREE, TREE_TYPE (x));
   8214 		    arg_name = get_identifier ("_value");
   8215 		    selector = objc_build_keyword_decl (get_identifier (setter_name),
   8216 							arg_type, arg_name, NULL);
   8217 		    setter_decl = build_method_decl (INSTANCE_METHOD_DECL,
   8218 						     ret_type, selector,
   8219 						     build_tree_list (NULL_TREE, NULL_TREE),
   8220 						     false);
   8221 		    if (PROPERTY_OPTIONAL (x))
   8222 		      objc_add_method (objc_interface_context, setter_decl, false, true);
   8223 		    else
   8224 		      objc_add_method (objc_interface_context, setter_decl, false, false);
   8225 		    TREE_DEPRECATED (setter_decl) = TREE_DEPRECATED (x);
   8226 		    TREE_UNAVAILABLE (setter_decl) = TREE_UNAVAILABLE (x);
   8227 		    METHOD_PROPERTY_CONTEXT (setter_decl) = x;
   8228 		  }
   8229 	      }
   8230 	  }
   8231 	break;
   8232       }
   8233     default:
   8234       gcc_unreachable ();
   8235       break;
   8236     }
   8237 }
   8238 
   8239 static tree
   8240 add_protocol (tree protocol)
   8241 {
   8242   /* Put protocol on list in reverse order.  */
   8243   TREE_CHAIN (protocol) = protocol_chain;
   8244   protocol_chain = protocol;
   8245   return protocol_chain;
   8246 }
   8247 
   8248 /* Check that a protocol is defined, and, recursively, that all
   8249    protocols that this protocol conforms to are defined too.  */
   8250 static void
   8251 check_that_protocol_is_defined (tree protocol)
   8252 {
   8253   if (!PROTOCOL_DEFINED (protocol))
   8254     warning (0, "definition of protocol %qE not found",
   8255 	     PROTOCOL_NAME (protocol));
   8256 
   8257   /* If the protocol itself conforms to other protocols, check them
   8258      too, recursively.  */
   8259   if (PROTOCOL_LIST (protocol))
   8260     {
   8261       tree p;
   8262 
   8263       for (p = PROTOCOL_LIST (protocol); p; p = TREE_CHAIN (p))
   8264 	check_that_protocol_is_defined (TREE_VALUE (p));
   8265     }
   8266 }
   8267 
   8268 /* Looks up a protocol.  If 'warn_if_deprecated' is true, a warning is
   8269    emitted if the protocol is deprecated.  If 'definition_required' is
   8270    true, a warning is emitted if a full @protocol definition has not
   8271    been seen.  */
   8272 static tree
   8273 lookup_protocol (tree ident, bool warn_if_deprecated, bool definition_required)
   8274 {
   8275   tree chain;
   8276 
   8277   for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
   8278     if (ident == PROTOCOL_NAME (chain))
   8279       {
   8280 	if (TREE_UNAVAILABLE (chain))
   8281 	  error ("protocol %qE is unavailable", PROTOCOL_NAME (chain));
   8282 	else if (warn_if_deprecated && TREE_DEPRECATED (chain))
   8283 	  {
   8284 	    /* It would be nice to use warn_deprecated_use() here, but
   8285 	       we are using TREE_CHAIN (which is supposed to be the
   8286 	       TYPE_STUB_DECL for a TYPE) for something different.  */
   8287 	    warning (OPT_Wdeprecated_declarations, "protocol %qE is deprecated",
   8288 		     PROTOCOL_NAME (chain));
   8289 	  }
   8290 
   8291 	if (definition_required)
   8292 	  check_that_protocol_is_defined (chain);
   8293 
   8294 	return chain;
   8295       }
   8296 
   8297   return NULL_TREE;
   8298 }
   8299 
   8300 /* This function forward declares the protocols named by NAMES.  If
   8301    they are already declared or defined, the function has no effect.  */
   8302 
   8303 void
   8304 objc_declare_protocol (tree name, tree attributes)
   8305 {
   8306   bool deprecated = false;
   8307   bool unavailable = false;
   8308 
   8309 #ifdef OBJCPLUS
   8310   if (current_namespace != global_namespace) {
   8311     error ("Objective-C declarations may only appear in global scope");
   8312   }
   8313 #endif /* OBJCPLUS */
   8314 
   8315   /* Determine if 'deprecated', the only attribute we recognize for
   8316      protocols, was used.  Ignore all other attributes.  */
   8317   if (attributes)
   8318     {
   8319       tree attribute;
   8320       for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
   8321 	{
   8322 	  tree name = TREE_PURPOSE (attribute);
   8323 
   8324 	  if (is_attribute_p  ("deprecated", name))
   8325 	    deprecated = true;
   8326 	  else if (is_attribute_p  ("unavailable", name))
   8327 	    unavailable = true;
   8328 	  else
   8329 	    warning (OPT_Wattributes, "%qE attribute directive ignored", name);
   8330 	}
   8331     }
   8332 
   8333   if (lookup_protocol (name, /* warn if deprecated */ false,
   8334 		       /* definition_required */ false) == NULL_TREE)
   8335     {
   8336       tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
   8337 
   8338       TYPE_LANG_SLOT_1 (protocol)
   8339 	= make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
   8340       PROTOCOL_NAME (protocol) = name;
   8341       PROTOCOL_LIST (protocol) = NULL_TREE;
   8342       add_protocol (protocol);
   8343       PROTOCOL_DEFINED (protocol) = 0;
   8344       PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
   8345 
   8346       if (attributes)
   8347 	{
   8348 	  /* TODO: Do we need to store the attributes here ? */
   8349 	  TYPE_ATTRIBUTES (protocol) = attributes;
   8350 	  if (deprecated)
   8351 	    TREE_DEPRECATED (protocol) = 1;
   8352 	  if (unavailable)
   8353 	    TREE_UNAVAILABLE (protocol) = 1;
   8354 	}
   8355     }
   8356 }
   8357 
   8358 static tree
   8359 start_protocol (enum tree_code code, tree name, tree list, tree attributes)
   8360 {
   8361   tree protocol;
   8362   bool deprecated = false;
   8363   bool unavailable = false;
   8364 
   8365 #ifdef OBJCPLUS
   8366   if (current_namespace != global_namespace) {
   8367     error ("Objective-C declarations may only appear in global scope");
   8368   }
   8369 #endif /* OBJCPLUS */
   8370 
   8371   /* Determine if 'deprecated', the only attribute we recognize for
   8372      protocols, was used.  Ignore all other attributes.  */
   8373   if (attributes)
   8374     {
   8375       tree attribute;
   8376       for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
   8377 	{
   8378 	  tree name = TREE_PURPOSE (attribute);
   8379 
   8380 	  if (is_attribute_p  ("deprecated", name))
   8381 	    deprecated = true;
   8382 	  else if (is_attribute_p  ("unavailable", name))
   8383 	    unavailable = true;
   8384 	  else
   8385 	    warning (OPT_Wattributes, "%qE attribute directive ignored", name);
   8386 	}
   8387     }
   8388 
   8389   protocol = lookup_protocol (name, /* warn_if_deprecated */ false,
   8390 			      /* definition_required */ false);
   8391 
   8392   if (!protocol)
   8393     {
   8394       protocol = make_node (code);
   8395       TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
   8396 
   8397       PROTOCOL_NAME (protocol) = name;
   8398       PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list, /* definition_required */ false);
   8399       add_protocol (protocol);
   8400       PROTOCOL_DEFINED (protocol) = 1;
   8401       PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
   8402 
   8403       check_protocol_recursively (protocol, list);
   8404     }
   8405   else if (! PROTOCOL_DEFINED (protocol))
   8406     {
   8407       PROTOCOL_DEFINED (protocol) = 1;
   8408       PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list, /* definition_required */ false);
   8409 
   8410       check_protocol_recursively (protocol, list);
   8411     }
   8412   else
   8413     {
   8414       warning (0, "duplicate declaration for protocol %qE",
   8415 	       name);
   8416     }
   8417 
   8418   if (attributes)
   8419     {
   8420       TYPE_ATTRIBUTES (protocol) = attributes;
   8421       if (deprecated)
   8422 	TREE_DEPRECATED (protocol) = 1;
   8423       if (unavailable)
   8424 	TREE_UNAVAILABLE (protocol) = 1;
   8425     }
   8426 
   8427   return protocol;
   8428 }
   8429 
   8430 /* Decay array and function parameters into pointers.  */
   8431 
   8432 static tree
   8433 objc_decay_parm_type (tree type)
   8434 {
   8435   if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == FUNCTION_TYPE)
   8436     type = build_pointer_type (TREE_CODE (type) == ARRAY_TYPE
   8437 			       ? TREE_TYPE (type)
   8438 			       : type);
   8439 
   8440   return type;
   8441 }
   8442 
   8443 static GTY(()) tree objc_parmlist = NULL_TREE;
   8444 
   8445 /* Append PARM to a list of formal parameters of a method, making a necessary
   8446    array-to-pointer adjustment along the way.  */
   8447 
   8448 void
   8449 objc_push_parm (tree parm)
   8450 {
   8451   tree type;
   8452 
   8453   if (TREE_TYPE (parm) == error_mark_node)
   8454     {
   8455       objc_parmlist = chainon (objc_parmlist, parm);
   8456       return;
   8457     }
   8458 
   8459   /* Decay arrays and functions into pointers.  */
   8460   type = objc_decay_parm_type (TREE_TYPE (parm));
   8461 
   8462   /* If the parameter type has been decayed, a new PARM_DECL needs to be
   8463      built as well.  */
   8464   if (type != TREE_TYPE (parm))
   8465     parm = build_decl (input_location, PARM_DECL, DECL_NAME (parm), type);
   8466 
   8467   DECL_ARG_TYPE (parm)
   8468     = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
   8469 
   8470   /* Record constancy and volatility.  */
   8471   c_apply_type_quals_to_decl
   8472   ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
   8473    | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
   8474    | (TYPE_ATOMIC (TREE_TYPE (parm)) ? TYPE_QUAL_ATOMIC : 0)
   8475    | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
   8476 
   8477   objc_parmlist = chainon (objc_parmlist, parm);
   8478 }
   8479 
   8480 /* Retrieve the formal parameter list constructed via preceding calls to
   8481    objc_push_parm().  */
   8482 
   8483 #ifdef OBJCPLUS
   8484 tree
   8485 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED,
   8486 		    tree expr ATTRIBUTE_UNUSED)
   8487 {
   8488   tree parm_info = objc_parmlist;
   8489   objc_parmlist = NULL_TREE;
   8490 
   8491   return parm_info;
   8492 }
   8493 #else
   8494 struct c_arg_info *
   8495 objc_get_parm_info (int have_ellipsis, tree expr)
   8496 {
   8497   tree parm_info = objc_parmlist;
   8498   struct c_arg_info *arg_info;
   8499   /* The C front-end requires an elaborate song and dance at
   8500      this point.  */
   8501   push_scope ();
   8502   declare_parm_level ();
   8503   while (parm_info)
   8504     {
   8505       tree next = DECL_CHAIN (parm_info);
   8506 
   8507       DECL_CHAIN (parm_info) = NULL_TREE;
   8508       parm_info = pushdecl (parm_info);
   8509       finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
   8510       parm_info = next;
   8511     }
   8512   arg_info = get_parm_info (have_ellipsis, expr);
   8513   pop_scope ();
   8514   objc_parmlist = NULL_TREE;
   8515   return arg_info;
   8516 }
   8517 #endif
   8518 
   8519 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
   8520    method definitions.  In the case of instance methods, we can be more
   8521    specific as to the type of 'self'.  */
   8522 
   8523 static void
   8524 synth_self_and_ucmd_args (void)
   8525 {
   8526   tree self_type;
   8527 
   8528   if (objc_method_context
   8529       && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
   8530     self_type = objc_instance_type;
   8531   else
   8532     /* Really a `struct objc_class *'. However, we allow people to
   8533        assign to self, which changes its type midstream.  */
   8534     self_type = objc_object_type;
   8535 
   8536   /* id self; */
   8537   objc_push_parm (build_decl (input_location,
   8538 			      PARM_DECL, self_id, self_type));
   8539 
   8540   /* SEL _cmd; */
   8541   objc_push_parm (build_decl (input_location,
   8542 			      PARM_DECL, ucmd_id, objc_selector_type));
   8543 }
   8544 
   8545 /* Transform an Objective-C method definition into a static C function
   8546    definition, synthesizing the first two arguments, "self" and "_cmd",
   8547    in the process.  EXPR is NULL or an expression that needs to be
   8548    evaluated for the side effects of array size expressions in the
   8549    parameters.  */
   8550 
   8551 static void
   8552 start_method_def (tree method, tree expr)
   8553 {
   8554   tree parmlist;
   8555 #ifdef OBJCPLUS
   8556   tree parm_info;
   8557 #else
   8558   struct c_arg_info *parm_info;
   8559 #endif
   8560   int have_ellipsis = 0;
   8561 
   8562   /* If we are defining a "dealloc" method in a non-root class, we
   8563      will need to check if a [super dealloc] is missing, and warn if
   8564      it is.  */
   8565   if(CLASS_SUPER_NAME (objc_implementation_context)
   8566      && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
   8567     should_call_super_dealloc = 1;
   8568   else
   8569     should_call_super_dealloc = 0;
   8570 
   8571   /* Required to implement _msgSuper.  */
   8572   objc_method_context = method;
   8573   UOBJC_SUPER_decl = NULL_TREE;
   8574 
   8575   /* Generate prototype declarations for arguments..."new-style".  */
   8576   synth_self_and_ucmd_args ();
   8577 
   8578   /* Generate argument declarations if a keyword_decl.  */
   8579   parmlist = METHOD_SEL_ARGS (method);
   8580   while (parmlist)
   8581     {
   8582       /* parmlist is a KEYWORD_DECL.  */
   8583       tree type = TREE_VALUE (TREE_TYPE (parmlist));
   8584       tree parm;
   8585 
   8586       parm = build_decl (input_location,
   8587 			 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
   8588       decl_attributes (&parm, DECL_ATTRIBUTES (parmlist), 0);
   8589       objc_push_parm (parm);
   8590       parmlist = DECL_CHAIN (parmlist);
   8591     }
   8592 
   8593   if (METHOD_ADD_ARGS (method))
   8594     {
   8595       tree akey;
   8596 
   8597       for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
   8598 	   akey; akey = TREE_CHAIN (akey))
   8599 	{
   8600 	  objc_push_parm (TREE_VALUE (akey));
   8601 	}
   8602 
   8603       if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
   8604 	have_ellipsis = 1;
   8605     }
   8606 
   8607   parm_info = objc_get_parm_info (have_ellipsis, expr);
   8608 
   8609   really_start_method (objc_method_context, parm_info);
   8610 }
   8611 
   8612 /* Return 1 if TYPE1 is equivalent to TYPE2 for purposes of method
   8613    overloading.  */
   8614 static int
   8615 objc_types_are_equivalent (tree type1, tree type2)
   8616 {
   8617   if (type1 == type2)
   8618     return 1;
   8619 
   8620   /* Strip away indirections.  */
   8621   while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
   8622 	 && (TREE_CODE (type1) == TREE_CODE (type2)))
   8623     type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
   8624   if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
   8625     return 0;
   8626 
   8627   /* Compare the protocol lists.  */
   8628   type1 = (TYPE_HAS_OBJC_INFO (type1)
   8629 	   ? TYPE_OBJC_PROTOCOL_LIST (type1)
   8630 	   : NULL_TREE);
   8631   type2 = (TYPE_HAS_OBJC_INFO (type2)
   8632 	   ? TYPE_OBJC_PROTOCOL_LIST (type2)
   8633 	   : NULL_TREE);
   8634 
   8635   /* If there are no protocols (most common case), the types are
   8636      identical.  */
   8637   if (type1 == NULL_TREE && type2 == NULL_TREE)
   8638     return 1;
   8639 
   8640   /* If one has protocols, and the other one hasn't, they are not
   8641      identical.  */
   8642   if ((type1 == NULL_TREE && type2 != NULL_TREE)
   8643       || (type1 != NULL_TREE && type2 == NULL_TREE))
   8644     return 0;
   8645   else
   8646     {
   8647       /* Else, both have protocols, and we need to do the full
   8648 	 comparison.  It is possible that either type1 or type2
   8649 	 contain some duplicate protocols in the list, so we can't
   8650 	 even just compare list_length as a first check.  */
   8651       tree t;
   8652 
   8653       for (t = type2; t; t = TREE_CHAIN (t))
   8654 	if (!lookup_protocol_in_reflist (type1, TREE_VALUE (t)))
   8655 	  return 0;
   8656 
   8657       for (t = type1; t; t = TREE_CHAIN (t))
   8658 	if (!lookup_protocol_in_reflist (type2, TREE_VALUE (t)))
   8659 	  return 0;
   8660 
   8661       return 1;
   8662     }
   8663 }
   8664 
   8665 /* Return 1 if TYPE1 has the same size and alignment as TYPE2.  */
   8666 
   8667 static int
   8668 objc_types_share_size_and_alignment (tree type1, tree type2)
   8669 {
   8670   return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
   8671 	  && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
   8672 }
   8673 
   8674 /* Return 1 if PROTO1 is equivalent to PROTO2
   8675    for purposes of method overloading.  Ordinarily, the type signatures
   8676    should match up exactly, unless STRICT is zero, in which case we
   8677    shall allow differences in which the size and alignment of a type
   8678    is the same.  */
   8679 
   8680 static int
   8681 comp_proto_with_proto (tree proto1, tree proto2, int strict)
   8682 {
   8683   tree type1, type2;
   8684 
   8685   /* The following test is needed in case there are hashing
   8686      collisions.  */
   8687   if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
   8688     return 0;
   8689 
   8690   /* Compare return types.  */
   8691   type1 = TREE_VALUE (TREE_TYPE (proto1));
   8692   type2 = TREE_VALUE (TREE_TYPE (proto2));
   8693 
   8694   if (!objc_types_are_equivalent (type1, type2)
   8695       && (strict || !objc_types_share_size_and_alignment (type1, type2)))
   8696     return 0;
   8697 
   8698   /* Compare argument types.  */
   8699 
   8700   /* The first argument (objc_object_type) is always the same, no need
   8701      to compare.  */
   8702 
   8703   /* The second argument (objc_selector_type) is always the same, no
   8704      need to compare.  */
   8705 
   8706   /* Compare the other arguments.  */
   8707   {
   8708     tree arg1, arg2;
   8709 
   8710     /* Compare METHOD_SEL_ARGS.  */
   8711     for (arg1 = METHOD_SEL_ARGS (proto1), arg2 = METHOD_SEL_ARGS (proto2);
   8712 	 arg1 && arg2;
   8713 	 arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2))
   8714       {
   8715 	type1 = TREE_VALUE (TREE_TYPE (arg1));
   8716 	type2 = TREE_VALUE (TREE_TYPE (arg2));
   8717 
   8718 	/* FIXME: Do we need to decay argument types to compare them ?  */
   8719 	type1 = objc_decay_parm_type (type1);
   8720 	type2 = objc_decay_parm_type (type2);
   8721 
   8722 	if (!objc_types_are_equivalent (type1, type2)
   8723 	    && (strict || !objc_types_share_size_and_alignment (type1, type2)))
   8724 	  return 0;
   8725       }
   8726 
   8727     /* The loop ends when arg1 or arg2 are NULL.  Make sure they are
   8728        both NULL.  */
   8729     if (arg1 != arg2)
   8730       return 0;
   8731 
   8732     /* Compare METHOD_ADD_ARGS.  */
   8733     if ((METHOD_ADD_ARGS (proto1) && !METHOD_ADD_ARGS (proto2))
   8734 	|| (METHOD_ADD_ARGS (proto2) && !METHOD_ADD_ARGS (proto1)))
   8735       return 0;
   8736 
   8737     if (METHOD_ADD_ARGS (proto1))
   8738       {
   8739 	for (arg1 = TREE_CHAIN (METHOD_ADD_ARGS (proto1)), arg2 = TREE_CHAIN (METHOD_ADD_ARGS (proto2));
   8740 	     arg1 && arg2;
   8741 	     arg1 = TREE_CHAIN (arg1), arg2 = TREE_CHAIN (arg2))
   8742 	  {
   8743 	    type1 = TREE_TYPE (TREE_VALUE (arg1));
   8744 	    type2 = TREE_TYPE (TREE_VALUE (arg2));
   8745 
   8746 	    /* FIXME: Do we need to decay argument types to compare them ?  */
   8747 	    type1 = objc_decay_parm_type (type1);
   8748 	    type2 = objc_decay_parm_type (type2);
   8749 
   8750 	    if (!objc_types_are_equivalent (type1, type2)
   8751 		&& (strict || !objc_types_share_size_and_alignment (type1, type2)))
   8752 	      return 0;
   8753 	  }
   8754       }
   8755 
   8756     /* The loop ends when arg1 or arg2 are NULL.  Make sure they are
   8757        both NULL.  */
   8758     if (arg1 != arg2)
   8759       return 0;
   8760 
   8761     /* Compare METHOD_ADD_ARGS_ELLIPSIS_P.  */
   8762     if (METHOD_ADD_ARGS_ELLIPSIS_P (proto1) != METHOD_ADD_ARGS_ELLIPSIS_P (proto2))
   8763       return 0;
   8764   }
   8765 
   8766   /* Success.  */
   8767   return 1;
   8768 }
   8769 
   8770 /* This routine returns true if TYPE is a valid objc object type,
   8771    suitable for messaging; false otherwise.  If 'accept_class' is
   8772    'true', then a Class object is considered valid for messaging and
   8773    'true' is returned if 'type' refers to a Class.  If 'accept_class'
   8774    is 'false', then a Class object is not considered valid for
   8775    messaging and 'false' is returned in that case.  */
   8776 
   8777 static bool
   8778 objc_type_valid_for_messaging (tree type, bool accept_classes)
   8779 {
   8780   if (!POINTER_TYPE_P (type))
   8781     return false;
   8782 
   8783   /* We will check for an NSObject type attribute  on the pointer if other
   8784      tests fail.  */
   8785   tree type_attr = TYPE_ATTRIBUTES (type);
   8786 
   8787   /* Remove the pointer indirection; don't remove more than one
   8788      otherwise we'd consider "NSObject **" a valid type for messaging,
   8789      which it isn't.  */
   8790   type = TREE_TYPE (type);
   8791 
   8792   /* We allow void * to have an NSObject type attr.  */
   8793   if (VOID_TYPE_P (type) && type_attr)
   8794     return lookup_attribute ("NSObject", type_attr) != NULL_TREE;
   8795 
   8796   if (TREE_CODE (type) != RECORD_TYPE)
   8797     return false;
   8798 
   8799   if (objc_is_object_id (type))
   8800     return true;
   8801 
   8802   if (objc_is_class_id (type))
   8803     return accept_classes;
   8804 
   8805   if (TYPE_HAS_OBJC_INFO (type))
   8806     return true;
   8807 
   8808   if (type_attr)
   8809     return lookup_attribute ("NSObject", type_attr) != NULL_TREE;
   8810 
   8811   return false;
   8812 }
   8813 
   8814 void
   8815 objc_start_function (tree name, tree type, tree attrs,
   8816 #ifdef OBJCPLUS
   8817 		     tree params
   8818 #else
   8819 		     struct c_arg_info *params
   8820 #endif
   8821 		     )
   8822 {
   8823   tree fndecl = build_decl (input_location,
   8824 			    FUNCTION_DECL, name, type);
   8825 
   8826 #ifdef OBJCPLUS
   8827   DECL_ARGUMENTS (fndecl) = params;
   8828   DECL_INITIAL (fndecl) = error_mark_node;
   8829   DECL_EXTERNAL (fndecl) = 0;
   8830   TREE_STATIC (fndecl) = 1;
   8831   retrofit_lang_decl (fndecl);
   8832   cplus_decl_attributes (&fndecl, attrs, 0);
   8833   start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
   8834 #else
   8835   current_function_returns_value = 0;  /* Assume, until we see it does.  */
   8836   current_function_returns_null = 0;
   8837   decl_attributes (&fndecl, attrs, 0);
   8838   announce_function (fndecl);
   8839   DECL_INITIAL (fndecl) = error_mark_node;
   8840   DECL_EXTERNAL (fndecl) = 0;
   8841   TREE_STATIC (fndecl) = 1;
   8842   current_function_decl = pushdecl (fndecl);
   8843   push_scope ();
   8844   declare_parm_level ();
   8845   DECL_RESULT (current_function_decl)
   8846     = build_decl (input_location,
   8847 		  RESULT_DECL, NULL_TREE,
   8848 		  TREE_TYPE (TREE_TYPE (current_function_decl)));
   8849   DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
   8850   DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
   8851   start_fname_decls ();
   8852   store_parm_decls_from (params);
   8853 #endif
   8854 
   8855   TREE_USED (current_function_decl) = 1;
   8856 }
   8857 
   8858 /* - Generate an identifier for the function. the format is "_n_cls",
   8859      where 1 <= n <= nMethods, and cls is the name the implementation we
   8860      are processing.
   8861    - Install the return type from the method declaration.
   8862    - If we have a prototype, check for type consistency.  */
   8863 
   8864 static void
   8865 really_start_method (tree method,
   8866 #ifdef OBJCPLUS
   8867 		     tree parmlist
   8868 #else
   8869 		     struct c_arg_info *parmlist
   8870 #endif
   8871 		     )
   8872 {
   8873   tree ret_type, meth_type;
   8874   tree method_id;
   8875   const char *sel_name, *class_name, *cat_name;
   8876   char *buf;
   8877 
   8878   /* Synth the storage class & assemble the return type.  */
   8879   ret_type = TREE_VALUE (TREE_TYPE (method));
   8880 
   8881   sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
   8882   class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
   8883   cat_name = ((TREE_CODE (objc_implementation_context)
   8884 	       == CLASS_IMPLEMENTATION_TYPE)
   8885 	      ? NULL
   8886 	      : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
   8887   method_slot++;
   8888 
   8889   /* Make sure this is big enough for any plausible method label.  */
   8890   buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
   8891 			 + (cat_name ? strlen (cat_name) : 0));
   8892 
   8893   OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
   8894 			 class_name, cat_name, sel_name, method_slot);
   8895 
   8896   method_id = get_identifier (buf);
   8897 
   8898 #ifdef OBJCPLUS
   8899   /* Objective-C methods cannot be overloaded, so we don't need
   8900      the type encoding appended.  It looks bad anyway... */
   8901   push_lang_context (lang_name_c);
   8902 #endif
   8903 
   8904   meth_type = build_function_type_for_method (ret_type, method, METHOD_DEF, 0);
   8905   objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
   8906 
   8907   /* Set self_decl from the first argument.  */
   8908   self_decl = DECL_ARGUMENTS (current_function_decl);
   8909 
   8910   /* Suppress unused warnings.  */
   8911   TREE_USED (self_decl) = 1;
   8912   DECL_READ_P (self_decl) = 1;
   8913   TREE_USED (DECL_CHAIN (self_decl)) = 1;
   8914   DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
   8915 #ifdef OBJCPLUS
   8916   pop_lang_context ();
   8917 #endif
   8918 
   8919   METHOD_DEFINITION (method) = current_function_decl;
   8920 
   8921   /* Check consistency...start_function, pushdecl, duplicate_decls.  */
   8922 
   8923   if (implementation_template != objc_implementation_context)
   8924     {
   8925       tree proto
   8926 	= lookup_method_static (implementation_template,
   8927 				METHOD_SEL_NAME (method),
   8928 				((TREE_CODE (method) == CLASS_METHOD_DECL)
   8929 				 | OBJC_LOOKUP_NO_SUPER));
   8930 
   8931       if (proto)
   8932 	{
   8933 	  if (!comp_proto_with_proto (method, proto, 1))
   8934 	    {
   8935 	      bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
   8936 
   8937 	      warning_at (DECL_SOURCE_LOCATION (method), 0,
   8938 			  "conflicting types for %<%c%s%>",
   8939 			  (type ? '-' : '+'),
   8940 			  identifier_to_locale (gen_method_decl (method)));
   8941 	      inform (DECL_SOURCE_LOCATION (proto),
   8942 		      "previous declaration of %<%c%s%>",
   8943 		      (type ? '-' : '+'),
   8944 		      identifier_to_locale (gen_method_decl (proto)));
   8945 	    }
   8946 	  else
   8947 	    {
   8948 	      /* If the method in the @interface was deprecated, mark
   8949 		 the implemented method as deprecated too.  It should
   8950 		 never be used for messaging (when the deprecation
   8951 		 warnings are produced), but just in case.  */
   8952 	      if (TREE_DEPRECATED (proto))
   8953 		TREE_DEPRECATED (method) = 1;
   8954 	      if (TREE_UNAVAILABLE (proto))
   8955 		TREE_UNAVAILABLE (method) = 1;
   8956 
   8957 	      /* If the method in the @interface was marked as
   8958 		 'noreturn', mark the function implementing the method
   8959 		 as 'noreturn' too.  */
   8960 	      TREE_THIS_VOLATILE (current_function_decl) = TREE_THIS_VOLATILE (proto);
   8961 	    }
   8962 	}
   8963       else
   8964 	{
   8965 	  /* We have a method @implementation even though we did not
   8966 	     see a corresponding @interface declaration (which is allowed
   8967 	     by Objective-C rules).  Go ahead and place the method in
   8968 	     the @interface anyway, so that message dispatch lookups
   8969 	     will see it.  */
   8970 	  tree interface = implementation_template;
   8971 
   8972 	  if (TREE_CODE (objc_implementation_context)
   8973 	      == CATEGORY_IMPLEMENTATION_TYPE)
   8974 	    interface = lookup_category
   8975 			(interface,
   8976 			 CLASS_SUPER_NAME (objc_implementation_context));
   8977 
   8978 	  if (interface)
   8979 	    objc_add_method (interface, copy_node (method),
   8980 			     TREE_CODE (method) == CLASS_METHOD_DECL,
   8981 			     /* is_optional= */ false);
   8982 	}
   8983     }
   8984 }
   8985 
   8986 static void *UOBJC_SUPER_scope = 0;
   8987 
   8988 /* _n_Method (id self, SEL sel, ...)
   8989      {
   8990        struct objc_super _S;
   8991        _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
   8992      }  */
   8993 
   8994 static tree
   8995 get_super_receiver (void)
   8996 {
   8997   if (objc_method_context)
   8998     {
   8999       tree super_expr, super_expr_list, class_expr;
   9000       bool inst_meth;
   9001       if (!UOBJC_SUPER_decl)
   9002       {
   9003 	UOBJC_SUPER_decl = build_decl (input_location,
   9004 				       VAR_DECL, get_identifier (TAG_SUPER),
   9005 				       objc_super_template);
   9006 	/* This prevents `unused variable' warnings when compiling with -Wall.  */
   9007 	TREE_USED (UOBJC_SUPER_decl) = 1;
   9008 	DECL_READ_P (UOBJC_SUPER_decl) = 1;
   9009 	lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
   9010         finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
   9011 		     NULL_TREE);
   9012 	UOBJC_SUPER_scope = objc_get_current_scope ();
   9013       }
   9014 
   9015       /* Set receiver to self.  */
   9016       super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
   9017       super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
   9018 				      NOP_EXPR, input_location, self_decl,
   9019 				      NULL_TREE);
   9020       super_expr_list = super_expr;
   9021 
   9022       /* Set class to begin searching.  */
   9023       /* Get the ident for the superclass class field & build a ref to it.
   9024          ??? maybe we should just name the field the same for all runtimes.  */
   9025       super_expr = (*runtime.super_superclassfield_ident) ();
   9026       super_expr = objc_build_component_ref (UOBJC_SUPER_decl, super_expr);
   9027 
   9028       gcc_assert (imp_list->imp_context == objc_implementation_context
   9029 		  && imp_list->imp_template == implementation_template);
   9030       inst_meth = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL);
   9031 
   9032       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
   9033 	class_expr =  (*runtime.get_class_super_ref) (input_location,
   9034 						      imp_list, inst_meth);
   9035       else
   9036 	/* We have a category.  */
   9037 	{
   9038 	  tree super_name = CLASS_SUPER_NAME (imp_list->imp_template);
   9039 	  tree super_class;
   9040 
   9041 	  /* Barf if super used in a category of a root object.  */
   9042 	  if (!super_name)
   9043 	    {
   9044 	      error ("no super class declared in interface for %qE",
   9045 		     CLASS_NAME (imp_list->imp_template));
   9046 	      return error_mark_node;
   9047 	    }
   9048 
   9049 	  super_class = (*runtime.get_category_super_ref) (input_location,
   9050 							   imp_list, inst_meth);
   9051 	  class_expr = build_c_cast (input_location,
   9052 				     TREE_TYPE (super_expr), super_class);
   9053 	}
   9054 
   9055       super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
   9056 				      NOP_EXPR,
   9057 				      input_location, class_expr, NULL_TREE);
   9058 
   9059       super_expr_list = build_compound_expr (input_location,
   9060 					     super_expr_list, super_expr);
   9061 
   9062       super_expr = build_unary_op (input_location,
   9063 				   ADDR_EXPR, UOBJC_SUPER_decl, 0);
   9064       super_expr_list = build_compound_expr (input_location,
   9065 					     super_expr_list, super_expr);
   9066 
   9067       return super_expr_list;
   9068     }
   9069   else
   9070     {
   9071       error ("%<[super ...]%> must appear in a method context");
   9072       return error_mark_node;
   9073     }
   9074 }
   9075 
   9076 /* When exiting a scope, sever links to a 'super' declaration (if any)
   9077    therein contained.  */
   9078 
   9079 void
   9080 objc_clear_super_receiver (void)
   9081 {
   9082   if (objc_method_context
   9083       && UOBJC_SUPER_scope == objc_get_current_scope ())
   9084     {
   9085       UOBJC_SUPER_decl = 0;
   9086       UOBJC_SUPER_scope = 0;
   9087     }
   9088 }
   9089 
   9090 void
   9091 objc_finish_method_definition (tree fndecl)
   9092 {
   9093   /* We cannot validly inline ObjC methods, at least not without a language
   9094      extension to declare that a method need not be dynamically
   9095      dispatched, so suppress all thoughts of doing so.  */
   9096   DECL_UNINLINABLE (fndecl) = 1;
   9097 
   9098 #ifndef OBJCPLUS
   9099   /* The C++ front-end will have called finish_function() for us.  */
   9100   finish_function ();
   9101 #endif
   9102 
   9103   METHOD_ENCODING (objc_method_context)
   9104     = encode_method_prototype (objc_method_context);
   9105 
   9106   /* Required to implement _msgSuper. This must be done AFTER finish_function,
   9107      since the optimizer may find "may be used before set" errors.  */
   9108   objc_method_context = NULL_TREE;
   9109 
   9110   if (should_call_super_dealloc)
   9111     warning (0, "method possibly missing a [super dealloc] call");
   9112 }
   9113 
   9114 /* Given a tree DECL node, produce a printable description of it in the given
   9115    buffer, overwriting the buffer.  */
   9116 
   9117 static char *
   9118 gen_declaration (tree decl)
   9119 {
   9120   errbuf[0] = '\0';
   9121 
   9122   if (DECL_P (decl))
   9123     {
   9124       gen_type_name_0 (TREE_TYPE (decl));
   9125 
   9126       if (DECL_NAME (decl))
   9127 	{
   9128 	  if (!POINTER_TYPE_P (TREE_TYPE (decl)))
   9129 	    strcat (errbuf, " ");
   9130 
   9131 	  strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
   9132 	}
   9133 
   9134 #ifdef OBJCPLUS
   9135       tree w = DECL_BIT_FIELD_REPRESENTATIVE (decl);
   9136 #else
   9137       tree w = DECL_INITIAL (decl);
   9138 #endif
   9139       if (w)
   9140 	{
   9141 	  STRIP_ANY_LOCATION_WRAPPER (w);
   9142 	  if (TREE_CODE (w) == INTEGER_CST)
   9143 	    sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
   9144 		     TREE_INT_CST_LOW (w));
   9145 	}
   9146     }
   9147 
   9148   return errbuf;
   9149 }
   9150 
   9151 /* Given a tree TYPE node, produce a printable description of it in the given
   9152    buffer, overwriting the buffer.  */
   9153 
   9154 static char *
   9155 gen_type_name_0 (tree type)
   9156 {
   9157   tree orig = type, proto;
   9158 
   9159   if (TYPE_P (type) && TYPE_NAME (type))
   9160     type = TYPE_NAME (type);
   9161   else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
   9162     {
   9163       tree inner = TREE_TYPE (type);
   9164 
   9165       while (TREE_CODE (inner) == ARRAY_TYPE)
   9166 	inner = TREE_TYPE (inner);
   9167 
   9168       gen_type_name_0 (inner);
   9169 
   9170       if (!POINTER_TYPE_P (inner))
   9171 	strcat (errbuf, " ");
   9172 
   9173       if (POINTER_TYPE_P (type))
   9174 	strcat (errbuf, "*");
   9175       else
   9176 	while (type != inner)
   9177 	  {
   9178 	    strcat (errbuf, "[");
   9179 
   9180 	    if (TYPE_DOMAIN (type))
   9181 	      {
   9182 		char sz[20];
   9183 
   9184 		sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
   9185 			 (TREE_INT_CST_LOW
   9186 			  (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
   9187 		strcat (errbuf, sz);
   9188 	      }
   9189 
   9190 	    strcat (errbuf, "]");
   9191 	    type = TREE_TYPE (type);
   9192 	  }
   9193 
   9194       goto exit_function;
   9195     }
   9196 
   9197   if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
   9198     type = DECL_NAME (type);
   9199 
   9200   strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
   9201 		  ? IDENTIFIER_POINTER (type)
   9202 		  : "");
   9203 
   9204   /* For 'id' and 'Class', adopted protocols are stored in the pointee.  */
   9205   if (objc_is_id (orig))
   9206     orig = TREE_TYPE (orig);
   9207 
   9208   proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
   9209 
   9210   if (proto)
   9211     {
   9212       strcat (errbuf, " <");
   9213 
   9214       while (proto) {
   9215 	strcat (errbuf,
   9216 		IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
   9217 	proto = TREE_CHAIN (proto);
   9218 	strcat (errbuf, proto ? ", " : ">");
   9219       }
   9220     }
   9221 
   9222  exit_function:
   9223   return errbuf;
   9224 }
   9225 
   9226 static char *
   9227 gen_type_name (tree type)
   9228 {
   9229   errbuf[0] = '\0';
   9230 
   9231   return gen_type_name_0 (type);
   9232 }
   9233 
   9234 /* Given a method tree, put a printable description into the given
   9235    buffer (overwriting) and return a pointer to the buffer.  */
   9236 
   9237 static char *
   9238 gen_method_decl (tree method)
   9239 {
   9240   tree chain;
   9241 
   9242   strcpy (errbuf, "(");  /* NB: Do _not_ call strcat() here.  */
   9243   gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
   9244   strcat (errbuf, ")");
   9245   chain = METHOD_SEL_ARGS (method);
   9246 
   9247   if (chain)
   9248     {
   9249       /* We have a chain of keyword_decls.  */
   9250       do
   9251         {
   9252 	  if (KEYWORD_KEY_NAME (chain))
   9253 	    strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
   9254 
   9255 	  strcat (errbuf, ":(");
   9256 	  gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
   9257 	  strcat (errbuf, ")");
   9258 
   9259 	  strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
   9260 	  if ((chain = DECL_CHAIN (chain)))
   9261 	    strcat (errbuf, " ");
   9262         }
   9263       while (chain);
   9264 
   9265       if (METHOD_ADD_ARGS (method))
   9266 	{
   9267 	  chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
   9268 
   9269 	  /* Know we have a chain of parm_decls.  */
   9270 	  while (chain)
   9271 	    {
   9272 	      strcat (errbuf, ", ");
   9273 	      gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
   9274 	      chain = TREE_CHAIN (chain);
   9275 	    }
   9276 
   9277 	  if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
   9278 	    strcat (errbuf, ", ...");
   9279 	}
   9280     }
   9281 
   9282   else
   9283     /* We have a unary selector.  */
   9284     strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
   9285 
   9286   return errbuf;
   9287 }
   9288 
   9289 /* Debug info.  */
   9291 
   9292 
   9293 /* Dump an @interface declaration of the supplied class CHAIN to the
   9294    supplied file FP.  Used to implement the -gen-decls option (which
   9295    prints out an @interface declaration of all classes compiled in
   9296    this run); potentially useful for debugging the compiler too.  */
   9297 void
   9298 dump_interface (FILE *fp, tree chain)
   9299 {
   9300   /* FIXME: A heap overflow here whenever a method (or ivar)
   9301      declaration is so long that it doesn't fit in the buffer.  The
   9302      code and all the related functions should be rewritten to avoid
   9303      using fixed size buffers.  */
   9304   const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
   9305   tree ivar_decls = CLASS_RAW_IVARS (chain);
   9306   tree nst_methods = CLASS_NST_METHODS (chain);
   9307   tree cls_methods = CLASS_CLS_METHODS (chain);
   9308 
   9309   fprintf (fp, "\n@interface %s", my_name);
   9310 
   9311   /* CLASS_SUPER_NAME is used to store the superclass name for
   9312      classes, and the category name for categories.  */
   9313   if (CLASS_SUPER_NAME (chain))
   9314     {
   9315       const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
   9316 
   9317       switch (TREE_CODE (chain))
   9318 	{
   9319 	case CATEGORY_IMPLEMENTATION_TYPE:
   9320 	case CATEGORY_INTERFACE_TYPE:
   9321 	  fprintf (fp, " (%s)\n", name);
   9322 	  break;
   9323 	default:
   9324 	  fprintf (fp, " : %s\n", name);
   9325 	  break;
   9326 	}
   9327     }
   9328   else
   9329     fprintf (fp, "\n");
   9330 
   9331   /* FIXME - the following doesn't seem to work at the moment.  */
   9332   if (ivar_decls)
   9333     {
   9334       fprintf (fp, "{\n");
   9335       do
   9336 	{
   9337 	  fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
   9338 	  ivar_decls = TREE_CHAIN (ivar_decls);
   9339 	}
   9340       while (ivar_decls);
   9341       fprintf (fp, "}\n");
   9342     }
   9343 
   9344   while (nst_methods)
   9345     {
   9346       fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
   9347       nst_methods = TREE_CHAIN (nst_methods);
   9348     }
   9349 
   9350   while (cls_methods)
   9351     {
   9352       fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
   9353       cls_methods = TREE_CHAIN (cls_methods);
   9354     }
   9355 
   9356   fprintf (fp, "@end\n");
   9357 }
   9358 
   9359 #if 0
   9360 /* Produce the pretty printing for an Objective-C method.  This is
   9361    currently unused, but could be handy while reorganizing the pretty
   9362    printing to be more robust.  */
   9363 static const char *
   9364 objc_pretty_print_method (bool is_class_method,
   9365 			  const char *class_name,
   9366 			  const char *category_name,
   9367 			  const char *selector)
   9368 {
   9369   if (category_name)
   9370     {
   9371       char *result = XNEWVEC (char, strlen (class_name) + strlen (category_name)
   9372 			      + strlen (selector) + 7);
   9373 
   9374       if (is_class_method)
   9375 	sprintf (result, "+[%s(%s) %s]", class_name, category_name, selector);
   9376       else
   9377 	sprintf (result, "-[%s(%s) %s]", class_name, category_name, selector);
   9378 
   9379       return result;
   9380     }
   9381   else
   9382     {
   9383       char *result = XNEWVEC (char, strlen (class_name)
   9384 			      + strlen (selector) + 5);
   9385 
   9386       if (is_class_method)
   9387 	sprintf (result, "+[%s %s]", class_name, selector);
   9388       else
   9389 	sprintf (result, "-[%s %s]", class_name, selector);
   9390 
   9391       return result;
   9392     }
   9393 }
   9394 #endif
   9395 
   9396 /* Demangle function for Objective-C.  Attempt to demangle the
   9397    function name associated with a method (eg, going from
   9398    "_i_NSObject__class" to "-[NSObject class]"); usually for the
   9399    purpose of pretty printing or error messages.  Return the demangled
   9400    name, or NULL if the string is not an Objective-C mangled method
   9401    name.
   9402 
   9403    Because of how the mangling is done, any method that has a '_' in
   9404    its original name is at risk of being demangled incorrectly.  In
   9405    some cases there are multiple valid ways to demangle a method name
   9406    and there is no way we can decide.
   9407 
   9408    TODO: objc_demangle() can't always get it right; the right way to
   9409    get this correct for all method names would be to store the
   9410    Objective-C method name somewhere in the function decl.  Then,
   9411    there is no demangling to do; we'd just pull the method name out of
   9412    the decl.  As an additional bonus, when printing error messages we
   9413    could check for such a method name, and if we find it, we know the
   9414    function is actually an Objective-C method and we could print error
   9415    messages saying "In method '+[NSObject class]" instead of "In
   9416    function '+[NSObject class]" as we do now.  */
   9417 static const char *
   9418 objc_demangle (const char *mangled)
   9419 {
   9420   char *demangled, *cp;
   9421 
   9422   /* First of all, if the name is too short it can't be an Objective-C
   9423      mangled method name.  */
   9424   if (mangled[0] == '\0' || mangled[1] == '\0' || mangled[2] == '\0')
   9425     return NULL;
   9426 
   9427   /* If the name looks like an already demangled one, return it
   9428      unchanged.  This should only happen on Darwin, where method names
   9429      are mangled differently into a pretty-print form (such as
   9430      '+[NSObject class]', see darwin.h).  In that case, demangling is
   9431      a no-op, but we need to return the demangled name if it was an
   9432      ObjC one, and return NULL if not.  We should be safe as no C/C++
   9433      function can start with "-[" or "+[".  */
   9434   if ((mangled[0] == '-' || mangled[0] == '+')
   9435       && (mangled[1] == '['))
   9436     return mangled;
   9437 
   9438   if (mangled[0] == '_' &&
   9439       (mangled[1] == 'i' || mangled[1] == 'c') &&
   9440       mangled[2] == '_')
   9441     {
   9442       cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
   9443       if (mangled[1] == 'i')
   9444 	*cp++ = '-';            /* for instance method */
   9445       else
   9446 	*cp++ = '+';            /* for class method */
   9447       *cp++ = '[';              /* opening left brace */
   9448       strcpy(cp, mangled+3);    /* tack on the rest of the mangled name */
   9449       while (*cp && *cp == '_')
   9450 	cp++;                   /* skip any initial underbars in class name */
   9451       cp = strchr(cp, '_');     /* find first non-initial underbar */
   9452       if (cp == NULL)
   9453 	{
   9454 	  free(demangled);      /* not mangled name */
   9455 	  return NULL;
   9456 	}
   9457       if (cp[1] == '_')  /* easy case: no category name */
   9458 	{
   9459 	  *cp++ = ' ';            /* replace two '_' with one ' ' */
   9460 	  strcpy(cp, mangled + (cp - demangled) + 2);
   9461 	}
   9462       else
   9463 	{
   9464 	  *cp++ = '(';            /* less easy case: category name */
   9465 	  cp = strchr(cp, '_');
   9466 	  if (cp == 0)
   9467 	    {
   9468 	      free(demangled);    /* not mangled name */
   9469 	      return NULL;
   9470 	    }
   9471 	  *cp++ = ')';
   9472 	  *cp++ = ' ';            /* overwriting 1st char of method name... */
   9473 	  strcpy(cp, mangled + (cp - demangled)); /* get it back */
   9474 	}
   9475       /* Now we have the method name.  We need to generally replace
   9476 	 '_' with ':' but trying to preserve '_' if it could only have
   9477 	 been in the mangled string because it was already in the
   9478 	 original name.  In cases where it's ambiguous, we assume that
   9479 	 any '_' originated from a ':'.  */
   9480 
   9481       /* Initial '_'s in method name can't have been generating by
   9482 	 converting ':'s.  Skip them.  */
   9483       while (*cp && *cp == '_')
   9484 	cp++;
   9485 
   9486       /* If the method name does not end with '_', then it has no
   9487 	 arguments and there was no replacement of ':'s with '_'s
   9488 	 during mangling.  Check for that case, and skip any
   9489 	 replacement if so.  This at least guarantees that methods
   9490 	 with no arguments are always demangled correctly (unless the
   9491 	 original name ends with '_').  */
   9492       if (*(mangled + strlen (mangled) - 1) != '_')
   9493 	{
   9494 	  /* Skip to the end.  */
   9495 	  for (; *cp; cp++)
   9496 	    ;
   9497 	}
   9498       else
   9499 	{
   9500 	  /* Replace remaining '_' with ':'.  This may get it wrong if
   9501 	     there were '_'s in the original name.  In most cases it
   9502 	     is impossible to disambiguate.  */
   9503 	  for (; *cp; cp++)
   9504 	    if (*cp == '_')
   9505 	      *cp = ':';
   9506 	}
   9507       *cp++ = ']';              /* closing right brace */
   9508       *cp++ = 0;                /* string terminator */
   9509       return demangled;
   9510     }
   9511   else
   9512     return NULL;             /* not an objc mangled name */
   9513 }
   9514 
   9515 /* Try to pretty-print a decl.  If the 'decl' is an Objective-C
   9516    specific decl, return the printable name for it.  If not, return
   9517    NULL.  */
   9518 const char *
   9519 objc_maybe_printable_name (tree decl, int v ATTRIBUTE_UNUSED)
   9520 {
   9521   switch (TREE_CODE (decl))
   9522     {
   9523     case FUNCTION_DECL:
   9524       return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
   9525 
   9526       /* The following happens when we are printing a deprecation
   9527 	 warning for a method.  The warn_deprecation() will end up
   9528 	 trying to print the decl for INSTANCE_METHOD_DECL or
   9529 	 CLASS_METHOD_DECL.  It would be nice to be able to print
   9530 	 "-[NSObject autorelease] is deprecated", but to do that, we'd
   9531 	 need to store the class and method name in the method decl,
   9532 	 which we currently don't do.  For now, just return the name
   9533 	 of the method.  We don't return NULL, because that may
   9534 	 trigger further attempts to pretty-print the decl in C/C++,
   9535 	 but they wouldn't know how to pretty-print it.  */
   9536     case INSTANCE_METHOD_DECL:
   9537     case CLASS_METHOD_DECL:
   9538       return IDENTIFIER_POINTER (DECL_NAME (decl));
   9539       /* This happens when printing a deprecation warning for a
   9540 	 property.  We may want to consider some sort of pretty
   9541 	 printing (eg, include the class name where it was declared
   9542 	 ?).  */
   9543     case PROPERTY_DECL:
   9544       return IDENTIFIER_POINTER (PROPERTY_NAME (decl));
   9545     default:
   9546       return NULL;
   9547     }
   9548 }
   9549 
   9550 /* Return a printable name for 'decl'.  This first tries
   9551    objc_maybe_printable_name(), and if that fails, it returns the name
   9552    in the decl.  This is used as LANG_HOOKS_DECL_PRINTABLE_NAME for
   9553    Objective-C; in Objective-C++, setting the hook is not enough
   9554    because lots of C++ Front-End code calls cxx_printable_name,
   9555    dump_decl and other C++ functions directly.  So instead we have
   9556    modified dump_decl to call objc_maybe_printable_name directly.  */
   9557 const char *
   9558 objc_printable_name (tree decl, int v)
   9559 {
   9560   const char *demangled_name = objc_maybe_printable_name (decl, v);
   9561 
   9562   if (demangled_name != NULL)
   9563     return demangled_name;
   9564   else
   9565     return IDENTIFIER_POINTER (DECL_NAME (decl));
   9566 }
   9567 
   9568 /* Routine is called to issue diagnostic when reference to a private
   9569    ivar is made and no other variable with same name is found in
   9570    current scope.  */
   9571 bool
   9572 objc_diagnose_private_ivar (tree id)
   9573 {
   9574   tree ivar;
   9575   if (!objc_method_context)
   9576     return false;
   9577   ivar = is_ivar (objc_ivar_chain, id);
   9578   if (ivar && is_private (ivar))
   9579     {
   9580       error ("instance variable %qs is declared private",
   9581 	     IDENTIFIER_POINTER (id));
   9582       return true;
   9583     }
   9584   return false;
   9585 }
   9586 
   9587 /* Look up ID as an instance variable.  OTHER contains the result of
   9588    the C or C++ lookup, which we may want to use instead.  */
   9589 /* To use properties inside an instance method, use self.property.  */
   9590 tree
   9591 objc_lookup_ivar (tree other, tree id)
   9592 {
   9593   tree ivar;
   9594 
   9595   /* If we are not inside of an ObjC method, ivar lookup makes no sense.  */
   9596   if (!objc_method_context)
   9597     return other;
   9598 
   9599   if (!strcmp (IDENTIFIER_POINTER (id), "super"))
   9600     /* We have a message to super.  */
   9601     return get_super_receiver ();
   9602 
   9603   /* In a class method, look up an instance variable only as a last
   9604      resort.  */
   9605   if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
   9606       && other && other != error_mark_node)
   9607     return other;
   9608 
   9609   /* Don't look up the ivar if the user has explicitly advised against
   9610      it with -fno-local-ivars.  */
   9611 
   9612   if (!flag_local_ivars)
   9613     return other;
   9614 
   9615   /* Look up the ivar, but do not use it if it is not accessible.  */
   9616   ivar = is_ivar (objc_ivar_chain, id);
   9617 
   9618   if (!ivar || is_private (ivar))
   9619     return other;
   9620 
   9621   /* In an instance method, a local variable (or parameter) may hide the
   9622      instance variable.  */
   9623   if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
   9624       && other && other != error_mark_node
   9625 #ifdef OBJCPLUS
   9626       && CP_DECL_CONTEXT (other) != global_namespace)
   9627 #else
   9628       && !DECL_FILE_SCOPE_P (other))
   9629 #endif
   9630     {
   9631       if (warn_shadow_ivar == 1 || (warn_shadow && warn_shadow_ivar != 0)) {
   9632           warning (warn_shadow_ivar ? OPT_Wshadow_ivar : OPT_Wshadow,
   9633                    "local declaration of %qE hides instance variable", id);
   9634       }
   9635 
   9636       return other;
   9637     }
   9638 
   9639   /* At this point, we are either in an instance method with no obscuring
   9640      local definitions, or in a class method with no alternate definitions
   9641      at all.  */
   9642   return build_ivar_reference (id);
   9643 }
   9644 
   9645 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression.  This
   9646    needs to be done if we are calling a function through a cast.  */
   9647 
   9648 tree
   9649 objc_rewrite_function_call (tree function, tree first_param)
   9650 {
   9651   if (TREE_CODE (function) == NOP_EXPR
   9652       && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
   9653       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
   9654 	 == FUNCTION_DECL)
   9655     function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
   9656 		       TREE_OPERAND (function, 0), first_param,
   9657 		       build_int_cst (TREE_TYPE (first_param), 0));
   9658 
   9659   return function;
   9660 }
   9661 
   9662 /* This is called to "gimplify" a PROPERTY_REF node.  It builds the
   9663    corresponding 'getter' function call.  Note that we assume the
   9664    PROPERTY_REF to be valid since we generated it while parsing.  */
   9665 static void
   9666 objc_gimplify_property_ref (tree *expr_p)
   9667 {
   9668   tree getter = PROPERTY_REF_GETTER_CALL (*expr_p);
   9669   tree call_exp;
   9670 
   9671   if (getter == NULL_TREE)
   9672     {
   9673       tree property_decl = PROPERTY_REF_PROPERTY_DECL (*expr_p);
   9674       /* This can happen if DECL_ARTIFICIAL (*expr_p), but
   9675 	 should be impossible for real properties, which always
   9676 	 have a getter.  */
   9677       error_at (EXPR_LOCATION (*expr_p), "no %qs getter found",
   9678 		IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
   9679       /* Try to recover from the error to prevent an ICE.  We take
   9680 	 zero and cast it to the type of the property.  */
   9681       *expr_p = convert (TREE_TYPE (property_decl),
   9682 			 integer_zero_node);
   9683       return;
   9684     }
   9685 
   9686   /* FIXME, this should be a label indicating availability in general.  */
   9687   if (PROPERTY_REF_DEPRECATED_GETTER (*expr_p))
   9688     {
   9689       if (TREE_UNAVAILABLE (PROPERTY_REF_DEPRECATED_GETTER (*expr_p)))
   9690 	error_unavailable_use (PROPERTY_REF_DEPRECATED_GETTER (*expr_p),
   9691 			       NULL_TREE);
   9692       else
   9693 	/* PROPERTY_REF_DEPRECATED_GETTER contains the method prototype
   9694 	 that is deprecated.  */
   9695 	warn_deprecated_use (PROPERTY_REF_DEPRECATED_GETTER (*expr_p),
   9696 			     NULL_TREE);
   9697     }
   9698 
   9699   call_exp = getter;
   9700 #ifdef OBJCPLUS
   9701   /* In C++, a getter which returns an aggregate value results in a
   9702      target_expr which initializes a temporary to the call
   9703      expression.  */
   9704   if (TREE_CODE (getter) == TARGET_EXPR)
   9705     {
   9706       gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter)));
   9707       gcc_assert (TREE_CODE (TREE_OPERAND (getter, 0)) == VAR_DECL);
   9708       call_exp = TREE_OPERAND (getter, 1);
   9709     }
   9710 #endif
   9711   gcc_checking_assert ((flag_objc_nilcheck
   9712 			&& TREE_CODE (call_exp) == COND_EXPR)
   9713 		       || TREE_CODE (call_exp) == CALL_EXPR);
   9714 
   9715   *expr_p = call_exp;
   9716 }
   9717 
   9718 /* This is called when "gimplifying" the trees.  We need to gimplify
   9719    the Objective-C/Objective-C++ specific trees, then hand over the
   9720    process to C/C++.  */
   9721 int
   9722 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   9723 {
   9724   enum tree_code code = TREE_CODE (*expr_p);
   9725   switch (code)
   9726     {
   9727       /* Look for the special case of OBJC_TYPE_REF with the address
   9728 	 of a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend
   9729 	 or one of its cousins).  */
   9730     case OBJ_TYPE_REF:
   9731       if (TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
   9732 	  && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
   9733 	  == FUNCTION_DECL)
   9734 	{
   9735 	  enum gimplify_status r0, r1;
   9736 
   9737 	  /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
   9738 	     value of the OBJ_TYPE_REF, so force them to be emitted
   9739 	     during subexpression evaluation rather than after the
   9740 	     OBJ_TYPE_REF. This permits objc_msgSend calls in
   9741 	     Objective C to use direct rather than indirect calls when
   9742 	     the object expression has a postincrement.  */
   9743 	  r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
   9744 			      is_gimple_val, fb_rvalue);
   9745 	  r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
   9746 			      is_gimple_val, fb_rvalue);
   9747 
   9748 	  return MIN (r0, r1);
   9749 	}
   9750       break;
   9751     case PROPERTY_REF:
   9752       objc_gimplify_property_ref (expr_p);
   9753       /* Do not return yet; let C/C++ gimplify the resulting expression.  */
   9754       break;
   9755     default:
   9756       break;
   9757     }
   9758 
   9759 #ifdef OBJCPLUS
   9760   return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
   9761 #else
   9762   return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
   9763 #endif
   9764 }
   9765 
   9766 /* --- FAST ENUMERATION --- */
   9767 /* Begin code generation for fast enumeration (foreach) ... */
   9768 
   9769 /* Defines
   9770 
   9771   struct __objcFastEnumerationState
   9772    {
   9773      unsigned long state;
   9774      id            *itemsPtr;
   9775      unsigned long *mutationsPtr;
   9776      unsigned long extra[5];
   9777    };
   9778 
   9779    Confusingly enough, NSFastEnumeration is then defined by libraries
   9780    to be the same structure.
   9781 */
   9782 
   9783 static void
   9784 build_fast_enumeration_state_template (void)
   9785 {
   9786   tree decls, *chain = NULL;
   9787 
   9788   /* { */
   9789   objc_fast_enumeration_state_template = objc_start_struct (get_identifier
   9790 							    (TAG_FAST_ENUMERATION_STATE));
   9791 
   9792   /* unsigned long state; */
   9793   decls = add_field_decl (long_unsigned_type_node, "state", &chain);
   9794 
   9795   /* id            *itemsPtr; */
   9796   add_field_decl (build_pointer_type (objc_object_type),
   9797 		  "itemsPtr", &chain);
   9798 
   9799   /* unsigned long *mutationsPtr; */
   9800   add_field_decl (build_pointer_type (long_unsigned_type_node),
   9801 		  "mutationsPtr", &chain);
   9802 
   9803   /* unsigned long extra[5]; */
   9804   add_field_decl (build_sized_array_type (long_unsigned_type_node, 5),
   9805 		  "extra", &chain);
   9806 
   9807   /* } */
   9808   objc_finish_struct (objc_fast_enumeration_state_template, decls);
   9809 }
   9810 
   9811 /*
   9812   'objc_finish_foreach_loop()' generates the code for an Objective-C
   9813   foreach loop.  The 'location' argument is the location of the 'for'
   9814   that starts the loop.  The 'object_expression' is the expression of
   9815   the 'object' that iterates; the 'collection_expression' is the
   9816   expression of the collection that we iterate over (we need to make
   9817   sure we evaluate this only once); the 'for_body' is the set of
   9818   statements to be executed in each iteration; 'break_label' and
   9819   'continue_label' are the break and continue labels which we need to
   9820   emit since the <statements> may be jumping to 'break_label' (if they
   9821   contain 'break') or to 'continue_label' (if they contain
   9822   'continue').
   9823 
   9824   The syntax is
   9825 
   9826   for (<object expression> in <collection expression>)
   9827     <statements>
   9828 
   9829   which is compiled into the following blurb:
   9830 
   9831   {
   9832     id __objc_foreach_collection;
   9833     __objc_fast_enumeration_state __objc_foreach_enum_state;
   9834     unsigned long __objc_foreach_batchsize;
   9835     id __objc_foreach_items[16];
   9836     __objc_foreach_collection = <collection expression>;
   9837     __objc_foreach_enum_state = { 0 };
   9838     __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16];
   9839 
   9840     if (__objc_foreach_batchsize == 0)
   9841       <object expression> = nil;
   9842     else
   9843       {
   9844 	unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
   9845         next_batch:
   9846 	  {
   9847 	    unsigned long __objc_foreach_index;
   9848             __objc_foreach_index = 0;
   9849 
   9850             next_object:
   9851 	    if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
   9852 	    <object expression> = enumState.itemsPtr[__objc_foreach_index];
   9853 	    <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
   9854 
   9855             continue_label:
   9856             __objc_foreach_index++;
   9857             if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
   9858 	    __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16];
   9859          }
   9860        if (__objc_foreach_batchsize != 0) goto next_batch;
   9861        <object expression> = nil;
   9862        break_label:
   9863       }
   9864   }
   9865 
   9866   'statements' may contain a 'continue' or 'break' instruction, which
   9867   the user expects to 'continue' or 'break' the entire foreach loop.
   9868   We are provided the labels that 'break' and 'continue' jump to, so
   9869   we place them where we want them to jump to when they pick them.
   9870 
   9871   Optimization TODO: we could cache the IMP of
   9872   countByEnumeratingWithState:objects:count:.
   9873 */
   9874 
   9875 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line.  */
   9876 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
   9877 
   9878 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
   9879 #include "tree-pretty-print.h"
   9880 #endif
   9881 
   9882 void
   9883 objc_finish_foreach_loop (location_t location, tree object_expression, tree collection_expression, tree for_body,
   9884 			  tree break_label, tree continue_label)
   9885 {
   9886   /* A tree representing the __objcFastEnumerationState struct type,
   9887      or NSFastEnumerationState struct, whatever we are using.  */
   9888   tree objc_fast_enumeration_state_type;
   9889 
   9890   /* The trees representing the declarations of each of the local variables.  */
   9891   tree objc_foreach_collection_decl;
   9892   tree objc_foreach_enum_state_decl;
   9893   tree objc_foreach_items_decl;
   9894   tree objc_foreach_batchsize_decl;
   9895   tree objc_foreach_mutations_pointer_decl;
   9896   tree objc_foreach_index_decl;
   9897 
   9898   /* A tree representing the selector countByEnumeratingWithState:objects:count:.  */
   9899   tree selector_name;
   9900 
   9901   /* A tree representing the local bind.  */
   9902   tree bind;
   9903 
   9904   /* A tree representing the external 'if (__objc_foreach_batchsize)' */
   9905   tree first_if;
   9906 
   9907   /* A tree representing the 'else' part of 'first_if'  */
   9908   tree first_else;
   9909 
   9910   /* A tree representing the 'next_batch' label.  */
   9911   tree next_batch_label_decl;
   9912 
   9913   /* A tree representing the binding after the 'next_batch' label.  */
   9914   tree next_batch_bind;
   9915 
   9916   /* A tree representing the 'next_object' label.  */
   9917   tree next_object_label_decl;
   9918 
   9919   /* Temporary variables.  */
   9920   tree t;
   9921   int i;
   9922 
   9923   if (flag_objc1_only)
   9924     error_at (location, "fast enumeration is not available in Objective-C 1.0");
   9925 
   9926   if (object_expression == error_mark_node)
   9927     return;
   9928 
   9929   if (collection_expression == error_mark_node)
   9930     return;
   9931 
   9932   if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression), true))
   9933     {
   9934       error_at (location, "iterating variable in fast enumeration is not an object");
   9935       return;
   9936     }
   9937 
   9938   if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression), true))
   9939     {
   9940       error_at (location, "collection in fast enumeration is not an object");
   9941       return;
   9942     }
   9943 
   9944   /* TODO: Check that object_expression is either a variable
   9945      declaration, or an lvalue.  */
   9946 
   9947   /* This kludge is an idea from apple.  We use the
   9948      __objcFastEnumerationState struct implicitly defined by the
   9949      compiler, unless a NSFastEnumerationState struct has been defined
   9950      (by a Foundation library such as GNUstep Base) in which case, we
   9951      use that one.
   9952   */
   9953   objc_fast_enumeration_state_type = objc_fast_enumeration_state_template;
   9954   {
   9955     tree objc_NSFastEnumeration_type = lookup_name (get_identifier ("NSFastEnumerationState"));
   9956 
   9957     if (objc_NSFastEnumeration_type)
   9958       {
   9959 	/* TODO: We really need to check that
   9960 	   objc_NSFastEnumeration_type is the same as ours!  */
   9961 	if (TREE_CODE (objc_NSFastEnumeration_type) == TYPE_DECL)
   9962 	  {
   9963 	    /* If it's a typedef, use the original type.  */
   9964 	    if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type))
   9965 	      objc_fast_enumeration_state_type = DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type);
   9966 	    else
   9967 	      objc_fast_enumeration_state_type = TREE_TYPE (objc_NSFastEnumeration_type);
   9968 	  }
   9969       }
   9970   }
   9971 
   9972   /* { */
   9973   /* Done by c-parser.cc.  */
   9974 
   9975   /* type object; */
   9976   /* Done by c-parser.cc.  */
   9977 
   9978   /* Disable warnings that 'object' is unused.  For example the code
   9979 
   9980      for (id object in collection)
   9981        i++;
   9982 
   9983      which can be used to count how many objects there are in the
   9984      collection is fine and should generate no warnings even if
   9985      'object' is technically unused.  */
   9986   TREE_USED (object_expression) = 1;
   9987   if (DECL_P (object_expression))
   9988     DECL_READ_P (object_expression) = 1;
   9989 
   9990   /*  id __objc_foreach_collection */
   9991   objc_foreach_collection_decl = objc_create_temporary_var (objc_object_type, "__objc_foreach_collection");
   9992 
   9993   /*  __objcFastEnumerationState __objc_foreach_enum_state; */
   9994   objc_foreach_enum_state_decl = objc_create_temporary_var (objc_fast_enumeration_state_type, "__objc_foreach_enum_state");
   9995   TREE_CHAIN (objc_foreach_enum_state_decl) = objc_foreach_collection_decl;
   9996 
   9997   /* id __objc_foreach_items[16]; */
   9998   objc_foreach_items_decl = objc_create_temporary_var (build_sized_array_type (objc_object_type, 16), "__objc_foreach_items");
   9999   TREE_CHAIN (objc_foreach_items_decl) = objc_foreach_enum_state_decl;
   10000 
   10001   /* unsigned long __objc_foreach_batchsize; */
   10002   objc_foreach_batchsize_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_batchsize");
   10003   TREE_CHAIN (objc_foreach_batchsize_decl) = objc_foreach_items_decl;
   10004 
   10005   /* Generate the local variable binding.  */
   10006   bind = build3 (BIND_EXPR, void_type_node, objc_foreach_batchsize_decl, NULL, NULL);
   10007   SET_EXPR_LOCATION (bind, location);
   10008   TREE_SIDE_EFFECTS (bind) = 1;
   10009 
   10010   /*  __objc_foreach_collection = <collection expression>; */
   10011   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_collection_decl, collection_expression);
   10012   SET_EXPR_LOCATION (t, location);
   10013   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
   10014   /* We have used 'collection_expression'.  */
   10015   mark_exp_read (collection_expression);
   10016 
   10017   /*  __objc_foreach_enum_state.state = 0; */
   10018   t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
   10019 								     get_identifier ("state")),
   10020 	      build_int_cst (long_unsigned_type_node, 0));
   10021   SET_EXPR_LOCATION (t, location);
   10022   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
   10023 
   10024   /*  __objc_foreach_enum_state.itemsPtr = NULL; */
   10025   t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
   10026 								     get_identifier ("itemsPtr")),
   10027 	      null_pointer_node);
   10028   SET_EXPR_LOCATION (t, location);
   10029   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
   10030 
   10031   /*  __objc_foreach_enum_state.mutationsPtr = NULL; */
   10032   t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
   10033 								     get_identifier ("mutationsPtr")),
   10034 	      null_pointer_node);
   10035   SET_EXPR_LOCATION (t, location);
   10036   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
   10037 
   10038   /*  __objc_foreach_enum_state.extra[0] = 0; */
   10039   /*  __objc_foreach_enum_state.extra[1] = 0; */
   10040   /*  __objc_foreach_enum_state.extra[2] = 0; */
   10041   /*  __objc_foreach_enum_state.extra[3] = 0; */
   10042   /*  __objc_foreach_enum_state.extra[4] = 0; */
   10043   for (i = 0; i < 5 ; i++)
   10044     {
   10045       t = build2 (MODIFY_EXPR, void_type_node,
   10046 		  build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
   10047 								       get_identifier ("extra")),
   10048 				   build_int_cst (NULL_TREE, i)),
   10049 		  build_int_cst (long_unsigned_type_node, 0));
   10050       SET_EXPR_LOCATION (t, location);
   10051       append_to_statement_list (t, &BIND_EXPR_BODY (bind));
   10052     }
   10053 
   10054   /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16]; */
   10055   selector_name = get_identifier ("countByEnumeratingWithState:objects:count:");
   10056 #ifdef OBJCPLUS
   10057   t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
   10058 				/* Parameters.  */
   10059 				tree_cons    /* &__objc_foreach_enum_state */
   10060 				(NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
   10061 				 tree_cons   /* __objc_foreach_items  */
   10062 				 (NULL_TREE, objc_foreach_items_decl,
   10063 				  tree_cons  /* 16 */
   10064 				  (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL);
   10065 #else
   10066   /* In C, we need to decay the __objc_foreach_items array that we are passing.  */
   10067   {
   10068     struct c_expr array;
   10069     array.value = objc_foreach_items_decl;
   10070     t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
   10071 				  /* Parameters.  */
   10072 				  tree_cons    /* &__objc_foreach_enum_state */
   10073 				  (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
   10074 				   tree_cons   /* __objc_foreach_items  */
   10075 				   (NULL_TREE, default_function_array_conversion (location, array).value,
   10076 				    tree_cons  /* 16 */
   10077 				    (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL);
   10078   }
   10079 #endif
   10080   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
   10081 	      convert (long_unsigned_type_node, t));
   10082   SET_EXPR_LOCATION (t, location);
   10083   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
   10084 
   10085   /* if (__objc_foreach_batchsize == 0) */
   10086   first_if = build3 (COND_EXPR, void_type_node,
   10087 		     /* Condition.  */
   10088 		     c_fully_fold
   10089 		     (c_common_truthvalue_conversion
   10090 		      (location,
   10091 		       build_binary_op (location,
   10092 					EQ_EXPR,
   10093 					objc_foreach_batchsize_decl,
   10094 					build_int_cst (long_unsigned_type_node, 0), 1)),
   10095 		      false, NULL),
   10096 		     /* Then block (we fill it in later).  */
   10097 		     NULL_TREE,
   10098 		     /* Else block (we fill it in later).  */
   10099 		     NULL_TREE);
   10100   SET_EXPR_LOCATION (first_if, location);
   10101   append_to_statement_list (first_if, &BIND_EXPR_BODY (bind));
   10102 
   10103   /* then <object expression> = nil; */
   10104   t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
   10105   SET_EXPR_LOCATION (t, location);
   10106   COND_EXPR_THEN (first_if) = t;
   10107 
   10108   /* Now we build the 'else' part of the if; once we finish building
   10109      it, we attach it to first_if as the 'else' part.  */
   10110 
   10111   /* else */
   10112   /* { */
   10113 
   10114   /* unsigned long __objc_foreach_mutations_pointer; */
   10115   objc_foreach_mutations_pointer_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_mutations_pointer");
   10116 
   10117   /* Generate the local variable binding.  */
   10118   first_else = build3 (BIND_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, NULL, NULL);
   10119   SET_EXPR_LOCATION (first_else, location);
   10120   TREE_SIDE_EFFECTS (first_else) = 1;
   10121 
   10122   /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
   10123   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_mutations_pointer_decl,
   10124 	      build_indirect_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
   10125 								      get_identifier ("mutationsPtr")),
   10126 				  RO_UNARY_STAR));
   10127   SET_EXPR_LOCATION (t, location);
   10128   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
   10129 
   10130   /* next_batch: */
   10131   next_batch_label_decl = create_artificial_label (location);
   10132   t = build1 (LABEL_EXPR, void_type_node, next_batch_label_decl);
   10133   SET_EXPR_LOCATION (t, location);
   10134   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
   10135 
   10136   /* { */
   10137 
   10138   /* unsigned long __objc_foreach_index; */
   10139   objc_foreach_index_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_index");
   10140 
   10141   /* Generate the local variable binding.  */
   10142   next_batch_bind = build3 (BIND_EXPR, void_type_node, objc_foreach_index_decl, NULL, NULL);
   10143   SET_EXPR_LOCATION (next_batch_bind, location);
   10144   TREE_SIDE_EFFECTS (next_batch_bind) = 1;
   10145   append_to_statement_list (next_batch_bind, &BIND_EXPR_BODY (first_else));
   10146 
   10147   /* __objc_foreach_index = 0; */
   10148   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
   10149 	      build_int_cst (long_unsigned_type_node, 0));
   10150   SET_EXPR_LOCATION (t, location);
   10151   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
   10152 
   10153   /* next_object: */
   10154   next_object_label_decl = create_artificial_label (location);
   10155   t = build1 (LABEL_EXPR, void_type_node, next_object_label_decl);
   10156   SET_EXPR_LOCATION (t, location);
   10157   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
   10158 
   10159   /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
   10160   t = build3 (COND_EXPR, void_type_node,
   10161 	      /* Condition.  */
   10162 	      c_fully_fold
   10163 	      (c_common_truthvalue_conversion
   10164 	       (location,
   10165 		build_binary_op
   10166 		(location,
   10167 		 NE_EXPR,
   10168 		 objc_foreach_mutations_pointer_decl,
   10169 		 build_indirect_ref (location,
   10170 				     objc_build_component_ref (objc_foreach_enum_state_decl,
   10171 							       get_identifier ("mutationsPtr")),
   10172 				     RO_UNARY_STAR), 1)),
   10173 	       false, NULL),
   10174 	      /* Then block.  */
   10175 	      build_function_call (input_location,
   10176 				   objc_enumeration_mutation_decl,
   10177 				   tree_cons (NULL, collection_expression, NULL)),
   10178 	      /* Else block.  */
   10179 	      NULL_TREE);
   10180   SET_EXPR_LOCATION (t, location);
   10181   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
   10182 
   10183   /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
   10184   t = build2 (MODIFY_EXPR, void_type_node, object_expression,
   10185 	      build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
   10186 								   get_identifier ("itemsPtr")),
   10187 			       objc_foreach_index_decl));
   10188   SET_EXPR_LOCATION (t, location);
   10189   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
   10190 
   10191   /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
   10192   append_to_statement_list (for_body, &BIND_EXPR_BODY (next_batch_bind));
   10193 
   10194   /* continue_label: */
   10195   if (continue_label)
   10196     {
   10197       t = build1 (LABEL_EXPR, void_type_node, continue_label);
   10198       SET_EXPR_LOCATION (t, location);
   10199       append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
   10200     }
   10201 
   10202   /* __objc_foreach_index++; */
   10203   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
   10204 	      build_binary_op (location,
   10205 			       PLUS_EXPR,
   10206 			       objc_foreach_index_decl,
   10207 			       build_int_cst (long_unsigned_type_node, 1), 1));
   10208   SET_EXPR_LOCATION (t, location);
   10209   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
   10210 
   10211   /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
   10212   t = build3 (COND_EXPR, void_type_node,
   10213 	      /* Condition.  */
   10214 	      c_fully_fold
   10215 	      (c_common_truthvalue_conversion
   10216 	       (location,
   10217 		build_binary_op (location,
   10218 				 LT_EXPR,
   10219 				 objc_foreach_index_decl,
   10220 				 objc_foreach_batchsize_decl, 1)),
   10221 	       false, NULL),
   10222 	      /* Then block.  */
   10223 	      build1 (GOTO_EXPR, void_type_node, next_object_label_decl),
   10224 	      /* Else block.  */
   10225 	      NULL_TREE);
   10226   SET_EXPR_LOCATION (t, location);
   10227   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
   10228 
   10229   /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16]; */
   10230 #ifdef OBJCPLUS
   10231   t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
   10232 				/* Parameters.  */
   10233 				tree_cons    /* &__objc_foreach_enum_state */
   10234 				(NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
   10235 				 tree_cons   /* __objc_foreach_items  */
   10236 				 (NULL_TREE, objc_foreach_items_decl,
   10237 				  tree_cons  /* 16 */
   10238 				  (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL);
   10239 #else
   10240   /* In C, we need to decay the __objc_foreach_items array that we are passing.  */
   10241   {
   10242     struct c_expr array;
   10243     array.value = objc_foreach_items_decl;
   10244     t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
   10245 				  /* Parameters.  */
   10246 				  tree_cons    /* &__objc_foreach_enum_state */
   10247 				  (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
   10248 				   tree_cons   /* __objc_foreach_items  */
   10249 				   (NULL_TREE, default_function_array_conversion (location, array).value,
   10250 				    tree_cons  /* 16 */
   10251 				    (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL);
   10252   }
   10253 #endif
   10254   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
   10255 	      convert (long_unsigned_type_node, t));
   10256   SET_EXPR_LOCATION (t, location);
   10257   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
   10258 
   10259   /* } */
   10260 
   10261   /* if (__objc_foreach_batchsize != 0) goto next_batch; */
   10262   t = build3 (COND_EXPR, void_type_node,
   10263 	      /* Condition.  */
   10264 	      c_fully_fold
   10265 	      (c_common_truthvalue_conversion
   10266 	       (location,
   10267 		build_binary_op (location,
   10268 				 NE_EXPR,
   10269 				 objc_foreach_batchsize_decl,
   10270 				 build_int_cst (long_unsigned_type_node, 0), 1)),
   10271 	       false, NULL),
   10272 	      /* Then block.  */
   10273 	      build1 (GOTO_EXPR, void_type_node, next_batch_label_decl),
   10274 	      /* Else block.  */
   10275 	      NULL_TREE);
   10276   SET_EXPR_LOCATION (t, location);
   10277   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
   10278 
   10279   /* <object expression> = nil; */
   10280   t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
   10281   SET_EXPR_LOCATION (t, location);
   10282   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
   10283 
   10284   /* break_label: */
   10285   if (break_label)
   10286     {
   10287       t = build1 (LABEL_EXPR, void_type_node, break_label);
   10288       SET_EXPR_LOCATION (t, location);
   10289       append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
   10290     }
   10291 
   10292   /* } */
   10293   COND_EXPR_ELSE (first_if) = first_else;
   10294 
   10295   /* Do the whole thing.  */
   10296   add_stmt (bind);
   10297 
   10298 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
   10299   /* This will print to stderr the whole blurb generated by the
   10300      compiler while compiling (assuming the compiler doesn't crash
   10301      before getting here).
   10302    */
   10303   debug_generic_stmt (bind);
   10304 #endif
   10305 
   10306   /* } */
   10307   /* Done by c-parser.cc  */
   10308 }
   10309 
   10310 /* --- SUPPORT FOR FORMAT ARG CHECKING --- */
   10311 /* Return true if we have an NxString object pointer.  */
   10312 
   10313 bool
   10314 objc_string_ref_type_p (tree strp)
   10315 {
   10316   tree tmv;
   10317   if (!strp || TREE_CODE (strp) != POINTER_TYPE)
   10318     return false;
   10319 
   10320   tmv = TYPE_MAIN_VARIANT (TREE_TYPE (strp));
   10321   tmv = OBJC_TYPE_NAME (tmv);
   10322   return (tmv
   10323 	  && TREE_CODE (tmv) == IDENTIFIER_NODE
   10324 	  && IDENTIFIER_POINTER (tmv)
   10325 	  && startswith (IDENTIFIER_POINTER (tmv), "NSString"));
   10326 }
   10327 
   10328 /* At present the behavior of this is undefined and it does nothing.  */
   10329 void
   10330 objc_check_format_arg (tree ARG_UNUSED (format_arg),
   10331 		       tree ARG_UNUSED (args_list))
   10332 {
   10333 }
   10334 
   10335 void
   10336 objc_common_init_ts (void)
   10337 {
   10338   c_common_init_ts ();
   10339 
   10340   MARK_TS_DECL_NON_COMMON (CLASS_METHOD_DECL);
   10341   MARK_TS_DECL_NON_COMMON (INSTANCE_METHOD_DECL);
   10342   MARK_TS_DECL_NON_COMMON (KEYWORD_DECL);
   10343   MARK_TS_DECL_NON_COMMON (PROPERTY_DECL);
   10344 
   10345   MARK_TS_COMMON (CLASS_INTERFACE_TYPE);
   10346   MARK_TS_COMMON (PROTOCOL_INTERFACE_TYPE);
   10347   MARK_TS_COMMON (CLASS_IMPLEMENTATION_TYPE);
   10348 
   10349   MARK_TS_TYPED (MESSAGE_SEND_EXPR);
   10350   MARK_TS_TYPED (PROPERTY_REF);
   10351 }
   10352 
   10353 size_t
   10354 objc_common_tree_size (enum tree_code code)
   10355 {
   10356   switch (code)
   10357     {
   10358     case CLASS_METHOD_DECL:
   10359     case INSTANCE_METHOD_DECL:
   10360     case KEYWORD_DECL:
   10361     case PROPERTY_DECL:			return sizeof (tree_decl_non_common);
   10362     case CLASS_INTERFACE_TYPE:
   10363     case CLASS_IMPLEMENTATION_TYPE:
   10364     case CATEGORY_INTERFACE_TYPE:
   10365     case CATEGORY_IMPLEMENTATION_TYPE:
   10366     case PROTOCOL_INTERFACE_TYPE:	return sizeof (tree_type_non_common);
   10367     default:
   10368       gcc_unreachable ();
   10369     }
   10370 }
   10371 
   10372 
   10373 #include "gt-objc-objc-act.h"
   10374