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