OSDN Git Service

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