OSDN Git Service

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