OSDN Git Service

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