OSDN Git Service

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