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