OSDN Git Service

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