OSDN Git Service

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