OSDN Git Service

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