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