OSDN Git Service

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