OSDN Git Service

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