OSDN Git Service

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