OSDN Git Service

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