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