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