OSDN Git Service

In gcc/:
[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 /* Called after parsing each instance variable declaration. Necessary to
5987    preserve typedefs and implement public/private...
5988
5989    VISIBILITY is 1 for public, 0 for protected, and 2 for private.  */
5990
5991 static tree
5992 add_instance_variable (tree klass, objc_ivar_visibility_kind visibility, 
5993                        tree field_decl)
5994 {
5995   tree field_type = TREE_TYPE (field_decl);
5996   const char *ivar_name = DECL_NAME (field_decl)
5997                           ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
5998                           : _("<unnamed>");
5999
6000 #ifdef OBJCPLUS
6001   if (TREE_CODE (field_type) == REFERENCE_TYPE)
6002     {
6003       error ("illegal reference type specified for instance variable %qs",
6004              ivar_name);
6005       /* Return class as is without adding this ivar.  */
6006       return klass;
6007     }
6008 #endif
6009
6010   if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6011       || TYPE_SIZE (field_type) == error_mark_node)
6012       /* 'type[0]' is allowed, but 'type[]' is not! */
6013     {
6014       error ("instance variable %qs has unknown size", ivar_name);
6015       /* Return class as is without adding this ivar.  */
6016       return klass;
6017     }
6018
6019 #ifndef OBJCPLUS
6020   /* Also, in C reject a struct with a flexible array member.  Ie,
6021
6022        struct A { int x; int[] y; };
6023
6024        @interface X
6025        {
6026          struct A instance_variable;
6027        }
6028        @end
6029
6030        is not valid because if the class is subclassed, we wouldn't be able
6031        to calculate the offset of the next instance variable.  */
6032   if (flexible_array_type_p (field_type))
6033     {
6034       error ("instance variable %qs uses flexible array member", ivar_name);
6035       /* Return class as is without adding this ivar.  */
6036       return klass;      
6037     }
6038 #endif
6039
6040 #ifdef OBJCPLUS
6041   /* Check if the ivar being added has a non-POD C++ type.   If so, we will
6042      need to either (1) warn the user about it or (2) generate suitable
6043      constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
6044      methods (if '-fobjc-call-cxx-cdtors' was specified).  */
6045   if (MAYBE_CLASS_TYPE_P (field_type)
6046       && (TYPE_NEEDS_CONSTRUCTING (field_type)
6047           || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
6048           || TYPE_POLYMORPHIC_P (field_type)))
6049     {
6050       tree type_name = OBJC_TYPE_NAME (field_type);
6051
6052       if (flag_objc_call_cxx_cdtors)
6053         {
6054           /* Since the ObjC runtime will be calling the constructors and
6055              destructors for us, the only thing we can't handle is the lack
6056              of a default constructor.  */
6057           if (TYPE_NEEDS_CONSTRUCTING (field_type)
6058               && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
6059             {
6060               warning (0, "type %qE has no default constructor to call",
6061                        type_name);
6062
6063               /* If we cannot call a constructor, we should also avoid
6064                  calling the destructor, for symmetry.  */
6065               if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6066                 warning (0, "destructor for %qE shall not be run either",
6067                          type_name);
6068             }
6069         }
6070       else
6071         {
6072           static bool warn_cxx_ivars = false;
6073
6074           if (TYPE_POLYMORPHIC_P (field_type))
6075             {
6076               /* Vtable pointers are Real Bad(tm), since Obj-C cannot
6077                  initialize them.  */
6078               error ("type %qE has virtual member functions", type_name);
6079               error ("illegal aggregate type %qE specified "
6080                      "for instance variable %qs",
6081                      type_name, ivar_name);
6082               /* Return class as is without adding this ivar.  */
6083               return klass;
6084             }
6085
6086           /* User-defined constructors and destructors are not known to Obj-C
6087              and hence will not be called.  This may or may not be a problem. */
6088           if (TYPE_NEEDS_CONSTRUCTING (field_type))
6089             warning (0, "type %qE has a user-defined constructor", type_name);
6090           if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6091             warning (0, "type %qE has a user-defined destructor", type_name);
6092
6093           if (!warn_cxx_ivars)
6094             {
6095               warning (0, "C++ constructors and destructors will not "
6096                        "be invoked for Objective-C fields");
6097               warn_cxx_ivars = true;
6098             }
6099         }
6100     }
6101 #endif
6102
6103   /* Overload the public attribute, it is not used for FIELD_DECLs.  */
6104   switch (visibility)
6105     {
6106     case OBJC_IVAR_VIS_PROTECTED:
6107       TREE_PUBLIC (field_decl) = 0;
6108       TREE_PRIVATE (field_decl) = 0;
6109       TREE_PROTECTED (field_decl) = 1;
6110       break;
6111
6112     case OBJC_IVAR_VIS_PACKAGE:
6113     /* TODO: Implement the package variant.  */
6114     case OBJC_IVAR_VIS_PUBLIC:
6115       TREE_PUBLIC (field_decl) = 1;
6116       TREE_PRIVATE (field_decl) = 0;
6117       TREE_PROTECTED (field_decl) = 0;
6118       break;
6119
6120     case OBJC_IVAR_VIS_PRIVATE:
6121       TREE_PUBLIC (field_decl) = 0;
6122       TREE_PRIVATE (field_decl) = 1;
6123       TREE_PROTECTED (field_decl) = 0;
6124       break;
6125
6126     }
6127
6128   CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
6129
6130   return klass;
6131 }
6132
6133 /* True if the ivar is private and we are not in its implementation.  */
6134
6135 static int
6136 is_private (tree decl)
6137 {
6138   return (TREE_PRIVATE (decl)
6139           && ! is_ivar (CLASS_IVARS (implementation_template),
6140                         DECL_NAME (decl)));
6141 }
6142
6143 /* We have an instance variable reference;, check to see if it is public.  */
6144
6145 int
6146 objc_is_public (tree expr, tree identifier)
6147 {
6148   tree basetype, decl;
6149
6150 #ifdef OBJCPLUS
6151   if (processing_template_decl)
6152     return 1;
6153 #endif
6154
6155   if (TREE_TYPE (expr) == error_mark_node)
6156     return 1;
6157
6158   basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
6159
6160   if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
6161     {
6162       if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
6163         {
6164           tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
6165
6166           if (!klass)
6167             {
6168               error ("cannot find interface declaration for %qE",
6169                      OBJC_TYPE_NAME (basetype));
6170               return 0;
6171             }
6172
6173           if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
6174             {
6175               if (TREE_PUBLIC (decl))
6176                 return 1;
6177
6178               /* Important difference between the Stepstone translator:
6179                  all instance variables should be public within the context
6180                  of the implementation.  */
6181               if (objc_implementation_context
6182                  && ((TREE_CODE (objc_implementation_context)
6183                       == CLASS_IMPLEMENTATION_TYPE)
6184                      || (TREE_CODE (objc_implementation_context)
6185                          == CATEGORY_IMPLEMENTATION_TYPE)))
6186                 {
6187                   tree curtype = TYPE_MAIN_VARIANT
6188                                  (CLASS_STATIC_TEMPLATE
6189                                   (implementation_template));
6190
6191                   if (basetype == curtype
6192                       || DERIVED_FROM_P (basetype, curtype))
6193                     {
6194                       int priv = is_private (decl);
6195
6196                       if (priv)
6197                         error ("instance variable %qE is declared private",
6198                                DECL_NAME (decl));
6199
6200                       return !priv;
6201                     }
6202                 }
6203
6204               /* The 2.95.2 compiler sometimes allowed C functions to access
6205                  non-@public ivars.  We will let this slide for now...  */
6206               if (!objc_method_context)
6207               {
6208                 warning (0, "instance variable %qE is %s; "
6209                          "this will be a hard error in the future",
6210                          identifier,
6211                          TREE_PRIVATE (decl) ? "@private" : "@protected");
6212                 return 1;
6213               }
6214
6215               error ("instance variable %qE is declared %s",
6216                      identifier,
6217                      TREE_PRIVATE (decl) ? "private" : "protected");
6218               return 0;
6219             }
6220         }
6221     }
6222
6223   return 1;
6224 }
6225 \f
6226 /* Make sure all methods in CHAIN (a list of method declarations from
6227    an @interface or a @protocol) are in IMPLEMENTATION (the
6228    implementation context).  This is used to check for example that
6229    all methods declared in an @interface were implemented in an
6230    @implementation.
6231
6232    Some special methods (property setters/getters) are special and if
6233    they are not found in IMPLEMENTATION, we look them up in its
6234    superclasses.  */
6235
6236 static int
6237 check_methods (tree chain, tree implementation, int mtype)
6238 {
6239   int first = 1;
6240   tree list;
6241
6242   if (mtype == (int)'+')
6243     list = CLASS_CLS_METHODS (implementation);
6244   else
6245     list = CLASS_NST_METHODS (implementation);
6246
6247   while (chain)
6248     {
6249       /* If the method is associated with a dynamic property, then it
6250          is Ok not to have the method implementation, as it will be
6251          generated dynamically at runtime.  To decide if the method is
6252          associated with a @dynamic property, we search the list of
6253          @synthesize and @dynamic for this implementation, and look
6254          for any @dynamic property with the same setter or getter name
6255          as this method.  */
6256       tree x;
6257       for (x = IMPL_PROPERTY_DECL (implementation); x; x = TREE_CHAIN (x))
6258         if (PROPERTY_DYNAMIC (x)
6259             && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
6260                 || PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
6261           break;
6262       
6263       if (x != NULL_TREE)
6264         {
6265           chain = TREE_CHAIN (chain); /* next method...  */
6266           continue;
6267         }
6268
6269       if (!lookup_method (list, chain))
6270         {
6271           /* If the method is a property setter/getter, we'll still
6272              allow it to be missing if it is implemented by
6273              'interface' or any of its superclasses.  */
6274           tree property = METHOD_PROPERTY_CONTEXT (chain);
6275           if (property)
6276             {
6277               /* Note that since this is a property getter/setter, it
6278                  is obviously an instance method.  */
6279               tree interface = NULL_TREE;
6280
6281               /* For a category, first check the main class
6282                  @interface.  */
6283               if (TREE_CODE (implementation) == CATEGORY_IMPLEMENTATION_TYPE)
6284                 {
6285                   interface = lookup_interface (CLASS_NAME (implementation));
6286
6287                   /* If the method is found in the main class, it's Ok.  */
6288                   if (lookup_method (CLASS_NST_METHODS (interface), chain))
6289                     {
6290                       chain = DECL_CHAIN (chain);
6291                       continue;               
6292                     }
6293
6294                   /* Else, get the superclass.  */
6295                   if (CLASS_SUPER_NAME (interface))
6296                     interface = lookup_interface (CLASS_SUPER_NAME (interface));
6297                   else
6298                     interface = NULL_TREE;
6299                 }
6300
6301               /* Get the superclass for classes.  */
6302               if (TREE_CODE (implementation) == CLASS_IMPLEMENTATION_TYPE)
6303                 {
6304                   if (CLASS_SUPER_NAME (implementation))
6305                     interface = lookup_interface (CLASS_SUPER_NAME (implementation));
6306                   else
6307                     interface = NULL_TREE;
6308                 }
6309
6310               /* Now, interface is the superclass, if any; go check it.  */
6311               if (interface)
6312                 {
6313                   if (lookup_method_static (interface, chain, 0))
6314                     {
6315                       chain = DECL_CHAIN (chain);
6316                       continue;
6317                     }
6318                 }
6319               /* Else, fall through - warn.  */
6320             }
6321           if (first)
6322             {
6323               switch (TREE_CODE (implementation))
6324                 {
6325                 case CLASS_IMPLEMENTATION_TYPE:
6326                   warning (0, "incomplete implementation of class %qE",
6327                            CLASS_NAME (implementation));
6328                   break;
6329                 case CATEGORY_IMPLEMENTATION_TYPE:
6330                   warning (0, "incomplete implementation of category %qE",
6331                            CLASS_SUPER_NAME (implementation));
6332                   break;
6333                 default:
6334                   gcc_unreachable ();
6335                 }
6336               first = 0;
6337             }
6338
6339           warning (0, "method definition for %<%c%E%> not found",
6340                    mtype, METHOD_SEL_NAME (chain));
6341         }
6342
6343       chain = DECL_CHAIN (chain);
6344     }
6345
6346     return first;
6347 }
6348
6349 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL.  */
6350
6351 static int
6352 conforms_to_protocol (tree klass, tree protocol)
6353 {
6354    if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6355      {
6356        tree p = CLASS_PROTOCOL_LIST (klass);
6357        while (p && TREE_VALUE (p) != protocol)
6358          p = TREE_CHAIN (p);
6359
6360        if (!p)
6361          {
6362            tree super = (CLASS_SUPER_NAME (klass)
6363                          ? lookup_interface (CLASS_SUPER_NAME (klass))
6364                          : NULL_TREE);
6365            int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6366            if (!tmp)
6367              return 0;
6368          }
6369      }
6370
6371    return 1;
6372 }
6373
6374 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6375    CONTEXT.  This is one of two mechanisms to check protocol integrity.  */
6376
6377 static int
6378 check_methods_accessible (tree chain, tree context, int mtype)
6379 {
6380   int first = 1;
6381   tree list;
6382   tree base_context = context;
6383
6384   while (chain)
6385     {
6386       /* If the method is associated with a dynamic property, then it
6387          is Ok not to have the method implementation, as it will be
6388          generated dynamically at runtime.  Search for any @dynamic
6389          property with the same setter or getter name as this
6390          method.  TODO: Use a hashtable lookup.  */
6391       tree x;
6392       for (x = IMPL_PROPERTY_DECL (base_context); x; x = TREE_CHAIN (x))
6393         if (PROPERTY_DYNAMIC (x)
6394             && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
6395                 || PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
6396           break;
6397       
6398       if (x != NULL_TREE)
6399         {
6400           chain = TREE_CHAIN (chain); /* next method...  */
6401           continue;
6402         }       
6403
6404       context = base_context;
6405       while (context)
6406         {
6407           if (mtype == '+')
6408             list = CLASS_CLS_METHODS (context);
6409           else
6410             list = CLASS_NST_METHODS (context);
6411
6412           if (lookup_method (list, chain))
6413               break;
6414
6415           switch (TREE_CODE (context))
6416             {
6417             case CLASS_IMPLEMENTATION_TYPE:
6418             case CLASS_INTERFACE_TYPE:
6419               context = (CLASS_SUPER_NAME (context)
6420                          ? lookup_interface (CLASS_SUPER_NAME (context))
6421                          : NULL_TREE);
6422               break;
6423             case CATEGORY_IMPLEMENTATION_TYPE:
6424             case CATEGORY_INTERFACE_TYPE:
6425               context = (CLASS_NAME (context)
6426                          ? lookup_interface (CLASS_NAME (context))
6427                          : NULL_TREE);
6428               break;
6429             default:
6430               gcc_unreachable ();
6431             }
6432         }
6433
6434       if (context == NULL_TREE)
6435         {
6436           if (first)
6437             {
6438               switch (TREE_CODE (objc_implementation_context))
6439                 {
6440                 case CLASS_IMPLEMENTATION_TYPE:
6441                   warning (0, "incomplete implementation of class %qE",
6442                            CLASS_NAME (objc_implementation_context));
6443                   break;
6444                 case CATEGORY_IMPLEMENTATION_TYPE:
6445                   warning (0, "incomplete implementation of category %qE",
6446                            CLASS_SUPER_NAME (objc_implementation_context));
6447                   break;
6448                 default:
6449                   gcc_unreachable ();
6450                 }
6451               first = 0;
6452             }
6453           warning (0, "method definition for %<%c%E%> not found",
6454                    mtype, METHOD_SEL_NAME (chain));
6455         }
6456
6457       chain = TREE_CHAIN (chain); /* next method...  */
6458     }
6459   return first;
6460 }
6461
6462 /* Check whether the current interface (accessible via
6463    'objc_implementation_context') actually implements protocol P, along
6464    with any protocols that P inherits.  */
6465
6466 static void
6467 check_protocol (tree p, const char *type, tree name)
6468 {
6469   if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6470     {
6471       int f1, f2;
6472
6473       /* Ensure that all protocols have bodies!  */
6474       if (warn_protocol)
6475         {
6476           f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6477                               objc_implementation_context,
6478                               '+');
6479           f2 = check_methods (PROTOCOL_NST_METHODS (p),
6480                               objc_implementation_context,
6481                               '-');
6482         }
6483       else
6484         {
6485           f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6486                                          objc_implementation_context,
6487                                          '+');
6488           f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6489                                          objc_implementation_context,
6490                                          '-');
6491         }
6492
6493       if (!f1 || !f2)
6494         warning (0, "%s %qE does not fully implement the %qE protocol",
6495                  type, name, PROTOCOL_NAME (p));
6496     }
6497
6498   /* Check protocols recursively.  */
6499   if (PROTOCOL_LIST (p))
6500     {
6501       tree subs = PROTOCOL_LIST (p);
6502       tree super_class =
6503         lookup_interface (CLASS_SUPER_NAME (implementation_template));
6504
6505       while (subs)
6506         {
6507           tree sub = TREE_VALUE (subs);
6508
6509           /* If the superclass does not conform to the protocols
6510              inherited by P, then we must!  */
6511           if (!super_class || !conforms_to_protocol (super_class, sub))
6512             check_protocol (sub, type, name);
6513           subs = TREE_CHAIN (subs);
6514         }
6515     }
6516 }
6517
6518 /* Check whether the current interface (accessible via
6519    'objc_implementation_context') actually implements the protocols listed
6520    in PROTO_LIST.  */
6521
6522 static void
6523 check_protocols (tree proto_list, const char *type, tree name)
6524 {
6525   for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6526     {
6527       tree p = TREE_VALUE (proto_list);
6528
6529       check_protocol (p, type, name);
6530     }
6531 }
6532 \f
6533 /* Make sure that the class CLASS_NAME is defined CODE says which kind
6534    of thing CLASS_NAME ought to be.  It can be CLASS_INTERFACE_TYPE,
6535    CLASS_IMPLEMENTATION_TYPE, CATEGORY_INTERFACE_TYPE, or
6536    CATEGORY_IMPLEMENTATION_TYPE.  For a CATEGORY_INTERFACE_TYPE,
6537    SUPER_NAME is the name of the category.  For a class extension,
6538    CODE is CATEGORY_INTERFACE_TYPE and SUPER_NAME is NULL_TREE.  */
6539 static tree
6540 start_class (enum tree_code code, tree class_name, tree super_name,
6541              tree protocol_list, tree attributes)
6542 {
6543   tree klass = NULL_TREE;
6544   tree decl;
6545
6546 #ifdef OBJCPLUS
6547   if (current_namespace != global_namespace)
6548     {
6549       error ("Objective-C declarations may only appear in global scope");
6550     }
6551 #endif /* OBJCPLUS */
6552
6553   if (objc_implementation_context)
6554     {
6555       warning (0, "%<@end%> missing in implementation context");
6556       finish_class (objc_implementation_context);
6557       objc_ivar_chain = NULL_TREE;
6558       objc_implementation_context = NULL_TREE;
6559     }
6560
6561   /* If this is a class extension, we'll be "reopening" the existing
6562      CLASS_INTERFACE_TYPE, so in that case there is no need to create
6563      a new node.  */
6564   if (code != CATEGORY_INTERFACE_TYPE || super_name != NULL_TREE)
6565     {
6566       klass = make_node (code);
6567       TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
6568     }
6569
6570   /* Check for existence of the super class, if one was specified.  Note
6571      that we must have seen an @interface, not just a @class.  If we
6572      are looking at a @compatibility_alias, traverse it first.  */
6573   if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
6574       && super_name)
6575     {
6576       tree super = objc_is_class_name (super_name);
6577       tree super_interface = NULL_TREE;
6578
6579       if (super)
6580         super_interface = lookup_interface (super);
6581       
6582       if (!super_interface)
6583         {
6584           error ("cannot find interface declaration for %qE, superclass of %qE",
6585                  super ? super : super_name,
6586                  class_name);
6587           super_name = NULL_TREE;
6588         }
6589       else
6590         {
6591           if (TREE_DEPRECATED (super_interface))
6592             warning (OPT_Wdeprecated_declarations, "class %qE is deprecated", 
6593                      super);
6594           super_name = super;
6595         }
6596     }
6597
6598   if (code != CATEGORY_INTERFACE_TYPE || super_name != NULL_TREE)
6599     {
6600       CLASS_NAME (klass) = class_name;
6601       CLASS_SUPER_NAME (klass) = super_name;
6602       CLASS_CLS_METHODS (klass) = NULL_TREE;
6603     }
6604
6605   if (! objc_is_class_name (class_name)
6606       && (decl = lookup_name (class_name)))
6607     {
6608       error ("%qE redeclared as different kind of symbol",
6609              class_name);
6610       error ("previous declaration of %q+D",
6611              decl);
6612     }
6613
6614   switch (code)
6615     {
6616     case CLASS_IMPLEMENTATION_TYPE:
6617       {
6618         tree chain;
6619         
6620         for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6621           if (TREE_VALUE (chain) == class_name)
6622             {
6623               error ("reimplementation of class %qE",
6624                      class_name);
6625               /* TODO: error message saying where it was previously
6626                  implemented.  */
6627               break;
6628             }
6629         if (chain == NULL_TREE)
6630           implemented_classes = tree_cons (NULL_TREE, class_name,
6631                                            implemented_classes);
6632       }
6633
6634       /* Reset for multiple classes per file.  */
6635       method_slot = 0;
6636
6637       objc_implementation_context = klass;
6638
6639       /* Lookup the interface for this implementation.  */
6640
6641       if (!(implementation_template = lookup_interface (class_name)))
6642         {
6643           warning (0, "cannot find interface declaration for %qE",
6644                    class_name);
6645           add_class (implementation_template = objc_implementation_context,
6646                      class_name);
6647         }
6648
6649       /* If a super class has been specified in the implementation,
6650          insure it conforms to the one specified in the interface.  */
6651
6652       if (super_name
6653           && (super_name != CLASS_SUPER_NAME (implementation_template)))
6654         {
6655           tree previous_name = CLASS_SUPER_NAME (implementation_template);
6656           error ("conflicting super class name %qE",
6657                  super_name);
6658           if (previous_name)
6659             error ("previous declaration of %qE", previous_name);
6660           else
6661             error ("previous declaration");
6662         }
6663
6664       else if (! super_name)
6665         {
6666           CLASS_SUPER_NAME (objc_implementation_context)
6667             = CLASS_SUPER_NAME (implementation_template);
6668         }
6669       break;
6670
6671     case CLASS_INTERFACE_TYPE:
6672       if (lookup_interface (class_name))
6673 #ifdef OBJCPLUS
6674         error ("duplicate interface declaration for class %qE", class_name);
6675 #else
6676         warning (0, "duplicate interface declaration for class %qE", class_name);
6677 #endif
6678       else
6679         add_class (klass, class_name);
6680        
6681       if (protocol_list)
6682         CLASS_PROTOCOL_LIST (klass)
6683           = lookup_and_install_protocols (protocol_list, /* definition_required */ true);
6684
6685       if (attributes)
6686         {
6687           tree attribute;
6688           for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
6689             {
6690               tree name = TREE_PURPOSE (attribute);
6691               
6692               /* TODO: Document what the objc_exception attribute is/does.  */
6693               /* We handle the 'deprecated' and (undocumented) 'objc_exception'
6694                  attributes.  */
6695               if (is_attribute_p  ("deprecated", name))
6696                 TREE_DEPRECATED (klass) = 1;
6697               else if (is_attribute_p  ("objc_exception", name))
6698                 CLASS_HAS_EXCEPTION_ATTR (klass) = 1;
6699               else
6700                 /* Warn about and ignore all others for now, but store them.  */
6701                 warning (OPT_Wattributes, "%qE attribute directive ignored", name);
6702             }
6703           TYPE_ATTRIBUTES (klass) = attributes;
6704         }
6705       break;     
6706
6707     case CATEGORY_INTERFACE_TYPE:
6708       {
6709         tree class_category_is_assoc_with;
6710         
6711         /* For a category, class_name is really the name of the class that
6712            the following set of methods will be associated with. We must
6713            find the interface so that can derive the objects template.  */
6714         if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6715           {
6716             error ("cannot find interface declaration for %qE",
6717                    class_name);
6718             exit (FATAL_EXIT_CODE);
6719           }
6720         else
6721           {
6722             if (TREE_DEPRECATED (class_category_is_assoc_with))
6723               warning (OPT_Wdeprecated_declarations, "class %qE is deprecated", 
6724                        class_name);
6725
6726             if (super_name == NULL_TREE)
6727               {
6728                 /* This is a class extension.  Get the original
6729                    interface, and continue working on it.  */
6730                 objc_in_class_extension = true;
6731                 klass = class_category_is_assoc_with;
6732
6733                 if (protocol_list)
6734                   {
6735                     /* Append protocols to the original protocol
6736                        list.  */
6737                     CLASS_PROTOCOL_LIST (klass)
6738                       = chainon (CLASS_PROTOCOL_LIST (klass),
6739                                  lookup_and_install_protocols
6740                                  (protocol_list,
6741                                   /* definition_required */ true));
6742                   }
6743               }
6744             else
6745               {
6746                 add_category (class_category_is_assoc_with, klass);
6747                 
6748                 if (protocol_list)
6749                   CLASS_PROTOCOL_LIST (klass)
6750                     = lookup_and_install_protocols
6751                     (protocol_list, /* definition_required */ true);
6752               }
6753           }
6754       }
6755       break;
6756         
6757     case CATEGORY_IMPLEMENTATION_TYPE:
6758       /* Reset for multiple classes per file.  */
6759       method_slot = 0;
6760
6761       objc_implementation_context = klass;
6762
6763       /* For a category, class_name is really the name of the class that
6764          the following set of methods will be associated with.  We must
6765          find the interface so that can derive the objects template.  */
6766
6767       if (!(implementation_template = lookup_interface (class_name)))
6768         {
6769           error ("cannot find interface declaration for %qE",
6770                  class_name);
6771           exit (FATAL_EXIT_CODE);
6772         }
6773       break;
6774     default:
6775       gcc_unreachable ();
6776     }
6777   return klass;
6778 }
6779
6780 static tree
6781 continue_class (tree klass)
6782 {
6783   switch (TREE_CODE (klass))
6784     {
6785     case CLASS_IMPLEMENTATION_TYPE:
6786     case CATEGORY_IMPLEMENTATION_TYPE:
6787       {
6788         struct imp_entry *imp_entry;
6789
6790         /* Check consistency of the instance variables.  */
6791
6792         if (CLASS_RAW_IVARS (klass))
6793           check_ivars (implementation_template, klass);
6794         
6795         /* code generation */
6796 #ifdef OBJCPLUS
6797         push_lang_context (lang_name_c);
6798 #endif
6799         build_private_template (implementation_template);
6800         uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
6801         objc_instance_type = build_pointer_type (uprivate_record);
6802
6803         imp_entry = ggc_alloc_imp_entry ();
6804
6805         imp_entry->next = imp_list;
6806         imp_entry->imp_context = klass;
6807         imp_entry->imp_template = implementation_template;
6808         ucls_super_ref = uucls_super_ref = NULL;
6809         if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
6810           {
6811             imp_entry->class_decl = (*runtime.class_decl) (klass);
6812             imp_entry->meta_decl = (*runtime.metaclass_decl) (klass);
6813           }
6814         else
6815           {
6816             imp_entry->class_decl = (*runtime.category_decl) (klass);
6817             imp_entry->meta_decl = NULL;
6818           }
6819         imp_entry->has_cxx_cdtors = 0;
6820
6821         /* Append to front and increment count.  */
6822         imp_list = imp_entry;
6823         if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
6824           imp_count++;
6825         else
6826           cat_count++;
6827 #ifdef OBJCPLUS
6828         pop_lang_context ();
6829 #endif /* OBJCPLUS */
6830         
6831         return get_class_ivars (implementation_template, true);
6832         break;
6833       }
6834     case CLASS_INTERFACE_TYPE:
6835       {
6836         if (objc_in_class_extension)
6837           return NULL_TREE;
6838 #ifdef OBJCPLUS
6839         push_lang_context (lang_name_c);
6840 #endif /* OBJCPLUS */
6841         objc_collecting_ivars = 1;
6842         build_private_template (klass);
6843         objc_collecting_ivars = 0;
6844 #ifdef OBJCPLUS
6845         pop_lang_context ();
6846 #endif /* OBJCPLUS */
6847         return NULL_TREE;
6848         break;
6849       }
6850     default:
6851       return error_mark_node;
6852     }
6853 }
6854
6855 /* This routine builds name of the setter synthesized function. */
6856 static char *
6857 objc_build_property_setter_name (tree ident)
6858 {
6859   /* TODO: Use alloca to allocate buffer of appropriate size.  */
6860   static char string[BUFSIZE];
6861   sprintf (string, "set%s:", IDENTIFIER_POINTER (ident));
6862   string[3] = TOUPPER (string[3]);
6863   return string;
6864 }
6865
6866 /* This routine prepares the declarations of the property accessor
6867    helper functions (objc_getProperty(), etc) that are used when
6868    @synthesize is used.  
6869    
6870    runtime-specific routines are built in the respective runtime 
6871    initialize functions.  */
6872 static void 
6873 build_common_objc_property_accessor_helpers (void)
6874 {
6875   tree type;
6876
6877   /* Declare the following function:
6878      id
6879      objc_getProperty (id self, SEL _cmd, 
6880                        ptrdiff_t offset, BOOL is_atomic);  */
6881   type = build_function_type_list (objc_object_type,
6882                                    objc_object_type,
6883                                    objc_selector_type,
6884                                    ptrdiff_type_node,
6885                                    boolean_type_node,
6886                                    NULL_TREE);
6887   objc_getProperty_decl = add_builtin_function ("objc_getProperty",
6888                                                 type, 0, NOT_BUILT_IN,
6889                                                 NULL, NULL_TREE);
6890   TREE_NOTHROW (objc_getProperty_decl) = 0;
6891   
6892   /* Declare the following function:
6893      void
6894      objc_setProperty (id self, SEL _cmd, 
6895                        ptrdiff_t offset, id new_value, 
6896                        BOOL is_atomic, BOOL should_copy);  */
6897   type = build_function_type_list (void_type_node,
6898                                    objc_object_type,
6899                                    objc_selector_type,
6900                                    ptrdiff_type_node,
6901                                    objc_object_type,
6902                                    boolean_type_node,
6903                                    boolean_type_node,
6904                                    NULL_TREE);
6905   objc_setProperty_decl = add_builtin_function ("objc_setProperty",
6906                                                 type, 0, NOT_BUILT_IN,
6907                                                 NULL, NULL_TREE);
6908   TREE_NOTHROW (objc_setProperty_decl) = 0;
6909 }
6910
6911 /* This looks up an ivar in a class (including superclasses).  */
6912 static tree
6913 lookup_ivar (tree interface, tree instance_variable_name)
6914 {
6915   while (interface)
6916     {
6917       tree decl_chain;
6918       
6919       for (decl_chain = CLASS_IVARS (interface); decl_chain; decl_chain = DECL_CHAIN (decl_chain))
6920         if (DECL_NAME (decl_chain) == instance_variable_name)
6921           return decl_chain;
6922       
6923       /* Not found.  Search superclass if any.  */
6924       if (CLASS_SUPER_NAME (interface))
6925         interface = lookup_interface (CLASS_SUPER_NAME (interface));
6926     }
6927   
6928   return NULL_TREE;
6929 }
6930
6931 /* This routine synthesizes a 'getter' method.  This is only called
6932    for @synthesize properties.  */
6933 static void
6934 objc_synthesize_getter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
6935 {
6936   location_t location = DECL_SOURCE_LOCATION (property);
6937   tree fn, decl;
6938   tree body;
6939   tree ret_val;
6940
6941   /* If user has implemented a getter with same name then do nothing.  */
6942   if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
6943                      PROPERTY_GETTER_NAME (property)))
6944     return;
6945
6946   /* Find declaration of the property getter in the interface (or
6947      superclass, or protocol). There must be one.  */
6948   decl = lookup_method_static (klass, PROPERTY_GETTER_NAME (property), 0);
6949
6950   /* If one not declared in the interface, this condition has already
6951      been reported as user error (because property was not declared in
6952      the interface).  */
6953   if (!decl)
6954     return;
6955
6956   /* Adapt the 'decl'.  Use the source location of the @synthesize
6957      statement for error messages.  */
6958   decl = copy_node (decl);
6959   DECL_SOURCE_LOCATION (decl) = location;
6960
6961   objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE);
6962   body = c_begin_compound_stmt (true);
6963
6964   /* Now we need to decide how we build the getter.  There are three
6965      cases:
6966
6967      for 'copy' or 'retain' properties we need to use the
6968      objc_getProperty() accessor helper which knows about retain and
6969      copy.  It supports both 'nonatomic' and 'atomic' access.
6970
6971      for 'nonatomic, assign' properties we can access the instance
6972      variable directly.  'nonatomic' means we don't have to use locks,
6973      and 'assign' means we don't have to worry about retain or copy.
6974      If you combine the two, it means we can just access the instance
6975      variable directly.
6976
6977      for 'atomic, assign' properties we use objc_copyStruct() (for the
6978      next runtime) or objc_getPropertyStruct() (for the GNU runtime).  */
6979   switch (PROPERTY_ASSIGN_SEMANTICS (property))
6980     {
6981     case OBJC_PROPERTY_RETAIN:
6982     case OBJC_PROPERTY_COPY:
6983       {
6984         /* We build "return objc_getProperty (self, _cmd, offset, is_atomic);"  */
6985         tree cmd, ivar, offset, is_atomic;
6986         cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
6987
6988         /* Find the ivar to compute the offset.  */
6989         ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
6990         if (!ivar || is_private (ivar))
6991           {
6992             /* This should never happen.  */
6993             error_at (location,
6994                       "can not find instance variable associated with property");
6995             ret_val = error_mark_node;
6996             break;
6997           }
6998         offset = byte_position (ivar);
6999
7000         if (PROPERTY_NONATOMIC (property))
7001           is_atomic = boolean_false_node;
7002         else
7003           is_atomic = boolean_true_node;
7004
7005         ret_val = build_function_call
7006           (location,
7007            /* Function prototype.  */
7008            objc_getProperty_decl,
7009            /* Parameters.  */
7010            tree_cons    /* self */
7011            (NULL_TREE, self_decl,
7012             tree_cons   /* _cmd */
7013             (NULL_TREE, cmd,
7014              tree_cons  /* offset */
7015              (NULL_TREE, offset,
7016               tree_cons /* is_atomic */
7017               (NULL_TREE, is_atomic, NULL_TREE)))));
7018       }
7019       break;
7020     case OBJC_PROPERTY_ASSIGN:    
7021       if (PROPERTY_NONATOMIC (property))
7022         {
7023           /* We build "return self->PROPERTY_IVAR_NAME;"  */
7024           ret_val = objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property));
7025           break;
7026         }
7027       else
7028         {
7029           /* We build
7030                <property type> __objc_property_temp;
7031                objc_getPropertyStruct (&__objc_property_temp,
7032                                        &(self->PROPERTY_IVAR_NAME),
7033                                        sizeof (type of self->PROPERTY_IVAR_NAME),
7034                                        is_atomic,
7035                                        false)
7036                return __objc_property_temp;
7037
7038              For the NeXT runtime, we need to use objc_copyStruct
7039              instead of objc_getPropertyStruct.  */
7040           tree objc_property_temp_decl, function_decl, function_call;
7041           tree size_of, is_atomic;
7042
7043           objc_property_temp_decl = objc_create_temporary_var (TREE_TYPE (property), "__objc_property_temp");
7044           DECL_SOURCE_LOCATION (objc_property_temp_decl) = location;
7045           objc_property_temp_decl = lang_hooks.decls.pushdecl (objc_property_temp_decl);
7046
7047           /* sizeof (ivar type).  Since the ivar and the property have
7048              the same type, there is no need to lookup the ivar.  */
7049           size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
7050                                               true /* is_sizeof */,
7051                                               false /* complain */);
7052           
7053           if (PROPERTY_NONATOMIC (property))
7054             is_atomic = boolean_false_node;
7055           else
7056             is_atomic = boolean_true_node;
7057           
7058           if (objc_copyStruct_decl)
7059             function_decl = objc_copyStruct_decl;
7060           else
7061             function_decl = objc_getPropertyStruct_decl;
7062
7063           function_call = build_function_call
7064             (location,
7065              /* Function prototype.  */
7066              function_decl,
7067              /* Parameters.  */
7068              tree_cons /* &__objc_property_temp_decl */
7069              /* Warning: note that using build_fold_addr_expr_loc()
7070                 here causes invalid code to be generated.  */
7071              (NULL_TREE, build_unary_op (location, ADDR_EXPR, objc_property_temp_decl, 0),
7072               tree_cons /* &(self->PROPERTY_IVAR_NAME); */
7073               (NULL_TREE, build_fold_addr_expr_loc (location, 
7074                                                     objc_lookup_ivar 
7075                                                     (NULL_TREE, PROPERTY_IVAR_NAME (property))),
7076                tree_cons /* sizeof (PROPERTY_IVAR) */
7077                (NULL_TREE, size_of,
7078                 tree_cons /* is_atomic */
7079                 (NULL_TREE, is_atomic,
7080                  /* TODO: This is currently ignored by the GNU
7081                     runtime, but what about the next one ? */
7082                  tree_cons /* has_strong */
7083                  (NULL_TREE, boolean_true_node, NULL_TREE))))));
7084
7085           add_stmt (function_call);
7086
7087           ret_val = objc_property_temp_decl;
7088         }
7089       break;
7090     default:
7091       gcc_unreachable ();
7092     }
7093
7094   gcc_assert (ret_val);
7095
7096 #ifdef OBJCPLUS
7097   finish_return_stmt (ret_val);
7098 #else
7099   c_finish_return (location, ret_val, NULL_TREE);
7100 #endif
7101
7102   add_stmt (c_end_compound_stmt (location, body, true));
7103   fn = current_function_decl;
7104 #ifdef OBJCPLUS
7105   finish_function ();
7106 #endif
7107   objc_finish_method_definition (fn);
7108 }
7109
7110 /* This routine synthesizes a 'setter' method.  */
7111
7112 static void
7113 objc_synthesize_setter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
7114 {
7115   location_t location = DECL_SOURCE_LOCATION (property);
7116   tree fn, decl;
7117   tree body;
7118   tree new_value, statement;
7119
7120   /* If user has implemented a setter with same name then do nothing.  */
7121   if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
7122                      PROPERTY_SETTER_NAME (property)))
7123     return;
7124
7125   /* Find declaration of the property setter in the interface (or
7126      superclass, or protocol). There must be one.  */
7127   decl = lookup_method_static (klass, PROPERTY_SETTER_NAME (property), 0);
7128
7129   /* If one not declared in the interface, this condition has already
7130      been reported as user error (because property was not declared in
7131      the interface).  */
7132   if (!decl)
7133     return;
7134
7135   /* Adapt the 'decl'.  Use the source location of the @synthesize
7136      statement for error messages.  */
7137   decl = copy_node (decl);
7138   DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (property);
7139
7140   objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE);
7141
7142   body = c_begin_compound_stmt (true);
7143
7144   /* The 'new_value' is the only argument to the method, which is the
7145      3rd argument of the function, after self and _cmd.  We use twice
7146      TREE_CHAIN to move forward two arguments.  */
7147   new_value = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)));
7148
7149   /* This would presumably happen if the user has specified a
7150      prototype for the setter that does not have an argument!  */
7151   if (new_value == NULL_TREE)
7152     {
7153       /* TODO: This should be caught much earlier than this.  */
7154       error_at (DECL_SOURCE_LOCATION (decl), "invalid setter, it must have one argument");
7155       /* Try to recover somehow.  */
7156       new_value = error_mark_node;
7157     }
7158
7159   /* Now we need to decide how we build the setter.  There are three
7160      cases:
7161
7162      for 'copy' or 'retain' properties we need to use the
7163      objc_setProperty() accessor helper which knows about retain and
7164      copy.  It supports both 'nonatomic' and 'atomic' access.
7165
7166      for 'nonatomic, assign' properties we can access the instance
7167      variable directly.  'nonatomic' means we don't have to use locks,
7168      and 'assign' means we don't have to worry about retain or copy.
7169      If you combine the two, it means we can just access the instance
7170      variable directly.
7171
7172      for 'atomic, assign' properties we use objc_copyStruct() (for the
7173      next runtime) or objc_setPropertyStruct() (for the GNU runtime).  */
7174   switch (PROPERTY_ASSIGN_SEMANTICS (property))
7175     {
7176     case OBJC_PROPERTY_RETAIN:
7177     case OBJC_PROPERTY_COPY:
7178       {
7179         /* We build "objc_setProperty (self, _cmd, new_value, offset, is_atomic, should_copy);"  */
7180         tree cmd, ivar, offset, is_atomic, should_copy;
7181         cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
7182
7183         /* Find the ivar to compute the offset.  */
7184         ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
7185         if (!ivar || is_private (ivar))
7186           {
7187             error_at (location,
7188                       "can not find instance variable associated with property");
7189             statement = error_mark_node;
7190             break;
7191           }
7192         offset = byte_position (ivar);
7193
7194         if (PROPERTY_NONATOMIC (property))
7195           is_atomic = boolean_false_node;
7196         else
7197           is_atomic = boolean_true_node;
7198         
7199         if (PROPERTY_ASSIGN_SEMANTICS (property) == OBJC_PROPERTY_COPY)
7200           should_copy = boolean_true_node;
7201         else
7202           should_copy = boolean_false_node;
7203
7204         statement = build_function_call
7205           (location,
7206            /* Function prototype.  */
7207            objc_setProperty_decl,
7208            /* Parameters.  */
7209            tree_cons    /* self */
7210            (NULL_TREE, self_decl,
7211             tree_cons   /* _cmd */
7212             (NULL_TREE, cmd,
7213              tree_cons  /* offset */
7214              (NULL_TREE, offset,
7215               tree_cons /* new_value */
7216               (NULL_TREE, new_value,
7217                tree_cons /* is_atomic */
7218                (NULL_TREE, is_atomic, 
7219                 tree_cons /* should_copy */
7220                 (NULL_TREE, should_copy, NULL_TREE)))))));
7221       }
7222       break;
7223     case OBJC_PROPERTY_ASSIGN:    
7224       if (PROPERTY_NONATOMIC (property))
7225         {
7226           /* We build "self->PROPERTY_IVAR_NAME = new_value;"  */
7227           statement = build_modify_expr
7228             (location,
7229              objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property)),
7230              NULL_TREE, NOP_EXPR, 
7231              location, new_value, NULL_TREE);
7232           break;
7233         }
7234       else
7235         {
7236           /* We build
7237                objc_setPropertyStruct (&(self->PROPERTY_IVAR_NAME),
7238                                        &new_value,
7239                                        sizeof (type of self->PROPERTY_IVAR_NAME),
7240                                        is_atomic,
7241                                        false)
7242
7243              For the NeXT runtime, we need to use objc_copyStruct
7244              instead of objc_getPropertyStruct.  */
7245           tree function_decl, size_of, is_atomic;
7246
7247           /* sizeof (ivar type).  Since the ivar and the property have
7248              the same type, there is no need to lookup the ivar.  */
7249           size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
7250                                               true /* is_sizeof */,
7251                                               false /* complain */);
7252           
7253           if (PROPERTY_NONATOMIC (property))
7254             is_atomic = boolean_false_node;
7255           else
7256             is_atomic = boolean_true_node;
7257           
7258           if (objc_copyStruct_decl)
7259             function_decl = objc_copyStruct_decl;
7260           else
7261             function_decl = objc_setPropertyStruct_decl;
7262
7263           statement = build_function_call 
7264             (location,
7265              /* Function prototype.  */
7266              function_decl,
7267              /* Parameters.  */
7268              tree_cons /* &(self->PROPERTY_IVAR_NAME); */
7269              (NULL_TREE, build_fold_addr_expr_loc (location, 
7270                                                    objc_lookup_ivar 
7271                                                    (NULL_TREE, PROPERTY_IVAR_NAME (property))),
7272               tree_cons /* &new_value */
7273               (NULL_TREE, build_fold_addr_expr_loc (location, new_value),
7274                tree_cons /* sizeof (PROPERTY_IVAR) */
7275                (NULL_TREE, size_of,
7276                 tree_cons /* is_atomic */
7277                 (NULL_TREE, is_atomic,
7278                  /* TODO: This is currently ignored by the GNU
7279                     runtime, but what about the next one ? */
7280                  tree_cons /* has_strong */
7281                  (NULL_TREE, boolean_true_node, NULL_TREE))))));
7282         }
7283       break;
7284     default:
7285       gcc_unreachable ();
7286     }
7287   gcc_assert (statement);
7288
7289   add_stmt (statement);  
7290   add_stmt (c_end_compound_stmt (location, body, true));
7291   fn = current_function_decl;
7292 #ifdef OBJCPLUS
7293   finish_function ();
7294 #endif
7295   objc_finish_method_definition (fn);
7296 }
7297
7298 /* This function is a sub-routine of objc_add_synthesize_declaration.
7299    It is called for each property to synthesize once we have
7300    determined that the context is Ok.  */
7301 static void
7302 objc_add_synthesize_declaration_for_property (location_t location, tree interface,
7303                                               tree property_name, tree ivar_name)
7304 {
7305   /* Find the @property declaration.  */
7306   tree property;
7307   tree x;
7308
7309   /* Check that synthesize or dynamic has not already been used for
7310      the same property.  */
7311   for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
7312     if (PROPERTY_NAME (property) == property_name)
7313       {
7314         location_t original_location = DECL_SOURCE_LOCATION (property);
7315         
7316         if (PROPERTY_DYNAMIC (property))
7317           error_at (location, "property %qs already specified in %<@dynamic%>", 
7318                     IDENTIFIER_POINTER (property_name));
7319         else
7320           error_at (location, "property %qs already specified in %<@synthesize%>", 
7321                     IDENTIFIER_POINTER (property_name));
7322         
7323         if (original_location != UNKNOWN_LOCATION)
7324           inform (original_location, "originally specified here");
7325         return;
7326       }
7327
7328   /* Check that the property is declared in the interface.  It could
7329      also be declared in a superclass or protocol.  */
7330   property = lookup_property (interface, property_name);
7331
7332   if (!property)
7333     {
7334       error_at (location, "no declaration of property %qs found in the interface", 
7335                 IDENTIFIER_POINTER (property_name));
7336       return;
7337     }
7338   else
7339     {
7340       /* We have to copy the property, because we want to chain it to
7341          the implementation context, and we want to store the source
7342          location of the @synthesize, not of the original
7343          @property.  */
7344       property = copy_node (property);
7345       DECL_SOURCE_LOCATION (property) = location;
7346     }
7347
7348   /* Determine PROPERTY_IVAR_NAME.  */
7349   if (ivar_name == NULL_TREE)
7350     ivar_name = property_name;
7351
7352   /* Check that the instance variable exists.  You can only use an
7353      instance variable from the same class, not one from the
7354      superclass (this makes sense as it allows us to check that an
7355      instance variable is only used in one synthesized property).  */
7356   {
7357     tree ivar = is_ivar (CLASS_IVARS (interface), ivar_name);
7358     tree type_of_ivar;
7359     if (!ivar)
7360       {
7361         error_at (location, "ivar %qs used by %<@synthesize%> declaration must be an existing ivar", 
7362                   IDENTIFIER_POINTER (property_name));
7363         return;
7364       }
7365
7366     if (DECL_BIT_FIELD_TYPE (ivar))
7367       type_of_ivar = DECL_BIT_FIELD_TYPE (ivar);
7368     else
7369       type_of_ivar = TREE_TYPE (ivar);
7370     
7371     /* If the instance variable has a different C type, we throw an error ...  */
7372     if (!comptypes (TREE_TYPE (property), type_of_ivar)
7373         /* ... unless the property is readonly, in which case we allow
7374            the instance variable to be more specialized (this means we
7375            can generate the getter all right and it works).  */
7376         && (!PROPERTY_READONLY (property)
7377             || !objc_compare_types (TREE_TYPE (property),
7378                                     type_of_ivar, -5, NULL_TREE)))
7379       {
7380         location_t original_location = DECL_SOURCE_LOCATION (ivar);
7381         
7382         error_at (location, "property %qs is using instance variable %qs of incompatible type",
7383                   IDENTIFIER_POINTER (property_name),
7384                   IDENTIFIER_POINTER (ivar_name));
7385         
7386         if (original_location != UNKNOWN_LOCATION)
7387           inform (original_location, "originally specified here");
7388       }
7389
7390     /* If the instance variable is a bitfield, the property must be
7391        'assign', 'nonatomic' because the runtime getter/setter helper
7392        do not work with bitfield instance variables.  */
7393     if (DECL_BIT_FIELD_TYPE (ivar))
7394       {
7395         /* If there is an error, we return and not generate any
7396            getter/setter because trying to set up the runtime
7397            getter/setter helper calls with bitfields is at high risk
7398            of ICE.  */
7399
7400         if (PROPERTY_ASSIGN_SEMANTICS (property) != OBJC_PROPERTY_ASSIGN)
7401           {
7402             location_t original_location = DECL_SOURCE_LOCATION (ivar);
7403             
7404             error_at (location, "'assign' property %qs is using bit-field instance variable %qs",
7405                       IDENTIFIER_POINTER (property_name),
7406                       IDENTIFIER_POINTER (ivar_name));
7407         
7408             if (original_location != UNKNOWN_LOCATION)
7409               inform (original_location, "originally specified here");
7410             return;
7411           }
7412
7413         if (!PROPERTY_NONATOMIC (property))
7414           {
7415             location_t original_location = DECL_SOURCE_LOCATION (ivar);
7416             
7417             error_at (location, "'atomic' property %qs is using bit-field instance variable %qs",
7418                       IDENTIFIER_POINTER (property_name),
7419                       IDENTIFIER_POINTER (ivar_name));
7420             
7421             if (original_location != UNKNOWN_LOCATION)
7422               inform (original_location, "originally specified here");
7423             return;
7424           }
7425       }
7426   }
7427
7428   /* Check that no other property is using the same instance
7429      variable.  */
7430   for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
7431     if (PROPERTY_IVAR_NAME (x) == ivar_name)
7432       {
7433         location_t original_location = DECL_SOURCE_LOCATION (x);
7434         
7435         error_at (location, "property %qs is using the same instance variable as property %qs",
7436                   IDENTIFIER_POINTER (property_name),
7437                   IDENTIFIER_POINTER (PROPERTY_NAME (x)));
7438         
7439         if (original_location != UNKNOWN_LOCATION)
7440           inform (original_location, "originally specified here");
7441         
7442         /* We keep going on.  This won't cause the compiler to fail;
7443            the failure would most likely be at runtime.  */
7444       }
7445
7446   /* Note that a @synthesize (and only a @synthesize) always sets
7447      PROPERTY_IVAR_NAME to a non-NULL_TREE.  You can recognize a
7448      @synthesize by that.  */
7449   PROPERTY_IVAR_NAME (property) = ivar_name;
7450   
7451   /* PROPERTY_SETTER_NAME and PROPERTY_GETTER_NAME are copied from the
7452      original declaration; they are always set (with the exception of
7453      PROPERTY_SETTER_NAME not being set if PROPERTY_READONLY == 1).  */
7454
7455   /* Add the property to the list of properties for current implementation. */
7456   TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
7457   IMPL_PROPERTY_DECL (objc_implementation_context) = property;
7458
7459   /* Note how we don't actually synthesize the getter/setter here; it
7460      would be very natural, but we may miss the fact that the user has
7461      implemented his own getter/setter later on in the @implementation
7462      (in which case we shouldn't generate getter/setter).  We wait
7463      until we have parsed it all before generating the code.  */
7464 }
7465
7466 /* This function is called by the parser after a @synthesize
7467    expression is parsed.  'location' is the location of the
7468    @synthesize expression, and 'property_and_ivar_list' is a chained
7469    list of the property and ivar names.  */
7470 void
7471 objc_add_synthesize_declaration (location_t location, tree property_and_ivar_list)
7472 {
7473   tree interface, chain;
7474
7475   if (flag_objc1_only)
7476     error_at (input_location, "%<@synthesize%> is not available in Objective-C 1.0");
7477
7478   if (property_and_ivar_list == error_mark_node)
7479     return;
7480
7481   if (!objc_implementation_context)
7482     {
7483       /* We can get here only in Objective-C; the Objective-C++ parser
7484          detects the problem while parsing, outputs the error
7485          "misplaced '@synthesize' Objective-C++ construct" and skips
7486          the declaration.  */
7487       error_at (location, "%<@synthesize%> not in @implementation context");
7488       return;
7489     }
7490
7491   if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
7492     {
7493       error_at (location, "%<@synthesize%> can not be used in categories");
7494       return;
7495     }
7496
7497   interface = lookup_interface (CLASS_NAME (objc_implementation_context));
7498   if (!interface)
7499     {
7500       /* I can't see how this could happen, but it is good as a safety check.  */
7501       error_at (location, 
7502                 "%<@synthesize%> requires the @interface of the class to be available");
7503       return;
7504     }
7505
7506   /* Now, iterate over the properties and do each of them.  */
7507   for (chain = property_and_ivar_list; chain; chain = TREE_CHAIN (chain))
7508     {
7509       objc_add_synthesize_declaration_for_property (location, interface, TREE_VALUE (chain), 
7510                                                     TREE_PURPOSE (chain));
7511     }
7512 }
7513
7514 /* This function is a sub-routine of objc_add_dynamic_declaration.  It
7515    is called for each property to mark as dynamic once we have
7516    determined that the context is Ok.  */
7517 static void
7518 objc_add_dynamic_declaration_for_property (location_t location, tree interface,
7519                                            tree property_name)
7520 {
7521   /* Find the @property declaration.  */
7522   tree property;
7523
7524   /* Check that synthesize or dynamic has not already been used for
7525      the same property.  */
7526   for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
7527     if (PROPERTY_NAME (property) == property_name)
7528       {
7529         location_t original_location = DECL_SOURCE_LOCATION (property);
7530         
7531         if (PROPERTY_DYNAMIC (property))
7532           error_at (location, "property %qs already specified in %<@dynamic%>", 
7533                     IDENTIFIER_POINTER (property_name));
7534         else
7535           error_at (location, "property %qs already specified in %<@synthesize%>",
7536                     IDENTIFIER_POINTER (property_name));
7537
7538         if (original_location != UNKNOWN_LOCATION)
7539           inform (original_location, "originally specified here");
7540         return;
7541       }
7542
7543   /* Check that the property is declared in the interface.  It could
7544      also be declared in a superclass or protocol.  */
7545   property = lookup_property (interface, property_name);
7546
7547   if (!property)
7548     {
7549       error_at (location, "no declaration of property %qs found in the interface",
7550                 IDENTIFIER_POINTER (property_name));
7551       return;
7552     }
7553   else
7554     {
7555       /* We have to copy the property, because we want to chain it to
7556          the implementation context, and we want to store the source
7557          location of the @synthesize, not of the original
7558          @property.  */
7559       property = copy_node (property);
7560       DECL_SOURCE_LOCATION (property) = location;
7561     }
7562
7563   /* Note that a @dynamic (and only a @dynamic) always sets
7564      PROPERTY_DYNAMIC to 1.  You can recognize a @dynamic by that.
7565      (actually, as explained above, PROPERTY_DECL generated by
7566      @property and associated with a @dynamic property are also marked
7567      as PROPERTY_DYNAMIC).  */
7568   PROPERTY_DYNAMIC (property) = 1;
7569
7570   /* Add the property to the list of properties for current implementation. */
7571   TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
7572   IMPL_PROPERTY_DECL (objc_implementation_context) = property;
7573 }
7574
7575 /* This function is called by the parser after a @dynamic expression
7576    is parsed.  'location' is the location of the @dynamic expression,
7577    and 'property_list' is a chained list of all the property
7578    names.  */
7579 void
7580 objc_add_dynamic_declaration (location_t location, tree property_list)
7581 {
7582   tree interface, chain;
7583
7584   if (flag_objc1_only)
7585     error_at (input_location, "%<@dynamic%> is not available in Objective-C 1.0");
7586
7587   if (property_list == error_mark_node)
7588     return;
7589
7590   if (!objc_implementation_context)
7591     {
7592       /* We can get here only in Objective-C; the Objective-C++ parser
7593          detects the problem while parsing, outputs the error
7594          "misplaced '@dynamic' Objective-C++ construct" and skips the
7595          declaration.  */
7596       error_at (location, "%<@dynamic%> not in @implementation context");
7597       return;
7598     }
7599
7600   /* @dynamic is allowed in categories.  */
7601   switch (TREE_CODE (objc_implementation_context))
7602     {
7603     case CLASS_IMPLEMENTATION_TYPE:
7604       interface = lookup_interface (CLASS_NAME (objc_implementation_context));
7605       break;
7606     case CATEGORY_IMPLEMENTATION_TYPE:
7607       interface = lookup_category (implementation_template, 
7608                                    CLASS_SUPER_NAME (objc_implementation_context));
7609       break;
7610     default:
7611       gcc_unreachable ();
7612     }
7613
7614   if (!interface)
7615     {
7616       /* I can't see how this could happen, but it is good as a safety check.  */
7617       error_at (location,
7618                 "%<@dynamic%> requires the @interface of the class to be available");
7619       return;
7620     }
7621
7622   /* Now, iterate over the properties and do each of them.  */
7623   for (chain = property_list; chain; chain = TREE_CHAIN (chain))
7624     {
7625       objc_add_dynamic_declaration_for_property (location, interface, TREE_VALUE (chain));
7626     }
7627 }
7628
7629 /* Main routine to generate code/data for all the property information for 
7630    current implementation (class or category). CLASS is the interface where
7631    ivars are declared.  CLASS_METHODS is where methods are found which
7632    could be a class or a category depending on whether we are implementing
7633    property of a class or a category.  */
7634
7635 static void
7636 objc_gen_property_data (tree klass, tree class_methods)
7637 {
7638   tree x;
7639
7640   for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
7641     {
7642       /* @dynamic property - nothing to check or synthesize.  */
7643       if (PROPERTY_DYNAMIC (x))
7644         continue;
7645       
7646       /* @synthesize property - need to synthesize the accessors.  */
7647       if (PROPERTY_IVAR_NAME (x))
7648         {
7649           objc_synthesize_getter (klass, class_methods, x);
7650           
7651           if (PROPERTY_READONLY (x) == 0)
7652             objc_synthesize_setter (klass, class_methods, x);
7653
7654           continue;
7655         }
7656
7657       gcc_unreachable ();
7658     }
7659 }
7660
7661 /* This is called once we see the "@end" in an interface/implementation.  */
7662
7663 static void
7664 finish_class (tree klass)
7665 {
7666   switch (TREE_CODE (klass))
7667     {
7668     case CLASS_IMPLEMENTATION_TYPE:
7669       {
7670         /* All metadata generation is done in runtime.generate_metadata().  */
7671         
7672         /* Generate what needed for property; setters, getters, etc. */
7673         objc_gen_property_data (implementation_template, implementation_template);
7674
7675         if (implementation_template != objc_implementation_context)
7676           {
7677             /* Ensure that all method listed in the interface contain bodies.  */
7678             check_methods (CLASS_CLS_METHODS (implementation_template),
7679                            objc_implementation_context, '+');
7680             check_methods (CLASS_NST_METHODS (implementation_template),
7681                            objc_implementation_context, '-');
7682
7683             if (CLASS_PROTOCOL_LIST (implementation_template))
7684               check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7685                                "class",
7686                                CLASS_NAME (objc_implementation_context));
7687           }
7688         break;
7689       }
7690     case CATEGORY_IMPLEMENTATION_TYPE:
7691       {
7692         tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
7693         
7694         if (category)
7695           {
7696             /* Generate what needed for property; setters, getters, etc. */
7697             objc_gen_property_data (implementation_template, category);
7698
7699             /* Ensure all method listed in the interface contain bodies.  */
7700             check_methods (CLASS_CLS_METHODS (category),
7701                            objc_implementation_context, '+');
7702             check_methods (CLASS_NST_METHODS (category),
7703                            objc_implementation_context, '-');
7704             
7705             if (CLASS_PROTOCOL_LIST (category))
7706               check_protocols (CLASS_PROTOCOL_LIST (category),
7707                                "category",
7708                                CLASS_SUPER_NAME (objc_implementation_context));
7709           }
7710         break;
7711       }
7712     case CLASS_INTERFACE_TYPE:
7713     case CATEGORY_INTERFACE_TYPE:
7714     case PROTOCOL_INTERFACE_TYPE:
7715       {
7716         /* Process properties of the class. */
7717         tree x;
7718         for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
7719           {
7720             /* Now we check that the appropriate getter is declared,
7721                and if not, we declare one ourselves.  */
7722             tree getter_decl = lookup_method (CLASS_NST_METHODS (klass),
7723                                               PROPERTY_GETTER_NAME (x));
7724             
7725             if (getter_decl)
7726               {
7727                 /* TODO: Check that the declaration is consistent with the property.  */
7728                 ;
7729               }
7730             else
7731               {
7732                 /* Generate an instance method declaration for the
7733                    getter; for example "- (id) name;".  In general it
7734                    will be of the form
7735                    -(type)property_getter_name;  */
7736                 tree rettype = build_tree_list (NULL_TREE, TREE_TYPE (x));
7737                 getter_decl = build_method_decl (INSTANCE_METHOD_DECL, 
7738                                                  rettype, PROPERTY_GETTER_NAME (x), 
7739                                                  NULL_TREE, false);
7740                 if (PROPERTY_OPTIONAL (x))
7741                   objc_add_method (objc_interface_context, getter_decl, false, true);
7742                 else
7743                   objc_add_method (objc_interface_context, getter_decl, false, false);
7744                 TREE_DEPRECATED (getter_decl) = TREE_DEPRECATED (x);
7745                 METHOD_PROPERTY_CONTEXT (getter_decl) = x;
7746               }
7747
7748             if (PROPERTY_READONLY (x) == 0)
7749               {
7750                 /* Now we check that the appropriate setter is declared,
7751                    and if not, we declare on ourselves.  */
7752                 tree setter_decl = lookup_method (CLASS_NST_METHODS (klass), 
7753                                                   PROPERTY_SETTER_NAME (x));
7754                 
7755                 if (setter_decl)
7756                   {
7757                     /* TODO: Check that the declaration is consistent with the property.  */
7758                     ;
7759                   }
7760                 else
7761                   {
7762                     /* The setter name is something like 'setName:'.
7763                        We need the substring 'setName' to build the
7764                        method declaration due to how the declaration
7765                        works.  TODO: build_method_decl() will then
7766                        generate back 'setName:' from 'setName'; it
7767                        would be more efficient to hook into there.  */
7768                     const char *full_setter_name = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x));
7769                     size_t length = strlen (full_setter_name);
7770                     char *setter_name = (char *) alloca (length);
7771                     tree ret_type, selector, arg_type, arg_name;
7772                     
7773                     strcpy (setter_name, full_setter_name);
7774                     setter_name[length - 1] = '\0';
7775                     ret_type = build_tree_list (NULL_TREE, void_type_node);
7776                     arg_type = build_tree_list (NULL_TREE, TREE_TYPE (x));
7777                     arg_name = get_identifier ("_value");
7778                     selector = objc_build_keyword_decl (get_identifier (setter_name),
7779                                                         arg_type, arg_name, NULL);
7780                     setter_decl = build_method_decl (INSTANCE_METHOD_DECL, 
7781                                                      ret_type, selector,
7782                                                      build_tree_list (NULL_TREE, NULL_TREE),
7783                                                      false);
7784                     if (PROPERTY_OPTIONAL (x))
7785                       objc_add_method (objc_interface_context, setter_decl, false, true);
7786                     else
7787                       objc_add_method (objc_interface_context, setter_decl, false, false);
7788                     TREE_DEPRECATED (setter_decl) = TREE_DEPRECATED (x);
7789                     METHOD_PROPERTY_CONTEXT (setter_decl) = x;
7790                   }            
7791               }
7792           }
7793         break;
7794       }
7795     default:
7796       gcc_unreachable ();
7797       break;
7798     }
7799 }
7800
7801 static tree
7802 add_protocol (tree protocol)
7803 {
7804   /* Put protocol on list in reverse order.  */
7805   TREE_CHAIN (protocol) = protocol_chain;
7806   protocol_chain = protocol;
7807   return protocol_chain;
7808 }
7809
7810 /* Check that a protocol is defined, and, recursively, that all
7811    protocols that this protocol conforms to are defined too.  */
7812 static void
7813 check_that_protocol_is_defined (tree protocol)
7814 {
7815   if (!PROTOCOL_DEFINED (protocol))
7816     warning (0, "definition of protocol %qE not found",
7817              PROTOCOL_NAME (protocol));
7818
7819   /* If the protocol itself conforms to other protocols, check them
7820      too, recursively.  */
7821   if (PROTOCOL_LIST (protocol))
7822     {
7823       tree p;
7824
7825       for (p = PROTOCOL_LIST (protocol); p; p = TREE_CHAIN (p))
7826         check_that_protocol_is_defined (TREE_VALUE (p));
7827     }
7828 }
7829
7830 /* Looks up a protocol.  If 'warn_if_deprecated' is true, a warning is
7831    emitted if the protocol is deprecated.  If 'definition_required' is
7832    true, a warning is emitted if a full @protocol definition has not
7833    been seen.  */
7834 static tree
7835 lookup_protocol (tree ident, bool warn_if_deprecated, bool definition_required)
7836 {
7837   tree chain;
7838
7839   for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7840     if (ident == PROTOCOL_NAME (chain))
7841       {
7842         if (warn_if_deprecated && TREE_DEPRECATED (chain))
7843           {
7844             /* It would be nice to use warn_deprecated_use() here, but
7845                we are using TREE_CHAIN (which is supposed to be the
7846                TYPE_STUB_DECL for a TYPE) for something different.  */
7847             warning (OPT_Wdeprecated_declarations, "protocol %qE is deprecated", 
7848                      PROTOCOL_NAME (chain));
7849           }
7850
7851         if (definition_required)
7852           check_that_protocol_is_defined (chain);
7853
7854         return chain;
7855       }
7856
7857   return NULL_TREE;
7858 }
7859
7860 /* This function forward declares the protocols named by NAMES.  If
7861    they are already declared or defined, the function has no effect.  */
7862
7863 void
7864 objc_declare_protocols (tree names, tree attributes)
7865 {
7866   tree list;
7867   bool deprecated = false;
7868
7869 #ifdef OBJCPLUS
7870   if (current_namespace != global_namespace) {
7871     error ("Objective-C declarations may only appear in global scope");
7872   }
7873 #endif /* OBJCPLUS */
7874
7875   /* Determine if 'deprecated', the only attribute we recognize for
7876      protocols, was used.  Ignore all other attributes.  */
7877   if (attributes)
7878     {
7879       tree attribute;
7880       for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
7881         {
7882           tree name = TREE_PURPOSE (attribute);
7883           
7884           if (is_attribute_p  ("deprecated", name))
7885             deprecated = true;
7886           else
7887             warning (OPT_Wattributes, "%qE attribute directive ignored", name);
7888         }
7889     }
7890
7891   for (list = names; list; list = TREE_CHAIN (list))
7892     {
7893       tree name = TREE_VALUE (list);
7894
7895       if (lookup_protocol (name, /* warn if deprecated */ false,
7896                            /* definition_required */ false) == NULL_TREE)
7897         {
7898           tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7899
7900           TYPE_LANG_SLOT_1 (protocol)
7901             = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7902           PROTOCOL_NAME (protocol) = name;
7903           PROTOCOL_LIST (protocol) = NULL_TREE;
7904           add_protocol (protocol);
7905           PROTOCOL_DEFINED (protocol) = 0;
7906           PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7907           
7908           if (attributes)
7909             {
7910               TYPE_ATTRIBUTES (protocol) = attributes;
7911               if (deprecated)
7912                 TREE_DEPRECATED (protocol) = 1;
7913             }
7914         }
7915     }
7916 }
7917
7918 static tree
7919 start_protocol (enum tree_code code, tree name, tree list, tree attributes)
7920 {
7921   tree protocol;
7922   bool deprecated = false;
7923
7924 #ifdef OBJCPLUS
7925   if (current_namespace != global_namespace) {
7926     error ("Objective-C declarations may only appear in global scope");
7927   }
7928 #endif /* OBJCPLUS */
7929
7930   /* Determine if 'deprecated', the only attribute we recognize for
7931      protocols, was used.  Ignore all other attributes.  */
7932   if (attributes)
7933     {
7934       tree attribute;
7935       for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
7936         {
7937           tree name = TREE_PURPOSE (attribute);
7938           
7939           if (is_attribute_p  ("deprecated", name))
7940             deprecated = true;
7941           else
7942             warning (OPT_Wattributes, "%qE attribute directive ignored", name);
7943         }
7944     }
7945
7946   protocol = lookup_protocol (name, /* warn_if_deprecated */ false,
7947                               /* definition_required */ false);
7948
7949   if (!protocol)
7950     {
7951       protocol = make_node (code);
7952       TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7953
7954       PROTOCOL_NAME (protocol) = name;
7955       PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list, /* definition_required */ false);
7956       add_protocol (protocol);
7957       PROTOCOL_DEFINED (protocol) = 1;
7958       PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7959
7960       check_protocol_recursively (protocol, list);
7961     }
7962   else if (! PROTOCOL_DEFINED (protocol))
7963     {
7964       PROTOCOL_DEFINED (protocol) = 1;
7965       PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list, /* definition_required */ false);
7966
7967       check_protocol_recursively (protocol, list);
7968     }
7969   else
7970     {
7971       warning (0, "duplicate declaration for protocol %qE",
7972                name);
7973     }
7974
7975   if (attributes)
7976     {
7977       TYPE_ATTRIBUTES (protocol) = attributes;
7978       if (deprecated)
7979         TREE_DEPRECATED (protocol) = 1;
7980     }
7981
7982   return protocol;
7983 }
7984
7985 /* Decay array and function parameters into pointers.  */
7986
7987 static tree
7988 objc_decay_parm_type (tree type)
7989 {
7990   if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == FUNCTION_TYPE)
7991     type = build_pointer_type (TREE_CODE (type) == ARRAY_TYPE
7992                                ? TREE_TYPE (type)
7993                                : type);
7994
7995   return type;
7996 }
7997
7998 static GTY(()) tree objc_parmlist = NULL_TREE;
7999
8000 /* Append PARM to a list of formal parameters of a method, making a necessary
8001    array-to-pointer adjustment along the way.  */
8002
8003 void
8004 objc_push_parm (tree parm)
8005 {
8006   tree type;
8007
8008   if (TREE_TYPE (parm) == error_mark_node)
8009     {
8010       objc_parmlist = chainon (objc_parmlist, parm);
8011       return;
8012     }
8013
8014   /* Decay arrays and functions into pointers.  */
8015   type = objc_decay_parm_type (TREE_TYPE (parm));
8016
8017   /* If the parameter type has been decayed, a new PARM_DECL needs to be
8018      built as well.  */
8019   if (type != TREE_TYPE (parm))
8020     parm = build_decl (input_location, PARM_DECL, DECL_NAME (parm), type);
8021
8022   DECL_ARG_TYPE (parm)
8023     = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8024
8025   /* Record constancy and volatility.  */
8026   c_apply_type_quals_to_decl
8027   ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8028    | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8029    | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8030
8031   objc_parmlist = chainon (objc_parmlist, parm);
8032 }
8033
8034 /* Retrieve the formal parameter list constructed via preceding calls to
8035    objc_push_parm().  */
8036
8037 #ifdef OBJCPLUS
8038 tree
8039 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8040 {
8041   tree parm_info = objc_parmlist;
8042   objc_parmlist = NULL_TREE;
8043
8044   return parm_info;
8045 }
8046 #else
8047 struct c_arg_info *
8048 objc_get_parm_info (int have_ellipsis)
8049 {
8050   tree parm_info = objc_parmlist;
8051   struct c_arg_info *arg_info;
8052   /* The C front-end requires an elaborate song and dance at
8053      this point.  */
8054   push_scope ();
8055   declare_parm_level ();
8056   while (parm_info)
8057     {
8058       tree next = DECL_CHAIN (parm_info);
8059
8060       DECL_CHAIN (parm_info) = NULL_TREE;
8061       parm_info = pushdecl (parm_info);
8062       finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
8063       parm_info = next;
8064     }
8065   arg_info = get_parm_info (have_ellipsis);
8066   pop_scope ();
8067   objc_parmlist = NULL_TREE;
8068   return arg_info;
8069 }
8070 #endif
8071
8072 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8073    method definitions.  In the case of instance methods, we can be more
8074    specific as to the type of 'self'.  */
8075
8076 static void
8077 synth_self_and_ucmd_args (void)
8078 {
8079   tree self_type;
8080
8081   if (objc_method_context
8082       && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8083     self_type = objc_instance_type;
8084   else
8085     /* Really a `struct objc_class *'. However, we allow people to
8086        assign to self, which changes its type midstream.  */
8087     self_type = objc_object_type;
8088
8089   /* id self; */
8090   objc_push_parm (build_decl (input_location,
8091                               PARM_DECL, self_id, self_type));
8092
8093   /* SEL _cmd; */
8094   objc_push_parm (build_decl (input_location,
8095                               PARM_DECL, ucmd_id, objc_selector_type));
8096 }
8097
8098 /* Transform an Objective-C method definition into a static C function
8099    definition, synthesizing the first two arguments, "self" and "_cmd",
8100    in the process.  */
8101
8102 static void
8103 start_method_def (tree method)
8104 {
8105   tree parmlist;
8106 #ifdef OBJCPLUS
8107   tree parm_info;
8108 #else
8109   struct c_arg_info *parm_info;
8110 #endif
8111   int have_ellipsis = 0;
8112
8113   /* If we are defining a "dealloc" method in a non-root class, we
8114      will need to check if a [super dealloc] is missing, and warn if
8115      it is.  */
8116   if(CLASS_SUPER_NAME (objc_implementation_context)
8117      && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8118     should_call_super_dealloc = 1;
8119   else
8120     should_call_super_dealloc = 0;
8121
8122   /* Required to implement _msgSuper.  */
8123   objc_method_context = method;
8124   UOBJC_SUPER_decl = NULL_TREE;
8125
8126   /* Generate prototype declarations for arguments..."new-style".  */
8127   synth_self_and_ucmd_args ();
8128
8129   /* Generate argument declarations if a keyword_decl.  */
8130   parmlist = METHOD_SEL_ARGS (method);
8131   while (parmlist)
8132     {
8133       /* parmlist is a KEYWORD_DECL.  */
8134       tree type = TREE_VALUE (TREE_TYPE (parmlist));
8135       tree parm;
8136
8137       parm = build_decl (input_location,
8138                          PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8139       decl_attributes (&parm, DECL_ATTRIBUTES (parmlist), 0);
8140       objc_push_parm (parm);
8141       parmlist = DECL_CHAIN (parmlist);
8142     }
8143
8144   if (METHOD_ADD_ARGS (method))
8145     {
8146       tree akey;
8147
8148       for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8149            akey; akey = TREE_CHAIN (akey))
8150         {
8151           objc_push_parm (TREE_VALUE (akey));
8152         }
8153
8154       if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8155         have_ellipsis = 1;
8156     }
8157
8158   parm_info = objc_get_parm_info (have_ellipsis);
8159
8160   really_start_method (objc_method_context, parm_info);
8161 }
8162
8163 /* Return 1 if TYPE1 is equivalent to TYPE2 for purposes of method
8164    overloading.  */
8165 static int
8166 objc_types_are_equivalent (tree type1, tree type2)
8167 {
8168   if (type1 == type2)
8169     return 1;
8170
8171   /* Strip away indirections.  */
8172   while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8173          && (TREE_CODE (type1) == TREE_CODE (type2)))
8174     type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8175   if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8176     return 0;
8177
8178   /* Compare the protocol lists.  */
8179   type1 = (TYPE_HAS_OBJC_INFO (type1)
8180            ? TYPE_OBJC_PROTOCOL_LIST (type1)
8181            : NULL_TREE);
8182   type2 = (TYPE_HAS_OBJC_INFO (type2)
8183            ? TYPE_OBJC_PROTOCOL_LIST (type2)
8184            : NULL_TREE);
8185
8186   /* If there are no protocols (most common case), the types are
8187      identical.  */
8188   if (type1 == NULL_TREE && type2 == NULL_TREE)
8189     return 1;
8190   
8191   /* If one has protocols, and the other one hasn't, they are not
8192      identical.  */
8193   if ((type1 == NULL_TREE && type2 != NULL_TREE)
8194       || (type1 != NULL_TREE && type2 == NULL_TREE))
8195     return 0;
8196   else
8197     {
8198       /* Else, both have protocols, and we need to do the full
8199          comparison.  It is possible that either type1 or type2
8200          contain some duplicate protocols in the list, so we can't
8201          even just compare list_length as a first check.  */
8202       tree t;
8203
8204       for (t = type2; t; t = TREE_CHAIN (t))
8205         if (!lookup_protocol_in_reflist (type1, TREE_VALUE (t)))
8206           return 0;
8207       
8208       for (t = type1; t; t = TREE_CHAIN (t))
8209         if (!lookup_protocol_in_reflist (type2, TREE_VALUE (t)))
8210           return 0;
8211       
8212       return 1;
8213     }
8214 }
8215
8216 /* Return 1 if TYPE1 has the same size and alignment as TYPE2.  */
8217
8218 static int
8219 objc_types_share_size_and_alignment (tree type1, tree type2)
8220 {
8221   return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8222           && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8223 }
8224
8225 /* Return 1 if PROTO1 is equivalent to PROTO2
8226    for purposes of method overloading.  Ordinarily, the type signatures
8227    should match up exactly, unless STRICT is zero, in which case we
8228    shall allow differences in which the size and alignment of a type
8229    is the same.  */
8230
8231 static int
8232 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8233 {
8234   /* The following test is needed in case there are hashing
8235      collisions.  */
8236   if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8237     return 0;
8238
8239   return match_proto_with_proto (proto1, proto2, strict);
8240 }
8241
8242 static int
8243 match_proto_with_proto (tree proto1, tree proto2, int strict)
8244 {
8245   tree type1, type2;
8246
8247   /* Compare return types.  */
8248   type1 = TREE_VALUE (TREE_TYPE (proto1));
8249   type2 = TREE_VALUE (TREE_TYPE (proto2));
8250
8251   if (!objc_types_are_equivalent (type1, type2)
8252       && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8253     return 0;
8254
8255   /* Compare argument types.  */
8256   for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8257        type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8258        type1 && type2;
8259        type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8260     {
8261       if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8262           && (strict
8263               || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8264                                                        TREE_VALUE (type2))))
8265         return 0;
8266     }
8267
8268   return (!type1 && !type2);
8269 }
8270
8271 /* This routine returns true if TYPE is a valid objc object type,
8272    suitable for messaging; false otherwise.  If 'accept_class' is
8273    'true', then a Class object is considered valid for messaging and
8274    'true' is returned if 'type' refers to a Class.  If 'accept_class'
8275    is 'false', then a Class object is not considered valid for
8276    messaging and 'false' is returned in that case.  */
8277
8278 static bool
8279 objc_type_valid_for_messaging (tree type, bool accept_classes)
8280 {
8281   if (!POINTER_TYPE_P (type))
8282     return false;
8283
8284   /* Remove the pointer indirection; don't remove more than one
8285      otherwise we'd consider "NSObject **" a valid type for messaging,
8286      which it isn't.  */
8287   type = TREE_TYPE (type);
8288
8289   if (TREE_CODE (type) != RECORD_TYPE)
8290     return false;
8291
8292   if (objc_is_object_id (type))
8293     return true;
8294
8295   if (objc_is_class_id (type))
8296     return accept_classes;
8297
8298   if (TYPE_HAS_OBJC_INFO (type))
8299     return true;
8300
8301   return false;
8302 }
8303
8304 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8305    this occurs.  ObjC method dispatches are _not_ like C++ virtual
8306    member function dispatches, and we account for the difference here.  */
8307 tree
8308 #ifdef OBJCPLUS
8309 objc_fold_obj_type_ref (tree ref, tree known_type)
8310 #else
8311 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8312                         tree known_type ATTRIBUTE_UNUSED)
8313 #endif
8314 {
8315 #ifdef OBJCPLUS
8316   tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8317
8318   /* If the receiver does not have virtual member functions, there
8319      is nothing we can (or need to) do here.  */
8320   if (!v)
8321     return NULL_TREE;
8322
8323   /* Let C++ handle C++ virtual functions.  */
8324   return cp_fold_obj_type_ref (ref, known_type);
8325 #else
8326   /* For plain ObjC, we currently do not need to do anything.  */
8327   return NULL_TREE;
8328 #endif
8329 }
8330
8331 void
8332 objc_start_function (tree name, tree type, tree attrs,
8333 #ifdef OBJCPLUS
8334                      tree params
8335 #else
8336                      struct c_arg_info *params
8337 #endif
8338                      )
8339 {
8340   tree fndecl = build_decl (input_location,
8341                             FUNCTION_DECL, name, type);
8342
8343 #ifdef OBJCPLUS
8344   DECL_ARGUMENTS (fndecl) = params;
8345   DECL_INITIAL (fndecl) = error_mark_node;
8346   DECL_EXTERNAL (fndecl) = 0;
8347   TREE_STATIC (fndecl) = 1;
8348   retrofit_lang_decl (fndecl);
8349   cplus_decl_attributes (&fndecl, attrs, 0);
8350   start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8351 #else
8352   current_function_returns_value = 0;  /* Assume, until we see it does.  */
8353   current_function_returns_null = 0;
8354   decl_attributes (&fndecl, attrs, 0);
8355   announce_function (fndecl);
8356   DECL_INITIAL (fndecl) = error_mark_node;
8357   DECL_EXTERNAL (fndecl) = 0;
8358   TREE_STATIC (fndecl) = 1;
8359   current_function_decl = pushdecl (fndecl);
8360   push_scope ();
8361   declare_parm_level ();
8362   DECL_RESULT (current_function_decl)
8363     = build_decl (input_location,
8364                   RESULT_DECL, NULL_TREE,
8365                   TREE_TYPE (TREE_TYPE (current_function_decl)));
8366   DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8367   DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8368   start_fname_decls ();
8369   store_parm_decls_from (params);
8370 #endif
8371
8372   TREE_USED (current_function_decl) = 1;
8373 }
8374
8375 /* - Generate an identifier for the function. the format is "_n_cls",
8376      where 1 <= n <= nMethods, and cls is the name the implementation we
8377      are processing.
8378    - Install the return type from the method declaration.
8379    - If we have a prototype, check for type consistency.  */
8380
8381 static void
8382 really_start_method (tree method,
8383 #ifdef OBJCPLUS
8384                      tree parmlist
8385 #else
8386                      struct c_arg_info *parmlist
8387 #endif
8388                      )
8389 {
8390   tree ret_type, meth_type;
8391   tree method_id;
8392   const char *sel_name, *class_name, *cat_name;
8393   char *buf;
8394
8395   /* Synth the storage class & assemble the return type.  */
8396   ret_type = TREE_VALUE (TREE_TYPE (method));
8397
8398   sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8399   class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8400   cat_name = ((TREE_CODE (objc_implementation_context)
8401                == CLASS_IMPLEMENTATION_TYPE)
8402               ? NULL
8403               : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8404   method_slot++;
8405
8406   /* Make sure this is big enough for any plausible method label.  */
8407   buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8408                          + (cat_name ? strlen (cat_name) : 0));
8409
8410   OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8411                          class_name, cat_name, sel_name, method_slot);
8412
8413   method_id = get_identifier (buf);
8414
8415 #ifdef OBJCPLUS
8416   /* Objective-C methods cannot be overloaded, so we don't need
8417      the type encoding appended.  It looks bad anyway... */
8418   push_lang_context (lang_name_c);
8419 #endif
8420
8421   meth_type
8422     = build_function_type (ret_type,
8423                            get_arg_type_list (method, METHOD_DEF, 0));
8424   objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8425
8426   /* Set self_decl from the first argument.  */
8427   self_decl = DECL_ARGUMENTS (current_function_decl);
8428
8429   /* Suppress unused warnings.  */
8430   TREE_USED (self_decl) = 1;
8431   DECL_READ_P (self_decl) = 1;
8432   TREE_USED (DECL_CHAIN (self_decl)) = 1;
8433   DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
8434 #ifdef OBJCPLUS
8435   pop_lang_context ();
8436 #endif
8437
8438   METHOD_DEFINITION (method) = current_function_decl;
8439
8440   /* Check consistency...start_function, pushdecl, duplicate_decls.  */
8441
8442   if (implementation_template != objc_implementation_context)
8443     {
8444       tree proto
8445         = lookup_method_static (implementation_template,
8446                                 METHOD_SEL_NAME (method),
8447                                 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8448                                  | OBJC_LOOKUP_NO_SUPER));
8449
8450       if (proto)
8451         {
8452           if (!comp_proto_with_proto (method, proto, 1))
8453             {
8454               bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
8455
8456               warning_at (DECL_SOURCE_LOCATION (method), 0,
8457                           "conflicting types for %<%c%s%>",
8458                           (type ? '-' : '+'),
8459                           identifier_to_locale (gen_method_decl (method)));
8460               inform (DECL_SOURCE_LOCATION (proto),
8461                       "previous declaration of %<%c%s%>",
8462                       (type ? '-' : '+'),
8463                       identifier_to_locale (gen_method_decl (proto)));
8464             }
8465           else
8466             {
8467               /* If the method in the @interface was deprecated, mark
8468                  the implemented method as deprecated too.  It should
8469                  never be used for messaging (when the deprecation
8470                  warnings are produced), but just in case.  */
8471               if (TREE_DEPRECATED (proto))
8472                 TREE_DEPRECATED (method) = 1;
8473
8474               /* If the method in the @interface was marked as
8475                  'noreturn', mark the function implementing the method
8476                  as 'noreturn' too.  */
8477               TREE_THIS_VOLATILE (current_function_decl) = TREE_THIS_VOLATILE (proto);
8478             }
8479         }
8480       else
8481         {
8482           /* We have a method @implementation even though we did not
8483              see a corresponding @interface declaration (which is allowed
8484              by Objective-C rules).  Go ahead and place the method in
8485              the @interface anyway, so that message dispatch lookups
8486              will see it.  */
8487           tree interface = implementation_template;
8488
8489           if (TREE_CODE (objc_implementation_context)
8490               == CATEGORY_IMPLEMENTATION_TYPE)
8491             interface = lookup_category
8492                         (interface,
8493                          CLASS_SUPER_NAME (objc_implementation_context));
8494
8495           if (interface)
8496             objc_add_method (interface, copy_node (method),
8497                              TREE_CODE (method) == CLASS_METHOD_DECL, 
8498                              /* is_optional= */ false);
8499         }
8500     }
8501 }
8502
8503 static void *UOBJC_SUPER_scope = 0;
8504
8505 /* _n_Method (id self, SEL sel, ...)
8506      {
8507        struct objc_super _S;
8508        _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8509      }  */
8510
8511 static tree
8512 get_super_receiver (void)
8513 {
8514   if (objc_method_context)
8515     {
8516       tree super_expr, super_expr_list, class_expr;
8517       bool inst_meth;
8518       if (!UOBJC_SUPER_decl)
8519       {
8520         UOBJC_SUPER_decl = build_decl (input_location,
8521                                        VAR_DECL, get_identifier (TAG_SUPER),
8522                                        objc_super_template);
8523         /* This prevents `unused variable' warnings when compiling with -Wall.  */
8524         TREE_USED (UOBJC_SUPER_decl) = 1;
8525         DECL_READ_P (UOBJC_SUPER_decl) = 1;
8526         lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8527         finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
8528                      NULL_TREE);
8529         UOBJC_SUPER_scope = objc_get_current_scope ();
8530       }
8531
8532       /* Set receiver to self.  */
8533       super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8534       super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
8535                                       NOP_EXPR, input_location, self_decl,
8536                                       NULL_TREE);
8537       super_expr_list = super_expr;
8538
8539       /* Set class to begin searching.  */
8540       /* Get the ident for the superclass class field & build a ref to it.
8541          ??? maybe we should just name the field the same for all runtimes.  */
8542       super_expr = (*runtime.super_superclassfield_ident) ();
8543       super_expr = objc_build_component_ref (UOBJC_SUPER_decl, super_expr);
8544
8545       gcc_assert (imp_list->imp_context == objc_implementation_context
8546                   && imp_list->imp_template == implementation_template);
8547       inst_meth = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL);
8548
8549       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8550         class_expr =  (*runtime.get_class_super_ref) (input_location, 
8551                                                       imp_list, inst_meth);
8552       else
8553         /* We have a category.  */
8554         {
8555           tree super_name = CLASS_SUPER_NAME (imp_list->imp_template);
8556           tree super_class;
8557
8558           /* Barf if super used in a category of a root object.  */
8559           if (!super_name)
8560             {
8561               error ("no super class declared in interface for %qE",
8562                      CLASS_NAME (imp_list->imp_template));
8563               return error_mark_node;
8564             }
8565
8566           super_class = (*runtime.get_category_super_ref) (input_location, 
8567                                                            imp_list, inst_meth);
8568           class_expr = build_c_cast (input_location, 
8569                                      TREE_TYPE (super_expr), super_class);
8570         }
8571
8572       super_expr = build_modify_expr (input_location, super_expr, NULL_TREE, 
8573                                       NOP_EXPR,
8574                                       input_location, class_expr, NULL_TREE);
8575
8576       super_expr_list = build_compound_expr (input_location, 
8577                                              super_expr_list, super_expr);
8578
8579       super_expr = build_unary_op (input_location, 
8580                                    ADDR_EXPR, UOBJC_SUPER_decl, 0);
8581       super_expr_list = build_compound_expr (input_location,
8582                                              super_expr_list, super_expr);
8583
8584       return super_expr_list;
8585     }
8586   else
8587     {
8588       error ("[super ...] must appear in a method context");
8589       return error_mark_node;
8590     }
8591 }
8592
8593 /* When exiting a scope, sever links to a 'super' declaration (if any)
8594    therein contained.  */
8595
8596 void
8597 objc_clear_super_receiver (void)
8598 {
8599   if (objc_method_context
8600       && UOBJC_SUPER_scope == objc_get_current_scope ())
8601     {
8602       UOBJC_SUPER_decl = 0;
8603       UOBJC_SUPER_scope = 0;
8604     }
8605 }
8606
8607 void
8608 objc_finish_method_definition (tree fndecl)
8609 {
8610   /* We cannot validly inline ObjC methods, at least not without a language
8611      extension to declare that a method need not be dynamically
8612      dispatched, so suppress all thoughts of doing so.  */
8613   DECL_UNINLINABLE (fndecl) = 1;
8614
8615 #ifndef OBJCPLUS
8616   /* The C++ front-end will have called finish_function() for us.  */
8617   finish_function ();
8618 #endif
8619
8620   METHOD_ENCODING (objc_method_context)
8621     = encode_method_prototype (objc_method_context);
8622
8623   /* Required to implement _msgSuper. This must be done AFTER finish_function,
8624      since the optimizer may find "may be used before set" errors.  */
8625   objc_method_context = NULL_TREE;
8626
8627   if (should_call_super_dealloc)
8628     warning (0, "method possibly missing a [super dealloc] call");
8629 }
8630
8631 /* Given a tree DECL node, produce a printable description of it in the given
8632    buffer, overwriting the buffer.  */
8633
8634 static char *
8635 gen_declaration (tree decl)
8636 {
8637   errbuf[0] = '\0';
8638
8639   if (DECL_P (decl))
8640     {
8641       gen_type_name_0 (TREE_TYPE (decl));
8642
8643       if (DECL_NAME (decl))
8644         {
8645           if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8646             strcat (errbuf, " ");
8647
8648           strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8649         }
8650
8651       if (DECL_INITIAL (decl)
8652           && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8653         sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8654                  TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8655     }
8656
8657   return errbuf;
8658 }
8659
8660 /* Given a tree TYPE node, produce a printable description of it in the given
8661    buffer, overwriting the buffer.  */
8662
8663 static char *
8664 gen_type_name_0 (tree type)
8665 {
8666   tree orig = type, proto;
8667
8668   if (TYPE_P (type) && TYPE_NAME (type))
8669     type = TYPE_NAME (type);
8670   else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8671     {
8672       tree inner = TREE_TYPE (type);
8673
8674       while (TREE_CODE (inner) == ARRAY_TYPE)
8675         inner = TREE_TYPE (inner);
8676
8677       gen_type_name_0 (inner);
8678
8679       if (!POINTER_TYPE_P (inner))
8680         strcat (errbuf, " ");
8681
8682       if (POINTER_TYPE_P (type))
8683         strcat (errbuf, "*");
8684       else
8685         while (type != inner)
8686           {
8687             strcat (errbuf, "[");
8688
8689             if (TYPE_DOMAIN (type))
8690               {
8691                 char sz[20];
8692
8693                 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8694                          (TREE_INT_CST_LOW
8695                           (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8696                 strcat (errbuf, sz);
8697               }
8698
8699             strcat (errbuf, "]");
8700             type = TREE_TYPE (type);
8701           }
8702
8703       goto exit_function;
8704     }
8705
8706   if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8707     type = DECL_NAME (type);
8708
8709   strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
8710                   ? IDENTIFIER_POINTER (type)
8711                   : "");
8712
8713   /* For 'id' and 'Class', adopted protocols are stored in the pointee.  */
8714   if (objc_is_id (orig))
8715     orig = TREE_TYPE (orig);
8716
8717   proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8718
8719   if (proto)
8720     {
8721       strcat (errbuf, " <");
8722
8723       while (proto) {
8724         strcat (errbuf,
8725                 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8726         proto = TREE_CHAIN (proto);
8727         strcat (errbuf, proto ? ", " : ">");
8728       }
8729     }
8730
8731  exit_function:
8732   return errbuf;
8733 }
8734
8735 static char *
8736 gen_type_name (tree type)
8737 {
8738   errbuf[0] = '\0';
8739
8740   return gen_type_name_0 (type);
8741 }
8742
8743 /* Given a method tree, put a printable description into the given
8744    buffer (overwriting) and return a pointer to the buffer.  */
8745
8746 static char *
8747 gen_method_decl (tree method)
8748 {
8749   tree chain;
8750
8751   strcpy (errbuf, "(");  /* NB: Do _not_ call strcat() here.  */
8752   gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8753   strcat (errbuf, ")");
8754   chain = METHOD_SEL_ARGS (method);
8755
8756   if (chain)
8757     {
8758       /* We have a chain of keyword_decls.  */
8759       do
8760         {
8761           if (KEYWORD_KEY_NAME (chain))
8762             strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8763
8764           strcat (errbuf, ":(");
8765           gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8766           strcat (errbuf, ")");
8767
8768           strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8769           if ((chain = DECL_CHAIN (chain)))
8770             strcat (errbuf, " ");
8771         }
8772       while (chain);
8773
8774       if (METHOD_ADD_ARGS (method))
8775         {
8776           chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8777
8778           /* Know we have a chain of parm_decls.  */
8779           while (chain)
8780             {
8781               strcat (errbuf, ", ");
8782               gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8783               chain = TREE_CHAIN (chain);
8784             }
8785
8786           if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8787             strcat (errbuf, ", ...");
8788         }
8789     }
8790
8791   else
8792     /* We have a unary selector.  */
8793     strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8794
8795   return errbuf;
8796 }
8797 \f
8798 /* Debug info.  */
8799
8800
8801 /* Dump an @interface declaration of the supplied class CHAIN to the
8802    supplied file FP.  Used to implement the -gen-decls option (which
8803    prints out an @interface declaration of all classes compiled in
8804    this run); potentially useful for debugging the compiler too.  */
8805 void
8806 dump_interface (FILE *fp, tree chain)
8807 {
8808   /* FIXME: A heap overflow here whenever a method (or ivar)
8809      declaration is so long that it doesn't fit in the buffer.  The
8810      code and all the related functions should be rewritten to avoid
8811      using fixed size buffers.  */
8812   const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8813   tree ivar_decls = CLASS_RAW_IVARS (chain);
8814   tree nst_methods = CLASS_NST_METHODS (chain);
8815   tree cls_methods = CLASS_CLS_METHODS (chain);
8816
8817   fprintf (fp, "\n@interface %s", my_name);
8818
8819   /* CLASS_SUPER_NAME is used to store the superclass name for
8820      classes, and the category name for categories.  */
8821   if (CLASS_SUPER_NAME (chain))
8822     {
8823       const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8824
8825       switch (TREE_CODE (chain))
8826         {
8827         case CATEGORY_IMPLEMENTATION_TYPE:
8828         case CATEGORY_INTERFACE_TYPE:
8829           fprintf (fp, " (%s)\n", name);
8830           break;
8831         default:
8832           fprintf (fp, " : %s\n", name);
8833           break;
8834         }
8835     }
8836   else
8837     fprintf (fp, "\n");
8838
8839   /* FIXME - the following doesn't seem to work at the moment.  */
8840   if (ivar_decls)
8841     {
8842       fprintf (fp, "{\n");
8843       do
8844         {
8845           fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
8846           ivar_decls = TREE_CHAIN (ivar_decls);
8847         }
8848       while (ivar_decls);
8849       fprintf (fp, "}\n");
8850     }
8851
8852   while (nst_methods)
8853     {
8854       fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
8855       nst_methods = TREE_CHAIN (nst_methods);
8856     }
8857
8858   while (cls_methods)
8859     {
8860       fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
8861       cls_methods = TREE_CHAIN (cls_methods);
8862     }
8863
8864   fprintf (fp, "@end\n");
8865 }
8866
8867 #if 0
8868 /* Produce the pretty printing for an Objective-C method.  This is
8869    currently unused, but could be handy while reorganizing the pretty
8870    printing to be more robust.  */
8871 static const char *
8872 objc_pretty_print_method (bool is_class_method,
8873                           const char *class_name,
8874                           const char *category_name,
8875                           const char *selector)
8876 {
8877   if (category_name)
8878     {
8879       char *result = XNEWVEC (char, strlen (class_name) + strlen (category_name) 
8880                               + strlen (selector) + 7);
8881
8882       if (is_class_method)
8883         sprintf (result, "+[%s(%s) %s]", class_name, category_name, selector);
8884       else
8885         sprintf (result, "-[%s(%s) %s]", class_name, category_name, selector);
8886
8887       return result;
8888     }
8889   else
8890     {
8891       char *result = XNEWVEC (char, strlen (class_name)
8892                               + strlen (selector) + 5);
8893
8894       if (is_class_method)
8895         sprintf (result, "+[%s %s]", class_name, selector);
8896       else
8897         sprintf (result, "-[%s %s]", class_name, selector);
8898
8899       return result;      
8900     }
8901 }
8902 #endif
8903
8904 /* Demangle function for Objective-C.  Attempt to demangle the
8905    function name associated with a method (eg, going from
8906    "_i_NSObject__class" to "-[NSObject class]"); usually for the
8907    purpose of pretty printing or error messages.  Return the demangled
8908    name, or NULL if the string is not an Objective-C mangled method
8909    name.
8910
8911    Because of how the mangling is done, any method that has a '_' in
8912    its original name is at risk of being demangled incorrectly.  In
8913    some cases there are multiple valid ways to demangle a method name
8914    and there is no way we can decide.
8915
8916    TODO: objc_demangle() can't always get it right; the right way to
8917    get this correct for all method names would be to store the
8918    Objective-C method name somewhere in the function decl.  Then,
8919    there is no demangling to do; we'd just pull the method name out of
8920    the decl.  As an additional bonus, when printing error messages we
8921    could check for such a method name, and if we find it, we know the
8922    function is actually an Objective-C method and we could print error
8923    messages saying "In method '+[NSObject class]" instead of "In
8924    function '+[NSObject class]" as we do now.  */
8925 static const char *
8926 objc_demangle (const char *mangled)
8927 {
8928   char *demangled, *cp;
8929
8930   /* First of all, if the name is too short it can't be an Objective-C
8931      mangled method name.  */
8932   if (mangled[0] == '\0' || mangled[1] == '\0' || mangled[2] == '\0')
8933     return NULL;
8934
8935   /* If the name looks like an already demangled one, return it
8936      unchanged.  This should only happen on Darwin, where method names
8937      are mangled differently into a pretty-print form (such as
8938      '+[NSObject class]', see darwin.h).  In that case, demangling is
8939      a no-op, but we need to return the demangled name if it was an
8940      ObjC one, and return NULL if not.  We should be safe as no C/C++
8941      function can start with "-[" or "+[".  */
8942   if ((mangled[0] == '-' || mangled[0] == '+')
8943       && (mangled[1] == '['))
8944     return mangled;
8945
8946   if (mangled[0] == '_' &&
8947       (mangled[1] == 'i' || mangled[1] == 'c') &&
8948       mangled[2] == '_')
8949     {
8950       cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
8951       if (mangled[1] == 'i')
8952         *cp++ = '-';            /* for instance method */
8953       else
8954         *cp++ = '+';            /* for class method */
8955       *cp++ = '[';              /* opening left brace */
8956       strcpy(cp, mangled+3);    /* tack on the rest of the mangled name */
8957       while (*cp && *cp == '_')
8958         cp++;                   /* skip any initial underbars in class name */
8959       cp = strchr(cp, '_');     /* find first non-initial underbar */
8960       if (cp == NULL)
8961         {
8962           free(demangled);      /* not mangled name */
8963           return NULL;
8964         }
8965       if (cp[1] == '_')  /* easy case: no category name */
8966         {
8967           *cp++ = ' ';            /* replace two '_' with one ' ' */
8968           strcpy(cp, mangled + (cp - demangled) + 2);
8969         }
8970       else
8971         {
8972           *cp++ = '(';            /* less easy case: category name */
8973           cp = strchr(cp, '_');
8974           if (cp == 0)
8975             {
8976               free(demangled);    /* not mangled name */
8977               return NULL;
8978             }
8979           *cp++ = ')';
8980           *cp++ = ' ';            /* overwriting 1st char of method name... */
8981           strcpy(cp, mangled + (cp - demangled)); /* get it back */
8982         }
8983       /* Now we have the method name.  We need to generally replace
8984          '_' with ':' but trying to preserve '_' if it could only have
8985          been in the mangled string because it was already in the
8986          original name.  In cases where it's ambiguous, we assume that
8987          any '_' originated from a ':'.  */
8988
8989       /* Initial '_'s in method name can't have been generating by
8990          converting ':'s.  Skip them.  */
8991       while (*cp && *cp == '_')
8992         cp++;
8993
8994       /* If the method name does not end with '_', then it has no
8995          arguments and there was no replacement of ':'s with '_'s
8996          during mangling.  Check for that case, and skip any
8997          replacement if so.  This at least guarantees that methods
8998          with no arguments are always demangled correctly (unless the
8999          original name ends with '_').  */
9000       if (*(mangled + strlen (mangled) - 1) != '_')
9001         {
9002           /* Skip to the end.  */
9003           for (; *cp; cp++)
9004             ;
9005         }
9006       else
9007         {
9008           /* Replace remaining '_' with ':'.  This may get it wrong if
9009              there were '_'s in the original name.  In most cases it
9010              is impossible to disambiguate.  */
9011           for (; *cp; cp++)
9012             if (*cp == '_')
9013               *cp = ':';         
9014         }
9015       *cp++ = ']';              /* closing right brace */
9016       *cp++ = 0;                /* string terminator */
9017       return demangled;
9018     }
9019   else
9020     return NULL;             /* not an objc mangled name */
9021 }
9022
9023 /* Try to pretty-print a decl.  If the 'decl' is an Objective-C
9024    specific decl, return the printable name for it.  If not, return
9025    NULL.  */
9026 const char *
9027 objc_maybe_printable_name (tree decl, int v ATTRIBUTE_UNUSED)
9028 {
9029   switch (TREE_CODE (decl))
9030     {
9031     case FUNCTION_DECL:
9032       return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9033       break;
9034
9035       /* The following happens when we are printing a deprecation
9036          warning for a method.  The warn_deprecation() will end up
9037          trying to print the decl for INSTANCE_METHOD_DECL or
9038          CLASS_METHOD_DECL.  It would be nice to be able to print
9039          "-[NSObject autorelease] is deprecated", but to do that, we'd
9040          need to store the class and method name in the method decl,
9041          which we currently don't do.  For now, just return the name
9042          of the method.  We don't return NULL, because that may
9043          trigger further attempts to pretty-print the decl in C/C++,
9044          but they wouldn't know how to pretty-print it.  */
9045     case INSTANCE_METHOD_DECL:
9046     case CLASS_METHOD_DECL:
9047       return IDENTIFIER_POINTER (DECL_NAME (decl));
9048       break;
9049       /* This happens when printing a deprecation warning for a
9050          property.  We may want to consider some sort of pretty
9051          printing (eg, include the class name where it was declared
9052          ?).  */
9053     case PROPERTY_DECL:
9054       return IDENTIFIER_POINTER (PROPERTY_NAME (decl));
9055       break;
9056     default:
9057       return NULL;
9058       break;
9059     }
9060 }
9061
9062 /* Return a printable name for 'decl'.  This first tries
9063    objc_maybe_printable_name(), and if that fails, it returns the name
9064    in the decl.  This is used as LANG_HOOKS_DECL_PRINTABLE_NAME for
9065    Objective-C; in Objective-C++, setting the hook is not enough
9066    because lots of C++ Front-End code calls cxx_printable_name,
9067    dump_decl and other C++ functions directly.  So instead we have
9068    modified dump_decl to call objc_maybe_printable_name directly.  */
9069 const char *
9070 objc_printable_name (tree decl, int v)
9071 {
9072   const char *demangled_name = objc_maybe_printable_name (decl, v);
9073
9074   if (demangled_name != NULL)
9075     return demangled_name;
9076   else
9077     return IDENTIFIER_POINTER (DECL_NAME (decl));
9078 }
9079
9080 /* Routine is called to issue diagnostic when reference to a private 
9081    ivar is made and no other variable with same name is found in 
9082    current scope.  */
9083 bool
9084 objc_diagnose_private_ivar (tree id)
9085 {
9086   tree ivar;
9087   if (!objc_method_context)
9088     return false;
9089   ivar = is_ivar (objc_ivar_chain, id);
9090   if (ivar && is_private (ivar))
9091     {
9092       error ("instance variable %qs is declared private", 
9093              IDENTIFIER_POINTER (id));
9094       return true;
9095     }
9096   return false;
9097 }
9098
9099 /* Look up ID as an instance variable.  OTHER contains the result of
9100    the C or C++ lookup, which we may want to use instead.  */
9101 /* To use properties inside an instance method, use self.property.  */
9102 tree
9103 objc_lookup_ivar (tree other, tree id)
9104 {
9105   tree ivar;
9106
9107   /* If we are not inside of an ObjC method, ivar lookup makes no sense.  */
9108   if (!objc_method_context)
9109     return other;
9110
9111   if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9112     /* We have a message to super.  */
9113     return get_super_receiver ();
9114
9115   /* In a class method, look up an instance variable only as a last
9116      resort.  */
9117   if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9118       && other && other != error_mark_node)
9119     return other;
9120
9121   /* Look up the ivar, but do not use it if it is not accessible.  */
9122   ivar = is_ivar (objc_ivar_chain, id);
9123   
9124   if (!ivar || is_private (ivar))
9125     return other;
9126
9127   /* In an instance method, a local variable (or parameter) may hide the
9128      instance variable.  */
9129   if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9130       && other && other != error_mark_node
9131 #ifdef OBJCPLUS
9132       && CP_DECL_CONTEXT (other) != global_namespace)
9133 #else
9134       && !DECL_FILE_SCOPE_P (other))
9135 #endif
9136     {
9137       warning (0, "local declaration of %qE hides instance variable", id);
9138
9139       return other;
9140     }
9141
9142   /* At this point, we are either in an instance method with no obscuring
9143      local definitions, or in a class method with no alternate definitions
9144      at all.  */
9145   return build_ivar_reference (id);
9146 }
9147
9148 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression.  This
9149    needs to be done if we are calling a function through a cast.  */
9150
9151 tree
9152 objc_rewrite_function_call (tree function, tree first_param)
9153 {
9154   if (TREE_CODE (function) == NOP_EXPR
9155       && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9156       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9157          == FUNCTION_DECL)
9158     {
9159       function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9160                          TREE_OPERAND (function, 0),
9161                          first_param, size_zero_node);
9162     }
9163
9164   return function;
9165 }
9166
9167 /* This is called to "gimplify" a PROPERTY_REF node.  It builds the
9168    corresponding 'getter' function call.  Note that we assume the
9169    PROPERTY_REF to be valid since we generated it while parsing.  */
9170 static void
9171 objc_gimplify_property_ref (tree *expr_p)
9172 {
9173   tree getter = PROPERTY_REF_GETTER_CALL (*expr_p);
9174   tree call_exp;
9175
9176   if (getter == NULL_TREE)
9177     {
9178       tree property_decl = PROPERTY_REF_PROPERTY_DECL (*expr_p);
9179       /* This can happen if DECL_ARTIFICIAL (*expr_p), but
9180          should be impossible for real properties, which always
9181          have a getter.  */
9182       error_at (EXPR_LOCATION (*expr_p), "no %qs getter found",
9183                 IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
9184       /* Try to recover from the error to prevent an ICE.  We take
9185          zero and cast it to the type of the property.  */
9186       *expr_p = convert (TREE_TYPE (property_decl),
9187                          integer_zero_node);
9188       return;
9189     }
9190
9191   if (PROPERTY_REF_DEPRECATED_GETTER (*expr_p))
9192     {
9193       /* PROPERTY_REF_DEPRECATED_GETTER contains the method prototype
9194          that is deprecated.  */
9195       warn_deprecated_use (PROPERTY_REF_DEPRECATED_GETTER (*expr_p),
9196                            NULL_TREE);
9197     }
9198
9199   call_exp = getter;
9200 #ifdef OBJCPLUS
9201   /* In C++, a getter which returns an aggregate value results in a
9202      target_expr which initializes a temporary to the call
9203      expression.  */
9204   if (TREE_CODE (getter) == TARGET_EXPR)
9205     {
9206       gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter)));
9207       gcc_assert (TREE_CODE (TREE_OPERAND (getter, 0)) == VAR_DECL);
9208       call_exp = TREE_OPERAND (getter, 1);
9209     }
9210 #endif
9211   gcc_assert (TREE_CODE (call_exp) == CALL_EXPR);
9212   
9213   *expr_p = call_exp;
9214 }
9215
9216 /* This is called when "gimplifying" the trees.  We need to gimplify
9217    the Objective-C/Objective-C++ specific trees, then hand over the
9218    process to C/C++.  */
9219 int
9220 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
9221 {
9222   enum tree_code code = TREE_CODE (*expr_p);
9223   switch (code)
9224     {
9225       /* Look for the special case of OBJC_TYPE_REF with the address
9226          of a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend
9227          or one of its cousins).  */
9228     case OBJ_TYPE_REF:
9229       if (TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9230           && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9231           == FUNCTION_DECL)
9232         {
9233           enum gimplify_status r0, r1;
9234
9235           /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9236              value of the OBJ_TYPE_REF, so force them to be emitted
9237              during subexpression evaluation rather than after the
9238              OBJ_TYPE_REF. This permits objc_msgSend calls in
9239              Objective C to use direct rather than indirect calls when
9240              the object expression has a postincrement.  */
9241           r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9242                               is_gimple_val, fb_rvalue);
9243           r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9244                               is_gimple_val, fb_rvalue);
9245           
9246           return MIN (r0, r1);
9247         }
9248       break;
9249     case PROPERTY_REF:
9250       objc_gimplify_property_ref (expr_p);
9251       /* Do not return yet; let C/C++ gimplify the resulting expression.  */
9252       break;
9253     default:
9254       break;
9255     }
9256
9257 #ifdef OBJCPLUS
9258   return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
9259 #else
9260   return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
9261 #endif
9262 }
9263
9264 /* --- FAST ENUMERATION --- */
9265 /* Begin code generation for fast enumeration (foreach) ... */
9266
9267 /* Defines
9268
9269   struct __objcFastEnumerationState
9270    {
9271      unsigned long state;
9272      id            *itemsPtr;
9273      unsigned long *mutationsPtr;
9274      unsigned long extra[5];
9275    };
9276
9277    Confusingly enough, NSFastEnumeration is then defined by libraries
9278    to be the same structure.  
9279 */
9280
9281 static void
9282 build_fast_enumeration_state_template (void)
9283 {
9284   tree decls, *chain = NULL;
9285
9286   /* { */
9287   objc_fast_enumeration_state_template = objc_start_struct (get_identifier 
9288                                                             (TAG_FAST_ENUMERATION_STATE));
9289
9290   /* unsigned long state; */
9291   decls = add_field_decl (long_unsigned_type_node, "state", &chain);
9292
9293   /* id            *itemsPtr; */
9294   add_field_decl (build_pointer_type (objc_object_type), 
9295                   "itemsPtr", &chain);
9296
9297   /* unsigned long *mutationsPtr; */
9298   add_field_decl (build_pointer_type (long_unsigned_type_node), 
9299                   "mutationsPtr", &chain);
9300
9301   /* unsigned long extra[5]; */
9302   add_field_decl (build_sized_array_type (long_unsigned_type_node, 5), 
9303                   "extra", &chain);
9304
9305   /* } */
9306   objc_finish_struct (objc_fast_enumeration_state_template, decls);
9307 }
9308
9309 /*
9310   'objc_finish_foreach_loop()' generates the code for an Objective-C
9311   foreach loop.  The 'location' argument is the location of the 'for'
9312   that starts the loop.  The 'object_expression' is the expression of
9313   the 'object' that iterates; the 'collection_expression' is the
9314   expression of the collection that we iterate over (we need to make
9315   sure we evaluate this only once); the 'for_body' is the set of
9316   statements to be executed in each iteration; 'break_label' and
9317   'continue_label' are the break and continue labels which we need to
9318   emit since the <statements> may be jumping to 'break_label' (if they
9319   contain 'break') or to 'continue_label' (if they contain
9320   'continue').
9321
9322   The syntax is
9323   
9324   for (<object expression> in <collection expression>)
9325     <statements>
9326
9327   which is compiled into the following blurb:
9328
9329   {
9330     id __objc_foreach_collection;
9331     __objc_fast_enumeration_state __objc_foreach_enum_state;
9332     unsigned long __objc_foreach_batchsize;
9333     id __objc_foreach_items[16];
9334     __objc_foreach_collection = <collection expression>;
9335     __objc_foreach_enum_state = { 0 };
9336     __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16];
9337     
9338     if (__objc_foreach_batchsize == 0)
9339       <object expression> = nil;
9340     else
9341       {
9342         unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
9343         next_batch:
9344           {
9345             unsigned long __objc_foreach_index;
9346             __objc_foreach_index = 0;
9347
9348             next_object:
9349             if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
9350             <object expression> = enumState.itemsPtr[__objc_foreach_index];
9351             <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
9352
9353             continue_label:
9354             __objc_foreach_index++;
9355             if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
9356             __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16];
9357          }
9358        if (__objc_foreach_batchsize != 0) goto next_batch;
9359        <object expression> = nil;
9360        break_label:
9361       }
9362   }
9363
9364   'statements' may contain a 'continue' or 'break' instruction, which
9365   the user expects to 'continue' or 'break' the entire foreach loop.
9366   We are provided the labels that 'break' and 'continue' jump to, so
9367   we place them where we want them to jump to when they pick them.
9368   
9369   Optimization TODO: we could cache the IMP of
9370   countByEnumeratingWithState:objects:count:.
9371 */
9372
9373 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line.  */
9374 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
9375
9376 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
9377 #include "tree-pretty-print.h"
9378 #endif
9379
9380 void
9381 objc_finish_foreach_loop (location_t location, tree object_expression, tree collection_expression, tree for_body, 
9382                           tree break_label, tree continue_label)
9383 {
9384   /* A tree representing the __objcFastEnumerationState struct type,
9385      or NSFastEnumerationState struct, whatever we are using.  */
9386   tree objc_fast_enumeration_state_type;
9387
9388   /* The trees representing the declarations of each of the local variables.  */
9389   tree objc_foreach_collection_decl;
9390   tree objc_foreach_enum_state_decl;
9391   tree objc_foreach_items_decl;
9392   tree objc_foreach_batchsize_decl;
9393   tree objc_foreach_mutations_pointer_decl;
9394   tree objc_foreach_index_decl;
9395
9396   /* A tree representing the selector countByEnumeratingWithState:objects:count:.  */
9397   tree selector_name;
9398
9399   /* A tree representing the local bind.  */
9400   tree bind;
9401
9402   /* A tree representing the external 'if (__objc_foreach_batchsize)' */
9403   tree first_if;
9404
9405   /* A tree representing the 'else' part of 'first_if'  */
9406   tree first_else;
9407
9408   /* A tree representing the 'next_batch' label.  */
9409   tree next_batch_label_decl;
9410
9411   /* A tree representing the binding after the 'next_batch' label.  */
9412   tree next_batch_bind;
9413
9414   /* A tree representing the 'next_object' label.  */
9415   tree next_object_label_decl;
9416
9417   /* Temporary variables.  */
9418   tree t;
9419   int i;
9420
9421   if (flag_objc1_only)
9422     error_at (location, "fast enumeration is not available in Objective-C 1.0");
9423
9424   if (object_expression == error_mark_node)
9425     return;
9426
9427   if (collection_expression == error_mark_node)
9428     return;
9429
9430   if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression), true))
9431     {
9432       error_at (location, "iterating variable in fast enumeration is not an object");
9433       return;
9434     }
9435
9436   if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression), true))
9437     {
9438       error_at (location, "collection in fast enumeration is not an object");
9439       return;
9440     }
9441
9442   /* TODO: Check that object_expression is either a variable
9443      declaration, or an lvalue.  */
9444
9445   /* This kludge is an idea from apple.  We use the
9446      __objcFastEnumerationState struct implicitly defined by the
9447      compiler, unless a NSFastEnumerationState struct has been defined
9448      (by a Foundation library such as GNUstep Base) in which case, we
9449      use that one.
9450   */
9451   objc_fast_enumeration_state_type = objc_fast_enumeration_state_template;
9452   {
9453     tree objc_NSFastEnumeration_type = lookup_name (get_identifier ("NSFastEnumerationState"));
9454
9455     if (objc_NSFastEnumeration_type)
9456       {
9457         /* TODO: We really need to check that
9458            objc_NSFastEnumeration_type is the same as ours!  */
9459         if (TREE_CODE (objc_NSFastEnumeration_type) == TYPE_DECL)
9460           {
9461             /* If it's a typedef, use the original type.  */
9462             if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type))
9463               objc_fast_enumeration_state_type = DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type);
9464             else
9465               objc_fast_enumeration_state_type = TREE_TYPE (objc_NSFastEnumeration_type);             
9466           }
9467       }
9468   }
9469
9470   /* { */
9471   /* Done by c-parser.c.  */
9472
9473   /* type object; */
9474   /* Done by c-parser.c.  */
9475
9476   /* Disable warnings that 'object' is unused.  For example the code
9477
9478      for (id object in collection)
9479        i++;
9480
9481      which can be used to count how many objects there are in the
9482      collection is fine and should generate no warnings even if
9483      'object' is technically unused.  */
9484   TREE_USED (object_expression) = 1;
9485   if (DECL_P (object_expression))
9486     DECL_READ_P (object_expression) = 1;
9487
9488   /*  id __objc_foreach_collection */
9489   objc_foreach_collection_decl = objc_create_temporary_var (objc_object_type, "__objc_foreach_collection");
9490
9491   /*  __objcFastEnumerationState __objc_foreach_enum_state; */
9492   objc_foreach_enum_state_decl = objc_create_temporary_var (objc_fast_enumeration_state_type, "__objc_foreach_enum_state");
9493   TREE_CHAIN (objc_foreach_enum_state_decl) = objc_foreach_collection_decl;
9494
9495   /* id __objc_foreach_items[16]; */
9496   objc_foreach_items_decl = objc_create_temporary_var (build_sized_array_type (objc_object_type, 16), "__objc_foreach_items");
9497   TREE_CHAIN (objc_foreach_items_decl) = objc_foreach_enum_state_decl;
9498
9499   /* unsigned long __objc_foreach_batchsize; */
9500   objc_foreach_batchsize_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_batchsize");
9501   TREE_CHAIN (objc_foreach_batchsize_decl) = objc_foreach_items_decl;
9502
9503   /* Generate the local variable binding.  */
9504   bind = build3 (BIND_EXPR, void_type_node, objc_foreach_batchsize_decl, NULL, NULL);
9505   SET_EXPR_LOCATION (bind, location);
9506   TREE_SIDE_EFFECTS (bind) = 1;
9507   
9508   /*  __objc_foreach_collection = <collection expression>; */
9509   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_collection_decl, collection_expression);
9510   SET_EXPR_LOCATION (t, location);
9511   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
9512   /* We have used 'collection_expression'.  */
9513   mark_exp_read (collection_expression);
9514
9515   /*  __objc_foreach_enum_state.state = 0; */
9516   t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl, 
9517                                                                      get_identifier ("state")),
9518               build_int_cst (long_unsigned_type_node, 0));
9519   SET_EXPR_LOCATION (t, location);
9520   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
9521
9522   /*  __objc_foreach_enum_state.itemsPtr = NULL; */
9523   t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl, 
9524                                                                      get_identifier ("itemsPtr")),
9525               null_pointer_node);
9526   SET_EXPR_LOCATION (t, location);
9527   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
9528
9529   /*  __objc_foreach_enum_state.mutationsPtr = NULL; */
9530   t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl, 
9531                                                                      get_identifier ("mutationsPtr")),
9532               null_pointer_node);
9533   SET_EXPR_LOCATION (t, location);
9534   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
9535
9536   /*  __objc_foreach_enum_state.extra[0] = 0; */
9537   /*  __objc_foreach_enum_state.extra[1] = 0; */
9538   /*  __objc_foreach_enum_state.extra[2] = 0; */
9539   /*  __objc_foreach_enum_state.extra[3] = 0; */
9540   /*  __objc_foreach_enum_state.extra[4] = 0; */
9541   for (i = 0; i < 5 ; i++)
9542     {
9543       t = build2 (MODIFY_EXPR, void_type_node,
9544                   build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl, 
9545                                                                        get_identifier ("extra")),
9546                                    build_int_cst (NULL_TREE, i)),
9547                   build_int_cst (long_unsigned_type_node, 0));
9548       SET_EXPR_LOCATION (t, location);
9549       append_to_statement_list (t, &BIND_EXPR_BODY (bind));
9550     }
9551     
9552   /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16]; */
9553   selector_name = get_identifier ("countByEnumeratingWithState:objects:count:");
9554 #ifdef OBJCPLUS
9555   t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
9556                                 /* Parameters.  */
9557                                 tree_cons    /* &__objc_foreach_enum_state */
9558                                 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
9559                                  tree_cons   /* __objc_foreach_items  */
9560                                  (NULL_TREE, objc_foreach_items_decl,
9561                                   tree_cons  /* 16 */
9562                                   (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL);
9563 #else
9564   /* In C, we need to decay the __objc_foreach_items array that we are passing.  */
9565   {
9566     struct c_expr array;
9567     array.value = objc_foreach_items_decl;
9568     t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
9569                                   /* Parameters.  */
9570                                   tree_cons    /* &__objc_foreach_enum_state */
9571                                   (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
9572                                    tree_cons   /* __objc_foreach_items  */
9573                                    (NULL_TREE, default_function_array_conversion (location, array).value,
9574                                     tree_cons  /* 16 */
9575                                     (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL);
9576   }
9577 #endif
9578   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
9579               convert (long_unsigned_type_node, t));
9580   SET_EXPR_LOCATION (t, location);
9581   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
9582
9583   /* if (__objc_foreach_batchsize == 0) */
9584   first_if = build3 (COND_EXPR, void_type_node, 
9585                      /* Condition.  */
9586                      c_fully_fold 
9587                      (c_common_truthvalue_conversion 
9588                       (location, 
9589                        build_binary_op (location,
9590                                         EQ_EXPR, 
9591                                         objc_foreach_batchsize_decl,
9592                                         build_int_cst (long_unsigned_type_node, 0), 1)),
9593                       false, NULL),
9594                      /* Then block (we fill it in later).  */
9595                      NULL_TREE,
9596                      /* Else block (we fill it in later).  */
9597                      NULL_TREE);
9598   SET_EXPR_LOCATION (first_if, location);
9599   append_to_statement_list (first_if, &BIND_EXPR_BODY (bind));
9600
9601   /* then <object expression> = nil; */
9602   t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
9603   SET_EXPR_LOCATION (t, location);
9604   COND_EXPR_THEN (first_if) = t;
9605
9606   /* Now we build the 'else' part of the if; once we finish building
9607      it, we attach it to first_if as the 'else' part.  */
9608
9609   /* else */
9610   /* { */
9611
9612   /* unsigned long __objc_foreach_mutations_pointer; */
9613   objc_foreach_mutations_pointer_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_mutations_pointer");
9614
9615   /* Generate the local variable binding.  */
9616   first_else = build3 (BIND_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, NULL, NULL);
9617   SET_EXPR_LOCATION (first_else, location);
9618   TREE_SIDE_EFFECTS (first_else) = 1;
9619
9620   /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
9621   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, 
9622               build_indirect_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl, 
9623                                                                       get_identifier ("mutationsPtr")),
9624                                   RO_UNARY_STAR));
9625   SET_EXPR_LOCATION (t, location);
9626   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
9627
9628   /* next_batch: */
9629   next_batch_label_decl = create_artificial_label (location);
9630   t = build1 (LABEL_EXPR, void_type_node, next_batch_label_decl); 
9631   SET_EXPR_LOCATION (t, location);
9632   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
9633   
9634   /* { */
9635
9636   /* unsigned long __objc_foreach_index; */
9637   objc_foreach_index_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_index");
9638
9639   /* Generate the local variable binding.  */
9640   next_batch_bind = build3 (BIND_EXPR, void_type_node, objc_foreach_index_decl, NULL, NULL);
9641   SET_EXPR_LOCATION (next_batch_bind, location);
9642   TREE_SIDE_EFFECTS (next_batch_bind) = 1;
9643   append_to_statement_list (next_batch_bind, &BIND_EXPR_BODY (first_else));
9644
9645   /* __objc_foreach_index = 0; */
9646   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
9647               build_int_cst (long_unsigned_type_node, 0));
9648   SET_EXPR_LOCATION (t, location);
9649   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
9650
9651   /* next_object: */
9652   next_object_label_decl = create_artificial_label (location);
9653   t = build1 (LABEL_EXPR, void_type_node, next_object_label_decl);
9654   SET_EXPR_LOCATION (t, location);
9655   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
9656
9657   /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
9658   t = build3 (COND_EXPR, void_type_node, 
9659               /* Condition.  */
9660               c_fully_fold 
9661               (c_common_truthvalue_conversion 
9662                (location, 
9663                 build_binary_op 
9664                 (location,
9665                  NE_EXPR, 
9666                  objc_foreach_mutations_pointer_decl,
9667                  build_indirect_ref (location, 
9668                                      objc_build_component_ref (objc_foreach_enum_state_decl, 
9669                                                                get_identifier ("mutationsPtr")),
9670                                      RO_UNARY_STAR), 1)),
9671                false, NULL),
9672               /* Then block.  */
9673               build_function_call (input_location,
9674                                    objc_enumeration_mutation_decl,
9675                                    tree_cons (NULL, collection_expression, NULL)),
9676               /* Else block.  */
9677               NULL_TREE);
9678   SET_EXPR_LOCATION (t, location);
9679   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
9680
9681   /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
9682   t = build2 (MODIFY_EXPR, void_type_node, object_expression, 
9683               build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl, 
9684                                                                    get_identifier ("itemsPtr")),
9685                                objc_foreach_index_decl));
9686   SET_EXPR_LOCATION (t, location);
9687   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
9688
9689   /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
9690   append_to_statement_list (for_body, &BIND_EXPR_BODY (next_batch_bind));
9691
9692   /* continue_label: */
9693   if (continue_label)
9694     {
9695       t = build1 (LABEL_EXPR, void_type_node, continue_label);
9696       SET_EXPR_LOCATION (t, location);
9697       append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
9698     }
9699
9700   /* __objc_foreach_index++; */
9701   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl, 
9702               build_binary_op (location,
9703                                PLUS_EXPR,
9704                                objc_foreach_index_decl,
9705                                build_int_cst (long_unsigned_type_node, 1), 1));
9706   SET_EXPR_LOCATION (t, location);
9707   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
9708
9709   /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
9710   t = build3 (COND_EXPR, void_type_node, 
9711               /* Condition.  */
9712               c_fully_fold 
9713               (c_common_truthvalue_conversion 
9714                (location, 
9715                 build_binary_op (location,
9716                                  LT_EXPR, 
9717                                  objc_foreach_index_decl,
9718                                  objc_foreach_batchsize_decl, 1)),
9719                false, NULL),
9720               /* Then block.  */
9721               build1 (GOTO_EXPR, void_type_node, next_object_label_decl),
9722               /* Else block.  */
9723               NULL_TREE);
9724   SET_EXPR_LOCATION (t, location);
9725   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
9726   
9727   /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16]; */
9728 #ifdef OBJCPLUS
9729   t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
9730                                 /* Parameters.  */
9731                                 tree_cons    /* &__objc_foreach_enum_state */
9732                                 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
9733                                  tree_cons   /* __objc_foreach_items  */
9734                                  (NULL_TREE, objc_foreach_items_decl,
9735                                   tree_cons  /* 16 */
9736                                   (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL);
9737 #else
9738   /* In C, we need to decay the __objc_foreach_items array that we are passing.  */
9739   {
9740     struct c_expr array;
9741     array.value = objc_foreach_items_decl;
9742     t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
9743                                   /* Parameters.  */
9744                                   tree_cons    /* &__objc_foreach_enum_state */
9745                                   (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
9746                                    tree_cons   /* __objc_foreach_items  */
9747                                    (NULL_TREE, default_function_array_conversion (location, array).value,
9748                                     tree_cons  /* 16 */
9749                                     (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL);
9750   }
9751 #endif
9752   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl, 
9753               convert (long_unsigned_type_node, t));
9754   SET_EXPR_LOCATION (t, location);
9755   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
9756
9757   /* } */
9758
9759   /* if (__objc_foreach_batchsize != 0) goto next_batch; */
9760   t = build3 (COND_EXPR, void_type_node, 
9761               /* Condition.  */
9762               c_fully_fold 
9763               (c_common_truthvalue_conversion 
9764                (location, 
9765                 build_binary_op (location,
9766                                  NE_EXPR, 
9767                                  objc_foreach_batchsize_decl,
9768                                  build_int_cst (long_unsigned_type_node, 0), 1)),
9769                false, NULL),
9770               /* Then block.  */
9771               build1 (GOTO_EXPR, void_type_node, next_batch_label_decl),
9772               /* Else block.  */
9773               NULL_TREE);
9774   SET_EXPR_LOCATION (t, location);
9775   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
9776
9777   /* <object expression> = nil; */
9778   t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
9779   SET_EXPR_LOCATION (t, location);
9780   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
9781
9782   /* break_label: */
9783   if (break_label)
9784     {
9785       t = build1 (LABEL_EXPR, void_type_node, break_label);
9786       SET_EXPR_LOCATION (t, location);
9787       append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
9788     }
9789
9790   /* } */
9791   COND_EXPR_ELSE (first_if) = first_else;
9792
9793   /* Do the whole thing.  */
9794   add_stmt (bind);
9795
9796 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
9797   /* This will print to stderr the whole blurb generated by the
9798      compiler while compiling (assuming the compiler doesn't crash
9799      before getting here).
9800    */
9801   debug_generic_stmt (bind);
9802 #endif
9803
9804   /* } */
9805   /* Done by c-parser.c  */
9806 }
9807
9808 /* --- SUPPORT FOR FORMAT ARG CHECKING --- */
9809 /* Return true if we have an NxString object pointer.  */
9810
9811 bool
9812 objc_string_ref_type_p (tree strp)
9813 {
9814   tree tmv;
9815   if (!strp || TREE_CODE (strp) != POINTER_TYPE)
9816     return false;
9817
9818   tmv = TYPE_MAIN_VARIANT (TREE_TYPE (strp));
9819   tmv = OBJC_TYPE_NAME (tmv);
9820   return (tmv
9821           && TREE_CODE (tmv) == IDENTIFIER_NODE
9822           && IDENTIFIER_POINTER (tmv)
9823           && !strncmp (IDENTIFIER_POINTER (tmv), "NSString", 8));
9824 }
9825
9826 /* At present the behavior of this is undefined and it does nothing.  */
9827 void
9828 objc_check_format_arg (tree ARG_UNUSED (format_arg), 
9829                        tree ARG_UNUSED (args_list))
9830 {
9831 }
9832
9833 /* --- Encode --- */
9834 /* "Encode" a data type into a string, which grows in util_obstack.
9835
9836    The format is described in gcc/doc/objc.texi, section 'Type
9837    encoding'.
9838
9839    Most of the encode_xxx functions have a 'type' argument, which is
9840    the type to encode, and an integer 'curtype' argument, which is the
9841    index in the encoding string of the beginning of the encoding of
9842    the current type, and allows you to find what characters have
9843    already been written for the current type (they are the ones in the
9844    current encoding string starting from 'curtype').
9845
9846    For example, if we are encoding a method which returns 'int' and
9847    takes a 'char **' argument, then when we get to the point of
9848    encoding the 'char **' argument, the encoded string already
9849    contains 'i12@0:4' (assuming a pointer size of 4 bytes).  So,
9850    'curtype' will be set to 7 when starting to encode 'char **'.
9851    During the whole of the encoding of 'char **', 'curtype' will be
9852    fixed at 7, so the routine encoding the second pointer can find out
9853    that it's actually encoding a pointer to a pointer by looking
9854    backwards at what has already been encoded for the current type,
9855    and seeing there is a "^" (meaning a pointer) in there.
9856 */
9857
9858
9859 /* Encode type qualifiers encodes one of the "PQ" Objective-C
9860    keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
9861    'const', instead, is encoded directly as part of the type.
9862  */
9863
9864 static void
9865 encode_type_qualifiers (tree declspecs)
9866 {
9867   tree spec;
9868
9869   for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
9870     {
9871       /* FIXME: Shouldn't we use token->keyword here ? */
9872       if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
9873         obstack_1grow (&util_obstack, 'n');
9874       else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
9875         obstack_1grow (&util_obstack, 'N');
9876       else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
9877         obstack_1grow (&util_obstack, 'o');
9878       else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
9879         obstack_1grow (&util_obstack, 'O');
9880       else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
9881         obstack_1grow (&util_obstack, 'R');
9882       else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
9883         obstack_1grow (&util_obstack, 'V');
9884       else
9885         gcc_unreachable ();
9886     }
9887 }
9888
9889 /* Determine if a pointee is marked read-only.  Only used by the NeXT
9890    runtime to be compatible with gcc-3.3.  */
9891
9892 static bool
9893 pointee_is_readonly (tree pointee)
9894 {
9895   while (POINTER_TYPE_P (pointee))
9896     pointee = TREE_TYPE (pointee);
9897
9898   return TYPE_READONLY (pointee);
9899 }
9900
9901 /* Encode a pointer type.  */
9902
9903 static void
9904 encode_pointer (tree type, int curtype, int format)
9905 {
9906   tree pointer_to = TREE_TYPE (type);
9907
9908   if (flag_next_runtime)
9909     {
9910       /* This code is used to be compatible with gcc-3.3.  */
9911       /* For historical/compatibility reasons, the read-only qualifier
9912          of the pointee gets emitted _before_ the '^'.  The read-only
9913          qualifier of the pointer itself gets ignored, _unless_ we are
9914          looking at a typedef!  Also, do not emit the 'r' for anything
9915          but the outermost type!  */
9916       if (!generating_instance_variables
9917           && (obstack_object_size (&util_obstack) - curtype <= 1)
9918           && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
9919               ? TYPE_READONLY (type)
9920               : pointee_is_readonly (pointer_to)))
9921         obstack_1grow (&util_obstack, 'r');
9922     }
9923
9924   if (TREE_CODE (pointer_to) == RECORD_TYPE)
9925     {
9926       if (OBJC_TYPE_NAME (pointer_to)
9927           && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
9928         {
9929           const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
9930
9931           if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
9932             {
9933               obstack_1grow (&util_obstack, '@');
9934               return;
9935             }
9936           else if (TYPE_HAS_OBJC_INFO (pointer_to)
9937                    && TYPE_OBJC_INTERFACE (pointer_to))
9938             {
9939               if (generating_instance_variables)
9940                 {
9941                   obstack_1grow (&util_obstack, '@');
9942                   obstack_1grow (&util_obstack, '"');
9943                   obstack_grow (&util_obstack, name, strlen (name));
9944                   obstack_1grow (&util_obstack, '"');
9945                   return;
9946                 }
9947               else
9948                 {
9949                   obstack_1grow (&util_obstack, '@');
9950                   return;
9951                 }
9952             }
9953           else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
9954             {
9955               obstack_1grow (&util_obstack, '#');
9956               return;
9957             }
9958           else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
9959             {
9960               obstack_1grow (&util_obstack, ':');
9961               return;
9962             }
9963         }
9964     }
9965   else if (TREE_CODE (pointer_to) == INTEGER_TYPE
9966            && TYPE_MODE (pointer_to) == QImode)
9967     {
9968       tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
9969                   ? OBJC_TYPE_NAME (pointer_to)
9970                   : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
9971
9972       /* (BOOL *) are an exception and are encoded as ^c, while all
9973          other pointers to char are encoded as *.   */
9974       if (strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
9975         {
9976           if (!flag_next_runtime)
9977             {
9978               /* The NeXT runtime adds the 'r' before getting here.  */
9979
9980               /* It appears that "r*" means "const char *" rather than
9981                  "char *const".  "char *const" is encoded as "*",
9982                  which is identical to "char *", so the "const" is
9983                  unfortunately lost.  */                 
9984               if (TYPE_READONLY (pointer_to))
9985                 obstack_1grow (&util_obstack, 'r');
9986             }
9987
9988           obstack_1grow (&util_obstack, '*');
9989           return;
9990         }
9991     }
9992
9993   /* We have a normal pointer type that does not get special treatment.  */
9994   obstack_1grow (&util_obstack, '^');
9995   encode_type (pointer_to, curtype, format);
9996 }
9997
9998 static void
9999 encode_array (tree type, int curtype, int format)
10000 {
10001   tree an_int_cst = TYPE_SIZE (type);
10002   tree array_of = TREE_TYPE (type);
10003   char buffer[40];
10004   
10005   if (an_int_cst == NULL)
10006     {
10007       /* We are trying to encode an incomplete array.  An incomplete
10008          array is forbidden as part of an instance variable; but it
10009          may occur if the instance variable is a pointer to such an
10010          array.  */
10011
10012       /* So the only case in which an incomplete array could occur
10013          (without being pointed to) is if we are encoding the
10014          arguments or return value of a method.  In that case, an
10015          incomplete array argument or return value (eg,
10016          -(void)display: (char[])string) is treated like a pointer
10017          because that is how the compiler does the function call.  A
10018          special, more complicated case, is when the incomplete array
10019          is the last member of a struct (eg, if we are encoding
10020          "struct { unsigned long int a;double b[];}"), which is again
10021          part of a method argument/return value.  In that case, we
10022          really need to communicate to the runtime that there is an
10023          incomplete array (not a pointer!) there.  So, we detect that
10024          special case and encode it as a zero-length array.
10025
10026          Try to detect that we are part of a struct.  We do this by
10027          searching for '=' in the type encoding for the current type.
10028          NB: This hack assumes that you can't use '=' as part of a C
10029          identifier.
10030       */
10031       {
10032         char *enc = obstack_base (&util_obstack) + curtype;
10033         if (memchr (enc, '=', 
10034                     obstack_object_size (&util_obstack) - curtype) == NULL)
10035           {
10036             /* We are not inside a struct.  Encode the array as a
10037                pointer.  */
10038             encode_pointer (type, curtype, format);
10039             return;
10040           }
10041       }
10042
10043       /* Else, we are in a struct, and we encode it as a zero-length
10044          array.  */
10045       sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
10046     }
10047   else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
10048    sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
10049   else
10050     sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
10051              TREE_INT_CST_LOW (an_int_cst)
10052               / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
10053
10054   obstack_grow (&util_obstack, buffer, strlen (buffer));
10055   encode_type (array_of, curtype, format);
10056   obstack_1grow (&util_obstack, ']');
10057   return;
10058 }
10059
10060 /* Encode a vector.  The vector type is a GCC extension to C.  */
10061 static void
10062 encode_vector (tree type, int curtype, int format)
10063 {
10064   tree vector_of = TREE_TYPE (type);
10065   char buffer[40];
10066
10067   /* Vectors are like simple fixed-size arrays.  */
10068
10069   /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
10070      alignment of the vector, and <code> is the base type.  Eg, int
10071      __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
10072      assuming that the alignment is 32 bytes.  We include size and
10073      alignment in bytes so that the runtime does not have to have any
10074      knowledge of the actual types.
10075   */
10076   sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d",
10077            /* We want to compute the equivalent of sizeof (<vector>).
10078               Code inspired by c_sizeof_or_alignof_type.  */
10079            ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type)) 
10080              / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))),
10081            /* We want to compute the equivalent of __alignof__
10082               (<vector>).  Code inspired by
10083               c_sizeof_or_alignof_type.  */
10084            TYPE_ALIGN_UNIT (type));
10085   obstack_grow (&util_obstack, buffer, strlen (buffer));
10086   encode_type (vector_of, curtype, format);
10087   obstack_1grow (&util_obstack, ']');
10088   return;
10089 }
10090 \f
10091 static void
10092 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format)
10093 {
10094   tree field = TYPE_FIELDS (type);
10095
10096   for (; field; field = DECL_CHAIN (field))
10097     {
10098 #ifdef OBJCPLUS
10099       /* C++ static members, and things that are not field at all,
10100          should not appear in the encoding.  */
10101       if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
10102         continue;
10103 #endif
10104
10105       /* Recursively encode fields of embedded base classes.  */
10106       if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
10107           && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
10108         {
10109           encode_aggregate_fields (TREE_TYPE (field),
10110                                    pointed_to, curtype, format);
10111           continue;
10112         }
10113
10114       if (generating_instance_variables && !pointed_to)
10115         {
10116           tree fname = DECL_NAME (field);
10117
10118           obstack_1grow (&util_obstack, '"');
10119
10120           if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
10121             obstack_grow (&util_obstack,
10122                           IDENTIFIER_POINTER (fname),
10123                           strlen (IDENTIFIER_POINTER (fname)));
10124
10125           obstack_1grow (&util_obstack, '"');
10126         }
10127
10128       encode_field_decl (field, curtype, format);
10129     }
10130 }
10131
10132 static void
10133 encode_aggregate_within (tree type, int curtype, int format, int left,
10134                          int right)
10135 {
10136   tree name;
10137   /* NB: aggregates that are pointed to have slightly different encoding
10138      rules in that you never encode the names of instance variables.  */
10139   int ob_size = obstack_object_size (&util_obstack);
10140   bool inline_contents = false;
10141   bool pointed_to = false;
10142
10143   if (flag_next_runtime)
10144     {
10145       if (ob_size > 0  &&  *(obstack_next_free (&util_obstack) - 1) == '^')
10146         pointed_to = true;
10147
10148       if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
10149           && (!pointed_to || ob_size - curtype == 1
10150               || (ob_size - curtype == 2
10151                   && *(obstack_next_free (&util_obstack) - 2) == 'r')))
10152         inline_contents = true;
10153     }
10154   else
10155     {
10156       /* c0 and c1 are the last two characters in the encoding of the
10157          current type; if the last two characters were '^' or '^r',
10158          then we are encoding an aggregate that is "pointed to".  The
10159          comment above applies: in that case we should avoid encoding
10160          the names of instance variables.
10161       */
10162       char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
10163       char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
10164       
10165       if (c0 == '^' || (c1 == '^' && c0 == 'r'))
10166         pointed_to = true;
10167       
10168       if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
10169         {
10170           if (!pointed_to)
10171             inline_contents = true;
10172           else
10173             {
10174               /* Note that the check (ob_size - curtype < 2) prevents
10175                  infinite recursion when encoding a structure which is
10176                  a linked list (eg, struct node { struct node *next;
10177                  }).  Each time we follow a pointer, we add one
10178                  character to ob_size, and curtype is fixed, so after
10179                  at most two pointers we stop inlining contents and
10180                  break the loop.
10181
10182                  The other case where we don't inline is "^r", which
10183                  is a pointer to a constant struct.
10184               */
10185               if ((ob_size - curtype <= 2) && !(c0 == 'r'))
10186                 inline_contents = true;
10187             }
10188         }
10189     }
10190
10191   /* Traverse struct aliases; it is important to get the
10192      original struct and its tag name (if any).  */
10193   type = TYPE_MAIN_VARIANT (type);
10194   name = OBJC_TYPE_NAME (type);
10195   /* Open parenth/bracket.  */
10196   obstack_1grow (&util_obstack, left);
10197
10198   /* Encode the struct/union tag name, or '?' if a tag was
10199      not provided.  Typedef aliases do not qualify.  */
10200 #ifdef OBJCPLUS
10201   /* For compatibility with the NeXT runtime, ObjC++ encodes template
10202      args as a composite struct tag name. */
10203   if (name && TREE_CODE (name) == IDENTIFIER_NODE
10204       /* Did this struct have a tag?  */
10205       && !TYPE_WAS_ANONYMOUS (type))
10206     obstack_grow (&util_obstack,
10207                   decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
10208                   strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
10209 #else
10210   if (name && TREE_CODE (name) == IDENTIFIER_NODE)
10211     obstack_grow (&util_obstack,
10212                   IDENTIFIER_POINTER (name),
10213                   strlen (IDENTIFIER_POINTER (name)));
10214 #endif
10215   else
10216     obstack_1grow (&util_obstack, '?');
10217
10218   /* Encode the types (and possibly names) of the inner fields,
10219      if required.  */
10220   if (inline_contents)
10221     {
10222       obstack_1grow (&util_obstack, '=');
10223       encode_aggregate_fields (type, pointed_to, curtype, format);
10224     }
10225   /* Close parenth/bracket.  */
10226   obstack_1grow (&util_obstack, right);
10227 }
10228
10229 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
10230    field type.  */
10231
10232 static void
10233 encode_next_bitfield (int width)
10234 {
10235   char buffer[40];
10236   sprintf (buffer, "b%d", width);
10237   obstack_grow (&util_obstack, buffer, strlen (buffer));
10238 }
10239
10240 /* Encodes 'type', ignoring type qualifiers (which you should encode
10241    beforehand if needed) with the exception of 'const', which is
10242    encoded by encode_type.  See above for the explanation of
10243    'curtype'.  'format' can be OBJC_ENCODE_INLINE_DEFS or
10244    OBJC_ENCODE_DONT_INLINE_DEFS.
10245 */
10246 static void
10247 encode_type (tree type, int curtype, int format)
10248 {
10249   enum tree_code code = TREE_CODE (type);
10250
10251   /* Ignore type qualifiers other than 'const' when encoding a
10252      type.  */
10253
10254   if (type == error_mark_node)
10255     return;
10256
10257   if (!flag_next_runtime)
10258     {
10259       if (TYPE_READONLY (type))
10260         obstack_1grow (&util_obstack, 'r');
10261     }
10262
10263   switch (code)
10264     {
10265     case ENUMERAL_TYPE:
10266       if (flag_next_runtime)
10267         {
10268           /* Kludge for backwards-compatibility with gcc-3.3: enums
10269              are always encoded as 'i' no matter what type they
10270              actually are (!).  */
10271           obstack_1grow (&util_obstack, 'i');
10272           break;
10273         }
10274       /* Else, they are encoded exactly like the integer type that is
10275          used by the compiler to store them.  */
10276     case INTEGER_TYPE:
10277       {
10278         char c;
10279         switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
10280           {
10281           case 8:  c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
10282           case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
10283           case 32:
10284             {
10285               tree int_type = type;
10286               if (flag_next_runtime)
10287                 {
10288                   /* Another legacy kludge for compatiblity with
10289                      gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
10290                      but not always.  For typedefs, we need to use 'i'
10291                      or 'I' instead if encoding a struct field, or a
10292                      pointer!  */
10293                   int_type =  ((!generating_instance_variables
10294                                 && (obstack_object_size (&util_obstack)
10295                                     == (unsigned) curtype))
10296                                ? TYPE_MAIN_VARIANT (type)
10297                                : type);
10298                 }
10299               if (int_type == long_unsigned_type_node
10300                   || int_type == long_integer_type_node)
10301                 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
10302               else
10303                 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
10304             }
10305             break;
10306           case 64:  c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
10307           case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
10308           default: gcc_unreachable ();
10309           }
10310         obstack_1grow (&util_obstack, c);
10311         break;
10312       }
10313     case REAL_TYPE:
10314       {
10315         char c;
10316         /* Floating point types.  */
10317         switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
10318           {
10319           case 32:  c = 'f'; break;
10320           case 64:  c = 'd'; break;
10321           case 96:
10322           case 128: c = 'D'; break;
10323           default: gcc_unreachable ();
10324           }
10325         obstack_1grow (&util_obstack, c);
10326         break;
10327       }
10328     case VOID_TYPE:
10329       obstack_1grow (&util_obstack, 'v');
10330       break;
10331
10332     case BOOLEAN_TYPE:
10333       obstack_1grow (&util_obstack, 'B');
10334       break;
10335
10336     case ARRAY_TYPE:
10337       encode_array (type, curtype, format);
10338       break;
10339
10340     case POINTER_TYPE:
10341 #ifdef OBJCPLUS
10342     case REFERENCE_TYPE:
10343 #endif
10344       encode_pointer (type, curtype, format);
10345       break;
10346
10347     case RECORD_TYPE:
10348       encode_aggregate_within (type, curtype, format, '{', '}');
10349       break;
10350
10351     case UNION_TYPE:
10352       encode_aggregate_within (type, curtype, format, '(', ')');
10353       break;
10354
10355     case FUNCTION_TYPE: /* '?' means an unknown type.  */
10356       obstack_1grow (&util_obstack, '?');
10357       break;
10358
10359     case COMPLEX_TYPE:
10360       /* A complex is encoded as 'j' followed by the inner type (eg,
10361          "_Complex int" is encoded as 'ji').  */
10362       obstack_1grow (&util_obstack, 'j');
10363       encode_type (TREE_TYPE (type), curtype, format);
10364       break;
10365
10366     case VECTOR_TYPE:
10367       encode_vector (type, curtype, format);
10368       break;
10369
10370     default:
10371       warning (0, "unknown type %s found during Objective-C encoding",
10372                gen_type_name (type));
10373       obstack_1grow (&util_obstack, '?');
10374       break;
10375     }
10376   
10377   if (flag_next_runtime)
10378     {
10379       /* Super-kludge.  Some ObjC qualifier and type combinations need
10380          to be rearranged for compatibility with gcc-3.3.  */
10381       if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
10382         {
10383           char *enc = obstack_base (&util_obstack) + curtype;
10384           
10385           /* Rewrite "in const" from "nr" to "rn".  */
10386           if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
10387             strncpy (enc - 1, "rn", 2);
10388         }
10389     }
10390 }
10391
10392 static void
10393 encode_gnu_bitfield (int position, tree type, int size)
10394 {
10395   enum tree_code code = TREE_CODE (type);
10396   char buffer[40];
10397   char charType = '?';
10398
10399   /* This code is only executed for the GNU runtime, so we can ignore
10400      the NeXT runtime kludge of always encoding enums as 'i' no matter
10401      what integers they actually are.  */
10402   if (code == INTEGER_TYPE  ||  code == ENUMERAL_TYPE)
10403     {
10404       if (integer_zerop (TYPE_MIN_VALUE (type)))
10405         /* Unsigned integer types.  */
10406         {
10407           switch (TYPE_MODE (type))
10408             {
10409             case QImode:
10410               charType = 'C'; break;
10411             case HImode:
10412               charType = 'S'; break;
10413             case SImode:
10414               {
10415                 if (type == long_unsigned_type_node)
10416                   charType = 'L';
10417                 else
10418                   charType = 'I';
10419                 break;
10420               }
10421             case DImode:
10422               charType = 'Q'; break;
10423             default:
10424               gcc_unreachable ();
10425             }
10426         }
10427       else
10428         /* Signed integer types.  */
10429         {
10430           switch (TYPE_MODE (type))
10431             {
10432             case QImode:
10433               charType = 'c'; break;
10434             case HImode:
10435               charType = 's'; break;
10436             case SImode:
10437               {
10438                 if (type == long_integer_type_node)
10439                   charType = 'l';
10440                 else
10441                   charType = 'i';
10442                 break;
10443               }
10444             case DImode:
10445               charType = 'q'; break;
10446             default:
10447               gcc_unreachable ();
10448             }
10449         }
10450     }
10451   else
10452     {
10453       /* Do not do any encoding, produce an error and keep going.  */
10454       error ("trying to encode non-integer type as a bitfield");
10455       return;
10456     }
10457
10458   sprintf (buffer, "b%d%c%d", position, charType, size);
10459   obstack_grow (&util_obstack, buffer, strlen (buffer));
10460 }
10461
10462 void
10463 encode_field_decl (tree field_decl, int curtype, int format)
10464 {
10465 #ifdef OBJCPLUS
10466   /* C++ static members, and things that are not fields at all,
10467      should not appear in the encoding.  */
10468   if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
10469     return;
10470 #endif
10471
10472   /* Generate the bitfield typing information, if needed.  Note the difference
10473      between GNU and NeXT runtimes.  */
10474   if (DECL_BIT_FIELD_TYPE (field_decl))
10475     {
10476       int size = tree_low_cst (DECL_SIZE (field_decl), 1);
10477
10478       if (flag_next_runtime)
10479         encode_next_bitfield (size);
10480       else
10481         encode_gnu_bitfield (int_bit_position (field_decl),
10482                              DECL_BIT_FIELD_TYPE (field_decl), size);
10483     }
10484   else
10485     encode_type (TREE_TYPE (field_decl), curtype, format);
10486 }
10487
10488 /* This routine encodes the attribute of the input PROPERTY according
10489    to following formula:
10490
10491    Property attributes are stored as a comma-delimited C string.
10492    Simple attributes such as readonly are encoded as single
10493    character. The parametrized attributes, getter=name and
10494    setter=name, are encoded as a single character followed by an
10495    identifier.  Property types are also encoded as a parametrized
10496    attribute.  The characters used to encode these attributes are
10497    defined by the following enumeration:
10498
10499    enum PropertyAttributes {
10500      kPropertyReadOnly = 'R',
10501      kPropertyBycopy = 'C',
10502      kPropertyByref = '&',
10503      kPropertyDynamic = 'D',
10504      kPropertyGetter = 'G',
10505      kPropertySetter = 'S',
10506      kPropertyInstanceVariable = 'V',
10507      kPropertyType = 'T',
10508      kPropertyWeak = 'W',
10509      kPropertyStrong = 'P',
10510      kPropertyNonAtomic = 'N'
10511    };  */
10512 tree
10513 objc_v2_encode_prop_attr (tree property)
10514 {
10515   const char *string;
10516   tree type = TREE_TYPE (property);
10517
10518   obstack_1grow (&util_obstack, 'T');
10519   encode_type (type, obstack_object_size (&util_obstack),
10520                OBJC_ENCODE_INLINE_DEFS);
10521
10522   if (PROPERTY_READONLY (property))
10523     obstack_grow (&util_obstack, ",R", 2);
10524
10525   switch (PROPERTY_ASSIGN_SEMANTICS (property))
10526     {
10527     case OBJC_PROPERTY_COPY:
10528       obstack_grow (&util_obstack, ",C", 2);
10529       break;
10530     case OBJC_PROPERTY_RETAIN:
10531       obstack_grow (&util_obstack, ",&", 2);
10532       break;
10533     case OBJC_PROPERTY_ASSIGN:
10534     default:
10535       break;
10536     }
10537
10538   if (PROPERTY_DYNAMIC (property))
10539     obstack_grow (&util_obstack, ",D", 2);    
10540
10541   if (PROPERTY_NONATOMIC (property))
10542     obstack_grow (&util_obstack, ",N", 2);
10543
10544   /* Here we want to encode the getter name, but only if it's not the
10545      standard one.  */
10546   if (PROPERTY_GETTER_NAME (property) != PROPERTY_NAME (property))
10547     {
10548       obstack_grow (&util_obstack, ",G", 2);
10549       string = IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property));
10550       obstack_grow (&util_obstack, string, strlen (string));
10551     }
10552
10553   if (!PROPERTY_READONLY (property))
10554     {
10555       /* Here we want to encode the setter name, but only if it's not
10556          the standard one.  */
10557       tree standard_setter = get_identifier (objc_build_property_setter_name (PROPERTY_NAME (property)));
10558       if (PROPERTY_SETTER_NAME (property) != standard_setter)
10559         {
10560           obstack_grow (&util_obstack, ",S", 2);
10561           string = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property));
10562           obstack_grow (&util_obstack, string, strlen (string));
10563         }
10564     }
10565
10566   /* TODO: Encode strong ('P'), weak ('W') for garbage collection.  */
10567
10568   if (!PROPERTY_DYNAMIC (property))
10569     {
10570       obstack_grow (&util_obstack, ",V", 2);
10571       if (PROPERTY_IVAR_NAME (property))
10572         string = IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property));
10573       else
10574         string = IDENTIFIER_POINTER (PROPERTY_NAME (property));
10575       obstack_grow (&util_obstack, string, strlen (string));
10576     }
10577
10578   /* NULL-terminate string.  */
10579   obstack_1grow (&util_obstack, 0);
10580   string = XOBFINISH (&util_obstack, char *);
10581   obstack_free (&util_obstack, util_firstobj);
10582   return get_identifier (string);
10583 }
10584
10585 #include "gt-objc-objc-act.h"