OSDN Git Service

PR c/46547
[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
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-pragma.h"
38 #include "c-family/c-format.h"
39 #include "flags.h"
40 #include "langhooks.h"
41 #include "objc-act.h"
42 #include "input.h"
43 #include "function.h"
44 #include "output.h"
45 #include "toplev.h"
46 #include "ggc.h"
47 #include "debug.h"
48 #include "target.h"
49 #include "diagnostic-core.h"
50 #include "intl.h"
51 #include "cgraph.h"
52 #include "tree-iterator.h"
53 #include "hashtab.h"
54 #include "langhooks-def.h"
55
56 /* For default_tree_printer ().  */
57 #include "tree-pretty-print.h"
58
59 /* For enum gimplify_status */
60 #include "gimple.h"
61
62 #define OBJC_VOID_AT_END        void_list_node
63
64 static unsigned int should_call_super_dealloc = 0;
65
66 /* When building Objective-C++, we are not linking against the C front-end
67    and so need to replicate the C tree-construction functions in some way.  */
68 #ifdef OBJCPLUS
69 #define OBJCP_REMAP_FUNCTIONS
70 #include "objcp-decl.h"
71 #endif  /* OBJCPLUS */
72
73 /* This is the default way of generating a method name.  */
74 /* This has the problem that "test_method:argument:" and
75    "test:method_argument:" will generate the same name
76    ("_i_Test__test_method_argument_" for an instance method of the
77    class "Test"), so you can't have them both in the same class!
78    Moreover, the demangling (going from
79    "_i_Test__test_method_argument" back to the original name) is
80    undefined because there are two correct ways of demangling the
81    name.  */
82 #ifndef OBJC_GEN_METHOD_LABEL
83 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
84   do {                                      \
85     char *temp;                             \
86     sprintf ((BUF), "_%s_%s_%s_%s",         \
87              ((IS_INST) ? "i" : "c"),       \
88              (CLASS_NAME),                  \
89              ((CAT_NAME)? (CAT_NAME) : ""), \
90              (SEL_NAME));                   \
91     for (temp = (BUF); *temp; temp++)       \
92       if (*temp == ':') *temp = '_';        \
93   } while (0)
94 #endif
95
96 /* These need specifying.  */
97 #ifndef OBJC_FORWARDING_STACK_OFFSET
98 #define OBJC_FORWARDING_STACK_OFFSET 0
99 #endif
100
101 #ifndef OBJC_FORWARDING_MIN_OFFSET
102 #define OBJC_FORWARDING_MIN_OFFSET 0
103 #endif
104 \f
105 /* Set up for use of obstacks.  */
106
107 #include "obstack.h"
108
109 /* This obstack is used to accumulate the encoding of a data type.  */
110 static struct obstack util_obstack;
111
112 /* This points to the beginning of obstack contents, so we can free
113    the whole contents.  */
114 char *util_firstobj;
115
116 /* The version identifies which language generation and runtime
117    the module (file) was compiled for, and is recorded in the
118    module descriptor.  */
119
120 #define OBJC_VERSION    (flag_next_runtime ? 6 : 8)
121 #define PROTOCOL_VERSION 2
122
123 /* (Decide if these can ever be validly changed.) */
124 #define OBJC_ENCODE_INLINE_DEFS         0
125 #define OBJC_ENCODE_DONT_INLINE_DEFS    1
126
127 /*** Private Interface (procedures) ***/
128
129 /* Used by compile_file.  */
130
131 static void init_objc (void);
132 static void finish_objc (void);
133
134 /* Code generation.  */
135
136 static tree objc_build_constructor (tree, VEC(constructor_elt,gc) *);
137 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
138 static tree get_proto_encoding (tree);
139 static tree lookup_interface (tree);
140 static tree objc_add_static_instance (tree, tree);
141
142 static tree start_class (enum tree_code, tree, tree, tree, tree);
143 static tree continue_class (tree);
144 static void finish_class (tree);
145 static void start_method_def (tree);
146 #ifdef OBJCPLUS
147 static void objc_start_function (tree, tree, tree, tree);
148 #else
149 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
150 #endif
151 static tree start_protocol (enum tree_code, tree, tree, tree);
152 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
153 static tree objc_add_method (tree, tree, int, bool);
154 static tree add_instance_variable (tree, objc_ivar_visibility_kind, tree);
155 static tree build_ivar_reference (tree);
156 static tree is_ivar (tree, tree);
157
158 static void build_objc_exception_stuff (void);
159 static void build_next_objc_exception_stuff (void);
160
161 /* We only need the following for ObjC; ObjC++ will use C++'s definition
162    of DERIVED_FROM_P.  */
163 #ifndef OBJCPLUS
164 static bool objc_derived_from_p (tree, tree);
165 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
166 #endif
167
168 /* Property.  */
169 static void objc_gen_property_data (tree, tree);
170 static void objc_synthesize_getter (tree, tree, tree);
171 static void objc_synthesize_setter (tree, tree, tree);
172 static char *objc_build_property_setter_name (tree);
173 static int match_proto_with_proto (tree, tree, int);
174 static tree lookup_property (tree, tree);
175 static tree lookup_property_in_list (tree, tree);
176 static tree lookup_property_in_protocol_list (tree, tree);
177 static void build_objc_property_accessor_helpers (void);
178
179 static void objc_xref_basetypes (tree, tree);
180
181 static void build_class_template (void);
182 static void build_selector_template (void);
183 static void build_category_template (void);
184 static void build_super_template (void);
185 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
186 static tree get_class_ivars (tree, bool);
187 static tree generate_protocol_list (tree);
188 static void build_protocol_reference (tree);
189
190 static void build_fast_enumeration_state_template (void);
191
192 #ifdef OBJCPLUS
193 static void objc_generate_cxx_cdtors (void);
194 #endif
195
196 /* objc attribute */
197 static void objc_decl_method_attributes (tree*, tree, int); 
198 static tree build_keyword_selector (tree);
199 static const char *synth_id_with_class_suffix (const char *, tree);
200
201 /* Hash tables to manage the global pool of method prototypes.  */
202
203 hash *nst_method_hash_list = 0;
204 hash *cls_method_hash_list = 0;
205
206 /* Hash tables to manage the global pool of class names.  */
207
208 hash *cls_name_hash_list = 0;
209 hash *als_name_hash_list = 0;
210
211 static void hash_class_name_enter (hash *, tree, tree);
212 static hash hash_class_name_lookup (hash *, tree);
213
214 static hash hash_lookup (hash *, tree);
215 static tree lookup_method (tree, tree);
216 static tree lookup_method_static (tree, tree, int);
217
218 static tree add_class (tree, tree);
219 static void add_category (tree, tree);
220 static inline tree lookup_category (tree, tree);
221
222 enum string_section
223 {
224   class_names,          /* class, category, protocol, module names */
225   meth_var_names,       /* method and variable names */
226   meth_var_types        /* method and variable type descriptors */
227 };
228
229 static tree add_objc_string (tree, enum string_section);
230 static void build_selector_table_decl (void);
231
232 /* Protocols.  */
233
234 static tree lookup_protocol (tree, bool);
235 static tree lookup_and_install_protocols (tree);
236
237 /* Type encoding.  */
238
239 static void encode_type_qualifiers (tree);
240 static void encode_type (tree, int, int);
241 static void encode_field_decl (tree, int, int);
242
243 #ifdef OBJCPLUS
244 static void really_start_method (tree, tree);
245 #else
246 static void really_start_method (tree, struct c_arg_info *);
247 #endif
248 static int comp_proto_with_proto (tree, tree, int);
249 static tree get_arg_type_list (tree, int, int);
250 static tree objc_decay_parm_type (tree);
251 static void objc_push_parm (tree);
252 #ifdef OBJCPLUS
253 static tree objc_get_parm_info (int);
254 #else
255 static struct c_arg_info *objc_get_parm_info (int);
256 #endif
257
258 /* Utilities for debugging and error diagnostics.  */
259
260 static char *gen_type_name (tree);
261 static char *gen_type_name_0 (tree);
262 static char *gen_method_decl (tree);
263 static char *gen_declaration (tree);
264
265 /* Everything else.  */
266
267 static tree create_field_decl (tree, const char *);
268 static void add_class_reference (tree);
269 static void build_protocol_template (void);
270 static tree encode_method_prototype (tree);
271 static void generate_classref_translation_entry (tree);
272 static void handle_class_ref (tree);
273 static void generate_struct_by_value_array (void)
274      ATTRIBUTE_NORETURN;
275 static void mark_referenced_methods (void);
276 static void generate_objc_image_info (void);
277 static bool objc_type_valid_for_messaging (tree type, bool allow_classes);
278
279 /*** Private Interface (data) ***/
280
281 /* Reserved tag definitions.  */
282
283 #define OBJECT_TYPEDEF_NAME             "id"
284 #define CLASS_TYPEDEF_NAME              "Class"
285
286 #define TAG_OBJECT                      "objc_object"
287 #define TAG_CLASS                       "objc_class"
288 #define TAG_SUPER                       "objc_super"
289 #define TAG_SELECTOR                    "objc_selector"
290
291 #define UTAG_CLASS                      "_objc_class"
292 #define UTAG_IVAR                       "_objc_ivar"
293 #define UTAG_IVAR_LIST                  "_objc_ivar_list"
294 #define UTAG_METHOD                     "_objc_method"
295 #define UTAG_METHOD_LIST                "_objc_method_list"
296 #define UTAG_CATEGORY                   "_objc_category"
297 #define UTAG_MODULE                     "_objc_module"
298 #define UTAG_SYMTAB                     "_objc_symtab"
299 #define UTAG_SUPER                      "_objc_super"
300 #define UTAG_SELECTOR                   "_objc_selector"
301
302 #define UTAG_PROTOCOL                   "_objc_protocol"
303 #define UTAG_METHOD_PROTOTYPE           "_objc_method_prototype"
304 #define UTAG_METHOD_PROTOTYPE_LIST      "_objc__method_prototype_list"
305
306 /* Note that the string object global name is only needed for the
307    NeXT runtime.  */
308 #define STRING_OBJECT_GLOBAL_FORMAT     "_%sClassReference"
309
310 #define PROTOCOL_OBJECT_CLASS_NAME      "Protocol"
311
312 #define TAG_ENUMERATION_MUTATION        "objc_enumerationMutation"
313 #define TAG_FAST_ENUMERATION_STATE      "__objcFastEnumerationState"
314
315 static const char *TAG_GETCLASS;
316 static const char *TAG_GETMETACLASS;
317 static const char *TAG_MSGSEND;
318 static const char *TAG_MSGSENDSUPER;
319 /* The NeXT Objective-C messenger may have two extra entry points, for use
320    when returning a structure. */
321 static const char *TAG_MSGSEND_STRET;
322 static const char *TAG_MSGSENDSUPER_STRET;
323 static const char *default_constant_string_class_name;
324
325 /* Runtime metadata flags.  */
326 #define CLS_FACTORY                     0x0001L
327 #define CLS_META                        0x0002L
328 #define CLS_HAS_CXX_STRUCTORS           0x2000L
329
330 #define OBJC_MODIFIER_STATIC            0x00000001
331 #define OBJC_MODIFIER_FINAL             0x00000002
332 #define OBJC_MODIFIER_PUBLIC            0x00000004
333 #define OBJC_MODIFIER_PRIVATE           0x00000008
334 #define OBJC_MODIFIER_PROTECTED         0x00000010
335 #define OBJC_MODIFIER_NATIVE            0x00000020
336 #define OBJC_MODIFIER_SYNCHRONIZED      0x00000040
337 #define OBJC_MODIFIER_ABSTRACT          0x00000080
338 #define OBJC_MODIFIER_VOLATILE          0x00000100
339 #define OBJC_MODIFIER_TRANSIENT         0x00000200
340 #define OBJC_MODIFIER_NONE_SPECIFIED    0x80000000
341
342 /* NeXT-specific tags.  */
343
344 #define TAG_MSGSEND_NONNIL              "objc_msgSendNonNil"
345 #define TAG_MSGSEND_NONNIL_STRET        "objc_msgSendNonNil_stret"
346 #define TAG_EXCEPTIONEXTRACT            "objc_exception_extract"
347 #define TAG_EXCEPTIONTRYENTER           "objc_exception_try_enter"
348 #define TAG_EXCEPTIONTRYEXIT            "objc_exception_try_exit"
349 #define TAG_EXCEPTIONMATCH              "objc_exception_match"
350 #define TAG_EXCEPTIONTHROW              "objc_exception_throw"
351 #define TAG_SYNCENTER                   "objc_sync_enter"
352 #define TAG_SYNCEXIT                    "objc_sync_exit"
353 #define TAG_SETJMP                      "_setjmp"
354 #define UTAG_EXCDATA                    "_objc_exception_data"
355
356 #define TAG_ASSIGNIVAR                  "objc_assign_ivar"
357 #define TAG_ASSIGNGLOBAL                "objc_assign_global"
358 #define TAG_ASSIGNSTRONGCAST            "objc_assign_strongCast"
359
360 /* Branch entry points.  All that matters here are the addresses;
361    functions with these names do not really exist in libobjc.  */
362
363 #define TAG_MSGSEND_FAST                "objc_msgSend_Fast"
364 #define TAG_ASSIGNIVAR_FAST             "objc_assign_ivar_Fast"
365
366 #define TAG_CXX_CONSTRUCT               ".cxx_construct"
367 #define TAG_CXX_DESTRUCT                ".cxx_destruct"
368
369 /* GNU-specific tags.  */
370
371 #define TAG_EXECCLASS                   "__objc_exec_class"
372 #define TAG_GNUINIT                     "__objc_gnu_init"
373
374 /* Flags for lookup_method_static().  */
375
376 /* Look for class methods.  */
377 #define OBJC_LOOKUP_CLASS       1
378 /* Do not examine superclasses.  */
379 #define OBJC_LOOKUP_NO_SUPER    2
380 /* Disable returning an instance method of a root class when a class
381    method can't be found.  */
382 #define OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS 4 
383
384 /* The OCTI_... enumeration itself is in objc/objc-act.h.  */
385 tree objc_global_trees[OCTI_MAX];
386
387 static void handle_impent (struct imp_entry *);
388
389 struct imp_entry *imp_list = 0;
390 int imp_count = 0;      /* `@implementation' */
391 int cat_count = 0;      /* `@category' */
392
393 objc_ivar_visibility_kind objc_ivar_visibility;
394
395 /* Use to generate method labels.  */
396 static int method_slot = 0;
397
398 /* Flag to say whether methods in a protocol are optional or
399    required.  */
400 static bool objc_method_optional_flag = false;
401
402 static int objc_collecting_ivars = 0;
403
404 #define BUFSIZE         1024
405
406 static char *errbuf;    /* Buffer for error diagnostics */
407
408 /* Data imported from tree.c.  */
409
410 extern enum debug_info_type write_symbols;
411
412 \f
413 static int flag_typed_selectors;
414
415 /* Store all constructed constant strings in a hash table so that
416    they get uniqued properly.  */
417
418 struct GTY(()) string_descriptor {
419   /* The literal argument .  */
420   tree literal;
421
422   /* The resulting constant string.  */
423   tree constructor;
424 };
425
426 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
427
428 FILE *gen_declaration_file;
429
430 /* Tells "encode_pointer/encode_aggregate" whether we are generating
431    type descriptors for instance variables (as opposed to methods).
432    Type descriptors for instance variables contain more information
433    than methods (for static typing and embedded structures).  */
434
435 static int generating_instance_variables = 0;
436
437 /* For building an objc struct.  These may not be used when this file
438    is compiled as part of obj-c++.  */
439
440 static bool objc_building_struct;
441 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
442
443 /* Start building a struct for objc.  */
444
445 static tree
446 objc_start_struct (tree name)
447 {
448   gcc_assert (!objc_building_struct);
449   objc_building_struct = true;
450   return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
451 }
452
453 /* Finish building a struct for objc.  */
454
455 static tree
456 objc_finish_struct (tree type, tree fieldlist)
457 {
458   gcc_assert (objc_building_struct);
459   objc_building_struct = false;
460   return finish_struct (input_location, type, fieldlist, NULL_TREE,
461                         objc_struct_info);
462 }
463
464 static tree
465 build_sized_array_type (tree base_type, int size)
466 {
467   tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
468   return build_array_type (base_type, index_type);
469 }
470
471 static tree
472 add_field_decl (tree type, const char *name, tree **chain)
473 {
474   tree field = create_field_decl (type, name);
475
476   if (*chain != NULL)
477     **chain = field;
478   *chain = &DECL_CHAIN (field);
479
480   return field;
481 }
482
483 /* Create a temporary variable of type 'type'.  If 'name' is set, uses
484    the specified name, else use no name.  Returns the declaration of
485    the type.  The 'name' is mostly useful for debugging.
486 */
487 static tree
488 objc_create_temporary_var (tree type, const char *name)
489 {
490   tree decl;
491
492   if (name != NULL)
493     {
494       decl = build_decl (input_location,
495                          VAR_DECL, get_identifier (name), type);
496     }
497   else
498     {
499       decl = build_decl (input_location,
500                          VAR_DECL, NULL_TREE, type);
501     }
502   TREE_USED (decl) = 1;
503   DECL_ARTIFICIAL (decl) = 1;
504   DECL_IGNORED_P (decl) = 1;
505   DECL_CONTEXT (decl) = current_function_decl;
506
507   return decl;
508 }
509
510 /* Some platforms pass small structures through registers versus
511    through an invisible pointer.  Determine at what size structure is
512    the transition point between the two possibilities.  */
513
514 static void
515 generate_struct_by_value_array (void)
516 {
517   tree type;
518   tree decls;
519   int i, j;
520   int aggregate_in_mem[32];
521   int found = 0;
522
523   /* Presumably no platform passes 32 byte structures in a register.  */
524   for (i = 1; i < 32; i++)
525     {
526       char buffer[5];
527       tree *chain = NULL;
528
529       /* Create an unnamed struct that has `i' character components */
530       type = objc_start_struct (NULL_TREE);
531
532       strcpy (buffer, "c1");
533       decls = add_field_decl (char_type_node, buffer, &chain);
534
535       for (j = 1; j < i; j++)
536         {
537           sprintf (buffer, "c%d", j + 1);
538           add_field_decl (char_type_node, buffer, &chain);
539         }
540       objc_finish_struct (type, decls);
541
542       aggregate_in_mem[i] = aggregate_value_p (type, 0);
543       if (!aggregate_in_mem[i])
544         found = 1;
545     }
546
547   /* We found some structures that are returned in registers instead of memory
548      so output the necessary data.  */
549   if (found)
550     {
551       for (i = 31; i >= 0;  i--)
552         if (!aggregate_in_mem[i])
553           break;
554       printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
555
556       /* The first member of the structure is always 0 because we don't handle
557          structures with 0 members */
558       printf ("static int struct_forward_array[] = {\n  0");
559
560       for (j = 1; j <= i; j++)
561         printf (", %d", aggregate_in_mem[j]);
562       printf ("\n};\n");
563     }
564
565   exit (0);
566 }
567
568 bool
569 objc_init (void)
570 {
571 #ifdef OBJCPLUS
572   if (cxx_init () == false)
573 #else
574   if (c_objc_common_init () == false)
575 #endif
576     return false;
577
578   /* If gen_declaration desired, open the output file.  */
579   if (flag_gen_declaration)
580     {
581       register char * const dumpname = concat (dump_base_name, ".decl", NULL);
582       gen_declaration_file = fopen (dumpname, "w");
583       if (gen_declaration_file == 0)
584         fatal_error ("can%'t open %s: %m", dumpname);
585       free (dumpname);
586     }
587
588   if (flag_next_runtime)
589     {
590       TAG_GETCLASS = "objc_getClass";
591       TAG_GETMETACLASS = "objc_getMetaClass";
592       TAG_MSGSEND = "objc_msgSend";
593       TAG_MSGSENDSUPER = "objc_msgSendSuper";
594       TAG_MSGSEND_STRET = "objc_msgSend_stret";
595       TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
596       default_constant_string_class_name = "NSConstantString";
597     }
598   else
599     {
600       TAG_GETCLASS = "objc_get_class";
601       TAG_GETMETACLASS = "objc_get_meta_class";
602       TAG_MSGSEND = "objc_msg_lookup";
603       TAG_MSGSENDSUPER = "objc_msg_lookup_super";
604       /* GNU runtime does not provide special functions to support
605          structure-returning methods.  */
606       default_constant_string_class_name = "NXConstantString";
607       flag_typed_selectors = 1;
608       /* GNU runtime does not need the compiler to change code
609          in order to do GC. */
610       if (flag_objc_gc)
611         {
612           warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
613           flag_objc_gc=0;
614         }
615     }
616
617   init_objc ();
618
619   if (print_struct_values && !flag_compare_debug)
620     generate_struct_by_value_array ();
621
622   return true;
623 }
624
625 /* This is called automatically (at the very end of compilation) by
626    c_write_global_declarations and cp_write_global_declarations.  */
627 void
628 objc_write_global_declarations (void)
629 {
630   mark_referenced_methods ();
631
632   /* Finalize Objective-C runtime data.  */
633   finish_objc ();
634
635   if (gen_declaration_file)
636     fclose (gen_declaration_file);
637 }
638 \f
639 /* Return the first occurrence of a method declaration corresponding
640    to sel_name in rproto_list.  Search rproto_list recursively.
641    If is_class is 0, search for instance methods, otherwise for class
642    methods.  */
643 static tree
644 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
645                                 int is_class)
646 {
647   tree rproto, p, m;
648
649    for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
650      {
651        p = TREE_VALUE (rproto);
652        m = NULL_TREE;
653
654         if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
655           {
656             /* First, search the @required protocol methods.  */
657             if (is_class)
658               m = lookup_method (PROTOCOL_CLS_METHODS (p),  sel_name);
659             else
660               m = lookup_method (PROTOCOL_NST_METHODS (p), sel_name);
661
662             if (m)
663               return m;
664
665             /* If still not found, search the @optional protocol methods.  */
666             if (is_class)
667               m = lookup_method (PROTOCOL_OPTIONAL_CLS_METHODS (p), sel_name);
668             else
669               m = lookup_method (PROTOCOL_OPTIONAL_NST_METHODS (p), sel_name);
670
671             if (m)
672               return m;
673
674             /* If still not found, search the attached protocols.  */
675             if (PROTOCOL_LIST (p))
676               m = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
677                                                   sel_name, is_class);
678             if (m)
679               return m;
680           }
681         else
682           {
683             ; /* An identifier...if we could not find a protocol.  */
684           }
685      }
686
687    return 0;
688 }
689
690 static tree
691 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
692 {
693   tree rproto, p;
694
695   /* Make sure the protocol is supported by the object on the rhs.  */
696   if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
697     {
698       tree fnd = 0;
699       for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
700         {
701           p = TREE_VALUE (rproto);
702
703           if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
704             {
705               if (lproto == p)
706                 fnd = lproto;
707
708               else if (PROTOCOL_LIST (p))
709                 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
710             }
711
712           if (fnd)
713             return fnd;
714         }
715     }
716   else
717     {
718       ; /* An identifier...if we could not find a protocol.  */
719     }
720
721   return 0;
722 }
723
724 void
725 objc_start_class_interface (tree klass, tree super_class,
726                             tree protos, tree attributes)
727 {
728   if (flag_objc1_only && attributes)
729     error_at (input_location, "class attributes are not available in Objective-C 1.0"); 
730
731   objc_interface_context
732     = objc_ivar_context
733     = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos, attributes);
734   objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
735 }
736
737 void
738 objc_start_category_interface (tree klass, tree categ,
739                                tree protos, tree attributes)
740 {
741   if (attributes)
742     {
743       if (flag_objc1_only)
744         error_at (input_location, "category attributes are not available in Objective-C 1.0");
745       else
746         warning_at (input_location, OPT_Wattributes, 
747                     "category attributes are not available in this version"
748                     " of the compiler, (ignored)");
749     }
750   objc_interface_context
751     = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos, NULL_TREE);
752   objc_ivar_chain
753     = continue_class (objc_interface_context);
754 }
755
756 void
757 objc_start_protocol (tree name, tree protos, tree attributes)
758 {
759   if (flag_objc1_only && attributes)
760     error_at (input_location, "protocol attributes are not available in Objective-C 1.0");      
761
762   objc_interface_context
763     = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos, attributes);
764   objc_method_optional_flag = false;
765 }
766
767 void
768 objc_continue_interface (void)
769 {
770   objc_ivar_chain
771     = continue_class (objc_interface_context);
772 }
773
774 void
775 objc_finish_interface (void)
776 {
777   finish_class (objc_interface_context);
778   objc_interface_context = NULL_TREE;
779   objc_method_optional_flag = false;
780 }
781
782 void
783 objc_start_class_implementation (tree klass, tree super_class)
784 {
785   objc_implementation_context
786     = objc_ivar_context
787     = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE,
788                    NULL_TREE);
789   objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
790 }
791
792 void
793 objc_start_category_implementation (tree klass, tree categ)
794 {
795   objc_implementation_context
796     = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE,
797                    NULL_TREE);
798   objc_ivar_chain
799     = continue_class (objc_implementation_context);
800 }
801
802 void
803 objc_continue_implementation (void)
804 {
805   objc_ivar_chain
806     = continue_class (objc_implementation_context);
807 }
808
809 void
810 objc_finish_implementation (void)
811 {
812 #ifdef OBJCPLUS
813   if (flag_objc_call_cxx_cdtors)
814     objc_generate_cxx_cdtors ();
815 #endif
816
817   if (objc_implementation_context)
818     {
819       finish_class (objc_implementation_context);
820       objc_ivar_chain = NULL_TREE;
821       objc_implementation_context = NULL_TREE;
822     }
823   else
824     warning (0, "%<@end%> must appear in an @implementation context");
825 }
826
827 void
828 objc_set_visibility (objc_ivar_visibility_kind visibility)
829 {
830   if (visibility == OBJC_IVAR_VIS_PACKAGE)
831     {
832       if (flag_objc1_only)
833         error ("%<@package%> is not available in Objective-C 1.0");
834       else
835         warning (0, "%<@package%> presently has the same effect as %<@public%>");
836     }
837   objc_ivar_visibility = visibility;
838 }
839
840 void
841 objc_set_method_opt (bool optional)
842 {
843   if (flag_objc1_only)
844     error_at (input_location, "@optional/@required are not available in Objective-C 1.0");      
845
846   objc_method_optional_flag = optional;
847   if (!objc_interface_context 
848       || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
849     {
850       error ("@optional/@required is allowed in @protocol context only");
851       objc_method_optional_flag = false;
852     }
853 }
854
855 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
856    PROTOCOL.  */
857 static tree
858 lookup_property_in_list (tree chain, tree property)
859 {
860   tree x;
861   for (x = CLASS_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
862     if (PROPERTY_NAME (x) == property)
863       return x;
864   return NULL_TREE;
865 }
866
867 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
868 static tree lookup_property_in_protocol_list (tree rproto_list, tree property)
869 {
870   tree rproto, x;
871   for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
872     {
873       tree p = TREE_VALUE (rproto);
874       if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
875         {
876           if ((x = lookup_property_in_list (p, property)))
877             return x;
878           if (PROTOCOL_LIST (p))
879             return lookup_property_in_protocol_list (PROTOCOL_LIST (p), property);
880         }
881       else
882         {
883           ; /* An identifier...if we could not find a protocol.  */
884         }
885     }
886   return NULL_TREE;
887 }
888
889 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
890    chain of interface hierarchy.  */
891 static tree
892 lookup_property (tree interface_type, tree property)
893 {
894   tree inter = interface_type;
895   while (inter)
896     {
897       tree x, category;
898       if ((x = lookup_property_in_list (inter, property)))
899         return x;
900       /* Failing that, look for the property in each category of the class.  */
901       category = inter;
902       while ((category = CLASS_CATEGORY_LIST (category)))
903         {
904           if ((x = lookup_property_in_list (category, property)))
905             return x;
906
907           /* When checking a category, also check the protocols
908              attached with the category itself.  */
909           if (CLASS_PROTOCOL_LIST (category)
910               && (x = lookup_property_in_protocol_list
911                   (CLASS_PROTOCOL_LIST (category), property)))
912             return x;
913         }
914
915       /*  Failing to find in categories, look for property in protocol list. */
916       if (CLASS_PROTOCOL_LIST (inter) 
917           && (x = lookup_property_in_protocol_list
918               (CLASS_PROTOCOL_LIST (inter), property)))
919         return x;
920       
921       /* Failing that, climb up the inheritance hierarchy.  */
922       inter = lookup_interface (CLASS_SUPER_NAME (inter));
923     }
924   return inter;
925 }
926
927 /* This routine is called by the parser when a
928    @property... declaration is found.  'decl' is the declaration of
929    the property (type/identifier), and the other arguments represent
930    property attributes that may have been specified in the Objective-C
931    declaration.  'parsed_property_readonly' is 'true' if the attribute
932    'readonly' was specified, and 'false' if not; similarly for the
933    other bool parameters.  'parsed_property_getter_ident' is NULL_TREE
934    if the attribute 'getter' was not specified, and is the identifier
935    corresponding to the specified getter if it was; similarly for
936    'parsed_property_setter_ident'.  */
937 void
938 objc_add_property_declaration (location_t location, tree decl,
939                                bool parsed_property_readonly, bool parsed_property_readwrite,
940                                bool parsed_property_assign, bool parsed_property_retain,
941                                bool parsed_property_copy, bool parsed_property_nonatomic,
942                                tree parsed_property_getter_ident, tree parsed_property_setter_ident)
943 {
944   tree property_decl;
945   tree x;
946   /* 'property_readonly' and 'property_assign_semantics' are the final
947      attributes of the property after all parsed attributes have been
948      considered (eg, if we parsed no 'readonly' and no 'readwrite', ie
949      parsed_property_readonly = false and parsed_property_readwrite =
950      false, then property_readonly will be false because the default
951      is readwrite).  */
952   bool property_readonly = false;
953   objc_property_assign_semantics property_assign_semantics = OBJC_PROPERTY_ASSIGN;
954
955   if (flag_objc1_only)
956     error_at (input_location, "%<@property%> is not available in Objective-C 1.0");
957
958   if (parsed_property_readonly && parsed_property_readwrite)
959     {
960       error_at (location, "%<readonly%> attribute conflicts with %<readwrite%> attribute");
961       /* In case of conflicting attributes (here and below), after
962          producing an error, we pick one of the attributes and keep
963          going.  */
964       property_readonly = false;
965     }
966   else
967     {
968       if (parsed_property_readonly)
969         property_readonly = true;
970   
971       if (parsed_property_readwrite)
972         property_readonly = false;
973     }
974
975   if (parsed_property_readonly && parsed_property_setter_ident)
976     {
977       error_at (location, "%<readonly%> attribute conflicts with %<setter%> attribute");
978       property_readonly = false;
979     }
980
981   if (parsed_property_assign && parsed_property_retain)
982     {
983       error_at (location, "%<assign%> attribute conflicts with %<retain%> attribute");
984       property_assign_semantics = OBJC_PROPERTY_RETAIN;
985     }
986   else if (parsed_property_assign && parsed_property_copy)
987     {
988       error_at (location, "%<assign%> attribute conflicts with %<copy%> attribute");
989       property_assign_semantics = OBJC_PROPERTY_COPY;
990     }
991   else if (parsed_property_retain && parsed_property_copy)
992     {
993       error_at (location, "%<retain%> attribute conflicts with %<copy%> attribute");
994       property_assign_semantics = OBJC_PROPERTY_COPY;
995     }
996   else
997     {
998       if (parsed_property_assign)
999         property_assign_semantics = OBJC_PROPERTY_ASSIGN;
1000
1001       if (parsed_property_retain)
1002         property_assign_semantics = OBJC_PROPERTY_RETAIN;
1003
1004       if (parsed_property_copy)
1005         property_assign_semantics = OBJC_PROPERTY_COPY;
1006     }
1007
1008   if (!objc_interface_context)
1009     {
1010       error_at (location, "property declaration not in @interface or @protocol context");
1011       return;
1012     }
1013
1014   /* At this point we know that we are either in an interface, a
1015      category, or a protocol.  */
1016
1017   /* We expect a FIELD_DECL from the parser.  Make sure we didn't get
1018      something else, as that would confuse the checks below.  */
1019   if (TREE_CODE (decl) != FIELD_DECL)
1020     {
1021       error_at (location, "invalid property declaration");
1022       return;      
1023     }
1024
1025   /* Do some spot-checks for the most obvious invalid types.  */
1026
1027   if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1028     {
1029       error_at (location, "property can not be an array");
1030       return;
1031     }
1032
1033   /* The C++/ObjC++ parser seems to reject the ':' for a bitfield when
1034      parsing, while the C/ObjC parser accepts it and gives us a
1035      FIELD_DECL with a DECL_INITIAL set.  So we use the DECL_INITIAL
1036      to check for a bitfield when doing ObjC.  */
1037 #ifndef OBJCPLUS
1038   if (DECL_INITIAL (decl))
1039     {
1040       /* A @property is not an actual variable, but it is a way to
1041          describe a pair of accessor methods, so its type (which is
1042          the type of the return value of the getter and the first
1043          argument of the setter) can't be a bitfield (as return values
1044          and arguments of functions can not be bitfields).  The
1045          underlying instance variable could be a bitfield, but that is
1046          a different matter.  */
1047       error_at (location, "property can not be a bit-field");
1048       return;      
1049     }
1050 #endif
1051
1052   /* TODO: Check that the property type is an Objective-C object or a
1053      "POD".  */
1054
1055   /* Implement -Wproperty-assign-default (which is enabled by default).  */
1056   if (warn_property_assign_default
1057       /* If garbage collection is not being used, then 'assign' is
1058          valid for objects (and typically used for delegates) but it
1059          is wrong in most cases (since most objects need to be
1060          retained or copied in setters).  Warn users when 'assign' is
1061          used implicitly.  */
1062       && property_assign_semantics == OBJC_PROPERTY_ASSIGN
1063       /* Read-only properties are never assigned, so the assignment
1064          semantics do not matter in that case.  */
1065       && !property_readonly
1066       && !flag_objc_gc)
1067     {
1068       /* Please note that it would make sense to default to 'assign'
1069          for non-{Objective-C objects}, and to 'retain' for
1070          Objective-C objects.  But that would break compatibility with
1071          other compilers.  */
1072       if (!parsed_property_assign && !parsed_property_retain && !parsed_property_copy)
1073         {
1074           /* Use 'false' so we do not warn for Class objects.  */
1075           if (objc_type_valid_for_messaging (TREE_TYPE (decl), false))
1076             {
1077               warning_at (location, 
1078                           0,
1079                           "object property %qD has no %<assign%>, %<retain%> or %<copy%> attribute; assuming %<assign%>", 
1080                           decl);
1081               inform (location, 
1082                       "%<assign%> can be unsafe for Objective-C objects; please state explicitly if you need it");
1083             }
1084         }
1085     }
1086   
1087   if (property_assign_semantics == OBJC_PROPERTY_RETAIN
1088       && !objc_type_valid_for_messaging (TREE_TYPE (decl), true))
1089     error_at (location, "%<retain%> attribute is only valid for Objective-C objects");
1090   
1091   if (property_assign_semantics == OBJC_PROPERTY_COPY
1092       && !objc_type_valid_for_messaging (TREE_TYPE (decl), true))
1093     error_at (location, "%<copy%> attribute is only valid for Objective-C objects");
1094
1095   /* Now determine the final property getter and setter names.  They
1096      will be stored in the PROPERTY_DECL, from which they'll always be
1097      extracted and used.  */
1098
1099   /* Adjust, or fill in, setter and getter names.  We overwrite the
1100      parsed_property_setter_ident and parsed_property_getter_ident
1101      with the final setter and getter identifiers that will be
1102      used.  */
1103   if (parsed_property_setter_ident)
1104     {
1105       /* The setter should be terminated by ':', but the parser only
1106          gives us an identifier without ':'.  So, we need to add ':'
1107          at the end.  */
1108       const char *parsed_setter = IDENTIFIER_POINTER (parsed_property_setter_ident);
1109       size_t length = strlen (parsed_setter);
1110       char *final_setter = (char *)alloca (length + 2);
1111
1112       sprintf (final_setter, "%s:", parsed_setter);
1113       parsed_property_setter_ident = get_identifier (final_setter);
1114     }
1115   else
1116     {
1117       if (!property_readonly)
1118         parsed_property_setter_ident = get_identifier (objc_build_property_setter_name 
1119                                                        (DECL_NAME (decl)));
1120     }
1121
1122   if (!parsed_property_getter_ident)
1123     parsed_property_getter_ident = DECL_NAME (decl);
1124
1125   /* Check for duplicate property declarations.  We first check the
1126      immediate context for a property with the same name.  Any such
1127      declarations are an error.  */
1128   for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
1129     {
1130       if (PROPERTY_NAME (x) == DECL_NAME (decl))
1131         {
1132           location_t original_location = DECL_SOURCE_LOCATION (x);
1133           
1134           error_at (location, "redeclaration of property %qD", decl);
1135
1136           if (original_location != UNKNOWN_LOCATION)
1137             inform (original_location, "originally specified here");
1138           return;
1139       }
1140     }
1141
1142   /* We now need to check for existing property declarations (in the
1143      superclass, other categories or protocols) and check that the new
1144      declaration is not in conflict with existing ones.  */
1145
1146   /* Search for a previous, existing declaration of a property with
1147      the same name in superclasses, protocols etc.  If one is found,
1148      it will be in the 'x' variable.  */
1149   x = NULL_TREE;
1150
1151   /* Note that, for simplicity, the following may search again the
1152      local context.  That's Ok as nothing will be found (else we'd
1153      have thrown an error above); it's only a little inefficient, but
1154      the code is simpler.  */
1155   switch (TREE_CODE (objc_interface_context))
1156     {
1157     case CLASS_INTERFACE_TYPE:
1158       /* Look up the property in the current @interface (which will
1159          find nothing), then its protocols and categories and
1160          superclasses.  */
1161       x = lookup_property (objc_interface_context, DECL_NAME (decl));
1162       break;
1163     case CATEGORY_INTERFACE_TYPE:
1164       /* Look up the property in the main @interface, then protocols
1165          and categories (one of them is ours, and will find nothing)
1166          and superclasses.  */
1167       x = lookup_property (lookup_interface (CLASS_NAME (objc_interface_context)),
1168                            DECL_NAME (decl));
1169       break;
1170     case PROTOCOL_INTERFACE_TYPE:
1171       /* Looks up the property in any protocols attached to the
1172          current protocol.  */
1173       if (PROTOCOL_LIST (objc_interface_context))
1174         {
1175           x = lookup_property_in_protocol_list (PROTOCOL_LIST (objc_interface_context),
1176                                                 DECL_NAME (decl));
1177         }
1178       break;
1179     default:
1180       gcc_unreachable ();
1181     }
1182
1183   if (x != NULL_TREE)
1184     {
1185       /* An existing property was found; check that it has the same
1186          types, or it is compatible.  */
1187       location_t original_location = DECL_SOURCE_LOCATION (x);
1188           
1189       if (PROPERTY_NONATOMIC (x) != parsed_property_nonatomic)
1190         {
1191           warning_at (location, 0,
1192                       "'nonatomic' attribute of property %qD conflicts with previous declaration", decl);
1193       
1194           if (original_location != UNKNOWN_LOCATION)
1195             inform (original_location, "originally specified here");
1196           return;
1197         }
1198
1199       if (PROPERTY_GETTER_NAME (x) != parsed_property_getter_ident)
1200         {
1201           warning_at (location, 0,
1202                       "'getter' attribute of property %qD conflicts with previous declaration", decl);
1203       
1204           if (original_location != UNKNOWN_LOCATION)
1205             inform (original_location, "originally specified here");
1206           return;
1207         }
1208
1209       /* We can only compare the setter names if both the old and new property have a setter.  */
1210       if (!property_readonly  &&  !PROPERTY_READONLY(x))
1211         {
1212           if (PROPERTY_SETTER_NAME (x) != parsed_property_setter_ident)
1213             {
1214               warning_at (location, 0,
1215                           "'setter' attribute of property %qD conflicts with previous declaration", decl);
1216               
1217               if (original_location != UNKNOWN_LOCATION)
1218                 inform (original_location, "originally specified here");
1219               return;
1220             }
1221         }
1222
1223       if (PROPERTY_ASSIGN_SEMANTICS (x) != property_assign_semantics)
1224         {
1225           warning_at (location, 0,
1226                       "assign semantics attributes of property %qD conflict with previous declaration", decl);
1227       
1228           if (original_location != UNKNOWN_LOCATION)
1229             inform (original_location, "originally specified here");
1230           return;
1231         }
1232
1233       /* It's ok to have a readonly property that becomes a readwrite, but not vice versa.  */
1234       if (PROPERTY_READONLY (x) == 0  &&  property_readonly == 1)
1235         {
1236           warning_at (location, 0,
1237                       "'readonly' attribute of property %qD conflicts with previous declaration", decl);
1238       
1239           if (original_location != UNKNOWN_LOCATION)
1240             inform (original_location, "originally specified here");
1241           return;
1242         }
1243
1244       /* We now check that the new and old property declarations have
1245          the same types (or compatible one).  In the Objective-C
1246          tradition of loose type checking, we do type-checking but
1247          only generate warnings (not errors) if they do not match.
1248          For non-readonly properties, the types must match exactly;
1249          for readonly properties, it is allowed to use a "more
1250          specialized" type in the new property declaration.  Eg, the
1251          superclass has a getter returning (NSArray *) and the
1252          subclass a getter returning (NSMutableArray *).  The object's
1253          getter returns an (NSMutableArray *); but if you cast the
1254          object to the superclass, which is allowed, you'd still
1255          expect the getter to return an (NSArray *), which works since
1256          an (NSMutableArray *) is an (NSArray *) too.  So, the set of
1257          objects belonging to the type of the new @property should be
1258          a subset of the set of objects belonging to the type of the
1259          old @property.  This is what "specialization" means.  And the
1260          reason it only applies to readonly properties is that for a
1261          readwrite property the setter would have the opposite
1262          requirement - ie that the superclass type is more specialized
1263          then the subclass one; hence the only way to satisfy both
1264          constraints is that the types match.  */
1265
1266       /* If the types are not the same in the C sense, we warn ...  */
1267       if (!comptypes (TREE_TYPE (x), TREE_TYPE (decl))
1268           /* ... unless the property is readonly, in which case we
1269              allow a new, more specialized, declaration.  */
1270           && (!property_readonly 
1271               || !objc_compare_types (TREE_TYPE (x),
1272                                       TREE_TYPE (decl), -5, NULL_TREE)))
1273         {
1274           warning_at (location, 0,
1275                       "type of property %qD conflicts with previous declaration", decl);
1276           if (original_location != UNKNOWN_LOCATION)
1277             inform (original_location, "originally specified here");
1278           return;
1279         }
1280     }
1281
1282   /* Create a PROPERTY_DECL node.  */
1283   property_decl = make_node (PROPERTY_DECL);
1284
1285   /* Copy the basic information from the original decl.  */
1286   TREE_TYPE (property_decl) = TREE_TYPE (decl);
1287   DECL_SOURCE_LOCATION (property_decl) = DECL_SOURCE_LOCATION (decl);
1288   TREE_DEPRECATED (property_decl) = TREE_DEPRECATED (decl);
1289   
1290   /* Add property-specific information.  */
1291   PROPERTY_NAME (property_decl) = DECL_NAME (decl);
1292   PROPERTY_GETTER_NAME (property_decl) = parsed_property_getter_ident;
1293   PROPERTY_SETTER_NAME (property_decl) = parsed_property_setter_ident;
1294   PROPERTY_READONLY (property_decl) = property_readonly;
1295   PROPERTY_NONATOMIC (property_decl) = parsed_property_nonatomic;
1296   PROPERTY_ASSIGN_SEMANTICS (property_decl) = property_assign_semantics;
1297   PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
1298   PROPERTY_DYNAMIC (property_decl) = 0;
1299
1300   /* Note that PROPERTY_GETTER_NAME is always set for all
1301      PROPERTY_DECLs, and PROPERTY_SETTER_NAME is always set for all
1302      PROPERTY_DECLs where PROPERTY_READONLY == 0.  Any time we deal
1303      with a getter or setter, we should get the PROPERTY_DECL and use
1304      PROPERTY_GETTER_NAME and PROPERTY_SETTER_NAME to know the correct
1305      names.  */
1306
1307   /* Add the PROPERTY_DECL to the list of properties for the class.  */
1308   TREE_CHAIN (property_decl) = CLASS_PROPERTY_DECL (objc_interface_context);
1309   CLASS_PROPERTY_DECL (objc_interface_context) = property_decl;
1310 }
1311
1312 /* This is a subroutine of objc_maybe_build_component_ref.  Search the
1313    list of methods in the interface (and, failing that, the local list
1314    in the implementation, and failing that, the protocol list)
1315    provided for a 'setter' or 'getter' for 'component' with default
1316    names (ie, if 'component' is "name", then search for "name" and
1317    "setName:").  If any is found, then create an artificial property
1318    that uses them.  Return NULL_TREE if 'getter' or 'setter' could not
1319    be found.  */
1320 static tree
1321 maybe_make_artificial_property_decl (tree interface, tree implementation, 
1322                                      tree protocol_list, tree component, bool is_class)
1323 {
1324   tree getter_name = component;
1325   tree setter_name = get_identifier (objc_build_property_setter_name (component));
1326   tree getter = NULL_TREE;
1327   tree setter = NULL_TREE;
1328
1329   /* First, check the @interface and all superclasses.  */
1330   if (interface)
1331     {
1332       int flags = 0;
1333
1334       /* Using instance methods of the root class as accessors is most
1335          likely unwanted and can be extremely confusing (and, most
1336          importantly, other Objective-C 2.0 compilers do not do it).
1337          Turn it off.  */
1338       if (is_class)
1339         flags = OBJC_LOOKUP_CLASS | OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS;
1340       
1341       getter = lookup_method_static (interface, getter_name, flags);
1342       setter = lookup_method_static (interface, setter_name, flags);
1343     }
1344
1345   /* Second, check the local @implementation context.  */
1346   if (!getter && !setter)
1347     {
1348       if (implementation)
1349         {
1350           if (is_class)
1351             {
1352               getter = lookup_method (CLASS_CLS_METHODS (implementation), getter_name);
1353               setter = lookup_method (CLASS_CLS_METHODS (implementation), setter_name);
1354             }
1355           else
1356             {
1357               getter = lookup_method (CLASS_NST_METHODS (implementation), getter_name);
1358               setter = lookup_method (CLASS_NST_METHODS (implementation), setter_name);       
1359             }
1360         }
1361     }
1362
1363   /* Try the protocol_list if we didn't find anything in the
1364      @interface and in the @implementation.  */
1365   if (!getter && !setter)
1366     {
1367       getter = lookup_method_in_protocol_list (protocol_list, getter_name, is_class);
1368       setter = lookup_method_in_protocol_list (protocol_list, setter_name, is_class);
1369     }
1370
1371   /* There needs to be at least a getter or setter for this to be a
1372      valid 'object.component' syntax.  */
1373   if (getter || setter)
1374     {
1375       /* Yes ... determine the type of the expression.  */
1376       tree property_decl;
1377       tree type;
1378       
1379       if (getter)
1380         type = TREE_VALUE (TREE_TYPE (getter));
1381       else
1382         type = TREE_VALUE (TREE_TYPE (METHOD_SEL_ARGS (setter)));
1383       
1384       /* Create an artificial property declaration with the
1385          information we collected on the type and getter/setter
1386          names.  */
1387       property_decl = make_node (PROPERTY_DECL);
1388       
1389       TREE_TYPE (property_decl) = type;
1390       DECL_SOURCE_LOCATION (property_decl) = input_location;
1391       TREE_DEPRECATED (property_decl) = 0;
1392       DECL_ARTIFICIAL (property_decl) = 1;
1393               
1394       /* Add property-specific information.  Note that one of
1395          PROPERTY_GETTER_NAME or PROPERTY_SETTER_NAME may refer to a
1396          non-existing method; this will generate an error when the
1397          expression is later compiled.  At this stage we don't know if
1398          the getter or setter will be used, so we can't generate an
1399          error.  */
1400       PROPERTY_NAME (property_decl) = component;
1401       PROPERTY_GETTER_NAME (property_decl) = getter_name;
1402       PROPERTY_SETTER_NAME (property_decl) = setter_name;
1403       PROPERTY_READONLY (property_decl) = 0;
1404       PROPERTY_NONATOMIC (property_decl) = 0;
1405       PROPERTY_ASSIGN_SEMANTICS (property_decl) = 0;
1406       PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
1407       PROPERTY_DYNAMIC (property_decl) = 0;
1408
1409       if (!getter)
1410         PROPERTY_HAS_NO_GETTER (property_decl) = 1;
1411
1412       /* The following is currently unused, but it's nice to have
1413          there.  We may use it if we need in the future.  */
1414       if (!setter)
1415         PROPERTY_HAS_NO_SETTER (property_decl) = 1;
1416
1417       return property_decl;
1418     }
1419
1420   return NULL_TREE;
1421 }
1422
1423 /* This hook routine is invoked by the parser when an expression such
1424    as 'xxx.yyy' is parsed.  We get a chance to process these
1425    expressions in a way that is specified to Objective-C (to implement
1426    the Objective-C 2.0 dot-syntax, properties, or non-fragile ivars).
1427    If the expression is not an Objective-C specified expression, we
1428    should return NULL_TREE; else we return the expression.
1429
1430    At the moment this only implements dot-syntax and properties (not
1431    non-fragile ivars yet), ie 'object.property' or 'object.component'
1432    where 'component' is not a declared property, but a valid getter or
1433    setter for it could be found.  */
1434 tree
1435 objc_maybe_build_component_ref (tree object, tree property_ident)
1436 {
1437   tree x = NULL_TREE;
1438   tree rtype;
1439
1440   /* If we are in Objective-C 1.0 mode, dot-syntax and properties are
1441      not available.  */
1442   if (flag_objc1_only)
1443     return NULL_TREE;
1444
1445   /* Try to determine if 'object' is an Objective-C object or not.  If
1446      not, return.  */
1447   if (object == NULL_TREE || object == error_mark_node 
1448       || (rtype = TREE_TYPE (object)) == NULL_TREE)
1449     return NULL_TREE;
1450   
1451   if (property_ident == NULL_TREE || property_ident == error_mark_node
1452       || TREE_CODE (property_ident) != IDENTIFIER_NODE)
1453     return NULL_TREE;
1454
1455   /* The following analysis of 'object' is similar to the one used for
1456      the 'receiver' of a method invocation.  We need to determine what
1457      'object' is and find the appropriate property (either declared,
1458      or artificial) for it (in the same way as we need to find the
1459      appropriate method prototype for a method invocation).  There are
1460      some simplifications here though: "object.property" is invalid if
1461      "object" has a type of "id" or "Class"; it must at least have a
1462      protocol attached to it, and "object" is never a class name as
1463      that is done by objc_build_class_component_ref.  Finally, we
1464      don't know if this really is a dot-syntax expression, so we want
1465      to make a quick exit if it is not; for this reason, we try to
1466      postpone checks after determining that 'object' looks like an
1467      Objective-C object.  */
1468
1469   if (objc_is_id (rtype))
1470     {
1471       /* This is the case that the 'object' is of type 'id' or
1472          'Class'.  */
1473
1474       /* Check if at least it is of type 'id <Protocol>' or 'Class
1475          <Protocol>'; if so, look the property up in the
1476          protocols.  */
1477       if (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype)))
1478         {
1479           tree rprotos = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype));
1480           
1481           if (rprotos)
1482             {
1483               /* No point looking up declared @properties if we are
1484                  dealing with a class.  Classes have no declared
1485                  properties.  */
1486               if (!IS_CLASS (rtype))
1487                 x = lookup_property_in_protocol_list (rprotos, property_ident);
1488               
1489               if (x == NULL_TREE)
1490                 {
1491                   /* Ok, no property.  Maybe it was an
1492                      object.component dot-syntax without a declared
1493                      property (this is valid for classes too).  Look
1494                      for getter/setter methods and internally declare
1495                      an artifical property based on them if found.  */
1496                   x = maybe_make_artificial_property_decl (NULL_TREE,
1497                                                            NULL_TREE,
1498                                                            rprotos, 
1499                                                            property_ident,
1500                                                            IS_CLASS (rtype));
1501                 }
1502             }
1503         }
1504       else if (objc_method_context)
1505         {
1506           /* Else, if we are inside a method it could be the case of
1507              'super' or 'self'.  */
1508           tree interface_type = NULL_TREE;
1509           tree t = object;
1510           while (TREE_CODE (t) == COMPOUND_EXPR
1511                  || TREE_CODE (t) == MODIFY_EXPR
1512                  || CONVERT_EXPR_P (t)
1513                  || TREE_CODE (t) == COMPONENT_REF)
1514             t = TREE_OPERAND (t, 0);
1515           
1516           if (t == UOBJC_SUPER_decl)
1517             {
1518               /* TODO: Check if this is correct also for 'super' in categories.  */
1519               interface_type = lookup_interface (CLASS_SUPER_NAME (implementation_template));
1520             }
1521           else if (t == self_decl)
1522             interface_type = lookup_interface (CLASS_NAME (implementation_template));
1523
1524           if (interface_type)
1525             {
1526               if (TREE_CODE (objc_method_context) != CLASS_METHOD_DECL)
1527                 x = lookup_property (interface_type, property_ident);
1528         
1529               if (x == NULL_TREE)
1530                 {
1531                   /* Try the dot-syntax without a declared property.
1532                      If this is an access to 'self', it is possible
1533                      that they may refer to a setter/getter that is
1534                      not declared in the interface, but exists locally
1535                      in the implementation.  In that case, get the
1536                      implementation context and use it.  */
1537                   tree implementation = NULL_TREE;
1538
1539                   if (t == self_decl)
1540                     implementation = objc_implementation_context;
1541                   
1542                   x = maybe_make_artificial_property_decl 
1543                     (interface_type, implementation, NULL_TREE,
1544                      property_ident,
1545                      (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL));
1546                 }
1547             }
1548         }
1549     }
1550   else
1551     {
1552       /* This is the case where we have more information on 'rtype'.  */
1553       tree basetype = TYPE_MAIN_VARIANT (rtype);
1554
1555       /* Skip the pointer - if none, it's not an Objective-C object or
1556          class.  */
1557       if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE)
1558         basetype = TREE_TYPE (basetype);
1559       else
1560         return NULL_TREE;
1561
1562       /* Traverse typedefs.  */
1563       while (basetype != NULL_TREE
1564              && TREE_CODE (basetype) == RECORD_TYPE 
1565              && OBJC_TYPE_NAME (basetype)
1566              && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
1567              && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
1568         basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
1569
1570       if (basetype != NULL_TREE && TYPED_OBJECT (basetype))
1571         {
1572           tree interface_type = TYPE_OBJC_INTERFACE (basetype);
1573           tree protocol_list = TYPE_OBJC_PROTOCOL_LIST (basetype);
1574
1575           if (interface_type 
1576               && (TREE_CODE (interface_type) == CLASS_INTERFACE_TYPE
1577                   || TREE_CODE (interface_type) == CATEGORY_INTERFACE_TYPE
1578                   || TREE_CODE (interface_type) == PROTOCOL_INTERFACE_TYPE))
1579             {
1580               /* Not sure 'rtype' could ever be a class here!  Just
1581                  for safety we keep the checks.  */
1582               if (!IS_CLASS (rtype))
1583                 {
1584                   x = lookup_property (interface_type, property_ident);
1585                   
1586                   if (x == NULL_TREE)
1587                     x = lookup_property_in_protocol_list (protocol_list, 
1588                                                           property_ident);
1589                 }
1590               
1591               if (x == NULL_TREE)
1592                 {
1593                   /* Try the dot-syntax without a declared property.
1594                      If we are inside a method implementation, it is
1595                      possible that they may refer to a setter/getter
1596                      that is not declared in the interface, but exists
1597                      locally in the implementation.  In that case, get
1598                      the implementation context and use it.  */
1599                   tree implementation = NULL_TREE;
1600
1601                   if (objc_implementation_context
1602                       && CLASS_NAME (objc_implementation_context) 
1603                       == OBJC_TYPE_NAME (interface_type))
1604                     implementation = objc_implementation_context;
1605                   
1606                   x = maybe_make_artificial_property_decl (interface_type,
1607                                                            implementation,
1608                                                            protocol_list, 
1609                                                            property_ident,
1610                                                            IS_CLASS (rtype));
1611                 }
1612             }
1613         }
1614     }
1615
1616   if (x)
1617     {
1618       tree expression;
1619       tree getter_call;
1620
1621       /* We have an additional nasty problem here; if this
1622          PROPERTY_REF needs to become a 'getter', then the conversion
1623          from PROPERTY_REF into a getter call happens in gimplify,
1624          after the selector table has already been generated and when
1625          it is too late to add another selector to it.  To work around
1626          the problem, we always create the getter call at this stage,
1627          which puts the selector in the table.  Note that if the
1628          PROPERTY_REF becomes a 'setter' instead of a 'getter', then
1629          we have added a selector too many to the selector table.
1630          This is a little inefficient.
1631
1632          Also note that method calls to 'self' and 'super' require the
1633          context (self_decl, UOBJS_SUPER_decl,
1634          objc_implementation_context etc) to be built correctly; this
1635          is yet another reason why building the call at the gimplify
1636          stage (when this context has been lost) is not very
1637          practical.  If we build it at this stage, we know it will
1638          always be built correctly.
1639
1640          If the PROPERTY_HAS_NO_GETTER() (ie, it is an artificial
1641          property decl created to deal with a dotsyntax not really
1642          referring to an existing property) then do not try to build a
1643          call to the getter as there is no getter.  */
1644       if (PROPERTY_HAS_NO_GETTER (x))
1645         getter_call = NULL_TREE;
1646       else
1647         getter_call = objc_finish_message_expr (object,
1648                                                 PROPERTY_GETTER_NAME (x),
1649                                                 NULL_TREE);
1650
1651       if (TREE_DEPRECATED (x))
1652         warn_deprecated_use (x, NULL_TREE);
1653
1654       expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call);
1655       SET_EXPR_LOCATION (expression, input_location);
1656       TREE_SIDE_EFFECTS (expression) = 1;
1657       
1658       return expression;
1659     }
1660
1661   return NULL_TREE;
1662 }
1663
1664 /* This hook routine is invoked by the parser when an expression such
1665    as 'xxx.yyy' is parsed, and 'xxx' is a class name.  This is the
1666    Objective-C 2.0 dot-syntax applied to classes, so we need to
1667    convert it into a setter/getter call on the class.  */
1668 tree
1669 objc_build_class_component_ref (tree class_name, tree property_ident)
1670 {
1671   tree x = NULL_TREE;
1672   tree object, rtype;
1673   
1674   if (flag_objc1_only)
1675     error_at (input_location, "the dot syntax is not available in Objective-C 1.0");
1676   
1677   if (class_name == NULL_TREE || class_name == error_mark_node
1678       || TREE_CODE (class_name) != IDENTIFIER_NODE)
1679     return error_mark_node;
1680   
1681   if (property_ident == NULL_TREE || property_ident == error_mark_node
1682       || TREE_CODE (property_ident) != IDENTIFIER_NODE)
1683     return NULL_TREE;
1684   
1685   object = objc_get_class_reference (class_name);
1686   if (!object)
1687     {
1688       /* We know that 'class_name' is an Objective-C class name as the
1689          parser won't call this function if it is not.  This is only a
1690          double-check for safety.  */
1691       error_at (input_location, "could not find class %qE", class_name); 
1692       return error_mark_node;
1693     }
1694
1695   rtype = lookup_interface (class_name);
1696   if (!rtype)
1697     {
1698       /* Again, this should never happen, but we do check.  */
1699       error_at (input_location, "could not find interface for class %qE", class_name); 
1700       return error_mark_node;
1701     }
1702   else
1703     {
1704       if (TREE_DEPRECATED (rtype))
1705         warning (OPT_Wdeprecated_declarations, "class %qE is deprecated", class_name);    
1706     }
1707
1708   x = maybe_make_artificial_property_decl (rtype, NULL_TREE, NULL_TREE,
1709                                            property_ident,
1710                                            true);
1711   
1712   if (x)
1713     {
1714       tree expression;
1715       tree getter_call;
1716
1717       if (PROPERTY_HAS_NO_GETTER (x))
1718         getter_call = NULL_TREE;
1719       else
1720         getter_call = objc_finish_message_expr (object,
1721                                                 PROPERTY_GETTER_NAME (x),
1722                                                 NULL_TREE);
1723       if (TREE_DEPRECATED (x))
1724         warn_deprecated_use (x, NULL_TREE);
1725
1726       expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call);
1727       SET_EXPR_LOCATION (expression, input_location);
1728       TREE_SIDE_EFFECTS (expression) = 1;
1729
1730       return expression;
1731     }
1732   else
1733     {
1734       error_at (input_location, "could not find setter/getter for %qE in class %qE", 
1735                 property_ident, class_name); 
1736       return error_mark_node;
1737     }
1738
1739   return NULL_TREE;
1740 }
1741
1742
1743
1744 /* This is used because we don't want to expose PROPERTY_REF to the
1745    C/C++ frontends.  Maybe we should!  */
1746 bool
1747 objc_is_property_ref (tree node)
1748 {
1749   if (node  &&  TREE_CODE (node) == PROPERTY_REF)
1750     return true;
1751   else
1752     return false;
1753 }
1754
1755 /* This function builds a setter call for a PROPERTY_REF (real, for a
1756    declared property, or artificial, for a dot-syntax accessor which
1757    is not corresponding to a property).  'lhs' must be a PROPERTY_REF
1758    (the caller must check this beforehand).  'rhs' is the value to
1759    assign to the property.  A plain setter call is returned, or
1760    error_mark_node if the property is readonly.  */
1761
1762 static tree
1763 objc_build_setter_call (tree lhs, tree rhs)
1764 {
1765   tree object_expr = PROPERTY_REF_OBJECT (lhs);
1766   tree property_decl = PROPERTY_REF_PROPERTY_DECL (lhs);
1767   
1768   if (PROPERTY_READONLY (property_decl))
1769     {
1770       error ("readonly property can not be set");         
1771       return error_mark_node;
1772     }
1773   else
1774     {
1775       tree setter_argument = build_tree_list (NULL_TREE, rhs);
1776       tree setter;
1777       
1778       /* TODO: Check that the setter return type is 'void'.  */
1779
1780       /* TODO: Decay arguments in C.  */
1781       setter = objc_finish_message_expr (object_expr, 
1782                                          PROPERTY_SETTER_NAME (property_decl),
1783                                          setter_argument);
1784       return setter;
1785     }
1786
1787   /* Unreachable, but the compiler may not realize.  */
1788   return error_mark_node;
1789 }
1790
1791 /* This hook routine is called when a MODIFY_EXPR is being built.  We
1792    check what is being modified; if it is a PROPERTY_REF, we need to
1793    generate a 'setter' function call for the property.  If this is not
1794    a PROPERTY_REF, we return NULL_TREE and the C/C++ frontend will go
1795    on creating their MODIFY_EXPR.
1796
1797    This is used for example if you write
1798
1799    object.count = 1;
1800
1801    where 'count' is a property.  The left-hand side creates a
1802    PROPERTY_REF, and then the compiler tries to generate a MODIFY_EXPR
1803    to assign something to it.  We intercept that here, and generate a
1804    call to the 'setter' method instead.  */
1805 tree
1806 objc_maybe_build_modify_expr (tree lhs, tree rhs)
1807 {
1808   if (lhs && TREE_CODE (lhs) == PROPERTY_REF)
1809     {
1810       /* Building a simple call to the setter method would work for cases such as
1811
1812       object.count = 1;
1813
1814       but wouldn't work for cases such as
1815
1816       count = object2.count = 1;
1817
1818       to get these to work with very little effort, we build a
1819       compound statement which does the setter call (to set the
1820       property to 'rhs'), but which can also be evaluated returning
1821       the 'rhs'.  So, we want to create the following:
1822
1823       (temp = rhs; [object setProperty: temp]; temp)
1824       */
1825       tree temp_variable_decl, bind;
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       /* TODO: If 'rhs' is a constant, we could maybe do without the
1831          'temp' variable ? */
1832
1833       /* Declare __objc_property_temp in a local bind.  */
1834       temp_variable_decl = objc_create_temporary_var (TREE_TYPE (rhs), "__objc_property_temp");
1835       DECL_SOURCE_LOCATION (temp_variable_decl) = input_location;
1836       bind = build3 (BIND_EXPR, void_type_node, temp_variable_decl, NULL, NULL);
1837       SET_EXPR_LOCATION (bind, input_location);
1838       TREE_SIDE_EFFECTS (bind) = 1;
1839       add_stmt (bind);
1840       
1841       /* Now build the compound statement.  */
1842       
1843       /* s1: __objc_property_temp = rhs */
1844       s1 = build_modify_expr (input_location, temp_variable_decl, NULL_TREE,
1845                               NOP_EXPR,
1846                               input_location, rhs, NULL_TREE);
1847       SET_EXPR_LOCATION (s1, input_location);
1848   
1849       /* s2: [object setProperty: __objc_property_temp] */
1850       s2 = objc_build_setter_call (lhs, temp_variable_decl);
1851
1852       /* This happens if building the setter failed because the property
1853          is readonly.  */
1854       if (s2 == error_mark_node)
1855         return error_mark_node;
1856
1857       SET_EXPR_LOCATION (s2, input_location);
1858   
1859       /* s3: __objc_property_temp */
1860       s3 = convert (TREE_TYPE (lhs), temp_variable_decl);
1861
1862       /* Now build the compound statement (s1, s2, s3) */
1863       compound_expr = build_compound_expr (input_location, build_compound_expr (input_location, s1, s2), s3);
1864
1865       /* Without this, with -Wall you get a 'valued computed is not
1866          used' every time there is a "object.property = x" where the
1867          value of the resulting MODIFY_EXPR is not used.  That is
1868          correct (maybe a more sophisticated implementation could
1869          avoid generating the compound expression if not needed), but
1870          we need to turn it off.  */
1871       TREE_NO_WARNING (compound_expr) = 1;
1872       return compound_expr;
1873     }
1874   else
1875     return NULL_TREE;
1876 }
1877
1878 /* This hook is called by the frontend when one of the four unary
1879    expressions PREINCREMENT_EXPR, POSTINCREMENT_EXPR,
1880    PREDECREMENT_EXPR and POSTDECREMENT_EXPR is being built with an
1881    argument which is a PROPERTY_REF.  For example, this happens if you have
1882
1883    object.count++;
1884
1885    where 'count' is a property.  We need to use the 'getter' and
1886    'setter' for the property in an appropriate way to build the
1887    appropriate expression.  'code' is the code for the expression (one
1888    of the four mentioned above); 'argument' is the PROPERTY_REF, and
1889    'increment' is how much we need to add or subtract.  */   
1890 tree
1891 objc_build_incr_expr_for_property_ref (location_t location,
1892                                        enum tree_code code, 
1893                                        tree argument, tree increment)
1894 {
1895   /* Here are the expressions that we want to build:
1896
1897      For PREINCREMENT_EXPR / PREDECREMENT_EXPR:
1898     (temp = [object property] +/- increment, [object setProperty: temp], temp)
1899     
1900     For POSTINCREMENT_EXPR / POSTECREMENT_EXPR:
1901     (temp = [object property], [object setProperty: temp +/- increment], temp) */
1902   
1903   tree temp_variable_decl, bind;
1904   /* s1, s2 and s3 are the tree statements that we need in the
1905      compound expression.  */
1906   tree s1, s2, s3, compound_expr;
1907   
1908   /* Safety check.  */
1909   if (!argument || TREE_CODE (argument) != PROPERTY_REF)
1910     return error_mark_node;
1911
1912   /* Declare __objc_property_temp in a local bind.  */
1913   temp_variable_decl = objc_create_temporary_var (TREE_TYPE (argument), "__objc_property_temp");
1914   DECL_SOURCE_LOCATION (temp_variable_decl) = location;
1915   bind = build3 (BIND_EXPR, void_type_node, temp_variable_decl, NULL, NULL);
1916   SET_EXPR_LOCATION (bind, location);
1917   TREE_SIDE_EFFECTS (bind) = 1;
1918   add_stmt (bind);
1919   
1920   /* Now build the compound statement.  */
1921   
1922   /* Note that the 'getter' is generated at gimplify time; at this
1923      time, we can simply put the property_ref (ie, argument) wherever
1924      we want the getter ultimately to be.  */
1925   
1926   /* s1: __objc_property_temp = [object property] <+/- increment> */
1927   switch (code)
1928     {
1929     case PREINCREMENT_EXPR:      
1930       /* __objc_property_temp = [object property] + increment */
1931       s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
1932                               NOP_EXPR,
1933                               location, build2 (PLUS_EXPR, TREE_TYPE (argument), 
1934                                                 argument, increment), NULL_TREE);
1935       break;
1936     case PREDECREMENT_EXPR:
1937       /* __objc_property_temp = [object property] - increment */
1938       s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
1939                               NOP_EXPR,
1940                               location, build2 (MINUS_EXPR, TREE_TYPE (argument), 
1941                                                 argument, increment), NULL_TREE);
1942       break;
1943     case POSTINCREMENT_EXPR:
1944     case POSTDECREMENT_EXPR:
1945       /* __objc_property_temp = [object property] */
1946       s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
1947                               NOP_EXPR,
1948                               location, argument, NULL_TREE);
1949       break;
1950     default:
1951       gcc_unreachable ();
1952     }
1953   
1954   /* s2: [object setProperty: __objc_property_temp <+/- increment>] */
1955   switch (code)
1956     {
1957     case PREINCREMENT_EXPR:      
1958     case PREDECREMENT_EXPR:
1959       /* [object setProperty: __objc_property_temp] */
1960       s2 = objc_build_setter_call (argument, temp_variable_decl);
1961       break;
1962     case POSTINCREMENT_EXPR:
1963       /* [object setProperty: __objc_property_temp + increment] */
1964       s2 = objc_build_setter_call (argument,
1965                                    build2 (PLUS_EXPR, TREE_TYPE (argument), 
1966                                            temp_variable_decl, increment));
1967       break;
1968     case POSTDECREMENT_EXPR:
1969       /* [object setProperty: __objc_property_temp - increment] */
1970       s2 = objc_build_setter_call (argument,
1971                                    build2 (MINUS_EXPR, TREE_TYPE (argument), 
1972                                            temp_variable_decl, increment));
1973       break;
1974     default:
1975       gcc_unreachable ();
1976     }
1977
1978   /* This happens if building the setter failed because the property
1979      is readonly.  */
1980   if (s2 == error_mark_node)
1981     return error_mark_node;
1982
1983   SET_EXPR_LOCATION (s2, location); 
1984   
1985   /* s3: __objc_property_temp */
1986   s3 = convert (TREE_TYPE (argument), temp_variable_decl);
1987   
1988   /* Now build the compound statement (s1, s2, s3) */
1989   compound_expr = build_compound_expr (location, build_compound_expr (location, s1, s2), s3);
1990
1991   /* Prevent C++ from warning with -Wall that "right operand of comma
1992      operator has no effect".  */
1993   TREE_NO_WARNING (compound_expr) = 1;
1994   return compound_expr;
1995 }
1996
1997 tree
1998 objc_build_method_signature (bool is_class_method, tree rettype, tree selector,
1999                              tree optparms, bool ellipsis)
2000 {
2001   if (is_class_method)
2002     return build_method_decl (CLASS_METHOD_DECL, rettype, selector,
2003                               optparms, ellipsis);
2004   else
2005     return build_method_decl (INSTANCE_METHOD_DECL, rettype, selector,
2006                               optparms, ellipsis);
2007 }
2008
2009 void
2010 objc_add_method_declaration (bool is_class_method, tree decl, tree attributes)
2011 {
2012   if (!objc_interface_context)
2013     {
2014       /* PS: At the moment, due to how the parser works, it should be
2015          impossible to get here.  But it's good to have the check in
2016          case the parser changes.
2017       */
2018       fatal_error ("method declaration not in @interface context");
2019     }
2020
2021   if (flag_objc1_only && attributes)
2022     error_at (input_location, "method attributes are not available in Objective-C 1.0");
2023
2024   objc_decl_method_attributes (&decl, attributes, 0);
2025   objc_add_method (objc_interface_context,
2026                    decl,
2027                    is_class_method,
2028                    objc_method_optional_flag);
2029 }
2030
2031 /* Return 'true' if the method definition could be started, and
2032    'false' if not (because we are outside an @implementation context).
2033 */
2034 bool
2035 objc_start_method_definition (bool is_class_method, tree decl, tree attributes)
2036 {
2037   if (!objc_implementation_context)
2038     {
2039       error ("method definition not in @implementation context");
2040       return false;
2041     }
2042
2043   if (decl != NULL_TREE  && METHOD_SEL_NAME (decl) == error_mark_node)
2044     return false;
2045
2046 #ifndef OBJCPLUS
2047   /* Indicate no valid break/continue context by setting these variables
2048      to some non-null, non-label value.  We'll notice and emit the proper
2049      error message in c_finish_bc_stmt.  */
2050   c_break_label = c_cont_label = size_zero_node;
2051 #endif
2052
2053   if (attributes)
2054     warning_at (input_location, 0, "method attributes can not be specified in @implementation context");
2055   else
2056     objc_decl_method_attributes (&decl, attributes, 0);
2057
2058   objc_add_method (objc_implementation_context,
2059                    decl,
2060                    is_class_method,
2061                    /* is optional */ false);
2062   start_method_def (decl);
2063   return true;
2064 }
2065
2066 void
2067 objc_add_instance_variable (tree decl)
2068 {
2069   (void) add_instance_variable (objc_ivar_context,
2070                                 objc_ivar_visibility,
2071                                 decl);
2072 }
2073
2074 /* Return true if TYPE is 'id'.  */
2075
2076 static bool
2077 objc_is_object_id (tree type)
2078 {
2079   return OBJC_TYPE_NAME (type) == objc_object_id;
2080 }
2081
2082 static bool
2083 objc_is_class_id (tree type)
2084 {
2085   return OBJC_TYPE_NAME (type) == objc_class_id;
2086 }
2087
2088 /* Construct a C struct with same name as KLASS, a base struct with tag
2089    SUPER_NAME (if any), and FIELDS indicated.  */
2090
2091 static tree
2092 objc_build_struct (tree klass, tree fields, tree super_name)
2093 {
2094   tree name = CLASS_NAME (klass);
2095   tree s = objc_start_struct (name);
2096   tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
2097   tree t;
2098   VEC(tree,heap) *objc_info = NULL;
2099   int i;
2100
2101   if (super)
2102     {
2103       /* Prepend a packed variant of the base class into the layout.  This
2104          is necessary to preserve ObjC ABI compatibility.  */
2105       tree base = build_decl (input_location,
2106                               FIELD_DECL, NULL_TREE, super);
2107       tree field = TYPE_FIELDS (super);
2108
2109       while (field && DECL_CHAIN (field)
2110              && TREE_CODE (DECL_CHAIN (field)) == FIELD_DECL)
2111         field = DECL_CHAIN (field);
2112
2113       /* For ObjC ABI purposes, the "packed" size of a base class is
2114          the sum of the offset and the size (in bits) of the last field
2115          in the class.  */
2116       DECL_SIZE (base)
2117         = (field && TREE_CODE (field) == FIELD_DECL
2118            ? size_binop (PLUS_EXPR,
2119                          size_binop (PLUS_EXPR,
2120                                      size_binop
2121                                      (MULT_EXPR,
2122                                       convert (bitsizetype,
2123                                                DECL_FIELD_OFFSET (field)),
2124                                       bitsize_int (BITS_PER_UNIT)),
2125                                      DECL_FIELD_BIT_OFFSET (field)),
2126                          DECL_SIZE (field))
2127            : bitsize_zero_node);
2128       DECL_SIZE_UNIT (base)
2129         = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
2130                       size_int (BITS_PER_UNIT));
2131       DECL_ARTIFICIAL (base) = 1;
2132       DECL_ALIGN (base) = 1;
2133       DECL_FIELD_CONTEXT (base) = s;
2134 #ifdef OBJCPLUS
2135       DECL_FIELD_IS_BASE (base) = 1;
2136
2137       if (fields)
2138         TREE_NO_WARNING (fields) = 1;   /* Suppress C++ ABI warnings -- we   */
2139 #endif                                  /* are following the ObjC ABI here.  */
2140       DECL_CHAIN (base) = fields;
2141       fields = base;
2142     }
2143
2144   /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
2145      in all variants of this RECORD_TYPE to be clobbered, but it is therein
2146      that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
2147      Hence, we must squirrel away the ObjC-specific information before calling
2148      finish_struct(), and then reinstate it afterwards.  */
2149
2150   for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
2151     {
2152       if (!TYPE_HAS_OBJC_INFO (t))
2153         {
2154           INIT_TYPE_OBJC_INFO (t);
2155           TYPE_OBJC_INTERFACE (t) = klass;
2156         }
2157       VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t));
2158     }
2159
2160   /* Point the struct at its related Objective-C class.  */
2161   INIT_TYPE_OBJC_INFO (s);
2162   TYPE_OBJC_INTERFACE (s) = klass;
2163
2164   s = objc_finish_struct (s, fields);
2165
2166   for (i = 0, t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
2167     {
2168       TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i);
2169       /* Replace the IDENTIFIER_NODE with an actual @interface.  */
2170       TYPE_OBJC_INTERFACE (t) = klass;
2171     }
2172   VEC_free (tree, heap, objc_info);
2173
2174   /* Use TYPE_BINFO structures to point at the super class, if any.  */
2175   objc_xref_basetypes (s, super);
2176
2177   /* Mark this struct as a class template.  */
2178   CLASS_STATIC_TEMPLATE (klass) = s;
2179
2180   return s;
2181 }
2182
2183 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
2184    Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
2185    process.  */
2186 static tree
2187 objc_build_volatilized_type (tree type)
2188 {
2189   tree t;
2190
2191   /* Check if we have not constructed the desired variant already.  */
2192   for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
2193     {
2194       /* The type qualifiers must (obviously) match up.  */
2195       if (!TYPE_VOLATILE (t)
2196           || (TYPE_READONLY (t) != TYPE_READONLY (type))
2197           || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
2198         continue;
2199
2200       /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
2201          info, if any) must match up.  */
2202       if (POINTER_TYPE_P (t)
2203           && (TREE_TYPE (t) != TREE_TYPE (type)))
2204         continue;
2205
2206       /* Only match up the types which were previously volatilized in similar fashion and not
2207          because they were declared as such. */
2208       if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t)))
2209         continue;
2210
2211       /* Everything matches up!  */
2212       return t;
2213     }
2214
2215   /* Ok, we could not re-use any of the pre-existing variants.  Create
2216      a new one.  */
2217   t = build_variant_type_copy (type);
2218   TYPE_VOLATILE (t) = 1;
2219
2220   TYPE_ATTRIBUTES (t) = merge_attributes (TYPE_ATTRIBUTES (type),
2221                                           tree_cons (get_identifier ("objc_volatilized"),
2222                                           NULL_TREE,
2223                                           NULL_TREE));
2224   if (TREE_CODE (t) == ARRAY_TYPE)
2225     TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (t));
2226
2227   /* Set up the canonical type information. */
2228   if (TYPE_STRUCTURAL_EQUALITY_P (type))
2229     SET_TYPE_STRUCTURAL_EQUALITY (t);
2230   else if (TYPE_CANONICAL (type) != type)
2231     TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
2232   else
2233     TYPE_CANONICAL (t) = t;
2234
2235   return t;
2236 }
2237
2238 /* Mark DECL as being 'volatile' for purposes of Darwin
2239    _setjmp()/_longjmp() exception handling.  Called from
2240    objc_mark_locals_volatile().  */
2241 void
2242 objc_volatilize_decl (tree decl)
2243 {
2244   /* Do not mess with variables that are 'static' or (already)
2245      'volatile'.  */
2246   if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
2247       && (TREE_CODE (decl) == VAR_DECL
2248           || TREE_CODE (decl) == PARM_DECL))
2249     {
2250       tree t = TREE_TYPE (decl);
2251
2252       t = objc_build_volatilized_type (t);
2253
2254       TREE_TYPE (decl) = t;
2255       TREE_THIS_VOLATILE (decl) = 1;
2256       TREE_SIDE_EFFECTS (decl) = 1;
2257       DECL_REGISTER (decl) = 0;
2258 #ifndef OBJCPLUS
2259       C_DECL_REGISTER (decl) = 0;
2260 #endif
2261     }
2262 }
2263
2264 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
2265    (including its categories and superclasses) or by object type TYP.
2266    Issue a warning if PROTO is not adopted anywhere and WARN is set.  */
2267
2268 static bool
2269 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
2270 {
2271   bool class_type = (cls != NULL_TREE);
2272
2273   while (cls)
2274     {
2275       tree c;
2276
2277       /* Check protocols adopted by the class and its categories.  */
2278       for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
2279         {
2280           if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
2281             return true;
2282         }
2283
2284       /* Repeat for superclasses.  */
2285       cls = lookup_interface (CLASS_SUPER_NAME (cls));
2286     }
2287
2288   /* Check for any protocols attached directly to the object type.  */
2289   if (TYPE_HAS_OBJC_INFO (typ))
2290     {
2291       if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
2292         return true;
2293     }
2294
2295   if (warn)
2296     {
2297       *errbuf = 0;
2298       gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
2299       /* NB: Types 'id' and 'Class' cannot reasonably be described as
2300          "implementing" a given protocol, since they do not have an
2301          implementation.  */
2302       if (class_type)
2303         warning (0, "class %qs does not implement the %qE protocol",
2304                  identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
2305       else
2306         warning (0, "type %qs does not conform to the %qE protocol",
2307                  identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
2308     }
2309
2310   return false;
2311 }
2312
2313 /* Check if class RCLS and instance struct type RTYP conform to at least the
2314    same protocols that LCLS and LTYP conform to.  */
2315
2316 static bool
2317 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
2318 {
2319   tree p;
2320   bool have_lproto = false;
2321
2322   while (lcls)
2323     {
2324       /* NB: We do _not_ look at categories defined for LCLS; these may or
2325          may not get loaded in, and therefore it is unreasonable to require
2326          that RCLS/RTYP must implement any of their protocols.  */
2327       for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
2328         {
2329           have_lproto = true;
2330
2331           if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
2332             return warn;
2333         }
2334
2335       /* Repeat for superclasses.  */
2336       lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
2337     }
2338
2339   /* Check for any protocols attached directly to the object type.  */
2340   if (TYPE_HAS_OBJC_INFO (ltyp))
2341     {
2342       for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
2343         {
2344           have_lproto = true;
2345
2346           if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
2347             return warn;
2348         }
2349     }
2350
2351   /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
2352      vacuously, _unless_ RTYP is a protocol-qualified 'id'.  We can get
2353      away with simply checking for 'id' or 'Class' (!RCLS), since this
2354      routine will not get called in other cases.  */
2355   return have_lproto || (rcls != NULL_TREE);
2356 }
2357
2358 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
2359    Both TYPE1 and TYPE2 must be pointers, and already determined to be
2360    compatible by objc_compare_types() below.  */
2361
2362 tree
2363 objc_common_type (tree type1, tree type2)
2364 {
2365   tree inner1 = TREE_TYPE (type1), inner2 = TREE_TYPE (type2);
2366
2367   while (POINTER_TYPE_P (inner1))
2368     {
2369       inner1 = TREE_TYPE (inner1);
2370       inner2 = TREE_TYPE (inner2);
2371     }
2372
2373   /* If one type is derived from another, return the base type.  */
2374   if (DERIVED_FROM_P (inner1, inner2))
2375     return type1;
2376   else if (DERIVED_FROM_P (inner2, inner1))
2377     return type2;
2378
2379   /* If both types are 'Class', return 'Class'.  */
2380   if (objc_is_class_id (inner1) && objc_is_class_id (inner2))
2381     return objc_class_type;
2382
2383   /* Otherwise, return 'id'.  */
2384   return objc_object_type;
2385 }
2386
2387 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
2388    an instance of RTYP to an instance of LTYP or to compare the two
2389    (if ARGNO is equal to -3), per ObjC type system rules.  Before
2390    returning 'true', this routine may issue warnings related to, e.g.,
2391    protocol conformance.  When returning 'false', the routine must
2392    produce absolutely no warnings; the C or C++ front-end will do so
2393    instead, if needed.  If either LTYP or RTYP is not an Objective-C
2394    type, the routine must return 'false'.
2395
2396    The ARGNO parameter is encoded as follows:
2397      >= 1       Parameter number (CALLEE contains function being called);
2398      0          Return value;
2399      -1         Assignment;
2400      -2         Initialization;
2401      -3         Comparison (LTYP and RTYP may match in either direction);
2402      -4         Silent comparison (for C++ overload resolution);
2403      -5         Silent "specialization" comparison for RTYP to be a "specialization" 
2404                 of LTYP (a specialization means that RTYP is LTYP plus some constraints, 
2405                 so that each object of type RTYP is also of type LTYP).  This is used
2406                 when comparing property types.  */
2407
2408 bool
2409 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
2410 {
2411   tree lcls, rcls, lproto, rproto;
2412   bool pointers_compatible;
2413
2414   /* We must be dealing with pointer types */
2415   if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
2416     return false;
2417
2418   do
2419     {
2420       ltyp = TREE_TYPE (ltyp);  /* Remove indirections.  */
2421       rtyp = TREE_TYPE (rtyp);
2422     }
2423   while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
2424
2425   /* We must also handle function pointers, since ObjC is a bit more
2426      lenient than C or C++ on this.  */
2427   if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
2428     {
2429       /* Return types must be covariant.  */
2430       if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
2431           && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
2432                                   argno, callee))
2433       return false;
2434
2435       /* Argument types must be contravariant.  */
2436       for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
2437            ltyp && rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
2438         {
2439           if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
2440               && !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
2441                                       argno, callee))
2442             return false;
2443       }
2444
2445       return (ltyp == rtyp);
2446     }
2447
2448   /* Past this point, we are only interested in ObjC class instances,
2449      or 'id' or 'Class'.  */
2450   if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
2451     return false;
2452
2453   if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
2454       && !TYPE_HAS_OBJC_INFO (ltyp))
2455     return false;
2456
2457   if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
2458       && !TYPE_HAS_OBJC_INFO (rtyp))
2459     return false;
2460
2461   /* Past this point, we are committed to returning 'true' to the caller
2462      (unless performing a silent comparison; see below).  However, we can
2463      still warn about type and/or protocol mismatches.  */
2464
2465   if (TYPE_HAS_OBJC_INFO (ltyp))
2466     {
2467       lcls = TYPE_OBJC_INTERFACE (ltyp);
2468       lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
2469     }
2470   else
2471     lcls = lproto = NULL_TREE;
2472
2473   if (TYPE_HAS_OBJC_INFO (rtyp))
2474     {
2475       rcls = TYPE_OBJC_INTERFACE (rtyp);
2476       rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
2477     }
2478   else
2479     rcls = rproto = NULL_TREE;
2480
2481   /* If we could not find an @interface declaration, we must have
2482      only seen a @class declaration; for purposes of type comparison,
2483      treat it as a stand-alone (root) class.  */
2484
2485   if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
2486     lcls = NULL_TREE;
2487
2488   if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
2489     rcls = NULL_TREE;
2490
2491   /* If either type is an unqualified 'id', we're done.  This is because
2492      an 'id' can be assigned to or from any type with no warnings.  */
2493   if (argno != -5)
2494     {
2495       if ((!lproto && objc_is_object_id (ltyp))
2496           || (!rproto && objc_is_object_id (rtyp)))
2497         return true;
2498     }
2499   else
2500     {
2501       /* For property checks, though, an 'id' is considered the most
2502          general type of object, hence if you try to specialize an
2503          'NSArray *' (ltyp) property with an 'id' (rtyp) one, we need
2504          to warn.  */
2505       if (!lproto && objc_is_object_id (ltyp))
2506         return true;
2507     }
2508   
2509   pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
2510
2511   /* If the underlying types are the same, and at most one of them has
2512      a protocol list, we do not need to issue any diagnostics.  */
2513   if (pointers_compatible && (!lproto || !rproto))
2514     return true;
2515
2516   /* If exactly one of the types is 'Class', issue a diagnostic; any
2517      exceptions of this rule have already been handled.  */
2518   if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
2519     pointers_compatible = false;
2520   /* Otherwise, check for inheritance relations.  */
2521   else
2522     {
2523       if (!pointers_compatible)
2524         {
2525           /* Again, if any of the two is an 'id', we're satisfied,
2526              unless we're comparing properties, in which case only an
2527              'id' on the left-hand side (old property) is good
2528              enough.  */
2529           if (argno != -5)
2530             pointers_compatible
2531               = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
2532           else
2533             pointers_compatible = objc_is_object_id (ltyp);         
2534         }
2535
2536       if (!pointers_compatible)
2537         pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
2538
2539       if (!pointers_compatible && (argno == -3 || argno == -4))
2540         pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
2541     }
2542
2543   /* If the pointers match modulo protocols, check for protocol conformance
2544      mismatches.  */
2545   if (pointers_compatible)
2546     {
2547       pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
2548                                                     argno != -3);
2549
2550       if (!pointers_compatible && argno == -3)
2551         pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
2552                                                       argno != -3);
2553     }
2554
2555   if (!pointers_compatible)
2556     {
2557       /* The two pointers are not exactly compatible.  Issue a warning, unless
2558          we are performing a silent comparison, in which case return 'false'
2559          instead.  */
2560       /* NB: For the time being, we shall make our warnings look like their
2561          C counterparts.  In the future, we may wish to make them more
2562          ObjC-specific.  */
2563       switch (argno)
2564         {
2565         case -5:
2566         case -4:
2567           return false;
2568
2569         case -3:
2570           warning (0, "comparison of distinct Objective-C types lacks a cast");
2571           break;
2572
2573         case -2:
2574           warning (0, "initialization from distinct Objective-C type");
2575           break;
2576
2577         case -1:
2578           warning (0, "assignment from distinct Objective-C type");
2579           break;
2580
2581         case 0:
2582           warning (0, "distinct Objective-C type in return");
2583           break;
2584
2585         default:
2586           warning (0, "passing argument %d of %qE from distinct "
2587                    "Objective-C type", argno, callee);
2588           break;
2589         }
2590     }
2591
2592   return true;
2593 }
2594
2595 /* This routine is similar to objc_compare_types except that function-pointers are
2596    excluded. This is because, caller assumes that common types are of (id, Object*)
2597    variety and calls objc_common_type to obtain a common type. There is no commonolty
2598    between two function-pointers in this regard. */
2599
2600 bool 
2601 objc_have_common_type (tree ltyp, tree rtyp, int argno, tree callee)
2602 {
2603   if (objc_compare_types (ltyp, rtyp, argno, callee))
2604     {
2605       /* exclude function-pointer types. */
2606       do
2607         {
2608           ltyp = TREE_TYPE (ltyp);  /* Remove indirections.  */
2609           rtyp = TREE_TYPE (rtyp);
2610         }
2611       while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
2612       return !(TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE);
2613     }
2614   return false;
2615 }
2616
2617 /* Check if LTYP and RTYP have the same type qualifiers.  If either type
2618    lives in the volatilized hash table, ignore the 'volatile' bit when
2619    making the comparison.  */
2620
2621 bool
2622 objc_type_quals_match (tree ltyp, tree rtyp)
2623 {
2624   int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
2625
2626   if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp)))
2627     lquals &= ~TYPE_QUAL_VOLATILE;
2628
2629   if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp)))
2630     rquals &= ~TYPE_QUAL_VOLATILE;
2631
2632   return (lquals == rquals);
2633 }
2634
2635 #ifndef OBJCPLUS
2636 /* Determine if CHILD is derived from PARENT.  The routine assumes that
2637    both parameters are RECORD_TYPEs, and is non-reflexive.  */
2638
2639 static bool
2640 objc_derived_from_p (tree parent, tree child)
2641 {
2642   parent = TYPE_MAIN_VARIANT (parent);
2643
2644   for (child = TYPE_MAIN_VARIANT (child);
2645        TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
2646     {
2647       child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
2648                                              (TYPE_BINFO (child),
2649                                               0)));
2650
2651       if (child == parent)
2652         return true;
2653     }
2654
2655   return false;
2656 }
2657 #endif
2658
2659 static tree
2660 objc_build_component_ref (tree datum, tree component)
2661 {
2662   /* If COMPONENT is NULL, the caller is referring to the anonymous
2663      base class field.  */
2664   if (!component)
2665     {
2666       tree base = TYPE_FIELDS (TREE_TYPE (datum));
2667
2668       return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
2669     }
2670
2671   /* The 'build_component_ref' routine has been removed from the C++
2672      front-end, but 'finish_class_member_access_expr' seems to be
2673      a worthy substitute.  */
2674 #ifdef OBJCPLUS
2675   return finish_class_member_access_expr (datum, component, false,
2676                                           tf_warning_or_error);
2677 #else
2678   return build_component_ref (input_location, datum, component);
2679 #endif
2680 }
2681
2682 /* Recursively copy inheritance information rooted at BINFO.  To do this,
2683    we emulate the song and dance performed by cp/tree.c:copy_binfo().  */
2684
2685 static tree
2686 objc_copy_binfo (tree binfo)
2687 {
2688   tree btype = BINFO_TYPE (binfo);
2689   tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
2690   tree base_binfo;
2691   int ix;
2692
2693   BINFO_TYPE (binfo2) = btype;
2694   BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
2695   BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
2696
2697   /* Recursively copy base binfos of BINFO.  */
2698   for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
2699     {
2700       tree base_binfo2 = objc_copy_binfo (base_binfo);
2701
2702       BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
2703       BINFO_BASE_APPEND (binfo2, base_binfo2);
2704     }
2705
2706   return binfo2;
2707 }
2708
2709 /* Record superclass information provided in BASETYPE for ObjC class REF.
2710    This is loosely based on cp/decl.c:xref_basetypes().  */
2711
2712 static void
2713 objc_xref_basetypes (tree ref, tree basetype)
2714 {
2715   tree binfo = make_tree_binfo (basetype ? 1 : 0);
2716
2717   TYPE_BINFO (ref) = binfo;
2718   BINFO_OFFSET (binfo) = size_zero_node;
2719   BINFO_TYPE (binfo) = ref;
2720
2721   if (basetype)
2722     {
2723       tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
2724
2725       BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
2726       BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
2727       BINFO_BASE_APPEND (binfo, base_binfo);
2728       BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
2729     }
2730 }
2731
2732 /* Called from finish_decl.  */
2733
2734 void
2735 objc_check_decl (tree decl)
2736 {
2737   tree type = TREE_TYPE (decl);
2738
2739   if (TREE_CODE (type) != RECORD_TYPE)
2740     return;
2741   if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
2742     error ("statically allocated instance of Objective-C class %qE",
2743            type);
2744 }
2745
2746 void
2747 objc_check_global_decl (tree decl)
2748 {
2749   tree id = DECL_NAME (decl);
2750   if (objc_is_class_name (id) && global_bindings_p())
2751     error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
2752 }
2753
2754 /* Return a non-volatalized version of TYPE. */
2755
2756 tree
2757 objc_non_volatilized_type (tree type)
2758 {
2759   if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type)))
2760     type = build_qualified_type (type, (TYPE_QUALS (type) & ~TYPE_QUAL_VOLATILE));
2761   return type;
2762 }
2763
2764 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
2765    either name an Objective-C class, or refer to the special 'id' or 'Class'
2766    types.  If INTERFACE is not a valid ObjC type, just return it unchanged.  */
2767
2768 tree
2769 objc_get_protocol_qualified_type (tree interface, tree protocols)
2770 {
2771   /* If INTERFACE is not provided, default to 'id'.  */
2772   tree type = (interface ? objc_is_id (interface) : objc_object_type);
2773   bool is_ptr = (type != NULL_TREE);
2774
2775   if (!is_ptr)
2776     {
2777       type = objc_is_class_name (interface);
2778
2779       if (type)
2780         {
2781           /* If looking at a typedef, retrieve the precise type it
2782              describes.  */
2783           if (TREE_CODE (interface) == IDENTIFIER_NODE)
2784             interface = identifier_global_value (interface);
2785
2786           type = ((interface && TREE_CODE (interface) == TYPE_DECL
2787                    && DECL_ORIGINAL_TYPE (interface))
2788                   ? DECL_ORIGINAL_TYPE (interface)
2789                   : xref_tag (RECORD_TYPE, type));
2790         }
2791       else
2792         {
2793           /* This case happens when we are given an 'interface' which
2794              is not a valid class name.  For example if a typedef was
2795              used, and 'interface' really is the identifier of the
2796              typedef, but when you resolve it you don't get an
2797              Objective-C class, but something else, such as 'int'.
2798              This is an error; protocols make no sense unless you use
2799              them with Objective-C objects.  */
2800           error_at (input_location, "only Objective-C object types can be qualified with a protocol");
2801
2802           /* Try to recover.  Ignore the invalid class name, and treat
2803              the object as an 'id' to silence further warnings about
2804              the class.  */
2805           type = objc_object_type;
2806           is_ptr = true;
2807         }
2808     }
2809
2810   if (protocols)
2811     {
2812       type = build_variant_type_copy (type);
2813
2814       /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
2815          to the pointee.  */
2816       if (is_ptr)
2817         {
2818           tree orig_pointee_type = TREE_TYPE (type);
2819           TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
2820
2821           /* Set up the canonical type information. */
2822           TYPE_CANONICAL (type) 
2823             = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
2824
2825           TYPE_POINTER_TO (TREE_TYPE (type)) = type;
2826           type = TREE_TYPE (type);
2827         }
2828
2829       /* Look up protocols and install in lang specific list.  */
2830       DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
2831       TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
2832
2833       /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
2834          return the pointer to the new pointee variant.  */
2835       if (is_ptr)
2836         type = TYPE_POINTER_TO (type);
2837       else
2838         TYPE_OBJC_INTERFACE (type)
2839           = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
2840     }
2841
2842   return type;
2843 }
2844
2845 /* Check for circular dependencies in protocols.  The arguments are
2846    PROTO, the protocol to check, and LIST, a list of protocol it
2847    conforms to.  */
2848
2849 static void
2850 check_protocol_recursively (tree proto, tree list)
2851 {
2852   tree p;
2853
2854   for (p = list; p; p = TREE_CHAIN (p))
2855     {
2856       tree pp = TREE_VALUE (p);
2857
2858       if (TREE_CODE (pp) == IDENTIFIER_NODE)
2859         pp = lookup_protocol (pp, /* warn if deprecated */ false);
2860
2861       if (pp == proto)
2862         fatal_error ("protocol %qE has circular dependency",
2863                      PROTOCOL_NAME (pp));
2864       if (pp)
2865         check_protocol_recursively (proto, PROTOCOL_LIST (pp));
2866     }
2867 }
2868
2869 /* Look up PROTOCOLS, and return a list of those that are found.  If
2870    none are found, return NULL.  Note that this function will emit a
2871    warning if a protocol is found and is deprecated.  */
2872
2873 static tree
2874 lookup_and_install_protocols (tree protocols)
2875 {
2876   tree proto;
2877   tree return_value = NULL_TREE;
2878
2879   if (protocols == error_mark_node)
2880     return NULL;
2881
2882   for (proto = protocols; proto; proto = TREE_CHAIN (proto))
2883     {
2884       tree ident = TREE_VALUE (proto);
2885       tree p = lookup_protocol (ident, /* warn_if_deprecated */ true);
2886
2887       if (p)
2888         return_value = chainon (return_value,
2889                                 build_tree_list (NULL_TREE, p));
2890       else if (ident != error_mark_node)
2891         error ("cannot find protocol declaration for %qE",
2892                ident);
2893     }
2894
2895   return return_value;
2896 }
2897
2898 /* Create a declaration for field NAME of a given TYPE.  */
2899
2900 static tree
2901 create_field_decl (tree type, const char *name)
2902 {
2903   return build_decl (input_location,
2904                      FIELD_DECL, get_identifier (name), type);
2905 }
2906
2907 /* Create a global, static declaration for variable NAME of a given TYPE.  The
2908    finish_var_decl() routine will need to be called on it afterwards.  */
2909
2910 static tree
2911 start_var_decl (tree type, const char *name)
2912 {
2913   tree var = build_decl (input_location,
2914                          VAR_DECL, get_identifier (name), type);
2915
2916   TREE_STATIC (var) = 1;
2917   DECL_INITIAL (var) = error_mark_node;  /* A real initializer is coming... */
2918   DECL_IGNORED_P (var) = 1;
2919   DECL_ARTIFICIAL (var) = 1;
2920   DECL_CONTEXT (var) = NULL_TREE;
2921 #ifdef OBJCPLUS
2922   DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
2923 #endif
2924
2925   return var;
2926 }
2927
2928 /* Finish off the variable declaration created by start_var_decl().  */
2929
2930 static void
2931 finish_var_decl (tree var, tree initializer)
2932 {
2933   finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
2934 }
2935
2936 /* Find the decl for the constant string class reference.  This is only
2937    used for the NeXT runtime.  */
2938
2939 static tree
2940 setup_string_decl (void)
2941 {
2942   char *name;
2943   size_t length;
2944
2945   /* %s in format will provide room for terminating null */
2946   length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
2947            + strlen (constant_string_class_name);
2948   name = XNEWVEC (char, length);
2949   sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
2950            constant_string_class_name);
2951   constant_string_global_id = get_identifier (name);
2952   string_class_decl = lookup_name (constant_string_global_id);
2953
2954   return string_class_decl;
2955 }
2956
2957 /* Purpose: "play" parser, creating/installing representations
2958    of the declarations that are required by Objective-C.
2959
2960    Model:
2961
2962         type_spec--------->sc_spec
2963         (tree_list)        (tree_list)
2964             |                  |
2965             |                  |
2966         identifier_node    identifier_node  */
2967
2968 static void
2969 synth_module_prologue (void)
2970 {
2971   tree type;
2972   enum debug_info_type save_write_symbols = write_symbols;
2973   const struct gcc_debug_hooks *const save_hooks = debug_hooks;
2974
2975   /* Suppress outputting debug symbols, because
2976      dbxout_init hasn't been called yet.  */
2977   write_symbols = NO_DEBUG;
2978   debug_hooks = &do_nothing_debug_hooks;
2979
2980 #ifdef OBJCPLUS
2981   push_lang_context (lang_name_c); /* extern "C" */
2982 #endif
2983
2984   /* The following are also defined in <objc/objc.h> and friends.  */
2985
2986   objc_object_id = get_identifier (TAG_OBJECT);
2987   objc_class_id = get_identifier (TAG_CLASS);
2988
2989   objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
2990   objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
2991
2992   objc_object_type = build_pointer_type (objc_object_reference);
2993   objc_class_type = build_pointer_type (objc_class_reference);
2994
2995   objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
2996   objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
2997
2998   /* Declare the 'id' and 'Class' typedefs.  */
2999
3000   type = lang_hooks.decls.pushdecl (build_decl (input_location,
3001                                                 TYPE_DECL,
3002                                                 objc_object_name,
3003                                                 objc_object_type));
3004   TREE_NO_WARNING (type) = 1;
3005   type = lang_hooks.decls.pushdecl (build_decl (input_location,
3006                                                 TYPE_DECL,
3007                                                 objc_class_name,
3008                                                 objc_class_type));
3009   TREE_NO_WARNING (type) = 1;
3010
3011   /* Forward-declare '@interface Protocol'.  */
3012
3013   type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
3014   objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
3015   objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
3016                                 type));
3017
3018   /* Declare type of selector-objects that represent an operation name.  */
3019
3020   if (flag_next_runtime)
3021     /* `struct objc_selector *' */
3022     objc_selector_type
3023       = build_pointer_type (xref_tag (RECORD_TYPE,
3024                                       get_identifier (TAG_SELECTOR)));
3025   else
3026     /* `const struct objc_selector *' */
3027     objc_selector_type
3028       = build_pointer_type
3029         (build_qualified_type (xref_tag (RECORD_TYPE,
3030                                          get_identifier (TAG_SELECTOR)),
3031                                TYPE_QUAL_CONST));
3032
3033   /* Declare receiver type used for dispatching messages to 'super'.  */
3034
3035   /* `struct objc_super *' */
3036   objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
3037                                                   get_identifier (TAG_SUPER)));
3038
3039   /* Declare pointers to method and ivar lists.  */
3040   objc_method_list_ptr = build_pointer_type
3041                          (xref_tag (RECORD_TYPE,
3042                                     get_identifier (UTAG_METHOD_LIST)));
3043   objc_method_proto_list_ptr
3044     = build_pointer_type (xref_tag (RECORD_TYPE,
3045                                     get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3046   objc_ivar_list_ptr = build_pointer_type
3047                        (xref_tag (RECORD_TYPE,
3048                                   get_identifier (UTAG_IVAR_LIST)));
3049
3050   /* TREE_NOTHROW is cleared for the message-sending functions,
3051      because the function that gets called can throw in Obj-C++, or
3052      could itself call something that can throw even in Obj-C.  */
3053
3054   if (flag_next_runtime)
3055     {
3056       /* NB: In order to call one of the ..._stret (struct-returning)
3057       functions, the function *MUST* first be cast to a signature that
3058       corresponds to the actual ObjC method being invoked.  This is
3059       what is done by the build_objc_method_call() routine below.  */
3060
3061       /* id objc_msgSend (id, SEL, ...); */
3062       /* id objc_msgSendNonNil (id, SEL, ...); */
3063       /* id objc_msgSend_stret (id, SEL, ...); */
3064       /* id objc_msgSendNonNil_stret (id, SEL, ...); */
3065       type
3066         = build_varargs_function_type_list (objc_object_type,
3067                                             objc_object_type,
3068                                             objc_selector_type,
3069                                             NULL_TREE);
3070       umsg_decl = add_builtin_function (TAG_MSGSEND,
3071                                         type, 0, NOT_BUILT_IN,
3072                                         NULL, NULL_TREE);
3073       umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
3074                                                type, 0, NOT_BUILT_IN,
3075                                                NULL, NULL_TREE);
3076       umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
3077                                               type, 0, NOT_BUILT_IN,
3078                                               NULL, NULL_TREE);
3079       umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
3080                                                      type, 0, NOT_BUILT_IN,
3081                                                      NULL, NULL_TREE);
3082
3083       /* These can throw, because the function that gets called can throw
3084          in Obj-C++, or could itself call something that can throw even
3085          in Obj-C.  */
3086       TREE_NOTHROW (umsg_decl) = 0;
3087       TREE_NOTHROW (umsg_nonnil_decl) = 0;
3088       TREE_NOTHROW (umsg_stret_decl) = 0;
3089       TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
3090
3091       /* id objc_msgSend_Fast (id, SEL, ...)
3092            __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
3093 #ifdef OFFS_MSGSEND_FAST
3094       umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
3095                                              type, 0, NOT_BUILT_IN,
3096                                              NULL, NULL_TREE);
3097       TREE_NOTHROW (umsg_fast_decl) = 0;
3098       DECL_ATTRIBUTES (umsg_fast_decl)
3099         = tree_cons (get_identifier ("hard_coded_address"),
3100                      build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
3101                      NULL_TREE);
3102 #else
3103       /* No direct dispatch available.  */
3104       umsg_fast_decl = umsg_decl;
3105 #endif
3106
3107       /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
3108       /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
3109       type
3110         = build_varargs_function_type_list (objc_object_type,
3111                                             objc_super_type,
3112                                             objc_selector_type,
3113                                             NULL_TREE);
3114       umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
3115                                               type, 0, NOT_BUILT_IN,
3116                                               NULL, NULL_TREE);
3117       umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
3118                                                     type, 0, NOT_BUILT_IN, 0,
3119                                                     NULL_TREE);
3120       TREE_NOTHROW (umsg_super_decl) = 0;
3121       TREE_NOTHROW (umsg_super_stret_decl) = 0;
3122     }
3123   else
3124     {
3125       /* GNU runtime messenger entry points.  */
3126
3127       /* typedef id (*IMP)(id, SEL, ...); */
3128       tree ftype =
3129         build_varargs_function_type_list (objc_object_type,
3130                                           objc_object_type,
3131                                           objc_selector_type,
3132                                           NULL_TREE);
3133       tree IMP_type = build_pointer_type (ftype);
3134
3135       /* IMP objc_msg_lookup (id, SEL); */
3136       type = build_function_type_list (IMP_type,
3137                                        objc_object_type,
3138                                        objc_selector_type,
3139                                        NULL_TREE);
3140       umsg_decl = add_builtin_function (TAG_MSGSEND,
3141                                         type, 0, NOT_BUILT_IN,
3142                                         NULL, NULL_TREE);
3143       TREE_NOTHROW (umsg_decl) = 0;
3144
3145       /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
3146       type
3147         = build_function_type_list (IMP_type,
3148                                     objc_super_type,
3149                                     objc_selector_type,
3150                                     NULL_TREE);
3151       umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
3152                                               type, 0, NOT_BUILT_IN,
3153                                               NULL, NULL_TREE);
3154       TREE_NOTHROW (umsg_super_decl) = 0;
3155
3156       /* The following GNU runtime entry point is called to initialize
3157          each module:
3158
3159          __objc_exec_class (void *); */
3160       type
3161         = build_function_type_list (void_type_node,
3162                                     ptr_type_node,
3163                                     NULL_TREE);
3164       execclass_decl = add_builtin_function (TAG_EXECCLASS,
3165                                              type, 0, NOT_BUILT_IN,
3166                                              NULL, NULL_TREE);
3167     }
3168
3169   /* id objc_getClass (const char *); */
3170
3171   type = build_function_type_list (objc_object_type,
3172                                    const_string_type_node,
3173                                    NULL_TREE);
3174
3175   objc_get_class_decl
3176     = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
3177                             NULL, NULL_TREE);
3178
3179   /* id objc_getMetaClass (const char *); */
3180
3181   objc_get_meta_class_decl
3182     = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3183
3184   build_class_template ();
3185   build_super_template ();
3186   build_protocol_template ();
3187   build_category_template ();
3188   build_objc_exception_stuff ();
3189
3190   /* Declare objc_getProperty, object_setProperty and other property
3191      accessor helpers.  */
3192   build_objc_property_accessor_helpers ();
3193
3194   if (flag_next_runtime)
3195     build_next_objc_exception_stuff ();
3196
3197   /* static SEL _OBJC_SELECTOR_TABLE[]; */
3198
3199   if (! flag_next_runtime)
3200     build_selector_table_decl ();
3201
3202   /* Forward declare constant_string_id and constant_string_type.  */
3203   if (!constant_string_class_name)
3204     constant_string_class_name = default_constant_string_class_name;
3205
3206   constant_string_id = get_identifier (constant_string_class_name);
3207   objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
3208
3209   /* Pre-build the following entities - for speed/convenience.  */
3210   self_id = get_identifier ("self");
3211   ucmd_id = get_identifier ("_cmd");
3212
3213   /* Declare struct _objc_fast_enumeration_state { ... };  */
3214   build_fast_enumeration_state_template ();
3215   
3216   /* void objc_enumeration_mutation (id) */
3217   type = build_function_type (void_type_node,
3218                               tree_cons (NULL_TREE, objc_object_type, NULL_TREE));
3219   objc_enumeration_mutation_decl 
3220     = add_builtin_function (TAG_ENUMERATION_MUTATION, type, 0, NOT_BUILT_IN, 
3221                             NULL, NULL_TREE);
3222   TREE_NOTHROW (objc_enumeration_mutation_decl) = 0;
3223
3224 #ifdef OBJCPLUS
3225   pop_lang_context ();
3226 #endif
3227
3228   write_symbols = save_write_symbols;
3229   debug_hooks = save_hooks;
3230 }
3231
3232 /* Ensure that the ivar list for NSConstantString/NXConstantString
3233    (or whatever was specified via `-fconstant-string-class')
3234    contains fields at least as large as the following three, so that
3235    the runtime can stomp on them with confidence:
3236
3237    struct STRING_OBJECT_CLASS_NAME
3238    {
3239      Object isa;
3240      char *cString;
3241      unsigned int length;
3242    }; */
3243
3244 static int
3245 check_string_class_template (void)
3246 {
3247   tree field_decl = objc_get_class_ivars (constant_string_id);
3248
3249 #define AT_LEAST_AS_LARGE_AS(F, T) \
3250   (F && TREE_CODE (F) == FIELD_DECL \
3251      && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
3252          >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
3253
3254   if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
3255     return 0;
3256
3257   field_decl = DECL_CHAIN (field_decl);
3258   if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
3259     return 0;
3260
3261   field_decl = DECL_CHAIN (field_decl);
3262   return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
3263
3264 #undef AT_LEAST_AS_LARGE_AS
3265 }
3266
3267 /* Avoid calling `check_string_class_template ()' more than once.  */
3268 static GTY(()) int string_layout_checked;
3269
3270 /* Construct an internal string layout to be used as a template for
3271    creating NSConstantString/NXConstantString instances.  */
3272
3273 static tree
3274 objc_build_internal_const_str_type (void)
3275 {
3276   tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
3277   tree fields = build_decl (input_location,
3278                             FIELD_DECL, NULL_TREE, ptr_type_node);
3279   tree field = build_decl (input_location,
3280                            FIELD_DECL, NULL_TREE, ptr_type_node);
3281
3282   DECL_CHAIN (field) = fields; fields = field;
3283   field = build_decl (input_location,
3284                       FIELD_DECL, NULL_TREE, unsigned_type_node);
3285   DECL_CHAIN (field) = fields; fields = field;
3286   /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
3287      reverse order!  */
3288   finish_builtin_struct (type, "__builtin_ObjCString",
3289                          fields, NULL_TREE);
3290
3291   return type;
3292 }
3293
3294 /* Custom build_string which sets TREE_TYPE!  */
3295
3296 static tree
3297 my_build_string (int len, const char *str)
3298 {
3299   return fix_string_type (build_string (len, str));
3300 }
3301
3302 /* Build a string with contents STR and length LEN and convert it to a
3303    pointer.  */
3304
3305 static tree
3306 my_build_string_pointer (int len, const char *str)
3307 {
3308   tree string = my_build_string (len, str);
3309   tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
3310   return build1 (ADDR_EXPR, ptrtype, string);
3311 }
3312
3313 static hashval_t
3314 string_hash (const void *ptr)
3315 {
3316   const_tree const str = ((const struct string_descriptor *)ptr)->literal;
3317   const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
3318   int i, len = TREE_STRING_LENGTH (str);
3319   hashval_t h = len;
3320
3321   for (i = 0; i < len; i++)
3322     h = ((h * 613) + p[i]);
3323
3324   return h;
3325 }
3326
3327 static int
3328 string_eq (const void *ptr1, const void *ptr2)
3329 {
3330   const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
3331   const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
3332   int len1 = TREE_STRING_LENGTH (str1);
3333
3334   return (len1 == TREE_STRING_LENGTH (str2)
3335           && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
3336                       len1));
3337 }
3338
3339 /* Given a chain of STRING_CST's, build a static instance of
3340    NXConstantString which points at the concatenation of those
3341    strings.  We place the string object in the __string_objects
3342    section of the __OBJC segment.  The Objective-C runtime will
3343    initialize the isa pointers of the string objects to point at the
3344    NXConstantString class object.  */
3345
3346 tree
3347 objc_build_string_object (tree string)
3348 {
3349   tree constant_string_class;
3350   int length;
3351   tree fields, addr;
3352   struct string_descriptor *desc, key;
3353   void **loc;
3354
3355   /* Prep the string argument.  */
3356   string = fix_string_type (string);
3357   TREE_SET_CODE (string, STRING_CST);
3358   length = TREE_STRING_LENGTH (string) - 1;
3359
3360   /* The target may have different ideas on how to construct an ObjC string 
3361      literal.  On Darwin (Mac OS X), for example, we may wish to obtain a 
3362      constant CFString reference instead.
3363      At present, this is only supported for the NeXT runtime.  */
3364   if (flag_next_runtime && targetcm.objc_construct_string_object)
3365     {
3366       tree constructor = (*targetcm.objc_construct_string_object) (string);
3367       if (constructor)
3368         return build1 (NOP_EXPR, objc_object_type, constructor);
3369     }
3370
3371   /* Check whether the string class being used actually exists and has the
3372      correct ivar layout.  */
3373   if (!string_layout_checked)
3374     {
3375       string_layout_checked = -1;
3376       constant_string_class = lookup_interface (constant_string_id);
3377       internal_const_str_type = objc_build_internal_const_str_type ();
3378
3379       if (!constant_string_class
3380           || !(constant_string_type
3381                = CLASS_STATIC_TEMPLATE (constant_string_class)))
3382         error ("cannot find interface declaration for %qE",
3383                constant_string_id);
3384       /* The NSConstantString/NXConstantString ivar layout is now known.  */
3385       else if (!check_string_class_template ())
3386         error ("interface %qE does not have valid constant string layout",
3387                constant_string_id);
3388       /* For the NeXT runtime, we can generate a literal reference
3389          to the string class, don't need to run a constructor.  */
3390       else if (flag_next_runtime && !setup_string_decl ())
3391         error ("cannot find reference tag for class %qE",
3392                constant_string_id);
3393       else
3394         {
3395           string_layout_checked = 1;  /* Success!  */
3396           add_class_reference (constant_string_id);
3397         }
3398     }
3399
3400   if (string_layout_checked == -1)
3401     return error_mark_node;
3402
3403   /* Perhaps we already constructed a constant string just like this one? */
3404   key.literal = string;
3405   loc = htab_find_slot (string_htab, &key, INSERT);
3406   desc = (struct string_descriptor *) *loc;
3407
3408   if (!desc)
3409     {
3410       tree var, constructor;
3411       VEC(constructor_elt,gc) *v = NULL;
3412       *loc = desc = ggc_alloc_string_descriptor ();
3413       desc->literal = string;
3414
3415       /* GNU:    (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length })  */
3416       /* NeXT:   (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length })   */
3417       fields = TYPE_FIELDS (internal_const_str_type);
3418       CONSTRUCTOR_APPEND_ELT (v, fields,
3419                               flag_next_runtime
3420                               ? build_unary_op (input_location,
3421                                                 ADDR_EXPR, string_class_decl, 0)
3422                               : build_int_cst (NULL_TREE, 0));
3423       fields = DECL_CHAIN (fields);
3424       CONSTRUCTOR_APPEND_ELT (v, fields,
3425                               build_unary_op (input_location,
3426                                               ADDR_EXPR, string, 1));
3427       fields = DECL_CHAIN (fields);
3428       CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
3429       constructor = objc_build_constructor (internal_const_str_type, v);
3430
3431       if (!flag_next_runtime)
3432         constructor
3433           = objc_add_static_instance (constructor, constant_string_type);
3434       else
3435         {
3436           var = build_decl (input_location,
3437                             CONST_DECL, NULL, TREE_TYPE (constructor));
3438           DECL_INITIAL (var) = constructor;
3439           TREE_STATIC (var) = 1;
3440           pushdecl_top_level (var);
3441           constructor = var;
3442         }
3443       desc->constructor = constructor;
3444     }
3445
3446   addr = convert (build_pointer_type (constant_string_type),
3447                   build_unary_op (input_location,
3448                                   ADDR_EXPR, desc->constructor, 1));
3449
3450   return addr;
3451 }
3452
3453 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR.  */
3454
3455 static GTY(()) int num_static_inst;
3456
3457 static tree
3458 objc_add_static_instance (tree constructor, tree class_decl)
3459 {
3460   tree *chain, decl;
3461   char buf[256];
3462
3463   /* Find the list of static instances for the CLASS_DECL.  Create one if
3464      not found.  */
3465   for (chain = &objc_static_instances;
3466        *chain && TREE_VALUE (*chain) != class_decl;
3467        chain = &TREE_CHAIN (*chain));
3468   if (!*chain)
3469     {
3470       *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
3471       add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
3472     }
3473
3474   sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
3475   decl = build_decl (input_location,
3476                      VAR_DECL, get_identifier (buf), class_decl);
3477   TREE_STATIC (decl) = 1;
3478   DECL_ARTIFICIAL (decl) = 1;
3479   TREE_USED (decl) = 1;
3480   DECL_INITIAL (decl) = constructor;
3481
3482   /* We may be writing something else just now.
3483      Postpone till end of input.  */
3484   DECL_DEFER_OUTPUT (decl) = 1;
3485   pushdecl_top_level (decl);
3486   rest_of_decl_compilation (decl, 1, 0);
3487
3488   /* Add the DECL to the head of this CLASS' list.  */
3489   TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
3490
3491   return decl;
3492 }
3493
3494 /* Build a static constant CONSTRUCTOR
3495    with type TYPE and elements ELTS.  */
3496
3497 static tree
3498 objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts)
3499 {
3500   tree constructor = build_constructor (type, elts);
3501
3502   TREE_CONSTANT (constructor) = 1;
3503   TREE_STATIC (constructor) = 1;
3504   TREE_READONLY (constructor) = 1;
3505
3506 #ifdef OBJCPLUS
3507   /* Adjust for impedance mismatch.  We should figure out how to build
3508      CONSTRUCTORs that consistently please both the C and C++ gods.  */
3509   if (!VEC_index (constructor_elt, elts, 0)->index)
3510     TREE_TYPE (constructor) = init_list_type_node;
3511 #endif
3512
3513   return constructor;
3514 }
3515 \f
3516 /* Take care of defining and initializing _OBJC_SYMBOLS.  */
3517
3518 /* Predefine the following data type:
3519
3520    struct _objc_symtab
3521    {
3522      long sel_ref_cnt;
3523      SEL *refs;
3524      short cls_def_cnt;
3525      short cat_def_cnt;
3526      void *defs[cls_def_cnt + cat_def_cnt];
3527    }; */
3528
3529 static void
3530 build_objc_symtab_template (void)
3531 {
3532   tree fields, *chain = NULL;
3533
3534   objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
3535
3536   /* long sel_ref_cnt; */
3537   fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
3538
3539   /* SEL *refs; */
3540   add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
3541
3542   /* short cls_def_cnt; */
3543   add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
3544
3545   /* short cat_def_cnt; */
3546   add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
3547
3548   if (imp_count || cat_count || !flag_next_runtime)
3549     {
3550       /* void *defs[imp_count + cat_count (+ 1)]; */
3551       /* NB: The index is one less than the size of the array.  */
3552       int index = imp_count + cat_count + (flag_next_runtime ? -1: 0);
3553       tree array_type = build_sized_array_type (ptr_type_node, index + 1);
3554       add_field_decl (array_type, "defs", &chain);
3555     }
3556
3557   objc_finish_struct (objc_symtab_template, fields);
3558 }
3559
3560 /* Create the initial value for the `defs' field of _objc_symtab.
3561    This is a CONSTRUCTOR.  */
3562
3563 static tree
3564 init_def_list (tree type)
3565 {
3566   tree expr;
3567   struct imp_entry *impent;
3568   VEC(constructor_elt,gc) *v = NULL;
3569
3570   if (imp_count)
3571     for (impent = imp_list; impent; impent = impent->next)
3572       {
3573         if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
3574           {
3575             expr = build_unary_op (input_location,
3576                                    ADDR_EXPR, impent->class_decl, 0);
3577             CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3578           }
3579       }
3580
3581   if (cat_count)
3582     for (impent = imp_list; impent; impent = impent->next)
3583       {
3584         if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
3585           {
3586             expr = build_unary_op (input_location,
3587                                    ADDR_EXPR, impent->class_decl, 0);
3588             CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3589           }
3590       }
3591
3592   if (!flag_next_runtime)
3593     {
3594       /* statics = { ..., _OBJC_STATIC_INSTANCES, ... }  */
3595       if (static_instances_decl)
3596         expr = build_unary_op (input_location,
3597                                ADDR_EXPR, static_instances_decl, 0);
3598       else
3599         expr = integer_zero_node;
3600
3601       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3602     }
3603
3604   return objc_build_constructor (type, v);
3605 }
3606
3607 /* Construct the initial value for all of _objc_symtab.  */
3608
3609 static tree
3610 init_objc_symtab (tree type)
3611 {
3612   VEC(constructor_elt,gc) *v = NULL;
3613
3614   /* sel_ref_cnt = { ..., 5, ... } */
3615
3616   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3617                           build_int_cst (long_integer_type_node, 0));
3618
3619   /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
3620
3621   if (flag_next_runtime || ! sel_ref_chain)
3622     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (
3623                                         build_pointer_type (objc_selector_type),
3624                                                         integer_zero_node));
3625   else
3626     {
3627       tree expr = build_unary_op (input_location, ADDR_EXPR,
3628                                   UOBJC_SELECTOR_TABLE_decl, 1);
3629
3630       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3631                               convert (build_pointer_type (objc_selector_type),
3632                                        expr));
3633     }
3634
3635   /* cls_def_cnt = { ..., 5, ... } */
3636
3637   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 
3638                           build_int_cst (short_integer_type_node, imp_count));
3639
3640   /* cat_def_cnt = { ..., 5, ... } */
3641
3642   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 
3643                           build_int_cst (short_integer_type_node, cat_count));
3644
3645   /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
3646
3647   if (imp_count || cat_count || !flag_next_runtime)
3648     {
3649
3650       tree field = TYPE_FIELDS (type);
3651       field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
3652
3653       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
3654     }
3655
3656   return objc_build_constructor (type, v);
3657 }
3658
3659 /* Generate forward declarations for metadata such as
3660   'OBJC_CLASS_...'.  */
3661
3662 static tree
3663 build_metadata_decl (const char *name, tree type)
3664 {
3665   tree decl;
3666
3667   /* struct TYPE NAME_<name>; */
3668   decl = start_var_decl (type, synth_id_with_class_suffix
3669                                (name,
3670                                 objc_implementation_context));
3671
3672   return decl;
3673 }
3674
3675 /* Push forward-declarations of all the categories so that
3676    init_def_list can use them in a CONSTRUCTOR.  */
3677
3678 static void
3679 forward_declare_categories (void)
3680 {
3681   struct imp_entry *impent;
3682   tree sav = objc_implementation_context;
3683
3684   for (impent = imp_list; impent; impent = impent->next)
3685     {
3686       if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
3687         {
3688           /* Set an invisible arg to synth_id_with_class_suffix.  */
3689           objc_implementation_context = impent->imp_context;
3690           /* extern struct objc_category _OBJC_CATEGORY_<name>; */
3691           impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
3692                                                     objc_category_template);
3693         }
3694     }
3695   objc_implementation_context = sav;
3696 }
3697
3698 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
3699    and initialized appropriately.  */
3700
3701 static void
3702 generate_objc_symtab_decl (void)
3703 {
3704  
3705   build_objc_symtab_template ();
3706   UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
3707   finish_var_decl (UOBJC_SYMBOLS_decl,
3708                    init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
3709 }
3710 \f
3711 static tree
3712 init_module_descriptor (tree type)
3713 {
3714   tree expr;
3715   VEC(constructor_elt,gc) *v = NULL;
3716
3717   /* version = { 1, ... } */
3718
3719   expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
3720   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3721
3722   /* size = { ..., sizeof (struct _objc_module), ... } */
3723
3724   expr = convert (long_integer_type_node,
3725                   size_in_bytes (objc_module_template));
3726   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3727
3728   /* Don't provide any file name for security reasons. */
3729   /* name = { ..., "", ... } */
3730
3731   expr = add_objc_string (get_identifier (""), class_names);
3732   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3733
3734   /* symtab = { ..., _OBJC_SYMBOLS, ... } */
3735
3736   if (UOBJC_SYMBOLS_decl)
3737     expr = build_unary_op (input_location,
3738                            ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
3739   else
3740     expr = null_pointer_node;
3741   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3742
3743   return objc_build_constructor (type, v);
3744 }
3745
3746 /* Write out the data structures to describe Objective C classes defined.
3747
3748    struct _objc_module { ... } _OBJC_MODULE = { ... };   */
3749
3750 static void
3751 build_module_descriptor (void)
3752 {
3753   tree decls, *chain = NULL;
3754
3755 #ifdef OBJCPLUS
3756   push_lang_context (lang_name_c); /* extern "C" */
3757 #endif
3758
3759   objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
3760
3761   /* long version; */
3762   decls = add_field_decl (long_integer_type_node, "version", &chain);
3763
3764   /* long size; */
3765   add_field_decl (long_integer_type_node, "size", &chain);
3766
3767   /* char *name; */
3768   add_field_decl (string_type_node, "name", &chain);
3769
3770   /* struct _objc_symtab *symtab; */
3771   add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
3772                                                 get_identifier (UTAG_SYMTAB))),
3773                   "symtab", &chain);
3774
3775   objc_finish_struct (objc_module_template, decls);
3776
3777   /* Create an instance of "_objc_module".  */
3778   UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
3779   /* This is the root of the metadata for defined classes and categories, it
3780      is referenced by the runtime and, therefore, needed.  */
3781   DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
3782   finish_var_decl (UOBJC_MODULES_decl,
3783                    init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
3784
3785 #ifdef OBJCPLUS
3786   pop_lang_context ();
3787 #endif
3788 }
3789
3790 /* The GNU runtime requires us to provide a static initializer function
3791    for each module:
3792
3793    static void __objc_gnu_init (void) {
3794      __objc_exec_class (&L_OBJC_MODULES);
3795    }  */
3796
3797 static void
3798 build_module_initializer_routine (void)
3799 {
3800   tree body;
3801
3802 #ifdef OBJCPLUS
3803   push_lang_context (lang_name_c); /* extern "C" */
3804 #endif
3805
3806   objc_push_parm (build_decl (input_location,
3807                               PARM_DECL, NULL_TREE, void_type_node));
3808 #ifdef OBJCPLUS
3809   objc_start_function (get_identifier (TAG_GNUINIT),
3810                        build_function_type_list (void_type_node, NULL_TREE),
3811                        NULL_TREE, NULL_TREE);
3812 #else
3813   objc_start_function (get_identifier (TAG_GNUINIT),
3814                        build_function_type_list (void_type_node, NULL_TREE),
3815                        NULL_TREE, objc_get_parm_info (0));
3816 #endif
3817   body = c_begin_compound_stmt (true);
3818   add_stmt (build_function_call
3819             (input_location,
3820              execclass_decl,
3821              build_tree_list
3822              (NULL_TREE,
3823               build_unary_op (input_location, ADDR_EXPR,
3824                               UOBJC_MODULES_decl, 0))));
3825   add_stmt (c_end_compound_stmt (input_location, body, true));
3826
3827   TREE_PUBLIC (current_function_decl) = 0;
3828
3829 #ifndef OBJCPLUS
3830   /* For Objective-C++, we will need to call __objc_gnu_init
3831      from objc_generate_static_init_call() below.  */
3832   DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
3833 #endif
3834
3835   GNU_INIT_decl = current_function_decl;
3836   finish_function ();
3837
3838 #ifdef OBJCPLUS
3839     pop_lang_context ();
3840 #endif
3841 }
3842
3843 #ifdef OBJCPLUS
3844 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
3845    to be called by the module initializer routine.  */
3846
3847 int
3848 objc_static_init_needed_p (void)
3849 {
3850   return (GNU_INIT_decl != NULL_TREE);
3851 }
3852
3853 /* Generate a call to the __objc_gnu_init initializer function.  */
3854
3855 tree
3856 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
3857 {
3858   add_stmt (build_stmt (input_location, EXPR_STMT,
3859                         build_function_call (input_location,
3860                                              GNU_INIT_decl, NULL_TREE)));
3861
3862   return ctors;
3863 }
3864 #endif /* OBJCPLUS */
3865
3866 /* Return the DECL of the string IDENT in the SECTION.  */
3867
3868 static tree
3869 get_objc_string_decl (tree ident, enum string_section section)
3870 {
3871   tree chain;
3872
3873   switch (section)
3874     {
3875     case class_names:
3876       chain = class_names_chain;
3877       break;
3878     case meth_var_names:
3879       chain = meth_var_names_chain;
3880       break;
3881     case meth_var_types:
3882       chain = meth_var_types_chain;
3883       break;
3884     default:
3885       gcc_unreachable ();
3886     }
3887
3888   for (; chain != 0; chain = TREE_CHAIN (chain))
3889     if (TREE_VALUE (chain) == ident)
3890       return (TREE_PURPOSE (chain));
3891
3892   gcc_unreachable ();
3893   return NULL_TREE;
3894 }
3895
3896 /* Output references to all statically allocated objects.  Return the DECL
3897    for the array built.  */
3898
3899 static void
3900 generate_static_references (void)
3901 {
3902   tree expr = NULL_TREE;
3903   tree class_name, klass, decl;
3904   tree cl_chain, in_chain, type
3905     = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
3906   int num_inst, num_class;
3907   char buf[256];
3908   VEC(constructor_elt,gc) *decls = NULL;
3909
3910   if (flag_next_runtime)
3911     gcc_unreachable ();
3912
3913   for (cl_chain = objc_static_instances, num_class = 0;
3914        cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
3915     {
3916       VEC(constructor_elt,gc) *v = NULL;
3917
3918       for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
3919            in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
3920
3921       sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
3922       decl = start_var_decl (type, buf);
3923
3924       /* Output {class_name, ...}.  */
3925       klass = TREE_VALUE (cl_chain);
3926       class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
3927       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3928                               build_unary_op (input_location, 
3929                                               ADDR_EXPR, class_name, 1));
3930
3931       /* Output {..., instance, ...}.  */
3932       for (in_chain = TREE_PURPOSE (cl_chain);
3933            in_chain; in_chain = TREE_CHAIN (in_chain))
3934         {
3935           expr = build_unary_op (input_location,
3936                                  ADDR_EXPR, TREE_VALUE (in_chain), 1);
3937           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3938         }
3939
3940       /* Output {..., NULL}.  */
3941       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
3942
3943       expr = objc_build_constructor (TREE_TYPE (decl), v);
3944       finish_var_decl (decl, expr);
3945       CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
3946                               build_unary_op (input_location,
3947                                               ADDR_EXPR, decl, 1));
3948     }
3949
3950   CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
3951   expr = objc_build_constructor (type, decls);
3952   static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
3953   finish_var_decl (static_instances_decl, expr);
3954 }
3955
3956 static GTY(()) int selector_reference_idx;
3957
3958 static tree
3959 build_selector_reference_decl (void)
3960 {
3961   tree decl;
3962   char buf[256];
3963
3964   sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
3965   decl = start_var_decl (objc_selector_type, buf);
3966
3967   return decl;
3968 }
3969
3970 static void
3971 build_selector_table_decl (void)
3972 {
3973   tree temp;
3974
3975   if (flag_typed_selectors)
3976     {
3977       build_selector_template ();
3978       temp = build_array_type (objc_selector_template, NULL_TREE);
3979     }
3980   else
3981     temp = build_array_type (objc_selector_type, NULL_TREE);
3982
3983   UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
3984 }
3985
3986 /* Just a handy wrapper for add_objc_string.  */
3987
3988 static tree
3989 build_selector (tree ident)
3990 {
3991   return convert (objc_selector_type,
3992                   add_objc_string (ident, meth_var_names));
3993 }
3994
3995 /* Used only by build_*_selector_translation_table (). */
3996 static void
3997 diagnose_missing_method (tree meth, location_t here)
3998 {
3999   tree method_chain;
4000   bool found = false;
4001   for (method_chain = meth_var_names_chain;
4002        method_chain;
4003        method_chain = TREE_CHAIN (method_chain))
4004     {
4005       if (TREE_VALUE (method_chain) == meth)
4006         {
4007           found = true;
4008           break;
4009         }
4010      }
4011
4012   if (!found)
4013     warning_at (here, 0, "creating selector for nonexistent method %qE",
4014                         meth);
4015 }
4016
4017 static void
4018 build_next_selector_translation_table (void)
4019 {
4020   tree chain;
4021   for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
4022     {
4023       tree expr;
4024       tree decl = TREE_PURPOSE (chain);
4025       if (warn_selector && objc_implementation_context)
4026         {
4027           location_t loc;
4028           if (decl) 
4029             loc = DECL_SOURCE_LOCATION (decl);
4030           else
4031             loc = input_location;
4032           diagnose_missing_method (TREE_VALUE (chain), loc);
4033         }
4034
4035       expr = build_selector (TREE_VALUE (chain));
4036
4037       if (decl)
4038         {
4039           /* Entries of this form are used for references to methods.
4040           The runtime re-writes these on start-up, but the compiler can't see 
4041           that and optimizes it away unless we force it.  */
4042           DECL_PRESERVE_P (decl) = 1;
4043           finish_var_decl (decl, expr);
4044         }
4045     }
4046 }
4047
4048 static void
4049 build_gnu_selector_translation_table (void)
4050 {
4051   tree chain;
4052 /*  int offset = 0;
4053   tree decl = NULL_TREE;*/
4054   VEC(constructor_elt,gc) *inits = NULL;
4055
4056   for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
4057     {
4058       tree expr;
4059
4060       if (warn_selector && objc_implementation_context)
4061         diagnose_missing_method (TREE_VALUE (chain), input_location);
4062
4063       expr = build_selector (TREE_VALUE (chain));
4064       /* add one for the '\0' character 
4065       offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
4066
4067         {
4068           if (flag_typed_selectors)
4069             {
4070               VEC(constructor_elt,gc) *v = NULL;
4071               tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
4072               CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
4073               CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
4074               expr = objc_build_constructor (objc_selector_template, v);
4075             }
4076
4077           CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
4078         }
4079     } /* each element in the chain */
4080
4081     {
4082       /* Cause the selector table (previously forward-declared)
4083          to be actually output.  */
4084       tree expr;
4085
4086       if (flag_typed_selectors)
4087         {
4088           VEC(constructor_elt,gc) *v = NULL;
4089           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
4090           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
4091           expr = objc_build_constructor (objc_selector_template, v);
4092         }
4093       else
4094         expr = integer_zero_node;
4095
4096       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
4097       expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
4098                                      inits);
4099       finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
4100     }
4101 }
4102
4103 static tree
4104 get_proto_encoding (tree proto)
4105 {
4106   tree encoding;
4107   if (proto)
4108     {
4109       if (! METHOD_ENCODING (proto))
4110         {
4111           encoding = encode_method_prototype (proto);
4112           METHOD_ENCODING (proto) = encoding;
4113         }
4114       else
4115         encoding = METHOD_ENCODING (proto);
4116
4117       return add_objc_string (encoding, meth_var_types);
4118     }
4119   else
4120     return build_int_cst (NULL_TREE, 0);
4121 }
4122
4123 /* sel_ref_chain is a list whose "value" fields will be instances of
4124    identifier_node that represent the selector.  LOC is the location of
4125    the @selector.  */
4126
4127 static tree
4128 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
4129 {
4130   tree *chain = &sel_ref_chain;
4131   tree expr;
4132   int index = 0;
4133
4134   while (*chain)
4135     {
4136       if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
4137         goto return_at_index;
4138
4139       index++;
4140       chain = &TREE_CHAIN (*chain);
4141     }
4142
4143   *chain = tree_cons (prototype, ident, NULL_TREE);
4144
4145  return_at_index:
4146   expr = build_unary_op (loc, ADDR_EXPR,
4147                          build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
4148                                           build_int_cst (NULL_TREE, index)),
4149                          1);
4150   return convert (objc_selector_type, expr);
4151 }
4152
4153 static tree
4154 build_selector_reference (location_t loc, tree ident)
4155 {
4156   tree *chain = &sel_ref_chain;
4157   tree expr;
4158   int index = 0;
4159
4160   while (*chain)
4161     {
4162       if (TREE_VALUE (*chain) == ident)
4163         return (flag_next_runtime
4164                 ? TREE_PURPOSE (*chain)
4165                 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
4166                                    build_int_cst (NULL_TREE, index)));
4167
4168       index++;
4169       chain = &TREE_CHAIN (*chain);
4170     }
4171
4172   expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
4173
4174   *chain = tree_cons (expr, ident, NULL_TREE);
4175
4176   return (flag_next_runtime
4177           ? expr
4178           : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
4179                              build_int_cst (NULL_TREE, index)));
4180 }
4181
4182 static GTY(()) int class_reference_idx;
4183
4184 static tree
4185 build_class_reference_decl (void)
4186 {
4187   tree decl;
4188   char buf[256];
4189
4190   sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
4191   decl = start_var_decl (objc_class_type, buf);
4192
4193   return decl;
4194 }
4195
4196 /* Create a class reference, but don't create a variable to reference
4197    it.  */
4198
4199 static void
4200 add_class_reference (tree ident)
4201 {
4202   tree chain;
4203
4204   if ((chain = cls_ref_chain))
4205     {
4206       tree tail;
4207       do
4208         {
4209           if (ident == TREE_VALUE (chain))
4210             return;
4211
4212           tail = chain;
4213           chain = TREE_CHAIN (chain);
4214         }
4215       while (chain);
4216
4217       /* Append to the end of the list */
4218       TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
4219     }
4220   else
4221     cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
4222 }
4223
4224 /* Get a class reference, creating it if necessary.  Also create the
4225    reference variable.  */
4226 tree
4227 objc_get_class_reference (tree ident)
4228 {
4229   tree orig_ident = (DECL_P (ident)
4230                      ? DECL_NAME (ident)
4231                      : TYPE_P (ident)
4232                      ? OBJC_TYPE_NAME (ident)
4233                      : ident);
4234   bool local_scope = false;
4235
4236 #ifdef OBJCPLUS
4237   if (processing_template_decl)
4238     /* Must wait until template instantiation time.  */
4239     return build_min_nt (CLASS_REFERENCE_EXPR, ident);
4240 #endif
4241
4242   if (TREE_CODE (ident) == TYPE_DECL)
4243     ident = (DECL_ORIGINAL_TYPE (ident)
4244              ? DECL_ORIGINAL_TYPE (ident)
4245              : TREE_TYPE (ident));
4246
4247 #ifdef OBJCPLUS
4248   if (TYPE_P (ident)
4249       && CP_TYPE_CONTEXT (ident) != global_namespace)
4250     local_scope = true;
4251 #endif
4252
4253   if (local_scope || !(ident = objc_is_class_name (ident)))
4254     {
4255       error ("%qE is not an Objective-C class name or alias",
4256              orig_ident);
4257       return error_mark_node;
4258     }
4259
4260   if (flag_next_runtime && !flag_zero_link)
4261     {
4262       tree *chain;
4263       tree decl;
4264
4265       for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
4266         if (TREE_VALUE (*chain) == ident)
4267           {
4268             if (! TREE_PURPOSE (*chain))
4269               TREE_PURPOSE (*chain) = build_class_reference_decl ();
4270
4271             return TREE_PURPOSE (*chain);
4272           }
4273
4274       decl = build_class_reference_decl ();
4275       *chain = tree_cons (decl, ident, NULL_TREE);
4276       return decl;
4277     }
4278   else
4279     {
4280       tree params;
4281
4282       add_class_reference (ident);
4283
4284       params = build_tree_list (NULL_TREE,
4285                                 my_build_string_pointer
4286                                 (IDENTIFIER_LENGTH (ident) + 1,
4287                                  IDENTIFIER_POINTER (ident)));
4288
4289       assemble_external (objc_get_class_decl);
4290       return build_function_call (input_location, objc_get_class_decl, params);
4291     }
4292 }
4293
4294 /* For each string section we have a chain which maps identifier nodes
4295    to decls for the strings.  */
4296
4297 static GTY(()) int class_names_idx;
4298 static GTY(()) int meth_var_names_idx;
4299 static GTY(()) int meth_var_types_idx;
4300
4301 static tree
4302 add_objc_string (tree ident, enum string_section section)
4303 {
4304   tree *chain, decl, type, string_expr;
4305   char buf[256];
4306   
4307   buf[0] = 0;
4308   switch (section)
4309     {
4310     case class_names:
4311       chain = &class_names_chain;
4312       sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
4313       break;
4314     case meth_var_names:
4315       chain = &meth_var_names_chain;
4316       sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
4317       break;
4318     case meth_var_types:
4319       chain = &meth_var_types_chain;
4320       sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
4321       break;
4322     default:
4323       gcc_unreachable ();
4324     }
4325
4326   while (*chain)
4327     {
4328       if (TREE_VALUE (*chain) == ident)
4329         return convert (string_type_node,
4330                         build_unary_op (input_location,
4331                                         ADDR_EXPR, TREE_PURPOSE (*chain), 1));
4332
4333       chain = &TREE_CHAIN (*chain);
4334     }
4335
4336   type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
4337   decl = start_var_decl (type, buf);
4338   string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
4339                                  IDENTIFIER_POINTER (ident));
4340   TREE_CONSTANT (decl) = 1;
4341   finish_var_decl (decl, string_expr);
4342
4343   *chain = tree_cons (decl, ident, NULL_TREE);
4344
4345   return convert (string_type_node, build_unary_op (input_location,
4346                                                     ADDR_EXPR, decl, 1));
4347 }
4348
4349 void
4350 objc_declare_alias (tree alias_ident, tree class_ident)
4351 {
4352   tree underlying_class;
4353
4354 #ifdef OBJCPLUS
4355   if (current_namespace != global_namespace) {
4356     error ("Objective-C declarations may only appear in global scope");
4357   }
4358 #endif /* OBJCPLUS */
4359
4360   if (!(underlying_class = objc_is_class_name (class_ident)))
4361     warning (0, "cannot find class %qE", class_ident);
4362   else if (objc_is_class_name (alias_ident))
4363     warning (0, "class %qE already exists", alias_ident);
4364   else
4365     {
4366       /* Implement @compatibility_alias as a typedef.  */
4367 #ifdef OBJCPLUS
4368       push_lang_context (lang_name_c); /* extern "C" */
4369 #endif
4370       lang_hooks.decls.pushdecl (build_decl
4371                                  (input_location,
4372                                   TYPE_DECL,
4373                                   alias_ident,
4374                                   xref_tag (RECORD_TYPE, underlying_class)));
4375 #ifdef OBJCPLUS
4376       pop_lang_context ();
4377 #endif
4378       hash_class_name_enter (als_name_hash_list, alias_ident, 
4379                              underlying_class);
4380     }
4381 }
4382
4383 void
4384 objc_declare_class (tree ident_list)
4385 {
4386   tree list;
4387 #ifdef OBJCPLUS
4388   if (current_namespace != global_namespace) {
4389     error ("Objective-C declarations may only appear in global scope");
4390   }
4391 #endif /* OBJCPLUS */
4392
4393   for (list = ident_list; list; list = TREE_CHAIN (list))
4394     {
4395       tree ident = TREE_VALUE (list);
4396
4397       if (! objc_is_class_name (ident))
4398         {
4399           tree record = lookup_name (ident), type = record;
4400
4401           if (record)
4402             {
4403               if (TREE_CODE (record) == TYPE_DECL)
4404                 type = DECL_ORIGINAL_TYPE (record) ? 
4405                         DECL_ORIGINAL_TYPE (record) : 
4406                         TREE_TYPE (record);
4407
4408               if (!TYPE_HAS_OBJC_INFO (type)
4409                   || !TYPE_OBJC_INTERFACE (type))
4410                 {
4411                   error ("%qE redeclared as different kind of symbol",
4412                          ident);
4413                   error ("previous declaration of %q+D",
4414                          record);
4415                 }
4416             }
4417
4418           record = xref_tag (RECORD_TYPE, ident);
4419           INIT_TYPE_OBJC_INFO (record);
4420           TYPE_OBJC_INTERFACE (record) = ident;
4421           hash_class_name_enter (cls_name_hash_list, ident, NULL_TREE);
4422         }
4423     }
4424 }
4425
4426 tree
4427 objc_is_class_name (tree ident)
4428 {
4429   hash target;
4430
4431   if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
4432       && identifier_global_value (ident))
4433     ident = identifier_global_value (ident);
4434   while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
4435     ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
4436
4437   if (ident && TREE_CODE (ident) == RECORD_TYPE)
4438     ident = OBJC_TYPE_NAME (ident);
4439 #ifdef OBJCPLUS
4440   if (ident && TREE_CODE (ident) == TYPE_DECL)
4441     {
4442       tree type = TREE_TYPE (ident);
4443       if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
4444         return NULL_TREE;
4445       ident = DECL_NAME (ident);
4446     }
4447 #endif
4448   if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
4449     return NULL_TREE;
4450
4451   if (lookup_interface (ident))
4452     return ident;
4453
4454   target = hash_class_name_lookup (cls_name_hash_list, ident);
4455   if (target)
4456     return target->key;
4457
4458   target = hash_class_name_lookup (als_name_hash_list, ident);
4459   if (target)
4460     {
4461       gcc_assert (target->list && target->list->value);
4462       return target->list->value;
4463     }
4464
4465   return 0;
4466 }
4467
4468 /* Check whether TYPE is either 'id' or 'Class'.  */
4469
4470 tree
4471 objc_is_id (tree type)
4472 {
4473   if (type && TREE_CODE (type) == IDENTIFIER_NODE
4474       && identifier_global_value (type))
4475     type = identifier_global_value (type);
4476
4477   if (type && TREE_CODE (type) == TYPE_DECL)
4478     type = TREE_TYPE (type);
4479
4480   /* NB: This function may be called before the ObjC front-end has
4481      been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL.  */
4482   return (objc_object_type && type
4483           && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
4484           ? type
4485           : NULL_TREE);
4486 }
4487
4488 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
4489    class instance.  This is needed by other parts of the compiler to
4490    handle ObjC types gracefully.  */
4491
4492 tree
4493 objc_is_object_ptr (tree type)
4494 {
4495   tree ret;
4496
4497   type = TYPE_MAIN_VARIANT (type);
4498   if (!POINTER_TYPE_P (type))
4499     return 0;
4500
4501   ret = objc_is_id (type);
4502   if (!ret)
4503     ret = objc_is_class_name (TREE_TYPE (type));
4504
4505   return ret;
4506 }
4507
4508 static int
4509 objc_is_gcable_type (tree type, int or_strong_p)
4510 {
4511   tree name;
4512
4513   if (!TYPE_P (type))
4514     return 0;
4515   if (objc_is_id (TYPE_MAIN_VARIANT (type)))
4516     return 1;
4517   if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
4518     return 1;
4519   if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
4520     return 0;
4521   type = TREE_TYPE (type);
4522   if (TREE_CODE (type) != RECORD_TYPE)
4523     return 0;
4524   name = TYPE_NAME (type);
4525   return (objc_is_class_name (name) != NULL_TREE);
4526 }
4527
4528 static tree
4529 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
4530 {
4531   if (expr == oldexpr)
4532     return newexpr;
4533
4534   switch (TREE_CODE (expr))
4535     {
4536     case COMPONENT_REF:
4537       return objc_build_component_ref
4538              (objc_substitute_decl (TREE_OPERAND (expr, 0),
4539                                     oldexpr,
4540                                     newexpr),
4541               DECL_NAME (TREE_OPERAND (expr, 1)));
4542     case ARRAY_REF:
4543       return build_array_ref (input_location,
4544                               objc_substitute_decl (TREE_OPERAND (expr, 0),
4545                                                     oldexpr,
4546                                                     newexpr),
4547                               TREE_OPERAND (expr, 1));
4548     case INDIRECT_REF:
4549       return build_indirect_ref (input_location,
4550                                  objc_substitute_decl (TREE_OPERAND (expr, 0),
4551                                                        oldexpr,
4552                                                        newexpr), RO_ARROW);
4553     default:
4554       return expr;
4555     }
4556 }
4557
4558 static tree
4559 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
4560 {
4561   tree func_params;
4562   /* The LHS parameter contains the expression 'outervar->memberspec';
4563      we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
4564      where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
4565   */
4566   tree offs
4567     = objc_substitute_decl
4568       (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
4569   tree func
4570     = (flag_objc_direct_dispatch
4571        ? objc_assign_ivar_fast_decl
4572        : objc_assign_ivar_decl);
4573
4574   offs = convert (integer_type_node, build_unary_op (input_location,
4575                                                      ADDR_EXPR, offs, 0));
4576   offs = fold (offs);
4577   func_params = tree_cons (NULL_TREE,
4578         convert (objc_object_type, rhs),
4579             tree_cons (NULL_TREE, convert (objc_object_type, outervar),
4580                 tree_cons (NULL_TREE, offs,
4581                     NULL_TREE)));
4582
4583   assemble_external (func);
4584   return build_function_call (input_location, func, func_params);
4585 }
4586
4587 static tree
4588 objc_build_global_assignment (tree lhs, tree rhs)
4589 {
4590   tree func_params = tree_cons (NULL_TREE,
4591         convert (objc_object_type, rhs),
4592             tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
4593                       build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
4594                     NULL_TREE));
4595
4596   assemble_external (objc_assign_global_decl);
4597   return build_function_call (input_location, 
4598                               objc_assign_global_decl, func_params);
4599 }
4600
4601 static tree
4602 objc_build_strong_cast_assignment (tree lhs, tree rhs)
4603 {
4604   tree func_params = tree_cons (NULL_TREE,
4605         convert (objc_object_type, rhs),
4606             tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
4607                       build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
4608                     NULL_TREE));
4609
4610   assemble_external (objc_assign_strong_cast_decl);
4611   return build_function_call (input_location,
4612                               objc_assign_strong_cast_decl, func_params);
4613 }
4614
4615 static int
4616 objc_is_gcable_p (tree expr)
4617 {
4618   return (TREE_CODE (expr) == COMPONENT_REF
4619           ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
4620           : TREE_CODE (expr) == ARRAY_REF
4621           ? (objc_is_gcable_p (TREE_TYPE (expr))
4622              || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
4623           : TREE_CODE (expr) == ARRAY_TYPE
4624           ? objc_is_gcable_p (TREE_TYPE (expr))
4625           : TYPE_P (expr)
4626           ? objc_is_gcable_type (expr, 1)
4627           : (objc_is_gcable_p (TREE_TYPE (expr))
4628              || (DECL_P (expr)
4629                  && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
4630 }
4631
4632 static int
4633 objc_is_ivar_reference_p (tree expr)
4634 {
4635   return (TREE_CODE (expr) == ARRAY_REF
4636           ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
4637           : TREE_CODE (expr) == COMPONENT_REF
4638           ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
4639           : 0);
4640 }
4641
4642 static int
4643 objc_is_global_reference_p (tree expr)
4644 {
4645   return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
4646           ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
4647           : DECL_P (expr)
4648           ? (DECL_FILE_SCOPE_P (expr) || TREE_STATIC (expr))
4649           : 0);
4650 }
4651
4652 tree
4653 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
4654 {
4655   tree result = NULL_TREE, outer;
4656   int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
4657
4658   /* See if we have any lhs casts, and strip them out.  NB: The lvalue casts
4659      will have been transformed to the form '*(type *)&expr'.  */
4660   if (TREE_CODE (lhs) == INDIRECT_REF)
4661     {
4662       outer = TREE_OPERAND (lhs, 0);
4663
4664       while (!strong_cast_p
4665              && (CONVERT_EXPR_P (outer)
4666                  || TREE_CODE (outer) == NON_LVALUE_EXPR))
4667         {
4668           tree lhstype = TREE_TYPE (outer);
4669
4670           /* Descend down the cast chain, and record the first objc_gc
4671              attribute found.  */
4672           if (POINTER_TYPE_P (lhstype))
4673             {
4674               tree attr
4675                 = lookup_attribute ("objc_gc",
4676                                     TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
4677
4678               if (attr)
4679                 strong_cast_p = 1;
4680             }
4681
4682           outer = TREE_OPERAND (outer, 0);
4683         }
4684     }
4685
4686   /* If we have a __strong cast, it trumps all else.  */
4687   if (strong_cast_p)
4688     {
4689       if (modifycode != NOP_EXPR)
4690         goto invalid_pointer_arithmetic;
4691
4692       if (warn_assign_intercept)
4693         warning (0, "strong-cast assignment has been intercepted");
4694
4695       result = objc_build_strong_cast_assignment (lhs, rhs);
4696
4697       goto exit_point;
4698     }
4699
4700   /* the lhs must be of a suitable type, regardless of its underlying
4701      structure.  */
4702   if (!objc_is_gcable_p (lhs))
4703     goto exit_point;
4704
4705   outer = lhs;
4706
4707   while (outer
4708          && (TREE_CODE (outer) == COMPONENT_REF
4709              || TREE_CODE (outer) == ARRAY_REF))
4710     outer = TREE_OPERAND (outer, 0);
4711
4712   if (TREE_CODE (outer) == INDIRECT_REF)
4713     {
4714       outer = TREE_OPERAND (outer, 0);
4715       indirect_p = 1;
4716     }
4717
4718   outer_gc_p = objc_is_gcable_p (outer);
4719
4720   /* Handle ivar assignments. */
4721   if (objc_is_ivar_reference_p (lhs))
4722     {
4723       /* if the struct to the left of the ivar is not an Objective-C object (__strong
4724          doesn't cut it here), the best we can do here is suggest a cast.  */
4725       if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
4726         {
4727           /* We may still be able to use the global write barrier... */
4728           if (!indirect_p && objc_is_global_reference_p (outer))
4729             goto global_reference;
4730
4731          suggest_cast:
4732           if (modifycode == NOP_EXPR)
4733             {
4734               if (warn_assign_intercept)
4735                 warning (0, "strong-cast may possibly be needed");
4736             }
4737
4738           goto exit_point;
4739         }
4740
4741       if (modifycode != NOP_EXPR)
4742         goto invalid_pointer_arithmetic;
4743
4744       if (warn_assign_intercept)
4745         warning (0, "instance variable assignment has been intercepted");
4746
4747       result = objc_build_ivar_assignment (outer, lhs, rhs);
4748
4749       goto exit_point;
4750     }
4751
4752   /* Likewise, intercept assignment to global/static variables if their type is
4753      GC-marked.  */
4754   if (objc_is_global_reference_p (outer))
4755     {
4756       if (indirect_p)
4757         goto suggest_cast;
4758
4759      global_reference:
4760       if (modifycode != NOP_EXPR)
4761         {
4762          invalid_pointer_arithmetic:
4763           if (outer_gc_p)
4764             warning (0, "pointer arithmetic for garbage-collected objects not allowed");
4765
4766           goto exit_point;
4767         }
4768
4769       if (warn_assign_intercept)
4770         warning (0, "global/static variable assignment has been intercepted");
4771
4772       result = objc_build_global_assignment (lhs, rhs);
4773     }
4774
4775   /* In all other cases, fall back to the normal mechanism.  */
4776  exit_point:
4777   return result;
4778 }
4779
4780 struct GTY(()) interface_tuple {
4781   tree id;
4782   tree class_name;
4783 };
4784
4785 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
4786
4787 static hashval_t
4788 hash_interface (const void *p)
4789 {
4790   const struct interface_tuple *d = (const struct interface_tuple *) p;
4791   return IDENTIFIER_HASH_VALUE (d->id);
4792 }
4793
4794 static int
4795 eq_interface (const void *p1, const void *p2)
4796 {
4797   const struct interface_tuple *d = (const struct interface_tuple *) p1;
4798   return d->id == p2;
4799 }
4800
4801 static tree
4802 lookup_interface (tree ident)
4803 {
4804 #ifdef OBJCPLUS
4805   if (ident && TREE_CODE (ident) == TYPE_DECL)
4806     ident = DECL_NAME (ident);
4807 #endif
4808
4809   if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
4810     return NULL_TREE;
4811
4812   {
4813     struct interface_tuple **slot;
4814     tree i = NULL_TREE;
4815
4816     if (interface_htab)
4817       {
4818         slot = (struct interface_tuple **)
4819           htab_find_slot_with_hash (interface_htab, ident,
4820                                     IDENTIFIER_HASH_VALUE (ident),
4821                                     NO_INSERT);
4822         if (slot && *slot)
4823           i = (*slot)->class_name;
4824       }
4825     return i;
4826   }
4827 }
4828
4829 /* Implement @defs (<classname>) within struct bodies.  */
4830
4831 tree
4832 objc_get_class_ivars (tree class_name)
4833 {
4834   tree interface = lookup_interface (class_name);
4835
4836   if (interface)
4837     return get_class_ivars (interface, true);
4838
4839   error ("cannot find interface declaration for %qE",
4840          class_name);
4841
4842   return error_mark_node;
4843 }
4844
4845 /* Called when checking the variables in a struct.  If we are not
4846    doing the ivars list inside an @interface context, then returns
4847    fieldlist unchanged.  Else, returns the list of class ivars.
4848 */
4849 tree
4850 objc_get_interface_ivars (tree fieldlist)
4851 {
4852   if (!objc_collecting_ivars || !objc_interface_context 
4853       || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE
4854       || CLASS_SUPER_NAME (objc_interface_context) == NULL_TREE)
4855     return fieldlist;
4856
4857   return get_class_ivars (objc_interface_context, true);
4858 }
4859
4860 /* Used by: build_private_template, continue_class,
4861    and for @defs constructs.  */
4862
4863 static tree
4864 get_class_ivars (tree interface, bool inherited)
4865 {
4866   tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
4867
4868   /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
4869      by the current class (i.e., they do not include super-class ivars).
4870      However, the CLASS_IVARS list will be side-effected by a call to
4871      finish_struct(), which will fill in field offsets.  */
4872   if (!CLASS_IVARS (interface))
4873     CLASS_IVARS (interface) = ivar_chain;
4874
4875   if (!inherited)
4876     return ivar_chain;
4877
4878   while (CLASS_SUPER_NAME (interface))
4879     {
4880       /* Prepend super-class ivars.  */
4881       interface = lookup_interface (CLASS_SUPER_NAME (interface));
4882       ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
4883                             ivar_chain);
4884     }
4885
4886   return ivar_chain;
4887 }
4888
4889 \f
4890 /* Exception handling constructs.  We begin by having the parser do most
4891    of the work and passing us blocks.  What we do next depends on whether
4892    we're doing "native" exception handling or legacy Darwin setjmp exceptions.
4893    We abstract all of this in a handful of appropriately named routines.  */
4894
4895 /* Stack of open try blocks.  */
4896
4897 struct objc_try_context
4898 {
4899   struct objc_try_context *outer;
4900
4901   /* Statements (or statement lists) as processed by the parser.  */
4902   tree try_body;
4903   tree finally_body;
4904
4905   /* Some file position locations.  */
4906   location_t try_locus;
4907   location_t end_try_locus;
4908   location_t end_catch_locus;
4909   location_t finally_locus;
4910   location_t end_finally_locus;
4911
4912   /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
4913      of a TRY_CATCH_EXPR.  Even when doing Darwin setjmp.  */
4914   tree catch_list;
4915
4916   /* The CATCH_EXPR of an open @catch clause.  */
4917   tree current_catch;
4918
4919   /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer.  */
4920   tree caught_decl;
4921   tree stack_decl;
4922   tree rethrow_decl;
4923 };
4924
4925 static struct objc_try_context *cur_try_context;
4926
4927 static GTY(()) tree objc_eh_personality_decl;
4928
4929 /* This hook, called via lang_eh_runtime_type, generates a runtime object
4930    that represents TYPE.  For Objective-C, this is just the class name.  */
4931 /* ??? Isn't there a class object or some such?  Is it easy to get?  */
4932
4933 #ifndef OBJCPLUS
4934 tree
4935 objc_eh_runtime_type (tree type)
4936 {
4937   return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
4938 }
4939
4940 tree
4941 objc_eh_personality (void)
4942 {
4943   if (!flag_objc_sjlj_exceptions && !objc_eh_personality_decl)
4944     objc_eh_personality_decl = build_personality_function ("gnu_objc");
4945   return objc_eh_personality_decl;
4946 }
4947 #endif
4948
4949 /* Build __builtin_eh_pointer, or the moral equivalent.  In the case
4950    of Darwin, we'll arrange for it to be initialized (and associated
4951    with a binding) later.  */
4952
4953 static tree
4954 objc_build_exc_ptr (void)
4955 {
4956   if (flag_objc_sjlj_exceptions)
4957     {
4958       tree var = cur_try_context->caught_decl;
4959       if (!var)
4960         {
4961           var = objc_create_temporary_var (objc_object_type, NULL);
4962           cur_try_context->caught_decl = var;
4963         }
4964       return var;
4965     }
4966   else
4967     {
4968       tree t;
4969       t = built_in_decls[BUILT_IN_EH_POINTER];
4970       t = build_call_expr (t, 1, integer_zero_node);
4971       return fold_convert (objc_object_type, t);
4972     }
4973 }
4974
4975 /* Build "objc_exception_try_exit(&_stack)".  */
4976
4977 static tree
4978 next_sjlj_build_try_exit (void)
4979 {
4980   tree t;
4981   t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4982   t = tree_cons (NULL, t, NULL);
4983   t = build_function_call (input_location,
4984                            objc_exception_try_exit_decl, t);
4985   return t;
4986 }
4987
4988 /* Build
4989         objc_exception_try_enter (&_stack);
4990         if (_setjmp(&_stack.buf))
4991           ;
4992         else
4993           ;
4994    Return the COND_EXPR.  Note that the THEN and ELSE fields are left
4995    empty, ready for the caller to fill them in.  */
4996
4997 static tree
4998 next_sjlj_build_enter_and_setjmp (void)
4999 {
5000   tree t, enter, sj, cond;
5001
5002   t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
5003   t = tree_cons (NULL, t, NULL);
5004   enter = build_function_call (input_location,
5005                                objc_exception_try_enter_decl, t);
5006
5007   t = objc_build_component_ref (cur_try_context->stack_decl,
5008                                 get_identifier ("buf"));
5009   t = build_fold_addr_expr_loc (input_location, t);
5010 #ifdef OBJCPLUS
5011   /* Convert _setjmp argument to type that is expected.  */
5012   if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
5013     t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
5014   else
5015     t = convert (ptr_type_node, t);
5016 #else
5017   t = convert (ptr_type_node, t);
5018 #endif
5019   t = tree_cons (NULL, t, NULL);
5020   sj = build_function_call (input_location,
5021                             objc_setjmp_decl, t);
5022
5023   cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
5024   cond = c_common_truthvalue_conversion (input_location, cond);
5025
5026   return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
5027 }
5028
5029 /* Build:
5030
5031    DECL = objc_exception_extract(&_stack);  */
5032
5033 static tree
5034 next_sjlj_build_exc_extract (tree decl)
5035 {
5036   tree t;
5037
5038   t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
5039   t = tree_cons (NULL, t, NULL);
5040   t = build_function_call (input_location,
5041                            objc_exception_extract_decl, t);
5042   t = convert (TREE_TYPE (decl), t);
5043   t = build2 (MODIFY_EXPR, void_type_node, decl, t);
5044
5045   return t;
5046 }
5047
5048 /* Build
5049         if (objc_exception_match(obj_get_class(TYPE), _caught)
5050           BODY
5051         else if (...)
5052           ...
5053         else
5054           {
5055             _rethrow = _caught;
5056             objc_exception_try_exit(&_stack);
5057           }
5058    from the sequence of CATCH_EXPRs in the current try context.  */
5059
5060 static tree
5061 next_sjlj_build_catch_list (void)
5062 {
5063   tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
5064   tree catch_seq, t;
5065   tree *last = &catch_seq;
5066   bool saw_id = false;
5067
5068   for (; !tsi_end_p (i); tsi_next (&i))
5069     {
5070       tree stmt = tsi_stmt (i);
5071       tree type = CATCH_TYPES (stmt);
5072       tree body = CATCH_BODY (stmt);
5073
5074       if (type == NULL)
5075         {
5076           *last = body;
5077           saw_id = true;
5078           break;
5079         }
5080       else
5081         {
5082           tree args, cond;
5083
5084           if (type == error_mark_node)
5085             cond = error_mark_node;
5086           else
5087             {
5088               args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
5089               t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
5090               args = tree_cons (NULL, t, args);
5091               t = build_function_call (input_location,
5092                                        objc_exception_match_decl, args);
5093               cond = c_common_truthvalue_conversion (input_location, t);
5094             }
5095           t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
5096           SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
5097
5098           *last = t;
5099           last = &COND_EXPR_ELSE (t);
5100         }
5101     }
5102
5103   if (!saw_id)
5104     {
5105       t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
5106                   cur_try_context->caught_decl);
5107       SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
5108       append_to_statement_list (t, last);
5109
5110       t = next_sjlj_build_try_exit ();
5111       SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
5112       append_to_statement_list (t, last);
5113     }
5114
5115   return catch_seq;
5116 }
5117
5118 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
5119    exception handling.  We aim to build:
5120
5121         {
5122           struct _objc_exception_data _stack;
5123           id _rethrow = 0;
5124           try
5125             {
5126               objc_exception_try_enter (&_stack);
5127               if (_setjmp(&_stack.buf))
5128                 {
5129                   id _caught = objc_exception_extract(&_stack);
5130                   objc_exception_try_enter (&_stack);
5131                   if (_setjmp(&_stack.buf))
5132                     _rethrow = objc_exception_extract(&_stack);
5133                   else
5134                     CATCH-LIST
5135                 }
5136               else
5137                 TRY-BLOCK
5138             }
5139           finally
5140             {
5141               if (!_rethrow)
5142                 objc_exception_try_exit(&_stack);
5143               FINALLY-BLOCK
5144               if (_rethrow)
5145                 objc_exception_throw(_rethrow);
5146             }
5147         }
5148
5149    If CATCH-LIST is empty, we can omit all of the block containing
5150    "_caught" except for the setting of _rethrow.  Note the use of
5151    a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
5152    but handles goto and other exits from the block.  */
5153
5154 static tree
5155 next_sjlj_build_try_catch_finally (void)
5156 {
5157   tree rethrow_decl, stack_decl, t;
5158   tree catch_seq, try_fin, bind;
5159
5160   /* Create the declarations involved.  */
5161   t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
5162   stack_decl = objc_create_temporary_var (t, NULL);
5163   cur_try_context->stack_decl = stack_decl;
5164
5165   rethrow_decl = objc_create_temporary_var (objc_object_type, NULL);
5166   cur_try_context->rethrow_decl = rethrow_decl;
5167   TREE_CHAIN (rethrow_decl) = stack_decl;
5168
5169   /* Build the outermost variable binding level.  */
5170   bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
5171   SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
5172   TREE_SIDE_EFFECTS (bind) = 1;
5173
5174   /* Initialize rethrow_decl.  */
5175   t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
5176               convert (objc_object_type, null_pointer_node));
5177   SET_EXPR_LOCATION (t, cur_try_context->try_locus);
5178   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
5179
5180   /* Build the outermost TRY_FINALLY_EXPR.  */
5181   try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
5182   SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
5183   TREE_SIDE_EFFECTS (try_fin) = 1;
5184   append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
5185
5186   /* Create the complete catch sequence.  */
5187   if (cur_try_context->catch_list)
5188     {
5189       tree caught_decl = objc_build_exc_ptr ();
5190       catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
5191       TREE_SIDE_EFFECTS (catch_seq) = 1;
5192
5193       t = next_sjlj_build_exc_extract (caught_decl);
5194       append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
5195
5196       t = next_sjlj_build_enter_and_setjmp ();
5197       COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
5198       COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
5199       append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
5200     }
5201   else
5202     catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
5203   SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
5204
5205   /* Build the main register-and-try if statement.  */
5206   t = next_sjlj_build_enter_and_setjmp ();
5207   SET_EXPR_LOCATION (t, cur_try_context->try_locus);
5208   COND_EXPR_THEN (t) = catch_seq;
5209   COND_EXPR_ELSE (t) = cur_try_context->try_body;
5210   TREE_OPERAND (try_fin, 0) = t;
5211
5212   /* Build the complete FINALLY statement list.  */
5213   t = next_sjlj_build_try_exit ();
5214   t = build_stmt (input_location, COND_EXPR,
5215                   c_common_truthvalue_conversion 
5216                     (input_location, rethrow_decl),
5217                   NULL, t);
5218   SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
5219   append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
5220
5221   append_to_statement_list (cur_try_context->finally_body,
5222                             &TREE_OPERAND (try_fin, 1));
5223
5224   t = tree_cons (NULL, rethrow_decl, NULL);
5225   t = build_function_call (input_location,
5226                            objc_exception_throw_decl, t);
5227   t = build_stmt (input_location, COND_EXPR,
5228                   c_common_truthvalue_conversion (input_location, 
5229                                                   rethrow_decl),
5230                   t, NULL);
5231   SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
5232   append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
5233
5234   return bind;
5235 }
5236
5237 /* Called just after parsing the @try and its associated BODY.  We now
5238    must prepare for the tricky bits -- handling the catches and finally.  */
5239
5240 void
5241 objc_begin_try_stmt (location_t try_locus, tree body)
5242 {
5243   struct objc_try_context *c = XCNEW (struct objc_try_context);
5244   c->outer = cur_try_context;
5245   c->try_body = body;
5246   c->try_locus = try_locus;
5247   c->end_try_locus = input_location;
5248   cur_try_context = c;
5249
5250   /* -fobjc-exceptions is required to enable Objective-C exceptions.
5251      For example, on Darwin, ObjC exceptions require a sufficiently
5252      recent version of the runtime, so the user must ask for them
5253      explicitly.  On other platforms, at the moment -fobjc-exceptions
5254      triggers -fexceptions which again is required for exceptions to
5255      work.
5256   */
5257   if (!flag_objc_exceptions)
5258     {
5259       error_at (try_locus, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
5260     }
5261
5262   if (flag_objc_sjlj_exceptions)
5263     objc_mark_locals_volatile (NULL);
5264 }
5265
5266 /* Called just after parsing "@catch (parm)".  Open a binding level,
5267    enter DECL into the binding level, and initialize it.  Leave the
5268    binding level open while the body of the compound statement is parsed.  */
5269
5270 void
5271 objc_begin_catch_clause (tree decl)
5272 {
5273   tree compound, type, t;
5274
5275   /* Begin a new scope that the entire catch clause will live in.  */
5276   compound = c_begin_compound_stmt (true);
5277
5278   /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL.  */
5279   decl = build_decl (input_location,
5280                      VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
5281   lang_hooks.decls.pushdecl (decl);
5282
5283   /* Since a decl is required here by syntax, don't warn if its unused.  */
5284   /* ??? As opposed to __attribute__((unused))?  Anyway, this appears to
5285      be what the previous objc implementation did.  */
5286   TREE_USED (decl) = 1;
5287   DECL_READ_P (decl) = 1;
5288
5289   /* Verify that the type of the catch is valid.  It must be a pointer
5290      to an Objective-C class, or "id" (which is catch-all).  */
5291   type = TREE_TYPE (decl);
5292
5293   if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
5294     type = NULL;
5295   else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
5296     {
5297       error ("@catch parameter is not a known Objective-C class type");
5298       type = error_mark_node;
5299     }
5300   else if (cur_try_context->catch_list)
5301     {
5302       /* Examine previous @catch clauses and see if we've already
5303          caught the type in question.  */
5304       tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
5305       for (; !tsi_end_p (i); tsi_next (&i))
5306         {
5307           tree stmt = tsi_stmt (i);
5308           t = CATCH_TYPES (stmt);
5309           if (t == error_mark_node)
5310             continue;
5311           if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
5312             {
5313               warning (0, "exception of type %<%T%> will be caught",
5314                        TREE_TYPE (type));
5315               warning_at  (EXPR_LOCATION (stmt), 0, "   by earlier handler for %<%T%>",
5316                            TREE_TYPE (t ? t : objc_object_type));
5317               break;
5318             }
5319         }
5320     }
5321
5322   /* Record the data for the catch in the try context so that we can
5323      finalize it later.  */
5324   t = build_stmt (input_location, CATCH_EXPR, type, compound);
5325   cur_try_context->current_catch = t;
5326
5327   /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime.  */
5328   t = objc_build_exc_ptr ();
5329   t = convert (TREE_TYPE (decl), t);
5330   t = build2 (MODIFY_EXPR, void_type_node, decl, t);
5331   add_stmt (t);
5332 }
5333
5334 /* Called just after parsing the closing brace of a @catch clause.  Close
5335    the open binding level, and record a CATCH_EXPR for it.  */
5336
5337 void
5338 objc_finish_catch_clause (void)
5339 {
5340   tree c = cur_try_context->current_catch;
5341   cur_try_context->current_catch = NULL;
5342   cur_try_context->end_catch_locus = input_location;
5343
5344   CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
5345   append_to_statement_list (c, &cur_try_context->catch_list);
5346 }
5347
5348 /* Called after parsing a @finally clause and its associated BODY.
5349    Record the body for later placement.  */
5350
5351 void
5352 objc_build_finally_clause (location_t finally_locus, tree body)
5353 {
5354   cur_try_context->finally_body = body;
5355   cur_try_context->finally_locus = finally_locus;
5356   cur_try_context->end_finally_locus = input_location;
5357 }
5358
5359 /* Called to finalize a @try construct.  */
5360
5361 tree
5362 objc_finish_try_stmt (void)
5363 {
5364   struct objc_try_context *c = cur_try_context;
5365   tree stmt;
5366
5367   if (c->catch_list == NULL && c->finally_body == NULL)
5368     error ("%<@try%> without %<@catch%> or %<@finally%>");
5369
5370   /* If we're doing Darwin setjmp exceptions, build the big nasty.  */
5371   if (flag_objc_sjlj_exceptions)
5372     {
5373       bool save = in_late_binary_op;
5374       in_late_binary_op = true;
5375       if (!cur_try_context->finally_body)
5376         {
5377           cur_try_context->finally_locus = input_location;
5378           cur_try_context->end_finally_locus = input_location;
5379         }
5380       stmt = next_sjlj_build_try_catch_finally ();
5381       in_late_binary_op = save;
5382     }
5383   else
5384     {
5385       /* Otherwise, nest the CATCH inside a FINALLY.  */
5386       stmt = c->try_body;
5387       if (c->catch_list)
5388         {
5389           stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
5390           SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
5391         }
5392       if (c->finally_body)
5393         {
5394           stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
5395           SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
5396         }
5397     }
5398   add_stmt (stmt);
5399
5400   cur_try_context = c->outer;
5401   free (c);
5402   return stmt;
5403 }
5404
5405 tree
5406 objc_build_throw_stmt (location_t loc, tree throw_expr)
5407 {
5408   tree args;
5409
5410   if (!flag_objc_exceptions)
5411     {
5412       error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
5413     }
5414
5415   if (throw_expr == NULL)
5416     {
5417       /* If we're not inside a @catch block, there is no "current
5418          exception" to be rethrown.  */
5419       if (cur_try_context == NULL
5420           || cur_try_context->current_catch == NULL)
5421         {
5422           error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
5423           return NULL_TREE;
5424         }
5425
5426       /* Otherwise the object is still sitting in the EXC_PTR_EXPR
5427          value that we get from the runtime.  */
5428       throw_expr = objc_build_exc_ptr ();
5429     }
5430
5431   /* A throw is just a call to the runtime throw function with the
5432      object as a parameter.  */
5433   args = tree_cons (NULL, throw_expr, NULL);
5434   return add_stmt (build_function_call (loc,
5435                                         objc_exception_throw_decl, args));
5436 }
5437
5438 tree
5439 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
5440 {
5441   tree args, call;
5442
5443   /* First lock the mutex.  */
5444   mutex = save_expr (mutex);
5445   args = tree_cons (NULL, mutex, NULL);
5446   call = build_function_call (input_location,
5447                               objc_sync_enter_decl, args);
5448   SET_EXPR_LOCATION (call, start_locus);
5449   add_stmt (call);
5450
5451   /* Build the mutex unlock.  */
5452   args = tree_cons (NULL, mutex, NULL);
5453   call = build_function_call (input_location,
5454                               objc_sync_exit_decl, args);
5455   SET_EXPR_LOCATION (call, input_location);
5456
5457   /* Put the that and the body in a TRY_FINALLY.  */
5458   objc_begin_try_stmt (start_locus, body);
5459   objc_build_finally_clause (input_location, call);
5460   return objc_finish_try_stmt ();
5461 }
5462
5463 \f
5464 /* Predefine the following data type:
5465
5466    struct _objc_exception_data
5467    {
5468      int buf[OBJC_JBLEN];
5469      void *pointers[4];
5470    }; */
5471
5472 /* The following yuckiness should prevent users from having to #include
5473    <setjmp.h> in their code... */
5474
5475 /* Define to a harmless positive value so the below code doesn't die.  */
5476 #ifndef OBJC_JBLEN
5477 #define OBJC_JBLEN 18
5478 #endif
5479
5480 static void
5481 build_next_objc_exception_stuff (void)
5482 {
5483   tree decls, temp_type, *chain = NULL;
5484
5485   objc_exception_data_template
5486     = objc_start_struct (get_identifier (UTAG_EXCDATA));
5487
5488   /* int buf[OBJC_JBLEN]; */
5489
5490   temp_type = build_sized_array_type (integer_type_node, OBJC_JBLEN);
5491   decls = add_field_decl (temp_type, "buf", &chain);
5492
5493   /* void *pointers[4]; */
5494
5495   temp_type = build_sized_array_type (ptr_type_node, 4);
5496   add_field_decl (temp_type, "pointers", &chain);
5497
5498   objc_finish_struct (objc_exception_data_template, decls);
5499
5500   /* int _setjmp(...); */
5501   /* If the user includes <setjmp.h>, this shall be superseded by
5502      'int _setjmp(jmp_buf);' */
5503   temp_type = build_varargs_function_type_list (integer_type_node, NULL_TREE);
5504   objc_setjmp_decl
5505     = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
5506
5507   /* id objc_exception_extract(struct _objc_exception_data *); */
5508   temp_type
5509     = build_function_type_list (objc_object_type,
5510                                 build_pointer_type (objc_exception_data_template),
5511                                 NULL_TREE);
5512   objc_exception_extract_decl
5513     = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
5514                             NULL_TREE);
5515   /* void objc_exception_try_enter(struct _objc_exception_data *); */
5516   /* void objc_exception_try_exit(struct _objc_exception_data *); */
5517   temp_type
5518     = build_function_type_list (void_type_node,
5519                                 build_pointer_type (objc_exception_data_template),
5520                                 NULL_TREE);
5521   objc_exception_try_enter_decl
5522     = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
5523                             NULL_TREE);
5524   objc_exception_try_exit_decl
5525     = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
5526                             NULL_TREE);
5527
5528   /* int objc_exception_match(id, id); */
5529   temp_type
5530     = build_function_type_list (integer_type_node,
5531                                 objc_object_type, objc_object_type, NULL_TREE);
5532   objc_exception_match_decl
5533     = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
5534                             NULL_TREE);
5535
5536   /* id objc_assign_ivar (id, id, unsigned int); */
5537   /* id objc_assign_ivar_Fast (id, id, unsigned int)
5538        __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
5539   temp_type
5540     = build_function_type_list (objc_object_type,
5541                                 objc_object_type,
5542                                 objc_object_type,
5543                                 unsigned_type_node,
5544                                 NULL_TREE);
5545   objc_assign_ivar_decl
5546     = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
5547                             NULL, NULL_TREE);
5548 #ifdef OFFS_ASSIGNIVAR_FAST
5549   objc_assign_ivar_fast_decl
5550     = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
5551                             NOT_BUILT_IN, NULL, NULL_TREE);
5552   DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
5553     = tree_cons (get_identifier ("hard_coded_address"),
5554                  build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
5555                  NULL_TREE);
5556 #else
5557   /* Default to slower ivar method.  */
5558   objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
5559 #endif
5560
5561   /* id objc_assign_global (id, id *); */
5562   /* id objc_assign_strongCast (id, id *); */
5563   temp_type = build_function_type_list (objc_object_type,
5564                                         objc_object_type,
5565                                         build_pointer_type (objc_object_type),
5566                                         NULL_TREE);
5567   objc_assign_global_decl
5568         = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
5569                                 NULL_TREE);
5570   objc_assign_strong_cast_decl
5571         = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
5572                                 NULL_TREE);
5573 }
5574
5575 static void
5576 build_objc_exception_stuff (void)
5577 {
5578   tree noreturn_list, nothrow_list, temp_type;
5579
5580   noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
5581   nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
5582
5583   /* void objc_exception_throw(id) __attribute__((noreturn)); */
5584   /* void objc_sync_enter(id); */
5585   /* void objc_sync_exit(id); */
5586   temp_type = build_function_type_list (void_type_node,
5587                                         objc_object_type,
5588                                         NULL_TREE);
5589   objc_exception_throw_decl
5590     = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
5591                             noreturn_list);
5592   objc_sync_enter_decl
5593     = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
5594                             NULL, nothrow_list);
5595   objc_sync_exit_decl
5596     = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
5597                             NULL, nothrow_list);
5598 }
5599
5600 /* Construct a C struct corresponding to ObjC class CLASS, with the same
5601    name as the class:
5602
5603    struct <classname> {
5604      struct _objc_class *isa;
5605      ...
5606    };  */
5607
5608 static void
5609 build_private_template (tree klass)
5610 {
5611   if (!CLASS_STATIC_TEMPLATE (klass))
5612     {
5613       tree record = objc_build_struct (klass,
5614                                        get_class_ivars (klass, false),
5615                                        CLASS_SUPER_NAME (klass));
5616
5617       /* Set the TREE_USED bit for this struct, so that stab generator
5618          can emit stabs for this struct type.  */
5619       if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
5620         TREE_USED (TYPE_STUB_DECL (record)) = 1;
5621
5622       /* Copy the attributes from the class to the type.  */
5623       if (TREE_DEPRECATED (klass))
5624         TREE_DEPRECATED (record) = 1;
5625     }
5626 }
5627 \f
5628 /* Begin code generation for protocols...  */
5629
5630 /* struct _objc_protocol {
5631      struct _objc_class *isa;
5632      char *protocol_name;
5633      struct _objc_protocol **protocol_list;
5634      struct _objc__method_prototype_list *instance_methods;
5635      struct _objc__method_prototype_list *class_methods;
5636    };  */
5637
5638 static void
5639 build_protocol_template (void)
5640 {
5641   tree ptype, decls, *chain = NULL;
5642
5643   objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
5644
5645   /* struct _objc_class *isa; */
5646   ptype = build_pointer_type (xref_tag (RECORD_TYPE,
5647                                         get_identifier (UTAG_CLASS)));
5648   decls = add_field_decl (ptype, "isa", &chain);
5649
5650   /* char *protocol_name; */
5651   add_field_decl (string_type_node, "protocol_name", &chain);
5652
5653   /* struct _objc_protocol **protocol_list; */
5654   ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
5655   add_field_decl (ptype, "protocol_list", &chain);
5656
5657   /* struct _objc__method_prototype_list *instance_methods; */
5658   add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
5659
5660   /* struct _objc__method_prototype_list *class_methods; */
5661   add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
5662
5663   objc_finish_struct (objc_protocol_template, decls);
5664 }
5665
5666 static tree
5667 build_descriptor_table_initializer (tree type, tree entries)
5668 {
5669   VEC(constructor_elt,gc) *inits = NULL;
5670
5671   do
5672     {
5673       VEC(constructor_elt,gc) *elts = NULL;
5674
5675       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
5676                               build_selector (METHOD_SEL_NAME (entries)));
5677       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
5678                               add_objc_string (METHOD_ENCODING (entries),
5679                                                meth_var_types));
5680
5681       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5682                               objc_build_constructor (type, elts));
5683
5684       entries = DECL_CHAIN (entries);
5685     }
5686   while (entries);
5687
5688   return objc_build_constructor (build_array_type (type, 0), inits);
5689 }
5690
5691 /* struct objc_method_prototype_list {
5692      int count;
5693      struct objc_method_prototype {
5694         SEL name;
5695         char *types;
5696      } list[1];
5697    };  */
5698
5699 static tree
5700 build_method_prototype_list_template (tree list_type, int size)
5701 {
5702   tree objc_ivar_list_record;
5703   tree array_type, decls, *chain = NULL;
5704
5705   /* Generate an unnamed struct definition.  */
5706
5707   objc_ivar_list_record = objc_start_struct (NULL_TREE);
5708
5709   /* int method_count; */
5710   decls = add_field_decl (integer_type_node, "method_count", &chain);
5711
5712   /* struct objc_method method_list[]; */
5713   array_type = build_sized_array_type (list_type, size);
5714   add_field_decl (array_type, "method_list", &chain);
5715
5716   objc_finish_struct (objc_ivar_list_record, decls);
5717
5718   return objc_ivar_list_record;
5719 }
5720
5721 static tree
5722 build_method_prototype_template (void)
5723 {
5724   tree proto_record;
5725   tree decls, *chain = NULL;
5726
5727   proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
5728
5729   /* SEL _cmd; */
5730   decls = add_field_decl (objc_selector_type, "_cmd", &chain);
5731
5732   /* char *method_types; */
5733   add_field_decl (string_type_node, "method_types", &chain);
5734
5735   objc_finish_struct (proto_record, decls);
5736
5737   return proto_record;
5738 }
5739
5740 static tree
5741 objc_method_parm_type (tree type)
5742 {
5743   type = TREE_VALUE (TREE_TYPE (type));
5744   if (TREE_CODE (type) == TYPE_DECL)
5745     type = TREE_TYPE (type);
5746   return type;
5747 }
5748
5749 static int
5750 objc_encoded_type_size (tree type)
5751 {
5752   int sz = int_size_in_bytes (type);
5753
5754   /* Make all integer and enum types at least as large
5755      as an int.  */
5756   if (sz > 0 && INTEGRAL_TYPE_P (type))
5757     sz = MAX (sz, int_size_in_bytes (integer_type_node));
5758   /* Treat arrays as pointers, since that's how they're
5759      passed in.  */
5760   else if (TREE_CODE (type) == ARRAY_TYPE)
5761     sz = int_size_in_bytes (ptr_type_node);
5762   return sz;
5763 }
5764
5765 /* Encode a method prototype.
5766
5767    The format is described in gcc/doc/objc.texi, section 'Method
5768    signatures'.
5769  */
5770 static tree
5771 encode_method_prototype (tree method_decl)
5772 {
5773   tree parms;
5774   int parm_offset, i;
5775   char buf[40];
5776   tree result;
5777
5778   /* ONEWAY and BYCOPY, for remote object are the only method qualifiers.  */
5779   encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
5780
5781   /* Encode return type.  */
5782   encode_type (objc_method_parm_type (method_decl),
5783                obstack_object_size (&util_obstack),
5784                OBJC_ENCODE_INLINE_DEFS);
5785
5786   /* Stack size.  */
5787   /* The first two arguments (self and _cmd) are pointers; account for
5788      their size.  */
5789   i = int_size_in_bytes (ptr_type_node);
5790   parm_offset = 2 * i;
5791   for (parms = METHOD_SEL_ARGS (method_decl); parms;
5792        parms = DECL_CHAIN (parms))
5793     {
5794       tree type = objc_method_parm_type (parms);
5795       int sz = objc_encoded_type_size (type);
5796
5797       /* If a type size is not known, bail out.  */
5798       if (sz < 0)
5799         {
5800           error ("type %q+D does not have a known size",
5801                  type);
5802           /* Pretend that the encoding succeeded; the compilation will
5803              fail nevertheless.  */
5804           goto finish_encoding;
5805         }
5806       parm_offset += sz;
5807     }
5808
5809   sprintf (buf, "%d@0:%d", parm_offset, i);
5810   obstack_grow (&util_obstack, buf, strlen (buf));
5811
5812   /* Argument types.  */
5813   parm_offset = 2 * i;
5814   for (parms = METHOD_SEL_ARGS (method_decl); parms;
5815        parms = DECL_CHAIN (parms))
5816     {
5817       tree type = objc_method_parm_type (parms);
5818
5819       /* Process argument qualifiers for user supplied arguments.  */
5820       encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
5821
5822       /* Type.  */
5823       encode_type (type, obstack_object_size (&util_obstack),
5824                    OBJC_ENCODE_INLINE_DEFS);
5825
5826       /* Compute offset.  */
5827       sprintf (buf, "%d", parm_offset);
5828       parm_offset += objc_encoded_type_size (type);
5829
5830       obstack_grow (&util_obstack, buf, strlen (buf));
5831     }
5832
5833   finish_encoding:
5834   obstack_1grow (&util_obstack, '\0');
5835   result = get_identifier (XOBFINISH (&util_obstack, char *));
5836   obstack_free (&util_obstack, util_firstobj);
5837   return result;
5838 }
5839
5840 static tree
5841 generate_descriptor_table (tree type, const char *name, int size, tree list,
5842                            tree proto)
5843 {
5844   tree decl;
5845   VEC(constructor_elt,gc) *v = NULL;
5846
5847   decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
5848
5849   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
5850   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
5851
5852   finish_var_decl (decl, objc_build_constructor (type, v));
5853
5854   return decl;
5855 }
5856
5857 static void
5858 generate_method_descriptors (tree protocol)
5859 {
5860   tree initlist, chain, method_list_template;
5861   int size;
5862
5863   if (!objc_method_prototype_template)
5864     objc_method_prototype_template = build_method_prototype_template ();
5865
5866   chain = PROTOCOL_CLS_METHODS (protocol);
5867   if (chain)
5868     {
5869       size = list_length (chain);
5870
5871       method_list_template
5872         = build_method_prototype_list_template (objc_method_prototype_template,
5873                                                 size);
5874
5875       initlist
5876         = build_descriptor_table_initializer (objc_method_prototype_template,
5877                                               chain);
5878
5879       UOBJC_CLASS_METHODS_decl
5880         = generate_descriptor_table (method_list_template,
5881                                      "_OBJC_PROTOCOL_CLASS_METHODS",
5882                                      size, initlist, protocol);
5883     }
5884   else
5885     UOBJC_CLASS_METHODS_decl = 0;
5886
5887   chain = PROTOCOL_NST_METHODS (protocol);
5888   if (chain)
5889     {
5890       size = list_length (chain);
5891
5892       method_list_template
5893         = build_method_prototype_list_template (objc_method_prototype_template,
5894                                                 size);
5895       initlist
5896         = build_descriptor_table_initializer (objc_method_prototype_template,
5897                                               chain);
5898
5899       UOBJC_INSTANCE_METHODS_decl
5900         = generate_descriptor_table (method_list_template,
5901                                      "_OBJC_PROTOCOL_INSTANCE_METHODS",
5902                                      size, initlist, protocol);
5903     }
5904   else
5905     UOBJC_INSTANCE_METHODS_decl = 0;
5906 }
5907
5908 static void
5909 generate_protocol_references (tree plist)
5910 {
5911   tree lproto;
5912
5913   /* Forward declare protocols referenced.  */
5914   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5915     {
5916       tree proto = TREE_VALUE (lproto);
5917
5918       if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
5919           && PROTOCOL_NAME (proto))
5920         {
5921           if (! PROTOCOL_FORWARD_DECL (proto))
5922             build_protocol_reference (proto);
5923
5924           if (PROTOCOL_LIST (proto))
5925             generate_protocol_references (PROTOCOL_LIST (proto));
5926         }
5927     }
5928 }
5929
5930 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
5931    current class.  */
5932 #ifdef OBJCPLUS
5933 static void
5934 objc_generate_cxx_ctor_or_dtor (bool dtor)
5935 {
5936   tree fn, body, compound_stmt, ivar;
5937
5938   /* - (id) .cxx_construct { ... return self; } */
5939   /* - (void) .cxx_construct { ... }            */
5940
5941   objc_start_method_definition
5942     (false /* is_class_method */,
5943      objc_build_method_signature (false /* is_class_method */,
5944                                   build_tree_list (NULL_TREE,
5945                                                    dtor
5946                                                    ? void_type_node
5947                                                    : objc_object_type),
5948                                   get_identifier (dtor
5949                                                   ? TAG_CXX_DESTRUCT
5950                                                   : TAG_CXX_CONSTRUCT),
5951                                   make_node (TREE_LIST),
5952                                   false), NULL);
5953   body = begin_function_body ();
5954   compound_stmt = begin_compound_stmt (0);
5955
5956   ivar = CLASS_IVARS (implementation_template);
5957   /* Destroy ivars in reverse order.  */
5958   if (dtor)
5959     ivar = nreverse (copy_list (ivar));
5960
5961   for (; ivar; ivar = TREE_CHAIN (ivar))
5962     {
5963       if (TREE_CODE (ivar) == FIELD_DECL)
5964         {
5965           tree type = TREE_TYPE (ivar);
5966
5967           /* Call the ivar's default constructor or destructor.  Do not
5968              call the destructor unless a corresponding constructor call
5969              has also been made (or is not needed).  */
5970           if (MAYBE_CLASS_TYPE_P (type)
5971               && (dtor
5972                   ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5973                      && (!TYPE_NEEDS_CONSTRUCTING (type)
5974                          || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5975                   : (TYPE_NEEDS_CONSTRUCTING (type)
5976                      && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
5977             finish_expr_stmt
5978              (build_special_member_call
5979               (build_ivar_reference (DECL_NAME (ivar)),
5980                dtor ? complete_dtor_identifier : complete_ctor_identifier,
5981                NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
5982         }
5983     }
5984
5985   /* The constructor returns 'self'.  */
5986   if (!dtor)
5987     finish_return_stmt (self_decl);
5988
5989   finish_compound_stmt (compound_stmt);
5990   finish_function_body (body);
5991   fn = current_function_decl;
5992   finish_function ();
5993   objc_finish_method_definition (fn);
5994 }
5995
5996 /* The following routine will examine the current @interface for any
5997    non-POD C++ ivars requiring non-trivial construction and/or
5998    destruction, and then synthesize special '- .cxx_construct' and/or
5999    '- .cxx_destruct' methods which will run the appropriate
6000    construction or destruction code.  Note that ivars inherited from
6001    super-classes are _not_ considered.  */
6002 static void
6003 objc_generate_cxx_cdtors (void)
6004 {
6005   bool need_ctor = false, need_dtor = false;
6006   tree ivar;
6007
6008   /* Error case, due to possibly an extra @end. */
6009   if (!objc_implementation_context)
6010     return;
6011
6012   /* We do not want to do this for categories, since they do not have
6013      their own ivars.  */
6014
6015   if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
6016     return;
6017
6018   /* First, determine if we even need a constructor and/or destructor.  */
6019
6020   for (ivar = CLASS_IVARS (implementation_template); ivar;
6021        ivar = TREE_CHAIN (ivar))
6022     {
6023       if (TREE_CODE (ivar) == FIELD_DECL)
6024         {
6025           tree type = TREE_TYPE (ivar);
6026
6027           if (MAYBE_CLASS_TYPE_P (type))
6028             {
6029               if (TYPE_NEEDS_CONSTRUCTING (type)
6030                   && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
6031                 /* NB: If a default constructor is not available, we will not
6032                    be able to initialize this ivar; the add_instance_variable()
6033                    routine will already have warned about this.  */
6034                 need_ctor = true;
6035
6036               if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
6037                   && (!TYPE_NEEDS_CONSTRUCTING (type)
6038                       || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
6039                 /* NB: If a default constructor is not available, we will not
6040                    call the destructor either, for symmetry.  */
6041                 need_dtor = true;
6042             }
6043         }
6044     }
6045
6046   /* Generate '- .cxx_construct' if needed.  */
6047
6048   if (need_ctor)
6049     objc_generate_cxx_ctor_or_dtor (false);
6050
6051   /* Generate '- .cxx_destruct' if needed.  */
6052
6053   if (need_dtor)
6054     objc_generate_cxx_ctor_or_dtor (true);
6055
6056   /* The 'imp_list' variable points at an imp_entry record for the current
6057      @implementation.  Record the existence of '- .cxx_construct' and/or
6058      '- .cxx_destruct' methods therein; it will be included in the
6059      metadata for the class.  */
6060   if (flag_next_runtime)
6061     imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
6062 }
6063 #endif
6064
6065 /* For each protocol which was referenced either from a @protocol()
6066    expression, or because a class/category implements it (then a
6067    pointer to the protocol is stored in the struct describing the
6068    class/category), we create a statically allocated instance of the
6069    Protocol class.  The code is written in such a way as to generate
6070    as few Protocol objects as possible; we generate a unique Protocol
6071    instance for each protocol, and we don't generate a Protocol
6072    instance if the protocol is never referenced (either from a
6073    @protocol() or from a class/category implementation).  These
6074    statically allocated objects can be referred to via the static
6075    (that is, private to this module) symbols _OBJC_PROTOCOL_n.
6076
6077    The statically allocated Protocol objects that we generate here
6078    need to be fixed up at runtime in order to be used: the 'isa'
6079    pointer of the objects need to be set up to point to the 'Protocol'
6080    class, as known at runtime.
6081
6082    The NeXT runtime fixes up all protocols at program startup time,
6083    before main() is entered.  It uses a low-level trick to look up all
6084    those symbols, then loops on them and fixes them up.
6085
6086    The GNU runtime as well fixes up all protocols before user code
6087    from the module is executed; it requires pointers to those symbols
6088    to be put in the objc_symtab (which is then passed as argument to
6089    the function __objc_exec_class() which the compiler sets up to be
6090    executed automatically when the module is loaded); setup of those
6091    Protocol objects happen in two ways in the GNU runtime: all
6092    Protocol objects referred to by a class or category implementation
6093    are fixed up when the class/category is loaded; all Protocol
6094    objects referred to by a @protocol() expression are added by the
6095    compiler to the list of statically allocated instances to fixup
6096    (the same list holding the statically allocated constant string
6097    objects).  Because, as explained above, the compiler generates as
6098    few Protocol objects as possible, some Protocol object might end up
6099    being referenced multiple times when compiled with the GNU runtime,
6100    and end up being fixed up multiple times at runtime initialization.
6101    But that doesn't hurt, it's just a little inefficient.  */
6102
6103 static void
6104 generate_protocols (void)
6105 {
6106   tree p, encoding;
6107   tree decl;
6108   tree initlist, protocol_name_expr, refs_decl, refs_expr;
6109
6110   /* If a protocol was directly referenced, pull in indirect references.  */
6111   for (p = protocol_chain; p; p = TREE_CHAIN (p))
6112     if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
6113       generate_protocol_references (PROTOCOL_LIST (p));
6114
6115   for (p = protocol_chain; p; p = TREE_CHAIN (p))
6116     {
6117       tree nst_methods = PROTOCOL_NST_METHODS (p);
6118       tree cls_methods = PROTOCOL_CLS_METHODS (p);
6119
6120       /* If protocol wasn't referenced, don't generate any code.  */
6121       decl = PROTOCOL_FORWARD_DECL (p);
6122
6123       if (!decl)
6124         continue;
6125
6126       /* Make sure we link in the Protocol class.  */
6127       add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6128
6129       while (nst_methods)
6130         {
6131           if (! METHOD_ENCODING (nst_methods))
6132             {
6133               encoding = encode_method_prototype (nst_methods);
6134               METHOD_ENCODING (nst_methods) = encoding;
6135             }
6136           nst_methods = DECL_CHAIN (nst_methods);
6137         }
6138
6139       while (cls_methods)
6140         {
6141           if (! METHOD_ENCODING (cls_methods))
6142             {
6143               encoding = encode_method_prototype (cls_methods);
6144               METHOD_ENCODING (cls_methods) = encoding;
6145             }
6146
6147           cls_methods = DECL_CHAIN (cls_methods);
6148         }
6149       generate_method_descriptors (p);
6150
6151       if (PROTOCOL_LIST (p))
6152         refs_decl = generate_protocol_list (p);
6153       else
6154         refs_decl = 0;
6155
6156       /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
6157       protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
6158
6159       if (refs_decl)
6160         refs_expr = convert (build_pointer_type (build_pointer_type
6161                                                  (objc_protocol_template)),
6162                              build_unary_op (input_location,
6163                                              ADDR_EXPR, refs_decl, 0));
6164       else
6165         refs_expr = build_int_cst (NULL_TREE, 0);
6166
6167       /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
6168          by generate_method_descriptors, which is called above.  */
6169       initlist = build_protocol_initializer (TREE_TYPE (decl),
6170                                              protocol_name_expr, refs_expr,
6171                                              UOBJC_INSTANCE_METHODS_decl,
6172                                              UOBJC_CLASS_METHODS_decl);
6173       finish_var_decl (decl, initlist);
6174     }
6175 }
6176
6177 static tree
6178 build_protocol_initializer (tree type, tree protocol_name,
6179                             tree protocol_list, tree instance_methods,
6180                             tree class_methods)
6181 {
6182   tree expr;
6183   tree cast_type = build_pointer_type
6184                    (xref_tag (RECORD_TYPE,
6185                               get_identifier (UTAG_CLASS)));
6186   VEC(constructor_elt,gc) *inits = NULL;
6187
6188   /* Filling the "isa" in with one allows the runtime system to
6189      detect that the version change...should remove before final release.  */
6190
6191   expr = build_int_cst (cast_type, PROTOCOL_VERSION);
6192   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
6193   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
6194   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
6195
6196   if (!instance_methods)
6197     CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
6198   else
6199     {
6200       expr = convert (objc_method_proto_list_ptr,
6201                       build_unary_op (input_location, 
6202                                       ADDR_EXPR, instance_methods, 0));
6203       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
6204     }
6205
6206   if (!class_methods)
6207     CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
6208   else
6209     {
6210       expr = convert (objc_method_proto_list_ptr,
6211                       build_unary_op (input_location, 
6212                                       ADDR_EXPR, class_methods, 0));
6213       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
6214     }
6215
6216   return objc_build_constructor (type, inits);
6217 }
6218 \f
6219 /* struct _objc_category {
6220      char *category_name;
6221      char *class_name;
6222      struct _objc_method_list *instance_methods;
6223      struct _objc_method_list *class_methods;
6224      struct _objc_protocol_list *protocols;
6225    };   */
6226
6227 static void
6228 build_category_template (void)
6229 {
6230   tree ptype, decls, *chain = NULL;
6231
6232   objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
6233
6234   /* char *category_name; */
6235   decls = add_field_decl (string_type_node, "category_name", &chain);
6236
6237   /* char *class_name; */
6238   add_field_decl (string_type_node, "class_name", &chain);
6239
6240   /* struct _objc_method_list *instance_methods; */
6241   add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
6242
6243   /* struct _objc_method_list *class_methods; */
6244   add_field_decl (objc_method_list_ptr, "class_methods", &chain);
6245
6246   /* struct _objc_protocol **protocol_list; */
6247   ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
6248   add_field_decl (ptype, "protocol_list", &chain);
6249
6250   objc_finish_struct (objc_category_template, decls);
6251 }
6252
6253 /* struct _objc_selector {
6254      SEL sel_id;
6255      char *sel_type;
6256    }; */
6257
6258 static void
6259 build_selector_template (void)
6260 {
6261   tree decls, *chain = NULL;
6262
6263   objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
6264
6265   /* SEL sel_id; */
6266   decls = add_field_decl (objc_selector_type, "sel_id", &chain);
6267
6268   /* char *sel_type; */
6269   add_field_decl (string_type_node, "sel_type", &chain);
6270
6271   objc_finish_struct (objc_selector_template, decls);
6272 }
6273
6274 /* struct _objc_class {
6275      struct _objc_class *isa;
6276      struct _objc_class *super_class;
6277      char *name;
6278      long version;
6279      long info;
6280      long instance_size;
6281      struct _objc_ivar_list *ivars;
6282      struct _objc_method_list *methods;
6283      #ifdef __NEXT_RUNTIME__
6284        struct objc_cache *cache;
6285      #else
6286        struct sarray *dtable;
6287        struct _objc_class *subclass_list;
6288        struct _objc_class *sibling_class;
6289      #endif
6290      struct _objc_protocol_list *protocols;
6291      #ifdef __NEXT_RUNTIME__
6292        void *sel_id;
6293      #endif
6294      void *gc_object_type;
6295    };  */
6296
6297 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
6298    the NeXT/Apple runtime; still, the compiler must generate them to
6299    maintain backward binary compatibility (and to allow for future
6300    expansion).  */
6301
6302 static void
6303 build_class_template (void)
6304 {
6305   tree ptype, decls, *chain = NULL;
6306
6307   objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
6308
6309   /* struct _objc_class *isa; */
6310   decls = add_field_decl (build_pointer_type (objc_class_template),
6311                           "isa", &chain);
6312
6313   /* struct _objc_class *super_class; */
6314   add_field_decl (build_pointer_type (objc_class_template),
6315                   "super_class", &chain);
6316
6317   /* char *name; */
6318   add_field_decl (string_type_node, "name", &chain);
6319
6320   /* long version; */
6321   add_field_decl (long_integer_type_node, "version", &chain);
6322
6323   /* long info; */
6324   add_field_decl (long_integer_type_node, "info", &chain);
6325
6326   /* long instance_size; */
6327   add_field_decl (long_integer_type_node, "instance_size", &chain);
6328
6329   /* struct _objc_ivar_list *ivars; */
6330   add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
6331
6332   /* struct _objc_method_list *methods; */
6333   add_field_decl (objc_method_list_ptr, "methods", &chain);
6334
6335   if (flag_next_runtime)
6336     {
6337       /* struct objc_cache *cache; */
6338       ptype = build_pointer_type (xref_tag (RECORD_TYPE,
6339                                             get_identifier ("objc_cache")));
6340       add_field_decl (ptype, "cache", &chain);
6341     }
6342   else
6343     {
6344       /* struct sarray *dtable; */
6345       ptype = build_pointer_type(xref_tag (RECORD_TYPE,
6346                                            get_identifier ("sarray")));
6347       add_field_decl (ptype, "dtable", &chain);
6348
6349       /* struct objc_class *subclass_list; */
6350       ptype = build_pointer_type (objc_class_template);
6351       add_field_decl (ptype, "subclass_list", &chain);
6352
6353       /* struct objc_class *sibling_class; */
6354       ptype = build_pointer_type (objc_class_template);
6355       add_field_decl (ptype, "sibling_class", &chain);
6356     }
6357
6358   /* struct _objc_protocol **protocol_list; */
6359   ptype = build_pointer_type (build_pointer_type
6360                               (xref_tag (RECORD_TYPE,
6361                                          get_identifier (UTAG_PROTOCOL))));
6362   add_field_decl (ptype, "protocol_list", &chain);
6363
6364   if (flag_next_runtime)
6365     {
6366       /* void *sel_id; */
6367       add_field_decl (build_pointer_type (void_type_node), "sel_id", &chain);
6368     }
6369
6370   /* void *gc_object_type; */
6371   add_field_decl (build_pointer_type (void_type_node),
6372                   "gc_object_type", &chain);
6373
6374   objc_finish_struct (objc_class_template, decls);
6375 }
6376
6377 /* Generate appropriate forward declarations for an implementation.  */
6378
6379 static void
6380 synth_forward_declarations (void)
6381 {
6382   tree an_id;
6383
6384   /* static struct objc_class _OBJC_CLASS_<my_name>; */
6385   UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
6386                                           objc_class_template);
6387
6388   /* static struct objc_class _OBJC_METACLASS_<my_name>; */
6389   UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
6390                                                   objc_class_template);
6391
6392   /* Pre-build the following entities - for speed/convenience.  */
6393
6394   an_id = get_identifier ("super_class");
6395   ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
6396   uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
6397 }
6398
6399 static void
6400 error_with_ivar (const char *message, tree decl)
6401 {
6402   error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
6403             message, identifier_to_locale (gen_declaration (decl)));
6404
6405 }
6406
6407 static void
6408 check_ivars (tree inter, tree imp)
6409 {
6410   tree intdecls = CLASS_RAW_IVARS (inter);
6411   tree impdecls = CLASS_RAW_IVARS (imp);
6412
6413   while (1)
6414     {
6415       tree t1, t2;
6416
6417 #ifdef OBJCPLUS
6418       if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
6419         intdecls = TREE_CHAIN (intdecls);
6420 #endif
6421       if (intdecls == 0 && impdecls == 0)
6422         break;
6423       if (intdecls == 0 || impdecls == 0)
6424         {
6425           error ("inconsistent instance variable specification");
6426           break;
6427         }
6428
6429       t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
6430
6431       if (!comptypes (t1, t2)
6432           || !tree_int_cst_equal (DECL_INITIAL (intdecls),
6433                                   DECL_INITIAL (impdecls)))
6434         {
6435           if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
6436             {
6437               error_with_ivar ("conflicting instance variable type",
6438                                impdecls);
6439               error_with_ivar ("previous declaration of",
6440                                intdecls);
6441             }
6442           else                  /* both the type and the name don't match */
6443             {
6444               error ("inconsistent instance variable specification");
6445               break;
6446             }
6447         }
6448
6449       else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
6450         {
6451           error_with_ivar ("conflicting instance variable name",
6452                            impdecls);
6453           error_with_ivar ("previous declaration of",
6454                            intdecls);
6455         }
6456
6457       intdecls = DECL_CHAIN (intdecls);
6458       impdecls = DECL_CHAIN (impdecls);
6459     }
6460 }
6461
6462 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
6463    This needs to be done just once per compilation.  */
6464
6465 /* struct _objc_super {
6466      struct _objc_object *self;
6467      struct _objc_class *super_class;
6468    };  */
6469
6470 static void
6471 build_super_template (void)
6472 {
6473   tree decls, *chain = NULL;
6474
6475   objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
6476
6477   /* struct _objc_object *self; */
6478   decls = add_field_decl (objc_object_type, "self", &chain);
6479
6480   /* struct _objc_class *super_class; */
6481   add_field_decl (build_pointer_type (objc_class_template),
6482                   "super_class", &chain);
6483
6484   objc_finish_struct (objc_super_template, decls);
6485 }
6486
6487 /* struct _objc_ivar {
6488      char *ivar_name;
6489      char *ivar_type;
6490      int ivar_offset;
6491    };  */
6492
6493 static tree
6494 build_ivar_template (void)
6495 {
6496   tree objc_ivar_id, objc_ivar_record;
6497   tree decls, *chain = NULL;
6498
6499   objc_ivar_id = get_identifier (UTAG_IVAR);
6500   objc_ivar_record = objc_start_struct (objc_ivar_id);
6501
6502   /* char *ivar_name; */
6503   decls = add_field_decl (string_type_node, "ivar_name", &chain);
6504
6505   /* char *ivar_type; */
6506   add_field_decl (string_type_node, "ivar_type", &chain);
6507
6508   /* int ivar_offset; */
6509   add_field_decl (integer_type_node, "ivar_offset", &chain);
6510
6511   objc_finish_struct (objc_ivar_record, decls);
6512
6513   return objc_ivar_record;
6514 }
6515
6516 /* struct {
6517      int ivar_count;
6518      struct objc_ivar ivar_list[ivar_count];
6519    };  */
6520
6521 static tree
6522 build_ivar_list_template (tree list_type, int size)
6523 {
6524   tree objc_ivar_list_record;
6525   tree array_type, decls, *chain = NULL;
6526
6527   objc_ivar_list_record = objc_start_struct (NULL_TREE);
6528
6529   /* int ivar_count; */
6530   decls = add_field_decl (integer_type_node, "ivar_count", &chain);
6531
6532   /* struct objc_ivar ivar_list[]; */
6533   array_type = build_sized_array_type (list_type, size);
6534   add_field_decl (array_type, "ivar_list", &chain);
6535
6536   objc_finish_struct (objc_ivar_list_record, decls);
6537
6538   return objc_ivar_list_record;
6539 }
6540
6541 /* struct {
6542      struct _objc__method_prototype_list *method_next;
6543      int method_count;
6544      struct objc_method method_list[method_count];
6545    };  */
6546
6547 static tree
6548 build_method_list_template (tree list_type, int size)
6549 {
6550   tree objc_ivar_list_record;
6551   tree array_type, decls, *chain = NULL;
6552
6553   objc_ivar_list_record = objc_start_struct (NULL_TREE);
6554
6555   /* struct _objc__method_prototype_list *method_next; */
6556   decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
6557
6558   /* int method_count; */
6559   add_field_decl (integer_type_node, "method_count", &chain);
6560
6561   /* struct objc_method method_list[]; */
6562   array_type = build_sized_array_type (list_type, size);
6563   add_field_decl (array_type, "method_list", &chain);
6564
6565   objc_finish_struct (objc_ivar_list_record, decls);
6566
6567   return objc_ivar_list_record;
6568 }
6569
6570 static tree
6571 build_ivar_list_initializer (tree type, tree field_decl)
6572 {
6573   VEC(constructor_elt,gc) *inits = NULL;
6574
6575   do
6576     {
6577       VEC(constructor_elt,gc) *ivar = NULL;
6578       tree id;
6579
6580       /* Set name.  */
6581       if (DECL_NAME (field_decl))
6582         CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
6583                                 add_objc_string (DECL_NAME (field_decl),
6584                                                  meth_var_names));
6585       else
6586         /* Unnamed bit-field ivar (yuck).  */
6587         CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
6588
6589       /* Set type.  */
6590       encode_field_decl (field_decl,
6591                          obstack_object_size (&util_obstack),
6592                          OBJC_ENCODE_DONT_INLINE_DEFS);
6593
6594       /* Null terminate string.  */
6595       obstack_1grow (&util_obstack, 0);
6596       id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
6597                             meth_var_types);
6598       CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
6599       obstack_free (&util_obstack, util_firstobj);
6600
6601       /* Set offset.  */
6602       CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
6603       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
6604                               objc_build_constructor (type, ivar));
6605       do
6606         field_decl = DECL_CHAIN (field_decl);
6607       while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
6608     }
6609   while (field_decl);
6610
6611   return objc_build_constructor (build_array_type (type, 0), inits);
6612 }
6613
6614 static tree
6615 generate_ivars_list (tree type, const char *name, int size, tree list)
6616 {
6617   tree decl;
6618   VEC(constructor_elt,gc) *inits = NULL;
6619
6620   decl = start_var_decl (type, synth_id_with_class_suffix
6621                                (name, objc_implementation_context));
6622
6623   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
6624   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, list);
6625
6626   finish_var_decl (decl,
6627                    objc_build_constructor (TREE_TYPE (decl), inits));
6628
6629   return decl;
6630 }
6631
6632 /* Count only the fields occurring in T.  */
6633
6634 static int
6635 ivar_list_length (tree t)
6636 {
6637   int count = 0;
6638
6639   for (; t; t = DECL_CHAIN (t))
6640     if (TREE_CODE (t) == FIELD_DECL)
6641       ++count;
6642
6643   return count;
6644 }
6645
6646 static void
6647 generate_ivar_lists (void)
6648 {
6649   tree initlist, ivar_list_template, chain;
6650   int size;
6651
6652   generating_instance_variables = 1;
6653
6654   if (!objc_ivar_template)
6655     objc_ivar_template = build_ivar_template ();
6656
6657   /* Only generate class variables for the root of the inheritance
6658      hierarchy since these will be the same for every class.  */
6659
6660   if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
6661       && (chain = TYPE_FIELDS (objc_class_template)))
6662     {
6663       size = ivar_list_length (chain);
6664
6665       ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
6666       initlist = build_ivar_list_initializer (objc_ivar_template, chain);
6667
6668       UOBJC_CLASS_VARIABLES_decl
6669         = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
6670                                size, initlist);
6671     }
6672   else
6673     UOBJC_CLASS_VARIABLES_decl = 0;
6674
6675   chain = CLASS_IVARS (implementation_template);
6676   if (chain)
6677     {
6678       size = ivar_list_length (chain);
6679       ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
6680       initlist = build_ivar_list_initializer (objc_ivar_template, chain);
6681
6682       UOBJC_INSTANCE_VARIABLES_decl
6683         = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
6684                                size, initlist);
6685     }
6686   else
6687     UOBJC_INSTANCE_VARIABLES_decl = 0;
6688
6689   generating_instance_variables = 0;
6690 }
6691
6692 static tree
6693 build_dispatch_table_initializer (tree type, tree entries)
6694 {
6695   VEC(constructor_elt,gc) *inits = NULL;
6696
6697   do
6698     {
6699       VEC(constructor_elt,gc) *elems = NULL;
6700       tree expr;
6701
6702       CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
6703                               build_selector (METHOD_SEL_NAME (entries)));
6704
6705       /* Generate the method encoding if we don't have one already.  */
6706       if (! METHOD_ENCODING (entries))
6707         METHOD_ENCODING (entries) =
6708           encode_method_prototype (entries);
6709
6710       CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
6711                               add_objc_string (METHOD_ENCODING (entries),
6712                                                meth_var_types));
6713
6714       expr = convert (ptr_type_node,
6715                       build_unary_op (input_location, ADDR_EXPR,
6716                                       METHOD_DEFINITION (entries), 1));
6717       CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
6718
6719       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
6720                               objc_build_constructor (type, elems));
6721
6722       entries = DECL_CHAIN (entries);
6723     }
6724   while (entries);
6725
6726   return objc_build_constructor (build_array_type (type, 0), inits);
6727 }
6728
6729 /* To accomplish method prototyping without generating all kinds of
6730    inane warnings, the definition of the dispatch table entries were
6731    changed from:
6732
6733         struct objc_method { SEL _cmd; ...; id (*_imp)(); };
6734    to:
6735         struct objc_method { SEL _cmd; ...; void *_imp; };  */
6736
6737 static tree
6738 build_method_template (void)
6739 {
6740   tree _SLT_record;
6741   tree decls, *chain = NULL;
6742
6743   _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
6744
6745   /* SEL _cmd; */
6746   decls = add_field_decl (objc_selector_type, "_cmd", &chain);
6747
6748   /* char *method_types; */
6749   add_field_decl (string_type_node, "method_types", &chain);
6750
6751   /* void *_imp; */
6752   add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
6753
6754   objc_finish_struct (_SLT_record, decls);
6755
6756   return _SLT_record;
6757 }
6758
6759
6760 static tree
6761 generate_dispatch_table (tree type, const char *name, int size, tree list)
6762 {
6763   tree decl;
6764   VEC(constructor_elt,gc) *v = NULL;
6765
6766   decl = start_var_decl (type, synth_id_with_class_suffix
6767                                (name, objc_implementation_context));
6768
6769   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
6770   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, size));
6771   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
6772
6773   finish_var_decl (decl,
6774                    objc_build_constructor (TREE_TYPE (decl), v));
6775
6776   return decl;
6777 }
6778
6779 static void
6780 mark_referenced_methods (void)
6781 {
6782   struct imp_entry *impent;
6783   tree chain;
6784
6785   for (impent = imp_list; impent; impent = impent->next)
6786     {
6787       chain = CLASS_CLS_METHODS (impent->imp_context);
6788       while (chain)
6789         {
6790           cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6791           chain = DECL_CHAIN (chain);
6792         }
6793
6794       chain = CLASS_NST_METHODS (impent->imp_context);
6795       while (chain)
6796         {
6797           cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6798           chain = DECL_CHAIN (chain);
6799         }
6800     }
6801 }
6802
6803 static void
6804 generate_dispatch_tables (void)
6805 {
6806   tree initlist, chain, method_list_template;
6807   int size;
6808
6809   if (!objc_method_template)
6810     objc_method_template = build_method_template ();
6811
6812   chain = CLASS_CLS_METHODS (objc_implementation_context);
6813   if (chain)
6814     {
6815       size = list_length (chain);
6816
6817       method_list_template
6818         = build_method_list_template (objc_method_template, size);
6819       initlist
6820         = build_dispatch_table_initializer (objc_method_template, chain);
6821
6822       UOBJC_CLASS_METHODS_decl
6823         = generate_dispatch_table (method_list_template,
6824                                    ((TREE_CODE (objc_implementation_context)
6825                                      == CLASS_IMPLEMENTATION_TYPE)
6826                                     ? "_OBJC_CLASS_METHODS"
6827                                     : "_OBJC_CATEGORY_CLASS_METHODS"),
6828                                    size, initlist);
6829     }
6830   else
6831     UOBJC_CLASS_METHODS_decl = 0;
6832
6833   chain = CLASS_NST_METHODS (objc_implementation_context);
6834   if (chain)
6835     {
6836       size = list_length (chain);
6837
6838       method_list_template
6839         = build_method_list_template (objc_method_template, size);
6840       initlist
6841         = build_dispatch_table_initializer (objc_method_template, chain);
6842
6843       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6844         UOBJC_INSTANCE_METHODS_decl
6845           = generate_dispatch_table (method_list_template,
6846                                      "_OBJC_INSTANCE_METHODS",
6847                                      size, initlist);
6848       else
6849         /* We have a category.  */
6850         UOBJC_INSTANCE_METHODS_decl
6851           = generate_dispatch_table (method_list_template,
6852                                      "_OBJC_CATEGORY_INSTANCE_METHODS",
6853                                      size, initlist);
6854     }
6855   else
6856     UOBJC_INSTANCE_METHODS_decl = 0;
6857 }
6858
6859 static tree
6860 generate_protocol_list (tree i_or_p)
6861 {
6862   tree array_type, ptype, refs_decl, lproto, e, plist;
6863   int size = 0;
6864   const char *ref_name;
6865   VEC(constructor_elt,gc) *v = NULL;
6866
6867   switch (TREE_CODE (i_or_p))
6868     {
6869     case CLASS_INTERFACE_TYPE:
6870     case CATEGORY_INTERFACE_TYPE:
6871       plist = CLASS_PROTOCOL_LIST (i_or_p);
6872       break;
6873     case PROTOCOL_INTERFACE_TYPE:
6874       plist = PROTOCOL_LIST (i_or_p);
6875       break;
6876     default:
6877       gcc_unreachable ();
6878     }
6879
6880   /* Compute size.  */
6881   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6882     if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
6883         && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
6884       size++;
6885
6886   /* Build initializer.  */
6887   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6888   e = build_int_cst (build_pointer_type (objc_protocol_template), size);
6889   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6890
6891   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6892     {
6893       tree pval = TREE_VALUE (lproto);
6894
6895       if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
6896           && PROTOCOL_FORWARD_DECL (pval))
6897         {
6898           e = build_unary_op (input_location, ADDR_EXPR, 
6899                               PROTOCOL_FORWARD_DECL (pval), 0);
6900           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6901         }
6902     }
6903
6904   /* static struct objc_protocol *refs[n]; */
6905
6906   switch (TREE_CODE (i_or_p))
6907     {
6908     case PROTOCOL_INTERFACE_TYPE:
6909       ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
6910       break;
6911     case CLASS_INTERFACE_TYPE:
6912       ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
6913       break;
6914     case CATEGORY_INTERFACE_TYPE:
6915       ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
6916       break;
6917     default:
6918       gcc_unreachable ();
6919     }
6920
6921   ptype = build_pointer_type (objc_protocol_template);
6922   array_type = build_sized_array_type (ptype, size + 3);
6923   refs_decl = start_var_decl (array_type, ref_name);
6924
6925   finish_var_decl (refs_decl,
6926                    objc_build_constructor (TREE_TYPE (refs_decl), v));
6927
6928   return refs_decl;
6929 }
6930
6931 static tree
6932 build_category_initializer (tree type, tree cat_name, tree class_name,
6933                             tree instance_methods, tree class_methods,
6934                             tree protocol_list)
6935 {
6936   tree expr;
6937   VEC(constructor_elt,gc) *v = NULL;
6938
6939   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
6940   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
6941
6942   if (!instance_methods)
6943     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6944   else
6945     {
6946       expr = convert (objc_method_list_ptr,
6947                       build_unary_op (input_location, ADDR_EXPR, 
6948                                       instance_methods, 0));
6949       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6950     }
6951   if (!class_methods)
6952     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6953   else
6954     {
6955       expr = convert (objc_method_list_ptr,
6956                       build_unary_op (input_location, ADDR_EXPR, 
6957                                       class_methods, 0));
6958       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6959     }
6960
6961   /* protocol_list = */
6962   if (!protocol_list)
6963     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6964   else
6965     {
6966       expr = convert (build_pointer_type
6967                       (build_pointer_type
6968                        (objc_protocol_template)),
6969                       build_unary_op (input_location, ADDR_EXPR, 
6970                                       protocol_list, 0));
6971       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6972     }
6973
6974   return objc_build_constructor (type, v);
6975 }
6976
6977 /* struct _objc_class {
6978      struct objc_class *isa;
6979      struct objc_class *super_class;
6980      char *name;
6981      long version;
6982      long info;
6983      long instance_size;
6984      struct objc_ivar_list *ivars;
6985      struct objc_method_list *methods;
6986      if (flag_next_runtime)
6987        struct objc_cache *cache;
6988      else {
6989        struct sarray *dtable;
6990        struct objc_class *subclass_list;
6991        struct objc_class *sibling_class;
6992      }
6993      struct objc_protocol_list *protocols;
6994      if (flag_next_runtime)
6995        void *sel_id;
6996      void *gc_object_type;
6997    };  */
6998
6999 static tree
7000 build_shared_structure_initializer (tree type, tree isa, tree super,
7001                                     tree name, tree size, int status,
7002                                     tree dispatch_table, tree ivar_list,
7003                                     tree protocol_list)
7004 {
7005   tree expr;
7006   VEC(constructor_elt,gc) *v = NULL;
7007
7008   /* isa = */
7009   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
7010
7011   /* super_class = */
7012   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
7013
7014   /* name = */
7015   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
7016
7017   /* version = */
7018   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
7019                           build_int_cst (long_integer_type_node, 0));
7020
7021   /* info = */
7022   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
7023                           build_int_cst (long_integer_type_node, status));
7024
7025   /* instance_size = */
7026   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
7027                           convert (long_integer_type_node, size));
7028
7029   /* objc_ivar_list = */
7030   if (!ivar_list)
7031     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7032   else
7033     {
7034       expr = convert (objc_ivar_list_ptr,
7035                       build_unary_op (input_location, ADDR_EXPR, 
7036                                       ivar_list, 0));
7037       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
7038     }
7039
7040   /* objc_method_list = */
7041   if (!dispatch_table)
7042     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7043   else
7044     {
7045       expr = convert (objc_method_list_ptr,
7046                       build_unary_op (input_location, ADDR_EXPR, 
7047                                       dispatch_table, 0));
7048       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
7049     }
7050
7051   if (flag_next_runtime)
7052     /* method_cache = */
7053     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7054   else
7055     {
7056       /* dtable = */
7057       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7058
7059       /* subclass_list = */
7060       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7061
7062       /* sibling_class = */
7063       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7064     }
7065
7066   /* protocol_list = */
7067   if (! protocol_list)
7068     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7069   else
7070     {
7071       expr = convert (build_pointer_type
7072                       (build_pointer_type
7073                        (objc_protocol_template)),
7074                       build_unary_op (input_location, ADDR_EXPR, 
7075                                       protocol_list, 0));
7076       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
7077     }
7078
7079   if (flag_next_runtime)
7080     /* sel_id = NULL */
7081     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7082
7083   /* gc_object_type = NULL */
7084   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7085
7086   return objc_build_constructor (type, v);
7087 }
7088
7089 /* Retrieve category interface CAT_NAME (if any) associated with CLASS.  */
7090
7091 static inline tree
7092 lookup_category (tree klass, tree cat_name)
7093 {
7094   tree category = CLASS_CATEGORY_LIST (klass);
7095
7096   while (category && CLASS_SUPER_NAME (category) != cat_name)
7097     category = CLASS_CATEGORY_LIST (category);
7098   return category;
7099 }
7100
7101 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... };  */
7102
7103 static void
7104 generate_category (struct imp_entry *impent)
7105 {
7106   tree initlist, cat_name_expr, class_name_expr;
7107   tree protocol_decl, category;
7108   tree cat = impent->imp_context;
7109
7110   implementation_template = impent->imp_template;
7111   UOBJC_CLASS_decl = impent->class_decl;
7112   UOBJC_METACLASS_decl = impent->meta_decl;
7113
7114   add_class_reference (CLASS_NAME (cat));
7115   cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
7116
7117   class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
7118
7119   category = lookup_category (implementation_template,
7120                                 CLASS_SUPER_NAME (cat));
7121
7122   if (category && CLASS_PROTOCOL_LIST (category))
7123     {
7124       generate_protocol_references (CLASS_PROTOCOL_LIST (category));
7125       protocol_decl = generate_protocol_list (category);
7126     }
7127   else
7128     protocol_decl = 0;
7129
7130   initlist = build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl),
7131                                          cat_name_expr, class_name_expr,
7132                                          UOBJC_INSTANCE_METHODS_decl,
7133                                          UOBJC_CLASS_METHODS_decl,
7134                                          protocol_decl);
7135   /* Finish and initialize the forward decl.  */
7136   finish_var_decl (UOBJC_CLASS_decl, initlist);
7137 }
7138
7139 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
7140    static struct objc_class _OBJC_CLASS_Foo={ ... };  */
7141
7142 static void
7143 generate_shared_structures (struct imp_entry *impent)
7144 {
7145   tree name_expr, super_expr, root_expr;
7146   tree my_root_id, my_super_id;
7147   tree cast_type, initlist, protocol_decl;
7148   int cls_flags;
7149   
7150   objc_implementation_context = impent->imp_context;
7151   implementation_template = impent->imp_template;
7152   UOBJC_CLASS_decl = impent->class_decl;
7153   UOBJC_METACLASS_decl = impent->meta_decl;
7154   cls_flags = impent->has_cxx_cdtors ? CLS_HAS_CXX_STRUCTORS : 0 ;
7155   
7156   my_super_id = CLASS_SUPER_NAME (implementation_template);
7157   if (my_super_id)
7158     {
7159       add_class_reference (my_super_id);
7160
7161       /* Compute "my_root_id" - this is required for code generation.
7162          the "isa" for all meta class structures points to the root of
7163          the inheritance hierarchy (e.g. "__Object")...  */
7164       my_root_id = my_super_id;
7165       do
7166         {
7167           tree my_root_int = lookup_interface (my_root_id);
7168
7169           if (my_root_int && CLASS_SUPER_NAME (my_root_int))
7170             my_root_id = CLASS_SUPER_NAME (my_root_int);
7171           else
7172             break;
7173         }
7174       while (1);
7175     }
7176   else
7177     /* No super class.  */
7178     my_root_id = CLASS_NAME (implementation_template);
7179
7180   cast_type = build_pointer_type (objc_class_template);
7181   name_expr = add_objc_string (CLASS_NAME (implementation_template),
7182                                class_names);
7183
7184   /* Install class `isa' and `super' pointers at runtime.  */
7185   if (my_super_id)
7186     super_expr = add_objc_string (my_super_id, class_names);
7187   else
7188     super_expr = integer_zero_node;
7189     
7190   super_expr = build_c_cast (input_location,
7191                                  cast_type, super_expr); /* cast! */
7192
7193   root_expr = add_objc_string (my_root_id, class_names);
7194   root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
7195
7196   if (CLASS_PROTOCOL_LIST (implementation_template))
7197     {
7198       generate_protocol_references
7199         (CLASS_PROTOCOL_LIST (implementation_template));
7200       protocol_decl = generate_protocol_list (implementation_template);
7201     }
7202   else
7203     protocol_decl = 0;
7204
7205   /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
7206
7207   initlist
7208     = build_shared_structure_initializer
7209       (TREE_TYPE (UOBJC_METACLASS_decl),
7210        root_expr, super_expr, name_expr,
7211        convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
7212        2 /*CLS_META*/,
7213        UOBJC_CLASS_METHODS_decl,
7214        UOBJC_CLASS_VARIABLES_decl,
7215        protocol_decl);
7216
7217   finish_var_decl (UOBJC_METACLASS_decl, initlist);
7218
7219   /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
7220
7221   initlist
7222     = build_shared_structure_initializer
7223       (TREE_TYPE (UOBJC_CLASS_decl),
7224        build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
7225        super_expr, name_expr,
7226        convert (integer_type_node,
7227                 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
7228                                 (implementation_template))),
7229        1 /*CLS_FACTORY*/ | cls_flags,
7230        UOBJC_INSTANCE_METHODS_decl,
7231        UOBJC_INSTANCE_VARIABLES_decl,
7232        protocol_decl);
7233
7234   finish_var_decl (UOBJC_CLASS_decl, initlist);
7235 }
7236
7237
7238 static const char *
7239 synth_id_with_class_suffix (const char *preamble, tree ctxt)
7240 {
7241   static char string[BUFSIZE];
7242
7243   switch (TREE_CODE (ctxt))
7244     {
7245     case CLASS_IMPLEMENTATION_TYPE:
7246     case CLASS_INTERFACE_TYPE:
7247       sprintf (string, "%s_%s", preamble,
7248                IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
7249       break;
7250     case CATEGORY_IMPLEMENTATION_TYPE:
7251     case CATEGORY_INTERFACE_TYPE:
7252       {
7253         /* We have a category.  */
7254         const char *const class_name
7255           = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7256         const char *const class_super_name
7257           = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
7258         sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
7259         break;
7260     }
7261     case PROTOCOL_INTERFACE_TYPE:
7262       {
7263         const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
7264         sprintf (string, "%s_%s", preamble, protocol_name);
7265         break;
7266       }
7267     default:
7268       gcc_unreachable ();
7269     }
7270
7271   return string;
7272 }
7273
7274 /* If type is empty or only type qualifiers are present, add default
7275    type of id (otherwise grokdeclarator will default to int).  */
7276 static inline tree
7277 adjust_type_for_id_default (tree type)
7278 {
7279   if (!type)
7280     type = make_node (TREE_LIST);
7281
7282   if (!TREE_VALUE (type))
7283     TREE_VALUE (type) = objc_object_type;
7284   else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
7285            && TYPED_OBJECT (TREE_VALUE (type)))
7286     error ("can not use an object as parameter to a method");
7287
7288   return type;
7289 }
7290
7291 /* Return a KEYWORD_DECL built using the specified key_name, arg_type,
7292    arg_name and attributes. (TODO: Rename KEYWORD_DECL to
7293    OBJC_METHOD_PARM_DECL ?)
7294
7295    A KEYWORD_DECL is a tree representing the declaration of a
7296    parameter of an Objective-C method.  It is produced when parsing a
7297    fragment of Objective-C method declaration of the form
7298
7299    keyworddecl:
7300      selector ':' '(' typename ')' identifier
7301
7302    For example, take the Objective-C method
7303
7304    -(NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type; 
7305
7306    the two fragments "pathForResource:(NSString *)resource" and
7307    "ofType:(NSString *)type" will generate a KEYWORD_DECL each.  The
7308    KEYWORD_DECL stores the 'key_name' (eg, identifier for
7309    "pathForResource"), the 'arg_type' (eg, tree representing a
7310    NSString *), the 'arg_name' (eg identifier for "resource") and
7311    potentially some attributes (for example, a tree representing
7312    __attribute__ ((unused)) if such an attribute was attached to a
7313    certain parameter).  You can access this information using the
7314    TREE_TYPE (for arg_type), KEYWORD_ARG_NAME (for arg_name),
7315    KEYWORD_KEY_NAME (for key_name), DECL_ATTRIBUTES (for attributes).
7316
7317    'key_name' is an identifier node (and is optional as you can omit
7318    it in Objective-C methods).
7319    'arg_type' is a tree list (and is optional too if no parameter type
7320    was specified).
7321    'arg_name' is an identifier node and is required.
7322    'attributes' is an optional tree containing parameter attributes.  */
7323 tree
7324 objc_build_keyword_decl (tree key_name, tree arg_type, 
7325                          tree arg_name, tree attributes)
7326 {
7327   tree keyword_decl;
7328
7329   if (flag_objc1_only && attributes)
7330     error_at (input_location, "method argument attributes are not available in Objective-C 1.0");
7331
7332   /* If no type is specified, default to "id".  */
7333   arg_type = adjust_type_for_id_default (arg_type);
7334
7335   keyword_decl = make_node (KEYWORD_DECL);
7336
7337   TREE_TYPE (keyword_decl) = arg_type;
7338   KEYWORD_ARG_NAME (keyword_decl) = arg_name;
7339   KEYWORD_KEY_NAME (keyword_decl) = key_name;
7340   DECL_ATTRIBUTES (keyword_decl) = attributes;
7341
7342   return keyword_decl;
7343 }
7344
7345 /* Given a chain of keyword_decl's, synthesize the full keyword selector.  */
7346 static tree
7347 build_keyword_selector (tree selector)
7348 {
7349   int len = 0;
7350   tree key_chain, key_name;
7351   char *buf;
7352
7353   /* Scan the selector to see how much space we'll need.  */
7354   for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
7355     {
7356       switch (TREE_CODE (selector))
7357         {
7358         case KEYWORD_DECL:
7359           key_name = KEYWORD_KEY_NAME (key_chain);
7360           break;
7361         case TREE_LIST:
7362           key_name = TREE_PURPOSE (key_chain);
7363           break;
7364         default:
7365           gcc_unreachable ();
7366         }
7367
7368       if (key_name)
7369         len += IDENTIFIER_LENGTH (key_name) + 1;
7370       else
7371         /* Just a ':' arg.  */
7372         len++;
7373     }
7374
7375   buf = (char *) alloca (len + 1);
7376   /* Start the buffer out as an empty string.  */
7377   buf[0] = '\0';
7378
7379   for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
7380     {
7381       switch (TREE_CODE (selector))
7382         {
7383         case KEYWORD_DECL:
7384           key_name = KEYWORD_KEY_NAME (key_chain);
7385           break;
7386         case TREE_LIST:
7387           key_name = TREE_PURPOSE (key_chain);
7388           /* The keyword decl chain will later be used as a function
7389              argument chain.  Unhook the selector itself so as to not
7390              confuse other parts of the compiler.  */
7391           TREE_PURPOSE (key_chain) = NULL_TREE;
7392           break;
7393         default:
7394           gcc_unreachable ();
7395         }
7396
7397       if (key_name)
7398         strcat (buf, IDENTIFIER_POINTER (key_name));
7399       strcat (buf, ":");
7400     }
7401
7402   return get_identifier (buf);
7403 }
7404
7405 /* Used for declarations and definitions.  */
7406
7407 static tree
7408 build_method_decl (enum tree_code code, tree ret_type, tree selector,
7409                    tree add_args, bool ellipsis)
7410 {
7411   tree method_decl;
7412
7413   /* If no type is specified, default to "id".  */
7414   ret_type = adjust_type_for_id_default (ret_type);
7415
7416   /* Note how a method_decl has a TREE_TYPE which is not the function
7417      type of the function implementing the method, but only the return
7418      type of the method.  We may want to change this, and store the
7419      entire function type in there (eg, it may be used to simplify
7420      dealing with attributes below).  */
7421   method_decl = make_node (code);
7422   TREE_TYPE (method_decl) = ret_type;
7423
7424   /* If we have a keyword selector, create an identifier_node that
7425      represents the full selector name (`:' included)...  */
7426   if (TREE_CODE (selector) == KEYWORD_DECL)
7427     {
7428       METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
7429       METHOD_SEL_ARGS (method_decl) = selector;
7430       METHOD_ADD_ARGS (method_decl) = add_args;
7431       METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
7432     }
7433   else
7434     {
7435       METHOD_SEL_NAME (method_decl) = selector;
7436       METHOD_SEL_ARGS (method_decl) = NULL_TREE;
7437       METHOD_ADD_ARGS (method_decl) = NULL_TREE;
7438     }
7439
7440   return method_decl;
7441 }
7442
7443 #define METHOD_DEF 0
7444 #define METHOD_REF 1
7445
7446 /* This routine processes objective-c method attributes. */
7447
7448 static void
7449 objc_decl_method_attributes (tree *node, tree attributes, int flags)
7450 {
7451   /* TODO: Replace the hackery below.  An idea would be to store the
7452      full function type in the method declaration (for example in
7453      TREE_TYPE) and then expose ObjC method declarations to c-family
7454      and they could deal with them by simply treating them as
7455      functions.  */
7456
7457   /* Because of the dangers in the hackery below, we filter out any
7458      attribute that we do not know about.  For the ones we know about,
7459      we know that they work with the hackery.  For the other ones,
7460      there is no guarantee, so we have to filter them out.  */
7461   tree filtered_attributes = NULL_TREE;
7462
7463   if (attributes)
7464     {
7465       tree attribute;
7466       for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
7467         {
7468           tree name = TREE_PURPOSE (attribute);
7469           
7470           if (is_attribute_p  ("deprecated", name)
7471               || is_attribute_p ("sentinel", name)
7472               || is_attribute_p ("noreturn", name))
7473             {
7474               /* An attribute that we support; add it to the filtered
7475                  attributes.  */
7476               filtered_attributes = chainon (filtered_attributes, 
7477                                              copy_node (attribute));
7478             }
7479           else if (is_attribute_p ("format", name))
7480             {
7481               /* "format" is special because before adding it to the
7482                  filtered attributes we need to adjust the specified
7483                  format by adding the hidden function parameters for
7484                  an Objective-C method (self, _cmd).  */
7485               tree new_attribute = copy_node (attribute);
7486
7487               /* Check the arguments specified with the attribute, and
7488                  modify them adding 2 for the two hidden arguments.
7489                  Note how this differs from C++; according to the
7490                  specs, C++ does not do it so you have to add the +1
7491                  yourself.  For Objective-C, instead, the compiler
7492                  adds the +2 for you.  */
7493
7494               /* The attribute arguments have not been checked yet, so
7495                  we need to be careful as they could be missing or
7496                  invalid.  If anything looks wrong, we skip the
7497                  process and the compiler will complain about it later
7498                  when it validates the attribute.  */
7499               /* Check that we have at least three arguments.  */
7500               if (TREE_VALUE (new_attribute)
7501                   && TREE_CHAIN (TREE_VALUE (new_attribute))
7502                   && TREE_CHAIN (TREE_CHAIN (TREE_VALUE (new_attribute))))
7503                 {
7504                   tree second_argument = TREE_CHAIN (TREE_VALUE (new_attribute));
7505                   tree third_argument = TREE_CHAIN (second_argument);
7506                   tree number;
7507
7508                   /* This is the second argument, the "string-index",
7509                      which specifies the index of the format string
7510                      argument.  Add 2.  */
7511                   number = TREE_VALUE (second_argument);
7512                   if (number
7513                       && TREE_CODE (number) == INTEGER_CST
7514                       && TREE_INT_CST_HIGH (number) == 0)
7515                     {
7516                       TREE_VALUE (second_argument) 
7517                         = build_int_cst (integer_type_node,
7518                                          TREE_INT_CST_LOW (number) + 2);
7519                     }
7520                   
7521                   /* This is the third argument, the "first-to-check",
7522                      which specifies the index of the first argument to
7523                      check.  This could be 0, meaning it is not available,
7524                      in which case we don't need to add 2.  Add 2 if not
7525                      0.  */
7526                   number = TREE_VALUE (third_argument);
7527                   if (number
7528                       && TREE_CODE (number) == INTEGER_CST
7529                       && TREE_INT_CST_HIGH (number) == 0
7530                       && TREE_INT_CST_LOW (number) != 0)
7531                     {
7532                       TREE_VALUE (third_argument) 
7533                         = build_int_cst (integer_type_node,
7534                                          TREE_INT_CST_LOW (number) + 2);
7535                     }
7536                 }
7537               filtered_attributes = chainon (filtered_attributes,
7538                                              new_attribute);
7539             }
7540           else
7541             warning (OPT_Wattributes, "%qE attribute directive ignored", name);
7542         }
7543     }
7544
7545   if (filtered_attributes)
7546     {
7547       /* This hackery changes the TREE_TYPE of the ObjC method
7548          declaration to be a function type, so that decl_attributes
7549          will treat the ObjC method as if it was a function.  Some
7550          attributes (sentinel, format) will be applied to the function
7551          type, changing it in place; so after calling decl_attributes,
7552          we extract the function type attributes and store them in
7553          METHOD_TYPE_ATTRIBUTES.  Some other attributes (noreturn,
7554          deprecated) are applied directly to the method declaration
7555          (by setting TREE_DEPRECATED and TREE_THIS_VOLATILE) so there
7556          is nothing to do.  */
7557       tree saved_type = TREE_TYPE (*node);
7558       TREE_TYPE (*node) = build_function_type 
7559         (TREE_VALUE (saved_type), get_arg_type_list (*node, METHOD_REF, 0));
7560       decl_attributes (node, filtered_attributes, flags);
7561       METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
7562       TREE_TYPE (*node) = saved_type;
7563     }
7564 }
7565
7566 bool 
7567 objc_method_decl (enum tree_code opcode)
7568 {
7569   return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
7570 }
7571
7572 /* Used by `build_objc_method_call' and `comp_proto_with_proto'.  Return
7573    an argument list for method METH.  CONTEXT is either METHOD_DEF or
7574    METHOD_REF, saying whether we are trying to define a method or call
7575    one.  SUPERFLAG says this is for a send to super; this makes a
7576    difference for the NeXT calling sequence in which the lookup and
7577    the method call are done together.  If METH is null, user-defined
7578    arguments (i.e., beyond self and _cmd) shall be represented by `...'.  */
7579
7580 static tree
7581 get_arg_type_list (tree meth, int context, int superflag)
7582 {
7583   tree arglist, akey;
7584
7585   /* Receiver type.  */
7586   if (flag_next_runtime && superflag)
7587     arglist = build_tree_list (NULL_TREE, objc_super_type);
7588   else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
7589     arglist = build_tree_list (NULL_TREE, objc_instance_type);
7590   else
7591     arglist = build_tree_list (NULL_TREE, objc_object_type);
7592
7593   /* Selector type - will eventually change to `int'.  */
7594   chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
7595
7596   /* No actual method prototype given -- assume that remaining arguments
7597      are `...'.  */
7598   if (!meth)
7599     return arglist;
7600
7601   /* Build a list of argument types.  */
7602   for (akey = METHOD_SEL_ARGS (meth); akey; akey = DECL_CHAIN (akey))
7603     {
7604       tree arg_type = TREE_VALUE (TREE_TYPE (akey));
7605
7606       /* Decay argument types for the underlying C function as appropriate.  */
7607       arg_type = objc_decay_parm_type (arg_type);
7608
7609       chainon (arglist, build_tree_list (NULL_TREE, arg_type));
7610     }
7611
7612   if (METHOD_ADD_ARGS (meth))
7613     {
7614       for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
7615            akey; akey = TREE_CHAIN (akey))
7616         {
7617           tree arg_type = TREE_TYPE (TREE_VALUE (akey));
7618
7619           arg_type = objc_decay_parm_type (arg_type);
7620
7621           chainon (arglist, build_tree_list (NULL_TREE, arg_type));
7622         }
7623
7624       if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
7625         goto lack_of_ellipsis;
7626     }
7627   else
7628     {
7629      lack_of_ellipsis:
7630       chainon (arglist, OBJC_VOID_AT_END);
7631     }
7632
7633   return arglist;
7634 }
7635
7636 static tree
7637 check_duplicates (hash hsh, int methods, int is_class)
7638 {
7639   tree meth = NULL_TREE;
7640
7641   if (hsh)
7642     {
7643       meth = hsh->key;
7644
7645       if (hsh->list)
7646         {
7647           /* We have two or more methods with the same name but
7648              different types.  */
7649           attr loop;
7650
7651           /* But just how different are those types?  If
7652              -Wno-strict-selector-match is specified, we shall not
7653              complain if the differences are solely among types with
7654              identical size and alignment.  */
7655           if (!warn_strict_selector_match)
7656             {
7657               for (loop = hsh->list; loop; loop = loop->next)
7658                 if (!comp_proto_with_proto (meth, loop->value, 0))
7659                   goto issue_warning;
7660
7661               return meth;
7662             }
7663
7664         issue_warning:
7665           if (methods)
7666             {
7667               bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
7668
7669               warning_at (input_location, 0,
7670                           "multiple methods named %<%c%E%> found",
7671                           (is_class ? '+' : '-'),
7672                           METHOD_SEL_NAME (meth));
7673               inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
7674                       (type ? '-' : '+'),
7675                       identifier_to_locale (gen_method_decl (meth)));
7676             }
7677           else
7678             {
7679               bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
7680
7681               warning_at (input_location, 0,
7682                           "multiple selectors named %<%c%E%> found",
7683                           (is_class ? '+' : '-'),
7684                           METHOD_SEL_NAME (meth));
7685               inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
7686                       (type ? '-' : '+'),
7687                       identifier_to_locale (gen_method_decl (meth)));
7688             }
7689
7690           for (loop = hsh->list; loop; loop = loop->next)
7691             {
7692               bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
7693
7694               inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
7695                       (type ? '-' : '+'),
7696                       identifier_to_locale (gen_method_decl (loop->value)));
7697             }
7698         }
7699     }
7700   return meth;
7701 }
7702
7703 /* If RECEIVER is a class reference, return the identifier node for
7704    the referenced class.  RECEIVER is created by objc_get_class_reference,
7705    so we check the exact form created depending on which runtimes are
7706    used.  */
7707
7708 static tree
7709 receiver_is_class_object (tree receiver, int self, int super)
7710 {
7711   tree chain, exp, arg;
7712
7713   /* The receiver is 'self' or 'super' in the context of a class method.  */
7714   if (objc_method_context
7715       && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
7716       && (self || super))
7717     return (super
7718             ? CLASS_SUPER_NAME (implementation_template)
7719             : CLASS_NAME (implementation_template));
7720
7721   if (flag_next_runtime)
7722     {
7723       /* The receiver is a variable created by
7724          build_class_reference_decl.  */
7725       if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
7726         /* Look up the identifier.  */
7727         for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
7728           if (TREE_PURPOSE (chain) == receiver)
7729             return TREE_VALUE (chain);
7730     }
7731
7732   /* The receiver is a function call that returns an id.  Check if
7733      it is a call to objc_getClass, if so, pick up the class name.  */
7734   if (TREE_CODE (receiver) == CALL_EXPR
7735       && (exp = CALL_EXPR_FN (receiver))
7736       && TREE_CODE (exp) == ADDR_EXPR
7737       && (exp = TREE_OPERAND (exp, 0))
7738       && TREE_CODE (exp) == FUNCTION_DECL
7739       /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
7740          prototypes for objc_get_class().  Thankfully, they seem to share the
7741          same function type.  */
7742       && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
7743       && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
7744       /* We have a call to objc_get_class/objc_getClass!  */
7745       && (arg = CALL_EXPR_ARG (receiver, 0)))
7746     {
7747       STRIP_NOPS (arg);
7748       if (TREE_CODE (arg) == ADDR_EXPR
7749           && (arg = TREE_OPERAND (arg, 0))
7750           && TREE_CODE (arg) == STRING_CST)
7751         /* Finally, we have the class name.  */
7752         return get_identifier (TREE_STRING_POINTER (arg));
7753     }
7754   return 0;
7755 }
7756 \f
7757 /* If we are currently building a message expr, this holds
7758    the identifier of the selector of the message.  This is
7759    used when printing warnings about argument mismatches.  */
7760
7761 static tree current_objc_message_selector = 0;
7762
7763 tree
7764 objc_message_selector (void)
7765 {
7766   return current_objc_message_selector;
7767 }
7768
7769 /* Construct an expression for sending a message.
7770    MESS has the object to send to in TREE_PURPOSE
7771    and the argument list (including selector) in TREE_VALUE.
7772
7773    (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
7774    (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...);  */
7775
7776 tree
7777 objc_build_message_expr (tree mess)
7778 {
7779   tree receiver = TREE_PURPOSE (mess);
7780   tree sel_name;
7781 #ifdef OBJCPLUS
7782   tree args = TREE_PURPOSE (TREE_VALUE (mess));
7783 #else
7784   tree args = TREE_VALUE (mess);
7785 #endif
7786   tree method_params = NULL_TREE;
7787
7788   if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
7789     return error_mark_node;
7790
7791   /* Obtain the full selector name.  */
7792   switch (TREE_CODE (args))
7793     {
7794     case IDENTIFIER_NODE:
7795       /* A unary selector.  */
7796       sel_name = args;
7797       break;
7798     case TREE_LIST:
7799       sel_name = build_keyword_selector (args);
7800       break;
7801     default:
7802       gcc_unreachable ();
7803     }
7804
7805   /* Build the parameter list to give to the method.  */
7806   if (TREE_CODE (args) == TREE_LIST)
7807 #ifdef OBJCPLUS
7808     method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
7809 #else
7810     {
7811       tree chain = args, prev = NULL_TREE;
7812
7813       /* We have a keyword selector--check for comma expressions.  */
7814       while (chain)
7815         {
7816           tree element = TREE_VALUE (chain);
7817
7818           /* We have a comma expression, must collapse...  */
7819           if (TREE_CODE (element) == TREE_LIST)
7820             {
7821               if (prev)
7822                 TREE_CHAIN (prev) = element;
7823               else
7824                 args = element;
7825             }
7826           prev = chain;
7827           chain = TREE_CHAIN (chain);
7828         }
7829       method_params = args;
7830     }
7831 #endif
7832
7833 #ifdef OBJCPLUS
7834   if (processing_template_decl)
7835     /* Must wait until template instantiation time.  */
7836     return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
7837                          method_params);
7838 #endif
7839
7840   return objc_finish_message_expr (receiver, sel_name, method_params);
7841 }
7842
7843 /* Look up method SEL_NAME that would be suitable for receiver
7844    of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
7845    nonzero), and report on any duplicates.  */
7846
7847 static tree
7848 lookup_method_in_hash_lists (tree sel_name, int is_class)
7849 {
7850   hash method_prototype = NULL;
7851
7852   if (!is_class)
7853     method_prototype = hash_lookup (nst_method_hash_list,
7854                                     sel_name);
7855
7856   if (!method_prototype)
7857     {
7858       method_prototype = hash_lookup (cls_method_hash_list,
7859                                       sel_name);
7860       is_class = 1;
7861     }
7862
7863   return check_duplicates (method_prototype, 1, is_class);
7864 }
7865
7866 /* The 'objc_finish_message_expr' routine is called from within
7867    'objc_build_message_expr' for non-template functions.  In the case of
7868    C++ template functions, it is called from 'build_expr_from_tree'
7869    (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded.  */
7870
7871 tree
7872 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
7873 {
7874   tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
7875   tree selector, retval, class_tree;
7876   int self, super, have_cast;
7877
7878   /* We have used the receiver, so mark it as read.  */
7879   mark_exp_read (receiver);
7880
7881   /* Extract the receiver of the message, as well as its type
7882      (where the latter may take the form of a cast or be inferred
7883      from the implementation context).  */
7884   rtype = receiver;
7885   while (TREE_CODE (rtype) == COMPOUND_EXPR
7886               || TREE_CODE (rtype) == MODIFY_EXPR
7887               || CONVERT_EXPR_P (rtype)
7888               || TREE_CODE (rtype) == COMPONENT_REF)
7889     rtype = TREE_OPERAND (rtype, 0);
7890
7891   self = (rtype == self_decl);
7892   super = (rtype == UOBJC_SUPER_decl);
7893   rtype = TREE_TYPE (receiver);
7894
7895   have_cast = (TREE_CODE (receiver) == NOP_EXPR
7896                || (TREE_CODE (receiver) == COMPOUND_EXPR
7897                    && !IS_SUPER (rtype)));
7898
7899   /* If we are calling [super dealloc], reset our warning flag.  */
7900   if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
7901     should_call_super_dealloc = 0;
7902
7903   /* If the receiver is a class object, retrieve the corresponding
7904      @interface, if one exists. */
7905   class_tree = receiver_is_class_object (receiver, self, super);
7906
7907   /* Now determine the receiver type (if an explicit cast has not been
7908      provided).  */
7909   if (!have_cast)
7910     {
7911       if (class_tree)
7912         rtype = lookup_interface (class_tree);
7913       /* Handle `self' and `super'.  */
7914       else if (super)
7915         {
7916           if (!CLASS_SUPER_NAME (implementation_template))
7917             {
7918               error ("no super class declared in @interface for %qE",
7919                      CLASS_NAME (implementation_template));
7920               return error_mark_node;
7921             }
7922           rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
7923         }
7924       else if (self)
7925         rtype = lookup_interface (CLASS_NAME (implementation_template));
7926     }
7927
7928   /* If receiver is of type `id' or `Class' (or if the @interface for a
7929      class is not visible), we shall be satisfied with the existence of
7930      any instance or class method. */
7931   if (objc_is_id (rtype))
7932     {
7933       class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
7934       rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
7935                  ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
7936                  : NULL_TREE);
7937       rtype = NULL_TREE;
7938
7939       if (rprotos)
7940         {
7941           /* If messaging 'id <Protos>' or 'Class <Proto>', first search
7942              in protocols themselves for the method prototype.  */
7943           method_prototype
7944             = lookup_method_in_protocol_list (rprotos, sel_name,
7945                                               class_tree != NULL_TREE);
7946
7947           /* If messaging 'Class <Proto>' but did not find a class method
7948              prototype, search for an instance method instead, and warn
7949              about having done so.  */
7950           if (!method_prototype && !rtype && class_tree != NULL_TREE)
7951             {
7952               method_prototype
7953                 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7954
7955               if (method_prototype)
7956                 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
7957                          sel_name, sel_name);
7958             }
7959         }
7960     }
7961   else if (rtype)
7962     {
7963       tree orig_rtype = rtype;
7964
7965       if (TREE_CODE (rtype) == POINTER_TYPE)
7966         rtype = TREE_TYPE (rtype);
7967       /* Traverse typedef aliases */
7968       while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
7969              && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
7970              && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
7971         rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
7972       if (TYPED_OBJECT (rtype))
7973         {
7974           rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
7975           rtype = TYPE_OBJC_INTERFACE (rtype);
7976         }
7977       /* If we could not find an @interface declaration, we must have
7978          only seen a @class declaration; so, we cannot say anything
7979          more intelligent about which methods the receiver will
7980          understand. */
7981       if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
7982         {
7983           rtype = NULL_TREE;
7984           /* We could not find an @interface declaration, yet Message maybe in a 
7985              @class's protocol. */
7986           if (!method_prototype && rprotos)
7987             method_prototype
7988               = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7989         }
7990       else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
7991           || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
7992         {
7993           /* We have a valid ObjC class name.  Look up the method name
7994              in the published @interface for the class (and its
7995              superclasses). */
7996           method_prototype
7997             = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
7998
7999           /* If the method was not found in the @interface, it may still
8000              exist locally as part of the @implementation.  */
8001           if (!method_prototype && objc_implementation_context
8002              && CLASS_NAME (objc_implementation_context)
8003                 == OBJC_TYPE_NAME (rtype))
8004             method_prototype
8005               = lookup_method
8006                 ((class_tree
8007                   ? CLASS_CLS_METHODS (objc_implementation_context)
8008                   : CLASS_NST_METHODS (objc_implementation_context)),
8009                   sel_name);
8010
8011           /* If we haven't found a candidate method by now, try looking for
8012              it in the protocol list.  */
8013           if (!method_prototype && rprotos)
8014             method_prototype
8015               = lookup_method_in_protocol_list (rprotos, sel_name,
8016                                                 class_tree != NULL_TREE);
8017         }
8018       else
8019         {
8020           warning (0, "invalid receiver type %qs",
8021                    identifier_to_locale (gen_type_name (orig_rtype)));
8022           /* After issuing the "invalid receiver" warning, perform method
8023              lookup as if we were messaging 'id'.  */
8024           rtype = rprotos = NULL_TREE;
8025         }
8026     }
8027
8028
8029   /* For 'id' or 'Class' receivers, search in the global hash table
8030      as a last resort.  For all receivers, warn if protocol searches
8031      have failed.  */
8032   if (!method_prototype)
8033     {
8034       if (rprotos)
8035         warning (0, "%<%c%E%> not found in protocol(s)",
8036                  (class_tree ? '+' : '-'),
8037                  sel_name);
8038
8039       if (!rtype)
8040         method_prototype
8041           = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
8042     }
8043
8044   if (!method_prototype) 
8045     {
8046       static bool warn_missing_methods = false;
8047
8048       if (rtype)
8049         warning (0, "%qE may not respond to %<%c%E%>",
8050                  OBJC_TYPE_NAME (rtype),
8051                  (class_tree ? '+' : '-'),
8052                  sel_name);
8053       /* If we are messaging an 'id' or 'Class' object and made it here,
8054          then we have failed to find _any_ instance or class method,
8055          respectively.  */
8056       else
8057         warning (0, "no %<%c%E%> method found",
8058                  (class_tree ? '+' : '-'),
8059                  sel_name);
8060
8061       if (!warn_missing_methods)
8062         {
8063           warning_at (input_location, 
8064                       0, "(Messages without a matching method signature");
8065           warning_at (input_location, 
8066                       0, "will be assumed to return %<id%> and accept");
8067           warning_at (input_location, 
8068                       0, "%<...%> as arguments.)");
8069           warn_missing_methods = true;
8070         }
8071     }
8072   else
8073     {
8074       /* Warn if the method is deprecated, but not if the receiver is
8075          a generic 'id'.  'id' is used to cast an object to a generic
8076          object of an unspecified class; in that case, we'll use
8077          whatever method prototype we can find to get the method
8078          argument and return types, but it is not appropriate to
8079          produce deprecation warnings since we don't know the class
8080          that the object will be of at runtime.  The @interface(s) for
8081          that class may not even be available to the compiler right
8082          now, and it is perfectly possible that the method is marked
8083          as non-deprecated in such @interface(s).
8084
8085          In practice this makes sense since casting an object to 'id'
8086          is often used precisely to turn off warnings associated with
8087          the object being of a particular class.  */
8088       if (TREE_DEPRECATED (method_prototype)  &&  rtype != NULL_TREE)
8089         warn_deprecated_use (method_prototype, NULL_TREE);
8090     }
8091
8092
8093   /* Save the selector name for printing error messages.  */
8094   current_objc_message_selector = sel_name;
8095
8096   /* Build the parameters list for looking up the method.
8097      These are the object itself and the selector.  */
8098
8099   if (flag_typed_selectors)
8100     selector = build_typed_selector_reference (input_location,
8101                                                sel_name, method_prototype);
8102   else
8103     selector = build_selector_reference (input_location, sel_name);
8104
8105   retval = build_objc_method_call (input_location, super, method_prototype,
8106                                    receiver,
8107                                    selector, method_params);
8108
8109   current_objc_message_selector = 0;
8110
8111   return retval;
8112 }
8113 \f
8114 /* Build a tree expression to send OBJECT the operation SELECTOR,
8115    looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
8116    assuming the method has prototype METHOD_PROTOTYPE.
8117    (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
8118    LOC is the location of the expression to build.
8119    Use METHOD_PARAMS as list of args to pass to the method.
8120    If SUPER_FLAG is nonzero, we look up the superclass's method.  */
8121
8122 static tree
8123 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
8124                         tree lookup_object, tree selector,
8125                         tree method_params)
8126 {
8127   tree sender = (super_flag ? umsg_super_decl :
8128                  (!flag_next_runtime || flag_nil_receivers
8129                   ? (flag_objc_direct_dispatch
8130                      ? umsg_fast_decl
8131                      : umsg_decl)
8132                   : umsg_nonnil_decl));
8133   tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
8134   VEC(tree, gc) *parms = NULL;
8135   unsigned nparm = (method_params ? list_length (method_params) : 0);
8136
8137   /* If a prototype for the method to be called exists, then cast
8138      the sender's return type and arguments to match that of the method.
8139      Otherwise, leave sender as is.  */
8140   tree ret_type
8141     = (method_prototype
8142        ? TREE_VALUE (TREE_TYPE (method_prototype))
8143        : objc_object_type);
8144
8145   tree method_param_types = 
8146                 get_arg_type_list (method_prototype, METHOD_REF, super_flag);
8147   tree ftype = build_function_type (ret_type, method_param_types);
8148   tree sender_cast;
8149   tree method, t;
8150
8151   if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
8152     ftype = build_type_attribute_variant (ftype, 
8153                                           METHOD_TYPE_ATTRIBUTES 
8154                                           (method_prototype));
8155
8156   sender_cast = build_pointer_type (ftype);
8157
8158   lookup_object = build_c_cast (loc, rcv_p, lookup_object);
8159
8160   /* Use SAVE_EXPR to avoid evaluating the receiver twice.  */
8161   lookup_object = save_expr (lookup_object);
8162
8163   /* Param list + 2 slots for object and selector.  */
8164   parms = VEC_alloc (tree, gc, nparm + 2);
8165
8166   if (flag_next_runtime)
8167     {
8168       /* If we are returning a struct in memory, and the address
8169          of that memory location is passed as a hidden first
8170          argument, then change which messenger entry point this
8171          expr will call.  NB: Note that sender_cast remains
8172          unchanged (it already has a struct return type).  */
8173       if (!targetm.calls.struct_value_rtx (0, 0)
8174           && (TREE_CODE (ret_type) == RECORD_TYPE
8175               || TREE_CODE (ret_type) == UNION_TYPE)
8176           && targetm.calls.return_in_memory (ret_type, 0))
8177         sender = (super_flag ? umsg_super_stret_decl :
8178                 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
8179
8180       method = build_fold_addr_expr_loc (input_location, sender);
8181       /* Pass the object to the method.  */
8182       VEC_quick_push (tree, parms, lookup_object);
8183     }
8184   else
8185     {
8186       /* This is the portable (GNU) way.  */
8187       /* First, call the lookup function to get a pointer to the method,
8188          then cast the pointer, then call it with the method arguments.  */
8189       VEC(tree, gc) *tv = VEC_alloc (tree, gc, 2);
8190       VEC_quick_push (tree, tv, lookup_object);
8191       VEC_quick_push (tree, tv, selector);
8192       method = build_function_call_vec (loc, sender, tv, NULL);
8193       VEC_free (tree, gc, tv);
8194
8195       /* Pass the appropriate object to the method.  */
8196       VEC_quick_push (tree, parms, (super_flag ? self_decl : lookup_object));
8197     }
8198
8199   /* Pass the selector to the method.  */
8200   VEC_quick_push (tree, parms, selector);
8201   /* Now append the remainder of the parms.  */
8202   if (nparm)
8203     for (; method_params; method_params = TREE_CHAIN (method_params))
8204       VEC_quick_push (tree, parms, TREE_VALUE (method_params));
8205
8206   /* Build an obj_type_ref, with the correct cast for the method call.  */
8207   t = build3 (OBJ_TYPE_REF, sender_cast, method, 
8208                             lookup_object, size_zero_node);
8209   t = build_function_call_vec (loc, t, parms, NULL);\
8210   VEC_free (tree, gc, parms);
8211   return t;
8212 }
8213
8214 static void
8215 build_protocol_reference (tree p)
8216 {
8217   tree decl;
8218   const char *proto_name;
8219
8220   /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
8221
8222   proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
8223   decl = start_var_decl (objc_protocol_template, proto_name);
8224
8225   PROTOCOL_FORWARD_DECL (p) = decl;
8226 }
8227
8228 /* This function is called by the parser when (and only when) a
8229    @protocol() expression is found, in order to compile it.  */
8230 tree
8231 objc_build_protocol_expr (tree protoname)
8232 {
8233   tree expr;
8234   tree p = lookup_protocol (protoname, /* warn if deprecated */ true);
8235
8236   if (!p)
8237     {
8238       error ("cannot find protocol declaration for %qE",
8239              protoname);
8240       return error_mark_node;
8241     }
8242
8243   if (!PROTOCOL_FORWARD_DECL (p))
8244     build_protocol_reference (p);
8245
8246   expr = build_unary_op (input_location, 
8247                          ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
8248
8249   /* ??? Ideally we'd build the reference with objc_protocol_type directly,
8250      if we have it, rather than converting it here.  */
8251   expr = convert (objc_protocol_type, expr);
8252
8253   /* The @protocol() expression is being compiled into a pointer to a
8254      statically allocated instance of the Protocol class.  To become
8255      usable at runtime, the 'isa' pointer of the instance need to be
8256      fixed up at runtime by the runtime library, to point to the
8257      actual 'Protocol' class.  */
8258
8259   /* For the GNU runtime, put the static Protocol instance in the list
8260      of statically allocated instances, so that we make sure that its
8261      'isa' pointer is fixed up at runtime by the GNU runtime library
8262      to point to the Protocol class (at runtime, when loading the
8263      module, the GNU runtime library loops on the statically allocated
8264      instances (as found in the defs field in objc_symtab) and fixups
8265      all the 'isa' pointers of those objects).  */
8266   if (! flag_next_runtime)
8267     {
8268       /* This type is a struct containing the fields of a Protocol
8269         object.  (Cfr. objc_protocol_type instead is the type of a pointer
8270         to such a struct).  */
8271       tree protocol_struct_type = xref_tag
8272        (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
8273       tree *chain;
8274
8275       /* Look for the list of Protocol statically allocated instances
8276         to fixup at runtime.  Create a new list to hold Protocol
8277         statically allocated instances, if the list is not found.  At
8278         present there is only another list, holding NSConstantString
8279         static instances to be fixed up at runtime.  */
8280       for (chain = &objc_static_instances;
8281            *chain && TREE_VALUE (*chain) != protocol_struct_type;
8282            chain = &TREE_CHAIN (*chain));
8283       if (!*chain)
8284         {
8285          *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
8286          add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
8287                           class_names);
8288        }
8289
8290       /* Add this statically allocated instance to the Protocol list.  */
8291       TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
8292                                          PROTOCOL_FORWARD_DECL (p),
8293                                          TREE_PURPOSE (*chain));
8294     }
8295
8296
8297   return expr;
8298 }
8299
8300 /* This function is called by the parser when a @selector() expression
8301    is found, in order to compile it.  It is only called by the parser
8302    and only to compile a @selector().  LOC is the location of the
8303    @selector.  */
8304 tree
8305 objc_build_selector_expr (location_t loc, tree selnamelist)
8306 {
8307   tree selname;
8308
8309   /* Obtain the full selector name.  */
8310   switch (TREE_CODE (selnamelist))
8311     {
8312     case IDENTIFIER_NODE:
8313       /* A unary selector.  */
8314       selname = selnamelist;
8315       break;
8316     case TREE_LIST:
8317       selname = build_keyword_selector (selnamelist);
8318       break;
8319     default:
8320       gcc_unreachable ();
8321     }
8322
8323   /* If we are required to check @selector() expressions as they
8324      are found, check that the selector has been declared.  */
8325   if (warn_undeclared_selector)
8326     {
8327       /* Look the selector up in the list of all known class and
8328          instance methods (up to this line) to check that the selector
8329          exists.  */
8330       hash hsh;
8331
8332       /* First try with instance methods.  */
8333       hsh = hash_lookup (nst_method_hash_list, selname);
8334
8335       /* If not found, try with class methods.  */
8336       if (!hsh)
8337         {
8338           hsh = hash_lookup (cls_method_hash_list, selname);
8339         }
8340
8341       /* If still not found, print out a warning.  */
8342       if (!hsh)
8343         {
8344           warning (0, "undeclared selector %qE", selname);
8345         }
8346     }
8347
8348
8349   if (flag_typed_selectors)
8350     return build_typed_selector_reference (loc, selname, 0);
8351   else
8352     return build_selector_reference (loc, selname);
8353 }
8354
8355 /* This is used to implement @encode().  See gcc/doc/objc.texi,
8356    section '@encode'.  */
8357 tree
8358 objc_build_encode_expr (tree type)
8359 {
8360   tree result;
8361   const char *string;
8362
8363   encode_type (type, obstack_object_size (&util_obstack),
8364                OBJC_ENCODE_INLINE_DEFS);
8365   obstack_1grow (&util_obstack, 0);    /* null terminate string */
8366   string = XOBFINISH (&util_obstack, const char *);
8367
8368   /* Synthesize a string that represents the encoded struct/union.  */
8369   result = my_build_string (strlen (string) + 1, string);
8370   obstack_free (&util_obstack, util_firstobj);
8371   return result;
8372 }
8373
8374 static tree
8375 build_ivar_reference (tree id)
8376 {
8377   if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8378     {
8379       /* Historically, a class method that produced objects (factory
8380          method) would assign `self' to the instance that it
8381          allocated.  This would effectively turn the class method into
8382          an instance method.  Following this assignment, the instance
8383          variables could be accessed.  That practice, while safe,
8384          violates the simple rule that a class method should not refer
8385          to an instance variable.  It's better to catch the cases
8386          where this is done unknowingly than to support the above
8387          paradigm.  */
8388       warning (0, "instance variable %qE accessed in class method",
8389                id);
8390       self_decl = convert (objc_instance_type, self_decl); /* cast */
8391     }
8392
8393   return objc_build_component_ref (build_indirect_ref (input_location,
8394                                                        self_decl, RO_ARROW),
8395                                    id);
8396 }
8397 \f
8398 /* Compute a hash value for a given method SEL_NAME.  */
8399
8400 static size_t
8401 hash_func (tree sel_name)
8402 {
8403   const unsigned char *s
8404     = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
8405   size_t h = 0;
8406
8407   while (*s)
8408     h = h * 67 + *s++ - 113;
8409   return h;
8410 }
8411
8412 static void
8413 hash_init (void)
8414 {
8415   nst_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8416   cls_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8417
8418   cls_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8419   als_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8420
8421   /* Initialize the hash table used to hold the constant string objects.  */
8422   string_htab = htab_create_ggc (31, string_hash,
8423                                    string_eq, NULL);
8424 }
8425
8426 /* This routine adds sel_name to the hash list. sel_name  is a class or alias
8427    name for the class. If alias name, then value is its underlying class.
8428    If class, the value is NULL_TREE. */
8429
8430 static void
8431 hash_class_name_enter (hash *hashlist, tree sel_name, tree value)
8432 {
8433   hash obj;
8434   int slot = hash_func (sel_name) % SIZEHASHTABLE;
8435
8436   obj = ggc_alloc_hashed_entry ();
8437   if (value != NULL_TREE)
8438     {
8439       /* Save the underlying class for the 'alias' in the hash table */
8440       attr obj_attr = ggc_alloc_hashed_attribute ();
8441       obj_attr->value = value;
8442       obj->list = obj_attr;
8443     }
8444   else
8445     obj->list = 0;
8446   obj->next = hashlist[slot];
8447   obj->key = sel_name;
8448
8449   hashlist[slot] = obj;         /* append to front */
8450
8451 }
8452
8453 /*
8454    Searches in the hash table looking for a match for class or alias name.
8455 */
8456
8457 static hash
8458 hash_class_name_lookup (hash *hashlist, tree sel_name)
8459 {
8460   hash target;
8461
8462   target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
8463
8464   while (target)
8465     {
8466       if (sel_name == target->key)
8467         return target;
8468
8469       target = target->next;
8470     }
8471   return 0;
8472 }
8473
8474 /* WARNING!!!!  hash_enter is called with a method, and will peek
8475    inside to find its selector!  But hash_lookup is given a selector
8476    directly, and looks for the selector that's inside the found
8477    entry's key (method) for comparison.  */
8478
8479 static void
8480 hash_enter (hash *hashlist, tree method)
8481 {
8482   hash obj;
8483   int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
8484
8485   obj = ggc_alloc_hashed_entry ();
8486   obj->list = 0;
8487   obj->next = hashlist[slot];
8488   obj->key = method;
8489
8490   hashlist[slot] = obj;         /* append to front */
8491 }
8492
8493 static hash
8494 hash_lookup (hash *hashlist, tree sel_name)
8495 {
8496   hash target;
8497
8498   target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
8499
8500   while (target)
8501     {
8502       if (sel_name == METHOD_SEL_NAME (target->key))
8503         return target;
8504
8505       target = target->next;
8506     }
8507   return 0;
8508 }
8509
8510 static void
8511 hash_add_attr (hash entry, tree value)
8512 {
8513   attr obj;
8514
8515   obj = ggc_alloc_hashed_attribute ();
8516   obj->next = entry->list;
8517   obj->value = value;
8518
8519   entry->list = obj;            /* append to front */
8520 }
8521 \f
8522 static tree
8523 lookup_method (tree mchain, tree method)
8524 {
8525   tree key;
8526
8527   if (TREE_CODE (method) == IDENTIFIER_NODE)
8528     key = method;
8529   else
8530     key = METHOD_SEL_NAME (method);
8531
8532   while (mchain)
8533     {
8534       if (METHOD_SEL_NAME (mchain) == key)
8535         return mchain;
8536
8537       mchain = DECL_CHAIN (mchain);
8538     }
8539   return NULL_TREE;
8540 }
8541
8542 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance
8543    method in INTERFACE, along with any categories and protocols
8544    attached thereto.  If method is not found, and the
8545    OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS, recursively examine the
8546    INTERFACE's superclass.  If OBJC_LOOKUP_CLASS is set,
8547    OBJC_LOOKUP_NO_SUPER is clear, and no suitable class method could
8548    be found in INTERFACE or any of its superclasses, look for an
8549    _instance_ method of the same name in the root class as a last
8550    resort.  This behaviour can be turned off by using
8551    OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS.
8552
8553    If a suitable method cannot be found, return NULL_TREE.  */
8554
8555 static tree
8556 lookup_method_static (tree interface, tree ident, int flags)
8557 {
8558   tree meth = NULL_TREE, root_inter = NULL_TREE;
8559   tree inter = interface;
8560   int is_class = (flags & OBJC_LOOKUP_CLASS);
8561   int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
8562   int no_instance_methods_of_root_class = (flags & OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS);
8563
8564   while (inter)
8565     {
8566       tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
8567       tree category = inter;
8568
8569       /* First, look up the method in the class itself.  */
8570       if ((meth = lookup_method (chain, ident)))
8571         return meth;
8572
8573       /* Failing that, look for the method in each category of the class.  */
8574       while ((category = CLASS_CATEGORY_LIST (category)))
8575         {
8576           chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
8577
8578           /* Check directly in each category.  */
8579           if ((meth = lookup_method (chain, ident)))
8580             return meth;
8581
8582           /* Failing that, check in each category's protocols.  */
8583           if (CLASS_PROTOCOL_LIST (category))
8584             {
8585               if ((meth = (lookup_method_in_protocol_list
8586                            (CLASS_PROTOCOL_LIST (category), ident, is_class))))
8587                 return meth;
8588             }
8589         }
8590
8591       /* If not found in categories, check in protocols of the main class.  */
8592       if (CLASS_PROTOCOL_LIST (inter))
8593         {
8594           if ((meth = (lookup_method_in_protocol_list
8595                        (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
8596             return meth;
8597         }
8598
8599       /* If we were instructed not to look in superclasses, don't.  */
8600       if (no_superclasses)
8601         return NULL_TREE;
8602
8603       /* Failing that, climb up the inheritance hierarchy.  */
8604       root_inter = inter;
8605       inter = lookup_interface (CLASS_SUPER_NAME (inter));
8606     }
8607   while (inter);
8608
8609   if (is_class && !no_instance_methods_of_root_class)
8610     {
8611       /* If no class (factory) method was found, check if an _instance_
8612          method of the same name exists in the root class.  This is what
8613          the Objective-C runtime will do.  */
8614       return lookup_method_static (root_inter, ident, 0);
8615     }
8616   else
8617     {
8618       /* If an instance method was not found, return 0.  */      
8619       return NULL_TREE;
8620     }
8621 }
8622
8623 /* Add the method to the hash list if it doesn't contain an identical
8624    method already. */
8625
8626 static void
8627 add_method_to_hash_list (hash *hash_list, tree method)
8628 {
8629   hash hsh;
8630
8631   if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
8632     {
8633       /* Install on a global chain.  */
8634       hash_enter (hash_list, method);
8635     }
8636   else
8637     {
8638       /* Check types against those; if different, add to a list.  */
8639       attr loop;
8640       int already_there = comp_proto_with_proto (method, hsh->key, 1);
8641       for (loop = hsh->list; !already_there && loop; loop = loop->next)
8642         already_there |= comp_proto_with_proto (method, loop->value, 1);
8643       if (!already_there)
8644         hash_add_attr (hsh, method);
8645     }
8646 }
8647
8648 static tree
8649 objc_add_method (tree klass, tree method, int is_class, bool is_optional)
8650 {
8651   tree mth;
8652
8653   /* @optional methods are added to protocol's OPTIONAL list.  Note
8654      that this disables checking that the methods are implemented by
8655      classes implementing the protocol, since these checks only use
8656      the CLASS_CLS_METHODS and CLASS_NST_METHODS.  */
8657   if (is_optional)
8658     {
8659       gcc_assert (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE);
8660       if (!(mth = lookup_method (is_class
8661                                 ? PROTOCOL_OPTIONAL_CLS_METHODS (klass)
8662                                 : PROTOCOL_OPTIONAL_NST_METHODS (klass), 
8663                                                                 method)))
8664         {
8665           if (is_class)
8666             {
8667               TREE_CHAIN (method) = PROTOCOL_OPTIONAL_CLS_METHODS (klass);
8668               PROTOCOL_OPTIONAL_CLS_METHODS (klass) = method;
8669             }
8670           else
8671             {
8672               TREE_CHAIN (method) = PROTOCOL_OPTIONAL_NST_METHODS (klass);
8673               PROTOCOL_OPTIONAL_NST_METHODS (klass) = method;
8674             }
8675         }
8676     }
8677   else if (!(mth = lookup_method (is_class
8678                              ? CLASS_CLS_METHODS (klass)
8679                              : CLASS_NST_METHODS (klass), method)))
8680     {
8681       /* put method on list in reverse order */
8682       if (is_class)
8683         {
8684           DECL_CHAIN (method) = CLASS_CLS_METHODS (klass);
8685           CLASS_CLS_METHODS (klass) = method;
8686         }
8687       else
8688         {
8689           DECL_CHAIN (method) = CLASS_NST_METHODS (klass);
8690           CLASS_NST_METHODS (klass) = method;
8691         }
8692     }
8693   else
8694     {
8695       /* When processing an @interface for a class or category, give hard
8696          errors on methods with identical selectors but differing argument
8697          and/or return types. We do not do this for @implementations, because
8698          C/C++ will do it for us (i.e., there will be duplicate function
8699          definition errors).  */
8700       if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
8701            || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
8702           && !comp_proto_with_proto (method, mth, 1))
8703         error ("duplicate declaration of method %<%c%E%>",
8704                 is_class ? '+' : '-',
8705                 METHOD_SEL_NAME (mth));
8706     }
8707
8708   if (is_class)
8709     add_method_to_hash_list (cls_method_hash_list, method);
8710   else
8711     {
8712       add_method_to_hash_list (nst_method_hash_list, method);
8713
8714       /* Instance methods in root classes (and categories thereof)
8715          may act as class methods as a last resort.  We also add
8716          instance methods listed in @protocol declarations to
8717          the class hash table, on the assumption that @protocols
8718          may be adopted by root classes or categories.  */
8719       if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
8720           || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
8721         klass = lookup_interface (CLASS_NAME (klass));
8722
8723       if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
8724           || !CLASS_SUPER_NAME (klass))
8725         add_method_to_hash_list (cls_method_hash_list, method);
8726     }
8727
8728   return method;
8729 }
8730
8731 static tree
8732 add_class (tree class_name, tree name)
8733 {
8734   struct interface_tuple **slot;
8735
8736   /* Put interfaces on list in reverse order.  */
8737   TREE_CHAIN (class_name) = interface_chain;
8738   interface_chain = class_name;
8739
8740   if (interface_htab == NULL)
8741     interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
8742   slot = (struct interface_tuple **)
8743     htab_find_slot_with_hash (interface_htab, name,
8744                               IDENTIFIER_HASH_VALUE (name),
8745                               INSERT);
8746   if (!*slot)
8747     {
8748       *slot = ggc_alloc_cleared_interface_tuple ();
8749       (*slot)->id = name;
8750     }
8751   (*slot)->class_name = class_name;
8752
8753   return interface_chain;
8754 }
8755
8756 static void
8757 add_category (tree klass, tree category)
8758 {
8759   /* Put categories on list in reverse order.  */
8760   tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
8761
8762   if (cat)
8763     {
8764       warning (0, "duplicate interface declaration for category %<%E(%E)%>",
8765                CLASS_NAME (klass),
8766                CLASS_SUPER_NAME (category));
8767     }
8768   else
8769     {
8770       CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
8771       CLASS_CATEGORY_LIST (klass) = category;
8772     }
8773 }
8774
8775 /* Called after parsing each instance variable declaration. Necessary to
8776    preserve typedefs and implement public/private...
8777
8778    VISIBILITY is 1 for public, 0 for protected, and 2 for private.  */
8779
8780 static tree
8781 add_instance_variable (tree klass, objc_ivar_visibility_kind visibility, 
8782                        tree field_decl)
8783 {
8784   tree field_type = TREE_TYPE (field_decl);
8785   const char *ivar_name = DECL_NAME (field_decl)
8786                           ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
8787                           : _("<unnamed>");
8788
8789 #ifdef OBJCPLUS
8790   if (TREE_CODE (field_type) == REFERENCE_TYPE)
8791     {
8792       error ("illegal reference type specified for instance variable %qs",
8793              ivar_name);
8794       /* Return class as is without adding this ivar.  */
8795       return klass;
8796     }
8797 #endif
8798
8799   if (field_type == error_mark_node || !TYPE_SIZE (field_type)
8800       || TYPE_SIZE (field_type) == error_mark_node)
8801       /* 'type[0]' is allowed, but 'type[]' is not! */
8802     {
8803       error ("instance variable %qs has unknown size", ivar_name);
8804       /* Return class as is without adding this ivar.  */
8805       return klass;
8806     }
8807
8808 #ifdef OBJCPLUS
8809   /* Check if the ivar being added has a non-POD C++ type.   If so, we will
8810      need to either (1) warn the user about it or (2) generate suitable
8811      constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
8812      methods (if '-fobjc-call-cxx-cdtors' was specified).  */
8813   if (MAYBE_CLASS_TYPE_P (field_type)
8814       && (TYPE_NEEDS_CONSTRUCTING (field_type)
8815           || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
8816           || TYPE_POLYMORPHIC_P (field_type)))
8817     {
8818       tree type_name = OBJC_TYPE_NAME (field_type);
8819
8820       if (flag_objc_call_cxx_cdtors)
8821         {
8822           /* Since the ObjC runtime will be calling the constructors and
8823              destructors for us, the only thing we can't handle is the lack
8824              of a default constructor.  */
8825           if (TYPE_NEEDS_CONSTRUCTING (field_type)
8826               && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
8827             {
8828               warning (0, "type %qE has no default constructor to call",
8829                        type_name);
8830
8831               /* If we cannot call a constructor, we should also avoid
8832                  calling the destructor, for symmetry.  */
8833               if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
8834                 warning (0, "destructor for %qE shall not be run either",
8835                          type_name);
8836             }
8837         }
8838       else
8839         {
8840           static bool warn_cxx_ivars = false;
8841
8842           if (TYPE_POLYMORPHIC_P (field_type))
8843             {
8844               /* Vtable pointers are Real Bad(tm), since Obj-C cannot
8845                  initialize them.  */
8846               error ("type %qE has virtual member functions", type_name);
8847               error ("illegal aggregate type %qE specified "
8848                      "for instance variable %qs",
8849                      type_name, ivar_name);
8850               /* Return class as is without adding this ivar.  */
8851               return klass;
8852             }
8853
8854           /* User-defined constructors and destructors are not known to Obj-C
8855              and hence will not be called.  This may or may not be a problem. */
8856           if (TYPE_NEEDS_CONSTRUCTING (field_type))
8857             warning (0, "type %qE has a user-defined constructor", type_name);
8858           if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
8859             warning (0, "type %qE has a user-defined destructor", type_name);
8860
8861           if (!warn_cxx_ivars)
8862             {
8863               warning (0, "C++ constructors and destructors will not "
8864                        "be invoked for Objective-C fields");
8865               warn_cxx_ivars = true;
8866             }
8867         }
8868     }
8869 #endif
8870
8871   /* Overload the public attribute, it is not used for FIELD_DECLs.  */
8872   switch (visibility)
8873     {
8874     case OBJC_IVAR_VIS_PROTECTED:
8875       TREE_PUBLIC (field_decl) = 0;
8876       TREE_PRIVATE (field_decl) = 0;
8877       TREE_PROTECTED (field_decl) = 1;
8878       break;
8879
8880     case OBJC_IVAR_VIS_PACKAGE:
8881     /* TODO: Implement the package variant.  */
8882     case OBJC_IVAR_VIS_PUBLIC:
8883       TREE_PUBLIC (field_decl) = 1;
8884       TREE_PRIVATE (field_decl) = 0;
8885       TREE_PROTECTED (field_decl) = 0;
8886       break;
8887
8888     case OBJC_IVAR_VIS_PRIVATE:
8889       TREE_PUBLIC (field_decl) = 0;
8890       TREE_PRIVATE (field_decl) = 1;
8891       TREE_PROTECTED (field_decl) = 0;
8892       break;
8893
8894     }
8895
8896   CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
8897
8898   return klass;
8899 }
8900 \f
8901
8902 static tree
8903 is_ivar (tree decl_chain, tree ident)
8904 {
8905   for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
8906     if (DECL_NAME (decl_chain) == ident)
8907       return decl_chain;
8908   return NULL_TREE;
8909 }
8910
8911 /* True if the ivar is private and we are not in its implementation.  */
8912
8913 static int
8914 is_private (tree decl)
8915 {
8916   return (TREE_PRIVATE (decl)
8917           && ! is_ivar (CLASS_IVARS (implementation_template),
8918                         DECL_NAME (decl)));
8919 }
8920
8921 /* We have an instance variable reference;, check to see if it is public.  */
8922
8923 int
8924 objc_is_public (tree expr, tree identifier)
8925 {
8926   tree basetype, decl;
8927
8928 #ifdef OBJCPLUS
8929   if (processing_template_decl)
8930     return 1;
8931 #endif
8932
8933   if (TREE_TYPE (expr) == error_mark_node)
8934     return 1;
8935
8936   basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
8937
8938   if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
8939     {
8940       if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
8941         {
8942           tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
8943
8944           if (!klass)
8945             {
8946               error ("cannot find interface declaration for %qE",
8947                      OBJC_TYPE_NAME (basetype));
8948               return 0;
8949             }
8950
8951           if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
8952             {
8953               if (TREE_PUBLIC (decl))
8954                 return 1;
8955
8956               /* Important difference between the Stepstone translator:
8957                  all instance variables should be public within the context
8958                  of the implementation.  */
8959               if (objc_implementation_context
8960                  && ((TREE_CODE (objc_implementation_context)
8961                       == CLASS_IMPLEMENTATION_TYPE)
8962                      || (TREE_CODE (objc_implementation_context)
8963                          == CATEGORY_IMPLEMENTATION_TYPE)))
8964                 {
8965                   tree curtype = TYPE_MAIN_VARIANT
8966                                  (CLASS_STATIC_TEMPLATE
8967                                   (implementation_template));
8968
8969                   if (basetype == curtype
8970                       || DERIVED_FROM_P (basetype, curtype))
8971                     {
8972                       int priv = is_private (decl);
8973
8974                       if (priv)
8975                         error ("instance variable %qE is declared private",
8976                                DECL_NAME (decl));
8977
8978                       return !priv;
8979                     }
8980                 }
8981
8982               /* The 2.95.2 compiler sometimes allowed C functions to access
8983                  non-@public ivars.  We will let this slide for now...  */
8984               if (!objc_method_context)
8985               {
8986                 warning (0, "instance variable %qE is %s; "
8987                          "this will be a hard error in the future",
8988                          identifier,
8989                          TREE_PRIVATE (decl) ? "@private" : "@protected");
8990                 return 1;
8991               }
8992
8993               error ("instance variable %qE is declared %s",
8994                      identifier,
8995                      TREE_PRIVATE (decl) ? "private" : "protected");
8996               return 0;
8997             }
8998         }
8999     }
9000
9001   return 1;
9002 }
9003 \f
9004 /* Make sure all methods in CHAIN (a list of method declarations from
9005    an @interface or a @protocol) are in IMPLEMENTATION (the
9006    implementation context).  This is used to check for example that
9007    all methods declared in an @interface were implemented in an
9008    @implementation.
9009
9010    Some special methods (property setters/getters) are special and if
9011    they are not found in IMPLEMENTATION, we look them up in its
9012    superclasses.  */
9013
9014 static int
9015 check_methods (tree chain, tree implementation, int mtype)
9016 {
9017   int first = 1;
9018   tree list;
9019
9020   if (mtype == (int)'+')
9021     list = CLASS_CLS_METHODS (implementation);
9022   else
9023     list = CLASS_NST_METHODS (implementation);
9024
9025   while (chain)
9026     {
9027       /* If the method is associated with a dynamic property, then it
9028          is Ok not to have the method implementation, as it will be
9029          generated dynamically at runtime.  To decide if the method is
9030          associated with a @dynamic property, we search the list of
9031          @synthesize and @dynamic for this implementation, and look
9032          for any @dynamic property with the same setter or getter name
9033          as this method.  */
9034       tree x;
9035       for (x = IMPL_PROPERTY_DECL (implementation); x; x = TREE_CHAIN (x))
9036         if (PROPERTY_DYNAMIC (x)
9037             && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
9038                 || PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
9039           break;
9040       
9041       if (x != NULL_TREE)
9042         {
9043           chain = TREE_CHAIN (chain); /* next method...  */
9044           continue;
9045         }
9046
9047       if (!lookup_method (list, chain))
9048         {
9049           /* If the method is a property setter/getter, we'll still
9050              allow it to be missing if it is implemented by
9051              'interface' or any of its superclasses.  */
9052           tree property = METHOD_PROPERTY_CONTEXT (chain);
9053           if (property)
9054             {
9055               /* Note that since this is a property getter/setter, it
9056                  is obviously an instance method.  */
9057               tree interface = NULL_TREE;
9058
9059               /* For a category, first check the main class
9060                  @interface.  */
9061               if (TREE_CODE (implementation) == CATEGORY_IMPLEMENTATION_TYPE)
9062                 {
9063                   interface = lookup_interface (CLASS_NAME (implementation));
9064
9065                   /* If the method is found in the main class, it's Ok.  */
9066                   if (lookup_method (CLASS_NST_METHODS (interface), chain))
9067                     {
9068                       chain = DECL_CHAIN (chain);
9069                       continue;               
9070                     }
9071
9072                   /* Else, get the superclass.  */
9073                   if (CLASS_SUPER_NAME (interface))
9074                     interface = lookup_interface (CLASS_SUPER_NAME (interface));
9075                   else
9076                     interface = NULL_TREE;
9077                 }
9078
9079               /* Get the superclass for classes.  */
9080               if (TREE_CODE (implementation) == CLASS_IMPLEMENTATION_TYPE)
9081                 {
9082                   if (CLASS_SUPER_NAME (implementation))
9083                     interface = lookup_interface (CLASS_SUPER_NAME (implementation));
9084                   else
9085                     interface = NULL_TREE;
9086                 }
9087
9088               /* Now, interface is the superclass, if any; go check it.  */
9089               if (interface)
9090                 {
9091                   if (lookup_method_static (interface, chain, 0))
9092                     {
9093                       chain = DECL_CHAIN (chain);
9094                       continue;
9095                     }
9096                 }
9097               /* Else, fall through - warn.  */
9098             }
9099           if (first)
9100             {
9101               switch (TREE_CODE (implementation))
9102                 {
9103                 case CLASS_IMPLEMENTATION_TYPE:
9104                   warning (0, "incomplete implementation of class %qE",
9105                            CLASS_NAME (implementation));
9106                   break;
9107                 case CATEGORY_IMPLEMENTATION_TYPE:
9108                   warning (0, "incomplete implementation of category %qE",
9109                            CLASS_SUPER_NAME (implementation));
9110                   break;
9111                 default:
9112                   gcc_unreachable ();
9113                 }
9114               first = 0;
9115             }
9116
9117           warning (0, "method definition for %<%c%E%> not found",
9118                    mtype, METHOD_SEL_NAME (chain));
9119         }
9120
9121       chain = DECL_CHAIN (chain);
9122     }
9123
9124     return first;
9125 }
9126
9127 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL.  */
9128
9129 static int
9130 conforms_to_protocol (tree klass, tree protocol)
9131 {
9132    if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
9133      {
9134        tree p = CLASS_PROTOCOL_LIST (klass);
9135        while (p && TREE_VALUE (p) != protocol)
9136          p = TREE_CHAIN (p);
9137
9138        if (!p)
9139          {
9140            tree super = (CLASS_SUPER_NAME (klass)
9141                          ? lookup_interface (CLASS_SUPER_NAME (klass))
9142                          : NULL_TREE);
9143            int tmp = super ? conforms_to_protocol (super, protocol) : 0;
9144            if (!tmp)
9145              return 0;
9146          }
9147      }
9148
9149    return 1;
9150 }
9151
9152 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
9153    CONTEXT.  This is one of two mechanisms to check protocol integrity.  */
9154
9155 static int
9156 check_methods_accessible (tree chain, tree context, int mtype)
9157 {
9158   int first = 1;
9159   tree list;
9160   tree base_context = context;
9161
9162   while (chain)
9163     {
9164       /* If the method is associated with a dynamic property, then it
9165          is Ok not to have the method implementation, as it will be
9166          generated dynamically at runtime.  Search for any @dynamic
9167          property with the same setter or getter name as this
9168          method.  TODO: Use a hashtable lookup.  */
9169       tree x;
9170       for (x = IMPL_PROPERTY_DECL (base_context); x; x = TREE_CHAIN (x))
9171         if (PROPERTY_DYNAMIC (x)
9172             && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
9173                 || PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
9174           break;
9175       
9176       if (x != NULL_TREE)
9177         {
9178           chain = TREE_CHAIN (chain); /* next method...  */
9179           continue;
9180         }       
9181
9182       context = base_context;
9183       while (context)
9184         {
9185           if (mtype == '+')
9186             list = CLASS_CLS_METHODS (context);
9187           else
9188             list = CLASS_NST_METHODS (context);
9189
9190           if (lookup_method (list, chain))
9191               break;
9192
9193           switch (TREE_CODE (context))
9194             {
9195             case CLASS_IMPLEMENTATION_TYPE:
9196             case CLASS_INTERFACE_TYPE:
9197               context = (CLASS_SUPER_NAME (context)
9198                          ? lookup_interface (CLASS_SUPER_NAME (context))
9199                          : NULL_TREE);
9200               break;
9201             case CATEGORY_IMPLEMENTATION_TYPE:
9202             case CATEGORY_INTERFACE_TYPE:
9203               context = (CLASS_NAME (context)
9204                          ? lookup_interface (CLASS_NAME (context))
9205                          : NULL_TREE);
9206               break;
9207             default:
9208               gcc_unreachable ();
9209             }
9210         }
9211
9212       if (context == NULL_TREE)
9213         {
9214           if (first)
9215             {
9216               switch (TREE_CODE (objc_implementation_context))
9217                 {
9218                 case CLASS_IMPLEMENTATION_TYPE:
9219                   warning (0, "incomplete implementation of class %qE",
9220                            CLASS_NAME (objc_implementation_context));
9221                   break;
9222                 case CATEGORY_IMPLEMENTATION_TYPE:
9223                   warning (0, "incomplete implementation of category %qE",
9224                            CLASS_SUPER_NAME (objc_implementation_context));
9225                   break;
9226                 default:
9227                   gcc_unreachable ();
9228                 }
9229               first = 0;
9230             }
9231           warning (0, "method definition for %<%c%E%> not found",
9232                    mtype, METHOD_SEL_NAME (chain));
9233         }
9234
9235       chain = TREE_CHAIN (chain); /* next method...  */
9236     }
9237   return first;
9238 }
9239
9240 /* Check whether the current interface (accessible via
9241    'objc_implementation_context') actually implements protocol P, along
9242    with any protocols that P inherits.  */
9243
9244 static void
9245 check_protocol (tree p, const char *type, tree name)
9246 {
9247   if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
9248     {
9249       int f1, f2;
9250
9251       /* Ensure that all protocols have bodies!  */
9252       if (warn_protocol)
9253         {
9254           f1 = check_methods (PROTOCOL_CLS_METHODS (p),
9255                               objc_implementation_context,
9256                               '+');
9257           f2 = check_methods (PROTOCOL_NST_METHODS (p),
9258                               objc_implementation_context,
9259                               '-');
9260         }
9261       else
9262         {
9263           f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
9264                                          objc_implementation_context,
9265                                          '+');
9266           f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
9267                                          objc_implementation_context,
9268                                          '-');
9269         }
9270
9271       if (!f1 || !f2)
9272         warning (0, "%s %qE does not fully implement the %qE protocol",
9273                  type, name, PROTOCOL_NAME (p));
9274     }
9275
9276   /* Check protocols recursively.  */
9277   if (PROTOCOL_LIST (p))
9278     {
9279       tree subs = PROTOCOL_LIST (p);
9280       tree super_class =
9281         lookup_interface (CLASS_SUPER_NAME (implementation_template));
9282
9283       while (subs)
9284         {
9285           tree sub = TREE_VALUE (subs);
9286
9287           /* If the superclass does not conform to the protocols
9288              inherited by P, then we must!  */
9289           if (!super_class || !conforms_to_protocol (super_class, sub))
9290             check_protocol (sub, type, name);
9291           subs = TREE_CHAIN (subs);
9292         }
9293     }
9294 }
9295
9296 /* Check whether the current interface (accessible via
9297    'objc_implementation_context') actually implements the protocols listed
9298    in PROTO_LIST.  */
9299
9300 static void
9301 check_protocols (tree proto_list, const char *type, tree name)
9302 {
9303   for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
9304     {
9305       tree p = TREE_VALUE (proto_list);
9306
9307       check_protocol (p, type, name);
9308     }
9309 }
9310 \f
9311 /* Make sure that the class CLASS_NAME is defined
9312    CODE says which kind of thing CLASS_NAME ought to be.
9313    It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
9314    CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.  */
9315
9316 static tree
9317 start_class (enum tree_code code, tree class_name, tree super_name,
9318              tree protocol_list, tree attributes)
9319 {
9320   tree klass, decl;
9321
9322 #ifdef OBJCPLUS
9323   if (current_namespace != global_namespace) {
9324     error ("Objective-C declarations may only appear in global scope");
9325   }
9326 #endif /* OBJCPLUS */
9327
9328   if (objc_implementation_context)
9329     {
9330       warning (0, "%<@end%> missing in implementation context");
9331       finish_class (objc_implementation_context);
9332       objc_ivar_chain = NULL_TREE;
9333       objc_implementation_context = NULL_TREE;
9334     }
9335
9336   klass = make_node (code);
9337   TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
9338
9339   /* Check for existence of the super class, if one was specified.  Note
9340      that we must have seen an @interface, not just a @class.  If we
9341      are looking at a @compatibility_alias, traverse it first.  */
9342   if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
9343       && super_name)
9344     {
9345       tree super = objc_is_class_name (super_name);
9346       tree super_interface = NULL_TREE;
9347
9348       if (super)
9349         super_interface = lookup_interface (super);
9350       
9351       if (!super_interface)
9352         {
9353           error ("cannot find interface declaration for %qE, superclass of %qE",
9354                  super ? super : super_name,
9355                  class_name);
9356           super_name = NULL_TREE;
9357         }
9358       else
9359         {
9360           if (TREE_DEPRECATED (super_interface))
9361             warning (OPT_Wdeprecated_declarations, "class %qE is deprecated", 
9362                      super);
9363           super_name = super;
9364         }
9365     }
9366
9367   CLASS_NAME (klass) = class_name;
9368   CLASS_SUPER_NAME (klass) = super_name;
9369   CLASS_CLS_METHODS (klass) = NULL_TREE;
9370
9371   if (! objc_is_class_name (class_name)
9372       && (decl = lookup_name (class_name)))
9373     {
9374       error ("%qE redeclared as different kind of symbol",
9375              class_name);
9376       error ("previous declaration of %q+D",
9377              decl);
9378     }
9379
9380   switch (code)
9381     {
9382     case CLASS_IMPLEMENTATION_TYPE:
9383       {
9384         tree chain;
9385         
9386         for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
9387           if (TREE_VALUE (chain) == class_name)
9388             {
9389               error ("reimplementation of class %qE",
9390                      class_name);
9391               return error_mark_node;
9392             }
9393         implemented_classes = tree_cons (NULL_TREE, class_name,
9394                                          implemented_classes);
9395       }
9396
9397       /* Reset for multiple classes per file.  */
9398       method_slot = 0;
9399
9400       objc_implementation_context = klass;
9401
9402       /* Lookup the interface for this implementation.  */
9403
9404       if (!(implementation_template = lookup_interface (class_name)))
9405         {
9406           warning (0, "cannot find interface declaration for %qE",
9407                    class_name);
9408           add_class (implementation_template = objc_implementation_context,
9409                      class_name);
9410         }
9411
9412       /* If a super class has been specified in the implementation,
9413          insure it conforms to the one specified in the interface.  */
9414
9415       if (super_name
9416           && (super_name != CLASS_SUPER_NAME (implementation_template)))
9417         {
9418           tree previous_name = CLASS_SUPER_NAME (implementation_template);
9419           error ("conflicting super class name %qE",
9420                  super_name);
9421           if (previous_name)
9422             error ("previous declaration of %qE", previous_name);
9423           else
9424             error ("previous declaration");
9425         }
9426
9427       else if (! super_name)
9428         {
9429           CLASS_SUPER_NAME (objc_implementation_context)
9430             = CLASS_SUPER_NAME (implementation_template);
9431         }
9432       break;
9433
9434     case CLASS_INTERFACE_TYPE:
9435       if (lookup_interface (class_name))
9436 #ifdef OBJCPLUS
9437         error ("duplicate interface declaration for class %qE", class_name);
9438 #else
9439         warning (0, "duplicate interface declaration for class %qE", class_name);
9440 #endif
9441       else
9442         add_class (klass, class_name);
9443        
9444       if (protocol_list)
9445         CLASS_PROTOCOL_LIST (klass)
9446           = lookup_and_install_protocols (protocol_list);
9447
9448       /* Determine if 'deprecated', the only attribute we recognize
9449          for classes, was used.  Ignore all other attributes for now,
9450          but store them in the klass.  */
9451       if (attributes)
9452         {
9453           tree attribute;
9454           for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
9455             {
9456               tree name = TREE_PURPOSE (attribute);
9457               
9458               if (is_attribute_p  ("deprecated", name))
9459                 TREE_DEPRECATED (klass) = 1;
9460             }
9461           TYPE_ATTRIBUTES (klass) = attributes;
9462         }
9463       break;     
9464
9465     case CATEGORY_INTERFACE_TYPE:
9466       {
9467         tree class_category_is_assoc_with;
9468         
9469         /* For a category, class_name is really the name of the class that
9470            the following set of methods will be associated with. We must
9471            find the interface so that can derive the objects template.  */
9472         if (!(class_category_is_assoc_with = lookup_interface (class_name)))
9473           {
9474             error ("cannot find interface declaration for %qE",
9475                    class_name);
9476             exit (FATAL_EXIT_CODE);
9477           }
9478         else
9479           {
9480             if (TREE_DEPRECATED (class_category_is_assoc_with))
9481               warning (OPT_Wdeprecated_declarations, "class %qE is deprecated", 
9482                        class_name);
9483             add_category (class_category_is_assoc_with, klass);
9484           }
9485
9486         if (protocol_list)
9487           CLASS_PROTOCOL_LIST (klass)
9488             = lookup_and_install_protocols (protocol_list);
9489       }
9490       break;
9491
9492     case CATEGORY_IMPLEMENTATION_TYPE:
9493       /* Reset for multiple classes per file.  */
9494       method_slot = 0;
9495
9496       objc_implementation_context = klass;
9497
9498       /* For a category, class_name is really the name of the class that
9499          the following set of methods will be associated with.  We must
9500          find the interface so that can derive the objects template.  */
9501
9502       if (!(implementation_template = lookup_interface (class_name)))
9503         {
9504           error ("cannot find interface declaration for %qE",
9505                  class_name);
9506           exit (FATAL_EXIT_CODE);
9507         }
9508       break;
9509     default:
9510       gcc_unreachable ();
9511     }
9512   return klass;
9513 }
9514
9515 static tree
9516 continue_class (tree klass)
9517 {
9518   switch (TREE_CODE (klass))
9519     {
9520     case CLASS_IMPLEMENTATION_TYPE:
9521     case CATEGORY_IMPLEMENTATION_TYPE:
9522       {
9523         struct imp_entry *imp_entry;
9524
9525         /* Check consistency of the instance variables.  */
9526
9527         if (CLASS_RAW_IVARS (klass))
9528           check_ivars (implementation_template, klass);
9529         
9530         /* code generation */
9531 #ifdef OBJCPLUS
9532         push_lang_context (lang_name_c);
9533 #endif
9534         build_private_template (implementation_template);
9535         uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
9536         objc_instance_type = build_pointer_type (uprivate_record);
9537
9538         imp_entry = ggc_alloc_imp_entry ();
9539
9540         imp_entry->next = imp_list;
9541         imp_entry->imp_context = klass;
9542         imp_entry->imp_template = implementation_template;
9543
9544         synth_forward_declarations ();
9545         imp_entry->class_decl = UOBJC_CLASS_decl;
9546         imp_entry->meta_decl = UOBJC_METACLASS_decl;
9547         imp_entry->has_cxx_cdtors = 0;
9548
9549         /* Append to front and increment count.  */
9550         imp_list = imp_entry;
9551         if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
9552           imp_count++;
9553         else
9554           cat_count++;
9555 #ifdef OBJCPLUS
9556         pop_lang_context ();
9557 #endif /* OBJCPLUS */
9558         
9559         return get_class_ivars (implementation_template, true);
9560         break;
9561       }
9562     case CLASS_INTERFACE_TYPE:
9563       {
9564 #ifdef OBJCPLUS
9565         push_lang_context (lang_name_c);
9566 #endif /* OBJCPLUS */
9567         objc_collecting_ivars = 1;
9568         build_private_template (klass);
9569         objc_collecting_ivars = 0;
9570 #ifdef OBJCPLUS
9571         pop_lang_context ();
9572 #endif /* OBJCPLUS */
9573         return NULL_TREE;
9574         break;
9575       }
9576     default:
9577       return error_mark_node;
9578     }
9579 }
9580
9581 /* This routine builds name of the setter synthesized function. */
9582 static char *
9583 objc_build_property_setter_name (tree ident)
9584 {
9585   /* TODO: Use alloca to allocate buffer of appropriate size.  */
9586   static char string[BUFSIZE];
9587   sprintf (string, "set%s:", IDENTIFIER_POINTER (ident));
9588   string[3] = TOUPPER (string[3]);
9589   return string;
9590 }
9591
9592 /* This routine prepares the declarations of the property accessor
9593    helper functions (objc_getProperty(), etc) that are used when
9594    @synthesize is used.  */
9595 static void 
9596 build_objc_property_accessor_helpers (void)
9597 {
9598   tree type;
9599
9600   /* Declare the following function:
9601      id
9602      objc_getProperty (id self, SEL _cmd, 
9603                        ptrdiff_t offset, BOOL is_atomic);  */
9604   type = build_function_type_list (objc_object_type,
9605                                    objc_object_type,
9606                                    objc_selector_type,
9607                                    ptrdiff_type_node,
9608                                    boolean_type_node,
9609                                    NULL_TREE);
9610   objc_getProperty_decl = add_builtin_function ("objc_getProperty",
9611                                                 type, 0, NOT_BUILT_IN,
9612                                                 NULL, NULL_TREE);
9613   TREE_NOTHROW (objc_getProperty_decl) = 0;
9614   
9615   /* Declare the following function:
9616      void
9617      objc_setProperty (id self, SEL _cmd, 
9618                        ptrdiff_t offset, id new_value, 
9619                        BOOL is_atomic, BOOL should_copy);  */
9620   type = build_function_type_list (void_type_node,
9621                                    objc_object_type,
9622                                    objc_selector_type,
9623                                    ptrdiff_type_node,
9624                                    objc_object_type,
9625                                    boolean_type_node,
9626                                    boolean_type_node,
9627                                    NULL_TREE);
9628   objc_setProperty_decl = add_builtin_function ("objc_setProperty",
9629                                                 type, 0, NOT_BUILT_IN,
9630                                                 NULL, NULL_TREE);
9631   TREE_NOTHROW (objc_setProperty_decl) = 0;
9632
9633   /* This is the type of all of the following functions
9634      (objc_copyStruct(), objc_getPropertyStruct() and
9635      objc_setPropertyStruct()).  */
9636   type = build_function_type_list (void_type_node,
9637                                    ptr_type_node,
9638                                    const_ptr_type_node,
9639                                    ptrdiff_type_node,       
9640                                    boolean_type_node,
9641                                    boolean_type_node,
9642                                    NULL_TREE);
9643
9644   if (flag_next_runtime)
9645     {
9646       /* Declare the following function:
9647          void
9648          objc_copyStruct (void *destination, const void *source, 
9649                           ptrdiff_t size, BOOL is_atomic, BOOL has_strong);  */
9650       objc_copyStruct_decl = add_builtin_function ("objc_copyStruct",
9651                                                    type, 0, NOT_BUILT_IN,
9652                                                    NULL, NULL_TREE);
9653       TREE_NOTHROW (objc_copyStruct_decl) = 0;
9654       objc_getPropertyStruct_decl = NULL_TREE;
9655       objc_setPropertyStruct_decl = NULL_TREE;
9656     }
9657   else
9658     {
9659       objc_copyStruct_decl = NULL_TREE;
9660
9661       /* Declare the following function:
9662          void
9663          objc_getPropertyStruct (void *destination, const void *source, 
9664                                  ptrdiff_t size, BOOL is_atomic, BOOL has_strong);  */
9665       objc_getPropertyStruct_decl = add_builtin_function ("objc_getPropertyStruct",
9666                                                           type, 0, NOT_BUILT_IN,
9667                                                           NULL, NULL_TREE);
9668       TREE_NOTHROW (objc_getPropertyStruct_decl) = 0;
9669       /* Declare the following function:
9670          void
9671          objc_setPropertyStruct (void *destination, const void *source, 
9672                                  ptrdiff_t size, BOOL is_atomic, BOOL has_strong);  */
9673       objc_setPropertyStruct_decl = add_builtin_function ("objc_setPropertyStruct",
9674                                                           type, 0, NOT_BUILT_IN,
9675                                                           NULL, NULL_TREE);
9676       TREE_NOTHROW (objc_setPropertyStruct_decl) = 0;
9677     }
9678 }
9679
9680 /* This looks up an ivar in a class (including superclasses).  */
9681 static tree
9682 lookup_ivar (tree interface, tree instance_variable_name)
9683 {
9684   while (interface)
9685     {
9686       tree decl_chain;
9687       
9688       for (decl_chain = CLASS_IVARS (interface); decl_chain; decl_chain = DECL_CHAIN (decl_chain))
9689         if (DECL_NAME (decl_chain) == instance_variable_name)
9690           return decl_chain;
9691       
9692       /* Not found.  Search superclass if any.  */
9693       if (CLASS_SUPER_NAME (interface))
9694         interface = lookup_interface (CLASS_SUPER_NAME (interface));
9695     }
9696   
9697   return NULL_TREE;
9698 }
9699
9700 /* This routine synthesizes a 'getter' method.  This is only called
9701    for @synthesize properties.  */
9702 static void
9703 objc_synthesize_getter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
9704 {
9705   location_t location = DECL_SOURCE_LOCATION (property);
9706   tree fn, decl;
9707   tree body;
9708   tree ret_val;
9709
9710   /* If user has implemented a getter with same name then do nothing.  */
9711   if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
9712                      PROPERTY_GETTER_NAME (property)))
9713     return;
9714
9715   /* Find declaration of the property getter in the interface (or
9716      superclass, or protocol). There must be one.  */
9717   decl = lookup_method_static (klass, PROPERTY_GETTER_NAME (property), 0);
9718
9719   /* If one not declared in the interface, this condition has already
9720      been reported as user error (because property was not declared in
9721      the interface).  */
9722   if (!decl)
9723     return;
9724
9725   /* Adapt the 'decl'.  Use the source location of the @synthesize
9726      statement for error messages.  */
9727   decl = copy_node (decl);
9728   DECL_SOURCE_LOCATION (decl) = location;
9729
9730   objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE);
9731   body = c_begin_compound_stmt (true);
9732
9733   /* Now we need to decide how we build the getter.  There are three
9734      cases:
9735
9736      for 'copy' or 'retain' properties we need to use the
9737      objc_getProperty() accessor helper which knows about retain and
9738      copy.  It supports both 'nonatomic' and 'atomic' access.
9739
9740      for 'nonatomic, assign' properties we can access the instance
9741      variable directly.  'nonatomic' means we don't have to use locks,
9742      and 'assign' means we don't have to worry about retain or copy.
9743      If you combine the two, it means we can just access the instance
9744      variable directly.
9745
9746      for 'atomic, assign' properties we use objc_copyStruct() (for the
9747      next runtime) or objc_getPropertyStruct() (for the GNU runtime).  */
9748   switch (PROPERTY_ASSIGN_SEMANTICS (property))
9749     {
9750     case OBJC_PROPERTY_RETAIN:
9751     case OBJC_PROPERTY_COPY:
9752       {
9753         /* We build "return objc_getProperty (self, _cmd, offset, is_atomic);"  */
9754         tree cmd, ivar, offset, is_atomic;
9755         cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
9756
9757         /* Find the ivar to compute the offset.  */
9758         ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
9759         if (!ivar || is_private (ivar))
9760           {
9761             /* This should never happen.  */
9762             error_at (location,
9763                       "can not find instance variable associated with property");
9764             ret_val = error_mark_node;
9765             break;
9766           }
9767         offset = byte_position (ivar);
9768
9769         if (PROPERTY_NONATOMIC (property))
9770           is_atomic = boolean_false_node;
9771         else
9772           is_atomic = boolean_true_node;
9773
9774         ret_val = build_function_call
9775           (location,
9776            /* Function prototype.  */
9777            objc_getProperty_decl,
9778            /* Parameters.  */
9779            tree_cons    /* self */
9780            (NULL_TREE, self_decl,
9781             tree_cons   /* _cmd */
9782             (NULL_TREE, cmd,
9783              tree_cons  /* offset */
9784              (NULL_TREE, offset,
9785               tree_cons /* is_atomic */
9786               (NULL_TREE, is_atomic, NULL_TREE)))));
9787       }
9788       break;
9789     case OBJC_PROPERTY_ASSIGN:    
9790       if (PROPERTY_NONATOMIC (property))
9791         {
9792           /* We build "return self->PROPERTY_IVAR_NAME;"  */
9793           ret_val = objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property));
9794           break;
9795         }
9796       else
9797         {
9798           /* We build
9799                <property type> __objc_property_temp;
9800                objc_getPropertyStruct (&__objc_property_temp,
9801                                        &(self->PROPERTY_IVAR_NAME),
9802                                        sizeof (type of self->PROPERTY_IVAR_NAME),
9803                                        is_atomic,
9804                                        false)
9805                return __objc_property_temp;
9806
9807              For the NeXT runtime, we need to use objc_copyStruct
9808              instead of objc_getPropertyStruct.  */
9809           tree objc_property_temp_decl, function_decl, function_call;
9810           tree size_of, is_atomic;
9811
9812           objc_property_temp_decl = objc_create_temporary_var (TREE_TYPE (property), "__objc_property_temp");
9813           DECL_SOURCE_LOCATION (objc_property_temp_decl) = location;
9814           objc_property_temp_decl = lang_hooks.decls.pushdecl (objc_property_temp_decl);
9815
9816           /* sizeof (ivar type).  Since the ivar and the property have
9817              the same type, there is no need to lookup the ivar.  */
9818           size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
9819                                               true /* is_sizeof */,
9820                                               false /* complain */);
9821           
9822           if (PROPERTY_NONATOMIC (property))
9823             is_atomic = boolean_false_node;
9824           else
9825             is_atomic = boolean_true_node;
9826           
9827           if (flag_next_runtime)
9828             function_decl = objc_copyStruct_decl;
9829           else
9830             function_decl = objc_getPropertyStruct_decl;
9831
9832           function_call = build_function_call
9833             (location,
9834              /* Function prototype.  */
9835              function_decl,
9836              /* Parameters.  */
9837              tree_cons /* &__objc_property_temp_decl */
9838              /* Warning: note that using build_fold_addr_expr_loc()
9839                 here causes invalid code to be generated.  */
9840              (NULL_TREE, build_unary_op (location, ADDR_EXPR, objc_property_temp_decl, 0),
9841               tree_cons /* &(self->PROPERTY_IVAR_NAME); */
9842               (NULL_TREE, build_fold_addr_expr_loc (location, 
9843                                                     objc_lookup_ivar 
9844                                                     (NULL_TREE, PROPERTY_IVAR_NAME (property))),
9845                tree_cons /* sizeof (PROPERTY_IVAR) */
9846                (NULL_TREE, size_of,
9847                 tree_cons /* is_atomic */
9848                 (NULL_TREE, is_atomic,
9849                  /* TODO: This is currently ignored by the GNU
9850                     runtime, but what about the next one ? */
9851                  tree_cons /* has_strong */
9852                  (NULL_TREE, boolean_true_node, NULL_TREE))))));
9853
9854           add_stmt (function_call);
9855
9856           ret_val = objc_property_temp_decl;
9857         }
9858       break;
9859     default:
9860       gcc_unreachable ();
9861     }
9862
9863   gcc_assert (ret_val);
9864
9865 #ifdef OBJCPLUS
9866   finish_return_stmt (ret_val);
9867 #else
9868   c_finish_return (location, ret_val, NULL_TREE);
9869 #endif
9870
9871   add_stmt (c_end_compound_stmt (location, body, true));
9872   fn = current_function_decl;
9873 #ifdef OBJCPLUS
9874   finish_function ();
9875 #endif
9876   objc_finish_method_definition (fn);
9877 }
9878
9879 /* This routine synthesizes a 'setter' method.  */
9880
9881 static void
9882 objc_synthesize_setter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
9883 {
9884   location_t location = DECL_SOURCE_LOCATION (property);
9885   tree fn, decl;
9886   tree body;
9887   tree new_value, statement;
9888
9889   /* If user has implemented a setter with same name then do nothing.  */
9890   if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
9891                      PROPERTY_SETTER_NAME (property)))
9892     return;
9893
9894   /* Find declaration of the property setter in the interface (or
9895      superclass, or protocol). There must be one.  */
9896   decl = lookup_method_static (klass, PROPERTY_SETTER_NAME (property), 0);
9897
9898   /* If one not declared in the interface, this condition has already
9899      been reported as user error (because property was not declared in
9900      the interface).  */
9901   if (!decl)
9902     return;
9903
9904   /* Adapt the 'decl'.  Use the source location of the @synthesize
9905      statement for error messages.  */
9906   decl = copy_node (decl);
9907   DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (property);
9908
9909   objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE);
9910
9911   body = c_begin_compound_stmt (true);
9912
9913   /* The 'new_value' is the only argument to the method, which is the
9914      3rd argument of the function, after self and _cmd.  We use twice
9915      TREE_CHAIN to move forward two arguments.  */
9916   new_value = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)));
9917
9918   /* This would presumably happen if the user has specified a
9919      prototype for the setter that does not have an argument!  */
9920   if (new_value == NULL_TREE)
9921     {
9922       /* TODO: This should be caught much earlier than this.  */
9923       error_at (DECL_SOURCE_LOCATION (decl), "invalid setter, it must have one argument");
9924       /* Try to recover somehow.  */
9925       new_value = error_mark_node;
9926     }
9927
9928   /* Now we need to decide how we build the setter.  There are three
9929      cases:
9930
9931      for 'copy' or 'retain' properties we need to use the
9932      objc_setProperty() accessor helper which knows about retain and
9933      copy.  It supports both 'nonatomic' and 'atomic' access.
9934
9935      for 'nonatomic, assign' properties we can access the instance
9936      variable directly.  'nonatomic' means we don't have to use locks,
9937      and 'assign' means we don't have to worry about retain or copy.
9938      If you combine the two, it means we can just access the instance
9939      variable directly.
9940
9941      for 'atomic, assign' properties we use objc_copyStruct() (for the
9942      next runtime) or objc_setPropertyStruct() (for the GNU runtime).  */
9943   switch (PROPERTY_ASSIGN_SEMANTICS (property))
9944     {
9945     case OBJC_PROPERTY_RETAIN:
9946     case OBJC_PROPERTY_COPY:
9947       {
9948         /* We build "objc_setProperty (self, _cmd, new_value, offset, is_atomic, should_copy);"  */
9949         tree cmd, ivar, offset, is_atomic, should_copy;
9950         cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
9951
9952         /* Find the ivar to compute the offset.  */
9953         ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
9954         if (!ivar || is_private (ivar))
9955           {
9956             error_at (location,
9957                       "can not find instance variable associated with property");
9958             statement = error_mark_node;
9959             break;
9960           }
9961         offset = byte_position (ivar);
9962
9963         if (PROPERTY_NONATOMIC (property))
9964           is_atomic = boolean_false_node;
9965         else
9966           is_atomic = boolean_true_node;
9967         
9968         if (PROPERTY_ASSIGN_SEMANTICS (property) == OBJC_PROPERTY_COPY)
9969           should_copy = boolean_true_node;
9970         else
9971           should_copy = boolean_false_node;
9972
9973         statement = build_function_call
9974           (location,
9975            /* Function prototype.  */
9976            objc_setProperty_decl,
9977            /* Parameters.  */
9978            tree_cons    /* self */
9979            (NULL_TREE, self_decl,
9980             tree_cons   /* _cmd */
9981             (NULL_TREE, cmd,
9982              tree_cons  /* offset */
9983              (NULL_TREE, offset,
9984               tree_cons /* new_value */
9985               (NULL_TREE, new_value,
9986                tree_cons /* is_atomic */
9987                (NULL_TREE, is_atomic, 
9988                 tree_cons /* should_copy */
9989                 (NULL_TREE, should_copy, NULL_TREE)))))));
9990       }
9991       break;
9992     case OBJC_PROPERTY_ASSIGN:    
9993       if (PROPERTY_NONATOMIC (property))
9994         {
9995           /* We build "self->PROPERTY_IVAR_NAME = new_value;"  */
9996           statement = build_modify_expr
9997             (location,
9998              objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property)),
9999              NULL_TREE, NOP_EXPR, 
10000              location, new_value, NULL_TREE);
10001           break;
10002         }
10003       else
10004         {
10005           /* We build
10006                objc_setPropertyStruct (&(self->PROPERTY_IVAR_NAME),
10007                                        &new_value,
10008                                        sizeof (type of self->PROPERTY_IVAR_NAME),
10009                                        is_atomic,
10010                                        false)
10011
10012              For the NeXT runtime, we need to use objc_copyStruct
10013              instead of objc_getPropertyStruct.  */
10014           tree function_decl, size_of, is_atomic;
10015
10016           /* sizeof (ivar type).  Since the ivar and the property have
10017              the same type, there is no need to lookup the ivar.  */
10018           size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
10019                                               true /* is_sizeof */,
10020                                               false /* complain */);
10021           
10022           if (PROPERTY_NONATOMIC (property))
10023             is_atomic = boolean_false_node;
10024           else
10025             is_atomic = boolean_true_node;
10026           
10027           if (flag_next_runtime)
10028             function_decl = objc_copyStruct_decl;
10029           else
10030             function_decl = objc_setPropertyStruct_decl;
10031
10032           statement = build_function_call 
10033             (location,
10034              /* Function prototype.  */
10035              function_decl,
10036              /* Parameters.  */
10037              tree_cons /* &(self->PROPERTY_IVAR_NAME); */
10038              (NULL_TREE, build_fold_addr_expr_loc (location, 
10039                                                    objc_lookup_ivar 
10040                                                    (NULL_TREE, PROPERTY_IVAR_NAME (property))),
10041               tree_cons /* &new_value */
10042               (NULL_TREE, build_fold_addr_expr_loc (location, new_value),
10043                tree_cons /* sizeof (PROPERTY_IVAR) */
10044                (NULL_TREE, size_of,
10045                 tree_cons /* is_atomic */
10046                 (NULL_TREE, is_atomic,
10047                  /* TODO: This is currently ignored by the GNU
10048                     runtime, but what about the next one ? */
10049                  tree_cons /* has_strong */
10050                  (NULL_TREE, boolean_true_node, NULL_TREE))))));
10051         }
10052       break;
10053     default:
10054       gcc_unreachable ();
10055     }
10056   gcc_assert (statement);
10057
10058   add_stmt (statement);  
10059   add_stmt (c_end_compound_stmt (location, body, true));
10060   fn = current_function_decl;
10061 #ifdef OBJCPLUS
10062   finish_function ();
10063 #endif
10064   objc_finish_method_definition (fn);
10065 }
10066
10067 /* This function is a sub-routine of objc_add_synthesize_declaration.
10068    It is called for each property to synthesize once we have
10069    determined that the context is Ok.  */
10070 static void
10071 objc_add_synthesize_declaration_for_property (location_t location, tree interface,
10072                                               tree property_name, tree ivar_name)
10073 {
10074   /* Find the @property declaration.  */
10075   tree property;
10076   tree x;
10077
10078   /* Check that synthesize or dynamic has not already been used for
10079      the same property.  */
10080   for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
10081     if (PROPERTY_NAME (property) == property_name)
10082       {
10083         location_t original_location = DECL_SOURCE_LOCATION (property);
10084         
10085         if (PROPERTY_DYNAMIC (property))
10086           error_at (location, "property %qs already specified in %<@dynamic%>", 
10087                     IDENTIFIER_POINTER (property_name));
10088         else
10089           error_at (location, "property %qs already specified in %<@synthesize%>", 
10090                     IDENTIFIER_POINTER (property_name));
10091         
10092         if (original_location != UNKNOWN_LOCATION)
10093           inform (original_location, "originally specified here");
10094         return;
10095       }
10096
10097   /* Check that the property is declared in the interface.  It could
10098      also be declared in a superclass or protocol.  */
10099   property = lookup_property (interface, property_name);
10100
10101   if (!property)
10102     {
10103       error_at (location, "no declaration of property %qs found in the interface", 
10104                 IDENTIFIER_POINTER (property_name));
10105       return;
10106     }
10107   else
10108     {
10109       /* We have to copy the property, because we want to chain it to
10110          the implementation context, and we want to store the source
10111          location of the @synthesize, not of the original
10112          @property.  */
10113       property = copy_node (property);
10114       DECL_SOURCE_LOCATION (property) = location;
10115     }
10116
10117   /* Determine PROPERTY_IVAR_NAME.  */
10118   if (ivar_name == NULL_TREE)
10119     ivar_name = property_name;
10120
10121   /* Check that the instance variable exists.  You can only use an
10122      instance variable from the same class, not one from the
10123      superclass (this makes sense as it allows us to check that an
10124      instance variable is only used in one synthesized property).  */
10125   {
10126     tree ivar = is_ivar (CLASS_IVARS (interface), ivar_name);
10127     tree type_of_ivar;
10128     if (!ivar)
10129       {
10130         error_at (location, "ivar %qs used by %<@synthesize%> declaration must be an existing ivar", 
10131                   IDENTIFIER_POINTER (property_name));
10132         return;
10133       }
10134
10135     if (DECL_BIT_FIELD_TYPE (ivar))
10136       type_of_ivar = DECL_BIT_FIELD_TYPE (ivar);
10137     else
10138       type_of_ivar = TREE_TYPE (ivar);
10139     
10140     /* If the instance variable has a different C type, we throw an error ...  */
10141     if (!comptypes (TREE_TYPE (property), type_of_ivar)
10142         /* ... unless the property is readonly, in which case we allow
10143            the instance variable to be more specialized (this means we
10144            can generate the getter all right and it works).  */
10145         && (!PROPERTY_READONLY (property)
10146             || !objc_compare_types (TREE_TYPE (property),
10147                                     type_of_ivar, -5, NULL_TREE)))
10148       {
10149         location_t original_location = DECL_SOURCE_LOCATION (ivar);
10150         
10151         error_at (location, "property %qs is using instance variable %qs of incompatible type",
10152                   IDENTIFIER_POINTER (property_name),
10153                   IDENTIFIER_POINTER (ivar_name));
10154         
10155         if (original_location != UNKNOWN_LOCATION)
10156           inform (original_location, "originally specified here");
10157       }
10158
10159     /* If the instance variable is a bitfield, the property must be
10160        'assign', 'nonatomic' because the runtime getter/setter helper
10161        do not work with bitfield instance variables.  */
10162     if (DECL_BIT_FIELD_TYPE (ivar))
10163       {
10164         /* If there is an error, we return and not generate any
10165            getter/setter because trying to set up the runtime
10166            getter/setter helper calls with bitfields is at high risk
10167            of ICE.  */
10168
10169         if (PROPERTY_ASSIGN_SEMANTICS (property) != OBJC_PROPERTY_ASSIGN)
10170           {
10171             location_t original_location = DECL_SOURCE_LOCATION (ivar);
10172             
10173             error_at (location, "'assign' property %qs is using bit-field instance variable %qs",
10174                       IDENTIFIER_POINTER (property_name),
10175                       IDENTIFIER_POINTER (ivar_name));
10176         
10177             if (original_location != UNKNOWN_LOCATION)
10178               inform (original_location, "originally specified here");
10179             return;
10180           }
10181
10182         if (!PROPERTY_NONATOMIC (property))
10183           {
10184             location_t original_location = DECL_SOURCE_LOCATION (ivar);
10185             
10186             error_at (location, "'atomic' property %qs is using bit-field instance variable %qs",
10187                       IDENTIFIER_POINTER (property_name),
10188                       IDENTIFIER_POINTER (ivar_name));
10189             
10190             if (original_location != UNKNOWN_LOCATION)
10191               inform (original_location, "originally specified here");
10192             return;
10193           }
10194       }
10195   }
10196
10197   /* Check that no other property is using the same instance
10198      variable.  */
10199   for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
10200     if (PROPERTY_IVAR_NAME (x) == ivar_name)
10201       {
10202         location_t original_location = DECL_SOURCE_LOCATION (x);
10203         
10204         error_at (location, "property %qs is using the same instance variable as property %qs",
10205                   IDENTIFIER_POINTER (property_name),
10206                   IDENTIFIER_POINTER (PROPERTY_NAME (x)));
10207         
10208         if (original_location != UNKNOWN_LOCATION)
10209           inform (original_location, "originally specified here");
10210         
10211         /* We keep going on.  This won't cause the compiler to fail;
10212            the failure would most likely be at runtime.  */
10213       }
10214
10215   /* Note that a @synthesize (and only a @synthesize) always sets
10216      PROPERTY_IVAR_NAME to a non-NULL_TREE.  You can recognize a
10217      @synthesize by that.  */
10218   PROPERTY_IVAR_NAME (property) = ivar_name;
10219   
10220   /* PROPERTY_SETTER_NAME and PROPERTY_GETTER_NAME are copied from the
10221      original declaration; they are always set (with the exception of
10222      PROPERTY_SETTER_NAME not being set if PROPERTY_READONLY == 1).  */
10223
10224   /* Add the property to the list of properties for current implementation. */
10225   TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
10226   IMPL_PROPERTY_DECL (objc_implementation_context) = property;
10227
10228   /* Note how we don't actually synthesize the getter/setter here; it
10229      would be very natural, but we may miss the fact that the user has
10230      implemented his own getter/setter later on in the @implementation
10231      (in which case we shouldn't generate getter/setter).  We wait
10232      until we have parsed it all before generating the code.  */
10233 }
10234
10235 /* This function is called by the parser after a @synthesize
10236    expression is parsed.  'location' is the location of the
10237    @synthesize expression, and 'property_and_ivar_list' is a chained
10238    list of the property and ivar names.  */
10239 void
10240 objc_add_synthesize_declaration (location_t location, tree property_and_ivar_list)
10241 {
10242   tree interface, chain;
10243
10244   if (flag_objc1_only)
10245     error_at (input_location, "%<@synthesize%> is not available in Objective-C 1.0");
10246
10247   if (property_and_ivar_list == error_mark_node)
10248     return;
10249
10250   if (!objc_implementation_context)
10251     {
10252       /* We can get here only in Objective-C; the Objective-C++ parser
10253          detects the problem while parsing, outputs the error
10254          "misplaced '@synthesize' Objective-C++ construct" and skips
10255          the declaration.  */
10256       error_at (location, "%<@synthesize%> not in @implementation context");
10257       return;
10258     }
10259
10260   if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
10261     {
10262       error_at (location, "%<@synthesize%> can not be used in categories");
10263       return;
10264     }
10265
10266   interface = lookup_interface (CLASS_NAME (objc_implementation_context));
10267   if (!interface)
10268     {
10269       /* I can't see how this could happen, but it is good as a safety check.  */
10270       error_at (location, 
10271                 "%<@synthesize%> requires the @interface of the class to be available");
10272       return;
10273     }
10274
10275   /* Now, iterate over the properties and do each of them.  */
10276   for (chain = property_and_ivar_list; chain; chain = TREE_CHAIN (chain))
10277     {
10278       objc_add_synthesize_declaration_for_property (location, interface, TREE_VALUE (chain), 
10279                                                     TREE_PURPOSE (chain));
10280     }
10281 }
10282
10283 /* This function is a sub-routine of objc_add_dynamic_declaration.  It
10284    is called for each property to mark as dynamic once we have
10285    determined that the context is Ok.  */
10286 static void
10287 objc_add_dynamic_declaration_for_property (location_t location, tree interface,
10288                                            tree property_name)
10289 {
10290   /* Find the @property declaration.  */
10291   tree property;
10292
10293   /* Check that synthesize or dynamic has not already been used for
10294      the same property.  */
10295   for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
10296     if (PROPERTY_NAME (property) == property_name)
10297       {
10298         location_t original_location = DECL_SOURCE_LOCATION (property);
10299         
10300         if (PROPERTY_DYNAMIC (property))
10301           error_at (location, "property %qs already specified in %<@dynamic%>", 
10302                     IDENTIFIER_POINTER (property_name));
10303         else
10304           error_at (location, "property %qs already specified in %<@synthesize%>",
10305                     IDENTIFIER_POINTER (property_name));
10306
10307         if (original_location != UNKNOWN_LOCATION)
10308           inform (original_location, "originally specified here");
10309         return;
10310       }
10311
10312   /* Check that the property is declared in the interface.  It could
10313      also be declared in a superclass or protocol.  */
10314   property = lookup_property (interface, property_name);
10315
10316   if (!property)
10317     {
10318       error_at (location, "no declaration of property %qs found in the interface",
10319                 IDENTIFIER_POINTER (property_name));
10320       return;
10321     }
10322   else
10323     {
10324       /* We have to copy the property, because we want to chain it to
10325          the implementation context, and we want to store the source
10326          location of the @synthesize, not of the original
10327          @property.  */
10328       property = copy_node (property);
10329       DECL_SOURCE_LOCATION (property) = location;
10330     }
10331
10332   /* Note that a @dynamic (and only a @dynamic) always sets
10333      PROPERTY_DYNAMIC to 1.  You can recognize a @dynamic by that.
10334      (actually, as explained above, PROPERTY_DECL generated by
10335      @property and associated with a @dynamic property are also marked
10336      as PROPERTY_DYNAMIC).  */
10337   PROPERTY_DYNAMIC (property) = 1;
10338
10339   /* Add the property to the list of properties for current implementation. */
10340   TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
10341   IMPL_PROPERTY_DECL (objc_implementation_context) = property;
10342 }
10343
10344 /* This function is called by the parser after a @dynamic expression
10345    is parsed.  'location' is the location of the @dynamic expression,
10346    and 'property_list' is a chained list of all the property
10347    names.  */
10348 void
10349 objc_add_dynamic_declaration (location_t location, tree property_list)
10350 {
10351   tree interface, chain;
10352
10353   if (flag_objc1_only)
10354     error_at (input_location, "%<@dynamic%> is not available in Objective-C 1.0");
10355
10356   if (property_list == error_mark_node)
10357     return;
10358
10359   if (!objc_implementation_context)
10360     {
10361       /* We can get here only in Objective-C; the Objective-C++ parser
10362          detects the problem while parsing, outputs the error
10363          "misplaced '@dynamic' Objective-C++ construct" and skips the
10364          declaration.  */
10365       error_at (location, "%<@dynamic%> not in @implementation context");
10366       return;
10367     }
10368
10369   /* @dynamic is allowed in categories.  */
10370   switch (TREE_CODE (objc_implementation_context))
10371     {
10372     case CLASS_IMPLEMENTATION_TYPE:
10373       interface = lookup_interface (CLASS_NAME (objc_implementation_context));
10374       break;
10375     case CATEGORY_IMPLEMENTATION_TYPE:
10376       interface = lookup_category (implementation_template, 
10377                                    CLASS_SUPER_NAME (objc_implementation_context));
10378       break;
10379     default:
10380       gcc_unreachable ();
10381     }
10382
10383   if (!interface)
10384     {
10385       /* I can't see how this could happen, but it is good as a safety check.  */
10386       error_at (location,
10387                 "%<@dynamic%> requires the @interface of the class to be available");
10388       return;
10389     }
10390
10391   /* Now, iterate over the properties and do each of them.  */
10392   for (chain = property_list; chain; chain = TREE_CHAIN (chain))
10393     {
10394       objc_add_dynamic_declaration_for_property (location, interface, TREE_VALUE (chain));
10395     }
10396 }
10397
10398 /* Main routine to generate code/data for all the property information for 
10399    current implementation (class or category). CLASS is the interface where
10400    ivars are declared.  CLASS_METHODS is where methods are found which
10401    could be a class or a category depending on whether we are implementing
10402    property of a class or a category.  */
10403
10404 static void
10405 objc_gen_property_data (tree klass, tree class_methods)
10406 {
10407   tree x;
10408
10409   for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
10410     {
10411       /* @dynamic property - nothing to check or synthesize.  */
10412       if (PROPERTY_DYNAMIC (x))
10413         continue;
10414       
10415       /* @synthesize property - need to synthesize the accessors.  */
10416       if (PROPERTY_IVAR_NAME (x))
10417         {
10418           objc_synthesize_getter (klass, class_methods, x);
10419           
10420           if (PROPERTY_READONLY (x) == 0)
10421             objc_synthesize_setter (klass, class_methods, x);
10422
10423           continue;
10424         }
10425
10426       gcc_unreachable ();
10427     }
10428 }
10429
10430 /* This is called once we see the "@end" in an interface/implementation.  */
10431
10432 static void
10433 finish_class (tree klass)
10434 {
10435   switch (TREE_CODE (klass))
10436     {
10437     case CLASS_IMPLEMENTATION_TYPE:
10438       {
10439         /* All code generation is done in finish_objc.  */
10440         
10441         /* Generate what needed for property; setters, getters, etc. */
10442         objc_gen_property_data (implementation_template, implementation_template);
10443
10444         if (implementation_template != objc_implementation_context)
10445           {
10446             /* Ensure that all method listed in the interface contain bodies.  */
10447             check_methods (CLASS_CLS_METHODS (implementation_template),
10448                            objc_implementation_context, '+');
10449             check_methods (CLASS_NST_METHODS (implementation_template),
10450                            objc_implementation_context, '-');
10451
10452             if (CLASS_PROTOCOL_LIST (implementation_template))
10453               check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
10454                                "class",
10455                                CLASS_NAME (objc_implementation_context));
10456           }
10457         break;
10458       }
10459     case CATEGORY_IMPLEMENTATION_TYPE:
10460       {
10461         tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
10462         
10463         if (category)
10464           {
10465             /* Generate what needed for property; setters, getters, etc. */
10466             objc_gen_property_data (implementation_template, category);
10467
10468             /* Ensure all method listed in the interface contain bodies.  */
10469             check_methods (CLASS_CLS_METHODS (category),
10470                            objc_implementation_context, '+');
10471             check_methods (CLASS_NST_METHODS (category),
10472                            objc_implementation_context, '-');
10473             
10474             if (CLASS_PROTOCOL_LIST (category))
10475               check_protocols (CLASS_PROTOCOL_LIST (category),
10476                                "category",
10477                                CLASS_SUPER_NAME (objc_implementation_context));
10478           }
10479         break;
10480       }
10481     case CLASS_INTERFACE_TYPE:
10482     case CATEGORY_INTERFACE_TYPE:
10483     case PROTOCOL_INTERFACE_TYPE:
10484       {
10485         /* Process properties of the class. */
10486         tree x;
10487         for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
10488           {
10489             /* Now we check that the appropriate getter is declared,
10490                and if not, we declare one ourselves.  */
10491             tree getter_decl = lookup_method (CLASS_NST_METHODS (klass),
10492                                               PROPERTY_GETTER_NAME (x));
10493             
10494             if (getter_decl)
10495               {
10496                 /* TODO: Check that the declaration is consistent with the property.  */
10497                 ;
10498               }
10499             else
10500               {
10501                 /* Generate an instance method declaration for the
10502                    getter; for example "- (id) name;".  In general it
10503                    will be of the form
10504                    -(type)property_getter_name;  */
10505                 tree rettype = build_tree_list (NULL_TREE, TREE_TYPE (x));
10506                 getter_decl = build_method_decl (INSTANCE_METHOD_DECL, 
10507                                                  rettype, PROPERTY_GETTER_NAME (x), 
10508                                                  NULL_TREE, false);
10509                 objc_add_method (objc_interface_context, getter_decl, false, false);
10510                 METHOD_PROPERTY_CONTEXT (getter_decl) = x;
10511               }
10512
10513             if (PROPERTY_READONLY (x) == 0)
10514               {
10515                 /* Now we check that the appropriate setter is declared,
10516                    and if not, we declare on ourselves.  */
10517                 tree setter_decl = lookup_method (CLASS_NST_METHODS (klass), 
10518                                                   PROPERTY_SETTER_NAME (x));
10519                 
10520                 if (setter_decl)
10521                   {
10522                     /* TODO: Check that the declaration is consistent with the property.  */
10523                     ;
10524                   }
10525                 else
10526                   {
10527                     /* The setter name is something like 'setName:'.
10528                        We need the substring 'setName' to build the
10529                        method declaration due to how the declaration
10530                        works.  TODO: build_method_decl() will then
10531                        generate back 'setName:' from 'setName'; it
10532                        would be more efficient to hook into there.  */
10533                     const char *full_setter_name = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x));
10534                     size_t length = strlen (full_setter_name);
10535                     char *setter_name = (char *) alloca (length);
10536                     tree ret_type, selector, arg_type, arg_name;
10537                     
10538                     strcpy (setter_name, full_setter_name);
10539                     setter_name[length - 1] = '\0';
10540                     ret_type = build_tree_list (NULL_TREE, void_type_node);
10541                     arg_type = build_tree_list (NULL_TREE, TREE_TYPE (x));
10542                     arg_name = get_identifier ("_value");
10543                     selector = objc_build_keyword_decl (get_identifier (setter_name),
10544                                                         arg_type, arg_name, NULL);
10545                     setter_decl = build_method_decl (INSTANCE_METHOD_DECL, 
10546                                                      ret_type, selector,
10547                                                      build_tree_list (NULL_TREE, NULL_TREE),
10548                                                      false);
10549                     objc_add_method (objc_interface_context, setter_decl, false, false);
10550                     METHOD_PROPERTY_CONTEXT (setter_decl) = x;
10551                   }            
10552               }
10553           }
10554         break;
10555       }
10556     default:
10557       gcc_unreachable ();
10558       break;
10559     }
10560 }
10561
10562 static tree
10563 add_protocol (tree protocol)
10564 {
10565   /* Put protocol on list in reverse order.  */
10566   TREE_CHAIN (protocol) = protocol_chain;
10567   protocol_chain = protocol;
10568   return protocol_chain;
10569 }
10570
10571 /* Looks up a protocol.  If 'warn_if_deprecated' is true, a warning is
10572    emitted if the protocol is deprecated.  */
10573
10574 static tree
10575 lookup_protocol (tree ident, bool warn_if_deprecated)
10576 {
10577   tree chain;
10578
10579   for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
10580     if (ident == PROTOCOL_NAME (chain))
10581       {
10582         if (warn_if_deprecated && TREE_DEPRECATED (chain))
10583           {
10584             /* It would be nice to use warn_deprecated_use() here, but
10585                we are using TREE_CHAIN (which is supposed to be the
10586                TYPE_STUB_DECL for a TYPE) for something different.  */
10587             warning (OPT_Wdeprecated_declarations, "protocol %qE is deprecated", 
10588                      PROTOCOL_NAME (chain));
10589           }
10590
10591         return chain;
10592       }
10593
10594   return NULL_TREE;
10595 }
10596
10597 /* This function forward declares the protocols named by NAMES.  If
10598    they are already declared or defined, the function has no effect.  */
10599
10600 void
10601 objc_declare_protocols (tree names, tree attributes)
10602 {
10603   tree list;
10604   bool deprecated = false;
10605
10606 #ifdef OBJCPLUS
10607   if (current_namespace != global_namespace) {
10608     error ("Objective-C declarations may only appear in global scope");
10609   }
10610 #endif /* OBJCPLUS */
10611
10612   /* Determine if 'deprecated', the only attribute we recognize for
10613      protocols, was used.  Ignore all other attributes.  */
10614   if (attributes)
10615     {
10616       tree attribute;
10617       for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
10618         {
10619           tree name = TREE_PURPOSE (attribute);
10620           
10621           if (is_attribute_p  ("deprecated", name))
10622             deprecated = true;
10623         }
10624     }
10625
10626   for (list = names; list; list = TREE_CHAIN (list))
10627     {
10628       tree name = TREE_VALUE (list);
10629
10630       if (lookup_protocol (name, /* warn if deprecated */ false) == NULL_TREE)
10631         {
10632           tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
10633
10634           TYPE_LANG_SLOT_1 (protocol)
10635             = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
10636           PROTOCOL_NAME (protocol) = name;
10637           PROTOCOL_LIST (protocol) = NULL_TREE;
10638           add_protocol (protocol);
10639           PROTOCOL_DEFINED (protocol) = 0;
10640           PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
10641           
10642           if (attributes)
10643             {
10644               TYPE_ATTRIBUTES (protocol) = attributes;
10645               if (deprecated)
10646                 TREE_DEPRECATED (protocol) = 1;
10647             }
10648         }
10649     }
10650 }
10651
10652 static tree
10653 start_protocol (enum tree_code code, tree name, tree list, tree attributes)
10654 {
10655   tree protocol;
10656   bool deprecated = false;
10657
10658 #ifdef OBJCPLUS
10659   if (current_namespace != global_namespace) {
10660     error ("Objective-C declarations may only appear in global scope");
10661   }
10662 #endif /* OBJCPLUS */
10663
10664   /* Determine if 'deprecated', the only attribute we recognize for
10665      protocols, was used.  Ignore all other attributes.  */
10666   if (attributes)
10667     {
10668       tree attribute;
10669       for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
10670         {
10671           tree name = TREE_PURPOSE (attribute);
10672           
10673           if (is_attribute_p  ("deprecated", name))
10674             deprecated = true;
10675         }
10676     }
10677
10678   protocol = lookup_protocol (name, /* warn_if_deprecated */ false);
10679
10680   if (!protocol)
10681     {
10682       protocol = make_node (code);
10683       TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
10684
10685       PROTOCOL_NAME (protocol) = name;
10686       PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
10687       add_protocol (protocol);
10688       PROTOCOL_DEFINED (protocol) = 1;
10689       PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
10690
10691       check_protocol_recursively (protocol, list);
10692     }
10693   else if (! PROTOCOL_DEFINED (protocol))
10694     {
10695       PROTOCOL_DEFINED (protocol) = 1;
10696       PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
10697
10698       check_protocol_recursively (protocol, list);
10699     }
10700   else
10701     {
10702       warning (0, "duplicate declaration for protocol %qE",
10703                name);
10704     }
10705
10706   if (attributes)
10707     {
10708       TYPE_ATTRIBUTES (protocol) = attributes;
10709       if (deprecated)
10710         TREE_DEPRECATED (protocol) = 1;
10711     }
10712
10713   return protocol;
10714 }
10715
10716 \f
10717 /* "Encode" a data type into a string, which grows in util_obstack.
10718
10719    The format is described in gcc/doc/objc.texi, section 'Type
10720    encoding'.
10721
10722    Most of the encode_xxx functions have a 'type' argument, which is
10723    the type to encode, and an integer 'curtype' argument, which is the
10724    index in the encoding string of the beginning of the encoding of
10725    the current type, and allows you to find what characters have
10726    already been written for the current type (they are the ones in the
10727    current encoding string starting from 'curtype').
10728
10729    For example, if we are encoding a method which returns 'int' and
10730    takes a 'char **' argument, then when we get to the point of
10731    encoding the 'char **' argument, the encoded string already
10732    contains 'i12@0:4' (assuming a pointer size of 4 bytes).  So,
10733    'curtype' will be set to 7 when starting to encode 'char **'.
10734    During the whole of the encoding of 'char **', 'curtype' will be
10735    fixed at 7, so the routine encoding the second pointer can find out
10736    that it's actually encoding a pointer to a pointer by looking
10737    backwards at what has already been encoded for the current type,
10738    and seeing there is a "^" (meaning a pointer) in there.
10739 */
10740
10741
10742 /* Encode type qualifiers encodes one of the "PQ" Objective-C
10743    keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
10744    'const', instead, is encoded directly as part of the type.
10745  */
10746
10747 static void
10748 encode_type_qualifiers (tree declspecs)
10749 {
10750   tree spec;
10751
10752   for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
10753     {
10754       /* FIXME: Shouldn't we use token->keyword here ? */
10755       if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
10756         obstack_1grow (&util_obstack, 'n');
10757       else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
10758         obstack_1grow (&util_obstack, 'N');
10759       else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
10760         obstack_1grow (&util_obstack, 'o');
10761       else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
10762         obstack_1grow (&util_obstack, 'O');
10763       else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
10764         obstack_1grow (&util_obstack, 'R');
10765       else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
10766         obstack_1grow (&util_obstack, 'V');
10767       else
10768         gcc_unreachable ();
10769     }
10770 }
10771
10772 /* Determine if a pointee is marked read-only.  Only used by the NeXT
10773    runtime to be compatible with gcc-3.3.  */
10774
10775 static bool
10776 pointee_is_readonly (tree pointee)
10777 {
10778   while (POINTER_TYPE_P (pointee))
10779     pointee = TREE_TYPE (pointee);
10780
10781   return TYPE_READONLY (pointee);
10782 }
10783
10784 /* Encode a pointer type.  */
10785
10786 static void
10787 encode_pointer (tree type, int curtype, int format)
10788 {
10789   tree pointer_to = TREE_TYPE (type);
10790
10791   if (flag_next_runtime)
10792     {
10793       /* This code is used to be compatible with gcc-3.3.  */
10794       /* For historical/compatibility reasons, the read-only qualifier
10795          of the pointee gets emitted _before_ the '^'.  The read-only
10796          qualifier of the pointer itself gets ignored, _unless_ we are
10797          looking at a typedef!  Also, do not emit the 'r' for anything
10798          but the outermost type!  */
10799       if (!generating_instance_variables
10800           && (obstack_object_size (&util_obstack) - curtype <= 1)
10801           && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
10802               ? TYPE_READONLY (type)
10803               : pointee_is_readonly (pointer_to)))
10804         obstack_1grow (&util_obstack, 'r');
10805     }
10806
10807   if (TREE_CODE (pointer_to) == RECORD_TYPE)
10808     {
10809       if (OBJC_TYPE_NAME (pointer_to)
10810           && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
10811         {
10812           const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
10813
10814           if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
10815             {
10816               obstack_1grow (&util_obstack, '@');
10817               return;
10818             }
10819           else if (TYPE_HAS_OBJC_INFO (pointer_to)
10820                    && TYPE_OBJC_INTERFACE (pointer_to))
10821             {
10822               if (generating_instance_variables)
10823                 {
10824                   obstack_1grow (&util_obstack, '@');
10825                   obstack_1grow (&util_obstack, '"');
10826                   obstack_grow (&util_obstack, name, strlen (name));
10827                   obstack_1grow (&util_obstack, '"');
10828                   return;
10829                 }
10830               else
10831                 {
10832                   obstack_1grow (&util_obstack, '@');
10833                   return;
10834                 }
10835             }
10836           else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
10837             {
10838               obstack_1grow (&util_obstack, '#');
10839               return;
10840             }
10841           else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
10842             {
10843               obstack_1grow (&util_obstack, ':');
10844               return;
10845             }
10846         }
10847     }
10848   else if (TREE_CODE (pointer_to) == INTEGER_TYPE
10849            && TYPE_MODE (pointer_to) == QImode)
10850     {
10851       tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
10852                   ? OBJC_TYPE_NAME (pointer_to)
10853                   : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
10854
10855       /* (BOOL *) are an exception and are encoded as ^c, while all
10856          other pointers to char are encoded as *.   */
10857       if (strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
10858         {
10859           if (!flag_next_runtime)
10860             {
10861               /* The NeXT runtime adds the 'r' before getting here.  */
10862
10863               /* It appears that "r*" means "const char *" rather than
10864                  "char *const".  "char *const" is encoded as "*",
10865                  which is identical to "char *", so the "const" is
10866                  unfortunately lost.  */                 
10867               if (TYPE_READONLY (pointer_to))
10868                 obstack_1grow (&util_obstack, 'r');
10869             }
10870
10871           obstack_1grow (&util_obstack, '*');
10872           return;
10873         }
10874     }
10875
10876   /* We have a normal pointer type that does not get special treatment.  */
10877   obstack_1grow (&util_obstack, '^');
10878   encode_type (pointer_to, curtype, format);
10879 }
10880
10881 static void
10882 encode_array (tree type, int curtype, int format)
10883 {
10884   tree an_int_cst = TYPE_SIZE (type);
10885   tree array_of = TREE_TYPE (type);
10886   char buffer[40];
10887   
10888   if (an_int_cst == NULL)
10889     {
10890       /* We are trying to encode an incomplete array.  An incomplete
10891          array is forbidden as part of an instance variable.  */
10892       if (generating_instance_variables)
10893         {
10894           /* TODO: Detect this error earlier.  */
10895           error ("instance variable has unknown size");
10896           return;
10897         }
10898
10899       /* So the only case in which an incomplete array could occur is
10900          if we are encoding the arguments or return value of a method.
10901          In that case, an incomplete array argument or return value
10902          (eg, -(void)display: (char[])string) is treated like a
10903          pointer because that is how the compiler does the function
10904          call.  A special, more complicated case, is when the
10905          incomplete array is the last member of a struct (eg, if we
10906          are encoding "struct { unsigned long int a;double b[];}"),
10907          which is again part of a method argument/return value.  In
10908          that case, we really need to communicate to the runtime that
10909          there is an incomplete array (not a pointer!) there.  So, we
10910          detect that special case and encode it as a zero-length
10911          array.
10912
10913          Try to detect that we are part of a struct.  We do this by
10914          searching for '=' in the type encoding for the current type.
10915          NB: This hack assumes that you can't use '=' as part of a C
10916          identifier.
10917       */
10918       {
10919         char *enc = obstack_base (&util_obstack) + curtype;
10920         if (memchr (enc, '=', 
10921                     obstack_object_size (&util_obstack) - curtype) == NULL)
10922           {
10923             /* We are not inside a struct.  Encode the array as a
10924                pointer.  */
10925             encode_pointer (type, curtype, format);
10926             return;
10927           }
10928       }
10929
10930       /* Else, we are in a struct, and we encode it as a zero-length
10931          array.  */
10932       sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
10933     }
10934   else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
10935    sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
10936   else
10937     sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
10938              TREE_INT_CST_LOW (an_int_cst)
10939               / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
10940
10941   obstack_grow (&util_obstack, buffer, strlen (buffer));
10942   encode_type (array_of, curtype, format);
10943   obstack_1grow (&util_obstack, ']');
10944   return;
10945 }
10946
10947 /* Encode a vector.  The vector type is a GCC extension to C.  */
10948 static void
10949 encode_vector (tree type, int curtype, int format)
10950 {
10951   tree vector_of = TREE_TYPE (type);
10952   char buffer[40];
10953
10954   /* Vectors are like simple fixed-size arrays.  */
10955
10956   /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
10957      alignment of the vector, and <code> is the base type.  Eg, int
10958      __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
10959      assuming that the alignment is 32 bytes.  We include size and
10960      alignment in bytes so that the runtime does not have to have any
10961      knowledge of the actual types.
10962   */
10963   sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d",
10964            /* We want to compute the equivalent of sizeof (<vector>).
10965               Code inspired by c_sizeof_or_alignof_type.  */
10966            ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type)) 
10967              / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))),
10968            /* We want to compute the equivalent of __alignof__
10969               (<vector>).  Code inspired by
10970               c_sizeof_or_alignof_type.  */
10971            TYPE_ALIGN_UNIT (type));
10972   obstack_grow (&util_obstack, buffer, strlen (buffer));
10973   encode_type (vector_of, curtype, format);
10974   obstack_1grow (&util_obstack, ']');
10975   return;
10976 }
10977 \f
10978 static void
10979 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format)
10980 {
10981   tree field = TYPE_FIELDS (type);
10982
10983   for (; field; field = DECL_CHAIN (field))
10984     {
10985 #ifdef OBJCPLUS
10986       /* C++ static members, and things that are not field at all,
10987          should not appear in the encoding.  */
10988       if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
10989         continue;
10990 #endif
10991
10992       /* Recursively encode fields of embedded base classes.  */
10993       if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
10994           && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
10995         {
10996           encode_aggregate_fields (TREE_TYPE (field),
10997                                    pointed_to, curtype, format);
10998           continue;
10999         }
11000
11001       if (generating_instance_variables && !pointed_to)
11002         {
11003           tree fname = DECL_NAME (field);
11004
11005           obstack_1grow (&util_obstack, '"');
11006
11007           if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
11008             obstack_grow (&util_obstack,
11009                           IDENTIFIER_POINTER (fname),
11010                           strlen (IDENTIFIER_POINTER (fname)));
11011
11012           obstack_1grow (&util_obstack, '"');
11013         }
11014
11015       encode_field_decl (field, curtype, format);
11016     }
11017 }
11018
11019 static void
11020 encode_aggregate_within (tree type, int curtype, int format, int left,
11021                          int right)
11022 {
11023   tree name;
11024   /* NB: aggregates that are pointed to have slightly different encoding
11025      rules in that you never encode the names of instance variables.  */
11026   int ob_size = obstack_object_size (&util_obstack);
11027   bool inline_contents = false;
11028   bool pointed_to = false;
11029
11030   if (flag_next_runtime)
11031     {
11032       if (ob_size > 0  &&  *(obstack_next_free (&util_obstack) - 1) == '^')
11033         pointed_to = true;
11034
11035       if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
11036           && (!pointed_to || ob_size - curtype == 1
11037               || (ob_size - curtype == 2
11038                   && *(obstack_next_free (&util_obstack) - 2) == 'r')))
11039         inline_contents = true;
11040     }
11041   else
11042     {
11043       /* c0 and c1 are the last two characters in the encoding of the
11044          current type; if the last two characters were '^' or '^r',
11045          then we are encoding an aggregate that is "pointed to".  The
11046          comment above applies: in that case we should avoid encoding
11047          the names of instance variables.
11048       */
11049       char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
11050       char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
11051       
11052       if (c0 == '^' || (c1 == '^' && c0 == 'r'))
11053         pointed_to = true;
11054       
11055       if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
11056         {
11057           if (!pointed_to)
11058             inline_contents = true;
11059           else
11060             {
11061               /* Note that the check (ob_size - curtype < 2) prevents
11062                  infinite recursion when encoding a structure which is
11063                  a linked list (eg, struct node { struct node *next;
11064                  }).  Each time we follow a pointer, we add one
11065                  character to ob_size, and curtype is fixed, so after
11066                  at most two pointers we stop inlining contents and
11067                  break the loop.
11068
11069                  The other case where we don't inline is "^r", which
11070                  is a pointer to a constant struct.
11071               */
11072               if ((ob_size - curtype <= 2) && !(c0 == 'r'))
11073                 inline_contents = true;
11074             }
11075         }
11076     }
11077
11078   /* Traverse struct aliases; it is important to get the
11079      original struct and its tag name (if any).  */
11080   type = TYPE_MAIN_VARIANT (type);
11081   name = OBJC_TYPE_NAME (type);
11082   /* Open parenth/bracket.  */
11083   obstack_1grow (&util_obstack, left);
11084
11085   /* Encode the struct/union tag name, or '?' if a tag was
11086      not provided.  Typedef aliases do not qualify.  */
11087 #ifdef OBJCPLUS
11088   /* For compatibility with the NeXT runtime, ObjC++ encodes template
11089      args as a composite struct tag name. */
11090   if (name && TREE_CODE (name) == IDENTIFIER_NODE
11091       /* Did this struct have a tag?  */
11092       && !TYPE_WAS_ANONYMOUS (type))
11093     obstack_grow (&util_obstack,
11094                   decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
11095                   strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
11096 #else
11097   if (name && TREE_CODE (name) == IDENTIFIER_NODE)
11098     obstack_grow (&util_obstack,
11099                   IDENTIFIER_POINTER (name),
11100                   strlen (IDENTIFIER_POINTER (name)));
11101 #endif
11102   else
11103     obstack_1grow (&util_obstack, '?');
11104
11105   /* Encode the types (and possibly names) of the inner fields,
11106      if required.  */
11107   if (inline_contents)
11108     {
11109       obstack_1grow (&util_obstack, '=');
11110       encode_aggregate_fields (type, pointed_to, curtype, format);
11111     }
11112   /* Close parenth/bracket.  */
11113   obstack_1grow (&util_obstack, right);
11114 }
11115
11116 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
11117    field type.  */
11118
11119 static void
11120 encode_next_bitfield (int width)
11121 {
11122   char buffer[40];
11123   sprintf (buffer, "b%d", width);
11124   obstack_grow (&util_obstack, buffer, strlen (buffer));
11125 }
11126 \f
11127
11128 /* Encodes 'type', ignoring type qualifiers (which you should encode
11129    beforehand if needed) with the exception of 'const', which is
11130    encoded by encode_type.  See above for the explanation of
11131    'curtype'.  'format' can be OBJC_ENCODE_INLINE_DEFS or
11132    OBJC_ENCODE_DONT_INLINE_DEFS.
11133 */
11134 static void
11135 encode_type (tree type, int curtype, int format)
11136 {
11137   enum tree_code code = TREE_CODE (type);
11138
11139   /* Ignore type qualifiers other than 'const' when encoding a
11140      type.  */
11141
11142   if (type == error_mark_node)
11143     return;
11144
11145   if (!flag_next_runtime)
11146     {
11147       if (TYPE_READONLY (type))
11148         obstack_1grow (&util_obstack, 'r');
11149     }
11150
11151   switch (code)
11152     {
11153     case ENUMERAL_TYPE:
11154       if (flag_next_runtime)
11155         {
11156           /* Kludge for backwards-compatibility with gcc-3.3: enums
11157              are always encoded as 'i' no matter what type they
11158              actually are (!).  */
11159           obstack_1grow (&util_obstack, 'i');
11160           break;
11161         }
11162       /* Else, they are encoded exactly like the integer type that is
11163          used by the compiler to store them.  */
11164     case INTEGER_TYPE:
11165       {
11166         char c;
11167         switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
11168           {
11169           case 8:  c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
11170           case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
11171           case 32:
11172             {
11173               tree int_type = type;
11174               if (flag_next_runtime)
11175                 {
11176                   /* Another legacy kludge for compatiblity with
11177                      gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
11178                      but not always.  For typedefs, we need to use 'i'
11179                      or 'I' instead if encoding a struct field, or a
11180                      pointer!  */
11181                   int_type =  ((!generating_instance_variables
11182                                 && (obstack_object_size (&util_obstack)
11183                                     == (unsigned) curtype))
11184                                ? TYPE_MAIN_VARIANT (type)
11185                                : type);
11186                 }
11187               if (int_type == long_unsigned_type_node
11188                   || int_type == long_integer_type_node)
11189                 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
11190               else
11191                 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
11192             }
11193             break;
11194           case 64:  c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
11195           case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
11196           default: gcc_unreachable ();
11197           }
11198         obstack_1grow (&util_obstack, c);
11199         break;
11200       }
11201     case REAL_TYPE:
11202       {
11203         char c;
11204         /* Floating point types.  */
11205         switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
11206           {
11207           case 32:  c = 'f'; break;
11208           case 64:  c = 'd'; break;
11209           case 96:
11210           case 128: c = 'D'; break;
11211           default: gcc_unreachable ();
11212           }
11213         obstack_1grow (&util_obstack, c);
11214         break;
11215       }
11216     case VOID_TYPE:
11217       obstack_1grow (&util_obstack, 'v');
11218       break;
11219
11220     case BOOLEAN_TYPE:
11221       obstack_1grow (&util_obstack, 'B');
11222       break;
11223
11224     case ARRAY_TYPE:
11225       encode_array (type, curtype, format);
11226       break;
11227
11228     case POINTER_TYPE:
11229 #ifdef OBJCPLUS
11230     case REFERENCE_TYPE:
11231 #endif
11232       encode_pointer (type, curtype, format);
11233       break;
11234
11235     case RECORD_TYPE:
11236       encode_aggregate_within (type, curtype, format, '{', '}');
11237       break;
11238
11239     case UNION_TYPE:
11240       encode_aggregate_within (type, curtype, format, '(', ')');
11241       break;
11242
11243     case FUNCTION_TYPE: /* '?' means an unknown type.  */
11244       obstack_1grow (&util_obstack, '?');
11245       break;
11246
11247     case COMPLEX_TYPE:
11248       /* A complex is encoded as 'j' followed by the inner type (eg,
11249          "_Complex int" is encoded as 'ji').  */
11250       obstack_1grow (&util_obstack, 'j');
11251       encode_type (TREE_TYPE (type), curtype, format);
11252       break;
11253
11254     case VECTOR_TYPE:
11255       encode_vector (type, curtype, format);
11256       break;
11257
11258     default:
11259       warning (0, "unknown type %s found during Objective-C encoding",
11260                gen_type_name (type));
11261       obstack_1grow (&util_obstack, '?');
11262       break;
11263     }
11264   
11265   if (flag_next_runtime)
11266     {
11267       /* Super-kludge.  Some ObjC qualifier and type combinations need
11268          to be rearranged for compatibility with gcc-3.3.  */
11269       if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
11270         {
11271           char *enc = obstack_base (&util_obstack) + curtype;
11272           
11273           /* Rewrite "in const" from "nr" to "rn".  */
11274           if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
11275             strncpy (enc - 1, "rn", 2);
11276         }
11277     }
11278 }
11279
11280 static void
11281 encode_gnu_bitfield (int position, tree type, int size)
11282 {
11283   enum tree_code code = TREE_CODE (type);
11284   char buffer[40];
11285   char charType = '?';
11286
11287   /* This code is only executed for the GNU runtime, so we can ignore
11288      the NeXT runtime kludge of always encoding enums as 'i' no matter
11289      what integers they actually are.  */
11290   if (code == INTEGER_TYPE  ||  code == ENUMERAL_TYPE)
11291     {
11292       if (integer_zerop (TYPE_MIN_VALUE (type)))
11293         /* Unsigned integer types.  */
11294         {
11295           switch (TYPE_MODE (type))
11296             {
11297             case QImode:
11298               charType = 'C'; break;
11299             case HImode:
11300               charType = 'S'; break;
11301             case SImode:
11302               {
11303                 if (type == long_unsigned_type_node)
11304                   charType = 'L';
11305                 else
11306                   charType = 'I';
11307                 break;
11308               }
11309             case DImode:
11310               charType = 'Q'; break;
11311             default:
11312               gcc_unreachable ();
11313             }
11314         }
11315       else
11316         /* Signed integer types.  */
11317         {
11318           switch (TYPE_MODE (type))
11319             {
11320             case QImode:
11321               charType = 'c'; break;
11322             case HImode:
11323               charType = 's'; break;
11324             case SImode:
11325               {
11326                 if (type == long_integer_type_node)
11327                   charType = 'l';
11328                 else
11329                   charType = 'i';
11330                 break;
11331               }
11332             case DImode:
11333               charType = 'q'; break;
11334             default:
11335               gcc_unreachable ();
11336             }
11337         }
11338     }
11339   else
11340     {
11341       /* Do not do any encoding, produce an error and keep going.  */
11342       error ("trying to encode non-integer type as a bitfield");
11343       return;
11344     }
11345
11346   sprintf (buffer, "b%d%c%d", position, charType, size);
11347   obstack_grow (&util_obstack, buffer, strlen (buffer));
11348 }
11349
11350 static void
11351 encode_field_decl (tree field_decl, int curtype, int format)
11352 {
11353 #ifdef OBJCPLUS
11354   /* C++ static members, and things that are not fields at all,
11355      should not appear in the encoding.  */
11356   if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
11357     return;
11358 #endif
11359
11360   /* Generate the bitfield typing information, if needed.  Note the difference
11361      between GNU and NeXT runtimes.  */
11362   if (DECL_BIT_FIELD_TYPE (field_decl))
11363     {
11364       int size = tree_low_cst (DECL_SIZE (field_decl), 1);
11365
11366       if (flag_next_runtime)
11367         encode_next_bitfield (size);
11368       else
11369         encode_gnu_bitfield (int_bit_position (field_decl),
11370                              DECL_BIT_FIELD_TYPE (field_decl), size);
11371     }
11372   else
11373     encode_type (TREE_TYPE (field_decl), curtype, format);
11374 }
11375
11376 /* Decay array and function parameters into pointers.  */
11377
11378 static tree
11379 objc_decay_parm_type (tree type)
11380 {
11381   if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == FUNCTION_TYPE)
11382     type = build_pointer_type (TREE_CODE (type) == ARRAY_TYPE
11383                                ? TREE_TYPE (type)
11384                                : type);
11385
11386   return type;
11387 }
11388
11389 static GTY(()) tree objc_parmlist = NULL_TREE;
11390
11391 /* Append PARM to a list of formal parameters of a method, making a necessary
11392    array-to-pointer adjustment along the way.  */
11393
11394 static void
11395 objc_push_parm (tree parm)
11396 {
11397   tree type;
11398
11399   if (TREE_TYPE (parm) == error_mark_node)
11400     {
11401       objc_parmlist = chainon (objc_parmlist, parm);
11402       return;
11403     }
11404
11405   /* Decay arrays and functions into pointers.  */
11406   type = objc_decay_parm_type (TREE_TYPE (parm));
11407
11408   /* If the parameter type has been decayed, a new PARM_DECL needs to be
11409      built as well.  */
11410   if (type != TREE_TYPE (parm))
11411     parm = build_decl (input_location, PARM_DECL, DECL_NAME (parm), type);
11412
11413   DECL_ARG_TYPE (parm)
11414     = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
11415
11416   /* Record constancy and volatility.  */
11417   c_apply_type_quals_to_decl
11418   ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
11419    | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
11420    | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
11421
11422   objc_parmlist = chainon (objc_parmlist, parm);
11423 }
11424
11425 /* Retrieve the formal parameter list constructed via preceding calls to
11426    objc_push_parm().  */
11427
11428 #ifdef OBJCPLUS
11429 static tree
11430 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
11431 #else
11432 static struct c_arg_info *
11433 objc_get_parm_info (int have_ellipsis)
11434 #endif
11435 {
11436 #ifdef OBJCPLUS
11437   tree parm_info = objc_parmlist;
11438   objc_parmlist = NULL_TREE;
11439
11440   return parm_info;
11441 #else
11442   tree parm_info = objc_parmlist;
11443   struct c_arg_info *arg_info;
11444   /* The C front-end requires an elaborate song and dance at
11445      this point.  */
11446   push_scope ();
11447   declare_parm_level ();
11448   while (parm_info)
11449     {
11450       tree next = DECL_CHAIN (parm_info);
11451
11452       DECL_CHAIN (parm_info) = NULL_TREE;
11453       parm_info = pushdecl (parm_info);
11454       finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
11455       parm_info = next;
11456     }
11457   arg_info = get_parm_info (have_ellipsis);
11458   pop_scope ();
11459   objc_parmlist = NULL_TREE;
11460   return arg_info;
11461 #endif
11462 }
11463
11464 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
11465    method definitions.  In the case of instance methods, we can be more
11466    specific as to the type of 'self'.  */
11467
11468 static void
11469 synth_self_and_ucmd_args (void)
11470 {
11471   tree self_type;
11472
11473   if (objc_method_context
11474       && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
11475     self_type = objc_instance_type;
11476   else
11477     /* Really a `struct objc_class *'. However, we allow people to
11478        assign to self, which changes its type midstream.  */
11479     self_type = objc_object_type;
11480
11481   /* id self; */
11482   objc_push_parm (build_decl (input_location,
11483                               PARM_DECL, self_id, self_type));
11484
11485   /* SEL _cmd; */
11486   objc_push_parm (build_decl (input_location,
11487                               PARM_DECL, ucmd_id, objc_selector_type));
11488 }
11489
11490 /* Transform an Objective-C method definition into a static C function
11491    definition, synthesizing the first two arguments, "self" and "_cmd",
11492    in the process.  */
11493
11494 static void
11495 start_method_def (tree method)
11496 {
11497   tree parmlist;
11498 #ifdef OBJCPLUS
11499   tree parm_info;
11500 #else
11501   struct c_arg_info *parm_info;
11502 #endif
11503   int have_ellipsis = 0;
11504
11505   /* If we are defining a "dealloc" method in a non-root class, we
11506      will need to check if a [super dealloc] is missing, and warn if
11507      it is.  */
11508   if(CLASS_SUPER_NAME (objc_implementation_context)
11509      && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
11510     should_call_super_dealloc = 1;
11511   else
11512     should_call_super_dealloc = 0;
11513
11514   /* Required to implement _msgSuper.  */
11515   objc_method_context = method;
11516   UOBJC_SUPER_decl = NULL_TREE;
11517
11518   /* Generate prototype declarations for arguments..."new-style".  */
11519   synth_self_and_ucmd_args ();
11520
11521   /* Generate argument declarations if a keyword_decl.  */
11522   parmlist = METHOD_SEL_ARGS (method);
11523   while (parmlist)
11524     {
11525       /* parmlist is a KEYWORD_DECL.  */
11526       tree type = TREE_VALUE (TREE_TYPE (parmlist));
11527       tree parm;
11528
11529       parm = build_decl (input_location,
11530                          PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
11531       decl_attributes (&parm, DECL_ATTRIBUTES (parmlist), 0);
11532       objc_push_parm (parm);
11533       parmlist = DECL_CHAIN (parmlist);
11534     }
11535
11536   if (METHOD_ADD_ARGS (method))
11537     {
11538       tree akey;
11539
11540       for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
11541            akey; akey = TREE_CHAIN (akey))
11542         {
11543           objc_push_parm (TREE_VALUE (akey));
11544         }
11545
11546       if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
11547         have_ellipsis = 1;
11548     }
11549
11550   parm_info = objc_get_parm_info (have_ellipsis);
11551
11552   really_start_method (objc_method_context, parm_info);
11553 }
11554
11555 /* Return 1 if TYPE1 is equivalent to TYPE2
11556    for purposes of method overloading.  */
11557
11558 static int
11559 objc_types_are_equivalent (tree type1, tree type2)
11560 {
11561   if (type1 == type2)
11562     return 1;
11563
11564   /* Strip away indirections.  */
11565   while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
11566          && (TREE_CODE (type1) == TREE_CODE (type2)))
11567     type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
11568   if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
11569     return 0;
11570
11571   type1 = (TYPE_HAS_OBJC_INFO (type1)
11572            ? TYPE_OBJC_PROTOCOL_LIST (type1)
11573            : NULL_TREE);
11574   type2 = (TYPE_HAS_OBJC_INFO (type2)
11575            ? TYPE_OBJC_PROTOCOL_LIST (type2)
11576            : NULL_TREE);
11577
11578   if (list_length (type1) == list_length (type2))
11579     {
11580       for (; type2; type2 = TREE_CHAIN (type2))
11581         if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
11582           return 0;
11583       return 1;
11584     }
11585   return 0;
11586 }
11587
11588 /* Return 1 if TYPE1 has the same size and alignment as TYPE2.  */
11589
11590 static int
11591 objc_types_share_size_and_alignment (tree type1, tree type2)
11592 {
11593   return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
11594           && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
11595 }
11596
11597 /* Return 1 if PROTO1 is equivalent to PROTO2
11598    for purposes of method overloading.  Ordinarily, the type signatures
11599    should match up exactly, unless STRICT is zero, in which case we
11600    shall allow differences in which the size and alignment of a type
11601    is the same.  */
11602
11603 static int
11604 comp_proto_with_proto (tree proto1, tree proto2, int strict)
11605 {
11606   /* The following test is needed in case there are hashing
11607      collisions.  */
11608   if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
11609     return 0;
11610
11611   return match_proto_with_proto (proto1, proto2, strict);
11612 }
11613
11614 static int
11615 match_proto_with_proto (tree proto1, tree proto2, int strict)
11616 {
11617   tree type1, type2;
11618
11619   /* Compare return types.  */
11620   type1 = TREE_VALUE (TREE_TYPE (proto1));
11621   type2 = TREE_VALUE (TREE_TYPE (proto2));
11622
11623   if (!objc_types_are_equivalent (type1, type2)
11624       && (strict || !objc_types_share_size_and_alignment (type1, type2)))
11625     return 0;
11626
11627   /* Compare argument types.  */
11628   for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
11629        type2 = get_arg_type_list (proto2, METHOD_REF, 0);
11630        type1 && type2;
11631        type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
11632     {
11633       if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
11634           && (strict
11635               || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
11636                                                        TREE_VALUE (type2))))
11637         return 0;
11638     }
11639
11640   return (!type1 && !type2);
11641 }
11642
11643 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
11644    this occurs.  ObjC method dispatches are _not_ like C++ virtual
11645    member function dispatches, and we account for the difference here.  */
11646 tree
11647 #ifdef OBJCPLUS
11648 objc_fold_obj_type_ref (tree ref, tree known_type)
11649 #else
11650 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
11651                         tree known_type ATTRIBUTE_UNUSED)
11652 #endif
11653 {
11654 #ifdef OBJCPLUS
11655   tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
11656
11657   /* If the receiver does not have virtual member functions, there
11658      is nothing we can (or need to) do here.  */
11659   if (!v)
11660     return NULL_TREE;
11661
11662   /* Let C++ handle C++ virtual functions.  */
11663   return cp_fold_obj_type_ref (ref, known_type);
11664 #else
11665   /* For plain ObjC, we currently do not need to do anything.  */
11666   return NULL_TREE;
11667 #endif
11668 }
11669
11670 static void
11671 objc_start_function (tree name, tree type, tree attrs,
11672 #ifdef OBJCPLUS
11673                      tree params
11674 #else
11675                      struct c_arg_info *params
11676 #endif
11677                      )
11678 {
11679   tree fndecl = build_decl (input_location,
11680                             FUNCTION_DECL, name, type);
11681
11682 #ifdef OBJCPLUS
11683   DECL_ARGUMENTS (fndecl) = params;
11684   DECL_INITIAL (fndecl) = error_mark_node;
11685   DECL_EXTERNAL (fndecl) = 0;
11686   TREE_STATIC (fndecl) = 1;
11687   retrofit_lang_decl (fndecl);
11688   cplus_decl_attributes (&fndecl, attrs, 0);
11689   start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
11690 #else
11691   current_function_returns_value = 0;  /* Assume, until we see it does.  */
11692   current_function_returns_null = 0;
11693   decl_attributes (&fndecl, attrs, 0);
11694   announce_function (fndecl);
11695   DECL_INITIAL (fndecl) = error_mark_node;
11696   DECL_EXTERNAL (fndecl) = 0;
11697   TREE_STATIC (fndecl) = 1;
11698   current_function_decl = pushdecl (fndecl);
11699   push_scope ();
11700   declare_parm_level ();
11701   DECL_RESULT (current_function_decl)
11702     = build_decl (input_location,
11703                   RESULT_DECL, NULL_TREE,
11704                   TREE_TYPE (TREE_TYPE (current_function_decl)));
11705   DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
11706   DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
11707   start_fname_decls ();
11708   store_parm_decls_from (params);
11709 #endif
11710
11711   TREE_USED (current_function_decl) = 1;
11712 }
11713
11714 /* - Generate an identifier for the function. the format is "_n_cls",
11715      where 1 <= n <= nMethods, and cls is the name the implementation we
11716      are processing.
11717    - Install the return type from the method declaration.
11718    - If we have a prototype, check for type consistency.  */
11719
11720 static void
11721 really_start_method (tree method,
11722 #ifdef OBJCPLUS
11723                      tree parmlist
11724 #else
11725                      struct c_arg_info *parmlist
11726 #endif
11727                      )
11728 {
11729   tree ret_type, meth_type;
11730   tree method_id;
11731   const char *sel_name, *class_name, *cat_name;
11732   char *buf;
11733
11734   /* Synth the storage class & assemble the return type.  */
11735   ret_type = TREE_VALUE (TREE_TYPE (method));
11736
11737   sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
11738   class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
11739   cat_name = ((TREE_CODE (objc_implementation_context)
11740                == CLASS_IMPLEMENTATION_TYPE)
11741               ? NULL
11742               : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
11743   method_slot++;
11744
11745   /* Make sure this is big enough for any plausible method label.  */
11746   buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
11747                          + (cat_name ? strlen (cat_name) : 0));
11748
11749   OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
11750                          class_name, cat_name, sel_name, method_slot);
11751
11752   method_id = get_identifier (buf);
11753
11754 #ifdef OBJCPLUS
11755   /* Objective-C methods cannot be overloaded, so we don't need
11756      the type encoding appended.  It looks bad anyway... */
11757   push_lang_context (lang_name_c);
11758 #endif
11759
11760   meth_type
11761     = build_function_type (ret_type,
11762                            get_arg_type_list (method, METHOD_DEF, 0));
11763   objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
11764
11765   /* Set self_decl from the first argument.  */
11766   self_decl = DECL_ARGUMENTS (current_function_decl);
11767
11768   /* Suppress unused warnings.  */
11769   TREE_USED (self_decl) = 1;
11770   DECL_READ_P (self_decl) = 1;
11771   TREE_USED (DECL_CHAIN (self_decl)) = 1;
11772   DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
11773 #ifdef OBJCPLUS
11774   pop_lang_context ();
11775 #endif
11776
11777   METHOD_DEFINITION (method) = current_function_decl;
11778
11779   /* Check consistency...start_function, pushdecl, duplicate_decls.  */
11780
11781   if (implementation_template != objc_implementation_context)
11782     {
11783       tree proto
11784         = lookup_method_static (implementation_template,
11785                                 METHOD_SEL_NAME (method),
11786                                 ((TREE_CODE (method) == CLASS_METHOD_DECL)
11787                                  | OBJC_LOOKUP_NO_SUPER));
11788
11789       if (proto)
11790         {
11791           if (!comp_proto_with_proto (method, proto, 1))
11792             {
11793               bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
11794
11795               warning_at (DECL_SOURCE_LOCATION (method), 0,
11796                           "conflicting types for %<%c%s%>",
11797                           (type ? '-' : '+'),
11798                           identifier_to_locale (gen_method_decl (method)));
11799               inform (DECL_SOURCE_LOCATION (proto),
11800                       "previous declaration of %<%c%s%>",
11801                       (type ? '-' : '+'),
11802                       identifier_to_locale (gen_method_decl (proto)));
11803             }
11804           else
11805             {
11806               /* If the method in the @interface was deprecated, mark
11807                  the implemented method as deprecated too.  It should
11808                  never be used for messaging (when the deprecation
11809                  warnings are produced), but just in case.  */
11810               if (TREE_DEPRECATED (proto))
11811                 TREE_DEPRECATED (method) = 1;
11812
11813               /* If the method in the @interface was marked as
11814                  'noreturn', mark the function implementing the method
11815                  as 'noreturn' too.  */
11816               TREE_THIS_VOLATILE (current_function_decl) = TREE_THIS_VOLATILE (proto);
11817             }
11818         }
11819       else
11820         {
11821           /* We have a method @implementation even though we did not
11822              see a corresponding @interface declaration (which is allowed
11823              by Objective-C rules).  Go ahead and place the method in
11824              the @interface anyway, so that message dispatch lookups
11825              will see it.  */
11826           tree interface = implementation_template;
11827
11828           if (TREE_CODE (objc_implementation_context)
11829               == CATEGORY_IMPLEMENTATION_TYPE)
11830             interface = lookup_category
11831                         (interface,
11832                          CLASS_SUPER_NAME (objc_implementation_context));
11833
11834           if (interface)
11835             objc_add_method (interface, copy_node (method),
11836                              TREE_CODE (method) == CLASS_METHOD_DECL, 
11837                              /* is_optional= */ false);
11838         }
11839     }
11840 }
11841
11842 static void *UOBJC_SUPER_scope = 0;
11843
11844 /* _n_Method (id self, SEL sel, ...)
11845      {
11846        struct objc_super _S;
11847        _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
11848      }  */
11849
11850 static tree
11851 get_super_receiver (void)
11852 {
11853   if (objc_method_context)
11854     {
11855       tree super_expr, super_expr_list;
11856
11857       if (!UOBJC_SUPER_decl)
11858       {
11859         UOBJC_SUPER_decl = build_decl (input_location,
11860                                        VAR_DECL, get_identifier (TAG_SUPER),
11861                                        objc_super_template);
11862         /* This prevents `unused variable' warnings when compiling with -Wall.  */
11863         TREE_USED (UOBJC_SUPER_decl) = 1;
11864         DECL_READ_P (UOBJC_SUPER_decl) = 1;
11865         lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
11866         finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
11867                      NULL_TREE);
11868         UOBJC_SUPER_scope = objc_get_current_scope ();
11869       }
11870
11871       /* Set receiver to self.  */
11872       super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
11873       super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
11874                                       NOP_EXPR, input_location, self_decl,
11875                                       NULL_TREE);
11876       super_expr_list = super_expr;
11877
11878       /* Set class to begin searching.  */
11879       super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
11880                                              get_identifier ("super_class"));
11881
11882       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
11883         {
11884           /* [_cls, __cls]Super are "pre-built" in
11885              synth_forward_declarations.  */
11886
11887           super_expr = build_modify_expr (input_location, super_expr,
11888                                           NULL_TREE, NOP_EXPR,
11889                                           input_location,
11890                                           ((TREE_CODE (objc_method_context)
11891                                             == INSTANCE_METHOD_DECL)
11892                                            ? ucls_super_ref
11893                                            : uucls_super_ref),
11894                                           NULL_TREE);
11895         }
11896
11897       else
11898         /* We have a category.  */
11899         {
11900           tree super_name = CLASS_SUPER_NAME (implementation_template);
11901           tree super_class;
11902
11903           /* Barf if super used in a category of Object.  */
11904           if (!super_name)
11905             {
11906               error ("no super class declared in interface for %qE",
11907                      CLASS_NAME (implementation_template));
11908               return error_mark_node;
11909             }
11910
11911           if (flag_next_runtime && !flag_zero_link)
11912             {
11913               super_class = objc_get_class_reference (super_name);
11914               if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
11915                 /* If we are in a class method, we must retrieve the
11916                    _metaclass_ for the current class, pointed at by
11917                    the class's "isa" pointer.  The following assumes that
11918                    "isa" is the first ivar in a class (which it must be).  */
11919                 super_class
11920                   = build_indirect_ref
11921                       (input_location,
11922                        build_c_cast (input_location,
11923                                      build_pointer_type (objc_class_type),
11924                                      super_class), RO_UNARY_STAR);
11925             }
11926           else
11927             {
11928               add_class_reference (super_name);
11929               super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
11930                              ? objc_get_class_decl : objc_get_meta_class_decl);
11931               assemble_external (super_class);
11932               super_class
11933                 = build_function_call
11934                   (input_location,
11935                    super_class,
11936                    build_tree_list
11937                    (NULL_TREE,
11938                     my_build_string_pointer
11939                     (IDENTIFIER_LENGTH (super_name) + 1,
11940                      IDENTIFIER_POINTER (super_name))));
11941             }
11942
11943           super_expr
11944             = build_modify_expr (input_location, super_expr, NULL_TREE,
11945                                  NOP_EXPR,
11946                                  input_location,
11947                                  build_c_cast (input_location, 
11948                                                TREE_TYPE (super_expr),
11949                                                super_class),
11950                                  NULL_TREE);
11951         }
11952
11953       super_expr_list = build_compound_expr (input_location, 
11954                                              super_expr_list, super_expr);
11955
11956       super_expr = build_unary_op (input_location, 
11957                                    ADDR_EXPR, UOBJC_SUPER_decl, 0);
11958       super_expr_list = build_compound_expr (input_location,
11959                                              super_expr_list, super_expr);
11960
11961       return super_expr_list;
11962     }
11963   else
11964     {
11965       error ("[super ...] must appear in a method context");
11966       return error_mark_node;
11967     }
11968 }
11969
11970 /* When exiting a scope, sever links to a 'super' declaration (if any)
11971    therein contained.  */
11972
11973 void
11974 objc_clear_super_receiver (void)
11975 {
11976   if (objc_method_context
11977       && UOBJC_SUPER_scope == objc_get_current_scope ()) {
11978     UOBJC_SUPER_decl = 0;
11979     UOBJC_SUPER_scope = 0;
11980   }
11981 }
11982
11983 void
11984 objc_finish_method_definition (tree fndecl)
11985 {
11986   /* We cannot validly inline ObjC methods, at least not without a language
11987      extension to declare that a method need not be dynamically
11988      dispatched, so suppress all thoughts of doing so.  */
11989   DECL_UNINLINABLE (fndecl) = 1;
11990
11991 #ifndef OBJCPLUS
11992   /* The C++ front-end will have called finish_function() for us.  */
11993   finish_function ();
11994 #endif
11995
11996   METHOD_ENCODING (objc_method_context)
11997     = encode_method_prototype (objc_method_context);
11998
11999   /* Required to implement _msgSuper. This must be done AFTER finish_function,
12000      since the optimizer may find "may be used before set" errors.  */
12001   objc_method_context = NULL_TREE;
12002
12003   if (should_call_super_dealloc)
12004     warning (0, "method possibly missing a [super dealloc] call");
12005 }
12006
12007 /* Given a tree DECL node, produce a printable description of it in the given
12008    buffer, overwriting the buffer.  */
12009
12010 static char *
12011 gen_declaration (tree decl)
12012 {
12013   errbuf[0] = '\0';
12014
12015   if (DECL_P (decl))
12016     {
12017       gen_type_name_0 (TREE_TYPE (decl));
12018
12019       if (DECL_NAME (decl))
12020         {
12021           if (!POINTER_TYPE_P (TREE_TYPE (decl)))
12022             strcat (errbuf, " ");
12023
12024           strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
12025         }
12026
12027       if (DECL_INITIAL (decl)
12028           && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
12029         sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
12030                  TREE_INT_CST_LOW (DECL_INITIAL (decl)));
12031     }
12032
12033   return errbuf;
12034 }
12035
12036 /* Given a tree TYPE node, produce a printable description of it in the given
12037    buffer, overwriting the buffer.  */
12038
12039 static char *
12040 gen_type_name_0 (tree type)
12041 {
12042   tree orig = type, proto;
12043
12044   if (TYPE_P (type) && TYPE_NAME (type))
12045     type = TYPE_NAME (type);
12046   else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
12047     {
12048       tree inner = TREE_TYPE (type);
12049
12050       while (TREE_CODE (inner) == ARRAY_TYPE)
12051         inner = TREE_TYPE (inner);
12052
12053       gen_type_name_0 (inner);
12054
12055       if (!POINTER_TYPE_P (inner))
12056         strcat (errbuf, " ");
12057
12058       if (POINTER_TYPE_P (type))
12059         strcat (errbuf, "*");
12060       else
12061         while (type != inner)
12062           {
12063             strcat (errbuf, "[");
12064
12065             if (TYPE_DOMAIN (type))
12066               {
12067                 char sz[20];
12068
12069                 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
12070                          (TREE_INT_CST_LOW
12071                           (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
12072                 strcat (errbuf, sz);
12073               }
12074
12075             strcat (errbuf, "]");
12076             type = TREE_TYPE (type);
12077           }
12078
12079       goto exit_function;
12080     }
12081
12082   if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
12083     type = DECL_NAME (type);
12084
12085   strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
12086                   ? IDENTIFIER_POINTER (type)
12087                   : "");
12088
12089   /* For 'id' and 'Class', adopted protocols are stored in the pointee.  */
12090   if (objc_is_id (orig))
12091     orig = TREE_TYPE (orig);
12092
12093   proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
12094
12095   if (proto)
12096     {
12097       strcat (errbuf, " <");
12098
12099       while (proto) {
12100         strcat (errbuf,
12101                 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
12102         proto = TREE_CHAIN (proto);
12103         strcat (errbuf, proto ? ", " : ">");
12104       }
12105     }
12106
12107  exit_function:
12108   return errbuf;
12109 }
12110
12111 static char *
12112 gen_type_name (tree type)
12113 {
12114   errbuf[0] = '\0';
12115
12116   return gen_type_name_0 (type);
12117 }
12118
12119 /* Given a method tree, put a printable description into the given
12120    buffer (overwriting) and return a pointer to the buffer.  */
12121
12122 static char *
12123 gen_method_decl (tree method)
12124 {
12125   tree chain;
12126
12127   strcpy (errbuf, "(");  /* NB: Do _not_ call strcat() here.  */
12128   gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
12129   strcat (errbuf, ")");
12130   chain = METHOD_SEL_ARGS (method);
12131
12132   if (chain)
12133     {
12134       /* We have a chain of keyword_decls.  */
12135       do
12136         {
12137           if (KEYWORD_KEY_NAME (chain))
12138             strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
12139
12140           strcat (errbuf, ":(");
12141           gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
12142           strcat (errbuf, ")");
12143
12144           strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
12145           if ((chain = DECL_CHAIN (chain)))
12146             strcat (errbuf, " ");
12147         }
12148       while (chain);
12149
12150       if (METHOD_ADD_ARGS (method))
12151         {
12152           chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
12153
12154           /* Know we have a chain of parm_decls.  */
12155           while (chain)
12156             {
12157               strcat (errbuf, ", ");
12158               gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
12159               chain = TREE_CHAIN (chain);
12160             }
12161
12162           if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
12163             strcat (errbuf, ", ...");
12164         }
12165     }
12166
12167   else
12168     /* We have a unary selector.  */
12169     strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
12170
12171   return errbuf;
12172 }
12173 \f
12174 /* Debug info.  */
12175
12176
12177 /* Dump an @interface declaration of the supplied class CHAIN to the
12178    supplied file FP.  Used to implement the -gen-decls option (which
12179    prints out an @interface declaration of all classes compiled in
12180    this run); potentially useful for debugging the compiler too.  */
12181 static void
12182 dump_interface (FILE *fp, tree chain)
12183 {
12184   /* FIXME: A heap overflow here whenever a method (or ivar)
12185      declaration is so long that it doesn't fit in the buffer.  The
12186      code and all the related functions should be rewritten to avoid
12187      using fixed size buffers.  */
12188   const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
12189   tree ivar_decls = CLASS_RAW_IVARS (chain);
12190   tree nst_methods = CLASS_NST_METHODS (chain);
12191   tree cls_methods = CLASS_CLS_METHODS (chain);
12192
12193   fprintf (fp, "\n@interface %s", my_name);
12194
12195   /* CLASS_SUPER_NAME is used to store the superclass name for
12196      classes, and the category name for categories.  */
12197   if (CLASS_SUPER_NAME (chain))
12198     {
12199       const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
12200
12201       switch (TREE_CODE (chain))
12202         {
12203         case CATEGORY_IMPLEMENTATION_TYPE:
12204         case CATEGORY_INTERFACE_TYPE:
12205           fprintf (fp, " (%s)\n", name);
12206           break;
12207         default:
12208           fprintf (fp, " : %s\n", name);
12209           break;
12210         }
12211     }
12212   else
12213     fprintf (fp, "\n");
12214
12215   /* FIXME - the following doesn't seem to work at the moment.  */
12216   if (ivar_decls)
12217     {
12218       fprintf (fp, "{\n");
12219       do
12220         {
12221           fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
12222           ivar_decls = TREE_CHAIN (ivar_decls);
12223         }
12224       while (ivar_decls);
12225       fprintf (fp, "}\n");
12226     }
12227
12228   while (nst_methods)
12229     {
12230       fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
12231       nst_methods = TREE_CHAIN (nst_methods);
12232     }
12233
12234   while (cls_methods)
12235     {
12236       fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
12237       cls_methods = TREE_CHAIN (cls_methods);
12238     }
12239
12240   fprintf (fp, "@end\n");
12241 }
12242
12243 #if 0
12244 /* Produce the pretty printing for an Objective-C method.  This is
12245    currently unused, but could be handy while reorganizing the pretty
12246    printing to be more robust.  */
12247 static const char *
12248 objc_pretty_print_method (bool is_class_method,
12249                           const char *class_name,
12250                           const char *category_name,
12251                           const char *selector)
12252 {
12253   if (category_name)
12254     {
12255       char *result = XNEWVEC (char, strlen (class_name) + strlen (category_name) 
12256                               + strlen (selector) + 7);
12257
12258       if (is_class_method)
12259         sprintf (result, "+[%s(%s) %s]", class_name, category_name, selector);
12260       else
12261         sprintf (result, "-[%s(%s) %s]", class_name, category_name, selector);
12262
12263       return result;
12264     }
12265   else
12266     {
12267       char *result = XNEWVEC (char, strlen (class_name)
12268                               + strlen (selector) + 5);
12269
12270       if (is_class_method)
12271         sprintf (result, "+[%s %s]", class_name, selector);
12272       else
12273         sprintf (result, "-[%s %s]", class_name, selector);
12274
12275       return result;      
12276     }
12277 }
12278 #endif
12279
12280 /* Demangle function for Objective-C.  Attempt to demangle the
12281    function name associated with a method (eg, going from
12282    "_i_NSObject__class" to "-[NSObject class]"); usually for the
12283    purpose of pretty printing or error messages.  Return the demangled
12284    name, or NULL if the string is not an Objective-C mangled method
12285    name.
12286
12287    Because of how the mangling is done, any method that has a '_' in
12288    its original name is at risk of being demangled incorrectly.  In
12289    some cases there are multiple valid ways to demangle a method name
12290    and there is no way we can decide.
12291
12292    TODO: objc_demangle() can't always get it right; the right way to
12293    get this correct for all method names would be to store the
12294    Objective-C method name somewhere in the function decl.  Then,
12295    there is no demangling to do; we'd just pull the method name out of
12296    the decl.  As an additional bonus, when printing error messages we
12297    could check for such a method name, and if we find it, we know the
12298    function is actually an Objective-C method and we could print error
12299    messages saying "In method '+[NSObject class]" instead of "In
12300    function '+[NSObject class]" as we do now.  */
12301 static const char *
12302 objc_demangle (const char *mangled)
12303 {
12304   char *demangled, *cp;
12305
12306   if (mangled[0] == '_' &&
12307       (mangled[1] == 'i' || mangled[1] == 'c') &&
12308       mangled[2] == '_')
12309     {
12310       cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
12311       if (mangled[1] == 'i')
12312         *cp++ = '-';            /* for instance method */
12313       else
12314         *cp++ = '+';            /* for class method */
12315       *cp++ = '[';              /* opening left brace */
12316       strcpy(cp, mangled+3);    /* tack on the rest of the mangled name */
12317       while (*cp && *cp == '_')
12318         cp++;                   /* skip any initial underbars in class name */
12319       cp = strchr(cp, '_');     /* find first non-initial underbar */
12320       if (cp == NULL)
12321         {
12322           free(demangled);      /* not mangled name */
12323           return NULL;
12324         }
12325       if (cp[1] == '_')  /* easy case: no category name */
12326         {
12327           *cp++ = ' ';            /* replace two '_' with one ' ' */
12328           strcpy(cp, mangled + (cp - demangled) + 2);
12329         }
12330       else
12331         {
12332           *cp++ = '(';            /* less easy case: category name */
12333           cp = strchr(cp, '_');
12334           if (cp == 0)
12335             {
12336               free(demangled);    /* not mangled name */
12337               return NULL;
12338             }
12339           *cp++ = ')';
12340           *cp++ = ' ';            /* overwriting 1st char of method name... */
12341           strcpy(cp, mangled + (cp - demangled)); /* get it back */
12342         }
12343       /* Now we have the method name.  We need to generally replace
12344          '_' with ':' but trying to preserve '_' if it could only have
12345          been in the mangled string because it was already in the
12346          original name.  In cases where it's ambiguous, we assume that
12347          any '_' originated from a ':'.  */
12348
12349       /* Initial '_'s in method name can't have been generating by
12350          converting ':'s.  Skip them.  */
12351       while (*cp && *cp == '_')
12352         cp++;
12353
12354       /* If the method name does not end with '_', then it has no
12355          arguments and there was no replacement of ':'s with '_'s
12356          during mangling.  Check for that case, and skip any
12357          replacement if so.  This at least guarantees that methods
12358          with no arguments are always demangled correctly (unless the
12359          original name ends with '_').  */
12360       if (*(mangled + strlen (mangled) - 1) != '_')
12361         {
12362           /* Skip to the end.  */
12363           for (; *cp; cp++)
12364             ;
12365         }
12366       else
12367         {
12368           /* Replace remaining '_' with ':'.  This may get it wrong if
12369              there were '_'s in the original name.  In most cases it
12370              is impossible to disambiguate.  */
12371           for (; *cp; cp++)
12372             if (*cp == '_')
12373               *cp = ':';         
12374         }
12375       *cp++ = ']';              /* closing right brace */
12376       *cp++ = 0;                /* string terminator */
12377       return demangled;
12378     }
12379   else
12380     return NULL;             /* not an objc mangled name */
12381 }
12382
12383 /* Try to pretty-print a decl.  If the 'decl' is an Objective-C
12384    specific decl, return the printable name for it.  If not, return
12385    NULL.  */
12386 const char *
12387 objc_maybe_printable_name (tree decl, int v ATTRIBUTE_UNUSED)
12388 {
12389   switch (TREE_CODE (decl))
12390     {
12391     case FUNCTION_DECL:
12392       return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
12393       break;
12394
12395       /* The following happens when we are printing a deprecation
12396          warning for a method.  The warn_deprecation() will end up
12397          trying to print the decl for INSTANCE_METHOD_DECL or
12398          CLASS_METHOD_DECL.  It would be nice to be able to print
12399          "-[NSObject autorelease] is deprecated", but to do that, we'd
12400          need to store the class and method name in the method decl,
12401          which we currently don't do.  For now, just return the name
12402          of the method.  We don't return NULL, because that may
12403          trigger further attempts to pretty-print the decl in C/C++,
12404          but they wouldn't know how to pretty-print it.  */
12405     case INSTANCE_METHOD_DECL:
12406     case CLASS_METHOD_DECL:
12407       return IDENTIFIER_POINTER (DECL_NAME (decl));
12408       break;
12409       /* This happens when printing a deprecation warning for a
12410          property.  We may want to consider some sort of pretty
12411          printing (eg, include the class name where it was declared
12412          ?).  */
12413     case PROPERTY_DECL:
12414       return IDENTIFIER_POINTER (PROPERTY_NAME (decl));
12415       break;
12416     default:
12417       return NULL;
12418       break;
12419     }
12420 }
12421
12422 /* Return a printable name for 'decl'.  This first tries
12423    objc_maybe_printable_name(), and if that fails, it returns the name
12424    in the decl.  This is used as LANG_HOOKS_DECL_PRINTABLE_NAME for
12425    Objective-C; in Objective-C++, setting the hook is not enough
12426    because lots of C++ Front-End code calls cxx_printable_name,
12427    dump_decl and other C++ functions directly.  So instead we have
12428    modified dump_decl to call objc_maybe_printable_name directly.  */
12429 const char *
12430 objc_printable_name (tree decl, int v)
12431 {
12432   const char *demangled_name = objc_maybe_printable_name (decl, v);
12433
12434   if (demangled_name != NULL)
12435     return demangled_name;
12436   else
12437     return IDENTIFIER_POINTER (DECL_NAME (decl));
12438 }
12439
12440 static void
12441 init_objc (void)
12442 {
12443   gcc_obstack_init (&util_obstack);
12444   util_firstobj = (char *) obstack_finish (&util_obstack);
12445
12446   errbuf = XNEWVEC (char, 1024 * 10);
12447   hash_init ();
12448   synth_module_prologue ();
12449 }
12450 \f
12451 static void
12452 finish_objc (void)
12453 {
12454   struct imp_entry *impent;
12455   tree chain;
12456   /* The internally generated initializers appear to have missing braces.
12457      Don't warn about this.  */
12458   int save_warn_missing_braces = warn_missing_braces;
12459   warn_missing_braces = 0;
12460
12461   /* A missing @end may not be detected by the parser.  */
12462   if (objc_implementation_context)
12463     {
12464       warning (0, "%<@end%> missing in implementation context");
12465       finish_class (objc_implementation_context);
12466       objc_ivar_chain = NULL_TREE;
12467       objc_implementation_context = NULL_TREE;
12468     }
12469
12470   /* Process the static instances here because initialization of objc_symtab
12471      depends on them.  */
12472   if (objc_static_instances)
12473     generate_static_references ();
12474
12475   /* forward declare categories */
12476   if (cat_count)
12477     forward_declare_categories ();
12478
12479   for (impent = imp_list; impent; impent = impent->next)
12480     {
12481       objc_implementation_context = impent->imp_context;
12482       implementation_template = impent->imp_template;
12483
12484       /* FIXME: This needs reworking to be more obvious.  */
12485
12486       UOBJC_CLASS_decl = impent->class_decl;
12487       UOBJC_METACLASS_decl = impent->meta_decl;
12488
12489       /* Dump the @interface of each class as we compile it, if the
12490          -gen-decls option is in use.  TODO: Dump the classes in the
12491          order they were found, rather than in reverse order as we
12492          are doing now.  */
12493       if (flag_gen_declaration)
12494         {
12495           dump_interface (gen_declaration_file, objc_implementation_context);
12496         }
12497
12498       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
12499         {
12500           /* all of the following reference the string pool...  */
12501           generate_ivar_lists ();
12502           generate_dispatch_tables ();
12503           generate_shared_structures (impent);
12504         }
12505       else
12506         {
12507           generate_dispatch_tables ();
12508           generate_category (impent);
12509         }
12510
12511       impent->class_decl = UOBJC_CLASS_decl;
12512       impent->meta_decl = UOBJC_METACLASS_decl;
12513     }
12514
12515   /* If we are using an array of selectors, we must always
12516      finish up the array decl even if no selectors were used.  */
12517   if (flag_next_runtime)
12518     build_next_selector_translation_table ();
12519   else
12520     build_gnu_selector_translation_table ();
12521
12522   if (protocol_chain)
12523     generate_protocols ();
12524
12525   if (flag_next_runtime)
12526     generate_objc_image_info ();
12527
12528   if (imp_list || class_names_chain
12529       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
12530     generate_objc_symtab_decl ();
12531
12532   /* Arrange for ObjC data structures to be initialized at run time.  */
12533   if (objc_implementation_context || class_names_chain || objc_static_instances
12534       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
12535     {
12536       build_module_descriptor ();
12537
12538       if (!flag_next_runtime)
12539         build_module_initializer_routine ();
12540     }
12541
12542   /* Dump the class references.  This forces the appropriate classes
12543      to be linked into the executable image, preserving unix archive
12544      semantics.  This can be removed when we move to a more dynamically
12545      linked environment.  */
12546
12547   for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
12548     {
12549       handle_class_ref (chain);
12550       if (TREE_PURPOSE (chain))
12551         generate_classref_translation_entry (chain);
12552     }
12553
12554   for (impent = imp_list; impent; impent = impent->next)
12555     handle_impent (impent);
12556
12557   if (warn_selector)
12558     {
12559       int slot;
12560       hash hsh;
12561
12562       /* Run through the selector hash tables and print a warning for any
12563          selector which has multiple methods.  */
12564
12565       for (slot = 0; slot < SIZEHASHTABLE; slot++)
12566         {
12567           for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
12568             check_duplicates (hsh, 0, 1);
12569           for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
12570             check_duplicates (hsh, 0, 1);
12571         }
12572     }
12573
12574   warn_missing_braces = save_warn_missing_braces;
12575 }
12576 \f
12577 /* Subroutines of finish_objc.  */
12578
12579 static void
12580 generate_classref_translation_entry (tree chain)
12581 {
12582   tree expr, decl, type;
12583
12584   decl = TREE_PURPOSE (chain);
12585   type = TREE_TYPE (decl);
12586
12587   expr = add_objc_string (TREE_VALUE (chain), class_names);
12588   expr = convert (type, expr); /* cast! */
12589
12590   /* This is a class reference.  It is re-written by the runtime,
12591      but will be optimized away unless we force it.  */
12592   DECL_PRESERVE_P (decl) = 1;
12593   finish_var_decl (decl, expr);
12594   return;
12595 }
12596
12597 static void
12598 handle_class_ref (tree chain)
12599 {
12600   const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
12601   char *string = (char *) alloca (strlen (name) + 30);
12602   tree decl;
12603   tree exp;
12604
12605   sprintf (string, "%sobjc_class_name_%s",
12606            (flag_next_runtime ? "." : "__"), name);
12607
12608 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
12609   if (flag_next_runtime)
12610     {
12611       ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
12612       return;
12613     }
12614 #endif
12615
12616   /* Make a decl for this name, so we can use its address in a tree.  */
12617   decl = build_decl (input_location,
12618                      VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
12619   DECL_EXTERNAL (decl) = 1;
12620   TREE_PUBLIC (decl) = 1;
12621   pushdecl (decl);
12622   finish_var_decl (decl, 0);
12623
12624   /* Make a decl for the address.  */
12625   sprintf (string, "%sobjc_class_ref_%s",
12626            (flag_next_runtime ? "." : "__"), name);
12627   exp = build1 (ADDR_EXPR, string_type_node, decl);
12628   decl = build_decl (input_location,
12629                      VAR_DECL, get_identifier (string), string_type_node);
12630   TREE_STATIC (decl) = 1;
12631   TREE_USED (decl) = 1;
12632   DECL_READ_P (decl) = 1;
12633   DECL_ARTIFICIAL (decl) = 1;
12634   DECL_INITIAL (decl) = error_mark_node;
12635  
12636   /* We must force the reference.  */
12637   DECL_PRESERVE_P (decl) = 1;
12638
12639   pushdecl (decl);
12640   finish_var_decl (decl, exp);
12641 }
12642
12643 static void
12644 handle_impent (struct imp_entry *impent)
12645 {
12646   char *string;
12647
12648   objc_implementation_context = impent->imp_context;
12649   implementation_template = impent->imp_template;
12650
12651   switch (TREE_CODE (impent->imp_context))
12652     {
12653     case CLASS_IMPLEMENTATION_TYPE:
12654       {
12655         const char *const class_name =
12656           IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
12657         
12658         string = (char *) alloca (strlen (class_name) + 30);
12659         
12660         sprintf (string, "%sobjc_class_name_%s",
12661                  (flag_next_runtime ? "." : "__"), class_name);
12662         break;
12663       }
12664     case CATEGORY_IMPLEMENTATION_TYPE:
12665       {
12666         const char *const class_name =
12667           IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
12668         const char *const class_super_name =
12669           IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
12670         
12671         string = (char *) alloca (strlen (class_name)
12672                                   + strlen (class_super_name) + 30);
12673         
12674         /* Do the same for categories.  Even though no references to
12675            these symbols are generated automatically by the compiler,
12676            it gives you a handle to pull them into an archive by
12677            hand.  */
12678         sprintf (string, "*%sobjc_category_name_%s_%s",
12679                  (flag_next_runtime ? "." : "__"), class_name, class_super_name);
12680         break;
12681       }
12682     default:
12683       return;
12684     }
12685
12686 #ifdef ASM_DECLARE_CLASS_REFERENCE
12687   if (flag_next_runtime)
12688     {
12689       ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
12690       return;
12691     }
12692   else
12693 #endif
12694     {
12695       tree decl, init;
12696
12697       init = integer_zero_node;
12698       decl = build_decl (input_location,
12699                          VAR_DECL, get_identifier (string), TREE_TYPE (init));
12700       TREE_PUBLIC (decl) = 1;
12701       TREE_READONLY (decl) = 1;
12702       TREE_USED (decl) = 1;
12703       TREE_CONSTANT (decl) = 1;
12704       DECL_CONTEXT (decl) = NULL_TREE;
12705       DECL_ARTIFICIAL (decl) = 1;
12706       TREE_STATIC (decl) = 1;
12707       DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
12708       /* We must force the reference.  */
12709       DECL_PRESERVE_P (decl) = 1;
12710
12711       finish_var_decl(decl, init) ;
12712     }
12713 }
12714 \f
12715 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
12716    later requires that ObjC translation units participating in F&C be
12717    specially marked.  The following routine accomplishes this.  */
12718
12719 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
12720
12721 static void
12722 generate_objc_image_info (void)
12723 {
12724   tree decl;
12725   int flags
12726     = ((flag_replace_objc_classes && imp_count ? 1 : 0)
12727        | (flag_objc_gc ? 2 : 0));
12728   VEC(constructor_elt,gc) *v = NULL;
12729   tree array_type;
12730   
12731    if (!flags)
12732     return; /* No need for an image_info entry.  */
12733   
12734   array_type  = build_sized_array_type (integer_type_node, 2);
12735
12736   decl = start_var_decl (array_type, "_OBJC_IMAGE_INFO");
12737
12738   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
12739   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags));
12740   /* If we need this (determined above) it is because the runtime wants to
12741      refer to it in a manner hidden from the compiler.  So we must force the 
12742      output.  */
12743   DECL_PRESERVE_P (decl) = 1;
12744   finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
12745 }
12746
12747 /* Routine is called to issue diagnostic when reference to a private 
12748    ivar is made and no other variable with same name is found in 
12749    current scope.  */
12750 bool
12751 objc_diagnose_private_ivar (tree id)
12752 {
12753   tree ivar;
12754   if (!objc_method_context)
12755     return false;
12756   ivar = is_ivar (objc_ivar_chain, id);
12757   if (ivar && is_private (ivar))
12758     {
12759       error ("instance variable %qs is declared private", 
12760              IDENTIFIER_POINTER (id));
12761       return true;
12762     }
12763   return false;
12764 }
12765
12766 /* Look up ID as an instance variable.  OTHER contains the result of
12767    the C or C++ lookup, which we may want to use instead.  */
12768 /* To use properties inside an instance method, use self.property.  */
12769 tree
12770 objc_lookup_ivar (tree other, tree id)
12771 {
12772   tree ivar;
12773
12774   /* If we are not inside of an ObjC method, ivar lookup makes no sense.  */
12775   if (!objc_method_context)
12776     return other;
12777
12778   if (!strcmp (IDENTIFIER_POINTER (id), "super"))
12779     /* We have a message to super.  */
12780     return get_super_receiver ();
12781
12782   /* In a class method, look up an instance variable only as a last
12783      resort.  */
12784   if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
12785       && other && other != error_mark_node)
12786     return other;
12787
12788   /* Look up the ivar, but do not use it if it is not accessible.  */
12789   ivar = is_ivar (objc_ivar_chain, id);
12790   
12791   if (!ivar || is_private (ivar))
12792     return other;
12793
12794   /* In an instance method, a local variable (or parameter) may hide the
12795      instance variable.  */
12796   if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
12797       && other && other != error_mark_node
12798 #ifdef OBJCPLUS
12799       && CP_DECL_CONTEXT (other) != global_namespace)
12800 #else
12801       && !DECL_FILE_SCOPE_P (other))
12802 #endif
12803     {
12804       warning (0, "local declaration of %qE hides instance variable", id);
12805
12806       return other;
12807     }
12808
12809   /* At this point, we are either in an instance method with no obscuring
12810      local definitions, or in a class method with no alternate definitions
12811      at all.  */
12812   return build_ivar_reference (id);
12813 }
12814
12815 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression.  This
12816    needs to be done if we are calling a function through a cast.  */
12817
12818 tree
12819 objc_rewrite_function_call (tree function, tree first_param)
12820 {
12821   if (TREE_CODE (function) == NOP_EXPR
12822       && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
12823       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
12824          == FUNCTION_DECL)
12825     {
12826       function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
12827                          TREE_OPERAND (function, 0),
12828                          first_param, size_zero_node);
12829     }
12830
12831   return function;
12832 }
12833
12834 /* This is called to "gimplify" a PROPERTY_REF node.  It builds the
12835    corresponding 'getter' function call.  Note that we assume the
12836    PROPERTY_REF to be valid since we generated it while parsing.  */
12837 static void
12838 objc_gimplify_property_ref (tree *expr_p)
12839 {
12840   tree getter = PROPERTY_REF_GETTER_CALL (*expr_p);
12841   tree call_exp;
12842
12843   if (getter == NULL_TREE)
12844     {
12845       tree property_decl = PROPERTY_REF_PROPERTY_DECL (*expr_p);
12846       /* This can happen if DECL_ARTIFICIAL (*expr_p), but
12847          should be impossible for real properties, which always
12848          have a getter.  */
12849       error_at (EXPR_LOCATION (*expr_p), "no %qs getter found",
12850                 IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
12851       /* Try to recover from the error to prevent an ICE.  We take
12852          zero and cast it to the type of the property.  */
12853       *expr_p = convert (TREE_TYPE (property_decl),
12854                          integer_zero_node);
12855       return;
12856     }
12857
12858   call_exp = getter;
12859 #ifdef OBJCPLUS
12860   /* In C++, a getter which returns an aggregate value results in a
12861      target_expr which initializes a temporary to the call
12862      expression.  */
12863   if (TREE_CODE (getter) == TARGET_EXPR)
12864     {
12865       gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter)));
12866       gcc_assert (TREE_CODE (TREE_OPERAND (getter, 0)) == VAR_DECL);
12867       call_exp = TREE_OPERAND (getter, 1);
12868     }
12869 #endif
12870   gcc_assert (TREE_CODE (call_exp) == CALL_EXPR);
12871   
12872   *expr_p = call_exp;
12873 }
12874
12875 /* This is called when "gimplifying" the trees.  We need to gimplify
12876    the Objective-C/Objective-C++ specific trees, then hand over the
12877    process to C/C++.  */
12878 int
12879 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
12880 {
12881   enum tree_code code = TREE_CODE (*expr_p);
12882   switch (code)
12883     {
12884       /* Look for the special case of OBJC_TYPE_REF with the address
12885          of a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend
12886          or one of its cousins).  */
12887     case OBJ_TYPE_REF:
12888       if (TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
12889           && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
12890           == FUNCTION_DECL)
12891         {
12892           enum gimplify_status r0, r1;
12893
12894           /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
12895              value of the OBJ_TYPE_REF, so force them to be emitted
12896              during subexpression evaluation rather than after the
12897              OBJ_TYPE_REF. This permits objc_msgSend calls in
12898              Objective C to use direct rather than indirect calls when
12899              the object expression has a postincrement.  */
12900           r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
12901                               is_gimple_val, fb_rvalue);
12902           r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
12903                               is_gimple_val, fb_rvalue);
12904           
12905           return MIN (r0, r1);
12906         }
12907       break;
12908     case PROPERTY_REF:
12909       objc_gimplify_property_ref (expr_p);
12910       /* Do not return yet; let C/C++ gimplify the resulting expression.  */
12911       break;
12912     default:
12913       break;
12914     }
12915
12916 #ifdef OBJCPLUS
12917   return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
12918 #else
12919   return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
12920 #endif
12921 }
12922
12923 /* This routine returns true if TYPE is a valid objc object type,
12924    suitable for messaging; false otherwise.  If 'accept_class' is
12925    'true', then a Class object is considered valid for messaging and
12926    'true' is returned if 'type' refers to a Class.  If 'accept_class'
12927    is 'false', then a Class object is not considered valid for
12928    messaging and 'false' is returned in that case.  */
12929
12930 static bool
12931 objc_type_valid_for_messaging (tree type, bool accept_classes)
12932 {
12933   if (!POINTER_TYPE_P (type))
12934     return false;
12935
12936   /* Remove the pointer indirection; don't remove more than one
12937      otherwise we'd consider "NSObject **" a valid type for messaging,
12938      which it isn't.  */
12939   type = TREE_TYPE (type);
12940
12941   if (TREE_CODE (type) != RECORD_TYPE)
12942     return false;
12943
12944   if (objc_is_object_id (type))
12945     return true;
12946
12947   if (objc_is_class_id (type))
12948     return accept_classes;
12949
12950   if (TYPE_HAS_OBJC_INFO (type))
12951     return true;
12952
12953   return false;
12954 }
12955
12956 /* Begin code generation for fast enumeration (foreach) ... */
12957
12958 /* Defines
12959
12960   struct __objcFastEnumerationState
12961    {
12962      unsigned long state;
12963      id            *itemsPtr;
12964      unsigned long *mutationsPtr;
12965      unsigned long extra[5];
12966    };
12967
12968    Confusingly enough, NSFastEnumeration is then defined by libraries
12969    to be the same structure.  
12970 */
12971
12972 static void
12973 build_fast_enumeration_state_template (void)
12974 {
12975   tree decls, *chain = NULL;
12976
12977   /* { */
12978   objc_fast_enumeration_state_template = objc_start_struct (get_identifier 
12979                                                             (TAG_FAST_ENUMERATION_STATE));
12980
12981   /* unsigned long state; */
12982   decls = add_field_decl (long_unsigned_type_node, "state", &chain);
12983
12984   /* id            *itemsPtr; */
12985   add_field_decl (build_pointer_type (objc_object_type), 
12986                   "itemsPtr", &chain);
12987
12988   /* unsigned long *mutationsPtr; */
12989   add_field_decl (build_pointer_type (long_unsigned_type_node), 
12990                   "mutationsPtr", &chain);
12991
12992   /* unsigned long extra[5]; */
12993   add_field_decl (build_sized_array_type (long_unsigned_type_node, 5), 
12994                   "extra", &chain);
12995
12996   /* } */
12997   objc_finish_struct (objc_fast_enumeration_state_template, decls);
12998 }
12999
13000 /*
13001   'objc_finish_foreach_loop()' generates the code for an Objective-C
13002   foreach loop.  The 'location' argument is the location of the 'for'
13003   that starts the loop.  The 'object_expression' is the expression of
13004   the 'object' that iterates; the 'collection_expression' is the
13005   expression of the collection that we iterate over (we need to make
13006   sure we evaluate this only once); the 'for_body' is the set of
13007   statements to be executed in each iteration; 'break_label' and
13008   'continue_label' are the break and continue labels which we need to
13009   emit since the <statements> may be jumping to 'break_label' (if they
13010   contain 'break') or to 'continue_label' (if they contain
13011   'continue').
13012
13013   The syntax is
13014   
13015   for (<object expression> in <collection expression>)
13016     <statements>
13017
13018   which is compiled into the following blurb:
13019
13020   {
13021     id __objc_foreach_collection;
13022     __objc_fast_enumeration_state __objc_foreach_enum_state;
13023     unsigned long __objc_foreach_batchsize;
13024     id __objc_foreach_items[16];
13025     __objc_foreach_collection = <collection expression>;
13026     __objc_foreach_enum_state = { 0 };
13027     __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16];
13028     
13029     if (__objc_foreach_batchsize == 0)
13030       <object expression> = nil;
13031     else
13032       {
13033         unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
13034         next_batch:
13035           {
13036             unsigned long __objc_foreach_index;
13037             __objc_foreach_index = 0;
13038
13039             next_object:
13040             if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
13041             <object expression> = enumState.itemsPtr[__objc_foreach_index];
13042             <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
13043
13044             continue_label:
13045             __objc_foreach_index++;
13046             if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
13047             __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16];
13048          }
13049        if (__objc_foreach_batchsize != 0) goto next_batch;
13050        <object expression> = nil;
13051        break_label:
13052       }
13053   }
13054
13055   'statements' may contain a 'continue' or 'break' instruction, which
13056   the user expects to 'continue' or 'break' the entire foreach loop.
13057   We are provided the labels that 'break' and 'continue' jump to, so
13058   we place them where we want them to jump to when they pick them.
13059   
13060   Optimization TODO: we could cache the IMP of
13061   countByEnumeratingWithState:objects:count:.
13062 */
13063
13064 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line.  */
13065 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
13066
13067 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
13068 #include "tree-pretty-print.h"
13069 #endif
13070
13071 void
13072 objc_finish_foreach_loop (location_t location, tree object_expression, tree collection_expression, tree for_body, 
13073                           tree break_label, tree continue_label)
13074 {
13075   /* A tree representing the __objcFastEnumerationState struct type,
13076      or NSFastEnumerationState struct, whatever we are using.  */
13077   tree objc_fast_enumeration_state_type;
13078
13079   /* The trees representing the declarations of each of the local variables.  */
13080   tree objc_foreach_collection_decl;
13081   tree objc_foreach_enum_state_decl;
13082   tree objc_foreach_items_decl;
13083   tree objc_foreach_batchsize_decl;
13084   tree objc_foreach_mutations_pointer_decl;
13085   tree objc_foreach_index_decl;
13086
13087   /* A tree representing the selector countByEnumeratingWithState:objects:count:.  */
13088   tree selector_name;
13089
13090   /* A tree representing the local bind.  */
13091   tree bind;
13092
13093   /* A tree representing the external 'if (__objc_foreach_batchsize)' */
13094   tree first_if;
13095
13096   /* A tree representing the 'else' part of 'first_if'  */
13097   tree first_else;
13098
13099   /* A tree representing the 'next_batch' label.  */
13100   tree next_batch_label_decl;
13101
13102   /* A tree representing the binding after the 'next_batch' label.  */
13103   tree next_batch_bind;
13104
13105   /* A tree representing the 'next_object' label.  */
13106   tree next_object_label_decl;
13107
13108   /* Temporary variables.  */
13109   tree t;
13110   int i;
13111
13112   if (flag_objc1_only)
13113     error_at (location, "fast enumeration is not available in Objective-C 1.0");
13114
13115   if (object_expression == error_mark_node)
13116     return;
13117
13118   if (collection_expression == error_mark_node)
13119     return;
13120
13121   if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression), true))
13122     {
13123       error ("iterating variable in fast enumeration is not an object");
13124       return;
13125     }
13126
13127   if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression), true))
13128     {
13129       error ("collection in fast enumeration is not an object");
13130       return;
13131     }
13132
13133   /* TODO: Check that object_expression is either a variable
13134      declaration, or an lvalue.  */
13135
13136   /* This kludge is an idea from apple.  We use the
13137      __objcFastEnumerationState struct implicitly defined by the
13138      compiler, unless a NSFastEnumerationState struct has been defined
13139      (by a Foundation library such as GNUstep Base) in which case, we
13140      use that one.
13141   */
13142   objc_fast_enumeration_state_type = objc_fast_enumeration_state_template;
13143   {
13144     tree objc_NSFastEnumeration_type = lookup_name (get_identifier ("NSFastEnumerationState"));
13145
13146     if (objc_NSFastEnumeration_type)
13147       {
13148         /* TODO: We really need to check that
13149            objc_NSFastEnumeration_type is the same as ours!  */
13150         if (TREE_CODE (objc_NSFastEnumeration_type) == TYPE_DECL)
13151           {
13152             /* If it's a typedef, use the original type.  */
13153             if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type))
13154               objc_fast_enumeration_state_type = DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type);
13155             else
13156               objc_fast_enumeration_state_type = TREE_TYPE (objc_NSFastEnumeration_type);             
13157           }
13158       }
13159   }
13160
13161   /* { */
13162   /* Done by c-parser.c.  */
13163
13164   /* type object; */
13165   /* Done by c-parser.c.  */
13166
13167   /*  id __objc_foreach_collection */
13168   objc_foreach_collection_decl = objc_create_temporary_var (objc_object_type, "__objc_foreach_collection");
13169
13170   /*  __objcFastEnumerationState __objc_foreach_enum_state; */
13171   objc_foreach_enum_state_decl = objc_create_temporary_var (objc_fast_enumeration_state_type, "__objc_foreach_enum_state");
13172   TREE_CHAIN (objc_foreach_enum_state_decl) = objc_foreach_collection_decl;
13173
13174   /* id __objc_foreach_items[16]; */
13175   objc_foreach_items_decl = objc_create_temporary_var (build_sized_array_type (objc_object_type, 16), "__objc_foreach_items");
13176   TREE_CHAIN (objc_foreach_items_decl) = objc_foreach_enum_state_decl;
13177
13178   /* unsigned long __objc_foreach_batchsize; */
13179   objc_foreach_batchsize_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_batchsize");
13180   TREE_CHAIN (objc_foreach_batchsize_decl) = objc_foreach_items_decl;
13181
13182   /* Generate the local variable binding.  */
13183   bind = build3 (BIND_EXPR, void_type_node, objc_foreach_batchsize_decl, NULL, NULL);
13184   SET_EXPR_LOCATION (bind, location);
13185   TREE_SIDE_EFFECTS (bind) = 1;
13186   
13187   /*  __objc_foreach_collection = <collection expression>; */
13188   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_collection_decl, collection_expression);
13189   SET_EXPR_LOCATION (t, location);
13190   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13191
13192   /*  __objc_foreach_enum_state.state = 0; */
13193   t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl, 
13194                                                                      get_identifier ("state")),
13195               build_int_cst (long_unsigned_type_node, 0));
13196   SET_EXPR_LOCATION (t, location);
13197   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13198
13199   /*  __objc_foreach_enum_state.itemsPtr = NULL; */
13200   t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl, 
13201                                                                      get_identifier ("itemsPtr")),
13202               null_pointer_node);
13203   SET_EXPR_LOCATION (t, location);
13204   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13205
13206   /*  __objc_foreach_enum_state.mutationsPtr = NULL; */
13207   t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl, 
13208                                                                      get_identifier ("mutationsPtr")),
13209               null_pointer_node);
13210   SET_EXPR_LOCATION (t, location);
13211   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13212
13213   /*  __objc_foreach_enum_state.extra[0] = 0; */
13214   /*  __objc_foreach_enum_state.extra[1] = 0; */
13215   /*  __objc_foreach_enum_state.extra[2] = 0; */
13216   /*  __objc_foreach_enum_state.extra[3] = 0; */
13217   /*  __objc_foreach_enum_state.extra[4] = 0; */
13218   for (i = 0; i < 5 ; i++)
13219     {
13220       t = build2 (MODIFY_EXPR, void_type_node,
13221                   build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl, 
13222                                                                        get_identifier ("extra")),
13223                                    build_int_cst (NULL_TREE, i)),
13224                   build_int_cst (long_unsigned_type_node, 0));
13225       SET_EXPR_LOCATION (t, location);
13226       append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13227     }
13228     
13229   /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16]; */
13230   selector_name = get_identifier ("countByEnumeratingWithState:objects:count:");
13231 #ifdef OBJCPLUS
13232   t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13233                                 /* Parameters.  */
13234                                 tree_cons    /* &__objc_foreach_enum_state */
13235                                 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13236                                  tree_cons   /* __objc_foreach_items  */
13237                                  (NULL_TREE, objc_foreach_items_decl,
13238                                   tree_cons  /* 16 */
13239                                   (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13240 #else
13241   /* In C, we need to decay the __objc_foreach_items array that we are passing.  */
13242   {
13243     struct c_expr array;
13244     array.value = objc_foreach_items_decl;
13245     t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13246                                   /* Parameters.  */
13247                                   tree_cons    /* &__objc_foreach_enum_state */
13248                                   (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13249                                    tree_cons   /* __objc_foreach_items  */
13250                                    (NULL_TREE, default_function_array_conversion (location, array).value,
13251                                     tree_cons  /* 16 */
13252                                     (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13253   }
13254 #endif
13255   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
13256               convert (long_unsigned_type_node, t));
13257   SET_EXPR_LOCATION (t, location);
13258   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13259
13260   /* if (__objc_foreach_batchsize == 0) */
13261   first_if = build3 (COND_EXPR, void_type_node, 
13262                      /* Condition.  */
13263                      c_fully_fold 
13264                      (c_common_truthvalue_conversion 
13265                       (location, 
13266                        build_binary_op (location,
13267                                         EQ_EXPR, 
13268                                         objc_foreach_batchsize_decl,
13269                                         build_int_cst (long_unsigned_type_node, 0), 1)),
13270                       false, NULL),
13271                      /* Then block (we fill it in later).  */
13272                      NULL_TREE,
13273                      /* Else block (we fill it in later).  */
13274                      NULL_TREE);
13275   SET_EXPR_LOCATION (first_if, location);
13276   append_to_statement_list (first_if, &BIND_EXPR_BODY (bind));
13277
13278   /* then <object expression> = nil; */
13279   t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
13280   SET_EXPR_LOCATION (t, location);
13281   COND_EXPR_THEN (first_if) = t;
13282
13283   /* Now we build the 'else' part of the if; once we finish building
13284      it, we attach it to first_if as the 'else' part.  */
13285
13286   /* else */
13287   /* { */
13288
13289   /* unsigned long __objc_foreach_mutations_pointer; */
13290   objc_foreach_mutations_pointer_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_mutations_pointer");
13291
13292   /* Generate the local variable binding.  */
13293   first_else = build3 (BIND_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, NULL, NULL);
13294   SET_EXPR_LOCATION (first_else, location);
13295   TREE_SIDE_EFFECTS (first_else) = 1;
13296
13297   /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
13298   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, 
13299               build_indirect_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl, 
13300                                                                       get_identifier ("mutationsPtr")),
13301                                   RO_UNARY_STAR));
13302   SET_EXPR_LOCATION (t, location);
13303   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13304
13305   /* next_batch: */
13306   next_batch_label_decl = create_artificial_label (location);
13307   t = build1 (LABEL_EXPR, void_type_node, next_batch_label_decl); 
13308   SET_EXPR_LOCATION (t, location);
13309   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13310   
13311   /* { */
13312
13313   /* unsigned long __objc_foreach_index; */
13314   objc_foreach_index_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_index");
13315
13316   /* Generate the local variable binding.  */
13317   next_batch_bind = build3 (BIND_EXPR, void_type_node, objc_foreach_index_decl, NULL, NULL);
13318   SET_EXPR_LOCATION (next_batch_bind, location);
13319   TREE_SIDE_EFFECTS (next_batch_bind) = 1;
13320   append_to_statement_list (next_batch_bind, &BIND_EXPR_BODY (first_else));
13321
13322   /* __objc_foreach_index = 0; */
13323   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
13324               build_int_cst (long_unsigned_type_node, 0));
13325   SET_EXPR_LOCATION (t, location);
13326   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13327
13328   /* next_object: */
13329   next_object_label_decl = create_artificial_label (location);
13330   t = build1 (LABEL_EXPR, void_type_node, next_object_label_decl);
13331   SET_EXPR_LOCATION (t, location);
13332   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13333
13334   /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
13335   t = build3 (COND_EXPR, void_type_node, 
13336               /* Condition.  */
13337               c_fully_fold 
13338               (c_common_truthvalue_conversion 
13339                (location, 
13340                 build_binary_op 
13341                 (location,
13342                  NE_EXPR, 
13343                  objc_foreach_mutations_pointer_decl,
13344                  build_indirect_ref (location, 
13345                                      objc_build_component_ref (objc_foreach_enum_state_decl, 
13346                                                                get_identifier ("mutationsPtr")),
13347                                      RO_UNARY_STAR), 1)),
13348                false, NULL),
13349               /* Then block.  */
13350               build_function_call (input_location,
13351                                    objc_enumeration_mutation_decl,
13352                                    tree_cons (NULL, collection_expression, NULL)),
13353               /* Else block.  */
13354               NULL_TREE);
13355   SET_EXPR_LOCATION (t, location);
13356   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13357
13358   /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
13359   t = build2 (MODIFY_EXPR, void_type_node, object_expression, 
13360               build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl, 
13361                                                                    get_identifier ("itemsPtr")),
13362                                objc_foreach_index_decl));
13363   SET_EXPR_LOCATION (t, location);
13364   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13365
13366   /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
13367   append_to_statement_list (for_body, &BIND_EXPR_BODY (next_batch_bind));
13368
13369   /* continue_label: */
13370   if (continue_label)
13371     {
13372       t = build1 (LABEL_EXPR, void_type_node, continue_label);
13373       SET_EXPR_LOCATION (t, location);
13374       append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13375     }
13376
13377   /* __objc_foreach_index++; */
13378   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl, 
13379               build_binary_op (location,
13380                                PLUS_EXPR,
13381                                objc_foreach_index_decl,
13382                                build_int_cst (long_unsigned_type_node, 1), 1));
13383   SET_EXPR_LOCATION (t, location);
13384   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13385
13386   /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
13387   t = build3 (COND_EXPR, void_type_node, 
13388               /* Condition.  */
13389               c_fully_fold 
13390               (c_common_truthvalue_conversion 
13391                (location, 
13392                 build_binary_op (location,
13393                                  LT_EXPR, 
13394                                  objc_foreach_index_decl,
13395                                  objc_foreach_batchsize_decl, 1)),
13396                false, NULL),
13397               /* Then block.  */
13398               build1 (GOTO_EXPR, void_type_node, next_object_label_decl),
13399               /* Else block.  */
13400               NULL_TREE);
13401   SET_EXPR_LOCATION (t, location);
13402   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13403   
13404   /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16]; */
13405 #ifdef OBJCPLUS
13406   t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13407                                 /* Parameters.  */
13408                                 tree_cons    /* &__objc_foreach_enum_state */
13409                                 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13410                                  tree_cons   /* __objc_foreach_items  */
13411                                  (NULL_TREE, objc_foreach_items_decl,
13412                                   tree_cons  /* 16 */
13413                                   (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13414 #else
13415   /* In C, we need to decay the __objc_foreach_items array that we are passing.  */
13416   {
13417     struct c_expr array;
13418     array.value = objc_foreach_items_decl;
13419     t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13420                                   /* Parameters.  */
13421                                   tree_cons    /* &__objc_foreach_enum_state */
13422                                   (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13423                                    tree_cons   /* __objc_foreach_items  */
13424                                    (NULL_TREE, default_function_array_conversion (location, array).value,
13425                                     tree_cons  /* 16 */
13426                                     (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13427   }
13428 #endif
13429   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl, 
13430               convert (long_unsigned_type_node, t));
13431   SET_EXPR_LOCATION (t, location);
13432   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13433
13434   /* } */
13435
13436   /* if (__objc_foreach_batchsize != 0) goto next_batch; */
13437   t = build3 (COND_EXPR, void_type_node, 
13438               /* Condition.  */
13439               c_fully_fold 
13440               (c_common_truthvalue_conversion 
13441                (location, 
13442                 build_binary_op (location,
13443                                  NE_EXPR, 
13444                                  objc_foreach_batchsize_decl,
13445                                  build_int_cst (long_unsigned_type_node, 0), 1)),
13446                false, NULL),
13447               /* Then block.  */
13448               build1 (GOTO_EXPR, void_type_node, next_batch_label_decl),
13449               /* Else block.  */
13450               NULL_TREE);
13451   SET_EXPR_LOCATION (t, location);
13452   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13453
13454   /* <object expression> = nil; */
13455   t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
13456   SET_EXPR_LOCATION (t, location);
13457   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13458
13459   /* break_label: */
13460   if (break_label)
13461     {
13462       t = build1 (LABEL_EXPR, void_type_node, break_label);
13463       SET_EXPR_LOCATION (t, location);
13464       append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13465     }
13466
13467   /* } */
13468   COND_EXPR_ELSE (first_if) = first_else;
13469
13470   /* Do the whole thing.  */
13471   add_stmt (bind);
13472
13473 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
13474   /* This will print to stderr the whole blurb generated by the
13475      compiler while compiling (assuming the compiler doesn't crash
13476      before getting here).
13477    */
13478   debug_generic_stmt (bind);
13479 #endif
13480
13481   /* } */
13482   /* Done by c-parser.c  */
13483 }
13484
13485 /* Return true if we have an NxString object pointer.  */
13486
13487 bool
13488 objc_string_ref_type_p (tree strp)
13489 {
13490   tree tmv;
13491   if (!strp || TREE_CODE (strp) != POINTER_TYPE)
13492     return false;
13493
13494   tmv = TYPE_MAIN_VARIANT (TREE_TYPE (strp));
13495   tmv = OBJC_TYPE_NAME (tmv);
13496   return (tmv
13497           && TREE_CODE (tmv) == IDENTIFIER_NODE
13498           && IDENTIFIER_POINTER (tmv)
13499           && !strncmp (IDENTIFIER_POINTER (tmv), "NSString", 8));
13500 }
13501
13502 /* At present the behavior of this is undefined and it does nothing.  */
13503 void
13504 objc_check_format_arg (tree ARG_UNUSED (format_arg), 
13505                        tree ARG_UNUSED (args_list))
13506 {
13507 }
13508
13509 #include "gt-objc-objc-act.h"