OSDN Git Service

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