OSDN Git Service

PR objc/43061
[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     {
875       if (!TYPE_HAS_OBJC_INFO (t))
876         {
877           INIT_TYPE_OBJC_INFO (t);
878           TYPE_OBJC_INTERFACE (t) = klass;
879         }
880       objc_info
881         = chainon (objc_info,
882                    build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
883     }
884
885   /* Point the struct at its related Objective-C class.  */
886   INIT_TYPE_OBJC_INFO (s);
887   TYPE_OBJC_INTERFACE (s) = klass;
888
889   s = objc_finish_struct (s, fields);
890
891   for (t = TYPE_NEXT_VARIANT (s); t;
892        t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
893     {
894       TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
895       /* Replace the IDENTIFIER_NODE with an actual @interface.  */
896       TYPE_OBJC_INTERFACE (t) = klass;
897     }
898
899   /* Use TYPE_BINFO structures to point at the super class, if any.  */
900   objc_xref_basetypes (s, super);
901
902   /* Mark this struct as a class template.  */
903   CLASS_STATIC_TEMPLATE (klass) = s;
904
905   return s;
906 }
907
908 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
909    Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
910    process.  */
911 static tree
912 objc_build_volatilized_type (tree type)
913 {
914   tree t;
915
916   /* Check if we have not constructed the desired variant already.  */
917   for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
918     {
919       /* The type qualifiers must (obviously) match up.  */
920       if (!TYPE_VOLATILE (t)
921           || (TYPE_READONLY (t) != TYPE_READONLY (type))
922           || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
923         continue;
924
925       /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
926          info, if any) must match up.  */
927       if (POINTER_TYPE_P (t)
928           && (TREE_TYPE (t) != TREE_TYPE (type)))
929         continue;
930
931       /* Everything matches up!  */
932       return t;
933     }
934
935   /* Ok, we could not re-use any of the pre-existing variants.  Create
936      a new one.  */
937   t = build_variant_type_copy (type);
938   TYPE_VOLATILE (t) = 1;
939
940   /* Set up the canonical type information. */
941   if (TYPE_STRUCTURAL_EQUALITY_P (type))
942     SET_TYPE_STRUCTURAL_EQUALITY (t);
943   else if (TYPE_CANONICAL (type) != type)
944     TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
945   else
946     TYPE_CANONICAL (t) = t;
947
948   return t;
949 }
950
951 /* Mark DECL as being 'volatile' for purposes of Darwin
952    _setjmp()/_longjmp() exception handling.  Called from
953    objc_mark_locals_volatile().  */
954 void
955 objc_volatilize_decl (tree decl)
956 {
957   /* Do not mess with variables that are 'static' or (already)
958      'volatile'.  */
959   if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
960       && (TREE_CODE (decl) == VAR_DECL
961           || TREE_CODE (decl) == PARM_DECL))
962     {
963       tree t = TREE_TYPE (decl);
964       struct volatilized_type key;
965       void **loc;
966
967       t = objc_build_volatilized_type (t);
968       key.type = t;
969       loc = htab_find_slot (volatilized_htab, &key, INSERT);
970
971       if (!*loc)
972         {
973           *loc = ggc_alloc (sizeof (key));
974           ((struct volatilized_type *) *loc)->type = t;
975         }
976
977       TREE_TYPE (decl) = t;
978       TREE_THIS_VOLATILE (decl) = 1;
979       TREE_SIDE_EFFECTS (decl) = 1;
980       DECL_REGISTER (decl) = 0;
981 #ifndef OBJCPLUS
982       C_DECL_REGISTER (decl) = 0;
983 #endif
984     }
985 }
986
987 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
988    (including its categories and superclasses) or by object type TYP.
989    Issue a warning if PROTO is not adopted anywhere and WARN is set.  */
990
991 static bool
992 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
993 {
994   bool class_type = (cls != NULL_TREE);
995
996   while (cls)
997     {
998       tree c;
999
1000       /* Check protocols adopted by the class and its categories.  */
1001       for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
1002         {
1003           if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
1004             return true;
1005         }
1006
1007       /* Repeat for superclasses.  */
1008       cls = lookup_interface (CLASS_SUPER_NAME (cls));
1009     }
1010
1011   /* Check for any protocols attached directly to the object type.  */
1012   if (TYPE_HAS_OBJC_INFO (typ))
1013     {
1014       if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
1015         return true;
1016     }
1017
1018   if (warn)
1019     {
1020       *errbuf = 0;
1021       gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
1022       /* NB: Types 'id' and 'Class' cannot reasonably be described as
1023          "implementing" a given protocol, since they do not have an
1024          implementation.  */
1025       if (class_type)
1026         warning (0, "class %qs does not implement the %qE protocol",
1027                  identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1028       else
1029         warning (0, "type %qs does not conform to the %qE protocol",
1030                  identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1031     }
1032
1033   return false;
1034 }
1035
1036 /* Check if class RCLS and instance struct type RTYP conform to at least the
1037    same protocols that LCLS and LTYP conform to.  */
1038
1039 static bool
1040 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1041 {
1042   tree p;
1043   bool have_lproto = false;
1044
1045   while (lcls)
1046     {
1047       /* NB: We do _not_ look at categories defined for LCLS; these may or
1048          may not get loaded in, and therefore it is unreasonable to require
1049          that RCLS/RTYP must implement any of their protocols.  */
1050       for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1051         {
1052           have_lproto = true;
1053
1054           if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1055             return warn;
1056         }
1057
1058       /* Repeat for superclasses.  */
1059       lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1060     }
1061
1062   /* Check for any protocols attached directly to the object type.  */
1063   if (TYPE_HAS_OBJC_INFO (ltyp))
1064     {
1065       for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1066         {
1067           have_lproto = true;
1068
1069           if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1070             return warn;
1071         }
1072     }
1073
1074   /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1075      vacuously, _unless_ RTYP is a protocol-qualified 'id'.  We can get
1076      away with simply checking for 'id' or 'Class' (!RCLS), since this
1077      routine will not get called in other cases.  */
1078   return have_lproto || (rcls != NULL_TREE);
1079 }
1080
1081 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1082    an instance of RTYP to an instance of LTYP or to compare the two
1083    (if ARGNO is equal to -3), per ObjC type system rules.  Before
1084    returning 'true', this routine may issue warnings related to, e.g.,
1085    protocol conformance.  When returning 'false', the routine must
1086    produce absolutely no warnings; the C or C++ front-end will do so
1087    instead, if needed.  If either LTYP or RTYP is not an Objective-C type,
1088    the routine must return 'false'.
1089
1090    The ARGNO parameter is encoded as follows:
1091      >= 1       Parameter number (CALLEE contains function being called);
1092      0          Return value;
1093      -1         Assignment;
1094      -2         Initialization;
1095      -3         Comparison (LTYP and RTYP may match in either direction).  */
1096
1097 bool
1098 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1099 {
1100   tree lcls, rcls, lproto, rproto;
1101   bool pointers_compatible;
1102
1103   /* We must be dealing with pointer types */
1104   if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1105     return false;
1106
1107   do
1108     {
1109       ltyp = TREE_TYPE (ltyp);  /* Remove indirections.  */
1110       rtyp = TREE_TYPE (rtyp);
1111     }
1112   while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1113
1114   /* Past this point, we are only interested in ObjC class instances,
1115      or 'id' or 'Class'.  */
1116   if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1117     return false;
1118
1119   if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1120       && !TYPE_HAS_OBJC_INFO (ltyp))
1121     return false;
1122
1123   if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1124       && !TYPE_HAS_OBJC_INFO (rtyp))
1125     return false;
1126
1127   /* Past this point, we are committed to returning 'true' to the caller.
1128      However, we can still warn about type and/or protocol mismatches.  */
1129
1130   if (TYPE_HAS_OBJC_INFO (ltyp))
1131     {
1132       lcls = TYPE_OBJC_INTERFACE (ltyp);
1133       lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1134     }
1135   else
1136     lcls = lproto = NULL_TREE;
1137
1138   if (TYPE_HAS_OBJC_INFO (rtyp))
1139     {
1140       rcls = TYPE_OBJC_INTERFACE (rtyp);
1141       rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1142     }
1143   else
1144     rcls = rproto = NULL_TREE;
1145
1146   /* If we could not find an @interface declaration, we must have
1147      only seen a @class declaration; for purposes of type comparison,
1148      treat it as a stand-alone (root) class.  */
1149
1150   if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1151     lcls = NULL_TREE;
1152
1153   if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1154     rcls = NULL_TREE;
1155
1156   /* If either type is an unqualified 'id', we're done.  */
1157   if ((!lproto && objc_is_object_id (ltyp))
1158       || (!rproto && objc_is_object_id (rtyp)))
1159     return true;
1160
1161   pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1162
1163   /* If the underlying types are the same, and at most one of them has
1164      a protocol list, we do not need to issue any diagnostics.  */
1165   if (pointers_compatible && (!lproto || !rproto))
1166     return true;
1167
1168   /* If exactly one of the types is 'Class', issue a diagnostic; any
1169      exceptions of this rule have already been handled.  */
1170   if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1171     pointers_compatible = false;
1172   /* Otherwise, check for inheritance relations.  */
1173   else
1174     {
1175       if (!pointers_compatible)
1176         pointers_compatible
1177           = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1178
1179       if (!pointers_compatible)
1180         pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1181
1182       if (!pointers_compatible && argno == -3)
1183         pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1184     }
1185
1186   /* If the pointers match modulo protocols, check for protocol conformance
1187      mismatches.  */
1188   if (pointers_compatible)
1189     {
1190       pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1191                                                     argno != -3);
1192
1193       if (!pointers_compatible && argno == -3)
1194         pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1195                                                       argno != -3);
1196     }
1197
1198   if (!pointers_compatible)
1199     {
1200       /* NB: For the time being, we shall make our warnings look like their
1201          C counterparts.  In the future, we may wish to make them more
1202          ObjC-specific.  */
1203       switch (argno)
1204         {
1205         case -3:
1206           warning (0, "comparison of distinct Objective-C types lacks a cast");
1207           break;
1208
1209         case -2:
1210           warning (0, "initialization from distinct Objective-C type");
1211           break;
1212
1213         case -1:
1214           warning (0, "assignment from distinct Objective-C type");
1215           break;
1216
1217         case 0:
1218           warning (0, "distinct Objective-C type in return");
1219           break;
1220
1221         default:
1222           warning (0, "passing argument %d of %qE from distinct "
1223                    "Objective-C type", argno, callee);
1224           break;
1225         }
1226     }
1227
1228   return true;
1229 }
1230
1231 /* Check if LTYP and RTYP have the same type qualifiers.  If either type
1232    lives in the volatilized hash table, ignore the 'volatile' bit when
1233    making the comparison.  */
1234
1235 bool
1236 objc_type_quals_match (tree ltyp, tree rtyp)
1237 {
1238   int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1239   struct volatilized_type key;
1240
1241   key.type = ltyp;
1242
1243   if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1244     lquals &= ~TYPE_QUAL_VOLATILE;
1245
1246   key.type = rtyp;
1247
1248   if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1249     rquals &= ~TYPE_QUAL_VOLATILE;
1250
1251   return (lquals == rquals);
1252 }
1253
1254 #ifndef OBJCPLUS
1255 /* Determine if CHILD is derived from PARENT.  The routine assumes that
1256    both parameters are RECORD_TYPEs, and is non-reflexive.  */
1257
1258 static bool
1259 objc_derived_from_p (tree parent, tree child)
1260 {
1261   parent = TYPE_MAIN_VARIANT (parent);
1262
1263   for (child = TYPE_MAIN_VARIANT (child);
1264        TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1265     {
1266       child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1267                                              (TYPE_BINFO (child),
1268                                               0)));
1269
1270       if (child == parent)
1271         return true;
1272     }
1273
1274   return false;
1275 }
1276 #endif
1277
1278 static tree
1279 objc_build_component_ref (tree datum, tree component)
1280 {
1281   /* If COMPONENT is NULL, the caller is referring to the anonymous
1282      base class field.  */
1283   if (!component)
1284     {
1285       tree base = TYPE_FIELDS (TREE_TYPE (datum));
1286
1287       return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1288     }
1289
1290   /* The 'build_component_ref' routine has been removed from the C++
1291      front-end, but 'finish_class_member_access_expr' seems to be
1292      a worthy substitute.  */
1293 #ifdef OBJCPLUS
1294   return finish_class_member_access_expr (datum, component, false,
1295                                           tf_warning_or_error);
1296 #else
1297   return build_component_ref (input_location, datum, component);
1298 #endif
1299 }
1300
1301 /* Recursively copy inheritance information rooted at BINFO.  To do this,
1302    we emulate the song and dance performed by cp/tree.c:copy_binfo().  */
1303
1304 static tree
1305 objc_copy_binfo (tree binfo)
1306 {
1307   tree btype = BINFO_TYPE (binfo);
1308   tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1309   tree base_binfo;
1310   int ix;
1311
1312   BINFO_TYPE (binfo2) = btype;
1313   BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1314   BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1315
1316   /* Recursively copy base binfos of BINFO.  */
1317   for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1318     {
1319       tree base_binfo2 = objc_copy_binfo (base_binfo);
1320
1321       BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1322       BINFO_BASE_APPEND (binfo2, base_binfo2);
1323     }
1324
1325   return binfo2;
1326 }
1327
1328 /* Record superclass information provided in BASETYPE for ObjC class REF.
1329    This is loosely based on cp/decl.c:xref_basetypes().  */
1330
1331 static void
1332 objc_xref_basetypes (tree ref, tree basetype)
1333 {
1334   tree binfo = make_tree_binfo (basetype ? 1 : 0);
1335
1336   TYPE_BINFO (ref) = binfo;
1337   BINFO_OFFSET (binfo) = size_zero_node;
1338   BINFO_TYPE (binfo) = ref;
1339
1340   if (basetype)
1341     {
1342       tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1343
1344       BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1345       BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1346       BINFO_BASE_APPEND (binfo, base_binfo);
1347       BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1348     }
1349 }
1350
1351 static hashval_t
1352 volatilized_hash (const void *ptr)
1353 {
1354   const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1355
1356   return htab_hash_pointer(typ);
1357 }
1358
1359 static int
1360 volatilized_eq (const void *ptr1, const void *ptr2)
1361 {
1362   const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1363   const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1364
1365   return typ1 == typ2;
1366 }
1367
1368 /* Called from finish_decl.  */
1369
1370 void
1371 objc_check_decl (tree decl)
1372 {
1373   tree type = TREE_TYPE (decl);
1374
1375   if (TREE_CODE (type) != RECORD_TYPE)
1376     return;
1377   if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1378     error ("statically allocated instance of Objective-C class %qE",
1379            type);
1380 }
1381
1382 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1383    either name an Objective-C class, or refer to the special 'id' or 'Class'
1384    types.  If INTERFACE is not a valid ObjC type, just return it unchanged.  */
1385
1386 tree
1387 objc_get_protocol_qualified_type (tree interface, tree protocols)
1388 {
1389   /* If INTERFACE is not provided, default to 'id'.  */
1390   tree type = (interface ? objc_is_id (interface) : objc_object_type);
1391   bool is_ptr = (type != NULL_TREE);
1392
1393   if (!is_ptr)
1394     {
1395       type = objc_is_class_name (interface);
1396
1397       if (type)
1398         type = xref_tag (RECORD_TYPE, type);
1399       else
1400         return interface;
1401     }
1402
1403   if (protocols)
1404     {
1405       type = build_variant_type_copy (type);
1406
1407       /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1408          to the pointee.  */
1409       if (is_ptr)
1410         {
1411           tree orig_pointee_type = TREE_TYPE (type);
1412           TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1413
1414           /* Set up the canonical type information. */
1415           TYPE_CANONICAL (type) 
1416             = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1417
1418           TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1419           type = TREE_TYPE (type);
1420         }
1421
1422       /* Look up protocols and install in lang specific list.  */
1423       DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1424       TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1425
1426       /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1427          return the pointer to the new pointee variant.  */
1428       if (is_ptr)
1429         type = TYPE_POINTER_TO (type);
1430       else
1431         TYPE_OBJC_INTERFACE (type)
1432           = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1433     }
1434
1435   return type;
1436 }
1437
1438 /* Check for circular dependencies in protocols.  The arguments are
1439    PROTO, the protocol to check, and LIST, a list of protocol it
1440    conforms to.  */
1441
1442 static void
1443 check_protocol_recursively (tree proto, tree list)
1444 {
1445   tree p;
1446
1447   for (p = list; p; p = TREE_CHAIN (p))
1448     {
1449       tree pp = TREE_VALUE (p);
1450
1451       if (TREE_CODE (pp) == IDENTIFIER_NODE)
1452         pp = lookup_protocol (pp);
1453
1454       if (pp == proto)
1455         fatal_error ("protocol %qE has circular dependency",
1456                      PROTOCOL_NAME (pp));
1457       if (pp)
1458         check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1459     }
1460 }
1461
1462 /* Look up PROTOCOLS, and return a list of those that are found.
1463    If none are found, return NULL.  */
1464
1465 static tree
1466 lookup_and_install_protocols (tree protocols)
1467 {
1468   tree proto;
1469   tree return_value = NULL_TREE;
1470
1471   for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1472     {
1473       tree ident = TREE_VALUE (proto);
1474       tree p = lookup_protocol (ident);
1475
1476       if (p)
1477         return_value = chainon (return_value,
1478                                 build_tree_list (NULL_TREE, p));
1479       else if (ident != error_mark_node)
1480         error ("cannot find protocol declaration for %qE",
1481                ident);
1482     }
1483
1484   return return_value;
1485 }
1486
1487 /* Create a declaration for field NAME of a given TYPE.  */
1488
1489 static tree
1490 create_field_decl (tree type, const char *name)
1491 {
1492   return build_decl (input_location,
1493                      FIELD_DECL, get_identifier (name), type);
1494 }
1495
1496 /* Create a global, static declaration for variable NAME of a given TYPE.  The
1497    finish_var_decl() routine will need to be called on it afterwards.  */
1498
1499 static tree
1500 start_var_decl (tree type, const char *name)
1501 {
1502   tree var = build_decl (input_location,
1503                          VAR_DECL, get_identifier (name), type);
1504
1505   TREE_STATIC (var) = 1;
1506   DECL_INITIAL (var) = error_mark_node;  /* A real initializer is coming... */
1507   DECL_IGNORED_P (var) = 1;
1508   DECL_ARTIFICIAL (var) = 1;
1509   DECL_CONTEXT (var) = NULL_TREE;
1510 #ifdef OBJCPLUS
1511   DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1512 #endif
1513
1514   return var;
1515 }
1516
1517 /* Finish off the variable declaration created by start_var_decl().  */
1518
1519 static void
1520 finish_var_decl (tree var, tree initializer)
1521 {
1522   finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
1523   /* Ensure that the variable actually gets output.  */
1524   mark_decl_referenced (var);
1525   /* Mark the decl to avoid "defined but not used" warning.  */
1526   TREE_USED (var) = 1;
1527   /* We reserve the right for the runtime to use/modify these variables
1528      in ways that are opaque to us.  */
1529   DECL_PRESERVE_P (var) = 1;
1530 }
1531
1532 /* Find the decl for the constant string class reference.  This is only
1533    used for the NeXT runtime.  */
1534
1535 static tree
1536 setup_string_decl (void)
1537 {
1538   char *name;
1539   size_t length;
1540
1541   /* %s in format will provide room for terminating null */
1542   length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1543            + strlen (constant_string_class_name);
1544   name = XNEWVEC (char, length);
1545   sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1546            constant_string_class_name);
1547   constant_string_global_id = get_identifier (name);
1548   string_class_decl = lookup_name (constant_string_global_id);
1549
1550   return string_class_decl;
1551 }
1552
1553 /* Purpose: "play" parser, creating/installing representations
1554    of the declarations that are required by Objective-C.
1555
1556    Model:
1557
1558         type_spec--------->sc_spec
1559         (tree_list)        (tree_list)
1560             |                  |
1561             |                  |
1562         identifier_node    identifier_node  */
1563
1564 static void
1565 synth_module_prologue (void)
1566 {
1567   tree type;
1568   enum debug_info_type save_write_symbols = write_symbols;
1569   const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1570
1571   /* Suppress outputting debug symbols, because
1572      dbxout_init hasn't been called yet.  */
1573   write_symbols = NO_DEBUG;
1574   debug_hooks = &do_nothing_debug_hooks;
1575
1576 #ifdef OBJCPLUS
1577   push_lang_context (lang_name_c); /* extern "C" */
1578 #endif
1579
1580   /* The following are also defined in <objc/objc.h> and friends.  */
1581
1582   objc_object_id = get_identifier (TAG_OBJECT);
1583   objc_class_id = get_identifier (TAG_CLASS);
1584
1585   objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1586   objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1587
1588   objc_object_type = build_pointer_type (objc_object_reference);
1589   objc_class_type = build_pointer_type (objc_class_reference);
1590
1591   objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1592   objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1593
1594   /* Declare the 'id' and 'Class' typedefs.  */
1595
1596   type = lang_hooks.decls.pushdecl (build_decl (input_location,
1597                                                 TYPE_DECL,
1598                                                 objc_object_name,
1599                                                 objc_object_type));
1600   TREE_NO_WARNING (type) = 1;
1601   type = lang_hooks.decls.pushdecl (build_decl (input_location,
1602                                                 TYPE_DECL,
1603                                                 objc_class_name,
1604                                                 objc_class_type));
1605   TREE_NO_WARNING (type) = 1;
1606
1607   /* Forward-declare '@interface Protocol'.  */
1608
1609   type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1610   objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1611   objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1612                                 type));
1613
1614   /* Declare type of selector-objects that represent an operation name.  */
1615
1616   if (flag_next_runtime)
1617     /* `struct objc_selector *' */
1618     objc_selector_type
1619       = build_pointer_type (xref_tag (RECORD_TYPE,
1620                                       get_identifier (TAG_SELECTOR)));
1621   else
1622     /* `const struct objc_selector *' */
1623     objc_selector_type
1624       = build_pointer_type
1625         (build_qualified_type (xref_tag (RECORD_TYPE,
1626                                          get_identifier (TAG_SELECTOR)),
1627                                TYPE_QUAL_CONST));
1628
1629   /* Declare receiver type used for dispatching messages to 'super'.  */
1630
1631   /* `struct objc_super *' */
1632   objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1633                                                   get_identifier (TAG_SUPER)));
1634
1635   /* Declare pointers to method and ivar lists.  */
1636   objc_method_list_ptr = build_pointer_type
1637                          (xref_tag (RECORD_TYPE,
1638                                     get_identifier (UTAG_METHOD_LIST)));
1639   objc_method_proto_list_ptr
1640     = build_pointer_type (xref_tag (RECORD_TYPE,
1641                                     get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1642   objc_ivar_list_ptr = build_pointer_type
1643                        (xref_tag (RECORD_TYPE,
1644                                   get_identifier (UTAG_IVAR_LIST)));
1645
1646   /* TREE_NOTHROW is cleared for the message-sending functions,
1647      because the function that gets called can throw in Obj-C++, or
1648      could itself call something that can throw even in Obj-C.  */
1649
1650   if (flag_next_runtime)
1651     {
1652       /* NB: In order to call one of the ..._stret (struct-returning)
1653       functions, the function *MUST* first be cast to a signature that
1654       corresponds to the actual ObjC method being invoked.  This is
1655       what is done by the build_objc_method_call() routine below.  */
1656
1657       /* id objc_msgSend (id, SEL, ...); */
1658       /* id objc_msgSendNonNil (id, SEL, ...); */
1659       /* id objc_msgSend_stret (id, SEL, ...); */
1660       /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1661       type
1662         = build_function_type (objc_object_type,
1663                                tree_cons (NULL_TREE, objc_object_type,
1664                                           tree_cons (NULL_TREE, objc_selector_type,
1665                                                      NULL_TREE)));
1666       umsg_decl = add_builtin_function (TAG_MSGSEND,
1667                                         type, 0, NOT_BUILT_IN,
1668                                         NULL, NULL_TREE);
1669       umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1670                                                type, 0, NOT_BUILT_IN,
1671                                                NULL, NULL_TREE);
1672       umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1673                                               type, 0, NOT_BUILT_IN,
1674                                               NULL, NULL_TREE);
1675       umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1676                                                      type, 0, NOT_BUILT_IN,
1677                                                      NULL, NULL_TREE);
1678
1679       /* These can throw, because the function that gets called can throw
1680          in Obj-C++, or could itself call something that can throw even
1681          in Obj-C.  */
1682       TREE_NOTHROW (umsg_decl) = 0;
1683       TREE_NOTHROW (umsg_nonnil_decl) = 0;
1684       TREE_NOTHROW (umsg_stret_decl) = 0;
1685       TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1686
1687       /* id objc_msgSend_Fast (id, SEL, ...)
1688            __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1689 #ifdef OFFS_MSGSEND_FAST
1690       umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1691                                              type, 0, NOT_BUILT_IN,
1692                                              NULL, NULL_TREE);
1693       TREE_NOTHROW (umsg_fast_decl) = 0;
1694       DECL_ATTRIBUTES (umsg_fast_decl)
1695         = tree_cons (get_identifier ("hard_coded_address"),
1696                      build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1697                      NULL_TREE);
1698 #else
1699       /* No direct dispatch available.  */
1700       umsg_fast_decl = umsg_decl;
1701 #endif
1702
1703       /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1704       /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1705       type
1706         = build_function_type (objc_object_type,
1707                                tree_cons (NULL_TREE, objc_super_type,
1708                                           tree_cons (NULL_TREE, objc_selector_type,
1709                                                      NULL_TREE)));
1710       umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1711                                               type, 0, NOT_BUILT_IN,
1712                                               NULL, NULL_TREE);
1713       umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1714                                                     type, 0, NOT_BUILT_IN, 0,
1715                                                     NULL_TREE);
1716       TREE_NOTHROW (umsg_super_decl) = 0;
1717       TREE_NOTHROW (umsg_super_stret_decl) = 0;
1718     }
1719   else
1720     {
1721       /* GNU runtime messenger entry points.  */
1722
1723       /* typedef id (*IMP)(id, SEL, ...); */
1724       tree IMP_type
1725         = build_pointer_type
1726           (build_function_type (objc_object_type,
1727                                 tree_cons (NULL_TREE, objc_object_type,
1728                                            tree_cons (NULL_TREE, objc_selector_type,
1729                                                       NULL_TREE))));
1730
1731       /* IMP objc_msg_lookup (id, SEL); */
1732       type
1733         = build_function_type (IMP_type,
1734                                tree_cons (NULL_TREE, objc_object_type,
1735                                           tree_cons (NULL_TREE, objc_selector_type,
1736                                                      OBJC_VOID_AT_END)));
1737       umsg_decl = add_builtin_function (TAG_MSGSEND,
1738                                         type, 0, NOT_BUILT_IN,
1739                                         NULL, NULL_TREE);
1740       TREE_NOTHROW (umsg_decl) = 0;
1741
1742       /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1743       type
1744         = build_function_type (IMP_type,
1745                                tree_cons (NULL_TREE, objc_super_type,
1746                                           tree_cons (NULL_TREE, objc_selector_type,
1747                                                      OBJC_VOID_AT_END)));
1748       umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1749                                               type, 0, NOT_BUILT_IN,
1750                                               NULL, NULL_TREE);
1751       TREE_NOTHROW (umsg_super_decl) = 0;
1752
1753       /* The following GNU runtime entry point is called to initialize
1754          each module:
1755
1756          __objc_exec_class (void *); */
1757       type
1758         = build_function_type (void_type_node,
1759                                tree_cons (NULL_TREE, ptr_type_node,
1760                                           OBJC_VOID_AT_END));
1761       execclass_decl = add_builtin_function (TAG_EXECCLASS,
1762                                              type, 0, NOT_BUILT_IN,
1763                                              NULL, NULL_TREE);
1764     }
1765
1766   /* id objc_getClass (const char *); */
1767
1768   type = build_function_type (objc_object_type,
1769                                    tree_cons (NULL_TREE,
1770                                               const_string_type_node,
1771                                               OBJC_VOID_AT_END));
1772
1773   objc_get_class_decl
1774     = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1775                             NULL, NULL_TREE);
1776
1777   /* id objc_getMetaClass (const char *); */
1778
1779   objc_get_meta_class_decl
1780     = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1781
1782   build_class_template ();
1783   build_super_template ();
1784   build_protocol_template ();
1785   build_category_template ();
1786   build_objc_exception_stuff ();
1787
1788   if (flag_next_runtime)
1789     build_next_objc_exception_stuff ();
1790
1791   /* static SEL _OBJC_SELECTOR_TABLE[]; */
1792
1793   if (! flag_next_runtime)
1794     build_selector_table_decl ();
1795
1796   /* Forward declare constant_string_id and constant_string_type.  */
1797   if (!constant_string_class_name)
1798     constant_string_class_name = default_constant_string_class_name;
1799
1800   constant_string_id = get_identifier (constant_string_class_name);
1801   objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1802
1803   /* Pre-build the following entities - for speed/convenience.  */
1804   self_id = get_identifier ("self");
1805   ucmd_id = get_identifier ("_cmd");
1806
1807 #ifdef OBJCPLUS
1808   pop_lang_context ();
1809 #endif
1810
1811   write_symbols = save_write_symbols;
1812   debug_hooks = save_hooks;
1813 }
1814
1815 /* Ensure that the ivar list for NSConstantString/NXConstantString
1816    (or whatever was specified via `-fconstant-string-class')
1817    contains fields at least as large as the following three, so that
1818    the runtime can stomp on them with confidence:
1819
1820    struct STRING_OBJECT_CLASS_NAME
1821    {
1822      Object isa;
1823      char *cString;
1824      unsigned int length;
1825    }; */
1826
1827 static int
1828 check_string_class_template (void)
1829 {
1830   tree field_decl = objc_get_class_ivars (constant_string_id);
1831
1832 #define AT_LEAST_AS_LARGE_AS(F, T) \
1833   (F && TREE_CODE (F) == FIELD_DECL \
1834      && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1835          >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1836
1837   if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1838     return 0;
1839
1840   field_decl = TREE_CHAIN (field_decl);
1841   if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1842     return 0;
1843
1844   field_decl = TREE_CHAIN (field_decl);
1845   return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1846
1847 #undef AT_LEAST_AS_LARGE_AS
1848 }
1849
1850 /* Avoid calling `check_string_class_template ()' more than once.  */
1851 static GTY(()) int string_layout_checked;
1852
1853 /* Construct an internal string layout to be used as a template for
1854    creating NSConstantString/NXConstantString instances.  */
1855
1856 static tree
1857 objc_build_internal_const_str_type (void)
1858 {
1859   tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1860   tree fields = build_decl (input_location,
1861                             FIELD_DECL, NULL_TREE, ptr_type_node);
1862   tree field = build_decl (input_location,
1863                            FIELD_DECL, NULL_TREE, ptr_type_node);
1864
1865   TREE_CHAIN (field) = fields; fields = field;
1866   field = build_decl (input_location,
1867                       FIELD_DECL, NULL_TREE, unsigned_type_node);
1868   TREE_CHAIN (field) = fields; fields = field;
1869   /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1870      reverse order!  */
1871   finish_builtin_struct (type, "__builtin_ObjCString",
1872                          fields, NULL_TREE);
1873
1874   return type;
1875 }
1876
1877 /* Custom build_string which sets TREE_TYPE!  */
1878
1879 static tree
1880 my_build_string (int len, const char *str)
1881 {
1882   return fix_string_type (build_string (len, str));
1883 }
1884
1885 /* Build a string with contents STR and length LEN and convert it to a
1886    pointer.  */
1887
1888 static tree
1889 my_build_string_pointer (int len, const char *str)
1890 {
1891   tree string = my_build_string (len, str);
1892   tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1893   return build1 (ADDR_EXPR, ptrtype, string);
1894 }
1895
1896 static hashval_t
1897 string_hash (const void *ptr)
1898 {
1899   const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1900   const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1901   int i, len = TREE_STRING_LENGTH (str);
1902   hashval_t h = len;
1903
1904   for (i = 0; i < len; i++)
1905     h = ((h * 613) + p[i]);
1906
1907   return h;
1908 }
1909
1910 static int
1911 string_eq (const void *ptr1, const void *ptr2)
1912 {
1913   const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
1914   const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
1915   int len1 = TREE_STRING_LENGTH (str1);
1916
1917   return (len1 == TREE_STRING_LENGTH (str2)
1918           && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1919                       len1));
1920 }
1921
1922 /* Given a chain of STRING_CST's, build a static instance of
1923    NXConstantString which points at the concatenation of those
1924    strings.  We place the string object in the __string_objects
1925    section of the __OBJC segment.  The Objective-C runtime will
1926    initialize the isa pointers of the string objects to point at the
1927    NXConstantString class object.  */
1928
1929 tree
1930 objc_build_string_object (tree string)
1931 {
1932   tree initlist, constructor, constant_string_class;
1933   int length;
1934   tree fields, addr;
1935   struct string_descriptor *desc, key;
1936   void **loc;
1937
1938   /* Prep the string argument.  */
1939   string = fix_string_type (string);
1940   TREE_SET_CODE (string, STRING_CST);
1941   length = TREE_STRING_LENGTH (string) - 1;
1942
1943   /* Check whether the string class being used actually exists and has the
1944      correct ivar layout.  */
1945   if (!string_layout_checked)
1946     {
1947       string_layout_checked = -1;
1948       constant_string_class = lookup_interface (constant_string_id);
1949       internal_const_str_type = objc_build_internal_const_str_type ();
1950
1951       if (!constant_string_class
1952           || !(constant_string_type
1953                = CLASS_STATIC_TEMPLATE (constant_string_class)))
1954         error ("cannot find interface declaration for %qE",
1955                constant_string_id);
1956       /* The NSConstantString/NXConstantString ivar layout is now known.  */
1957       else if (!check_string_class_template ())
1958         error ("interface %qE does not have valid constant string layout",
1959                constant_string_id);
1960       /* For the NeXT runtime, we can generate a literal reference
1961          to the string class, don't need to run a constructor.  */
1962       else if (flag_next_runtime && !setup_string_decl ())
1963         error ("cannot find reference tag for class %qE",
1964                constant_string_id);
1965       else
1966         {
1967           string_layout_checked = 1;  /* Success!  */
1968           add_class_reference (constant_string_id);
1969         }
1970     }
1971
1972   if (string_layout_checked == -1)
1973     return error_mark_node;
1974
1975   /* Perhaps we already constructed a constant string just like this one? */
1976   key.literal = string;
1977   loc = htab_find_slot (string_htab, &key, INSERT);
1978   desc = (struct string_descriptor *) *loc;
1979
1980   if (!desc)
1981     {
1982       tree var;
1983       *loc = desc = GGC_NEW (struct string_descriptor);
1984       desc->literal = string;
1985
1986       /* GNU:    (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length })  */
1987       /* NeXT:   (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length })   */
1988       fields = TYPE_FIELDS (internal_const_str_type);
1989       initlist
1990         = build_tree_list (fields,
1991                            flag_next_runtime
1992                            ? build_unary_op (input_location,
1993                                              ADDR_EXPR, string_class_decl, 0)
1994                            : build_int_cst (NULL_TREE, 0));
1995       fields = TREE_CHAIN (fields);
1996       initlist = tree_cons (fields, build_unary_op (input_location,
1997                                                     ADDR_EXPR, string, 1),
1998                             initlist);
1999       fields = TREE_CHAIN (fields);
2000       initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
2001                             initlist);
2002       constructor = objc_build_constructor (internal_const_str_type,
2003                                             nreverse (initlist));
2004
2005       if (!flag_next_runtime)
2006         constructor
2007           = objc_add_static_instance (constructor, constant_string_type);
2008       else
2009         {
2010           var = build_decl (input_location,
2011                             CONST_DECL, NULL, TREE_TYPE (constructor));
2012           DECL_INITIAL (var) = constructor;
2013           TREE_STATIC (var) = 1;
2014           pushdecl_top_level (var);
2015           constructor = var;
2016         }
2017       desc->constructor = constructor;
2018     }
2019
2020   addr = convert (build_pointer_type (constant_string_type),
2021                   build_unary_op (input_location,
2022                                   ADDR_EXPR, desc->constructor, 1));
2023
2024   return addr;
2025 }
2026
2027 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR.  */
2028
2029 static GTY(()) int num_static_inst;
2030
2031 static tree
2032 objc_add_static_instance (tree constructor, tree class_decl)
2033 {
2034   tree *chain, decl;
2035   char buf[256];
2036
2037   /* Find the list of static instances for the CLASS_DECL.  Create one if
2038      not found.  */
2039   for (chain = &objc_static_instances;
2040        *chain && TREE_VALUE (*chain) != class_decl;
2041        chain = &TREE_CHAIN (*chain));
2042   if (!*chain)
2043     {
2044       *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
2045       add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2046     }
2047
2048   sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2049   decl = build_decl (input_location,
2050                      VAR_DECL, get_identifier (buf), class_decl);
2051   TREE_STATIC (decl) = 1;
2052   DECL_ARTIFICIAL (decl) = 1;
2053   TREE_USED (decl) = 1;
2054   DECL_INITIAL (decl) = constructor;
2055
2056   /* We may be writing something else just now.
2057      Postpone till end of input.  */
2058   DECL_DEFER_OUTPUT (decl) = 1;
2059   pushdecl_top_level (decl);
2060   rest_of_decl_compilation (decl, 1, 0);
2061
2062   /* Add the DECL to the head of this CLASS' list.  */
2063   TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2064
2065   return decl;
2066 }
2067
2068 /* Build a static constant CONSTRUCTOR
2069    with type TYPE and elements ELTS.  */
2070
2071 static tree
2072 objc_build_constructor (tree type, tree elts)
2073 {
2074   tree constructor = build_constructor_from_list (type, elts);
2075
2076   TREE_CONSTANT (constructor) = 1;
2077   TREE_STATIC (constructor) = 1;
2078   TREE_READONLY (constructor) = 1;
2079
2080 #ifdef OBJCPLUS
2081   /* Adjust for impedance mismatch.  We should figure out how to build
2082      CONSTRUCTORs that consistently please both the C and C++ gods.  */
2083   if (!TREE_PURPOSE (elts))
2084     TREE_TYPE (constructor) = init_list_type_node;
2085 #endif
2086
2087   return constructor;
2088 }
2089 \f
2090 /* Take care of defining and initializing _OBJC_SYMBOLS.  */
2091
2092 /* Predefine the following data type:
2093
2094    struct _objc_symtab
2095    {
2096      long sel_ref_cnt;
2097      SEL *refs;
2098      short cls_def_cnt;
2099      short cat_def_cnt;
2100      void *defs[cls_def_cnt + cat_def_cnt];
2101    }; */
2102
2103 static void
2104 build_objc_symtab_template (void)
2105 {
2106   tree field_decl, field_decl_chain;
2107
2108   objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
2109
2110   /* long sel_ref_cnt; */
2111   field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2112   field_decl_chain = field_decl;
2113
2114   /* SEL *refs; */
2115   field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2116                                   "refs");
2117   chainon (field_decl_chain, field_decl);
2118
2119   /* short cls_def_cnt; */
2120   field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2121   chainon (field_decl_chain, field_decl);
2122
2123   /* short cat_def_cnt; */
2124   field_decl = create_field_decl (short_integer_type_node,
2125                                   "cat_def_cnt");
2126   chainon (field_decl_chain, field_decl);
2127
2128   if (imp_count || cat_count || !flag_next_runtime)
2129     {
2130       /* void *defs[imp_count + cat_count (+ 1)]; */
2131       /* NB: The index is one less than the size of the array.  */
2132       int index = imp_count + cat_count
2133                 + (flag_next_runtime? -1: 0);
2134       field_decl = create_field_decl
2135                    (build_array_type
2136                     (ptr_type_node,
2137                      build_index_type (build_int_cst (NULL_TREE, index))),
2138                     "defs");
2139       chainon (field_decl_chain, field_decl);
2140     }
2141
2142   objc_finish_struct (objc_symtab_template, field_decl_chain);
2143 }
2144
2145 /* Create the initial value for the `defs' field of _objc_symtab.
2146    This is a CONSTRUCTOR.  */
2147
2148 static tree
2149 init_def_list (tree type)
2150 {
2151   tree expr, initlist = NULL_TREE;
2152   struct imp_entry *impent;
2153
2154   if (imp_count)
2155     for (impent = imp_list; impent; impent = impent->next)
2156       {
2157         if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2158           {
2159             expr = build_unary_op (input_location,
2160                                    ADDR_EXPR, impent->class_decl, 0);
2161             initlist = tree_cons (NULL_TREE, expr, initlist);
2162           }
2163       }
2164
2165   if (cat_count)
2166     for (impent = imp_list; impent; impent = impent->next)
2167       {
2168         if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2169           {
2170             expr = build_unary_op (input_location,
2171                                    ADDR_EXPR, impent->class_decl, 0);
2172             initlist = tree_cons (NULL_TREE, expr, initlist);
2173           }
2174       }
2175
2176   if (!flag_next_runtime)
2177     {
2178       /* statics = { ..., _OBJC_STATIC_INSTANCES, ... }  */
2179       tree expr;
2180
2181       if (static_instances_decl)
2182         expr = build_unary_op (input_location,
2183                                ADDR_EXPR, static_instances_decl, 0);
2184       else
2185         expr = build_int_cst (NULL_TREE, 0);
2186
2187       initlist = tree_cons (NULL_TREE, expr, initlist);
2188     }
2189
2190   return objc_build_constructor (type, nreverse (initlist));
2191 }
2192
2193 /* Construct the initial value for all of _objc_symtab.  */
2194
2195 static tree
2196 init_objc_symtab (tree type)
2197 {
2198   tree initlist;
2199
2200   /* sel_ref_cnt = { ..., 5, ... } */
2201
2202   initlist = build_tree_list (NULL_TREE,
2203                               build_int_cst (long_integer_type_node, 0));
2204
2205   /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2206
2207   if (flag_next_runtime || ! sel_ref_chain)
2208     initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2209   else
2210     initlist
2211       = tree_cons (NULL_TREE,
2212                    convert (build_pointer_type (objc_selector_type),
2213                             build_unary_op (input_location, ADDR_EXPR,
2214                                             UOBJC_SELECTOR_TABLE_decl, 1)),
2215                    initlist);
2216
2217   /* cls_def_cnt = { ..., 5, ... } */
2218
2219   initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2220
2221   /* cat_def_cnt = { ..., 5, ... } */
2222
2223   initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2224
2225   /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2226
2227   if (imp_count || cat_count || !flag_next_runtime)
2228     {
2229
2230       tree field = TYPE_FIELDS (type);
2231       field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2232
2233       initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2234                             initlist);
2235     }
2236
2237   return objc_build_constructor (type, nreverse (initlist));
2238 }
2239
2240 /* Generate forward declarations for metadata such as
2241   'OBJC_CLASS_...'.  */
2242
2243 static tree
2244 build_metadata_decl (const char *name, tree type)
2245 {
2246   tree decl;
2247
2248   /* struct TYPE NAME_<name>; */
2249   decl = start_var_decl (type, synth_id_with_class_suffix
2250                                (name,
2251                                 objc_implementation_context));
2252
2253   return decl;
2254 }
2255
2256 /* Push forward-declarations of all the categories so that
2257    init_def_list can use them in a CONSTRUCTOR.  */
2258
2259 static void
2260 forward_declare_categories (void)
2261 {
2262   struct imp_entry *impent;
2263   tree sav = objc_implementation_context;
2264
2265   for (impent = imp_list; impent; impent = impent->next)
2266     {
2267       if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2268         {
2269           /* Set an invisible arg to synth_id_with_class_suffix.  */
2270           objc_implementation_context = impent->imp_context;
2271           /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2272           impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2273                                                     objc_category_template);
2274         }
2275     }
2276   objc_implementation_context = sav;
2277 }
2278
2279 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2280    and initialized appropriately.  */
2281
2282 static void
2283 generate_objc_symtab_decl (void)
2284 {
2285   /* forward declare categories */
2286   if (cat_count)
2287     forward_declare_categories ();
2288
2289   build_objc_symtab_template ();
2290   UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2291   finish_var_decl (UOBJC_SYMBOLS_decl,
2292                    init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2293 }
2294 \f
2295 static tree
2296 init_module_descriptor (tree type)
2297 {
2298   tree initlist, expr;
2299
2300   /* version = { 1, ... } */
2301
2302   expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2303   initlist = build_tree_list (NULL_TREE, expr);
2304
2305   /* size = { ..., sizeof (struct _objc_module), ... } */
2306
2307   expr = convert (long_integer_type_node,
2308                   size_in_bytes (objc_module_template));
2309   initlist = tree_cons (NULL_TREE, expr, initlist);
2310
2311   /* Don't provide any file name for security reasons. */
2312   /* name = { ..., "", ... } */
2313
2314   expr = add_objc_string (get_identifier (""), class_names);
2315   initlist = tree_cons (NULL_TREE, expr, initlist);
2316
2317   /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2318
2319   if (UOBJC_SYMBOLS_decl)
2320     expr = build_unary_op (input_location,
2321                            ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2322   else
2323     expr = build_int_cst (NULL_TREE, 0);
2324   initlist = tree_cons (NULL_TREE, expr, initlist);
2325
2326   return objc_build_constructor (type, nreverse (initlist));
2327 }
2328
2329 /* Write out the data structures to describe Objective C classes defined.
2330
2331    struct _objc_module { ... } _OBJC_MODULE = { ... };   */
2332
2333 static void
2334 build_module_descriptor (void)
2335 {
2336   tree field_decl, field_decl_chain;
2337
2338 #ifdef OBJCPLUS
2339   push_lang_context (lang_name_c); /* extern "C" */
2340 #endif
2341
2342   objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
2343
2344   /* long version; */
2345   field_decl = create_field_decl (long_integer_type_node, "version");
2346   field_decl_chain = field_decl;
2347
2348   /* long size; */
2349   field_decl = create_field_decl (long_integer_type_node, "size");
2350   chainon (field_decl_chain, field_decl);
2351
2352   /* char *name; */
2353   field_decl = create_field_decl (string_type_node, "name");
2354   chainon (field_decl_chain, field_decl);
2355
2356   /* struct _objc_symtab *symtab; */
2357   field_decl
2358     = create_field_decl (build_pointer_type
2359                          (xref_tag (RECORD_TYPE,
2360                                     get_identifier (UTAG_SYMTAB))),
2361                          "symtab");
2362   chainon (field_decl_chain, field_decl);
2363
2364   objc_finish_struct (objc_module_template, field_decl_chain);
2365
2366   /* Create an instance of "_objc_module".  */
2367   UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2368   finish_var_decl (UOBJC_MODULES_decl,
2369                    init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2370
2371 #ifdef OBJCPLUS
2372   pop_lang_context ();
2373 #endif
2374 }
2375
2376 /* The GNU runtime requires us to provide a static initializer function
2377    for each module:
2378
2379    static void __objc_gnu_init (void) {
2380      __objc_exec_class (&L_OBJC_MODULES);
2381    }  */
2382
2383 static void
2384 build_module_initializer_routine (void)
2385 {
2386   tree body;
2387
2388 #ifdef OBJCPLUS
2389   push_lang_context (lang_name_c); /* extern "C" */
2390 #endif
2391
2392   objc_push_parm (build_decl (input_location,
2393                               PARM_DECL, NULL_TREE, void_type_node));
2394   objc_start_function (get_identifier (TAG_GNUINIT),
2395                        build_function_type (void_type_node,
2396                                             OBJC_VOID_AT_END),
2397                        NULL_TREE, objc_get_parm_info (0));
2398
2399   body = c_begin_compound_stmt (true);
2400   add_stmt (build_function_call
2401             (input_location,
2402              execclass_decl,
2403              build_tree_list
2404              (NULL_TREE,
2405               build_unary_op (input_location, ADDR_EXPR,
2406                               UOBJC_MODULES_decl, 0))));
2407   add_stmt (c_end_compound_stmt (input_location, body, true));
2408
2409   TREE_PUBLIC (current_function_decl) = 0;
2410
2411 #ifndef OBJCPLUS
2412   /* For Objective-C++, we will need to call __objc_gnu_init
2413      from objc_generate_static_init_call() below.  */
2414   DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2415 #endif
2416
2417   GNU_INIT_decl = current_function_decl;
2418   finish_function ();
2419
2420 #ifdef OBJCPLUS
2421     pop_lang_context ();
2422 #endif
2423 }
2424
2425 #ifdef OBJCPLUS
2426 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2427    to be called by the module initializer routine.  */
2428
2429 int
2430 objc_static_init_needed_p (void)
2431 {
2432   return (GNU_INIT_decl != NULL_TREE);
2433 }
2434
2435 /* Generate a call to the __objc_gnu_init initializer function.  */
2436
2437 tree
2438 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2439 {
2440   add_stmt (build_stmt (input_location, EXPR_STMT,
2441                         build_function_call (input_location,
2442                                              GNU_INIT_decl, NULL_TREE)));
2443
2444   return ctors;
2445 }
2446 #endif /* OBJCPLUS */
2447
2448 /* Return the DECL of the string IDENT in the SECTION.  */
2449
2450 static tree
2451 get_objc_string_decl (tree ident, enum string_section section)
2452 {
2453   tree chain;
2454
2455   if (section == class_names)
2456     chain = class_names_chain;
2457   else if (section == meth_var_names)
2458     chain = meth_var_names_chain;
2459   else if (section == meth_var_types)
2460     chain = meth_var_types_chain;
2461   else
2462     abort ();
2463
2464   for (; chain != 0; chain = TREE_CHAIN (chain))
2465     if (TREE_VALUE (chain) == ident)
2466       return (TREE_PURPOSE (chain));
2467
2468   abort ();
2469   return NULL_TREE;
2470 }
2471
2472 /* Output references to all statically allocated objects.  Return the DECL
2473    for the array built.  */
2474
2475 static void
2476 generate_static_references (void)
2477 {
2478   tree decls = NULL_TREE, expr = NULL_TREE;
2479   tree class_name, klass, decl, initlist;
2480   tree cl_chain, in_chain, type
2481     = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2482   int num_inst, num_class;
2483   char buf[256];
2484
2485   if (flag_next_runtime)
2486     abort ();
2487
2488   for (cl_chain = objc_static_instances, num_class = 0;
2489        cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2490     {
2491       for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2492            in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2493
2494       sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2495       decl = start_var_decl (type, buf);
2496
2497       /* Output {class_name, ...}.  */
2498       klass = TREE_VALUE (cl_chain);
2499       class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
2500       initlist = build_tree_list (NULL_TREE,
2501                                   build_unary_op (input_location, 
2502                                                   ADDR_EXPR, class_name, 1));
2503
2504       /* Output {..., instance, ...}.  */
2505       for (in_chain = TREE_PURPOSE (cl_chain);
2506            in_chain; in_chain = TREE_CHAIN (in_chain))
2507         {
2508           expr = build_unary_op (input_location,
2509                                  ADDR_EXPR, TREE_VALUE (in_chain), 1);
2510           initlist = tree_cons (NULL_TREE, expr, initlist);
2511         }
2512
2513       /* Output {..., NULL}.  */
2514       initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2515
2516       expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2517       finish_var_decl (decl, expr);
2518       decls
2519         = tree_cons (NULL_TREE, build_unary_op (input_location,
2520                                                 ADDR_EXPR, decl, 1), decls);
2521     }
2522
2523   decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2524   expr = objc_build_constructor (type, nreverse (decls));
2525   static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2526   finish_var_decl (static_instances_decl, expr);
2527 }
2528
2529 static GTY(()) int selector_reference_idx;
2530
2531 static tree
2532 build_selector_reference_decl (void)
2533 {
2534   tree decl;
2535   char buf[256];
2536
2537   sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2538   decl = start_var_decl (objc_selector_type, buf);
2539
2540   return decl;
2541 }
2542
2543 static void
2544 build_selector_table_decl (void)
2545 {
2546   tree temp;
2547
2548   if (flag_typed_selectors)
2549     {
2550       build_selector_template ();
2551       temp = build_array_type (objc_selector_template, NULL_TREE);
2552     }
2553   else
2554     temp = build_array_type (objc_selector_type, NULL_TREE);
2555
2556   UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2557 }
2558
2559 /* Just a handy wrapper for add_objc_string.  */
2560
2561 static tree
2562 build_selector (tree ident)
2563 {
2564   return convert (objc_selector_type,
2565                   add_objc_string (ident, meth_var_names));
2566 }
2567
2568 static void
2569 build_selector_translation_table (void)
2570 {
2571   tree chain, initlist = NULL_TREE;
2572   int offset = 0;
2573   tree decl = NULL_TREE;
2574
2575   for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2576     {
2577       tree expr;
2578
2579       if (warn_selector && objc_implementation_context)
2580       {
2581         tree method_chain;
2582         bool found = false;
2583         for (method_chain = meth_var_names_chain;
2584              method_chain;
2585              method_chain = TREE_CHAIN (method_chain))
2586           {
2587             if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2588               {
2589                 found = true;
2590                 break;
2591               }
2592           }
2593         if (!found)
2594           {
2595             location_t loc;
2596             if (flag_next_runtime && TREE_PURPOSE (chain))
2597               loc = DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2598             else
2599               loc = input_location;
2600             warning_at (loc, 0, "creating selector for nonexistent method %qE",
2601                         TREE_VALUE (chain));
2602           }
2603       }
2604
2605       expr = build_selector (TREE_VALUE (chain));
2606       /* add one for the '\0' character */
2607       offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2608
2609       if (flag_next_runtime)
2610         {
2611           decl = TREE_PURPOSE (chain);
2612           finish_var_decl (decl, expr);
2613         }
2614       else
2615         {
2616           if (flag_typed_selectors)
2617             {
2618               tree eltlist = NULL_TREE;
2619               tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2620               eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2621               eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2622               expr = objc_build_constructor (objc_selector_template,
2623                                              nreverse (eltlist));
2624             }
2625
2626           initlist = tree_cons (NULL_TREE, expr, initlist);
2627         }
2628     }
2629
2630   if (! flag_next_runtime)
2631     {
2632       /* Cause the selector table (previously forward-declared)
2633          to be actually output.  */
2634       initlist = tree_cons (NULL_TREE,
2635                             flag_typed_selectors
2636                             ? objc_build_constructor
2637                               (objc_selector_template,
2638                                tree_cons (NULL_TREE,
2639                                           build_int_cst (NULL_TREE, 0),
2640                                           tree_cons (NULL_TREE,
2641                                                      build_int_cst (NULL_TREE, 0),
2642                                                      NULL_TREE)))
2643                             : build_int_cst (NULL_TREE, 0), initlist);
2644       initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2645                                          nreverse (initlist));
2646       finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2647     }
2648 }
2649
2650 static tree
2651 get_proto_encoding (tree proto)
2652 {
2653   tree encoding;
2654   if (proto)
2655     {
2656       if (! METHOD_ENCODING (proto))
2657         {
2658           encoding = encode_method_prototype (proto);
2659           METHOD_ENCODING (proto) = encoding;
2660         }
2661       else
2662         encoding = METHOD_ENCODING (proto);
2663
2664       return add_objc_string (encoding, meth_var_types);
2665     }
2666   else
2667     return build_int_cst (NULL_TREE, 0);
2668 }
2669
2670 /* sel_ref_chain is a list whose "value" fields will be instances of
2671    identifier_node that represent the selector.  LOC is the location of
2672    the @selector.  */
2673
2674 static tree
2675 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
2676 {
2677   tree *chain = &sel_ref_chain;
2678   tree expr;
2679   int index = 0;
2680
2681   while (*chain)
2682     {
2683       if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2684         goto return_at_index;
2685
2686       index++;
2687       chain = &TREE_CHAIN (*chain);
2688     }
2689
2690   *chain = tree_cons (prototype, ident, NULL_TREE);
2691
2692  return_at_index:
2693   expr = build_unary_op (loc, ADDR_EXPR,
2694                          build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2695                                           build_int_cst (NULL_TREE, index)),
2696                          1);
2697   return convert (objc_selector_type, expr);
2698 }
2699
2700 static tree
2701 build_selector_reference (location_t loc, tree ident)
2702 {
2703   tree *chain = &sel_ref_chain;
2704   tree expr;
2705   int index = 0;
2706
2707   while (*chain)
2708     {
2709       if (TREE_VALUE (*chain) == ident)
2710         return (flag_next_runtime
2711                 ? TREE_PURPOSE (*chain)
2712                 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2713                                    build_int_cst (NULL_TREE, index)));
2714
2715       index++;
2716       chain = &TREE_CHAIN (*chain);
2717     }
2718
2719   expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2720
2721   *chain = tree_cons (expr, ident, NULL_TREE);
2722
2723   return (flag_next_runtime
2724           ? expr
2725           : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2726                              build_int_cst (NULL_TREE, index)));
2727 }
2728
2729 static GTY(()) int class_reference_idx;
2730
2731 static tree
2732 build_class_reference_decl (void)
2733 {
2734   tree decl;
2735   char buf[256];
2736
2737   sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2738   decl = start_var_decl (objc_class_type, buf);
2739
2740   return decl;
2741 }
2742
2743 /* Create a class reference, but don't create a variable to reference
2744    it.  */
2745
2746 static void
2747 add_class_reference (tree ident)
2748 {
2749   tree chain;
2750
2751   if ((chain = cls_ref_chain))
2752     {
2753       tree tail;
2754       do
2755         {
2756           if (ident == TREE_VALUE (chain))
2757             return;
2758
2759           tail = chain;
2760           chain = TREE_CHAIN (chain);
2761         }
2762       while (chain);
2763
2764       /* Append to the end of the list */
2765       TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2766     }
2767   else
2768     cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2769 }
2770
2771 /* Get a class reference, creating it if necessary.  Also create the
2772    reference variable.  */
2773
2774 tree
2775 objc_get_class_reference (tree ident)
2776 {
2777   tree orig_ident = (DECL_P (ident)
2778                      ? DECL_NAME (ident)
2779                      : TYPE_P (ident)
2780                      ? OBJC_TYPE_NAME (ident)
2781                      : ident);
2782   bool local_scope = false;
2783
2784 #ifdef OBJCPLUS
2785   if (processing_template_decl)
2786     /* Must wait until template instantiation time.  */
2787     return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2788 #endif
2789
2790   if (TREE_CODE (ident) == TYPE_DECL)
2791     ident = (DECL_ORIGINAL_TYPE (ident)
2792              ? DECL_ORIGINAL_TYPE (ident)
2793              : TREE_TYPE (ident));
2794
2795 #ifdef OBJCPLUS
2796   if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2797       && TYPE_CONTEXT (ident) != global_namespace)
2798     local_scope = true;
2799 #endif
2800
2801   if (local_scope || !(ident = objc_is_class_name (ident)))
2802     {
2803       error ("%qE is not an Objective-C class name or alias",
2804              orig_ident);
2805       return error_mark_node;
2806     }
2807
2808   if (flag_next_runtime && !flag_zero_link)
2809     {
2810       tree *chain;
2811       tree decl;
2812
2813       for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2814         if (TREE_VALUE (*chain) == ident)
2815           {
2816             if (! TREE_PURPOSE (*chain))
2817               TREE_PURPOSE (*chain) = build_class_reference_decl ();
2818
2819             return TREE_PURPOSE (*chain);
2820           }
2821
2822       decl = build_class_reference_decl ();
2823       *chain = tree_cons (decl, ident, NULL_TREE);
2824       return decl;
2825     }
2826   else
2827     {
2828       tree params;
2829
2830       add_class_reference (ident);
2831
2832       params = build_tree_list (NULL_TREE,
2833                                 my_build_string_pointer
2834                                 (IDENTIFIER_LENGTH (ident) + 1,
2835                                  IDENTIFIER_POINTER (ident)));
2836
2837       assemble_external (objc_get_class_decl);
2838       return build_function_call (input_location, objc_get_class_decl, params);
2839     }
2840 }
2841
2842 /* For each string section we have a chain which maps identifier nodes
2843    to decls for the strings.  */
2844
2845 static tree
2846 add_objc_string (tree ident, enum string_section section)
2847 {
2848   tree *chain, decl, type, string_expr;
2849
2850   if (section == class_names)
2851     chain = &class_names_chain;
2852   else if (section == meth_var_names)
2853     chain = &meth_var_names_chain;
2854   else if (section == meth_var_types)
2855     chain = &meth_var_types_chain;
2856   else
2857     abort ();
2858
2859   while (*chain)
2860     {
2861       if (TREE_VALUE (*chain) == ident)
2862         return convert (string_type_node,
2863                         build_unary_op (input_location,
2864                                         ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2865
2866       chain = &TREE_CHAIN (*chain);
2867     }
2868
2869   decl = build_objc_string_decl (section);
2870
2871   type = build_array_type
2872          (char_type_node,
2873           build_index_type
2874           (build_int_cst (NULL_TREE,
2875                           IDENTIFIER_LENGTH (ident))));
2876   decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2877   string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2878                                  IDENTIFIER_POINTER (ident));
2879   finish_var_decl (decl, string_expr);
2880
2881   *chain = tree_cons (decl, ident, NULL_TREE);
2882
2883   return convert (string_type_node, build_unary_op (input_location,
2884                                                     ADDR_EXPR, decl, 1));
2885 }
2886
2887 static GTY(()) int class_names_idx;
2888 static GTY(()) int meth_var_names_idx;
2889 static GTY(()) int meth_var_types_idx;
2890
2891 static tree
2892 build_objc_string_decl (enum string_section section)
2893 {
2894   tree decl, ident;
2895   char buf[256];
2896
2897   if (section == class_names)
2898     sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2899   else if (section == meth_var_names)
2900     sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2901   else if (section == meth_var_types)
2902     sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2903
2904   ident = get_identifier (buf);
2905
2906   decl = build_decl (input_location,
2907                      VAR_DECL, ident, build_array_type (char_type_node, 0));
2908   DECL_EXTERNAL (decl) = 1;
2909   TREE_PUBLIC (decl) = 0;
2910   TREE_USED (decl) = 1;
2911   TREE_CONSTANT (decl) = 1;
2912   DECL_CONTEXT (decl) = 0;
2913   DECL_ARTIFICIAL (decl) = 1;
2914 #ifdef OBJCPLUS
2915   DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2916 #endif
2917
2918   make_decl_rtl (decl);
2919   pushdecl_top_level (decl);
2920
2921   return decl;
2922 }
2923
2924
2925 void
2926 objc_declare_alias (tree alias_ident, tree class_ident)
2927 {
2928   tree underlying_class;
2929
2930 #ifdef OBJCPLUS
2931   if (current_namespace != global_namespace) {
2932     error ("Objective-C declarations may only appear in global scope");
2933   }
2934 #endif /* OBJCPLUS */
2935
2936   if (!(underlying_class = objc_is_class_name (class_ident)))
2937     warning (0, "cannot find class %qE", class_ident);
2938   else if (objc_is_class_name (alias_ident))
2939     warning (0, "class %qE already exists", alias_ident);
2940   else
2941     {
2942       /* Implement @compatibility_alias as a typedef.  */
2943 #ifdef OBJCPLUS
2944       push_lang_context (lang_name_c); /* extern "C" */
2945 #endif
2946       lang_hooks.decls.pushdecl (build_decl
2947                                  (input_location,
2948                                   TYPE_DECL,
2949                                   alias_ident,
2950                                   xref_tag (RECORD_TYPE, underlying_class)));
2951 #ifdef OBJCPLUS
2952       pop_lang_context ();
2953 #endif
2954       alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2955     }
2956 }
2957
2958 void
2959 objc_declare_class (tree ident_list)
2960 {
2961   tree list;
2962 #ifdef OBJCPLUS
2963   if (current_namespace != global_namespace) {
2964     error ("Objective-C declarations may only appear in global scope");
2965   }
2966 #endif /* OBJCPLUS */
2967
2968   for (list = ident_list; list; list = TREE_CHAIN (list))
2969     {
2970       tree ident = TREE_VALUE (list);
2971
2972       if (! objc_is_class_name (ident))
2973         {
2974           tree record = lookup_name (ident), type = record;
2975
2976           if (record)
2977             {
2978               if (TREE_CODE (record) == TYPE_DECL)
2979                 type = DECL_ORIGINAL_TYPE (record);
2980
2981               if (!TYPE_HAS_OBJC_INFO (type)
2982                   || !TYPE_OBJC_INTERFACE (type))
2983                 {
2984                   error ("%qE redeclared as different kind of symbol",
2985                          ident);
2986                   error ("previous declaration of %q+D",
2987                          record);
2988                 }
2989             }
2990
2991           record = xref_tag (RECORD_TYPE, ident);
2992           INIT_TYPE_OBJC_INFO (record);
2993           TYPE_OBJC_INTERFACE (record) = ident;
2994           class_chain = tree_cons (NULL_TREE, ident, class_chain);
2995         }
2996     }
2997 }
2998
2999 tree
3000 objc_is_class_name (tree ident)
3001 {
3002   tree chain;
3003
3004   if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
3005       && identifier_global_value (ident))
3006     ident = identifier_global_value (ident);
3007   while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
3008     ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
3009
3010   if (ident && TREE_CODE (ident) == RECORD_TYPE)
3011     ident = OBJC_TYPE_NAME (ident);
3012 #ifdef OBJCPLUS
3013   if (ident && TREE_CODE (ident) == TYPE_DECL)
3014     ident = DECL_NAME (ident);
3015 #endif
3016   if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
3017     return NULL_TREE;
3018
3019   if (lookup_interface (ident))
3020     return ident;
3021
3022   for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
3023     {
3024       if (ident == TREE_VALUE (chain))
3025         return ident;
3026     }
3027
3028   for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
3029     {
3030       if (ident == TREE_VALUE (chain))
3031         return TREE_PURPOSE (chain);
3032     }
3033
3034   return 0;
3035 }
3036
3037 /* Check whether TYPE is either 'id' or 'Class'.  */
3038
3039 tree
3040 objc_is_id (tree type)
3041 {
3042   if (type && TREE_CODE (type) == IDENTIFIER_NODE
3043       && identifier_global_value (type))
3044     type = identifier_global_value (type);
3045
3046   if (type && TREE_CODE (type) == TYPE_DECL)
3047     type = TREE_TYPE (type);
3048
3049   /* NB: This function may be called before the ObjC front-end has
3050      been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL.  */
3051   return (objc_object_type && type
3052           && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3053           ? type
3054           : NULL_TREE);
3055 }
3056
3057 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3058    class instance.  This is needed by other parts of the compiler to
3059    handle ObjC types gracefully.  */
3060
3061 tree
3062 objc_is_object_ptr (tree type)
3063 {
3064   tree ret;
3065
3066   type = TYPE_MAIN_VARIANT (type);
3067   if (!POINTER_TYPE_P (type))
3068     return 0;
3069
3070   ret = objc_is_id (type);
3071   if (!ret)
3072     ret = objc_is_class_name (TREE_TYPE (type));
3073
3074   return ret;
3075 }
3076
3077 static int
3078 objc_is_gcable_type (tree type, int or_strong_p)
3079 {
3080   tree name;
3081
3082   if (!TYPE_P (type))
3083     return 0;
3084   if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3085     return 1;
3086   if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3087     return 1;
3088   if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3089     return 0;
3090   type = TREE_TYPE (type);
3091   if (TREE_CODE (type) != RECORD_TYPE)
3092     return 0;
3093   name = TYPE_NAME (type);
3094   return (objc_is_class_name (name) != NULL_TREE);
3095 }
3096
3097 static tree
3098 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3099 {
3100   if (expr == oldexpr)
3101     return newexpr;
3102
3103   switch (TREE_CODE (expr))
3104     {
3105     case COMPONENT_REF:
3106       return objc_build_component_ref
3107              (objc_substitute_decl (TREE_OPERAND (expr, 0),
3108                                     oldexpr,
3109                                     newexpr),
3110               DECL_NAME (TREE_OPERAND (expr, 1)));
3111     case ARRAY_REF:
3112       return build_array_ref (input_location,
3113                               objc_substitute_decl (TREE_OPERAND (expr, 0),
3114                                                     oldexpr,
3115                                                     newexpr),
3116                               TREE_OPERAND (expr, 1));
3117     case INDIRECT_REF:
3118       return build_indirect_ref (input_location,
3119                                  objc_substitute_decl (TREE_OPERAND (expr, 0),
3120                                                        oldexpr,
3121                                                        newexpr), RO_ARROW);
3122     default:
3123       return expr;
3124     }
3125 }
3126
3127 static tree
3128 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3129 {
3130   tree func_params;
3131   /* The LHS parameter contains the expression 'outervar->memberspec';
3132      we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3133      where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3134   */
3135   tree offs
3136     = objc_substitute_decl
3137       (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3138   tree func
3139     = (flag_objc_direct_dispatch
3140        ? objc_assign_ivar_fast_decl
3141        : objc_assign_ivar_decl);
3142
3143   offs = convert (integer_type_node, build_unary_op (input_location,
3144                                                      ADDR_EXPR, offs, 0));
3145   offs = fold (offs);
3146   func_params = tree_cons (NULL_TREE,
3147         convert (objc_object_type, rhs),
3148             tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3149                 tree_cons (NULL_TREE, offs,
3150                     NULL_TREE)));
3151
3152   assemble_external (func);
3153   return build_function_call (input_location, func, func_params);
3154 }
3155
3156 static tree
3157 objc_build_global_assignment (tree lhs, tree rhs)
3158 {
3159   tree func_params = tree_cons (NULL_TREE,
3160         convert (objc_object_type, rhs),
3161             tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3162                       build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3163                     NULL_TREE));
3164
3165   assemble_external (objc_assign_global_decl);
3166   return build_function_call (input_location, 
3167                               objc_assign_global_decl, func_params);
3168 }
3169
3170 static tree
3171 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3172 {
3173   tree func_params = tree_cons (NULL_TREE,
3174         convert (objc_object_type, rhs),
3175             tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3176                       build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3177                     NULL_TREE));
3178
3179   assemble_external (objc_assign_strong_cast_decl);
3180   return build_function_call (input_location,
3181                               objc_assign_strong_cast_decl, func_params);
3182 }
3183
3184 static int
3185 objc_is_gcable_p (tree expr)
3186 {
3187   return (TREE_CODE (expr) == COMPONENT_REF
3188           ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3189           : TREE_CODE (expr) == ARRAY_REF
3190           ? (objc_is_gcable_p (TREE_TYPE (expr))
3191              || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3192           : TREE_CODE (expr) == ARRAY_TYPE
3193           ? objc_is_gcable_p (TREE_TYPE (expr))
3194           : TYPE_P (expr)
3195           ? objc_is_gcable_type (expr, 1)
3196           : (objc_is_gcable_p (TREE_TYPE (expr))
3197              || (DECL_P (expr)
3198                  && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3199 }
3200
3201 static int
3202 objc_is_ivar_reference_p (tree expr)
3203 {
3204   return (TREE_CODE (expr) == ARRAY_REF
3205           ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3206           : TREE_CODE (expr) == COMPONENT_REF
3207           ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3208           : 0);
3209 }
3210
3211 static int
3212 objc_is_global_reference_p (tree expr)
3213 {
3214   return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3215           ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3216           : DECL_P (expr)
3217           ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3218           : 0);
3219 }
3220
3221 tree
3222 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3223 {
3224   tree result = NULL_TREE, outer;
3225   int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3226
3227   /* See if we have any lhs casts, and strip them out.  NB: The lvalue casts
3228      will have been transformed to the form '*(type *)&expr'.  */
3229   if (TREE_CODE (lhs) == INDIRECT_REF)
3230     {
3231       outer = TREE_OPERAND (lhs, 0);
3232
3233       while (!strong_cast_p
3234              && (CONVERT_EXPR_P (outer)
3235                  || TREE_CODE (outer) == NON_LVALUE_EXPR))
3236         {
3237           tree lhstype = TREE_TYPE (outer);
3238
3239           /* Descend down the cast chain, and record the first objc_gc
3240              attribute found.  */
3241           if (POINTER_TYPE_P (lhstype))
3242             {
3243               tree attr
3244                 = lookup_attribute ("objc_gc",
3245                                     TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3246
3247               if (attr)
3248                 strong_cast_p = 1;
3249             }
3250
3251           outer = TREE_OPERAND (outer, 0);
3252         }
3253     }
3254
3255   /* If we have a __strong cast, it trumps all else.  */
3256   if (strong_cast_p)
3257     {
3258       if (modifycode != NOP_EXPR)
3259         goto invalid_pointer_arithmetic;
3260
3261       if (warn_assign_intercept)
3262         warning (0, "strong-cast assignment has been intercepted");
3263
3264       result = objc_build_strong_cast_assignment (lhs, rhs);
3265
3266       goto exit_point;
3267     }
3268
3269   /* the lhs must be of a suitable type, regardless of its underlying
3270      structure.  */
3271   if (!objc_is_gcable_p (lhs))
3272     goto exit_point;
3273
3274   outer = lhs;
3275
3276   while (outer
3277          && (TREE_CODE (outer) == COMPONENT_REF
3278              || TREE_CODE (outer) == ARRAY_REF))
3279     outer = TREE_OPERAND (outer, 0);
3280
3281   if (TREE_CODE (outer) == INDIRECT_REF)
3282     {
3283       outer = TREE_OPERAND (outer, 0);
3284       indirect_p = 1;
3285     }
3286
3287   outer_gc_p = objc_is_gcable_p (outer);
3288
3289   /* Handle ivar assignments. */
3290   if (objc_is_ivar_reference_p (lhs))
3291     {
3292       /* if the struct to the left of the ivar is not an Objective-C object (__strong
3293          doesn't cut it here), the best we can do here is suggest a cast.  */
3294       if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3295         {
3296           /* We may still be able to use the global write barrier... */
3297           if (!indirect_p && objc_is_global_reference_p (outer))
3298             goto global_reference;
3299
3300          suggest_cast:
3301           if (modifycode == NOP_EXPR)
3302             {
3303               if (warn_assign_intercept)
3304                 warning (0, "strong-cast may possibly be needed");
3305             }
3306
3307           goto exit_point;
3308         }
3309
3310       if (modifycode != NOP_EXPR)
3311         goto invalid_pointer_arithmetic;
3312
3313       if (warn_assign_intercept)
3314         warning (0, "instance variable assignment has been intercepted");
3315
3316       result = objc_build_ivar_assignment (outer, lhs, rhs);
3317
3318       goto exit_point;
3319     }
3320
3321   /* Likewise, intercept assignment to global/static variables if their type is
3322      GC-marked.  */
3323   if (objc_is_global_reference_p (outer))
3324     {
3325       if (indirect_p)
3326         goto suggest_cast;
3327
3328      global_reference:
3329       if (modifycode != NOP_EXPR)
3330         {
3331          invalid_pointer_arithmetic:
3332           if (outer_gc_p)
3333             warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3334
3335           goto exit_point;
3336         }
3337
3338       if (warn_assign_intercept)
3339         warning (0, "global/static variable assignment has been intercepted");
3340
3341       result = objc_build_global_assignment (lhs, rhs);
3342     }
3343
3344   /* In all other cases, fall back to the normal mechanism.  */
3345  exit_point:
3346   return result;
3347 }
3348
3349 struct GTY(()) interface_tuple {
3350   tree id;
3351   tree class_name;
3352 };
3353
3354 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3355
3356 static hashval_t
3357 hash_interface (const void *p)
3358 {
3359   const struct interface_tuple *d = (const struct interface_tuple *) p;
3360   return IDENTIFIER_HASH_VALUE (d->id);
3361 }
3362
3363 static int
3364 eq_interface (const void *p1, const void *p2)
3365 {
3366   const struct interface_tuple *d = (const struct interface_tuple *) p1;
3367   return d->id == p2;
3368 }
3369
3370 static tree
3371 lookup_interface (tree ident)
3372 {
3373 #ifdef OBJCPLUS
3374   if (ident && TREE_CODE (ident) == TYPE_DECL)
3375     ident = DECL_NAME (ident);
3376 #endif
3377
3378   if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3379     return NULL_TREE;
3380
3381   {
3382     struct interface_tuple **slot;
3383     tree i = NULL_TREE;
3384
3385     if (interface_htab)
3386       {
3387         slot = (struct interface_tuple **)
3388           htab_find_slot_with_hash (interface_htab, ident,
3389                                     IDENTIFIER_HASH_VALUE (ident),
3390                                     NO_INSERT);
3391         if (slot && *slot)
3392           i = (*slot)->class_name;
3393       }
3394     return i;
3395   }
3396 }
3397
3398 /* Implement @defs (<classname>) within struct bodies.  */
3399
3400 tree
3401 objc_get_class_ivars (tree class_name)
3402 {
3403   tree interface = lookup_interface (class_name);
3404
3405   if (interface)
3406     return get_class_ivars (interface, true);
3407
3408   error ("cannot find interface declaration for %qE",
3409          class_name);
3410
3411   return error_mark_node;
3412 }
3413
3414 /* Used by: build_private_template, continue_class,
3415    and for @defs constructs.  */
3416
3417 static tree
3418 get_class_ivars (tree interface, bool inherited)
3419 {
3420   tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3421
3422   /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3423      by the current class (i.e., they do not include super-class ivars).
3424      However, the CLASS_IVARS list will be side-effected by a call to
3425      finish_struct(), which will fill in field offsets.  */
3426   if (!CLASS_IVARS (interface))
3427     CLASS_IVARS (interface) = ivar_chain;
3428
3429   if (!inherited)
3430     return ivar_chain;
3431
3432   while (CLASS_SUPER_NAME (interface))
3433     {
3434       /* Prepend super-class ivars.  */
3435       interface = lookup_interface (CLASS_SUPER_NAME (interface));
3436       ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3437                             ivar_chain);
3438     }
3439
3440   return ivar_chain;
3441 }
3442
3443 static tree
3444 objc_create_temporary_var (tree type)
3445 {
3446   tree decl;
3447
3448   decl = build_decl (input_location,
3449                      VAR_DECL, NULL_TREE, type);
3450   TREE_USED (decl) = 1;
3451   DECL_ARTIFICIAL (decl) = 1;
3452   DECL_IGNORED_P (decl) = 1;
3453   DECL_CONTEXT (decl) = current_function_decl;
3454
3455   return decl;
3456 }
3457 \f
3458 /* Exception handling constructs.  We begin by having the parser do most
3459    of the work and passing us blocks.  What we do next depends on whether
3460    we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3461    We abstract all of this in a handful of appropriately named routines.  */
3462
3463 /* Stack of open try blocks.  */
3464
3465 struct objc_try_context
3466 {
3467   struct objc_try_context *outer;
3468
3469   /* Statements (or statement lists) as processed by the parser.  */
3470   tree try_body;
3471   tree finally_body;
3472
3473   /* Some file position locations.  */
3474   location_t try_locus;
3475   location_t end_try_locus;
3476   location_t end_catch_locus;
3477   location_t finally_locus;
3478   location_t end_finally_locus;
3479
3480   /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3481      of a TRY_CATCH_EXPR.  Even when doing Darwin setjmp.  */
3482   tree catch_list;
3483
3484   /* The CATCH_EXPR of an open @catch clause.  */
3485   tree current_catch;
3486
3487   /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer.  */
3488   tree caught_decl;
3489   tree stack_decl;
3490   tree rethrow_decl;
3491 };
3492
3493 static struct objc_try_context *cur_try_context;
3494
3495 static GTY(()) tree objc_eh_personality_decl;
3496
3497 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3498    that represents TYPE.  For Objective-C, this is just the class name.  */
3499 /* ??? Isn't there a class object or some such?  Is it easy to get?  */
3500
3501 #ifndef OBJCPLUS
3502 tree
3503 objc_eh_runtime_type (tree type)
3504 {
3505   return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3506 }
3507
3508 tree
3509 objc_eh_personality (void)
3510 {
3511   if (!flag_objc_sjlj_exceptions
3512       && !objc_eh_personality_decl)
3513     objc_eh_personality_decl
3514       = build_personality_function (USING_SJLJ_EXCEPTIONS
3515                                     ? "__gnu_objc_personality_sj0"
3516                                     : "__gnu_objc_personality_v0");
3517
3518   return objc_eh_personality_decl;
3519 }
3520 #endif
3521
3522 /* Build __builtin_eh_pointer, or the moral equivalent.  In the case
3523    of Darwin, we'll arrange for it to be initialized (and associated
3524    with a binding) later.  */
3525
3526 static tree
3527 objc_build_exc_ptr (void)
3528 {
3529   if (flag_objc_sjlj_exceptions)
3530     {
3531       tree var = cur_try_context->caught_decl;
3532       if (!var)
3533         {
3534           var = objc_create_temporary_var (objc_object_type);
3535           cur_try_context->caught_decl = var;
3536         }
3537       return var;
3538     }
3539   else
3540     {
3541       tree t;
3542       t = built_in_decls[BUILT_IN_EH_POINTER];
3543       t = build_call_expr (t, 1, integer_zero_node);
3544       return fold_convert (objc_object_type, t);
3545     }
3546 }
3547
3548 /* Build "objc_exception_try_exit(&_stack)".  */
3549
3550 static tree
3551 next_sjlj_build_try_exit (void)
3552 {
3553   tree t;
3554   t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3555   t = tree_cons (NULL, t, NULL);
3556   t = build_function_call (input_location,
3557                            objc_exception_try_exit_decl, t);
3558   return t;
3559 }
3560
3561 /* Build
3562         objc_exception_try_enter (&_stack);
3563         if (_setjmp(&_stack.buf))
3564           ;
3565         else
3566           ;
3567    Return the COND_EXPR.  Note that the THEN and ELSE fields are left
3568    empty, ready for the caller to fill them in.  */
3569
3570 static tree
3571 next_sjlj_build_enter_and_setjmp (void)
3572 {
3573   tree t, enter, sj, cond;
3574
3575   t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3576   t = tree_cons (NULL, t, NULL);
3577   enter = build_function_call (input_location,
3578                                objc_exception_try_enter_decl, t);
3579
3580   t = objc_build_component_ref (cur_try_context->stack_decl,
3581                                 get_identifier ("buf"));
3582   t = build_fold_addr_expr_loc (input_location, t);
3583 #ifdef OBJCPLUS
3584   /* Convert _setjmp argument to type that is expected.  */
3585   if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3586     t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3587   else
3588     t = convert (ptr_type_node, t);
3589 #else
3590   t = convert (ptr_type_node, t);
3591 #endif
3592   t = tree_cons (NULL, t, NULL);
3593   sj = build_function_call (input_location,
3594                             objc_setjmp_decl, t);
3595
3596   cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3597   cond = c_common_truthvalue_conversion (input_location, cond);
3598
3599   return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3600 }
3601
3602 /* Build:
3603
3604    DECL = objc_exception_extract(&_stack);  */
3605
3606 static tree
3607 next_sjlj_build_exc_extract (tree decl)
3608 {
3609   tree t;
3610
3611   t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3612   t = tree_cons (NULL, t, NULL);
3613   t = build_function_call (input_location,
3614                            objc_exception_extract_decl, t);
3615   t = convert (TREE_TYPE (decl), t);
3616   t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3617
3618   return t;
3619 }
3620
3621 /* Build
3622         if (objc_exception_match(obj_get_class(TYPE), _caught)
3623           BODY
3624         else if (...)
3625           ...
3626         else
3627           {
3628             _rethrow = _caught;
3629             objc_exception_try_exit(&_stack);
3630           }
3631    from the sequence of CATCH_EXPRs in the current try context.  */
3632
3633 static tree
3634 next_sjlj_build_catch_list (void)
3635 {
3636   tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3637   tree catch_seq, t;
3638   tree *last = &catch_seq;
3639   bool saw_id = false;
3640
3641   for (; !tsi_end_p (i); tsi_next (&i))
3642     {
3643       tree stmt = tsi_stmt (i);
3644       tree type = CATCH_TYPES (stmt);
3645       tree body = CATCH_BODY (stmt);
3646
3647       if (type == NULL)
3648         {
3649           *last = body;
3650           saw_id = true;
3651           break;
3652         }
3653       else
3654         {
3655           tree args, cond;
3656
3657           if (type == error_mark_node)
3658             cond = error_mark_node;
3659           else
3660             {
3661               args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3662               t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3663               args = tree_cons (NULL, t, args);
3664               t = build_function_call (input_location,
3665                                        objc_exception_match_decl, args);
3666               cond = c_common_truthvalue_conversion (input_location, t);
3667             }
3668           t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3669           SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
3670
3671           *last = t;
3672           last = &COND_EXPR_ELSE (t);
3673         }
3674     }
3675
3676   if (!saw_id)
3677     {
3678       t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3679                   cur_try_context->caught_decl);
3680       SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3681       append_to_statement_list (t, last);
3682
3683       t = next_sjlj_build_try_exit ();
3684       SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3685       append_to_statement_list (t, last);
3686     }
3687
3688   return catch_seq;
3689 }
3690
3691 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3692    exception handling.  We aim to build:
3693
3694         {
3695           struct _objc_exception_data _stack;
3696           id _rethrow = 0;
3697           try
3698             {
3699               objc_exception_try_enter (&_stack);
3700               if (_setjmp(&_stack.buf))
3701                 {
3702                   id _caught = objc_exception_extract(&_stack);
3703                   objc_exception_try_enter (&_stack);
3704                   if (_setjmp(&_stack.buf))
3705                     _rethrow = objc_exception_extract(&_stack);
3706                   else
3707                     CATCH-LIST
3708                 }
3709               else
3710                 TRY-BLOCK
3711             }
3712           finally
3713             {
3714               if (!_rethrow)
3715                 objc_exception_try_exit(&_stack);
3716               FINALLY-BLOCK
3717               if (_rethrow)
3718                 objc_exception_throw(_rethrow);
3719             }
3720         }
3721
3722    If CATCH-LIST is empty, we can omit all of the block containing
3723    "_caught" except for the setting of _rethrow.  Note the use of
3724    a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3725    but handles goto and other exits from the block.  */
3726
3727 static tree
3728 next_sjlj_build_try_catch_finally (void)
3729 {
3730   tree rethrow_decl, stack_decl, t;
3731   tree catch_seq, try_fin, bind;
3732
3733   /* Create the declarations involved.  */
3734   t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3735   stack_decl = objc_create_temporary_var (t);
3736   cur_try_context->stack_decl = stack_decl;
3737
3738   rethrow_decl = objc_create_temporary_var (objc_object_type);
3739   cur_try_context->rethrow_decl = rethrow_decl;
3740   TREE_CHAIN (rethrow_decl) = stack_decl;
3741
3742   /* Build the outermost variable binding level.  */
3743   bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3744   SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3745   TREE_SIDE_EFFECTS (bind) = 1;
3746
3747   /* Initialize rethrow_decl.  */
3748   t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3749               convert (objc_object_type, null_pointer_node));
3750   SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3751   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3752
3753   /* Build the outermost TRY_FINALLY_EXPR.  */
3754   try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3755   SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3756   TREE_SIDE_EFFECTS (try_fin) = 1;
3757   append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3758
3759   /* Create the complete catch sequence.  */
3760   if (cur_try_context->catch_list)
3761     {
3762       tree caught_decl = objc_build_exc_ptr ();
3763       catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
3764       TREE_SIDE_EFFECTS (catch_seq) = 1;
3765
3766       t = next_sjlj_build_exc_extract (caught_decl);
3767       append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3768
3769       t = next_sjlj_build_enter_and_setjmp ();
3770       COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3771       COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3772       append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3773     }
3774   else
3775     catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3776   SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3777
3778   /* Build the main register-and-try if statement.  */
3779   t = next_sjlj_build_enter_and_setjmp ();
3780   SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3781   COND_EXPR_THEN (t) = catch_seq;
3782   COND_EXPR_ELSE (t) = cur_try_context->try_body;
3783   TREE_OPERAND (try_fin, 0) = t;
3784
3785   /* Build the complete FINALLY statement list.  */
3786   t = next_sjlj_build_try_exit ();
3787   t = build_stmt (input_location, COND_EXPR,
3788                   c_common_truthvalue_conversion 
3789                     (input_location, rethrow_decl),
3790                   NULL, t);
3791   SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3792   append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3793
3794   append_to_statement_list (cur_try_context->finally_body,
3795                             &TREE_OPERAND (try_fin, 1));
3796
3797   t = tree_cons (NULL, rethrow_decl, NULL);
3798   t = build_function_call (input_location,
3799                            objc_exception_throw_decl, t);
3800   t = build_stmt (input_location, COND_EXPR,
3801                   c_common_truthvalue_conversion (input_location, 
3802                                                   rethrow_decl),
3803                   t, NULL);
3804   SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3805   append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3806
3807   return bind;
3808 }
3809
3810 /* Called just after parsing the @try and its associated BODY.  We now
3811    must prepare for the tricky bits -- handling the catches and finally.  */
3812
3813 void
3814 objc_begin_try_stmt (location_t try_locus, tree body)
3815 {
3816   struct objc_try_context *c = XCNEW (struct objc_try_context);
3817   c->outer = cur_try_context;
3818   c->try_body = body;
3819   c->try_locus = try_locus;
3820   c->end_try_locus = input_location;
3821   cur_try_context = c;
3822
3823   if (flag_objc_sjlj_exceptions)
3824     {
3825       /* On Darwin, ObjC exceptions require a sufficiently recent
3826          version of the runtime, so the user must ask for them explicitly.  */
3827       if (!flag_objc_exceptions)
3828         warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3829                  "exception syntax");
3830     }
3831
3832   if (flag_objc_sjlj_exceptions)
3833     objc_mark_locals_volatile (NULL);
3834 }
3835
3836 /* Called just after parsing "@catch (parm)".  Open a binding level,
3837    enter DECL into the binding level, and initialize it.  Leave the
3838    binding level open while the body of the compound statement is parsed.  */
3839
3840 void
3841 objc_begin_catch_clause (tree decl)
3842 {
3843   tree compound, type, t;
3844
3845   /* Begin a new scope that the entire catch clause will live in.  */
3846   compound = c_begin_compound_stmt (true);
3847
3848   /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL.  */
3849   decl = build_decl (input_location,
3850                      VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3851   lang_hooks.decls.pushdecl (decl);
3852
3853   /* Since a decl is required here by syntax, don't warn if its unused.  */
3854   /* ??? As opposed to __attribute__((unused))?  Anyway, this appears to
3855      be what the previous objc implementation did.  */
3856   TREE_USED (decl) = 1;
3857
3858   /* Verify that the type of the catch is valid.  It must be a pointer
3859      to an Objective-C class, or "id" (which is catch-all).  */
3860   type = TREE_TYPE (decl);
3861
3862   if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3863     type = NULL;
3864   else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3865     {
3866       error ("@catch parameter is not a known Objective-C class type");
3867       type = error_mark_node;
3868     }
3869   else if (cur_try_context->catch_list)
3870     {
3871       /* Examine previous @catch clauses and see if we've already
3872          caught the type in question.  */
3873       tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3874       for (; !tsi_end_p (i); tsi_next (&i))
3875         {
3876           tree stmt = tsi_stmt (i);
3877           t = CATCH_TYPES (stmt);
3878           if (t == error_mark_node)
3879             continue;
3880           if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3881             {
3882               warning (0, "exception of type %<%T%> will be caught",
3883                        TREE_TYPE (type));
3884               warning_at  (EXPR_LOCATION (stmt), 0, "   by earlier handler for %<%T%>",
3885                            TREE_TYPE (t ? t : objc_object_type));
3886               break;
3887             }
3888         }
3889     }
3890
3891   /* Record the data for the catch in the try context so that we can
3892      finalize it later.  */
3893   t = build_stmt (input_location, CATCH_EXPR, type, compound);
3894   cur_try_context->current_catch = t;
3895
3896   /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime.  */
3897   t = objc_build_exc_ptr ();
3898   t = convert (TREE_TYPE (decl), t);
3899   t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3900   add_stmt (t);
3901 }
3902
3903 /* Called just after parsing the closing brace of a @catch clause.  Close
3904    the open binding level, and record a CATCH_EXPR for it.  */
3905
3906 void
3907 objc_finish_catch_clause (void)
3908 {
3909   tree c = cur_try_context->current_catch;
3910   cur_try_context->current_catch = NULL;
3911   cur_try_context->end_catch_locus = input_location;
3912
3913   CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
3914   append_to_statement_list (c, &cur_try_context->catch_list);
3915 }
3916
3917 /* Called after parsing a @finally clause and its associated BODY.
3918    Record the body for later placement.  */
3919
3920 void
3921 objc_build_finally_clause (location_t finally_locus, tree body)
3922 {
3923   cur_try_context->finally_body = body;
3924   cur_try_context->finally_locus = finally_locus;
3925   cur_try_context->end_finally_locus = input_location;
3926 }
3927
3928 /* Called to finalize a @try construct.  */
3929
3930 tree
3931 objc_finish_try_stmt (void)
3932 {
3933   struct objc_try_context *c = cur_try_context;
3934   tree stmt;
3935
3936   if (c->catch_list == NULL && c->finally_body == NULL)
3937     error ("%<@try%> without %<@catch%> or %<@finally%>");
3938
3939   /* If we're doing Darwin setjmp exceptions, build the big nasty.  */
3940   if (flag_objc_sjlj_exceptions)
3941     {
3942       bool save = in_late_binary_op;
3943       in_late_binary_op = true;
3944       if (!cur_try_context->finally_body)
3945         {
3946           cur_try_context->finally_locus = input_location;
3947           cur_try_context->end_finally_locus = input_location;
3948         }
3949       stmt = next_sjlj_build_try_catch_finally ();
3950       in_late_binary_op = save;
3951     }
3952   else
3953     {
3954       /* Otherwise, nest the CATCH inside a FINALLY.  */
3955       stmt = c->try_body;
3956       if (c->catch_list)
3957         {
3958           stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
3959           SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3960         }
3961       if (c->finally_body)
3962         {
3963           stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
3964           SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3965         }
3966     }
3967   add_stmt (stmt);
3968
3969   cur_try_context = c->outer;
3970   free (c);
3971   return stmt;
3972 }
3973
3974 tree
3975 objc_build_throw_stmt (location_t loc, tree throw_expr)
3976 {
3977   tree args;
3978
3979   if (flag_objc_sjlj_exceptions)
3980     {
3981       /* On Darwin, ObjC exceptions require a sufficiently recent
3982          version of the runtime, so the user must ask for them explicitly.  */
3983       if (!flag_objc_exceptions)
3984         warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3985                  "exception syntax");
3986     }
3987
3988   if (throw_expr == NULL)
3989     {
3990       /* If we're not inside a @catch block, there is no "current
3991          exception" to be rethrown.  */
3992       if (cur_try_context == NULL
3993           || cur_try_context->current_catch == NULL)
3994         {
3995           error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
3996           return NULL_TREE;
3997         }
3998
3999       /* Otherwise the object is still sitting in the EXC_PTR_EXPR
4000          value that we get from the runtime.  */
4001       throw_expr = objc_build_exc_ptr ();
4002     }
4003
4004   /* A throw is just a call to the runtime throw function with the
4005      object as a parameter.  */
4006   args = tree_cons (NULL, throw_expr, NULL);
4007   return add_stmt (build_function_call (loc,
4008                                         objc_exception_throw_decl, args));
4009 }
4010
4011 tree
4012 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
4013 {
4014   tree args, call;
4015
4016   /* First lock the mutex.  */
4017   mutex = save_expr (mutex);
4018   args = tree_cons (NULL, mutex, NULL);
4019   call = build_function_call (input_location,
4020                               objc_sync_enter_decl, args);
4021   SET_EXPR_LOCATION (call, start_locus);
4022   add_stmt (call);
4023
4024   /* Build the mutex unlock.  */
4025   args = tree_cons (NULL, mutex, NULL);
4026   call = build_function_call (input_location,
4027                               objc_sync_exit_decl, args);
4028   SET_EXPR_LOCATION (call, input_location);
4029
4030   /* Put the that and the body in a TRY_FINALLY.  */
4031   objc_begin_try_stmt (start_locus, body);
4032   objc_build_finally_clause (input_location, call);
4033   return objc_finish_try_stmt ();
4034 }
4035
4036 \f
4037 /* Predefine the following data type:
4038
4039    struct _objc_exception_data
4040    {
4041      int buf[OBJC_JBLEN];
4042      void *pointers[4];
4043    }; */
4044
4045 /* The following yuckiness should prevent users from having to #include
4046    <setjmp.h> in their code... */
4047
4048 /* Define to a harmless positive value so the below code doesn't die.  */
4049 #ifndef OBJC_JBLEN
4050 #define OBJC_JBLEN 18
4051 #endif
4052
4053 static void
4054 build_next_objc_exception_stuff (void)
4055 {
4056   tree field_decl, field_decl_chain, index, temp_type;
4057
4058   objc_exception_data_template
4059     = objc_start_struct (get_identifier (UTAG_EXCDATA));
4060
4061   /* int buf[OBJC_JBLEN]; */
4062
4063   index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
4064   field_decl = create_field_decl (build_array_type (integer_type_node, index),
4065                                   "buf");
4066   field_decl_chain = field_decl;
4067
4068   /* void *pointers[4]; */
4069
4070   index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
4071   field_decl = create_field_decl (build_array_type (ptr_type_node, index),
4072                                   "pointers");
4073   chainon (field_decl_chain, field_decl);
4074
4075   objc_finish_struct (objc_exception_data_template, field_decl_chain);
4076
4077   /* int _setjmp(...); */
4078   /* If the user includes <setjmp.h>, this shall be superseded by
4079      'int _setjmp(jmp_buf);' */
4080   temp_type = build_function_type (integer_type_node, NULL_TREE);
4081   objc_setjmp_decl
4082     = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4083
4084   /* id objc_exception_extract(struct _objc_exception_data *); */
4085   temp_type
4086     = build_function_type (objc_object_type,
4087                            tree_cons (NULL_TREE,
4088                                       build_pointer_type (objc_exception_data_template),
4089                                       OBJC_VOID_AT_END));
4090   objc_exception_extract_decl
4091     = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4092                             NULL_TREE);
4093   /* void objc_exception_try_enter(struct _objc_exception_data *); */
4094   /* void objc_exception_try_exit(struct _objc_exception_data *); */
4095   temp_type
4096     = build_function_type (void_type_node,
4097                            tree_cons (NULL_TREE,
4098                                       build_pointer_type (objc_exception_data_template),
4099                                       OBJC_VOID_AT_END));
4100   objc_exception_try_enter_decl
4101     = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4102                             NULL_TREE);
4103   objc_exception_try_exit_decl
4104     = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4105                             NULL_TREE);
4106
4107   /* int objc_exception_match(id, id); */
4108   temp_type
4109     = build_function_type (integer_type_node,
4110                            tree_cons (NULL_TREE, objc_object_type,
4111                                       tree_cons (NULL_TREE, objc_object_type,
4112                                                  OBJC_VOID_AT_END)));
4113   objc_exception_match_decl
4114     = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4115                             NULL_TREE);
4116
4117   /* id objc_assign_ivar (id, id, unsigned int); */
4118   /* id objc_assign_ivar_Fast (id, id, unsigned int)
4119        __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4120   temp_type
4121     = build_function_type (objc_object_type,
4122                            tree_cons
4123                            (NULL_TREE, objc_object_type,
4124                             tree_cons (NULL_TREE, objc_object_type,
4125                                        tree_cons (NULL_TREE,
4126                                                   unsigned_type_node,
4127                                                   OBJC_VOID_AT_END))));
4128   objc_assign_ivar_decl
4129     = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4130                             NULL, NULL_TREE);
4131 #ifdef OFFS_ASSIGNIVAR_FAST
4132   objc_assign_ivar_fast_decl
4133     = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4134                             NOT_BUILT_IN, NULL, NULL_TREE);
4135   DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4136     = tree_cons (get_identifier ("hard_coded_address"),
4137                  build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4138                  NULL_TREE);
4139 #else
4140   /* Default to slower ivar method.  */
4141   objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4142 #endif
4143
4144   /* id objc_assign_global (id, id *); */
4145   /* id objc_assign_strongCast (id, id *); */
4146   temp_type = build_function_type (objc_object_type,
4147                 tree_cons (NULL_TREE, objc_object_type,
4148                     tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4149                         OBJC_VOID_AT_END)));
4150   objc_assign_global_decl
4151         = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4152                                 NULL_TREE);
4153   objc_assign_strong_cast_decl
4154         = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4155                                 NULL_TREE);
4156 }
4157
4158 static void
4159 build_objc_exception_stuff (void)
4160 {
4161   tree noreturn_list, nothrow_list, temp_type;
4162
4163   noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4164   nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4165
4166   /* void objc_exception_throw(id) __attribute__((noreturn)); */
4167   /* void objc_sync_enter(id); */
4168   /* void objc_sync_exit(id); */
4169   temp_type = build_function_type (void_type_node,
4170                                    tree_cons (NULL_TREE, objc_object_type,
4171                                               OBJC_VOID_AT_END));
4172   objc_exception_throw_decl
4173     = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4174                             noreturn_list);
4175   objc_sync_enter_decl
4176     = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4177                             NULL, nothrow_list);
4178   objc_sync_exit_decl
4179     = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4180                             NULL, nothrow_list);
4181 }
4182
4183 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4184    name as the class:
4185
4186    struct <classname> {
4187      struct _objc_class *isa;
4188      ...
4189    };  */
4190
4191 static void
4192 build_private_template (tree klass)
4193 {
4194   if (!CLASS_STATIC_TEMPLATE (klass))
4195     {
4196       tree record = objc_build_struct (klass,
4197                                        get_class_ivars (klass, false),
4198                                        CLASS_SUPER_NAME (klass));
4199
4200       /* Set the TREE_USED bit for this struct, so that stab generator
4201          can emit stabs for this struct type.  */
4202       if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4203         TREE_USED (TYPE_STUB_DECL (record)) = 1;
4204     }
4205 }
4206 \f
4207 /* Begin code generation for protocols...  */
4208
4209 /* struct _objc_protocol {
4210      struct _objc_class *isa;
4211      char *protocol_name;
4212      struct _objc_protocol **protocol_list;
4213      struct _objc__method_prototype_list *instance_methods;
4214      struct _objc__method_prototype_list *class_methods;
4215    };  */
4216
4217 static void
4218 build_protocol_template (void)
4219 {
4220   tree field_decl, field_decl_chain;
4221
4222   objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
4223
4224   /* struct _objc_class *isa; */
4225   field_decl = create_field_decl (build_pointer_type
4226                                   (xref_tag (RECORD_TYPE,
4227                                              get_identifier (UTAG_CLASS))),
4228                                   "isa");
4229   field_decl_chain = field_decl;
4230
4231   /* char *protocol_name; */
4232   field_decl = create_field_decl (string_type_node, "protocol_name");
4233   chainon (field_decl_chain, field_decl);
4234
4235   /* struct _objc_protocol **protocol_list; */
4236   field_decl = create_field_decl (build_pointer_type
4237                                   (build_pointer_type
4238                                    (objc_protocol_template)),
4239                                   "protocol_list");
4240   chainon (field_decl_chain, field_decl);
4241
4242   /* struct _objc__method_prototype_list *instance_methods; */
4243   field_decl = create_field_decl (objc_method_proto_list_ptr,
4244                                   "instance_methods");
4245   chainon (field_decl_chain, field_decl);
4246
4247   /* struct _objc__method_prototype_list *class_methods; */
4248   field_decl = create_field_decl (objc_method_proto_list_ptr,
4249                                   "class_methods");
4250   chainon (field_decl_chain, field_decl);
4251
4252   objc_finish_struct (objc_protocol_template, field_decl_chain);
4253 }
4254
4255 static tree
4256 build_descriptor_table_initializer (tree type, tree entries)
4257 {
4258   tree initlist = NULL_TREE;
4259
4260   do
4261     {
4262       tree eltlist = NULL_TREE;
4263
4264       eltlist
4265         = tree_cons (NULL_TREE,
4266                      build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4267       eltlist
4268         = tree_cons (NULL_TREE,
4269                      add_objc_string (METHOD_ENCODING (entries),
4270                                       meth_var_types),
4271                      eltlist);
4272
4273       initlist
4274         = tree_cons (NULL_TREE,
4275                      objc_build_constructor (type, nreverse (eltlist)),
4276                      initlist);
4277
4278       entries = TREE_CHAIN (entries);
4279     }
4280   while (entries);
4281
4282   return objc_build_constructor (build_array_type (type, 0),
4283                                  nreverse (initlist));
4284 }
4285
4286 /* struct objc_method_prototype_list {
4287      int count;
4288      struct objc_method_prototype {
4289         SEL name;
4290         char *types;
4291      } list[1];
4292    };  */
4293
4294 static tree
4295 build_method_prototype_list_template (tree list_type, int size)
4296 {
4297   tree objc_ivar_list_record;
4298   tree field_decl, field_decl_chain;
4299
4300   /* Generate an unnamed struct definition.  */
4301
4302   objc_ivar_list_record = objc_start_struct (NULL_TREE);
4303
4304   /* int method_count; */
4305   field_decl = create_field_decl (integer_type_node, "method_count");
4306   field_decl_chain = field_decl;
4307
4308   /* struct objc_method method_list[]; */
4309   field_decl = create_field_decl (build_array_type
4310                                   (list_type,
4311                                    build_index_type
4312                                    (build_int_cst (NULL_TREE, size - 1))),
4313                                   "method_list");
4314   chainon (field_decl_chain, field_decl);
4315
4316   objc_finish_struct (objc_ivar_list_record, field_decl_chain);
4317
4318   return objc_ivar_list_record;
4319 }
4320
4321 static tree
4322 build_method_prototype_template (void)
4323 {
4324   tree proto_record;
4325   tree field_decl, field_decl_chain;
4326
4327   proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
4328
4329   /* SEL _cmd; */
4330   field_decl = create_field_decl (objc_selector_type, "_cmd");
4331   field_decl_chain = field_decl;
4332
4333   /* char *method_types; */
4334   field_decl = create_field_decl (string_type_node, "method_types");
4335   chainon (field_decl_chain, field_decl);
4336
4337   objc_finish_struct (proto_record, field_decl_chain);
4338
4339   return proto_record;
4340 }
4341
4342 static tree
4343 objc_method_parm_type (tree type)
4344 {
4345   type = TREE_VALUE (TREE_TYPE (type));
4346   if (TREE_CODE (type) == TYPE_DECL)
4347     type = TREE_TYPE (type);
4348   return type;
4349 }
4350
4351 static int
4352 objc_encoded_type_size (tree type)
4353 {
4354   int sz = int_size_in_bytes (type);
4355
4356   /* Make all integer and enum types at least as large
4357      as an int.  */
4358   if (sz > 0 && INTEGRAL_TYPE_P (type))
4359     sz = MAX (sz, int_size_in_bytes (integer_type_node));
4360   /* Treat arrays as pointers, since that's how they're
4361      passed in.  */
4362   else if (TREE_CODE (type) == ARRAY_TYPE)
4363     sz = int_size_in_bytes (ptr_type_node);
4364   return sz;
4365 }
4366
4367 static tree
4368 encode_method_prototype (tree method_decl)
4369 {
4370   tree parms;
4371   int parm_offset, i;
4372   char buf[40];
4373   tree result;
4374
4375   /* ONEWAY and BYCOPY, for remote object are the only method qualifiers.  */
4376   encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4377
4378   /* Encode return type.  */
4379   encode_type (objc_method_parm_type (method_decl),
4380                obstack_object_size (&util_obstack),
4381                OBJC_ENCODE_INLINE_DEFS);
4382
4383   /* Stack size.  */
4384   /* The first two arguments (self and _cmd) are pointers; account for
4385      their size.  */
4386   i = int_size_in_bytes (ptr_type_node);
4387   parm_offset = 2 * i;
4388   for (parms = METHOD_SEL_ARGS (method_decl); parms;
4389        parms = TREE_CHAIN (parms))
4390     {
4391       tree type = objc_method_parm_type (parms);
4392       int sz = objc_encoded_type_size (type);
4393
4394       /* If a type size is not known, bail out.  */
4395       if (sz < 0)
4396         {
4397           error ("type %q+D does not have a known size",
4398                  type);
4399           /* Pretend that the encoding succeeded; the compilation will
4400              fail nevertheless.  */
4401           goto finish_encoding;
4402         }
4403       parm_offset += sz;
4404     }
4405
4406   sprintf (buf, "%d@0:%d", parm_offset, i);
4407   obstack_grow (&util_obstack, buf, strlen (buf));
4408
4409   /* Argument types.  */
4410   parm_offset = 2 * i;
4411   for (parms = METHOD_SEL_ARGS (method_decl); parms;
4412        parms = TREE_CHAIN (parms))
4413     {
4414       tree type = objc_method_parm_type (parms);
4415
4416       /* Process argument qualifiers for user supplied arguments.  */
4417       encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4418
4419       /* Type.  */
4420       encode_type (type, obstack_object_size (&util_obstack),
4421                    OBJC_ENCODE_INLINE_DEFS);
4422
4423       /* Compute offset.  */
4424       sprintf (buf, "%d", parm_offset);
4425       parm_offset += objc_encoded_type_size (type);
4426
4427       obstack_grow (&util_obstack, buf, strlen (buf));
4428     }
4429
4430   finish_encoding:
4431   obstack_1grow (&util_obstack, '\0');
4432   result = get_identifier (XOBFINISH (&util_obstack, char *));
4433   obstack_free (&util_obstack, util_firstobj);
4434   return result;
4435 }
4436
4437 static tree
4438 generate_descriptor_table (tree type, const char *name, int size, tree list,
4439                            tree proto)
4440 {
4441   tree decl, initlist;
4442
4443   decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4444
4445   initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4446   initlist = tree_cons (NULL_TREE, list, initlist);
4447
4448   finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4449
4450   return decl;
4451 }
4452
4453 static void
4454 generate_method_descriptors (tree protocol)
4455 {
4456   tree initlist, chain, method_list_template;
4457   int size;
4458
4459   if (!objc_method_prototype_template)
4460     objc_method_prototype_template = build_method_prototype_template ();
4461
4462   chain = PROTOCOL_CLS_METHODS (protocol);
4463   if (chain)
4464     {
4465       size = list_length (chain);
4466
4467       method_list_template
4468         = build_method_prototype_list_template (objc_method_prototype_template,
4469                                                 size);
4470
4471       initlist
4472         = build_descriptor_table_initializer (objc_method_prototype_template,
4473                                               chain);
4474
4475       UOBJC_CLASS_METHODS_decl
4476         = generate_descriptor_table (method_list_template,
4477                                      "_OBJC_PROTOCOL_CLASS_METHODS",
4478                                      size, initlist, protocol);
4479     }
4480   else
4481     UOBJC_CLASS_METHODS_decl = 0;
4482
4483   chain = PROTOCOL_NST_METHODS (protocol);
4484   if (chain)
4485     {
4486       size = list_length (chain);
4487
4488       method_list_template
4489         = build_method_prototype_list_template (objc_method_prototype_template,
4490                                                 size);
4491       initlist
4492         = build_descriptor_table_initializer (objc_method_prototype_template,
4493                                               chain);
4494
4495       UOBJC_INSTANCE_METHODS_decl
4496         = generate_descriptor_table (method_list_template,
4497                                      "_OBJC_PROTOCOL_INSTANCE_METHODS",
4498                                      size, initlist, protocol);
4499     }
4500   else
4501     UOBJC_INSTANCE_METHODS_decl = 0;
4502 }
4503
4504 static void
4505 generate_protocol_references (tree plist)
4506 {
4507   tree lproto;
4508
4509   /* Forward declare protocols referenced.  */
4510   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4511     {
4512       tree proto = TREE_VALUE (lproto);
4513
4514       if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4515           && PROTOCOL_NAME (proto))
4516         {
4517           if (! PROTOCOL_FORWARD_DECL (proto))
4518             build_protocol_reference (proto);
4519
4520           if (PROTOCOL_LIST (proto))
4521             generate_protocol_references (PROTOCOL_LIST (proto));
4522         }
4523     }
4524 }
4525
4526 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4527    current class.  */
4528 #ifdef OBJCPLUS
4529 static void
4530 objc_generate_cxx_ctor_or_dtor (bool dtor)
4531 {
4532   tree fn, body, compound_stmt, ivar;
4533
4534   /* - (id) .cxx_construct { ... return self; } */
4535   /* - (void) .cxx_construct { ... }            */
4536
4537   objc_set_method_type (MINUS_EXPR);
4538   objc_start_method_definition
4539    (objc_build_method_signature (build_tree_list (NULL_TREE,
4540                                                   dtor
4541                                                   ? void_type_node
4542                                                   : objc_object_type),
4543                                  get_identifier (dtor
4544                                                  ? TAG_CXX_DESTRUCT
4545                                                  : TAG_CXX_CONSTRUCT),
4546                                  make_node (TREE_LIST),
4547                                  false));
4548   body = begin_function_body ();
4549   compound_stmt = begin_compound_stmt (0);
4550
4551   ivar = CLASS_IVARS (implementation_template);
4552   /* Destroy ivars in reverse order.  */
4553   if (dtor)
4554     ivar = nreverse (copy_list (ivar));
4555
4556   for (; ivar; ivar = TREE_CHAIN (ivar))
4557     {
4558       if (TREE_CODE (ivar) == FIELD_DECL)
4559         {
4560           tree type = TREE_TYPE (ivar);
4561
4562           /* Call the ivar's default constructor or destructor.  Do not
4563              call the destructor unless a corresponding constructor call
4564              has also been made (or is not needed).  */
4565           if (MAYBE_CLASS_TYPE_P (type)
4566               && (dtor
4567                   ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4568                      && (!TYPE_NEEDS_CONSTRUCTING (type)
4569                          || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4570                   : (TYPE_NEEDS_CONSTRUCTING (type)
4571                      && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4572             finish_expr_stmt
4573              (build_special_member_call
4574               (build_ivar_reference (DECL_NAME (ivar)),
4575                dtor ? complete_dtor_identifier : complete_ctor_identifier,
4576                NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
4577         }
4578     }
4579
4580   /* The constructor returns 'self'.  */
4581   if (!dtor)
4582     finish_return_stmt (self_decl);
4583
4584   finish_compound_stmt (compound_stmt);
4585   finish_function_body (body);
4586   fn = current_function_decl;
4587   finish_function ();
4588   objc_finish_method_definition (fn);
4589 }
4590
4591 /* The following routine will examine the current @interface for any
4592    non-POD C++ ivars requiring non-trivial construction and/or
4593    destruction, and then synthesize special '- .cxx_construct' and/or
4594    '- .cxx_destruct' methods which will run the appropriate
4595    construction or destruction code.  Note that ivars inherited from
4596    super-classes are _not_ considered.  */
4597 static void
4598 objc_generate_cxx_cdtors (void)
4599 {
4600   bool need_ctor = false, need_dtor = false;
4601   tree ivar;
4602
4603   /* We do not want to do this for categories, since they do not have
4604      their own ivars.  */
4605
4606   if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4607     return;
4608
4609   /* First, determine if we even need a constructor and/or destructor.  */
4610
4611   for (ivar = CLASS_IVARS (implementation_template); ivar;
4612        ivar = TREE_CHAIN (ivar))
4613     {
4614       if (TREE_CODE (ivar) == FIELD_DECL)
4615         {
4616           tree type = TREE_TYPE (ivar);
4617
4618           if (MAYBE_CLASS_TYPE_P (type))
4619             {
4620               if (TYPE_NEEDS_CONSTRUCTING (type)
4621                   && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4622                 /* NB: If a default constructor is not available, we will not
4623                    be able to initialize this ivar; the add_instance_variable()
4624                    routine will already have warned about this.  */
4625                 need_ctor = true;
4626
4627               if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4628                   && (!TYPE_NEEDS_CONSTRUCTING (type)
4629                       || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4630                 /* NB: If a default constructor is not available, we will not
4631                    call the destructor either, for symmetry.  */
4632                 need_dtor = true;
4633             }
4634         }
4635     }
4636
4637   /* Generate '- .cxx_construct' if needed.  */
4638
4639   if (need_ctor)
4640     objc_generate_cxx_ctor_or_dtor (false);
4641
4642   /* Generate '- .cxx_destruct' if needed.  */
4643
4644   if (need_dtor)
4645     objc_generate_cxx_ctor_or_dtor (true);
4646
4647   /* The 'imp_list' variable points at an imp_entry record for the current
4648      @implementation.  Record the existence of '- .cxx_construct' and/or
4649      '- .cxx_destruct' methods therein; it will be included in the
4650      metadata for the class.  */
4651   if (flag_next_runtime)
4652     imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4653 }
4654 #endif
4655
4656 /* For each protocol which was referenced either from a @protocol()
4657    expression, or because a class/category implements it (then a
4658    pointer to the protocol is stored in the struct describing the
4659    class/category), we create a statically allocated instance of the
4660    Protocol class.  The code is written in such a way as to generate
4661    as few Protocol objects as possible; we generate a unique Protocol
4662    instance for each protocol, and we don't generate a Protocol
4663    instance if the protocol is never referenced (either from a
4664    @protocol() or from a class/category implementation).  These
4665    statically allocated objects can be referred to via the static
4666    (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4667
4668    The statically allocated Protocol objects that we generate here
4669    need to be fixed up at runtime in order to be used: the 'isa'
4670    pointer of the objects need to be set up to point to the 'Protocol'
4671    class, as known at runtime.
4672
4673    The NeXT runtime fixes up all protocols at program startup time,
4674    before main() is entered.  It uses a low-level trick to look up all
4675    those symbols, then loops on them and fixes them up.
4676
4677    The GNU runtime as well fixes up all protocols before user code
4678    from the module is executed; it requires pointers to those symbols
4679    to be put in the objc_symtab (which is then passed as argument to
4680    the function __objc_exec_class() which the compiler sets up to be
4681    executed automatically when the module is loaded); setup of those
4682    Protocol objects happen in two ways in the GNU runtime: all
4683    Protocol objects referred to by a class or category implementation
4684    are fixed up when the class/category is loaded; all Protocol
4685    objects referred to by a @protocol() expression are added by the
4686    compiler to the list of statically allocated instances to fixup
4687    (the same list holding the statically allocated constant string
4688    objects).  Because, as explained above, the compiler generates as
4689    few Protocol objects as possible, some Protocol object might end up
4690    being referenced multiple times when compiled with the GNU runtime,
4691    and end up being fixed up multiple times at runtime initialization.
4692    But that doesn't hurt, it's just a little inefficient.  */
4693
4694 static void
4695 generate_protocols (void)
4696 {
4697   tree p, encoding;
4698   tree decl;
4699   tree initlist, protocol_name_expr, refs_decl, refs_expr;
4700
4701   /* If a protocol was directly referenced, pull in indirect references.  */
4702   for (p = protocol_chain; p; p = TREE_CHAIN (p))
4703     if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4704       generate_protocol_references (PROTOCOL_LIST (p));
4705
4706   for (p = protocol_chain; p; p = TREE_CHAIN (p))
4707     {
4708       tree nst_methods = PROTOCOL_NST_METHODS (p);
4709       tree cls_methods = PROTOCOL_CLS_METHODS (p);
4710
4711       /* If protocol wasn't referenced, don't generate any code.  */
4712       decl = PROTOCOL_FORWARD_DECL (p);
4713
4714       if (!decl)
4715         continue;
4716
4717       /* Make sure we link in the Protocol class.  */
4718       add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4719
4720       while (nst_methods)
4721         {
4722           if (! METHOD_ENCODING (nst_methods))
4723             {
4724               encoding = encode_method_prototype (nst_methods);
4725               METHOD_ENCODING (nst_methods) = encoding;
4726             }
4727           nst_methods = TREE_CHAIN (nst_methods);
4728         }
4729
4730       while (cls_methods)
4731         {
4732           if (! METHOD_ENCODING (cls_methods))
4733             {
4734               encoding = encode_method_prototype (cls_methods);
4735               METHOD_ENCODING (cls_methods) = encoding;
4736             }
4737
4738           cls_methods = TREE_CHAIN (cls_methods);
4739         }
4740       generate_method_descriptors (p);
4741
4742       if (PROTOCOL_LIST (p))
4743         refs_decl = generate_protocol_list (p);
4744       else
4745         refs_decl = 0;
4746
4747       /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4748       protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4749
4750       if (refs_decl)
4751         refs_expr = convert (build_pointer_type (build_pointer_type
4752                                                  (objc_protocol_template)),
4753                              build_unary_op (input_location,
4754                                              ADDR_EXPR, refs_decl, 0));
4755       else
4756         refs_expr = build_int_cst (NULL_TREE, 0);
4757
4758       /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4759          by generate_method_descriptors, which is called above.  */
4760       initlist = build_protocol_initializer (TREE_TYPE (decl),
4761                                              protocol_name_expr, refs_expr,
4762                                              UOBJC_INSTANCE_METHODS_decl,
4763                                              UOBJC_CLASS_METHODS_decl);
4764       finish_var_decl (decl, initlist);
4765     }
4766 }
4767
4768 static tree
4769 build_protocol_initializer (tree type, tree protocol_name,
4770                             tree protocol_list, tree instance_methods,
4771                             tree class_methods)
4772 {
4773   tree initlist = NULL_TREE, expr;
4774   tree cast_type = build_pointer_type
4775                    (xref_tag (RECORD_TYPE,
4776                               get_identifier (UTAG_CLASS)));
4777
4778   /* Filling the "isa" in with one allows the runtime system to
4779      detect that the version change...should remove before final release.  */
4780
4781   expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4782   initlist = tree_cons (NULL_TREE, expr, initlist);
4783   initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4784   initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4785
4786   if (!instance_methods)
4787     initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4788   else
4789     {
4790       expr = convert (objc_method_proto_list_ptr,
4791                       build_unary_op (input_location, 
4792                                       ADDR_EXPR, instance_methods, 0));
4793       initlist = tree_cons (NULL_TREE, expr, initlist);
4794     }
4795
4796   if (!class_methods)
4797     initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4798   else
4799     {
4800       expr = convert (objc_method_proto_list_ptr,
4801                       build_unary_op (input_location, 
4802                                       ADDR_EXPR, class_methods, 0));
4803       initlist = tree_cons (NULL_TREE, expr, initlist);
4804     }
4805
4806   return objc_build_constructor (type, nreverse (initlist));
4807 }
4808 \f
4809 /* struct _objc_category {
4810      char *category_name;
4811      char *class_name;
4812      struct _objc_method_list *instance_methods;
4813      struct _objc_method_list *class_methods;
4814      struct _objc_protocol_list *protocols;
4815    };   */
4816
4817 static void
4818 build_category_template (void)
4819 {
4820   tree field_decl, field_decl_chain;
4821
4822   objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
4823
4824   /* char *category_name; */
4825   field_decl = create_field_decl (string_type_node, "category_name");
4826   field_decl_chain = field_decl;
4827
4828   /* char *class_name; */
4829   field_decl = create_field_decl (string_type_node, "class_name");
4830   chainon (field_decl_chain, field_decl);
4831
4832   /* struct _objc_method_list *instance_methods; */
4833   field_decl = create_field_decl (objc_method_list_ptr,
4834                                   "instance_methods");
4835   chainon (field_decl_chain, field_decl);
4836
4837   /* struct _objc_method_list *class_methods; */
4838   field_decl = create_field_decl (objc_method_list_ptr,
4839                                   "class_methods");
4840   chainon (field_decl_chain, field_decl);
4841
4842   /* struct _objc_protocol **protocol_list; */
4843   field_decl = create_field_decl (build_pointer_type
4844                                   (build_pointer_type
4845                                    (objc_protocol_template)),
4846                                   "protocol_list");
4847   chainon (field_decl_chain, field_decl);
4848
4849   objc_finish_struct (objc_category_template, field_decl_chain);
4850 }
4851
4852 /* struct _objc_selector {
4853      SEL sel_id;
4854      char *sel_type;
4855    }; */
4856
4857 static void
4858 build_selector_template (void)
4859 {
4860   tree field_decl, field_decl_chain;
4861
4862   objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
4863
4864   /* SEL sel_id; */
4865   field_decl = create_field_decl (objc_selector_type, "sel_id");
4866   field_decl_chain = field_decl;
4867
4868   /* char *sel_type; */
4869   field_decl = create_field_decl (string_type_node, "sel_type");
4870   chainon (field_decl_chain, field_decl);
4871
4872   objc_finish_struct (objc_selector_template, field_decl_chain);
4873 }
4874
4875 /* struct _objc_class {
4876      struct _objc_class *isa;
4877      struct _objc_class *super_class;
4878      char *name;
4879      long version;
4880      long info;
4881      long instance_size;
4882      struct _objc_ivar_list *ivars;
4883      struct _objc_method_list *methods;
4884      #ifdef __NEXT_RUNTIME__
4885        struct objc_cache *cache;
4886      #else
4887        struct sarray *dtable;
4888        struct _objc_class *subclass_list;
4889        struct _objc_class *sibling_class;
4890      #endif
4891      struct _objc_protocol_list *protocols;
4892      #ifdef __NEXT_RUNTIME__
4893        void *sel_id;
4894      #endif
4895      void *gc_object_type;
4896    };  */
4897
4898 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4899    the NeXT/Apple runtime; still, the compiler must generate them to
4900    maintain backward binary compatibility (and to allow for future
4901    expansion).  */
4902
4903 static void
4904 build_class_template (void)
4905 {
4906   tree field_decl, field_decl_chain;
4907
4908   objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
4909
4910   /* struct _objc_class *isa; */
4911   field_decl = create_field_decl (build_pointer_type (objc_class_template),
4912                                   "isa");
4913   field_decl_chain = field_decl;
4914
4915   /* struct _objc_class *super_class; */
4916   field_decl = create_field_decl (build_pointer_type (objc_class_template),
4917                                   "super_class");
4918   chainon (field_decl_chain, field_decl);
4919
4920   /* char *name; */
4921   field_decl = create_field_decl (string_type_node, "name");
4922   chainon (field_decl_chain, field_decl);
4923
4924   /* long version; */
4925   field_decl = create_field_decl (long_integer_type_node, "version");
4926   chainon (field_decl_chain, field_decl);
4927
4928   /* long info; */
4929   field_decl = create_field_decl (long_integer_type_node, "info");
4930   chainon (field_decl_chain, field_decl);
4931
4932   /* long instance_size; */
4933   field_decl = create_field_decl (long_integer_type_node, "instance_size");
4934   chainon (field_decl_chain, field_decl);
4935
4936   /* struct _objc_ivar_list *ivars; */
4937   field_decl = create_field_decl (objc_ivar_list_ptr,
4938                                   "ivars");
4939   chainon (field_decl_chain, field_decl);
4940
4941   /* struct _objc_method_list *methods; */
4942   field_decl = create_field_decl (objc_method_list_ptr,
4943                                   "methods");
4944   chainon (field_decl_chain, field_decl);
4945
4946   if (flag_next_runtime)
4947     {
4948       /* struct objc_cache *cache; */
4949       field_decl = create_field_decl (build_pointer_type
4950                                       (xref_tag (RECORD_TYPE,
4951                                                  get_identifier
4952                                                  ("objc_cache"))),
4953                                       "cache");
4954       chainon (field_decl_chain, field_decl);
4955     }
4956   else
4957     {
4958       /* struct sarray *dtable; */
4959       field_decl = create_field_decl (build_pointer_type
4960                                       (xref_tag (RECORD_TYPE,
4961                                                  get_identifier
4962                                                  ("sarray"))),
4963                                       "dtable");
4964       chainon (field_decl_chain, field_decl);
4965
4966       /* struct objc_class *subclass_list; */
4967       field_decl = create_field_decl (build_pointer_type
4968                                       (objc_class_template),
4969                                       "subclass_list");
4970       chainon (field_decl_chain, field_decl);
4971
4972       /* struct objc_class *sibling_class; */
4973       field_decl = create_field_decl (build_pointer_type
4974                                       (objc_class_template),
4975                                       "sibling_class");
4976       chainon (field_decl_chain, field_decl);
4977     }
4978
4979   /* struct _objc_protocol **protocol_list; */
4980   field_decl = create_field_decl (build_pointer_type
4981                                   (build_pointer_type
4982                                    (xref_tag (RECORD_TYPE,
4983                                              get_identifier
4984                                              (UTAG_PROTOCOL)))),
4985                                   "protocol_list");
4986   chainon (field_decl_chain, field_decl);
4987
4988   if (flag_next_runtime)
4989     {
4990       /* void *sel_id; */
4991       field_decl = create_field_decl (build_pointer_type (void_type_node),
4992                                       "sel_id");
4993       chainon (field_decl_chain, field_decl);
4994     }
4995
4996   /* void *gc_object_type; */
4997   field_decl = create_field_decl (build_pointer_type (void_type_node),
4998                                   "gc_object_type");
4999   chainon (field_decl_chain, field_decl);
5000
5001   objc_finish_struct (objc_class_template, field_decl_chain);
5002 }
5003
5004 /* Generate appropriate forward declarations for an implementation.  */
5005
5006 static void
5007 synth_forward_declarations (void)
5008 {
5009   tree an_id;
5010
5011   /* static struct objc_class _OBJC_CLASS_<my_name>; */
5012   UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
5013                                           objc_class_template);
5014
5015   /* static struct objc_class _OBJC_METACLASS_<my_name>; */
5016   UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
5017                                                   objc_class_template);
5018
5019   /* Pre-build the following entities - for speed/convenience.  */
5020
5021   an_id = get_identifier ("super_class");
5022   ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
5023   uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
5024 }
5025
5026 static void
5027 error_with_ivar (const char *message, tree decl)
5028 {
5029   error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
5030             message, identifier_to_locale (gen_declaration (decl)));
5031
5032 }
5033
5034 static void
5035 check_ivars (tree inter, tree imp)
5036 {
5037   tree intdecls = CLASS_RAW_IVARS (inter);
5038   tree impdecls = CLASS_RAW_IVARS (imp);
5039
5040   while (1)
5041     {
5042       tree t1, t2;
5043
5044 #ifdef OBJCPLUS
5045       if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
5046         intdecls = TREE_CHAIN (intdecls);
5047 #endif
5048       if (intdecls == 0 && impdecls == 0)
5049         break;
5050       if (intdecls == 0 || impdecls == 0)
5051         {
5052           error ("inconsistent instance variable specification");
5053           break;
5054         }
5055
5056       t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
5057
5058       if (!comptypes (t1, t2)
5059           || !tree_int_cst_equal (DECL_INITIAL (intdecls),
5060                                   DECL_INITIAL (impdecls)))
5061         {
5062           if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
5063             {
5064               error_with_ivar ("conflicting instance variable type",
5065                                impdecls);
5066               error_with_ivar ("previous declaration of",
5067                                intdecls);
5068             }
5069           else                  /* both the type and the name don't match */
5070             {
5071               error ("inconsistent instance variable specification");
5072               break;
5073             }
5074         }
5075
5076       else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5077         {
5078           error_with_ivar ("conflicting instance variable name",
5079                            impdecls);
5080           error_with_ivar ("previous declaration of",
5081                            intdecls);
5082         }
5083
5084       intdecls = TREE_CHAIN (intdecls);
5085       impdecls = TREE_CHAIN (impdecls);
5086     }
5087 }
5088
5089 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5090    This needs to be done just once per compilation.  */
5091
5092 /* struct _objc_super {
5093      struct _objc_object *self;
5094      struct _objc_class *super_class;
5095    };  */
5096
5097 static void
5098 build_super_template (void)
5099 {
5100   tree field_decl, field_decl_chain;
5101
5102   objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
5103
5104   /* struct _objc_object *self; */
5105   field_decl = create_field_decl (objc_object_type, "self");
5106   field_decl_chain = field_decl;
5107
5108   /* struct _objc_class *super_class; */
5109   field_decl = create_field_decl (build_pointer_type (objc_class_template),
5110                                   "super_class");
5111   chainon (field_decl_chain, field_decl);
5112
5113   objc_finish_struct (objc_super_template, field_decl_chain);
5114 }
5115
5116 /* struct _objc_ivar {
5117      char *ivar_name;
5118      char *ivar_type;
5119      int ivar_offset;
5120    };  */
5121
5122 static tree
5123 build_ivar_template (void)
5124 {
5125   tree objc_ivar_id, objc_ivar_record;
5126   tree field_decl, field_decl_chain;
5127
5128   objc_ivar_id = get_identifier (UTAG_IVAR);
5129   objc_ivar_record = objc_start_struct (objc_ivar_id);
5130
5131   /* char *ivar_name; */
5132   field_decl = create_field_decl (string_type_node, "ivar_name");
5133   field_decl_chain = field_decl;
5134
5135   /* char *ivar_type; */
5136   field_decl = create_field_decl (string_type_node, "ivar_type");
5137   chainon (field_decl_chain, field_decl);
5138
5139   /* int ivar_offset; */
5140   field_decl = create_field_decl (integer_type_node, "ivar_offset");
5141   chainon (field_decl_chain, field_decl);
5142
5143   objc_finish_struct (objc_ivar_record, field_decl_chain);
5144
5145   return objc_ivar_record;
5146 }
5147
5148 /* struct {
5149      int ivar_count;
5150      struct objc_ivar ivar_list[ivar_count];
5151    };  */
5152
5153 static tree
5154 build_ivar_list_template (tree list_type, int size)
5155 {
5156   tree objc_ivar_list_record;
5157   tree field_decl, field_decl_chain;
5158
5159   objc_ivar_list_record = objc_start_struct (NULL_TREE);
5160
5161   /* int ivar_count; */
5162   field_decl = create_field_decl (integer_type_node, "ivar_count");
5163   field_decl_chain = field_decl;
5164
5165   /* struct objc_ivar ivar_list[]; */
5166   field_decl = create_field_decl (build_array_type
5167                                   (list_type,
5168                                    build_index_type
5169                                    (build_int_cst (NULL_TREE, size - 1))),
5170                                   "ivar_list");
5171   chainon (field_decl_chain, field_decl);
5172
5173   objc_finish_struct (objc_ivar_list_record, field_decl_chain);
5174
5175   return objc_ivar_list_record;
5176 }
5177
5178 /* struct {
5179      struct _objc__method_prototype_list *method_next;
5180      int method_count;
5181      struct objc_method method_list[method_count];
5182    };  */
5183
5184 static tree
5185 build_method_list_template (tree list_type, int size)
5186 {
5187   tree objc_ivar_list_record;
5188   tree field_decl, field_decl_chain;
5189
5190   objc_ivar_list_record = objc_start_struct (NULL_TREE);
5191
5192   /* struct _objc__method_prototype_list *method_next; */
5193   field_decl = create_field_decl (objc_method_proto_list_ptr,
5194                                   "method_next");
5195   field_decl_chain = field_decl;
5196
5197   /* int method_count; */
5198   field_decl = create_field_decl (integer_type_node, "method_count");
5199   chainon (field_decl_chain, field_decl);
5200
5201   /* struct objc_method method_list[]; */
5202   field_decl = create_field_decl (build_array_type
5203                                   (list_type,
5204                                    build_index_type
5205                                    (build_int_cst (NULL_TREE, size - 1))),
5206                                   "method_list");
5207   chainon (field_decl_chain, field_decl);
5208
5209   objc_finish_struct (objc_ivar_list_record, field_decl_chain);
5210
5211   return objc_ivar_list_record;
5212 }
5213
5214 static tree
5215 build_ivar_list_initializer (tree type, tree field_decl)
5216 {
5217   tree initlist = NULL_TREE;
5218
5219   do
5220     {
5221       tree ivar = NULL_TREE;
5222
5223       /* Set name.  */
5224       if (DECL_NAME (field_decl))
5225         ivar = tree_cons (NULL_TREE,
5226                           add_objc_string (DECL_NAME (field_decl),
5227                                            meth_var_names),
5228                           ivar);
5229       else
5230         /* Unnamed bit-field ivar (yuck).  */
5231         ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5232
5233       /* Set type.  */
5234       encode_field_decl (field_decl,
5235                          obstack_object_size (&util_obstack),
5236                          OBJC_ENCODE_DONT_INLINE_DEFS);
5237
5238       /* Null terminate string.  */
5239       obstack_1grow (&util_obstack, 0);
5240       ivar
5241         = tree_cons
5242           (NULL_TREE,
5243            add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5244                             meth_var_types),
5245            ivar);
5246       obstack_free (&util_obstack, util_firstobj);
5247
5248       /* Set offset.  */
5249       ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5250       initlist = tree_cons (NULL_TREE,
5251                             objc_build_constructor (type, nreverse (ivar)),
5252                             initlist);
5253       do
5254         field_decl = TREE_CHAIN (field_decl);
5255       while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5256     }
5257   while (field_decl);
5258
5259   return objc_build_constructor (build_array_type (type, 0),
5260                                  nreverse (initlist));
5261 }
5262
5263 static tree
5264 generate_ivars_list (tree type, const char *name, int size, tree list)
5265 {
5266   tree decl, initlist;
5267
5268   decl = start_var_decl (type, synth_id_with_class_suffix
5269                                (name, objc_implementation_context));
5270
5271   initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5272   initlist = tree_cons (NULL_TREE, list, initlist);
5273
5274   finish_var_decl (decl,
5275                    objc_build_constructor (TREE_TYPE (decl),
5276                                            nreverse (initlist)));
5277
5278   return decl;
5279 }
5280
5281 /* Count only the fields occurring in T.  */
5282
5283 static int
5284 ivar_list_length (tree t)
5285 {
5286   int count = 0;
5287
5288   for (; t; t = TREE_CHAIN (t))
5289     if (TREE_CODE (t) == FIELD_DECL)
5290       ++count;
5291
5292   return count;
5293 }
5294
5295 static void
5296 generate_ivar_lists (void)
5297 {
5298   tree initlist, ivar_list_template, chain;
5299   int size;
5300
5301   generating_instance_variables = 1;
5302
5303   if (!objc_ivar_template)
5304     objc_ivar_template = build_ivar_template ();
5305
5306   /* Only generate class variables for the root of the inheritance
5307      hierarchy since these will be the same for every class.  */
5308
5309   if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5310       && (chain = TYPE_FIELDS (objc_class_template)))
5311     {
5312       size = ivar_list_length (chain);
5313
5314       ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5315       initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5316
5317       UOBJC_CLASS_VARIABLES_decl
5318         = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5319                                size, initlist);
5320     }
5321   else
5322     UOBJC_CLASS_VARIABLES_decl = 0;
5323
5324   chain = CLASS_IVARS (implementation_template);
5325   if (chain)
5326     {
5327       size = ivar_list_length (chain);
5328       ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5329       initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5330
5331       UOBJC_INSTANCE_VARIABLES_decl
5332         = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5333                                size, initlist);
5334     }
5335   else
5336     UOBJC_INSTANCE_VARIABLES_decl = 0;
5337
5338   generating_instance_variables = 0;
5339 }
5340
5341 static tree
5342 build_dispatch_table_initializer (tree type, tree entries)
5343 {
5344   tree initlist = NULL_TREE;
5345
5346   do
5347     {
5348       tree elemlist = NULL_TREE;
5349
5350       elemlist = tree_cons (NULL_TREE,
5351                             build_selector (METHOD_SEL_NAME (entries)),
5352                             NULL_TREE);
5353
5354       /* Generate the method encoding if we don't have one already.  */
5355       if (! METHOD_ENCODING (entries))
5356         METHOD_ENCODING (entries) =
5357           encode_method_prototype (entries);
5358
5359       elemlist = tree_cons (NULL_TREE,
5360                             add_objc_string (METHOD_ENCODING (entries),
5361                                              meth_var_types),
5362                             elemlist);
5363
5364       elemlist
5365         = tree_cons (NULL_TREE,
5366                      convert (ptr_type_node,
5367                               build_unary_op (input_location, ADDR_EXPR,
5368                                               METHOD_DEFINITION (entries), 1)),
5369                      elemlist);
5370
5371       initlist = tree_cons (NULL_TREE,
5372                             objc_build_constructor (type, nreverse (elemlist)),
5373                             initlist);
5374
5375       entries = TREE_CHAIN (entries);
5376     }
5377   while (entries);
5378
5379   return objc_build_constructor (build_array_type (type, 0),
5380                                  nreverse (initlist));
5381 }
5382
5383 /* To accomplish method prototyping without generating all kinds of
5384    inane warnings, the definition of the dispatch table entries were
5385    changed from:
5386
5387         struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5388    to:
5389         struct objc_method { SEL _cmd; ...; void *_imp; };  */
5390
5391 static tree
5392 build_method_template (void)
5393 {
5394   tree _SLT_record;
5395   tree field_decl, field_decl_chain;
5396
5397   _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
5398
5399   /* SEL _cmd; */
5400   field_decl = create_field_decl (objc_selector_type, "_cmd");
5401   field_decl_chain = field_decl;
5402
5403   /* char *method_types; */
5404   field_decl = create_field_decl (string_type_node, "method_types");
5405   chainon (field_decl_chain, field_decl);
5406
5407   /* void *_imp; */
5408   field_decl = create_field_decl (build_pointer_type (void_type_node),
5409                                   "_imp");
5410   chainon (field_decl_chain, field_decl);
5411
5412   objc_finish_struct (_SLT_record, field_decl_chain);
5413
5414   return _SLT_record;
5415 }
5416
5417
5418 static tree
5419 generate_dispatch_table (tree type, const char *name, int size, tree list)
5420 {
5421   tree decl, initlist;
5422
5423   decl = start_var_decl (type, synth_id_with_class_suffix
5424                                (name, objc_implementation_context));
5425
5426   initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5427   initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5428   initlist = tree_cons (NULL_TREE, list, initlist);
5429
5430   finish_var_decl (decl,
5431                    objc_build_constructor (TREE_TYPE (decl),
5432                                            nreverse (initlist)));
5433
5434   return decl;
5435 }
5436
5437 static void
5438 mark_referenced_methods (void)
5439 {
5440   struct imp_entry *impent;
5441   tree chain;
5442
5443   for (impent = imp_list; impent; impent = impent->next)
5444     {
5445       chain = CLASS_CLS_METHODS (impent->imp_context);
5446       while (chain)
5447         {
5448           cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5449           chain = TREE_CHAIN (chain);
5450         }
5451
5452       chain = CLASS_NST_METHODS (impent->imp_context);
5453       while (chain)
5454         {
5455           cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5456           chain = TREE_CHAIN (chain);
5457         }
5458     }
5459 }
5460
5461 static void
5462 generate_dispatch_tables (void)
5463 {
5464   tree initlist, chain, method_list_template;
5465   int size;
5466
5467   if (!objc_method_template)
5468     objc_method_template = build_method_template ();
5469
5470   chain = CLASS_CLS_METHODS (objc_implementation_context);
5471   if (chain)
5472     {
5473       size = list_length (chain);
5474
5475       method_list_template
5476         = build_method_list_template (objc_method_template, size);
5477       initlist
5478         = build_dispatch_table_initializer (objc_method_template, chain);
5479
5480       UOBJC_CLASS_METHODS_decl
5481         = generate_dispatch_table (method_list_template,
5482                                    ((TREE_CODE (objc_implementation_context)
5483                                      == CLASS_IMPLEMENTATION_TYPE)
5484                                     ? "_OBJC_CLASS_METHODS"
5485                                     : "_OBJC_CATEGORY_CLASS_METHODS"),
5486                                    size, initlist);
5487     }
5488   else
5489     UOBJC_CLASS_METHODS_decl = 0;
5490
5491   chain = CLASS_NST_METHODS (objc_implementation_context);
5492   if (chain)
5493     {
5494       size = list_length (chain);
5495
5496       method_list_template
5497         = build_method_list_template (objc_method_template, size);
5498       initlist
5499         = build_dispatch_table_initializer (objc_method_template, chain);
5500
5501       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5502         UOBJC_INSTANCE_METHODS_decl
5503           = generate_dispatch_table (method_list_template,
5504                                      "_OBJC_INSTANCE_METHODS",
5505                                      size, initlist);
5506       else
5507         /* We have a category.  */
5508         UOBJC_INSTANCE_METHODS_decl
5509           = generate_dispatch_table (method_list_template,
5510                                      "_OBJC_CATEGORY_INSTANCE_METHODS",
5511                                      size, initlist);
5512     }
5513   else
5514     UOBJC_INSTANCE_METHODS_decl = 0;
5515 }
5516
5517 static tree
5518 generate_protocol_list (tree i_or_p)
5519 {
5520   tree initlist;
5521   tree refs_decl, lproto, e, plist;
5522   int size = 0;
5523   const char *ref_name;
5524
5525   if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5526       || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5527     plist = CLASS_PROTOCOL_LIST (i_or_p);
5528   else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5529     plist = PROTOCOL_LIST (i_or_p);
5530   else
5531     abort ();
5532
5533   /* Compute size.  */
5534   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5535     if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5536         && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5537       size++;
5538
5539   /* Build initializer.  */
5540   initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5541   e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5542   initlist = tree_cons (NULL_TREE, e, initlist);
5543
5544   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5545     {
5546       tree pval = TREE_VALUE (lproto);
5547
5548       if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5549           && PROTOCOL_FORWARD_DECL (pval))
5550         {
5551           e = build_unary_op (input_location, ADDR_EXPR, 
5552                               PROTOCOL_FORWARD_DECL (pval), 0);
5553           initlist = tree_cons (NULL_TREE, e, initlist);
5554         }
5555     }
5556
5557   /* static struct objc_protocol *refs[n]; */
5558
5559   if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5560     ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5561   else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5562     ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5563   else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5564     ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5565   else
5566     abort ();
5567
5568   refs_decl = start_var_decl
5569               (build_array_type
5570                (build_pointer_type (objc_protocol_template),
5571                 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5572                ref_name);
5573
5574   finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5575                                                       nreverse (initlist)));
5576
5577   return refs_decl;
5578 }
5579
5580 static tree
5581 build_category_initializer (tree type, tree cat_name, tree class_name,
5582                             tree instance_methods, tree class_methods,
5583                             tree protocol_list)
5584 {
5585   tree initlist = NULL_TREE, expr;
5586
5587   initlist = tree_cons (NULL_TREE, cat_name, initlist);
5588   initlist = tree_cons (NULL_TREE, class_name, initlist);
5589
5590   if (!instance_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                                       instance_methods, 0));
5597       initlist = tree_cons (NULL_TREE, expr, initlist);
5598     }
5599   if (!class_methods)
5600     initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5601   else
5602     {
5603       expr = convert (objc_method_list_ptr,
5604                       build_unary_op (input_location, ADDR_EXPR, 
5605                                       class_methods, 0));
5606       initlist = tree_cons (NULL_TREE, expr, initlist);
5607     }
5608
5609   /* protocol_list = */
5610   if (!protocol_list)
5611      initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5612   else
5613     {
5614       expr = convert (build_pointer_type
5615                       (build_pointer_type
5616                        (objc_protocol_template)),
5617                       build_unary_op (input_location, ADDR_EXPR, 
5618                                       protocol_list, 0));
5619       initlist = tree_cons (NULL_TREE, expr, initlist);
5620     }
5621
5622   return objc_build_constructor (type, nreverse (initlist));
5623 }
5624
5625 /* struct _objc_class {
5626      struct objc_class *isa;
5627      struct objc_class *super_class;
5628      char *name;
5629      long version;
5630      long info;
5631      long instance_size;
5632      struct objc_ivar_list *ivars;
5633      struct objc_method_list *methods;
5634      if (flag_next_runtime)
5635        struct objc_cache *cache;
5636      else {
5637        struct sarray *dtable;
5638        struct objc_class *subclass_list;
5639        struct objc_class *sibling_class;
5640      }
5641      struct objc_protocol_list *protocols;
5642      if (flag_next_runtime)
5643        void *sel_id;
5644      void *gc_object_type;
5645    };  */
5646
5647 static tree
5648 build_shared_structure_initializer (tree type, tree isa, tree super,
5649                                     tree name, tree size, int status,
5650                                     tree dispatch_table, tree ivar_list,
5651                                     tree protocol_list)
5652 {
5653   tree initlist = NULL_TREE, expr;
5654
5655   /* isa = */
5656   initlist = tree_cons (NULL_TREE, isa, initlist);
5657
5658   /* super_class = */
5659   initlist = tree_cons (NULL_TREE, super, initlist);
5660
5661   /* name = */
5662   initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5663
5664   /* version = */
5665   initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5666                         initlist);
5667
5668   /* info = */
5669   initlist = tree_cons (NULL_TREE,
5670                         build_int_cst (long_integer_type_node, status),
5671                         initlist);
5672
5673   /* instance_size = */
5674   initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5675                         initlist);
5676
5677   /* objc_ivar_list = */
5678   if (!ivar_list)
5679     initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5680   else
5681     {
5682       expr = convert (objc_ivar_list_ptr,
5683                       build_unary_op (input_location, ADDR_EXPR, 
5684                                       ivar_list, 0));
5685       initlist = tree_cons (NULL_TREE, expr, initlist);
5686     }
5687
5688   /* objc_method_list = */
5689   if (!dispatch_table)
5690     initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5691   else
5692     {
5693       expr = convert (objc_method_list_ptr,
5694                       build_unary_op (input_location, ADDR_EXPR, 
5695                                       dispatch_table, 0));
5696       initlist = tree_cons (NULL_TREE, expr, initlist);
5697     }
5698
5699   if (flag_next_runtime)
5700     /* method_cache = */
5701     initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5702   else
5703     {
5704       /* dtable = */
5705       initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5706
5707       /* subclass_list = */
5708       initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5709
5710       /* sibling_class = */
5711       initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5712     }
5713
5714   /* protocol_list = */
5715   if (! protocol_list)
5716     initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5717   else
5718     {
5719       expr = convert (build_pointer_type
5720                       (build_pointer_type
5721                        (objc_protocol_template)),
5722                       build_unary_op (input_location, ADDR_EXPR, 
5723                                       protocol_list, 0));
5724       initlist = tree_cons (NULL_TREE, expr, initlist);
5725     }
5726
5727   if (flag_next_runtime)
5728     /* sel_id = NULL */
5729     initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5730
5731   /* gc_object_type = NULL */
5732   initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5733
5734   return objc_build_constructor (type, nreverse (initlist));
5735 }
5736
5737 /* Retrieve category interface CAT_NAME (if any) associated with CLASS.  */
5738
5739 static inline tree
5740 lookup_category (tree klass, tree cat_name)
5741 {
5742   tree category = CLASS_CATEGORY_LIST (klass);
5743
5744   while (category && CLASS_SUPER_NAME (category) != cat_name)
5745     category = CLASS_CATEGORY_LIST (category);
5746   return category;
5747 }
5748
5749 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... };  */
5750
5751 static void
5752 generate_category (tree cat)
5753 {
5754   tree decl;
5755   tree initlist, cat_name_expr, class_name_expr;
5756   tree protocol_decl, category;
5757
5758   add_class_reference (CLASS_NAME (cat));
5759   cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5760
5761   class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5762
5763   category = lookup_category (implementation_template,
5764                                 CLASS_SUPER_NAME (cat));
5765
5766   if (category && CLASS_PROTOCOL_LIST (category))
5767     {
5768       generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5769       protocol_decl = generate_protocol_list (category);
5770     }
5771   else
5772     protocol_decl = 0;
5773
5774   decl = start_var_decl (objc_category_template,
5775                          synth_id_with_class_suffix
5776                          ("_OBJC_CATEGORY", objc_implementation_context));
5777
5778   initlist = build_category_initializer (TREE_TYPE (decl),
5779                                          cat_name_expr, class_name_expr,
5780                                          UOBJC_INSTANCE_METHODS_decl,
5781                                          UOBJC_CLASS_METHODS_decl,
5782                                          protocol_decl);
5783
5784   finish_var_decl (decl, initlist);
5785 }
5786
5787 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5788    static struct objc_class _OBJC_CLASS_Foo={ ... };  */
5789
5790 static void
5791 generate_shared_structures (int cls_flags)
5792 {
5793   tree decl;
5794   tree name_expr, super_expr, root_expr;
5795   tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5796   tree cast_type, initlist, protocol_decl;
5797
5798   my_super_id = CLASS_SUPER_NAME (implementation_template);
5799   if (my_super_id)
5800     {
5801       add_class_reference (my_super_id);
5802
5803       /* Compute "my_root_id" - this is required for code generation.
5804          the "isa" for all meta class structures points to the root of
5805          the inheritance hierarchy (e.g. "__Object")...  */
5806       my_root_id = my_super_id;
5807       do
5808         {
5809           tree my_root_int = lookup_interface (my_root_id);
5810
5811           if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5812             my_root_id = CLASS_SUPER_NAME (my_root_int);
5813           else
5814             break;
5815         }
5816       while (1);
5817     }
5818   else
5819     /* No super class.  */
5820     my_root_id = CLASS_NAME (implementation_template);
5821
5822   cast_type = build_pointer_type (objc_class_template);
5823   name_expr = add_objc_string (CLASS_NAME (implementation_template),
5824                                class_names);
5825
5826   /* Install class `isa' and `super' pointers at runtime.  */
5827   if (my_super_id)
5828     {
5829       super_expr = add_objc_string (my_super_id, class_names);
5830       super_expr = build_c_cast (input_location,
5831                                  cast_type, super_expr); /* cast! */
5832     }
5833   else
5834     super_expr = build_int_cst (NULL_TREE, 0);
5835
5836   root_expr = add_objc_string (my_root_id, class_names);
5837   root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
5838
5839   if (CLASS_PROTOCOL_LIST (implementation_template))
5840     {
5841       generate_protocol_references
5842         (CLASS_PROTOCOL_LIST (implementation_template));
5843       protocol_decl = generate_protocol_list (implementation_template);
5844     }
5845   else
5846     protocol_decl = 0;
5847
5848   /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5849
5850   decl = start_var_decl (objc_class_template,
5851                          IDENTIFIER_POINTER
5852                          (DECL_NAME (UOBJC_METACLASS_decl)));
5853
5854   initlist
5855     = build_shared_structure_initializer
5856       (TREE_TYPE (decl),
5857        root_expr, super_expr, name_expr,
5858        convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5859        2 /*CLS_META*/,
5860        UOBJC_CLASS_METHODS_decl,
5861        UOBJC_CLASS_VARIABLES_decl,
5862        protocol_decl);
5863
5864   finish_var_decl (decl, initlist);
5865
5866   /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5867
5868   decl = start_var_decl (objc_class_template,
5869                          IDENTIFIER_POINTER
5870                          (DECL_NAME (UOBJC_CLASS_decl)));
5871
5872   initlist
5873     = build_shared_structure_initializer
5874       (TREE_TYPE (decl),
5875        build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5876        super_expr, name_expr,
5877        convert (integer_type_node,
5878                 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5879                                 (implementation_template))),
5880        1 /*CLS_FACTORY*/ | cls_flags,
5881        UOBJC_INSTANCE_METHODS_decl,
5882        UOBJC_INSTANCE_VARIABLES_decl,
5883        protocol_decl);
5884
5885   finish_var_decl (decl, initlist);
5886 }
5887
5888
5889 static const char *
5890 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5891 {
5892   static char string[BUFSIZE];
5893
5894   if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5895       || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5896     {
5897       sprintf (string, "%s_%s", preamble,
5898                IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5899     }
5900   else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5901            || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5902     {
5903       /* We have a category.  */
5904       const char *const class_name
5905         = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5906       const char *const class_super_name
5907         = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5908       sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5909     }
5910   else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5911     {
5912       const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5913       sprintf (string, "%s_%s", preamble, protocol_name);
5914     }
5915   else
5916     abort ();
5917
5918   return string;
5919 }
5920
5921 /* If type is empty or only type qualifiers are present, add default
5922    type of id (otherwise grokdeclarator will default to int).  */
5923
5924 static tree
5925 adjust_type_for_id_default (tree type)
5926 {
5927   if (!type)
5928     type = make_node (TREE_LIST);
5929
5930   if (!TREE_VALUE (type))
5931     TREE_VALUE (type) = objc_object_type;
5932   else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5933            && TYPED_OBJECT (TREE_VALUE (type)))
5934     error ("can not use an object as parameter to a method");
5935
5936   return type;
5937 }
5938
5939 /*   Usage:
5940                 keyworddecl:
5941                         selector ':' '(' typename ')' identifier
5942
5943      Purpose:
5944                 Transform an Objective-C keyword argument into
5945                 the C equivalent parameter declarator.
5946
5947      In:        key_name, an "identifier_node" (optional).
5948                 arg_type, a  "tree_list" (optional).
5949                 arg_name, an "identifier_node".
5950
5951      Note:      It would be really nice to strongly type the preceding
5952                 arguments in the function prototype; however, then I
5953                 could not use the "accessor" macros defined in "tree.h".
5954
5955      Out:       an instance of "keyword_decl".  */
5956
5957 tree
5958 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5959 {
5960   tree keyword_decl;
5961
5962   /* If no type is specified, default to "id".  */
5963   arg_type = adjust_type_for_id_default (arg_type);
5964
5965   keyword_decl = make_node (KEYWORD_DECL);
5966
5967   TREE_TYPE (keyword_decl) = arg_type;
5968   KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5969   KEYWORD_KEY_NAME (keyword_decl) = key_name;
5970
5971   return keyword_decl;
5972 }
5973
5974 /* Given a chain of keyword_decl's, synthesize the full keyword selector.  */
5975
5976 static tree
5977 build_keyword_selector (tree selector)
5978 {
5979   int len = 0;
5980   tree key_chain, key_name;
5981   char *buf;
5982
5983   /* Scan the selector to see how much space we'll need.  */
5984   for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5985     {
5986       if (TREE_CODE (selector) == KEYWORD_DECL)
5987         key_name = KEYWORD_KEY_NAME (key_chain);
5988       else if (TREE_CODE (selector) == TREE_LIST)
5989         key_name = TREE_PURPOSE (key_chain);
5990       else
5991         abort ();
5992
5993       if (key_name)
5994         len += IDENTIFIER_LENGTH (key_name) + 1;
5995       else
5996         /* Just a ':' arg.  */
5997         len++;
5998     }
5999
6000   buf = (char *) alloca (len + 1);
6001   /* Start the buffer out as an empty string.  */
6002   buf[0] = '\0';
6003
6004   for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
6005     {
6006       if (TREE_CODE (selector) == KEYWORD_DECL)
6007         key_name = KEYWORD_KEY_NAME (key_chain);
6008       else if (TREE_CODE (selector) == TREE_LIST)
6009         {
6010           key_name = TREE_PURPOSE (key_chain);
6011           /* The keyword decl chain will later be used as a function argument
6012              chain.  Unhook the selector itself so as to not confuse other
6013              parts of the compiler.  */
6014           TREE_PURPOSE (key_chain) = NULL_TREE;
6015         }
6016       else
6017         abort ();
6018
6019       if (key_name)
6020         strcat (buf, IDENTIFIER_POINTER (key_name));
6021       strcat (buf, ":");
6022     }
6023
6024   return get_identifier (buf);
6025 }
6026
6027 /* Used for declarations and definitions.  */
6028
6029 static tree
6030 build_method_decl (enum tree_code code, tree ret_type, tree selector,
6031                    tree add_args, bool ellipsis)
6032 {
6033   tree method_decl;
6034
6035   /* If no type is specified, default to "id".  */
6036   ret_type = adjust_type_for_id_default (ret_type);
6037
6038   method_decl = make_node (code);
6039   TREE_TYPE (method_decl) = ret_type;
6040
6041   /* If we have a keyword selector, create an identifier_node that
6042      represents the full selector name (`:' included)...  */
6043   if (TREE_CODE (selector) == KEYWORD_DECL)
6044     {
6045       METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
6046       METHOD_SEL_ARGS (method_decl) = selector;
6047       METHOD_ADD_ARGS (method_decl) = add_args;
6048       METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
6049     }
6050   else
6051     {
6052       METHOD_SEL_NAME (method_decl) = selector;
6053       METHOD_SEL_ARGS (method_decl) = NULL_TREE;
6054       METHOD_ADD_ARGS (method_decl) = NULL_TREE;
6055     }
6056
6057   return method_decl;
6058 }
6059
6060 #define METHOD_DEF 0
6061 #define METHOD_REF 1
6062
6063 /* Used by `build_objc_method_call' and `comp_proto_with_proto'.  Return
6064    an argument list for method METH.  CONTEXT is either METHOD_DEF or
6065    METHOD_REF, saying whether we are trying to define a method or call
6066    one.  SUPERFLAG says this is for a send to super; this makes a
6067    difference for the NeXT calling sequence in which the lookup and
6068    the method call are done together.  If METH is null, user-defined
6069    arguments (i.e., beyond self and _cmd) shall be represented by `...'.  */
6070
6071 static tree
6072 get_arg_type_list (tree meth, int context, int superflag)
6073 {
6074   tree arglist, akey;
6075
6076   /* Receiver type.  */
6077   if (flag_next_runtime && superflag)
6078     arglist = build_tree_list (NULL_TREE, objc_super_type);
6079   else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6080     arglist = build_tree_list (NULL_TREE, objc_instance_type);
6081   else
6082     arglist = build_tree_list (NULL_TREE, objc_object_type);
6083
6084   /* Selector type - will eventually change to `int'.  */
6085   chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6086
6087   /* No actual method prototype given -- assume that remaining arguments
6088      are `...'.  */
6089   if (!meth)
6090     return arglist;
6091
6092   /* Build a list of argument types.  */
6093   for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6094     {
6095       tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6096
6097       /* Decay arrays and functions into pointers.  */
6098       if (TREE_CODE (arg_type) == ARRAY_TYPE)
6099         arg_type = build_pointer_type (TREE_TYPE (arg_type));
6100       else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6101         arg_type = build_pointer_type (arg_type);
6102
6103       chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6104     }
6105
6106   if (METHOD_ADD_ARGS (meth))
6107     {
6108       for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6109            akey; akey = TREE_CHAIN (akey))
6110         {
6111           tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6112
6113           chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6114         }
6115
6116       if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6117         goto lack_of_ellipsis;
6118     }
6119   else
6120     {
6121      lack_of_ellipsis:
6122       chainon (arglist, OBJC_VOID_AT_END);
6123     }
6124
6125   return arglist;
6126 }
6127
6128 static tree
6129 check_duplicates (hash hsh, int methods, int is_class)
6130 {
6131   tree meth = NULL_TREE;
6132
6133   if (hsh)
6134     {
6135       meth = hsh->key;
6136
6137       if (hsh->list)
6138         {
6139           /* We have two or more methods with the same name but
6140              different types.  */
6141           attr loop;
6142
6143           /* But just how different are those types?  If
6144              -Wno-strict-selector-match is specified, we shall not
6145              complain if the differences are solely among types with
6146              identical size and alignment.  */
6147           if (!warn_strict_selector_match)
6148             {
6149               for (loop = hsh->list; loop; loop = loop->next)
6150                 if (!comp_proto_with_proto (meth, loop->value, 0))
6151                   goto issue_warning;
6152
6153               return meth;
6154             }
6155
6156         issue_warning:
6157           if (methods)
6158             {
6159               bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6160
6161               warning_at (input_location, 0,
6162                           "multiple methods named %<%c%E%> found",
6163                           (is_class ? '+' : '-'),
6164                           METHOD_SEL_NAME (meth));
6165               inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
6166                       (type ? '-' : '+'),
6167                       identifier_to_locale (gen_method_decl (meth)));
6168             }
6169           else
6170             {
6171               bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6172
6173               warning_at (input_location, 0,
6174                           "multiple selectors named %<%c%E%> found",
6175                           (is_class ? '+' : '-'),
6176                           METHOD_SEL_NAME (meth));
6177               inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
6178                       (type ? '-' : '+'),
6179                       identifier_to_locale (gen_method_decl (meth)));
6180             }
6181
6182           for (loop = hsh->list; loop; loop = loop->next)
6183             {
6184               bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
6185
6186               inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
6187                       (type ? '-' : '+'),
6188                       identifier_to_locale (gen_method_decl (loop->value)));
6189             }
6190         }
6191     }
6192   return meth;
6193 }
6194
6195 /* If RECEIVER is a class reference, return the identifier node for
6196    the referenced class.  RECEIVER is created by objc_get_class_reference,
6197    so we check the exact form created depending on which runtimes are
6198    used.  */
6199
6200 static tree
6201 receiver_is_class_object (tree receiver, int self, int super)
6202 {
6203   tree chain, exp, arg;
6204
6205   /* The receiver is 'self' or 'super' in the context of a class method.  */
6206   if (objc_method_context
6207       && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6208       && (self || super))
6209     return (super
6210             ? CLASS_SUPER_NAME (implementation_template)
6211             : CLASS_NAME (implementation_template));
6212
6213   if (flag_next_runtime)
6214     {
6215       /* The receiver is a variable created by
6216          build_class_reference_decl.  */
6217       if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6218         /* Look up the identifier.  */
6219         for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6220           if (TREE_PURPOSE (chain) == receiver)
6221             return TREE_VALUE (chain);
6222     }
6223
6224   /* The receiver is a function call that returns an id.  Check if
6225      it is a call to objc_getClass, if so, pick up the class name.  */
6226   if (TREE_CODE (receiver) == CALL_EXPR
6227       && (exp = CALL_EXPR_FN (receiver))
6228       && TREE_CODE (exp) == ADDR_EXPR
6229       && (exp = TREE_OPERAND (exp, 0))
6230       && TREE_CODE (exp) == FUNCTION_DECL
6231       /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6232          prototypes for objc_get_class().  Thankfully, they seem to share the
6233          same function type.  */
6234       && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6235       && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6236       /* We have a call to objc_get_class/objc_getClass!  */
6237       && (arg = CALL_EXPR_ARG (receiver, 0)))
6238     {
6239       STRIP_NOPS (arg);
6240       if (TREE_CODE (arg) == ADDR_EXPR
6241           && (arg = TREE_OPERAND (arg, 0))
6242           && TREE_CODE (arg) == STRING_CST)
6243         /* Finally, we have the class name.  */
6244         return get_identifier (TREE_STRING_POINTER (arg));
6245     }
6246   return 0;
6247 }
6248 \f
6249 /* If we are currently building a message expr, this holds
6250    the identifier of the selector of the message.  This is
6251    used when printing warnings about argument mismatches.  */
6252
6253 static tree current_objc_message_selector = 0;
6254
6255 tree
6256 objc_message_selector (void)
6257 {
6258   return current_objc_message_selector;
6259 }
6260
6261 /* Construct an expression for sending a message.
6262    MESS has the object to send to in TREE_PURPOSE
6263    and the argument list (including selector) in TREE_VALUE.
6264
6265    (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6266    (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...);  */
6267
6268 tree
6269 objc_build_message_expr (tree mess)
6270 {
6271   tree receiver = TREE_PURPOSE (mess);
6272   tree sel_name;
6273 #ifdef OBJCPLUS
6274   tree args = TREE_PURPOSE (TREE_VALUE (mess));
6275 #else
6276   tree args = TREE_VALUE (mess);
6277 #endif
6278   tree method_params = NULL_TREE;
6279
6280   if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
6281     return error_mark_node;
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;
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       if (TYPED_OBJECT (rtype))
6455         {
6456           rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6457           rtype = TYPE_OBJC_INTERFACE (rtype);
6458         }
6459       /* If we could not find an @interface declaration, we must have
6460          only seen a @class declaration; so, we cannot say anything
6461          more intelligent about which methods the receiver will
6462          understand. */
6463       if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6464         rtype = NULL_TREE;
6465       else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6466           || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6467         {
6468           /* We have a valid ObjC class name.  Look up the method name
6469              in the published @interface for the class (and its
6470              superclasses). */
6471           method_prototype
6472             = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6473
6474           /* If the method was not found in the @interface, it may still
6475              exist locally as part of the @implementation.  */
6476           if (!method_prototype && objc_implementation_context
6477              && CLASS_NAME (objc_implementation_context)
6478                 == OBJC_TYPE_NAME (rtype))
6479             method_prototype
6480               = lookup_method
6481                 ((class_tree
6482                   ? CLASS_CLS_METHODS (objc_implementation_context)
6483                   : CLASS_NST_METHODS (objc_implementation_context)),
6484                   sel_name);
6485
6486           /* If we haven't found a candidate method by now, try looking for
6487              it in the protocol list.  */
6488           if (!method_prototype && rprotos)
6489             method_prototype
6490               = lookup_method_in_protocol_list (rprotos, sel_name,
6491                                                 class_tree != NULL_TREE);
6492         }
6493       else
6494         {
6495           warning (0, "invalid receiver type %qs",
6496                    identifier_to_locale (gen_type_name (orig_rtype)));
6497           /* After issuing the "invalid receiver" warning, perform method
6498              lookup as if we were messaging 'id'.  */
6499           rtype = rprotos = NULL_TREE;
6500         }
6501     }
6502
6503
6504   /* For 'id' or 'Class' receivers, search in the global hash table
6505      as a last resort.  For all receivers, warn if protocol searches
6506      have failed.  */
6507   if (!method_prototype)
6508     {
6509       if (rprotos)
6510         warning (0, "%<%c%E%> not found in protocol(s)",
6511                  (class_tree ? '+' : '-'),
6512                  sel_name);
6513
6514       if (!rtype)
6515         method_prototype
6516           = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6517     }
6518
6519   if (!method_prototype)
6520     {
6521       static bool warn_missing_methods = false;
6522
6523       if (rtype)
6524         warning (0, "%qE may not respond to %<%c%E%>",
6525                  OBJC_TYPE_NAME (rtype),
6526                  (class_tree ? '+' : '-'),
6527                  sel_name);
6528       /* If we are messaging an 'id' or 'Class' object and made it here,
6529          then we have failed to find _any_ instance or class method,
6530          respectively.  */
6531       else
6532         warning (0, "no %<%c%E%> method found",
6533                  (class_tree ? '+' : '-'),
6534                  sel_name);
6535
6536       if (!warn_missing_methods)
6537         {
6538           warning_at (input_location, 
6539                       0, "(Messages without a matching method signature");
6540           warning_at (input_location, 
6541                       0, "will be assumed to return %<id%> and accept");
6542           warning_at (input_location, 
6543                       0, "%<...%> as arguments.)");
6544           warn_missing_methods = true;
6545         }
6546     }
6547
6548   /* Save the selector name for printing error messages.  */
6549   current_objc_message_selector = sel_name;
6550
6551   /* Build the parameters list for looking up the method.
6552      These are the object itself and the selector.  */
6553
6554   if (flag_typed_selectors)
6555     selector = build_typed_selector_reference (input_location,
6556                                                sel_name, method_prototype);
6557   else
6558     selector = build_selector_reference (input_location, sel_name);
6559
6560   retval = build_objc_method_call (input_location, super, method_prototype,
6561                                    receiver,
6562                                    selector, method_params);
6563
6564   current_objc_message_selector = 0;
6565
6566   return retval;
6567 }
6568 \f
6569 /* Build a tree expression to send OBJECT the operation SELECTOR,
6570    looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6571    assuming the method has prototype METHOD_PROTOTYPE.
6572    (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6573    LOC is the location of the expression to build.
6574    Use METHOD_PARAMS as list of args to pass to the method.
6575    If SUPER_FLAG is nonzero, we look up the superclass's method.  */
6576
6577 static tree
6578 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
6579                         tree lookup_object, tree selector,
6580                         tree method_params)
6581 {
6582   tree sender = (super_flag ? umsg_super_decl :
6583                  (!flag_next_runtime || flag_nil_receivers
6584                   ? (flag_objc_direct_dispatch
6585                      ? umsg_fast_decl
6586                      : umsg_decl)
6587                   : umsg_nonnil_decl));
6588   tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6589
6590   /* If a prototype for the method to be called exists, then cast
6591      the sender's return type and arguments to match that of the method.
6592      Otherwise, leave sender as is.  */
6593   tree ret_type
6594     = (method_prototype
6595        ? TREE_VALUE (TREE_TYPE (method_prototype))
6596        : objc_object_type);
6597   tree sender_cast
6598     = build_pointer_type
6599       (build_function_type
6600        (ret_type,
6601         get_arg_type_list
6602         (method_prototype, METHOD_REF, super_flag)));
6603   tree method, t;
6604
6605   lookup_object = build_c_cast (loc, rcv_p, lookup_object);
6606
6607   /* Use SAVE_EXPR to avoid evaluating the receiver twice.  */
6608   lookup_object = save_expr (lookup_object);
6609
6610   if (flag_next_runtime)
6611     {
6612       /* If we are returning a struct in memory, and the address
6613          of that memory location is passed as a hidden first
6614          argument, then change which messenger entry point this
6615          expr will call.  NB: Note that sender_cast remains
6616          unchanged (it already has a struct return type).  */
6617       if (!targetm.calls.struct_value_rtx (0, 0)
6618           && (TREE_CODE (ret_type) == RECORD_TYPE
6619               || TREE_CODE (ret_type) == UNION_TYPE)
6620           && targetm.calls.return_in_memory (ret_type, 0))
6621         sender = (super_flag ? umsg_super_stret_decl :
6622                 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6623
6624       method_params = tree_cons (NULL_TREE, lookup_object,
6625                                  tree_cons (NULL_TREE, selector,
6626                                             method_params));
6627       method = build_fold_addr_expr_loc (input_location, sender);
6628     }
6629   else
6630     {
6631       /* This is the portable (GNU) way.  */
6632       tree object;
6633
6634       /* First, call the lookup function to get a pointer to the method,
6635          then cast the pointer, then call it with the method arguments.  */
6636
6637       object = (super_flag ? self_decl : lookup_object);
6638
6639       t = tree_cons (NULL_TREE, selector, NULL_TREE);
6640       t = tree_cons (NULL_TREE, lookup_object, t);
6641       method = build_function_call (loc, sender, t);
6642
6643       /* Pass the object to the method.  */
6644       method_params = tree_cons (NULL_TREE, object,
6645                                  tree_cons (NULL_TREE, selector,
6646                                             method_params));
6647     }
6648
6649   /* ??? Selector is not at this point something we can use inside
6650      the compiler itself.  Set it to garbage for the nonce.  */
6651   t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6652   return build_function_call (loc,
6653                               t, method_params);
6654 }
6655 \f
6656 static void
6657 build_protocol_reference (tree p)
6658 {
6659   tree decl;
6660   const char *proto_name;
6661
6662   /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6663
6664   proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6665   decl = start_var_decl (objc_protocol_template, proto_name);
6666
6667   PROTOCOL_FORWARD_DECL (p) = decl;
6668 }
6669
6670 /* This function is called by the parser when (and only when) a
6671    @protocol() expression is found, in order to compile it.  */
6672 tree
6673 objc_build_protocol_expr (tree protoname)
6674 {
6675   tree expr;
6676   tree p = lookup_protocol (protoname);
6677
6678   if (!p)
6679     {
6680       error ("cannot find protocol declaration for %qE",
6681              protoname);
6682       return error_mark_node;
6683     }
6684
6685   if (!PROTOCOL_FORWARD_DECL (p))
6686     build_protocol_reference (p);
6687
6688   expr = build_unary_op (input_location, 
6689                          ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6690
6691   /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6692      if we have it, rather than converting it here.  */
6693   expr = convert (objc_protocol_type, expr);
6694
6695   /* The @protocol() expression is being compiled into a pointer to a
6696      statically allocated instance of the Protocol class.  To become
6697      usable at runtime, the 'isa' pointer of the instance need to be
6698      fixed up at runtime by the runtime library, to point to the
6699      actual 'Protocol' class.  */
6700
6701   /* For the GNU runtime, put the static Protocol instance in the list
6702      of statically allocated instances, so that we make sure that its
6703      'isa' pointer is fixed up at runtime by the GNU runtime library
6704      to point to the Protocol class (at runtime, when loading the
6705      module, the GNU runtime library loops on the statically allocated
6706      instances (as found in the defs field in objc_symtab) and fixups
6707      all the 'isa' pointers of those objects).  */
6708   if (! flag_next_runtime)
6709     {
6710       /* This type is a struct containing the fields of a Protocol
6711         object.  (Cfr. objc_protocol_type instead is the type of a pointer
6712         to such a struct).  */
6713       tree protocol_struct_type = xref_tag
6714        (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6715       tree *chain;
6716
6717       /* Look for the list of Protocol statically allocated instances
6718         to fixup at runtime.  Create a new list to hold Protocol
6719         statically allocated instances, if the list is not found.  At
6720         present there is only another list, holding NSConstantString
6721         static instances to be fixed up at runtime.  */
6722       for (chain = &objc_static_instances;
6723            *chain && TREE_VALUE (*chain) != protocol_struct_type;
6724            chain = &TREE_CHAIN (*chain));
6725       if (!*chain)
6726         {
6727          *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6728          add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6729                           class_names);
6730        }
6731
6732       /* Add this statically allocated instance to the Protocol list.  */
6733       TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6734                                          PROTOCOL_FORWARD_DECL (p),
6735                                          TREE_PURPOSE (*chain));
6736     }
6737
6738
6739   return expr;
6740 }
6741
6742 /* This function is called by the parser when a @selector() expression
6743    is found, in order to compile it.  It is only called by the parser
6744    and only to compile a @selector().  LOC is the location of the
6745    @selector.  */
6746 tree
6747 objc_build_selector_expr (location_t loc, tree selnamelist)
6748 {
6749   tree selname;
6750
6751   /* Obtain the full selector name.  */
6752   if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6753     /* A unary selector.  */
6754     selname = selnamelist;
6755   else if (TREE_CODE (selnamelist) == TREE_LIST)
6756     selname = build_keyword_selector (selnamelist);
6757   else
6758     abort ();
6759
6760   /* If we are required to check @selector() expressions as they
6761      are found, check that the selector has been declared.  */
6762   if (warn_undeclared_selector)
6763     {
6764       /* Look the selector up in the list of all known class and
6765          instance methods (up to this line) to check that the selector
6766          exists.  */
6767       hash hsh;
6768
6769       /* First try with instance methods.  */
6770       hsh = hash_lookup (nst_method_hash_list, selname);
6771
6772       /* If not found, try with class methods.  */
6773       if (!hsh)
6774         {
6775           hsh = hash_lookup (cls_method_hash_list, selname);
6776         }
6777
6778       /* If still not found, print out a warning.  */
6779       if (!hsh)
6780         {
6781           warning (0, "undeclared selector %qE", selname);
6782         }
6783     }
6784
6785
6786   if (flag_typed_selectors)
6787     return build_typed_selector_reference (loc, selname, 0);
6788   else
6789     return build_selector_reference (loc, selname);
6790 }
6791
6792 tree
6793 objc_build_encode_expr (tree type)
6794 {
6795   tree result;
6796   const char *string;
6797
6798   encode_type (type, obstack_object_size (&util_obstack),
6799                OBJC_ENCODE_INLINE_DEFS);
6800   obstack_1grow (&util_obstack, 0);    /* null terminate string */
6801   string = XOBFINISH (&util_obstack, const char *);
6802
6803   /* Synthesize a string that represents the encoded struct/union.  */
6804   result = my_build_string (strlen (string) + 1, string);
6805   obstack_free (&util_obstack, util_firstobj);
6806   return result;
6807 }
6808
6809 static tree
6810 build_ivar_reference (tree id)
6811 {
6812   if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6813     {
6814       /* Historically, a class method that produced objects (factory
6815          method) would assign `self' to the instance that it
6816          allocated.  This would effectively turn the class method into
6817          an instance method.  Following this assignment, the instance
6818          variables could be accessed.  That practice, while safe,
6819          violates the simple rule that a class method should not refer
6820          to an instance variable.  It's better to catch the cases
6821          where this is done unknowingly than to support the above
6822          paradigm.  */
6823       warning (0, "instance variable %qE accessed in class method",
6824                id);
6825       self_decl = convert (objc_instance_type, self_decl); /* cast */
6826     }
6827
6828   return objc_build_component_ref (build_indirect_ref (input_location,
6829                                                        self_decl, RO_ARROW),
6830                                    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 #ifdef OBJCPLUS
8309   /* C++ static members, and things that are not fields at all,
8310      should not appear in the encoding.  */
8311   if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8312     return;
8313 #endif
8314
8315   /* Generate the bitfield typing information, if needed.  Note the difference
8316      between GNU and NeXT runtimes.  */
8317   if (DECL_BIT_FIELD_TYPE (field_decl))
8318     {
8319       int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8320
8321       if (flag_next_runtime)
8322         encode_next_bitfield (size);
8323       else
8324         encode_gnu_bitfield (int_bit_position (field_decl),
8325                                   DECL_BIT_FIELD_TYPE (field_decl), size);
8326     }
8327   else
8328     encode_type (TREE_TYPE (field_decl), curtype, format);
8329 }
8330
8331 static GTY(()) tree objc_parmlist = NULL_TREE;
8332
8333 /* Append PARM to a list of formal parameters of a method, making a necessary
8334    array-to-pointer adjustment along the way.  */
8335
8336 static void
8337 objc_push_parm (tree parm)
8338 {
8339   bool relayout_needed = false;
8340
8341   if (TREE_TYPE (parm) == error_mark_node)
8342     {
8343       objc_parmlist = chainon (objc_parmlist, parm);
8344       return;
8345     }
8346
8347   /* Decay arrays and functions into pointers.  */
8348   if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8349     {
8350       TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8351       relayout_needed = true;
8352     }
8353   else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8354     {
8355       TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8356       relayout_needed = true;
8357     }
8358
8359   if (relayout_needed)
8360     relayout_decl (parm);
8361   
8362
8363   DECL_ARG_TYPE (parm)
8364     = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8365
8366   /* Record constancy and volatility.  */
8367   c_apply_type_quals_to_decl
8368   ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8369    | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8370    | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8371
8372   objc_parmlist = chainon (objc_parmlist, parm);
8373 }
8374
8375 /* Retrieve the formal parameter list constructed via preceding calls to
8376    objc_push_parm().  */
8377
8378 #ifdef OBJCPLUS
8379 static tree
8380 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8381 #else
8382 static struct c_arg_info *
8383 objc_get_parm_info (int have_ellipsis)
8384 #endif
8385 {
8386 #ifdef OBJCPLUS
8387   tree parm_info = objc_parmlist;
8388   objc_parmlist = NULL_TREE;
8389
8390   return parm_info;
8391 #else
8392   tree parm_info = objc_parmlist;
8393   struct c_arg_info *arg_info;
8394   /* The C front-end requires an elaborate song and dance at
8395      this point.  */
8396   push_scope ();
8397   declare_parm_level ();
8398   while (parm_info)
8399     {
8400       tree next = TREE_CHAIN (parm_info);
8401
8402       TREE_CHAIN (parm_info) = NULL_TREE;
8403       parm_info = pushdecl (parm_info);
8404       finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
8405       parm_info = next;
8406     }
8407   arg_info = get_parm_info (have_ellipsis);
8408   pop_scope ();
8409   objc_parmlist = NULL_TREE;
8410   return arg_info;
8411 #endif
8412 }
8413
8414 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8415    method definitions.  In the case of instance methods, we can be more
8416    specific as to the type of 'self'.  */
8417
8418 static void
8419 synth_self_and_ucmd_args (void)
8420 {
8421   tree self_type;
8422
8423   if (objc_method_context
8424       && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8425     self_type = objc_instance_type;
8426   else
8427     /* Really a `struct objc_class *'. However, we allow people to
8428        assign to self, which changes its type midstream.  */
8429     self_type = objc_object_type;
8430
8431   /* id self; */
8432   objc_push_parm (build_decl (input_location,
8433                               PARM_DECL, self_id, self_type));
8434
8435   /* SEL _cmd; */
8436   objc_push_parm (build_decl (input_location,
8437                               PARM_DECL, ucmd_id, objc_selector_type));
8438 }
8439
8440 /* Transform an Objective-C method definition into a static C function
8441    definition, synthesizing the first two arguments, "self" and "_cmd",
8442    in the process.  */
8443
8444 static void
8445 start_method_def (tree method)
8446 {
8447   tree parmlist;
8448 #ifdef OBJCPLUS
8449   tree parm_info;
8450 #else
8451   struct c_arg_info *parm_info;
8452 #endif
8453   int have_ellipsis = 0;
8454
8455   /* If we are defining a "dealloc" method in a non-root class, we
8456      will need to check if a [super dealloc] is missing, and warn if
8457      it is.  */
8458   if(CLASS_SUPER_NAME (objc_implementation_context)
8459      && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8460     should_call_super_dealloc = 1;
8461   else
8462     should_call_super_dealloc = 0;
8463
8464   /* Required to implement _msgSuper.  */
8465   objc_method_context = method;
8466   UOBJC_SUPER_decl = NULL_TREE;
8467
8468   /* Generate prototype declarations for arguments..."new-style".  */
8469   synth_self_and_ucmd_args ();
8470
8471   /* Generate argument declarations if a keyword_decl.  */
8472   parmlist = METHOD_SEL_ARGS (method);
8473   while (parmlist)
8474     {
8475       tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8476
8477       parm = build_decl (input_location,
8478                          PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8479       objc_push_parm (parm);
8480       parmlist = TREE_CHAIN (parmlist);
8481     }
8482
8483   if (METHOD_ADD_ARGS (method))
8484     {
8485       tree akey;
8486
8487       for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8488            akey; akey = TREE_CHAIN (akey))
8489         {
8490           objc_push_parm (TREE_VALUE (akey));
8491         }
8492
8493       if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8494         have_ellipsis = 1;
8495     }
8496
8497   parm_info = objc_get_parm_info (have_ellipsis);
8498
8499   really_start_method (objc_method_context, parm_info);
8500 }
8501
8502 /* Return 1 if TYPE1 is equivalent to TYPE2
8503    for purposes of method overloading.  */
8504
8505 static int
8506 objc_types_are_equivalent (tree type1, tree type2)
8507 {
8508   if (type1 == type2)
8509     return 1;
8510
8511   /* Strip away indirections.  */
8512   while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8513          && (TREE_CODE (type1) == TREE_CODE (type2)))
8514     type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8515   if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8516     return 0;
8517
8518   type1 = (TYPE_HAS_OBJC_INFO (type1)
8519            ? TYPE_OBJC_PROTOCOL_LIST (type1)
8520            : NULL_TREE);
8521   type2 = (TYPE_HAS_OBJC_INFO (type2)
8522            ? TYPE_OBJC_PROTOCOL_LIST (type2)
8523            : NULL_TREE);
8524
8525   if (list_length (type1) == list_length (type2))
8526     {
8527       for (; type2; type2 = TREE_CHAIN (type2))
8528         if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8529           return 0;
8530       return 1;
8531     }
8532   return 0;
8533 }
8534
8535 /* Return 1 if TYPE1 has the same size and alignment as TYPE2.  */
8536
8537 static int
8538 objc_types_share_size_and_alignment (tree type1, tree type2)
8539 {
8540   return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8541           && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8542 }
8543
8544 /* Return 1 if PROTO1 is equivalent to PROTO2
8545    for purposes of method overloading.  Ordinarily, the type signatures
8546    should match up exactly, unless STRICT is zero, in which case we
8547    shall allow differences in which the size and alignment of a type
8548    is the same.  */
8549
8550 static int
8551 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8552 {
8553   tree type1, type2;
8554
8555   /* The following test is needed in case there are hashing
8556      collisions.  */
8557   if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8558     return 0;
8559
8560   /* Compare return types.  */
8561   type1 = TREE_VALUE (TREE_TYPE (proto1));
8562   type2 = TREE_VALUE (TREE_TYPE (proto2));
8563
8564   if (!objc_types_are_equivalent (type1, type2)
8565       && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8566     return 0;
8567
8568   /* Compare argument types.  */
8569   for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8570        type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8571        type1 && type2;
8572        type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8573     {
8574       if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8575           && (strict
8576               || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8577                                                        TREE_VALUE (type2))))
8578         return 0;
8579     }
8580
8581   return (!type1 && !type2);
8582 }
8583
8584 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8585    this occurs.  ObjC method dispatches are _not_ like C++ virtual
8586    member function dispatches, and we account for the difference here.  */
8587 tree
8588 #ifdef OBJCPLUS
8589 objc_fold_obj_type_ref (tree ref, tree known_type)
8590 #else
8591 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8592                         tree known_type ATTRIBUTE_UNUSED)
8593 #endif
8594 {
8595 #ifdef OBJCPLUS
8596   tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8597
8598   /* If the receiver does not have virtual member functions, there
8599      is nothing we can (or need to) do here.  */
8600   if (!v)
8601     return NULL_TREE;
8602
8603   /* Let C++ handle C++ virtual functions.  */
8604   return cp_fold_obj_type_ref (ref, known_type);
8605 #else
8606   /* For plain ObjC, we currently do not need to do anything.  */
8607   return NULL_TREE;
8608 #endif
8609 }
8610
8611 static void
8612 objc_start_function (tree name, tree type, tree attrs,
8613 #ifdef OBJCPLUS
8614                      tree params
8615 #else
8616                      struct c_arg_info *params
8617 #endif
8618                      )
8619 {
8620   tree fndecl = build_decl (input_location,
8621                             FUNCTION_DECL, name, type);
8622
8623 #ifdef OBJCPLUS
8624   DECL_ARGUMENTS (fndecl) = params;
8625   DECL_INITIAL (fndecl) = error_mark_node;
8626   DECL_EXTERNAL (fndecl) = 0;
8627   TREE_STATIC (fndecl) = 1;
8628   retrofit_lang_decl (fndecl);
8629   cplus_decl_attributes (&fndecl, attrs, 0);
8630   start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8631 #else
8632   current_function_returns_value = 0;  /* Assume, until we see it does.  */
8633   current_function_returns_null = 0;
8634
8635   decl_attributes (&fndecl, attrs, 0);
8636   announce_function (fndecl);
8637   DECL_INITIAL (fndecl) = error_mark_node;
8638   DECL_EXTERNAL (fndecl) = 0;
8639   TREE_STATIC (fndecl) = 1;
8640   current_function_decl = pushdecl (fndecl);
8641   push_scope ();
8642   declare_parm_level ();
8643   DECL_RESULT (current_function_decl)
8644     = build_decl (input_location,
8645                   RESULT_DECL, NULL_TREE,
8646                   TREE_TYPE (TREE_TYPE (current_function_decl)));
8647   DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8648   DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8649   start_fname_decls ();
8650   store_parm_decls_from (params);
8651 #endif
8652
8653   TREE_USED (current_function_decl) = 1;
8654 }
8655
8656 /* - Generate an identifier for the function. the format is "_n_cls",
8657      where 1 <= n <= nMethods, and cls is the name the implementation we
8658      are processing.
8659    - Install the return type from the method declaration.
8660    - If we have a prototype, check for type consistency.  */
8661
8662 static void
8663 really_start_method (tree method,
8664 #ifdef OBJCPLUS
8665                      tree parmlist
8666 #else
8667                      struct c_arg_info *parmlist
8668 #endif
8669                      )
8670 {
8671   tree ret_type, meth_type;
8672   tree method_id;
8673   const char *sel_name, *class_name, *cat_name;
8674   char *buf;
8675
8676   /* Synth the storage class & assemble the return type.  */
8677   ret_type = TREE_VALUE (TREE_TYPE (method));
8678
8679   sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8680   class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8681   cat_name = ((TREE_CODE (objc_implementation_context)
8682                == CLASS_IMPLEMENTATION_TYPE)
8683               ? NULL
8684               : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8685   method_slot++;
8686
8687   /* Make sure this is big enough for any plausible method label.  */
8688   buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8689                          + (cat_name ? strlen (cat_name) : 0));
8690
8691   OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8692                          class_name, cat_name, sel_name, method_slot);
8693
8694   method_id = get_identifier (buf);
8695
8696 #ifdef OBJCPLUS
8697   /* Objective-C methods cannot be overloaded, so we don't need
8698      the type encoding appended.  It looks bad anyway... */
8699   push_lang_context (lang_name_c);
8700 #endif
8701
8702   meth_type
8703     = build_function_type (ret_type,
8704                            get_arg_type_list (method, METHOD_DEF, 0));
8705   objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8706
8707   /* Set self_decl from the first argument.  */
8708   self_decl = DECL_ARGUMENTS (current_function_decl);
8709
8710   /* Suppress unused warnings.  */
8711   TREE_USED (self_decl) = 1;
8712   TREE_USED (TREE_CHAIN (self_decl)) = 1;
8713 #ifdef OBJCPLUS
8714   pop_lang_context ();
8715 #endif
8716
8717   METHOD_DEFINITION (method) = current_function_decl;
8718
8719   /* Check consistency...start_function, pushdecl, duplicate_decls.  */
8720
8721   if (implementation_template != objc_implementation_context)
8722     {
8723       tree proto
8724         = lookup_method_static (implementation_template,
8725                                 METHOD_SEL_NAME (method),
8726                                 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8727                                  | OBJC_LOOKUP_NO_SUPER));
8728
8729       if (proto)
8730         {
8731           if (!comp_proto_with_proto (method, proto, 1))
8732             {
8733               bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
8734
8735               warning_at (DECL_SOURCE_LOCATION (method), 0,
8736                           "conflicting types for %<%c%s%>",
8737                           (type ? '-' : '+'),
8738                           identifier_to_locale (gen_method_decl (method)));
8739               inform (DECL_SOURCE_LOCATION (proto),
8740                       "previous declaration of %<%c%s%>",
8741                       (type ? '-' : '+'),
8742                       identifier_to_locale (gen_method_decl (proto)));
8743             }
8744         }
8745       else
8746         {
8747           /* We have a method @implementation even though we did not
8748              see a corresponding @interface declaration (which is allowed
8749              by Objective-C rules).  Go ahead and place the method in
8750              the @interface anyway, so that message dispatch lookups
8751              will see it.  */
8752           tree interface = implementation_template;
8753
8754           if (TREE_CODE (objc_implementation_context)
8755               == CATEGORY_IMPLEMENTATION_TYPE)
8756             interface = lookup_category
8757                         (interface,
8758                          CLASS_SUPER_NAME (objc_implementation_context));
8759
8760           if (interface)
8761             objc_add_method (interface, copy_node (method),
8762                              TREE_CODE (method) == CLASS_METHOD_DECL);
8763         }
8764     }
8765 }
8766
8767 static void *UOBJC_SUPER_scope = 0;
8768
8769 /* _n_Method (id self, SEL sel, ...)
8770      {
8771        struct objc_super _S;
8772        _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8773      }  */
8774
8775 static tree
8776 get_super_receiver (void)
8777 {
8778   if (objc_method_context)
8779     {
8780       tree super_expr, super_expr_list;
8781
8782       if (!UOBJC_SUPER_decl)
8783       {
8784         UOBJC_SUPER_decl = build_decl (input_location,
8785                                        VAR_DECL, get_identifier (TAG_SUPER),
8786                                        objc_super_template);
8787         /* This prevents `unused variable' warnings when compiling with -Wall.  */
8788         TREE_USED (UOBJC_SUPER_decl) = 1;
8789         lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8790         finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
8791                      NULL_TREE);
8792         UOBJC_SUPER_scope = objc_get_current_scope ();
8793       }
8794
8795       /* Set receiver to self.  */
8796       super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8797       super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
8798                                       NOP_EXPR, input_location, self_decl,
8799                                       NULL_TREE);
8800       super_expr_list = super_expr;
8801
8802       /* Set class to begin searching.  */
8803       super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8804                                              get_identifier ("super_class"));
8805
8806       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8807         {
8808           /* [_cls, __cls]Super are "pre-built" in
8809              synth_forward_declarations.  */
8810
8811           super_expr = build_modify_expr (input_location, super_expr,
8812                                           NULL_TREE, NOP_EXPR,
8813                                           input_location,
8814                                           ((TREE_CODE (objc_method_context)
8815                                             == INSTANCE_METHOD_DECL)
8816                                            ? ucls_super_ref
8817                                            : uucls_super_ref),
8818                                           NULL_TREE);
8819         }
8820
8821       else
8822         /* We have a category.  */
8823         {
8824           tree super_name = CLASS_SUPER_NAME (implementation_template);
8825           tree super_class;
8826
8827           /* Barf if super used in a category of Object.  */
8828           if (!super_name)
8829             {
8830               error ("no super class declared in interface for %qE",
8831                      CLASS_NAME (implementation_template));
8832               return error_mark_node;
8833             }
8834
8835           if (flag_next_runtime && !flag_zero_link)
8836             {
8837               super_class = objc_get_class_reference (super_name);
8838               if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8839                 /* If we are in a class method, we must retrieve the
8840                    _metaclass_ for the current class, pointed at by
8841                    the class's "isa" pointer.  The following assumes that
8842                    "isa" is the first ivar in a class (which it must be).  */
8843                 super_class
8844                   = build_indirect_ref
8845                       (input_location,
8846                        build_c_cast (input_location,
8847                                      build_pointer_type (objc_class_type),
8848                                      super_class), RO_UNARY_STAR);
8849             }
8850           else
8851             {
8852               add_class_reference (super_name);
8853               super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8854                              ? objc_get_class_decl : objc_get_meta_class_decl);
8855               assemble_external (super_class);
8856               super_class
8857                 = build_function_call
8858                   (input_location,
8859                    super_class,
8860                    build_tree_list
8861                    (NULL_TREE,
8862                     my_build_string_pointer
8863                     (IDENTIFIER_LENGTH (super_name) + 1,
8864                      IDENTIFIER_POINTER (super_name))));
8865             }
8866
8867           super_expr
8868             = build_modify_expr (input_location, super_expr, NULL_TREE,
8869                                  NOP_EXPR,
8870                                  input_location,
8871                                  build_c_cast (input_location, 
8872                                                TREE_TYPE (super_expr),
8873                                                super_class),
8874                                  NULL_TREE);
8875         }
8876
8877       super_expr_list = build_compound_expr (input_location, 
8878                                              super_expr_list, super_expr);
8879
8880       super_expr = build_unary_op (input_location, 
8881                                    ADDR_EXPR, UOBJC_SUPER_decl, 0);
8882       super_expr_list = build_compound_expr (input_location,
8883                                              super_expr_list, super_expr);
8884
8885       return super_expr_list;
8886     }
8887   else
8888     {
8889       error ("[super ...] must appear in a method context");
8890       return error_mark_node;
8891     }
8892 }
8893
8894 /* When exiting a scope, sever links to a 'super' declaration (if any)
8895    therein contained.  */
8896
8897 void
8898 objc_clear_super_receiver (void)
8899 {
8900   if (objc_method_context
8901       && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8902     UOBJC_SUPER_decl = 0;
8903     UOBJC_SUPER_scope = 0;
8904   }
8905 }
8906
8907 void
8908 objc_finish_method_definition (tree fndecl)
8909 {
8910   /* We cannot validly inline ObjC methods, at least not without a language
8911      extension to declare that a method need not be dynamically
8912      dispatched, so suppress all thoughts of doing so.  */
8913   DECL_UNINLINABLE (fndecl) = 1;
8914
8915 #ifndef OBJCPLUS
8916   /* The C++ front-end will have called finish_function() for us.  */
8917   finish_function ();
8918 #endif
8919
8920   METHOD_ENCODING (objc_method_context)
8921     = encode_method_prototype (objc_method_context);
8922
8923   /* Required to implement _msgSuper. This must be done AFTER finish_function,
8924      since the optimizer may find "may be used before set" errors.  */
8925   objc_method_context = NULL_TREE;
8926
8927   if (should_call_super_dealloc)
8928     warning (0, "method possibly missing a [super dealloc] call");
8929 }
8930
8931 /* Given a tree DECL node, produce a printable description of it in the given
8932    buffer, overwriting the buffer.  */
8933
8934 static char *
8935 gen_declaration (tree decl)
8936 {
8937   errbuf[0] = '\0';
8938
8939   if (DECL_P (decl))
8940     {
8941       gen_type_name_0 (TREE_TYPE (decl));
8942
8943       if (DECL_NAME (decl))
8944         {
8945           if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8946             strcat (errbuf, " ");
8947
8948           strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8949         }
8950
8951       if (DECL_INITIAL (decl)
8952           && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8953         sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8954                  TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8955     }
8956
8957   return errbuf;
8958 }
8959
8960 /* Given a tree TYPE node, produce a printable description of it in the given
8961    buffer, overwriting the buffer.  */
8962
8963 static char *
8964 gen_type_name_0 (tree type)
8965 {
8966   tree orig = type, proto;
8967
8968   if (TYPE_P (type) && TYPE_NAME (type))
8969     type = TYPE_NAME (type);
8970   else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8971     {
8972       tree inner = TREE_TYPE (type);
8973
8974       while (TREE_CODE (inner) == ARRAY_TYPE)
8975         inner = TREE_TYPE (inner);
8976
8977       gen_type_name_0 (inner);
8978
8979       if (!POINTER_TYPE_P (inner))
8980         strcat (errbuf, " ");
8981
8982       if (POINTER_TYPE_P (type))
8983         strcat (errbuf, "*");
8984       else
8985         while (type != inner)
8986           {
8987             strcat (errbuf, "[");
8988
8989             if (TYPE_DOMAIN (type))
8990               {
8991                 char sz[20];
8992
8993                 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8994                          (TREE_INT_CST_LOW
8995                           (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8996                 strcat (errbuf, sz);
8997               }
8998
8999             strcat (errbuf, "]");
9000             type = TREE_TYPE (type);
9001           }
9002
9003       goto exit_function;
9004     }
9005
9006   if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
9007     type = DECL_NAME (type);
9008
9009   strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
9010                   ? IDENTIFIER_POINTER (type)
9011                   : "");
9012
9013   /* For 'id' and 'Class', adopted protocols are stored in the pointee.  */
9014   if (objc_is_id (orig))
9015     orig = TREE_TYPE (orig);
9016
9017   proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
9018
9019   if (proto)
9020     {
9021       strcat (errbuf, " <");
9022
9023       while (proto) {
9024         strcat (errbuf,
9025                 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
9026         proto = TREE_CHAIN (proto);
9027         strcat (errbuf, proto ? ", " : ">");
9028       }
9029     }
9030
9031  exit_function:
9032   return errbuf;
9033 }
9034
9035 static char *
9036 gen_type_name (tree type)
9037 {
9038   errbuf[0] = '\0';
9039
9040   return gen_type_name_0 (type);
9041 }
9042
9043 /* Given a method tree, put a printable description into the given
9044    buffer (overwriting) and return a pointer to the buffer.  */
9045
9046 static char *
9047 gen_method_decl (tree method)
9048 {
9049   tree chain;
9050
9051   strcpy (errbuf, "(");  /* NB: Do _not_ call strcat() here.  */
9052   gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
9053   strcat (errbuf, ")");
9054   chain = METHOD_SEL_ARGS (method);
9055
9056   if (chain)
9057     {
9058       /* We have a chain of keyword_decls.  */
9059       do
9060         {
9061           if (KEYWORD_KEY_NAME (chain))
9062             strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
9063
9064           strcat (errbuf, ":(");
9065           gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
9066           strcat (errbuf, ")");
9067
9068           strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
9069           if ((chain = TREE_CHAIN (chain)))
9070             strcat (errbuf, " ");
9071         }
9072       while (chain);
9073
9074       if (METHOD_ADD_ARGS (method))
9075         {
9076           chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
9077
9078           /* Know we have a chain of parm_decls.  */
9079           while (chain)
9080             {
9081               strcat (errbuf, ", ");
9082               gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
9083               chain = TREE_CHAIN (chain);
9084             }
9085
9086           if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
9087             strcat (errbuf, ", ...");
9088         }
9089     }
9090
9091   else
9092     /* We have a unary selector.  */
9093     strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
9094
9095   return errbuf;
9096 }
9097 \f
9098 /* Debug info.  */
9099
9100
9101 /* Dump an @interface declaration of the supplied class CHAIN to the
9102    supplied file FP.  Used to implement the -gen-decls option (which
9103    prints out an @interface declaration of all classes compiled in
9104    this run); potentially useful for debugging the compiler too.  */
9105 static void
9106 dump_interface (FILE *fp, tree chain)
9107 {
9108   /* FIXME: A heap overflow here whenever a method (or ivar)
9109      declaration is so long that it doesn't fit in the buffer.  The
9110      code and all the related functions should be rewritten to avoid
9111      using fixed size buffers.  */
9112   const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9113   tree ivar_decls = CLASS_RAW_IVARS (chain);
9114   tree nst_methods = CLASS_NST_METHODS (chain);
9115   tree cls_methods = CLASS_CLS_METHODS (chain);
9116
9117   fprintf (fp, "\n@interface %s", my_name);
9118
9119   /* CLASS_SUPER_NAME is used to store the superclass name for
9120      classes, and the category name for categories.  */
9121   if (CLASS_SUPER_NAME (chain))
9122     {
9123       const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9124
9125       if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9126           || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9127         {
9128           fprintf (fp, " (%s)\n", name);
9129         }
9130       else
9131         {
9132           fprintf (fp, " : %s\n", name);
9133         }
9134     }
9135   else
9136     fprintf (fp, "\n");
9137
9138   /* FIXME - the following doesn't seem to work at the moment.  */
9139   if (ivar_decls)
9140     {
9141       fprintf (fp, "{\n");
9142       do
9143         {
9144           fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9145           ivar_decls = TREE_CHAIN (ivar_decls);
9146         }
9147       while (ivar_decls);
9148       fprintf (fp, "}\n");
9149     }
9150
9151   while (nst_methods)
9152     {
9153       fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9154       nst_methods = TREE_CHAIN (nst_methods);
9155     }
9156
9157   while (cls_methods)
9158     {
9159       fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9160       cls_methods = TREE_CHAIN (cls_methods);
9161     }
9162
9163   fprintf (fp, "@end\n");
9164 }
9165
9166 /* Demangle function for Objective-C */
9167 static const char *
9168 objc_demangle (const char *mangled)
9169 {
9170   char *demangled, *cp;
9171
9172   if (mangled[0] == '_' &&
9173       (mangled[1] == 'i' || mangled[1] == 'c') &&
9174       mangled[2] == '_')
9175     {
9176       cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9177       if (mangled[1] == 'i')
9178         *cp++ = '-';            /* for instance method */
9179       else
9180         *cp++ = '+';            /* for class method */
9181       *cp++ = '[';              /* opening left brace */
9182       strcpy(cp, mangled+3);    /* tack on the rest of the mangled name */
9183       while (*cp && *cp == '_')
9184         cp++;                   /* skip any initial underbars in class name */
9185       cp = strchr(cp, '_');     /* find first non-initial underbar */
9186       if (cp == NULL)
9187         {
9188           free(demangled);      /* not mangled name */
9189           return mangled;
9190         }
9191       if (cp[1] == '_')  /* easy case: no category name */
9192         {
9193           *cp++ = ' ';            /* replace two '_' with one ' ' */
9194           strcpy(cp, mangled + (cp - demangled) + 2);
9195         }
9196       else
9197         {
9198           *cp++ = '(';            /* less easy case: category name */
9199           cp = strchr(cp, '_');
9200           if (cp == 0)
9201             {
9202               free(demangled);    /* not mangled name */
9203               return mangled;
9204             }
9205           *cp++ = ')';
9206           *cp++ = ' ';            /* overwriting 1st char of method name... */
9207           strcpy(cp, mangled + (cp - demangled)); /* get it back */
9208         }
9209       while (*cp && *cp == '_')
9210         cp++;                   /* skip any initial underbars in method name */
9211       for (; *cp; cp++)
9212         if (*cp == '_')
9213           *cp = ':';            /* replace remaining '_' with ':' */
9214       *cp++ = ']';              /* closing right brace */
9215       *cp++ = 0;                /* string terminator */
9216       return demangled;
9217     }
9218   else
9219     return mangled;             /* not an objc mangled name */
9220 }
9221
9222 const char *
9223 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9224 {
9225   return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9226 }
9227
9228 static void
9229 init_objc (void)
9230 {
9231   gcc_obstack_init (&util_obstack);
9232   util_firstobj = (char *) obstack_finish (&util_obstack);
9233
9234   errbuf = XNEWVEC (char, 1024 * 10);
9235   hash_init ();
9236   synth_module_prologue ();
9237 }
9238 \f
9239 static void
9240 finish_objc (void)
9241 {
9242   struct imp_entry *impent;
9243   tree chain;
9244   /* The internally generated initializers appear to have missing braces.
9245      Don't warn about this.  */
9246   int save_warn_missing_braces = warn_missing_braces;
9247   warn_missing_braces = 0;
9248
9249   /* A missing @end may not be detected by the parser.  */
9250   if (objc_implementation_context)
9251     {
9252       warning (0, "%<@end%> missing in implementation context");
9253       finish_class (objc_implementation_context);
9254       objc_ivar_chain = NULL_TREE;
9255       objc_implementation_context = NULL_TREE;
9256     }
9257
9258   /* Process the static instances here because initialization of objc_symtab
9259      depends on them.  */
9260   if (objc_static_instances)
9261     generate_static_references ();
9262
9263   if (imp_list || class_names_chain
9264       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9265     generate_objc_symtab_decl ();
9266
9267   for (impent = imp_list; impent; impent = impent->next)
9268     {
9269       objc_implementation_context = impent->imp_context;
9270       implementation_template = impent->imp_template;
9271
9272       UOBJC_CLASS_decl = impent->class_decl;
9273       UOBJC_METACLASS_decl = impent->meta_decl;
9274
9275       /* Dump the @interface of each class as we compile it, if the
9276          -gen-decls option is in use.  TODO: Dump the classes in the
9277          order they were found, rather than in reverse order as we
9278          are doing now.  */
9279       if (flag_gen_declaration)
9280         {
9281           dump_interface (gen_declaration_file, objc_implementation_context);
9282         }
9283
9284       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9285         {
9286           /* all of the following reference the string pool...  */
9287           generate_ivar_lists ();
9288           generate_dispatch_tables ();
9289           generate_shared_structures (impent->has_cxx_cdtors
9290                                       ? CLS_HAS_CXX_STRUCTORS
9291                                       : 0);
9292         }
9293       else
9294         {
9295           generate_dispatch_tables ();
9296           generate_category (objc_implementation_context);
9297         }
9298     }
9299
9300   /* If we are using an array of selectors, we must always
9301      finish up the array decl even if no selectors were used.  */
9302   if (! flag_next_runtime || sel_ref_chain)
9303     build_selector_translation_table ();
9304
9305   if (protocol_chain)
9306     generate_protocols ();
9307
9308   if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9309     generate_objc_image_info ();
9310
9311   /* Arrange for ObjC data structures to be initialized at run time.  */
9312   if (objc_implementation_context || class_names_chain || objc_static_instances
9313       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9314     {
9315       build_module_descriptor ();
9316
9317       if (!flag_next_runtime)
9318         build_module_initializer_routine ();
9319     }
9320
9321   /* Dump the class references.  This forces the appropriate classes
9322      to be linked into the executable image, preserving unix archive
9323      semantics.  This can be removed when we move to a more dynamically
9324      linked environment.  */
9325
9326   for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9327     {
9328       handle_class_ref (chain);
9329       if (TREE_PURPOSE (chain))
9330         generate_classref_translation_entry (chain);
9331     }
9332
9333   for (impent = imp_list; impent; impent = impent->next)
9334     handle_impent (impent);
9335
9336   if (warn_selector)
9337     {
9338       int slot;
9339       hash hsh;
9340
9341       /* Run through the selector hash tables and print a warning for any
9342          selector which has multiple methods.  */
9343
9344       for (slot = 0; slot < SIZEHASHTABLE; slot++)
9345         {
9346           for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9347             check_duplicates (hsh, 0, 1);
9348           for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9349             check_duplicates (hsh, 0, 1);
9350         }
9351     }
9352
9353   warn_missing_braces = save_warn_missing_braces;
9354 }
9355 \f
9356 /* Subroutines of finish_objc.  */
9357
9358 static void
9359 generate_classref_translation_entry (tree chain)
9360 {
9361   tree expr, decl, type;
9362
9363   decl = TREE_PURPOSE (chain);
9364   type = TREE_TYPE (decl);
9365
9366   expr = add_objc_string (TREE_VALUE (chain), class_names);
9367   expr = convert (type, expr); /* cast! */
9368
9369   /* The decl that is the one that we
9370      forward declared in build_class_reference.  */
9371   finish_var_decl (decl, expr);
9372   return;
9373 }
9374
9375 static void
9376 handle_class_ref (tree chain)
9377 {
9378   const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9379   char *string = (char *) alloca (strlen (name) + 30);
9380   tree decl;
9381   tree exp;
9382
9383   sprintf (string, "%sobjc_class_name_%s",
9384            (flag_next_runtime ? "." : "__"), name);
9385
9386 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9387   if (flag_next_runtime)
9388     {
9389       ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9390       return;
9391     }
9392 #endif
9393
9394   /* Make a decl for this name, so we can use its address in a tree.  */
9395   decl = build_decl (input_location,
9396                      VAR_DECL, get_identifier (string), char_type_node);
9397   DECL_EXTERNAL (decl) = 1;
9398   TREE_PUBLIC (decl) = 1;
9399
9400   pushdecl (decl);
9401   rest_of_decl_compilation (decl, 0, 0);
9402
9403   /* Make a decl for the address.  */
9404   sprintf (string, "%sobjc_class_ref_%s",
9405            (flag_next_runtime ? "." : "__"), name);
9406   exp = build1 (ADDR_EXPR, string_type_node, decl);
9407   decl = build_decl (input_location,
9408                      VAR_DECL, get_identifier (string), string_type_node);
9409   DECL_INITIAL (decl) = exp;
9410   TREE_STATIC (decl) = 1;
9411   TREE_USED (decl) = 1;
9412   /* Force the output of the decl as this forces the reference of the class.  */
9413   mark_decl_referenced (decl);
9414
9415   pushdecl (decl);
9416   rest_of_decl_compilation (decl, 0, 0);
9417 }
9418
9419 static void
9420 handle_impent (struct imp_entry *impent)
9421 {
9422   char *string;
9423
9424   objc_implementation_context = impent->imp_context;
9425   implementation_template = impent->imp_template;
9426
9427   if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9428     {
9429       const char *const class_name =
9430         IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9431
9432       string = (char *) alloca (strlen (class_name) + 30);
9433
9434       sprintf (string, "%sobjc_class_name_%s",
9435                (flag_next_runtime ? "." : "__"), class_name);
9436     }
9437   else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9438     {
9439       const char *const class_name =
9440         IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9441       const char *const class_super_name =
9442         IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9443
9444       string = (char *) alloca (strlen (class_name)
9445                                 + strlen (class_super_name) + 30);
9446
9447       /* Do the same for categories.  Even though no references to
9448          these symbols are generated automatically by the compiler, it
9449          gives you a handle to pull them into an archive by hand.  */
9450       sprintf (string, "*%sobjc_category_name_%s_%s",
9451                (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9452     }
9453   else
9454     return;
9455
9456 #ifdef ASM_DECLARE_CLASS_REFERENCE
9457   if (flag_next_runtime)
9458     {
9459       ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9460       return;
9461     }
9462   else
9463 #endif
9464     {
9465       tree decl, init;
9466
9467       init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9468       decl = build_decl (input_location,
9469                          VAR_DECL, get_identifier (string), TREE_TYPE (init));
9470       TREE_PUBLIC (decl) = 1;
9471       TREE_READONLY (decl) = 1;
9472       TREE_USED (decl) = 1;
9473       TREE_CONSTANT (decl) = 1;
9474       DECL_CONTEXT (decl) = 0;
9475       DECL_ARTIFICIAL (decl) = 1;
9476       DECL_INITIAL (decl) = init;
9477       assemble_variable (decl, 1, 0, 0);
9478     }
9479 }
9480 \f
9481 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9482    later requires that ObjC translation units participating in F&C be
9483    specially marked.  The following routine accomplishes this.  */
9484
9485 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9486
9487 static void
9488 generate_objc_image_info (void)
9489 {
9490   tree decl, initlist;
9491   int flags
9492     = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9493        | (flag_objc_gc ? 2 : 0));
9494
9495   decl = start_var_decl (build_array_type
9496                          (integer_type_node,
9497                           build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9498                          "_OBJC_IMAGE_INFO");
9499
9500   initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9501   initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9502   initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9503
9504   finish_var_decl (decl, initlist);
9505 }
9506
9507 /* Look up ID as an instance variable.  OTHER contains the result of
9508    the C or C++ lookup, which we may want to use instead.  */
9509
9510 tree
9511 objc_lookup_ivar (tree other, tree id)
9512 {
9513   tree ivar;
9514
9515   /* If we are not inside of an ObjC method, ivar lookup makes no sense.  */
9516   if (!objc_method_context)
9517     return other;
9518
9519   if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9520     /* We have a message to super.  */
9521     return get_super_receiver ();
9522
9523   /* In a class method, look up an instance variable only as a last
9524      resort.  */
9525   if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9526       && other && other != error_mark_node)
9527     return other;
9528
9529   /* Look up the ivar, but do not use it if it is not accessible.  */
9530   ivar = is_ivar (objc_ivar_chain, id);
9531
9532   if (!ivar || is_private (ivar))
9533     return other;
9534
9535   /* In an instance method, a local variable (or parameter) may hide the
9536      instance variable.  */
9537   if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9538       && other && other != error_mark_node
9539 #ifdef OBJCPLUS
9540       && CP_DECL_CONTEXT (other) != global_namespace)
9541 #else
9542       && !DECL_FILE_SCOPE_P (other))
9543 #endif
9544     {
9545       warning (0, "local declaration of %qE hides instance variable",
9546                id);
9547
9548       return other;
9549     }
9550
9551   /* At this point, we are either in an instance method with no obscuring
9552      local definitions, or in a class method with no alternate definitions
9553      at all.  */
9554   return build_ivar_reference (id);
9555 }
9556
9557 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression.  This
9558    needs to be done if we are calling a function through a cast.  */
9559
9560 tree
9561 objc_rewrite_function_call (tree function, tree first_param)
9562 {
9563   if (TREE_CODE (function) == NOP_EXPR
9564       && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9565       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9566          == FUNCTION_DECL)
9567     {
9568       function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9569                          TREE_OPERAND (function, 0),
9570                          first_param, size_zero_node);
9571     }
9572
9573   return function;
9574 }
9575
9576 /* Look for the special case of OBJC_TYPE_REF with the address of
9577    a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9578    of its cousins).  */
9579
9580 int
9581 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
9582 {
9583   enum gimplify_status r0, r1;
9584   if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9585       && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9586       && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9587          == FUNCTION_DECL)
9588     {
9589       /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9590          value of the OBJ_TYPE_REF, so force them to be emitted
9591          during subexpression evaluation rather than after the
9592          OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9593          C to use direct rather than indirect calls when the
9594          object expression has a postincrement.  */
9595       r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9596                           is_gimple_val, fb_rvalue);
9597       r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9598                           is_gimple_val, fb_rvalue);
9599
9600       return MIN (r0, r1);
9601     }
9602
9603 #ifdef OBJCPLUS
9604   return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
9605 #else
9606   return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
9607 #endif
9608 }
9609
9610 #include "gt-objc-objc-act.h"