OSDN Git Service

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