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