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