OSDN Git Service

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