OSDN Git Service

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