OSDN Git Service

In gcc/:
[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 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
28
29 #ifdef OBJCPLUS
30 #include "cp-tree.h"
31 #else
32 #include "c-tree.h"
33 #include "c-lang.h"
34 #endif
35
36 #include "c-family/c-common.h"
37 #include "c-family/c-pragma.h"
38 #include "c-family/c-format.h"
39 #include "flags.h"
40 #include "langhooks.h"
41 #include "objc-act.h"
42 #include "input.h"
43 #include "function.h"
44 #include "output.h"
45 #include "toplev.h"
46 #include "ggc.h"
47 #include "debug.h"
48 #include "target.h"
49 #include "diagnostic-core.h"
50 #include "intl.h"
51 #include "cgraph.h"
52 #include "tree-iterator.h"
53 #include "hashtab.h"
54 #include "langhooks-def.h"
55
56 /* For default_tree_printer ().  */
57 #include "tree-pretty-print.h"
58
59 /* For enum gimplify_status */
60 #include "gimple.h"
61
62 #define OBJC_VOID_AT_END        void_list_node
63
64 static unsigned int should_call_super_dealloc = 0;
65
66 /* When building Objective-C++, we need in_late_binary_op.  */
67 #ifdef OBJCPLUS
68 bool in_late_binary_op = false;
69 #endif  /* OBJCPLUS */
70
71 /* When building Objective-C++, we are not linking against the C front-end
72    and so need to replicate the C tree-construction functions in some way.  */
73 #ifdef OBJCPLUS
74 #define OBJCP_REMAP_FUNCTIONS
75 #include "objcp-decl.h"
76 #endif  /* OBJCPLUS */
77
78 /* This is the default way of generating a method name.  */
79 /* This has the problem that "test_method:argument:" and
80    "test:method_argument:" will generate the same name
81    ("_i_Test__test_method_argument_" for an instance method of the
82    class "Test"), so you can't have them both in the same class!
83    Moreover, the demangling (going from
84    "_i_Test__test_method_argument" back to the original name) is
85    undefined because there are two correct ways of demangling the
86    name.  */
87 #ifndef OBJC_GEN_METHOD_LABEL
88 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
89   do {                                      \
90     char *temp;                             \
91     sprintf ((BUF), "_%s_%s_%s_%s",         \
92              ((IS_INST) ? "i" : "c"),       \
93              (CLASS_NAME),                  \
94              ((CAT_NAME)? (CAT_NAME) : ""), \
95              (SEL_NAME));                   \
96     for (temp = (BUF); *temp; temp++)       \
97       if (*temp == ':') *temp = '_';        \
98   } while (0)
99 #endif
100
101 /* These need specifying.  */
102 #ifndef OBJC_FORWARDING_STACK_OFFSET
103 #define OBJC_FORWARDING_STACK_OFFSET 0
104 #endif
105
106 #ifndef OBJC_FORWARDING_MIN_OFFSET
107 #define OBJC_FORWARDING_MIN_OFFSET 0
108 #endif
109 \f
110 /* Set up for use of obstacks.  */
111
112 #include "obstack.h"
113
114 /* This obstack is used to accumulate the encoding of a data type.  */
115 static struct obstack util_obstack;
116
117 /* This points to the beginning of obstack contents, so we can free
118    the whole contents.  */
119 char *util_firstobj;
120
121 /* The version identifies which language generation and runtime
122    the module (file) was compiled for, and is recorded in the
123    module descriptor.  */
124
125 #define OBJC_VERSION    (flag_next_runtime ? 6 : 8)
126 #define PROTOCOL_VERSION 2
127
128 /* (Decide if these can ever be validly changed.) */
129 #define OBJC_ENCODE_INLINE_DEFS         0
130 #define OBJC_ENCODE_DONT_INLINE_DEFS    1
131
132 /*** Private Interface (procedures) ***/
133
134 /* Used by compile_file.  */
135
136 static void init_objc (void);
137 static void finish_objc (void);
138
139 /* Code generation.  */
140
141 static tree objc_build_constructor (tree, VEC(constructor_elt,gc) *);
142 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
143 static tree get_proto_encoding (tree);
144 static tree lookup_interface (tree);
145 static tree objc_add_static_instance (tree, tree);
146
147 static tree start_class (enum tree_code, tree, tree, tree);
148 static tree continue_class (tree);
149 static void finish_class (tree);
150 static void start_method_def (tree);
151 #ifdef OBJCPLUS
152 static void objc_start_function (tree, tree, tree, tree);
153 #else
154 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
155 #endif
156 static tree start_protocol (enum tree_code, tree, tree);
157 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
158 static tree objc_add_method (tree, tree, int, bool);
159 static tree add_instance_variable (tree, objc_ivar_visibility_kind, tree);
160 static tree build_ivar_reference (tree);
161 static tree is_ivar (tree, tree);
162
163 static void build_objc_exception_stuff (void);
164 static void build_next_objc_exception_stuff (void);
165
166 /* We only need the following for ObjC; ObjC++ will use C++'s definition
167    of DERIVED_FROM_P.  */
168 #ifndef OBJCPLUS
169 static bool objc_derived_from_p (tree, tree);
170 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
171 #endif
172
173 /* Property.  */
174 static void objc_gen_property_data (tree, tree);
175 static void objc_synthesize_getter (tree, tree, tree);
176 static void objc_synthesize_setter (tree, tree, tree);
177 static char *objc_build_property_setter_name (tree);
178 static int match_proto_with_proto (tree, tree, int);
179 static tree lookup_property (tree, tree);
180 static tree lookup_property_in_list (tree, tree);
181 static tree lookup_property_in_protocol_list (tree, tree);
182 static void build_objc_property_accessor_helpers (void);
183
184 static void objc_xref_basetypes (tree, tree);
185
186 static void build_class_template (void);
187 static void build_selector_template (void);
188 static void build_category_template (void);
189 static void build_super_template (void);
190 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
191 static tree get_class_ivars (tree, bool);
192 static tree generate_protocol_list (tree);
193 static void build_protocol_reference (tree);
194
195 static void build_fast_enumeration_state_template (void);
196
197 #ifdef OBJCPLUS
198 static void objc_generate_cxx_cdtors (void);
199 #endif
200
201 /* objc attribute */
202 static void objc_decl_method_attributes (tree*, tree, int); 
203 static tree build_keyword_selector (tree);
204 static const char *synth_id_with_class_suffix (const char *, tree);
205
206 /* Hash tables to manage the global pool of method prototypes.  */
207
208 hash *nst_method_hash_list = 0;
209 hash *cls_method_hash_list = 0;
210
211 /* Hash tables to manage the global pool of class names.  */
212
213 hash *cls_name_hash_list = 0;
214 hash *als_name_hash_list = 0;
215
216 static void hash_class_name_enter (hash *, tree, tree);
217 static hash hash_class_name_lookup (hash *, tree);
218
219 static hash hash_lookup (hash *, tree);
220 static tree lookup_method (tree, tree);
221 static tree lookup_method_static (tree, tree, int);
222
223 static tree add_class (tree, tree);
224 static void add_category (tree, tree);
225 static inline tree lookup_category (tree, tree);
226
227 enum string_section
228 {
229   class_names,          /* class, category, protocol, module names */
230   meth_var_names,       /* method and variable names */
231   meth_var_types        /* method and variable type descriptors */
232 };
233
234 static tree add_objc_string (tree, enum string_section);
235 static void build_selector_table_decl (void);
236
237 /* Protocol additions.  */
238
239 static tree lookup_protocol (tree);
240 static tree lookup_and_install_protocols (tree);
241
242 /* Type encoding.  */
243
244 static void encode_type_qualifiers (tree);
245 static void encode_type (tree, int, int);
246 static void encode_field_decl (tree, int, int);
247
248 #ifdef OBJCPLUS
249 static void really_start_method (tree, tree);
250 #else
251 static void really_start_method (tree, struct c_arg_info *);
252 #endif
253 static int comp_proto_with_proto (tree, tree, int);
254 static tree get_arg_type_list (tree, int, int);
255 static tree objc_decay_parm_type (tree);
256 static void objc_push_parm (tree);
257 #ifdef OBJCPLUS
258 static tree objc_get_parm_info (int);
259 #else
260 static struct c_arg_info *objc_get_parm_info (int);
261 #endif
262
263 /* Utilities for debugging and error diagnostics.  */
264
265 static char *gen_type_name (tree);
266 static char *gen_type_name_0 (tree);
267 static char *gen_method_decl (tree);
268 static char *gen_declaration (tree);
269
270 /* Everything else.  */
271
272 static tree create_field_decl (tree, const char *);
273 static void add_class_reference (tree);
274 static void build_protocol_template (void);
275 static tree encode_method_prototype (tree);
276 static void generate_classref_translation_entry (tree);
277 static void handle_class_ref (tree);
278 static void generate_struct_by_value_array (void)
279      ATTRIBUTE_NORETURN;
280 static void mark_referenced_methods (void);
281 static void generate_objc_image_info (void);
282 static bool objc_type_valid_for_messaging (tree type, bool allow_classes);
283
284 /*** Private Interface (data) ***/
285
286 /* Reserved tag definitions.  */
287
288 #define OBJECT_TYPEDEF_NAME             "id"
289 #define CLASS_TYPEDEF_NAME              "Class"
290
291 #define TAG_OBJECT                      "objc_object"
292 #define TAG_CLASS                       "objc_class"
293 #define TAG_SUPER                       "objc_super"
294 #define TAG_SELECTOR                    "objc_selector"
295
296 #define UTAG_CLASS                      "_objc_class"
297 #define UTAG_IVAR                       "_objc_ivar"
298 #define UTAG_IVAR_LIST                  "_objc_ivar_list"
299 #define UTAG_METHOD                     "_objc_method"
300 #define UTAG_METHOD_LIST                "_objc_method_list"
301 #define UTAG_CATEGORY                   "_objc_category"
302 #define UTAG_MODULE                     "_objc_module"
303 #define UTAG_SYMTAB                     "_objc_symtab"
304 #define UTAG_SUPER                      "_objc_super"
305 #define UTAG_SELECTOR                   "_objc_selector"
306
307 #define UTAG_PROTOCOL                   "_objc_protocol"
308 #define UTAG_METHOD_PROTOTYPE           "_objc_method_prototype"
309 #define UTAG_METHOD_PROTOTYPE_LIST      "_objc__method_prototype_list"
310
311 /* Note that the string object global name is only needed for the
312    NeXT runtime.  */
313 #define STRING_OBJECT_GLOBAL_FORMAT     "_%sClassReference"
314
315 #define PROTOCOL_OBJECT_CLASS_NAME      "Protocol"
316
317 #define TAG_ENUMERATION_MUTATION        "objc_enumerationMutation"
318 #define TAG_FAST_ENUMERATION_STATE      "__objcFastEnumerationState"
319
320 static const char *TAG_GETCLASS;
321 static const char *TAG_GETMETACLASS;
322 static const char *TAG_MSGSEND;
323 static const char *TAG_MSGSENDSUPER;
324 /* The NeXT Objective-C messenger may have two extra entry points, for use
325    when returning a structure. */
326 static const char *TAG_MSGSEND_STRET;
327 static const char *TAG_MSGSENDSUPER_STRET;
328 static const char *default_constant_string_class_name;
329
330 /* Runtime metadata flags.  */
331 #define CLS_FACTORY                     0x0001L
332 #define CLS_META                        0x0002L
333 #define CLS_HAS_CXX_STRUCTORS           0x2000L
334
335 #define OBJC_MODIFIER_STATIC            0x00000001
336 #define OBJC_MODIFIER_FINAL             0x00000002
337 #define OBJC_MODIFIER_PUBLIC            0x00000004
338 #define OBJC_MODIFIER_PRIVATE           0x00000008
339 #define OBJC_MODIFIER_PROTECTED         0x00000010
340 #define OBJC_MODIFIER_NATIVE            0x00000020
341 #define OBJC_MODIFIER_SYNCHRONIZED      0x00000040
342 #define OBJC_MODIFIER_ABSTRACT          0x00000080
343 #define OBJC_MODIFIER_VOLATILE          0x00000100
344 #define OBJC_MODIFIER_TRANSIENT         0x00000200
345 #define OBJC_MODIFIER_NONE_SPECIFIED    0x80000000
346
347 /* NeXT-specific tags.  */
348
349 #define TAG_MSGSEND_NONNIL              "objc_msgSendNonNil"
350 #define TAG_MSGSEND_NONNIL_STRET        "objc_msgSendNonNil_stret"
351 #define TAG_EXCEPTIONEXTRACT            "objc_exception_extract"
352 #define TAG_EXCEPTIONTRYENTER           "objc_exception_try_enter"
353 #define TAG_EXCEPTIONTRYEXIT            "objc_exception_try_exit"
354 #define TAG_EXCEPTIONMATCH              "objc_exception_match"
355 #define TAG_EXCEPTIONTHROW              "objc_exception_throw"
356 #define TAG_SYNCENTER                   "objc_sync_enter"
357 #define TAG_SYNCEXIT                    "objc_sync_exit"
358 #define TAG_SETJMP                      "_setjmp"
359 #define UTAG_EXCDATA                    "_objc_exception_data"
360
361 #define TAG_ASSIGNIVAR                  "objc_assign_ivar"
362 #define TAG_ASSIGNGLOBAL                "objc_assign_global"
363 #define TAG_ASSIGNSTRONGCAST            "objc_assign_strongCast"
364
365 /* Branch entry points.  All that matters here are the addresses;
366    functions with these names do not really exist in libobjc.  */
367
368 #define TAG_MSGSEND_FAST                "objc_msgSend_Fast"
369 #define TAG_ASSIGNIVAR_FAST             "objc_assign_ivar_Fast"
370
371 #define TAG_CXX_CONSTRUCT               ".cxx_construct"
372 #define TAG_CXX_DESTRUCT                ".cxx_destruct"
373
374 /* GNU-specific tags.  */
375
376 #define TAG_EXECCLASS                   "__objc_exec_class"
377 #define TAG_GNUINIT                     "__objc_gnu_init"
378
379 /* Flags for lookup_method_static().  */
380
381 /* Look for class methods.  */
382 #define OBJC_LOOKUP_CLASS       1
383 /* Do not examine superclasses.  */
384 #define OBJC_LOOKUP_NO_SUPER    2
385 /* Disable returning an instance method of a root class when a class
386    method can't be found.  */
387 #define OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS 4 
388
389 /* The OCTI_... enumeration itself is in objc/objc-act.h.  */
390 tree objc_global_trees[OCTI_MAX];
391
392 static void handle_impent (struct imp_entry *);
393
394 struct imp_entry *imp_list = 0;
395 int imp_count = 0;      /* `@implementation' */
396 int cat_count = 0;      /* `@category' */
397
398 objc_ivar_visibility_kind objc_ivar_visibility;
399
400 /* Use to generate method labels.  */
401 static int method_slot = 0;
402
403 /* Flag to say whether methods in a protocol are optional or
404    required.  */
405 static bool objc_method_optional_flag = false;
406
407 static int objc_collecting_ivars = 0;
408
409 #define BUFSIZE         1024
410
411 static char *errbuf;    /* Buffer for error diagnostics */
412
413 /* Data imported from tree.c.  */
414
415 extern enum debug_info_type write_symbols;
416
417 \f
418 static int flag_typed_selectors;
419
420 /* Store all constructed constant strings in a hash table so that
421    they get uniqued properly.  */
422
423 struct GTY(()) string_descriptor {
424   /* The literal argument .  */
425   tree literal;
426
427   /* The resulting constant string.  */
428   tree constructor;
429 };
430
431 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
432
433 FILE *gen_declaration_file;
434
435 /* Tells "encode_pointer/encode_aggregate" whether we are generating
436    type descriptors for instance variables (as opposed to methods).
437    Type descriptors for instance variables contain more information
438    than methods (for static typing and embedded structures).  */
439
440 static int generating_instance_variables = 0;
441
442 /* For building an objc struct.  These may not be used when this file
443    is compiled as part of obj-c++.  */
444
445 static bool objc_building_struct;
446 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
447
448 /* Start building a struct for objc.  */
449
450 static tree
451 objc_start_struct (tree name)
452 {
453   gcc_assert (!objc_building_struct);
454   objc_building_struct = true;
455   return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
456 }
457
458 /* Finish building a struct for objc.  */
459
460 static tree
461 objc_finish_struct (tree type, tree fieldlist)
462 {
463   gcc_assert (objc_building_struct);
464   objc_building_struct = false;
465   return finish_struct (input_location, type, fieldlist, NULL_TREE,
466                         objc_struct_info);
467 }
468
469 static tree
470 build_sized_array_type (tree base_type, int size)
471 {
472   tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
473   return build_array_type (base_type, index_type);
474 }
475
476 static tree
477 add_field_decl (tree type, const char *name, tree **chain)
478 {
479   tree field = create_field_decl (type, name);
480
481   if (*chain != NULL)
482     **chain = field;
483   *chain = &DECL_CHAIN (field);
484
485   return field;
486 }
487
488 /* Create a temporary variable of type 'type'.  If 'name' is set, uses
489    the specified name, else use no name.  Returns the declaration of
490    the type.  The 'name' is mostly useful for debugging.
491 */
492 static tree
493 objc_create_temporary_var (tree type, const char *name)
494 {
495   tree decl;
496
497   if (name != NULL)
498     {
499       decl = build_decl (input_location,
500                          VAR_DECL, get_identifier (name), type);
501     }
502   else
503     {
504       decl = build_decl (input_location,
505                          VAR_DECL, NULL_TREE, type);
506     }
507   TREE_USED (decl) = 1;
508   DECL_ARTIFICIAL (decl) = 1;
509   DECL_IGNORED_P (decl) = 1;
510   DECL_CONTEXT (decl) = current_function_decl;
511
512   return decl;
513 }
514
515 /* Some platforms pass small structures through registers versus
516    through an invisible pointer.  Determine at what size structure is
517    the transition point between the two possibilities.  */
518
519 static void
520 generate_struct_by_value_array (void)
521 {
522   tree type;
523   tree decls;
524   int i, j;
525   int aggregate_in_mem[32];
526   int found = 0;
527
528   /* Presumably no platform passes 32 byte structures in a register.  */
529   for (i = 1; i < 32; i++)
530     {
531       char buffer[5];
532       tree *chain = NULL;
533
534       /* Create an unnamed struct that has `i' character components */
535       type = objc_start_struct (NULL_TREE);
536
537       strcpy (buffer, "c1");
538       decls = add_field_decl (char_type_node, buffer, &chain);
539
540       for (j = 1; j < i; j++)
541         {
542           sprintf (buffer, "c%d", j + 1);
543           add_field_decl (char_type_node, buffer, &chain);
544         }
545       objc_finish_struct (type, decls);
546
547       aggregate_in_mem[i] = aggregate_value_p (type, 0);
548       if (!aggregate_in_mem[i])
549         found = 1;
550     }
551
552   /* We found some structures that are returned in registers instead of memory
553      so output the necessary data.  */
554   if (found)
555     {
556       for (i = 31; i >= 0;  i--)
557         if (!aggregate_in_mem[i])
558           break;
559       printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
560
561       /* The first member of the structure is always 0 because we don't handle
562          structures with 0 members */
563       printf ("static int struct_forward_array[] = {\n  0");
564
565       for (j = 1; j <= i; j++)
566         printf (", %d", aggregate_in_mem[j]);
567       printf ("\n};\n");
568     }
569
570   exit (0);
571 }
572
573 bool
574 objc_init (void)
575 {
576 #ifdef OBJCPLUS
577   if (cxx_init () == false)
578 #else
579   if (c_objc_common_init () == false)
580 #endif
581     return false;
582
583   /* If gen_declaration desired, open the output file.  */
584   if (flag_gen_declaration)
585     {
586       register char * const dumpname = concat (dump_base_name, ".decl", NULL);
587       gen_declaration_file = fopen (dumpname, "w");
588       if (gen_declaration_file == 0)
589         fatal_error ("can%'t open %s: %m", dumpname);
590       free (dumpname);
591     }
592
593   if (flag_next_runtime)
594     {
595       TAG_GETCLASS = "objc_getClass";
596       TAG_GETMETACLASS = "objc_getMetaClass";
597       TAG_MSGSEND = "objc_msgSend";
598       TAG_MSGSENDSUPER = "objc_msgSendSuper";
599       TAG_MSGSEND_STRET = "objc_msgSend_stret";
600       TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
601       default_constant_string_class_name = "NSConstantString";
602     }
603   else
604     {
605       TAG_GETCLASS = "objc_get_class";
606       TAG_GETMETACLASS = "objc_get_meta_class";
607       TAG_MSGSEND = "objc_msg_lookup";
608       TAG_MSGSENDSUPER = "objc_msg_lookup_super";
609       /* GNU runtime does not provide special functions to support
610          structure-returning methods.  */
611       default_constant_string_class_name = "NXConstantString";
612       flag_typed_selectors = 1;
613       /* GNU runtime does not need the compiler to change code
614          in order to do GC. */
615       if (flag_objc_gc)
616         {
617           warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
618           flag_objc_gc=0;
619         }
620     }
621
622   init_objc ();
623
624   if (print_struct_values && !flag_compare_debug)
625     generate_struct_by_value_array ();
626
627   return true;
628 }
629
630 /* This is called automatically (at the very end of compilation) by
631    c_write_global_declarations and cp_write_global_declarations.  */
632 void
633 objc_write_global_declarations (void)
634 {
635   mark_referenced_methods ();
636
637   /* Finalize Objective-C runtime data.  */
638   finish_objc ();
639
640   if (gen_declaration_file)
641     fclose (gen_declaration_file);
642 }
643 \f
644 /* Return the first occurrence of a method declaration corresponding
645    to sel_name in rproto_list.  Search rproto_list recursively.
646    If is_class is 0, search for instance methods, otherwise for class
647    methods.  */
648 static tree
649 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
650                                 int is_class)
651 {
652    tree rproto, p;
653    tree fnd = 0;
654
655    for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
656      {
657         p = TREE_VALUE (rproto);
658
659         if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
660           {
661             if ((fnd = lookup_method (is_class
662                                       ? PROTOCOL_CLS_METHODS (p)
663                                       : PROTOCOL_NST_METHODS (p), sel_name)))
664               ;
665             else if (PROTOCOL_LIST (p))
666               fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
667                                                     sel_name, is_class);
668           }
669         else
670           {
671             ; /* An identifier...if we could not find a protocol.  */
672           }
673
674         if (fnd)
675           return fnd;
676      }
677
678    return 0;
679 }
680
681 static tree
682 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
683 {
684   tree rproto, p;
685
686   /* Make sure the protocol is supported by the object on the rhs.  */
687   if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
688     {
689       tree fnd = 0;
690       for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
691         {
692           p = TREE_VALUE (rproto);
693
694           if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
695             {
696               if (lproto == p)
697                 fnd = lproto;
698
699               else if (PROTOCOL_LIST (p))
700                 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
701             }
702
703           if (fnd)
704             return fnd;
705         }
706     }
707   else
708     {
709       ; /* An identifier...if we could not find a protocol.  */
710     }
711
712   return 0;
713 }
714
715 void
716 objc_start_class_interface (tree klass, tree super_class,
717                             tree protos, tree attributes)
718 {
719   if (attributes)
720     {
721       if (flag_objc1_only)
722         error_at (input_location, "class attributes are not available in Objective-C 1.0");
723       else
724         warning_at (input_location, OPT_Wattributes, 
725                     "class attributes are not available in this version"
726                     " of the compiler, (ignored)");
727     }
728   objc_interface_context
729     = objc_ivar_context
730     = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
731   objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
732 }
733
734 void
735 objc_start_category_interface (tree klass, tree categ,
736                                tree protos, tree attributes)
737 {
738   if (attributes)
739     {
740       if (flag_objc1_only)
741         error_at (input_location, "category attributes are not available in Objective-C 1.0");
742       else
743         warning_at (input_location, OPT_Wattributes, 
744                     "category attributes are not available in this version"
745                     " of the compiler, (ignored)");
746     }
747   objc_interface_context
748     = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
749   objc_ivar_chain
750     = continue_class (objc_interface_context);
751 }
752
753 void
754 objc_start_protocol (tree name, tree protos, tree attributes)
755 {
756   if (attributes)
757     {
758       if (flag_objc1_only)
759         error_at (input_location, "protocol attributes are not available in Objective-C 1.0");  
760       else
761         warning_at (input_location, OPT_Wattributes, 
762                     "protocol attributes are not available in this version"
763                     " of the compiler, (ignored)");
764     }
765   objc_interface_context
766     = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
767   objc_method_optional_flag = false;
768 }
769
770 void
771 objc_continue_interface (void)
772 {
773   objc_ivar_chain
774     = continue_class (objc_interface_context);
775 }
776
777 void
778 objc_finish_interface (void)
779 {
780   finish_class (objc_interface_context);
781   objc_interface_context = NULL_TREE;
782   objc_method_optional_flag = false;
783 }
784
785 void
786 objc_start_class_implementation (tree klass, tree super_class)
787 {
788   objc_implementation_context
789     = objc_ivar_context
790     = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
791   objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
792 }
793
794 void
795 objc_start_category_implementation (tree klass, tree categ)
796 {
797   objc_implementation_context
798     = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
799   objc_ivar_chain
800     = continue_class (objc_implementation_context);
801 }
802
803 void
804 objc_continue_implementation (void)
805 {
806   objc_ivar_chain
807     = continue_class (objc_implementation_context);
808 }
809
810 void
811 objc_finish_implementation (void)
812 {
813 #ifdef OBJCPLUS
814   if (flag_objc_call_cxx_cdtors)
815     objc_generate_cxx_cdtors ();
816 #endif
817
818   if (objc_implementation_context)
819     {
820       finish_class (objc_implementation_context);
821       objc_ivar_chain = NULL_TREE;
822       objc_implementation_context = NULL_TREE;
823     }
824   else
825     warning (0, "%<@end%> must appear in an @implementation context");
826 }
827
828 void
829 objc_set_visibility (objc_ivar_visibility_kind visibility)
830 {
831   if (visibility == OBJC_IVAR_VIS_PACKAGE)
832     {
833       if (flag_objc1_only)
834         error ("%<@package%> is not available in Objective-C 1.0");
835       else
836         warning (0, "%<@package%> presently has the same effect as %<@public%>");
837     }
838   objc_ivar_visibility = visibility;
839 }
840
841 void
842 objc_set_method_opt (bool optional)
843 {
844   if (flag_objc1_only)
845     error_at (input_location, "@optional/@required are not available in Objective-C 1.0");      
846
847   objc_method_optional_flag = optional;
848   if (!objc_interface_context 
849       || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
850     {
851       error ("@optional/@required is allowed in @protocol context only");
852       objc_method_optional_flag = false;
853     }
854 }
855
856 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
857    PROTOCOL.  */
858 static tree
859 lookup_property_in_list (tree chain, tree property)
860 {
861   tree x;
862   for (x = CLASS_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
863     if (PROPERTY_NAME (x) == property)
864       return x;
865   return NULL_TREE;
866 }
867
868 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
869 static tree lookup_property_in_protocol_list (tree rproto_list, tree property)
870 {
871   tree rproto, x;
872   for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
873     {
874       tree p = TREE_VALUE (rproto);
875       if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
876         {
877           if ((x = lookup_property_in_list (p, property)))
878             return x;
879           if (PROTOCOL_LIST (p))
880             return lookup_property_in_protocol_list (PROTOCOL_LIST (p), property);
881         }
882       else
883         {
884           ; /* An identifier...if we could not find a protocol.  */
885         }
886     }
887   return NULL_TREE;
888 }
889
890 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
891    chain of interface hierarchy.  */
892 static tree
893 lookup_property (tree interface_type, tree property)
894 {
895   tree inter = interface_type;
896   while (inter)
897     {
898       tree x, category;
899       if ((x = lookup_property_in_list (inter, property)))
900         return x;
901       /* Failing that, look for the property in each category of the class.  */
902       category = inter;
903       while ((category = CLASS_CATEGORY_LIST (category)))
904         {
905           if ((x = lookup_property_in_list (category, property)))
906             return x;
907
908           /* When checking a category, also check the protocols
909              attached with the category itself.  */
910           if (CLASS_PROTOCOL_LIST (category)
911               && (x = lookup_property_in_protocol_list
912                   (CLASS_PROTOCOL_LIST (category), property)))
913             return x;
914         }
915
916       /*  Failing to find in categories, look for property in protocol list. */
917       if (CLASS_PROTOCOL_LIST (inter) 
918           && (x = lookup_property_in_protocol_list
919               (CLASS_PROTOCOL_LIST (inter), property)))
920         return x;
921       
922       /* Failing that, climb up the inheritance hierarchy.  */
923       inter = lookup_interface (CLASS_SUPER_NAME (inter));
924     }
925   return inter;
926 }
927
928 /* This routine is called by the parser when a
929    @property... declaration is found.  'decl' is the declaration of
930    the property (type/identifier), and the other arguments represent
931    property attributes that may have been specified in the Objective-C
932    declaration.  'parsed_property_readonly' is 'true' if the attribute
933    'readonly' was specified, and 'false' if not; similarly for the
934    other bool parameters.  'parsed_property_getter_ident' is NULL_TREE
935    if the attribute 'getter' was not specified, and is the identifier
936    corresponding to the specified getter if it was; similarly for
937    'parsed_property_setter_ident'.  */
938 void
939 objc_add_property_declaration (location_t location, tree decl,
940                                bool parsed_property_readonly, bool parsed_property_readwrite,
941                                bool parsed_property_assign, bool parsed_property_retain,
942                                bool parsed_property_copy, bool parsed_property_nonatomic,
943                                tree parsed_property_getter_ident, tree parsed_property_setter_ident)
944 {
945   tree property_decl;
946   tree x;
947   /* 'property_readonly' and 'property_assign_semantics' are the final
948      attributes of the property after all parsed attributes have been
949      considered (eg, if we parsed no 'readonly' and no 'readwrite', ie
950      parsed_property_readonly = false and parsed_property_readwrite =
951      false, then property_readonly will be false because the default
952      is readwrite).  */
953   bool property_readonly = false;
954   objc_property_assign_semantics property_assign_semantics = OBJC_PROPERTY_ASSIGN;
955
956   if (flag_objc1_only)
957     error_at (input_location, "%<@property%> is not available in Objective-C 1.0");
958
959   if (parsed_property_readonly && parsed_property_readwrite)
960     {
961       error_at (location, "%<readonly%> attribute conflicts with %<readwrite%> attribute");
962       /* In case of conflicting attributes (here and below), after
963          producing an error, we pick one of the attributes and keep
964          going.  */
965       property_readonly = false;
966     }
967   else
968     {
969       if (parsed_property_readonly)
970         property_readonly = true;
971   
972       if (parsed_property_readwrite)
973         property_readonly = false;
974     }
975
976   if (parsed_property_readonly && parsed_property_setter_ident)
977     {
978       error_at (location, "%<readonly%> attribute conflicts with %<setter%> attribute");
979       property_readonly = false;
980     }
981
982   if (parsed_property_assign && parsed_property_retain)
983     {
984       error_at (location, "%<assign%> attribute conflicts with %<retain%> attribute");
985       property_assign_semantics = OBJC_PROPERTY_RETAIN;
986     }
987   else if (parsed_property_assign && parsed_property_copy)
988     {
989       error_at (location, "%<assign%> attribute conflicts with %<copy%> attribute");
990       property_assign_semantics = OBJC_PROPERTY_COPY;
991     }
992   else if (parsed_property_retain && parsed_property_copy)
993     {
994       error_at (location, "%<retain%> attribute conflicts with %<copy%> attribute");
995       property_assign_semantics = OBJC_PROPERTY_COPY;
996     }
997   else
998     {
999       if (parsed_property_assign)
1000         property_assign_semantics = OBJC_PROPERTY_ASSIGN;
1001
1002       if (parsed_property_retain)
1003         property_assign_semantics = OBJC_PROPERTY_RETAIN;
1004
1005       if (parsed_property_copy)
1006         property_assign_semantics = OBJC_PROPERTY_COPY;
1007     }
1008
1009   if (!objc_interface_context)
1010     {
1011       error_at (location, "property declaration not in @interface or @protocol context");
1012       return;
1013     }
1014
1015   /* At this point we know that we are either in an interface, a
1016      category, or a protocol.  */
1017
1018   /* We expect a FIELD_DECL from the parser.  Make sure we didn't get
1019      something else, as that would confuse the checks below.  */
1020   if (TREE_CODE (decl) != FIELD_DECL)
1021     {
1022       error_at (location, "invalid property declaration");
1023       return;      
1024     }
1025
1026   /* Do some spot-checks for the most obvious invalid types.  */
1027
1028   if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1029     {
1030       error_at (location, "property can not be an array");
1031       return;
1032     }
1033
1034   /* The C++/ObjC++ parser seems to reject the ':' for a bitfield when
1035      parsing, while the C/ObjC parser accepts it and gives us a
1036      FIELD_DECL with a DECL_INITIAL set.  So we use the DECL_INITIAL
1037      to check for a bitfield when doing ObjC.  */
1038 #ifndef OBJCPLUS
1039   if (DECL_INITIAL (decl))
1040     {
1041       /* A @property is not an actual variable, but it is a way to
1042          describe a pair of accessor methods, so its type (which is
1043          the type of the return value of the getter and the first
1044          argument of the setter) can't be a bitfield (as return values
1045          and arguments of functions can not be bitfields).  The
1046          underlying instance variable could be a bitfield, but that is
1047          a different matter.  */
1048       error_at (location, "property can not be a bit-field");
1049       return;      
1050     }
1051 #endif
1052
1053   /* TODO: Check that the property type is an Objective-C object or a
1054      "POD".  */
1055
1056   /* Implement -Wproperty-assign-default (which is enabled by default).  */
1057   if (warn_property_assign_default
1058       /* If garbage collection is not being used, then 'assign' is
1059          valid for objects (and typically used for delegates) but it
1060          is wrong in most cases (since most objects need to be
1061          retained or copied in setters).  Warn users when 'assign' is
1062          used implicitly.  */
1063       && property_assign_semantics == OBJC_PROPERTY_ASSIGN
1064       /* Read-only properties are never assigned, so the assignment
1065          semantics do not matter in that case.  */
1066       && !property_readonly
1067       && !flag_objc_gc)
1068     {
1069       /* Please note that it would make sense to default to 'assign'
1070          for non-{Objective-C objects}, and to 'retain' for
1071          Objective-C objects.  But that would break compatibility with
1072          other compilers.  */
1073       if (!parsed_property_assign && !parsed_property_retain && !parsed_property_copy)
1074         {
1075           /* Use 'false' so we do not warn for Class objects.  */
1076           if (objc_type_valid_for_messaging (TREE_TYPE (decl), false))
1077             {
1078               warning_at (location, 
1079                           0,
1080                           "object property %qD has no %<assign%>, %<retain%> or %<copy%> attribute; assuming %<assign%>", 
1081                           decl);
1082               inform (location, 
1083                       "%<assign%> can be unsafe for Objective-C objects; please state explicitly if you need it");
1084             }
1085         }
1086     }
1087   
1088   if (property_assign_semantics == OBJC_PROPERTY_RETAIN
1089       && !objc_type_valid_for_messaging (TREE_TYPE (decl), true))
1090     error_at (location, "%<retain%> attribute is only valid for Objective-C objects");
1091   
1092   if (property_assign_semantics == OBJC_PROPERTY_COPY
1093       && !objc_type_valid_for_messaging (TREE_TYPE (decl), true))
1094     error_at (location, "%<copy%> attribute is only valid for Objective-C objects");
1095
1096   /* Now determine the final property getter and setter names.  They
1097      will be stored in the PROPERTY_DECL, from which they'll always be
1098      extracted and used.  */
1099
1100   /* Adjust, or fill in, setter and getter names.  We overwrite the
1101      parsed_property_setter_ident and parsed_property_getter_ident
1102      with the final setter and getter identifiers that will be
1103      used.  */
1104   if (parsed_property_setter_ident)
1105     {
1106       /* The setter should be terminated by ':', but the parser only
1107          gives us an identifier without ':'.  So, we need to add ':'
1108          at the end.  */
1109       const char *parsed_setter = IDENTIFIER_POINTER (parsed_property_setter_ident);
1110       size_t length = strlen (parsed_setter);
1111       char *final_setter = (char *)alloca (length + 2);
1112
1113       sprintf (final_setter, "%s:", parsed_setter);
1114       parsed_property_setter_ident = get_identifier (final_setter);
1115     }
1116   else
1117     {
1118       if (!property_readonly)
1119         parsed_property_setter_ident = get_identifier (objc_build_property_setter_name 
1120                                                        (DECL_NAME (decl)));
1121     }
1122
1123   if (!parsed_property_getter_ident)
1124     parsed_property_getter_ident = DECL_NAME (decl);
1125
1126   /* Check for duplicate property declarations.  We first check the
1127      immediate context for a property with the same name.  Any such
1128      declarations are an error.  */
1129   for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
1130     {
1131       if (PROPERTY_NAME (x) == DECL_NAME (decl))
1132         {
1133           location_t original_location = DECL_SOURCE_LOCATION (x);
1134           
1135           error_at (location, "redeclaration of property %qD", decl);
1136
1137           if (original_location != UNKNOWN_LOCATION)
1138             inform (original_location, "originally specified here");
1139           return;
1140       }
1141     }
1142
1143   /* We now need to check for existing property declarations (in the
1144      superclass, other categories or protocols) and check that the new
1145      declaration is not in conflict with existing ones.  */
1146
1147   /* Search for a previous, existing declaration of a property with
1148      the same name in superclasses, protocols etc.  If one is found,
1149      it will be in the 'x' variable.  */
1150   x = NULL_TREE;
1151
1152   /* Note that, for simplicity, the following may search again the
1153      local context.  That's Ok as nothing will be found (else we'd
1154      have thrown an error above); it's only a little inefficient, but
1155      the code is simpler.  */
1156   switch (TREE_CODE (objc_interface_context))
1157     {
1158     case CLASS_INTERFACE_TYPE:
1159       /* Look up the property in the current @interface (which will
1160          find nothing), then its protocols and categories and
1161          superclasses.  */
1162       x = lookup_property (objc_interface_context, DECL_NAME (decl));
1163       break;
1164     case CATEGORY_INTERFACE_TYPE:
1165       /* Look up the property in the main @interface, then protocols
1166          and categories (one of them is ours, and will find nothing)
1167          and superclasses.  */
1168       x = lookup_property (lookup_interface (CLASS_NAME (objc_interface_context)),
1169                            DECL_NAME (decl));
1170       break;
1171     case PROTOCOL_INTERFACE_TYPE:
1172       /* Looks up the property in any protocols attached to the
1173          current protocol.  */
1174       if (PROTOCOL_LIST (objc_interface_context))
1175         {
1176           x = lookup_property_in_protocol_list (PROTOCOL_LIST (objc_interface_context),
1177                                                 DECL_NAME (decl));
1178         }
1179       break;
1180     default:
1181       gcc_unreachable ();
1182     }
1183
1184   if (x != NULL_TREE)
1185     {
1186       /* An existing property was found; check that it has the same
1187          types, or it is compatible.  */
1188       location_t original_location = DECL_SOURCE_LOCATION (x);
1189           
1190       if (PROPERTY_NONATOMIC (x) != parsed_property_nonatomic)
1191         {
1192           warning_at (location, 0,
1193                       "'nonatomic' attribute of property %qD conflicts with previous declaration", decl);
1194       
1195           if (original_location != UNKNOWN_LOCATION)
1196             inform (original_location, "originally specified here");
1197           return;
1198         }
1199
1200       if (PROPERTY_GETTER_NAME (x) != parsed_property_getter_ident)
1201         {
1202           warning_at (location, 0,
1203                       "'getter' attribute of property %qD conflicts with previous declaration", decl);
1204       
1205           if (original_location != UNKNOWN_LOCATION)
1206             inform (original_location, "originally specified here");
1207           return;
1208         }
1209
1210       /* We can only compare the setter names if both the old and new property have a setter.  */
1211       if (!property_readonly  &&  !PROPERTY_READONLY(x))
1212         {
1213           if (PROPERTY_SETTER_NAME (x) != parsed_property_setter_ident)
1214             {
1215               warning_at (location, 0,
1216                           "'setter' attribute of property %qD conflicts with previous declaration", decl);
1217               
1218               if (original_location != UNKNOWN_LOCATION)
1219                 inform (original_location, "originally specified here");
1220               return;
1221             }
1222         }
1223
1224       if (PROPERTY_ASSIGN_SEMANTICS (x) != property_assign_semantics)
1225         {
1226           warning_at (location, 0,
1227                       "assign semantics attributes of property %qD conflict with previous declaration", decl);
1228       
1229           if (original_location != UNKNOWN_LOCATION)
1230             inform (original_location, "originally specified here");
1231           return;
1232         }
1233
1234       /* It's ok to have a readonly property that becomes a readwrite, but not vice versa.  */
1235       if (PROPERTY_READONLY (x) == 0  &&  property_readonly == 1)
1236         {
1237           warning_at (location, 0,
1238                       "'readonly' attribute of property %qD conflicts with previous declaration", decl);
1239       
1240           if (original_location != UNKNOWN_LOCATION)
1241             inform (original_location, "originally specified here");
1242           return;
1243         }
1244
1245       /* We now check that the new and old property declarations have
1246          the same types (or compatible one).  In the Objective-C
1247          tradition of loose type checking, we do type-checking but
1248          only generate warnings (not errors) if they do not match.
1249          For non-readonly properties, the types must match exactly;
1250          for readonly properties, it is allowed to use a "more
1251          specialized" type in the new property declaration.  Eg, the
1252          superclass has a getter returning (NSArray *) and the
1253          subclass a getter returning (NSMutableArray *).  The object's
1254          getter returns an (NSMutableArray *); but if you cast the
1255          object to the superclass, which is allowed, you'd still
1256          expect the getter to return an (NSArray *), which works since
1257          an (NSMutableArray *) is an (NSArray *) too.  So, the set of
1258          objects belonging to the type of the new @property should be
1259          a subset of the set of objects belonging to the type of the
1260          old @property.  This is what "specialization" means.  And the
1261          reason it only applies to readonly properties is that for a
1262          readwrite property the setter would have the opposite
1263          requirement - ie that the superclass type is more specialized
1264          then the subclass one; hence the only way to satisfy both
1265          constraints is that the types match.  */
1266
1267       /* If the types are not the same in the C sense, we warn ...  */
1268       if (!comptypes (TREE_TYPE (x), TREE_TYPE (decl))
1269           /* ... unless the property is readonly, in which case we
1270              allow a new, more specialized, declaration.  */
1271           && (!property_readonly 
1272               || !objc_compare_types (TREE_TYPE (x),
1273                                       TREE_TYPE (decl), -5, NULL_TREE)))
1274         {
1275           warning_at (location, 0,
1276                       "type of property %qD conflicts with previous declaration", decl);
1277           if (original_location != UNKNOWN_LOCATION)
1278             inform (original_location, "originally specified here");
1279           return;
1280         }
1281     }
1282
1283   /* Create a PROPERTY_DECL node.  */
1284   property_decl = make_node (PROPERTY_DECL);
1285
1286   /* Copy the basic information from the original decl.  */
1287   TREE_TYPE (property_decl) = TREE_TYPE (decl);
1288   DECL_SOURCE_LOCATION (property_decl) = DECL_SOURCE_LOCATION (decl);
1289   TREE_DEPRECATED (property_decl) = TREE_DEPRECATED (decl);
1290   
1291   /* Add property-specific information.  */
1292   PROPERTY_NAME (property_decl) = DECL_NAME (decl);
1293   PROPERTY_GETTER_NAME (property_decl) = parsed_property_getter_ident;
1294   PROPERTY_SETTER_NAME (property_decl) = parsed_property_setter_ident;
1295   PROPERTY_READONLY (property_decl) = property_readonly;
1296   PROPERTY_NONATOMIC (property_decl) = parsed_property_nonatomic;
1297   PROPERTY_ASSIGN_SEMANTICS (property_decl) = property_assign_semantics;
1298   PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
1299   PROPERTY_DYNAMIC (property_decl) = 0;
1300
1301   /* Note that PROPERTY_GETTER_NAME is always set for all
1302      PROPERTY_DECLs, and PROPERTY_SETTER_NAME is always set for all
1303      PROPERTY_DECLs where PROPERTY_READONLY == 0.  Any time we deal
1304      with a getter or setter, we should get the PROPERTY_DECL and use
1305      PROPERTY_GETTER_NAME and PROPERTY_SETTER_NAME to know the correct
1306      names.  */
1307
1308   /* Add the PROPERTY_DECL to the list of properties for the class.  */
1309   TREE_CHAIN (property_decl) = CLASS_PROPERTY_DECL (objc_interface_context);
1310   CLASS_PROPERTY_DECL (objc_interface_context) = property_decl;
1311 }
1312
1313 /* This is a subroutine of objc_maybe_build_component_ref.  Search the
1314    list of methods in the interface (and, failing that, the local list
1315    in the implementation, and failing that, the protocol list)
1316    provided for a 'setter' or 'getter' for 'component' with default
1317    names (ie, if 'component' is "name", then search for "name" and
1318    "setName:").  If any is found, then create an artificial property
1319    that uses them.  Return NULL_TREE if 'getter' or 'setter' could not
1320    be found.  */
1321 static tree
1322 maybe_make_artificial_property_decl (tree interface, tree implementation, 
1323                                      tree protocol_list, tree component, bool is_class)
1324 {
1325   tree getter_name = component;
1326   tree setter_name = get_identifier (objc_build_property_setter_name (component));
1327   tree getter = NULL_TREE;
1328   tree setter = NULL_TREE;
1329
1330   /* First, check the @interface and all superclasses.  */
1331   if (interface)
1332     {
1333       int flags = 0;
1334
1335       /* Using instance methods of the root class as accessors is most
1336          likely unwanted and can be extremely confusing (and, most
1337          importantly, other Objective-C 2.0 compilers do not do it).
1338          Turn it off.  */
1339       if (is_class)
1340         flags = OBJC_LOOKUP_CLASS | OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS;
1341       
1342       getter = lookup_method_static (interface, getter_name, flags);
1343       setter = lookup_method_static (interface, setter_name, flags);
1344     }
1345
1346   /* Second, check the local @implementation context.  */
1347   if (!getter && !setter)
1348     {
1349       if (implementation)
1350         {
1351           if (is_class)
1352             {
1353               getter = lookup_method (CLASS_CLS_METHODS (implementation), getter_name);
1354               setter = lookup_method (CLASS_CLS_METHODS (implementation), setter_name);
1355             }
1356           else
1357             {
1358               getter = lookup_method (CLASS_NST_METHODS (implementation), getter_name);
1359               setter = lookup_method (CLASS_NST_METHODS (implementation), setter_name);       
1360             }
1361         }
1362     }
1363
1364   /* Try the protocol_list if we didn't find anything in the
1365      @interface and in the @implementation.  */
1366   if (!getter && !setter)
1367     {
1368       getter = lookup_method_in_protocol_list (protocol_list, getter_name, is_class);
1369       setter = lookup_method_in_protocol_list (protocol_list, setter_name, is_class);
1370     }
1371
1372   /* There needs to be at least a getter or setter for this to be a
1373      valid 'object.component' syntax.  */
1374   if (getter || setter)
1375     {
1376       /* Yes ... determine the type of the expression.  */
1377       tree property_decl;
1378       tree type;
1379       
1380       if (getter)
1381         type = TREE_VALUE (TREE_TYPE (getter));
1382       else
1383         type = TREE_VALUE (TREE_TYPE (METHOD_SEL_ARGS (setter)));
1384       
1385       /* Create an artificial property declaration with the
1386          information we collected on the type and getter/setter
1387          names.  */
1388       property_decl = make_node (PROPERTY_DECL);
1389       
1390       TREE_TYPE (property_decl) = type;
1391       DECL_SOURCE_LOCATION (property_decl) = input_location;
1392       TREE_DEPRECATED (property_decl) = 0;
1393       DECL_ARTIFICIAL (property_decl) = 1;
1394               
1395       /* Add property-specific information.  Note that one of
1396          PROPERTY_GETTER_NAME or PROPERTY_SETTER_NAME may refer to a
1397          non-existing method; this will generate an error when the
1398          expression is later compiled.  At this stage we don't know if
1399          the getter or setter will be used, so we can't generate an
1400          error.  */
1401       PROPERTY_NAME (property_decl) = component;
1402       PROPERTY_GETTER_NAME (property_decl) = getter_name;
1403       PROPERTY_SETTER_NAME (property_decl) = setter_name;
1404       PROPERTY_READONLY (property_decl) = 0;
1405       PROPERTY_NONATOMIC (property_decl) = 0;
1406       PROPERTY_ASSIGN_SEMANTICS (property_decl) = 0;
1407       PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
1408       PROPERTY_DYNAMIC (property_decl) = 0;
1409
1410       if (!getter)
1411         PROPERTY_HAS_NO_GETTER (property_decl) = 1;
1412
1413       /* The following is currently unused, but it's nice to have
1414          there.  We may use it if we need in the future.  */
1415       if (!setter)
1416         PROPERTY_HAS_NO_SETTER (property_decl) = 1;
1417
1418       return property_decl;
1419     }
1420
1421   return NULL_TREE;
1422 }
1423
1424 /* This hook routine is invoked by the parser when an expression such
1425    as 'xxx.yyy' is parsed.  We get a chance to process these
1426    expressions in a way that is specified to Objective-C (to implement
1427    the Objective-C 2.0 dot-syntax, properties, or non-fragile ivars).
1428    If the expression is not an Objective-C specified expression, we
1429    should return NULL_TREE; else we return the expression.
1430
1431    At the moment this only implements dot-syntax and properties (not
1432    non-fragile ivars yet), ie 'object.property' or 'object.component'
1433    where 'component' is not a declared property, but a valid getter or
1434    setter for it could be found.  */
1435 tree
1436 objc_maybe_build_component_ref (tree object, tree property_ident)
1437 {
1438   tree x = NULL_TREE;
1439   tree rtype;
1440
1441   /* If we are in Objective-C 1.0 mode, dot-syntax and properties are
1442      not available.  */
1443   if (flag_objc1_only)
1444     return NULL_TREE;
1445
1446   /* Try to determine if 'object' is an Objective-C object or not.  If
1447      not, return.  */
1448   if (object == NULL_TREE || object == error_mark_node 
1449       || (rtype = TREE_TYPE (object)) == NULL_TREE)
1450     return NULL_TREE;
1451   
1452   if (property_ident == NULL_TREE || property_ident == error_mark_node
1453       || TREE_CODE (property_ident) != IDENTIFIER_NODE)
1454     return NULL_TREE;
1455
1456   /* The following analysis of 'object' is similar to the one used for
1457      the 'receiver' of a method invocation.  We need to determine what
1458      'object' is and find the appropriate property (either declared,
1459      or artificial) for it (in the same way as we need to find the
1460      appropriate method prototype for a method invocation).  There are
1461      some simplifications here though: "object.property" is invalid if
1462      "object" has a type of "id" or "Class"; it must at least have a
1463      protocol attached to it, and "object" is never a class name as
1464      that is done by objc_build_class_component_ref.  Finally, we
1465      don't know if this really is a dot-syntax expression, so we want
1466      to make a quick exit if it is not; for this reason, we try to
1467      postpone checks after determining that 'object' looks like an
1468      Objective-C object.  */
1469
1470   if (objc_is_id (rtype))
1471     {
1472       /* This is the case that the 'object' is of type 'id' or
1473          'Class'.  */
1474
1475       /* Check if at least it is of type 'id <Protocol>' or 'Class
1476          <Protocol>'; if so, look the property up in the
1477          protocols.  */
1478       if (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype)))
1479         {
1480           tree rprotos = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype));
1481           
1482           if (rprotos)
1483             {
1484               /* No point looking up declared @properties if we are
1485                  dealing with a class.  Classes have no declared
1486                  properties.  */
1487               if (!IS_CLASS (rtype))
1488                 x = lookup_property_in_protocol_list (rprotos, property_ident);
1489               
1490               if (x == NULL_TREE)
1491                 {
1492                   /* Ok, no property.  Maybe it was an
1493                      object.component dot-syntax without a declared
1494                      property (this is valid for classes too).  Look
1495                      for getter/setter methods and internally declare
1496                      an artifical property based on them if found.  */
1497                   x = maybe_make_artificial_property_decl (NULL_TREE,
1498                                                            NULL_TREE,
1499                                                            rprotos, 
1500                                                            property_ident,
1501                                                            IS_CLASS (rtype));
1502                 }
1503             }
1504         }
1505       else if (objc_method_context)
1506         {
1507           /* Else, if we are inside a method it could be the case of
1508              'super' or 'self'.  */
1509           tree interface_type = NULL_TREE;
1510           tree t = object;
1511           while (TREE_CODE (t) == COMPOUND_EXPR
1512                  || TREE_CODE (t) == MODIFY_EXPR
1513                  || CONVERT_EXPR_P (t)
1514                  || TREE_CODE (t) == COMPONENT_REF)
1515             t = TREE_OPERAND (t, 0);
1516           
1517           if (t == UOBJC_SUPER_decl)
1518             {
1519               /* TODO: Check if this is correct also for 'super' in categories.  */
1520               interface_type = lookup_interface (CLASS_SUPER_NAME (implementation_template));
1521             }
1522           else if (t == self_decl)
1523             interface_type = lookup_interface (CLASS_NAME (implementation_template));
1524
1525           if (interface_type)
1526             {
1527               if (TREE_CODE (objc_method_context) != CLASS_METHOD_DECL)
1528                 x = lookup_property (interface_type, property_ident);
1529         
1530               if (x == NULL_TREE)
1531                 {
1532                   /* Try the dot-syntax without a declared property.
1533                      If this is an access to 'self', it is possible
1534                      that they may refer to a setter/getter that is
1535                      not declared in the interface, but exists locally
1536                      in the implementation.  In that case, get the
1537                      implementation context and use it.  */
1538                   tree implementation = NULL_TREE;
1539
1540                   if (t == self_decl)
1541                     implementation = objc_implementation_context;
1542                   
1543                   x = maybe_make_artificial_property_decl 
1544                     (interface_type, implementation, NULL_TREE,
1545                      property_ident,
1546                      (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL));
1547                 }
1548             }
1549         }
1550     }
1551   else
1552     {
1553       /* This is the case where we have more information on 'rtype'.  */
1554       tree basetype = TYPE_MAIN_VARIANT (rtype);
1555
1556       /* Skip the pointer - if none, it's not an Objective-C object or
1557          class.  */
1558       if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE)
1559         basetype = TREE_TYPE (basetype);
1560       else
1561         return NULL_TREE;
1562
1563       /* Traverse typedefs.  */
1564       while (basetype != NULL_TREE
1565              && TREE_CODE (basetype) == RECORD_TYPE 
1566              && OBJC_TYPE_NAME (basetype)
1567              && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
1568              && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
1569         basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
1570
1571       if (basetype != NULL_TREE && TYPED_OBJECT (basetype))
1572         {
1573           tree interface_type = TYPE_OBJC_INTERFACE (basetype);
1574           tree protocol_list = TYPE_OBJC_PROTOCOL_LIST (basetype);
1575
1576           if (interface_type 
1577               && (TREE_CODE (interface_type) == CLASS_INTERFACE_TYPE
1578                   || TREE_CODE (interface_type) == CATEGORY_INTERFACE_TYPE
1579                   || TREE_CODE (interface_type) == PROTOCOL_INTERFACE_TYPE))
1580             {
1581               /* Not sure 'rtype' could ever be a class here!  Just
1582                  for safety we keep the checks.  */
1583               if (!IS_CLASS (rtype))
1584                 {
1585                   x = lookup_property (interface_type, property_ident);
1586                   
1587                   if (x == NULL_TREE)
1588                     x = lookup_property_in_protocol_list (protocol_list, 
1589                                                           property_ident);
1590                 }
1591               
1592               if (x == NULL_TREE)
1593                 {
1594                   /* Try the dot-syntax without a declared property.
1595                      If we are inside a method implementation, it is
1596                      possible that they may refer to a setter/getter
1597                      that is not declared in the interface, but exists
1598                      locally in the implementation.  In that case, get
1599                      the implementation context and use it.  */
1600                   tree implementation = NULL_TREE;
1601
1602                   if (objc_implementation_context
1603                       && CLASS_NAME (objc_implementation_context) 
1604                       == OBJC_TYPE_NAME (interface_type))
1605                     implementation = objc_implementation_context;
1606                   
1607                   x = maybe_make_artificial_property_decl (interface_type,
1608                                                            implementation,
1609                                                            protocol_list, 
1610                                                            property_ident,
1611                                                            IS_CLASS (rtype));
1612                 }
1613             }
1614         }
1615     }
1616
1617   if (x)
1618     {
1619       tree expression;
1620       tree getter_call;
1621
1622       /* We have an additional nasty problem here; if this
1623          PROPERTY_REF needs to become a 'getter', then the conversion
1624          from PROPERTY_REF into a getter call happens in gimplify,
1625          after the selector table has already been generated and when
1626          it is too late to add another selector to it.  To work around
1627          the problem, we always create the getter call at this stage,
1628          which puts the selector in the table.  Note that if the
1629          PROPERTY_REF becomes a 'setter' instead of a 'getter', then
1630          we have added a selector too many to the selector table.
1631          This is a little inefficient.
1632
1633          Also note that method calls to 'self' and 'super' require the
1634          context (self_decl, UOBJS_SUPER_decl,
1635          objc_implementation_context etc) to be built correctly; this
1636          is yet another reason why building the call at the gimplify
1637          stage (when this context has been lost) is not very
1638          practical.  If we build it at this stage, we know it will
1639          always be built correctly.
1640
1641          If the PROPERTY_HAS_NO_GETTER() (ie, it is an artificial
1642          property decl created to deal with a dotsyntax not really
1643          referring to an existing property) then do not try to build a
1644          call to the getter as there is no getter.  */
1645       if (PROPERTY_HAS_NO_GETTER (x))
1646         getter_call = NULL_TREE;
1647       else
1648         getter_call = objc_finish_message_expr (object,
1649                                                 PROPERTY_GETTER_NAME (x),
1650                                                 NULL_TREE);
1651
1652       if (TREE_DEPRECATED (x))
1653         warn_deprecated_use (x, NULL_TREE);
1654
1655       expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call);
1656       SET_EXPR_LOCATION (expression, input_location);
1657       TREE_SIDE_EFFECTS (expression) = 1;
1658       
1659       return expression;
1660     }
1661
1662   return NULL_TREE;
1663 }
1664
1665 /* This hook routine is invoked by the parser when an expression such
1666    as 'xxx.yyy' is parsed, and 'xxx' is a class name.  This is the
1667    Objective-C 2.0 dot-syntax applied to classes, so we need to
1668    convert it into a setter/getter call on the class.  */
1669 tree
1670 objc_build_class_component_ref (tree class_name, tree property_ident)
1671 {
1672   tree x = NULL_TREE;
1673   tree object, rtype;
1674   
1675   if (flag_objc1_only)
1676     error_at (input_location, "the dot syntax is not available in Objective-C 1.0");
1677   
1678   if (class_name == NULL_TREE || class_name == error_mark_node
1679       || TREE_CODE (class_name) != IDENTIFIER_NODE)
1680     return error_mark_node;
1681   
1682   if (property_ident == NULL_TREE || property_ident == error_mark_node
1683       || TREE_CODE (property_ident) != IDENTIFIER_NODE)
1684     return NULL_TREE;
1685   
1686   object = objc_get_class_reference (class_name);
1687   if (!object)
1688     {
1689       /* We know that 'class_name' is an Objective-C class name as the
1690          parser won't call this function if it is not.  This is only a
1691          double-check for safety.  */
1692       error_at (input_location, "could not find class %qE", class_name); 
1693       return error_mark_node;
1694     }
1695
1696   rtype = lookup_interface (class_name);
1697   if (!rtype)
1698     {
1699       /* Again, this should never happen, but we do check.  */
1700       error_at (input_location, "could not find interface for class %qE", class_name); 
1701       return error_mark_node;
1702     }
1703
1704   x = maybe_make_artificial_property_decl (rtype, NULL_TREE, NULL_TREE,
1705                                            property_ident,
1706                                            true);
1707   
1708   if (x)
1709     {
1710       tree expression;
1711       tree getter_call;
1712
1713       if (PROPERTY_HAS_NO_GETTER (x))
1714         getter_call = NULL_TREE;
1715       else
1716         getter_call = objc_finish_message_expr (object,
1717                                                 PROPERTY_GETTER_NAME (x),
1718                                                 NULL_TREE);
1719       if (TREE_DEPRECATED (x))
1720         warn_deprecated_use (x, NULL_TREE);
1721
1722       expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call);
1723       SET_EXPR_LOCATION (expression, input_location);
1724       TREE_SIDE_EFFECTS (expression) = 1;
1725
1726       return expression;
1727     }
1728   else
1729     {
1730       error_at (input_location, "could not find setter/getter for %qE in class %qE", 
1731                 property_ident, class_name); 
1732       return error_mark_node;
1733     }
1734
1735   return NULL_TREE;
1736 }
1737
1738
1739
1740 /* This is used because we don't want to expose PROPERTY_REF to the
1741    C/C++ frontends.  Maybe we should!  */
1742 bool
1743 objc_is_property_ref (tree node)
1744 {
1745   if (node  &&  TREE_CODE (node) == PROPERTY_REF)
1746     return true;
1747   else
1748     return false;
1749 }
1750
1751 /* This hook routine is called when a MODIFY_EXPR is being built.  We
1752    check what is being modified; if it is a PROPERTY_REF, we need to
1753    generate a 'setter' function call for the property.  If this is not
1754    a PROPERTY_REF, we return NULL_TREE and the C/C++ frontend will go
1755    on creating their MODIFY_EXPR.
1756
1757    This is used for example if you write
1758
1759    object.count = 1;
1760
1761    where 'count' is a property.  The left-hand side creates a
1762    PROPERTY_REF, and then the compiler tries to generate a MODIFY_EXPR
1763    to assign something to it.  We intercept that here, and generate a
1764    call to the 'setter' method instead.  */
1765 tree
1766 objc_maybe_build_modify_expr (tree lhs, tree rhs)
1767 {
1768   if (lhs && TREE_CODE (lhs) == PROPERTY_REF)
1769     {
1770       tree object_expr = PROPERTY_REF_OBJECT (lhs);
1771       tree property_decl = PROPERTY_REF_PROPERTY_DECL (lhs);
1772
1773       if (PROPERTY_READONLY (property_decl))
1774         {
1775           error ("readonly property can not be set");     
1776           return error_mark_node;
1777         }
1778       else
1779         {
1780           tree setter_argument = build_tree_list (NULL_TREE, rhs);
1781           tree setter;
1782
1783           /* TODO: Check that the setter return type is 'void'.  */
1784
1785           /* TODO: Decay argument in C.  */
1786           setter = objc_finish_message_expr (object_expr, 
1787                                              PROPERTY_SETTER_NAME (property_decl),
1788                                              setter_argument);
1789           return setter;
1790         }
1791     }
1792   else
1793     return NULL_TREE;
1794 }
1795
1796 /* This hook is called by the frontend when one of the four unary
1797    expressions PREINCREMENT_EXPR, POSTINCREMENT_EXPR,
1798    PREDECREMENT_EXPR and POSTDECREMENT_EXPR is being built with an
1799    argument which is a PROPERTY_REF.  For example, this happens if you have
1800
1801    object.count++;
1802
1803    where 'count' is a property.  We need to use the 'getter' and
1804    'setter' for the property in an appropriate way to build the
1805    appropriate expression.  'code' is the code for the expression (one
1806    of the four mentioned above); 'argument' is the PROPERTY_REF, and
1807    'increment' is how much we need to add or subtract.  */   
1808 tree
1809 objc_build_incr_expr_for_property_ref (location_t location,
1810                                        enum tree_code code, 
1811                                        tree argument, tree increment)
1812 {
1813   /* Here are the expressions that we want to build:
1814
1815      For PREINCREMENT_EXPR / PREDECREMENT_EXPR:
1816     (temp = [object property] +/- increment, [object setProperty: temp], temp)
1817     
1818     For POSTINCREMENT_EXPR / POSTECREMENT_EXPR:
1819     (temp = [object property], [object setProperty: temp +/- increment], temp) */
1820   
1821   tree temp_variable_decl, bind;
1822   /* s1, s2 and s3 are the tree statements that we need in the
1823      compound expression.  */
1824   tree s1, s2, s3;
1825   
1826   /* Safety check.  */
1827   if (!argument || TREE_CODE (argument) != PROPERTY_REF)
1828     return error_mark_node;
1829
1830   /* Declare __objc_property_temp in a local bind.  */
1831   temp_variable_decl = objc_create_temporary_var (TREE_TYPE (argument), "__objc_property_temp");
1832   DECL_SOURCE_LOCATION (temp_variable_decl) = location;
1833   bind = build3 (BIND_EXPR, void_type_node, temp_variable_decl, NULL, NULL);
1834   SET_EXPR_LOCATION (bind, location);
1835   TREE_SIDE_EFFECTS (bind) = 1;
1836   add_stmt (bind);
1837   
1838   /* Now build the compound statement.  */
1839   
1840   /* Note that the 'getter' is generated at gimplify time; at this
1841      time, we can simply put the property_ref (ie, argument) wherever
1842      we want the getter ultimately to be.  */
1843   
1844   /* s1: __objc_property_temp = [object property] <+/- increment> */
1845   switch (code)
1846     {
1847     case PREINCREMENT_EXPR:      
1848       /* __objc_property_temp = [object property] + increment */
1849       s1 = build2 (MODIFY_EXPR, void_type_node, temp_variable_decl,
1850                    build2 (PLUS_EXPR, TREE_TYPE (argument), argument, increment));
1851       break;
1852     case PREDECREMENT_EXPR:
1853       /* __objc_property_temp = [object property] - increment */
1854       s1 = build2 (MODIFY_EXPR, void_type_node, temp_variable_decl,
1855                    build2 (MINUS_EXPR, TREE_TYPE (argument), argument, increment));
1856       break;
1857     case POSTINCREMENT_EXPR:
1858     case POSTDECREMENT_EXPR:
1859       /* __objc_property_temp = [object property] */
1860       s1 = build2 (MODIFY_EXPR, void_type_node, temp_variable_decl, argument);
1861       break;
1862     default:
1863       gcc_unreachable ();
1864     }
1865   SET_EXPR_LOCATION (s1, location);
1866   
1867   /* s2: [object setProperty: __objc_property_temp <+/- increment>] */
1868   switch (code)
1869     {
1870     case PREINCREMENT_EXPR:      
1871     case PREDECREMENT_EXPR:
1872       /* [object setProperty: __objc_property_temp] */
1873       s2 = objc_maybe_build_modify_expr (argument, temp_variable_decl);
1874       break;
1875     case POSTINCREMENT_EXPR:
1876       /* [object setProperty: __objc_property_temp + increment] */
1877       s2 = objc_maybe_build_modify_expr (argument,
1878                                          build2 (PLUS_EXPR, TREE_TYPE (argument), 
1879                                                  temp_variable_decl, increment));
1880       break;
1881     case POSTDECREMENT_EXPR:
1882       /* [object setProperty: __objc_property_temp - increment] */
1883       s2 = objc_maybe_build_modify_expr (argument,
1884                                          build2 (MINUS_EXPR, TREE_TYPE (argument), 
1885                                                  temp_variable_decl, increment));
1886       break;
1887     default:
1888       gcc_unreachable ();
1889     }
1890
1891   /* This happens if building the setter failed because the property
1892      is readonly.  */
1893   if (s2 == error_mark_node)
1894     return error_mark_node;
1895
1896   SET_EXPR_LOCATION (s2, location); 
1897   
1898   /* s3: __objc_property_temp */
1899   s3 = build1 (NOP_EXPR, TREE_TYPE (argument), temp_variable_decl);
1900   SET_EXPR_LOCATION (s3, location); 
1901   
1902   /* Now build the compound statement (s1, s2, s3) */
1903   return build_compound_expr (location, build_compound_expr (location, s1, s2), s3);
1904 }
1905
1906 tree
1907 objc_build_method_signature (bool is_class_method, tree rettype, tree selector,
1908                              tree optparms, bool ellipsis)
1909 {
1910   if (is_class_method)
1911     return build_method_decl (CLASS_METHOD_DECL, rettype, selector,
1912                               optparms, ellipsis);
1913   else
1914     return build_method_decl (INSTANCE_METHOD_DECL, rettype, selector,
1915                               optparms, ellipsis);
1916 }
1917
1918 void
1919 objc_add_method_declaration (bool is_class_method, tree decl, tree attributes)
1920 {
1921   if (!objc_interface_context)
1922     {
1923       /* PS: At the moment, due to how the parser works, it should be
1924          impossible to get here.  But it's good to have the check in
1925          case the parser changes.
1926       */
1927       fatal_error ("method declaration not in @interface context");
1928     }
1929
1930   if (flag_objc1_only && attributes)
1931     error_at (input_location, "method attributes are not available in Objective-C 1.0");
1932
1933   objc_decl_method_attributes (&decl, attributes, 0);
1934   objc_add_method (objc_interface_context,
1935                    decl,
1936                    is_class_method,
1937                    objc_method_optional_flag);
1938 }
1939
1940 /* Return 'true' if the method definition could be started, and
1941    'false' if not (because we are outside an @implementation context).
1942 */
1943 bool
1944 objc_start_method_definition (bool is_class_method, tree decl, tree attributes)
1945 {
1946   if (!objc_implementation_context)
1947     {
1948       error ("method definition not in @implementation context");
1949       return false;
1950     }
1951
1952   if (decl != NULL_TREE  && METHOD_SEL_NAME (decl) == error_mark_node)
1953     return false;
1954
1955 #ifndef OBJCPLUS
1956   /* Indicate no valid break/continue context by setting these variables
1957      to some non-null, non-label value.  We'll notice and emit the proper
1958      error message in c_finish_bc_stmt.  */
1959   c_break_label = c_cont_label = size_zero_node;
1960 #endif
1961
1962   if (attributes)
1963     warning_at (input_location, 0, "method attributes can not be specified in @implementation context");
1964   else
1965     objc_decl_method_attributes (&decl, attributes, 0);
1966
1967   objc_add_method (objc_implementation_context,
1968                    decl,
1969                    is_class_method,
1970                    /* is optional */ false);
1971   start_method_def (decl);
1972   return true;
1973 }
1974
1975 void
1976 objc_add_instance_variable (tree decl)
1977 {
1978   (void) add_instance_variable (objc_ivar_context,
1979                                 objc_ivar_visibility,
1980                                 decl);
1981 }
1982
1983 /* Return true if TYPE is 'id'.  */
1984
1985 static bool
1986 objc_is_object_id (tree type)
1987 {
1988   return OBJC_TYPE_NAME (type) == objc_object_id;
1989 }
1990
1991 static bool
1992 objc_is_class_id (tree type)
1993 {
1994   return OBJC_TYPE_NAME (type) == objc_class_id;
1995 }
1996
1997 /* Construct a C struct with same name as KLASS, a base struct with tag
1998    SUPER_NAME (if any), and FIELDS indicated.  */
1999
2000 static tree
2001 objc_build_struct (tree klass, tree fields, tree super_name)
2002 {
2003   tree name = CLASS_NAME (klass);
2004   tree s = objc_start_struct (name);
2005   tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
2006   tree t;
2007   VEC(tree,heap) *objc_info = NULL;
2008   int i;
2009
2010   if (super)
2011     {
2012       /* Prepend a packed variant of the base class into the layout.  This
2013          is necessary to preserve ObjC ABI compatibility.  */
2014       tree base = build_decl (input_location,
2015                               FIELD_DECL, NULL_TREE, super);
2016       tree field = TYPE_FIELDS (super);
2017
2018       while (field && DECL_CHAIN (field)
2019              && TREE_CODE (DECL_CHAIN (field)) == FIELD_DECL)
2020         field = DECL_CHAIN (field);
2021
2022       /* For ObjC ABI purposes, the "packed" size of a base class is
2023          the sum of the offset and the size (in bits) of the last field
2024          in the class.  */
2025       DECL_SIZE (base)
2026         = (field && TREE_CODE (field) == FIELD_DECL
2027            ? size_binop (PLUS_EXPR,
2028                          size_binop (PLUS_EXPR,
2029                                      size_binop
2030                                      (MULT_EXPR,
2031                                       convert (bitsizetype,
2032                                                DECL_FIELD_OFFSET (field)),
2033                                       bitsize_int (BITS_PER_UNIT)),
2034                                      DECL_FIELD_BIT_OFFSET (field)),
2035                          DECL_SIZE (field))
2036            : bitsize_zero_node);
2037       DECL_SIZE_UNIT (base)
2038         = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
2039                       size_int (BITS_PER_UNIT));
2040       DECL_ARTIFICIAL (base) = 1;
2041       DECL_ALIGN (base) = 1;
2042       DECL_FIELD_CONTEXT (base) = s;
2043 #ifdef OBJCPLUS
2044       DECL_FIELD_IS_BASE (base) = 1;
2045
2046       if (fields)
2047         TREE_NO_WARNING (fields) = 1;   /* Suppress C++ ABI warnings -- we   */
2048 #endif                                  /* are following the ObjC ABI here.  */
2049       DECL_CHAIN (base) = fields;
2050       fields = base;
2051     }
2052
2053   /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
2054      in all variants of this RECORD_TYPE to be clobbered, but it is therein
2055      that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
2056      Hence, we must squirrel away the ObjC-specific information before calling
2057      finish_struct(), and then reinstate it afterwards.  */
2058
2059   for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
2060     {
2061       if (!TYPE_HAS_OBJC_INFO (t))
2062         {
2063           INIT_TYPE_OBJC_INFO (t);
2064           TYPE_OBJC_INTERFACE (t) = klass;
2065         }
2066       VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t));
2067     }
2068
2069   /* Point the struct at its related Objective-C class.  */
2070   INIT_TYPE_OBJC_INFO (s);
2071   TYPE_OBJC_INTERFACE (s) = klass;
2072
2073   s = objc_finish_struct (s, fields);
2074
2075   for (i = 0, t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
2076     {
2077       TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i);
2078       /* Replace the IDENTIFIER_NODE with an actual @interface.  */
2079       TYPE_OBJC_INTERFACE (t) = klass;
2080     }
2081   VEC_free (tree, heap, objc_info);
2082
2083   /* Use TYPE_BINFO structures to point at the super class, if any.  */
2084   objc_xref_basetypes (s, super);
2085
2086   /* Mark this struct as a class template.  */
2087   CLASS_STATIC_TEMPLATE (klass) = s;
2088
2089   return s;
2090 }
2091
2092 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
2093    Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
2094    process.  */
2095 static tree
2096 objc_build_volatilized_type (tree type)
2097 {
2098   tree t;
2099
2100   /* Check if we have not constructed the desired variant already.  */
2101   for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
2102     {
2103       /* The type qualifiers must (obviously) match up.  */
2104       if (!TYPE_VOLATILE (t)
2105           || (TYPE_READONLY (t) != TYPE_READONLY (type))
2106           || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
2107         continue;
2108
2109       /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
2110          info, if any) must match up.  */
2111       if (POINTER_TYPE_P (t)
2112           && (TREE_TYPE (t) != TREE_TYPE (type)))
2113         continue;
2114
2115       /* Only match up the types which were previously volatilized in similar fashion and not
2116          because they were declared as such. */
2117       if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t)))
2118         continue;
2119
2120       /* Everything matches up!  */
2121       return t;
2122     }
2123
2124   /* Ok, we could not re-use any of the pre-existing variants.  Create
2125      a new one.  */
2126   t = build_variant_type_copy (type);
2127   TYPE_VOLATILE (t) = 1;
2128
2129   TYPE_ATTRIBUTES (t) = merge_attributes (TYPE_ATTRIBUTES (type),
2130                                           tree_cons (get_identifier ("objc_volatilized"),
2131                                           NULL_TREE,
2132                                           NULL_TREE));
2133   if (TREE_CODE (t) == ARRAY_TYPE)
2134     TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (t));
2135
2136   /* Set up the canonical type information. */
2137   if (TYPE_STRUCTURAL_EQUALITY_P (type))
2138     SET_TYPE_STRUCTURAL_EQUALITY (t);
2139   else if (TYPE_CANONICAL (type) != type)
2140     TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
2141   else
2142     TYPE_CANONICAL (t) = t;
2143
2144   return t;
2145 }
2146
2147 /* Mark DECL as being 'volatile' for purposes of Darwin
2148    _setjmp()/_longjmp() exception handling.  Called from
2149    objc_mark_locals_volatile().  */
2150 void
2151 objc_volatilize_decl (tree decl)
2152 {
2153   /* Do not mess with variables that are 'static' or (already)
2154      'volatile'.  */
2155   if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
2156       && (TREE_CODE (decl) == VAR_DECL
2157           || TREE_CODE (decl) == PARM_DECL))
2158     {
2159       tree t = TREE_TYPE (decl);
2160
2161       t = objc_build_volatilized_type (t);
2162
2163       TREE_TYPE (decl) = t;
2164       TREE_THIS_VOLATILE (decl) = 1;
2165       TREE_SIDE_EFFECTS (decl) = 1;
2166       DECL_REGISTER (decl) = 0;
2167 #ifndef OBJCPLUS
2168       C_DECL_REGISTER (decl) = 0;
2169 #endif
2170     }
2171 }
2172
2173 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
2174    (including its categories and superclasses) or by object type TYP.
2175    Issue a warning if PROTO is not adopted anywhere and WARN is set.  */
2176
2177 static bool
2178 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
2179 {
2180   bool class_type = (cls != NULL_TREE);
2181
2182   while (cls)
2183     {
2184       tree c;
2185
2186       /* Check protocols adopted by the class and its categories.  */
2187       for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
2188         {
2189           if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
2190             return true;
2191         }
2192
2193       /* Repeat for superclasses.  */
2194       cls = lookup_interface (CLASS_SUPER_NAME (cls));
2195     }
2196
2197   /* Check for any protocols attached directly to the object type.  */
2198   if (TYPE_HAS_OBJC_INFO (typ))
2199     {
2200       if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
2201         return true;
2202     }
2203
2204   if (warn)
2205     {
2206       *errbuf = 0;
2207       gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
2208       /* NB: Types 'id' and 'Class' cannot reasonably be described as
2209          "implementing" a given protocol, since they do not have an
2210          implementation.  */
2211       if (class_type)
2212         warning (0, "class %qs does not implement the %qE protocol",
2213                  identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
2214       else
2215         warning (0, "type %qs does not conform to the %qE protocol",
2216                  identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
2217     }
2218
2219   return false;
2220 }
2221
2222 /* Check if class RCLS and instance struct type RTYP conform to at least the
2223    same protocols that LCLS and LTYP conform to.  */
2224
2225 static bool
2226 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
2227 {
2228   tree p;
2229   bool have_lproto = false;
2230
2231   while (lcls)
2232     {
2233       /* NB: We do _not_ look at categories defined for LCLS; these may or
2234          may not get loaded in, and therefore it is unreasonable to require
2235          that RCLS/RTYP must implement any of their protocols.  */
2236       for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
2237         {
2238           have_lproto = true;
2239
2240           if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
2241             return warn;
2242         }
2243
2244       /* Repeat for superclasses.  */
2245       lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
2246     }
2247
2248   /* Check for any protocols attached directly to the object type.  */
2249   if (TYPE_HAS_OBJC_INFO (ltyp))
2250     {
2251       for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
2252         {
2253           have_lproto = true;
2254
2255           if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
2256             return warn;
2257         }
2258     }
2259
2260   /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
2261      vacuously, _unless_ RTYP is a protocol-qualified 'id'.  We can get
2262      away with simply checking for 'id' or 'Class' (!RCLS), since this
2263      routine will not get called in other cases.  */
2264   return have_lproto || (rcls != NULL_TREE);
2265 }
2266
2267 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
2268    Both TYPE1 and TYPE2 must be pointers, and already determined to be
2269    compatible by objc_compare_types() below.  */
2270
2271 tree
2272 objc_common_type (tree type1, tree type2)
2273 {
2274   tree inner1 = TREE_TYPE (type1), inner2 = TREE_TYPE (type2);
2275
2276   while (POINTER_TYPE_P (inner1))
2277     {
2278       inner1 = TREE_TYPE (inner1);
2279       inner2 = TREE_TYPE (inner2);
2280     }
2281
2282   /* If one type is derived from another, return the base type.  */
2283   if (DERIVED_FROM_P (inner1, inner2))
2284     return type1;
2285   else if (DERIVED_FROM_P (inner2, inner1))
2286     return type2;
2287
2288   /* If both types are 'Class', return 'Class'.  */
2289   if (objc_is_class_id (inner1) && objc_is_class_id (inner2))
2290     return objc_class_type;
2291
2292   /* Otherwise, return 'id'.  */
2293   return objc_object_type;
2294 }
2295
2296 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
2297    an instance of RTYP to an instance of LTYP or to compare the two
2298    (if ARGNO is equal to -3), per ObjC type system rules.  Before
2299    returning 'true', this routine may issue warnings related to, e.g.,
2300    protocol conformance.  When returning 'false', the routine must
2301    produce absolutely no warnings; the C or C++ front-end will do so
2302    instead, if needed.  If either LTYP or RTYP is not an Objective-C
2303    type, the routine must return 'false'.
2304
2305    The ARGNO parameter is encoded as follows:
2306      >= 1       Parameter number (CALLEE contains function being called);
2307      0          Return value;
2308      -1         Assignment;
2309      -2         Initialization;
2310      -3         Comparison (LTYP and RTYP may match in either direction);
2311      -4         Silent comparison (for C++ overload resolution);
2312      -5         Silent "specialization" comparison for RTYP to be a "specialization" 
2313                 of LTYP (a specialization means that RTYP is LTYP plus some constraints, 
2314                 so that each object of type RTYP is also of type LTYP).  This is used
2315                 when comparing property types.  */
2316
2317 bool
2318 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
2319 {
2320   tree lcls, rcls, lproto, rproto;
2321   bool pointers_compatible;
2322
2323   /* We must be dealing with pointer types */
2324   if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
2325     return false;
2326
2327   do
2328     {
2329       ltyp = TREE_TYPE (ltyp);  /* Remove indirections.  */
2330       rtyp = TREE_TYPE (rtyp);
2331     }
2332   while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
2333
2334   /* We must also handle function pointers, since ObjC is a bit more
2335      lenient than C or C++ on this.  */
2336   if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
2337     {
2338       /* Return types must be covariant.  */
2339       if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
2340           && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
2341                                   argno, callee))
2342       return false;
2343
2344       /* Argument types must be contravariant.  */
2345       for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
2346            ltyp && rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
2347         {
2348           if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
2349               && !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
2350                                       argno, callee))
2351             return false;
2352       }
2353
2354       return (ltyp == rtyp);
2355     }
2356
2357   /* Past this point, we are only interested in ObjC class instances,
2358      or 'id' or 'Class'.  */
2359   if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
2360     return false;
2361
2362   if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
2363       && !TYPE_HAS_OBJC_INFO (ltyp))
2364     return false;
2365
2366   if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
2367       && !TYPE_HAS_OBJC_INFO (rtyp))
2368     return false;
2369
2370   /* Past this point, we are committed to returning 'true' to the caller
2371      (unless performing a silent comparison; see below).  However, we can
2372      still warn about type and/or protocol mismatches.  */
2373
2374   if (TYPE_HAS_OBJC_INFO (ltyp))
2375     {
2376       lcls = TYPE_OBJC_INTERFACE (ltyp);
2377       lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
2378     }
2379   else
2380     lcls = lproto = NULL_TREE;
2381
2382   if (TYPE_HAS_OBJC_INFO (rtyp))
2383     {
2384       rcls = TYPE_OBJC_INTERFACE (rtyp);
2385       rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
2386     }
2387   else
2388     rcls = rproto = NULL_TREE;
2389
2390   /* If we could not find an @interface declaration, we must have
2391      only seen a @class declaration; for purposes of type comparison,
2392      treat it as a stand-alone (root) class.  */
2393
2394   if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
2395     lcls = NULL_TREE;
2396
2397   if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
2398     rcls = NULL_TREE;
2399
2400   /* If either type is an unqualified 'id', we're done.  This is because
2401      an 'id' can be assigned to or from any type with no warnings.  */
2402   if (argno != -5)
2403     {
2404       if ((!lproto && objc_is_object_id (ltyp))
2405           || (!rproto && objc_is_object_id (rtyp)))
2406         return true;
2407     }
2408   else
2409     {
2410       /* For property checks, though, an 'id' is considered the most
2411          general type of object, hence if you try to specialize an
2412          'NSArray *' (ltyp) property with an 'id' (rtyp) one, we need
2413          to warn.  */
2414       if (!lproto && objc_is_object_id (ltyp))
2415         return true;
2416     }
2417   
2418   pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
2419
2420   /* If the underlying types are the same, and at most one of them has
2421      a protocol list, we do not need to issue any diagnostics.  */
2422   if (pointers_compatible && (!lproto || !rproto))
2423     return true;
2424
2425   /* If exactly one of the types is 'Class', issue a diagnostic; any
2426      exceptions of this rule have already been handled.  */
2427   if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
2428     pointers_compatible = false;
2429   /* Otherwise, check for inheritance relations.  */
2430   else
2431     {
2432       if (!pointers_compatible)
2433         {
2434           /* Again, if any of the two is an 'id', we're satisfied,
2435              unless we're comparing properties, in which case only an
2436              'id' on the left-hand side (old property) is good
2437              enough.  */
2438           if (argno != -5)
2439             pointers_compatible
2440               = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
2441           else
2442             pointers_compatible = objc_is_object_id (ltyp);         
2443         }
2444
2445       if (!pointers_compatible)
2446         pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
2447
2448       if (!pointers_compatible && (argno == -3 || argno == -4))
2449         pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
2450     }
2451
2452   /* If the pointers match modulo protocols, check for protocol conformance
2453      mismatches.  */
2454   if (pointers_compatible)
2455     {
2456       pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
2457                                                     argno != -3);
2458
2459       if (!pointers_compatible && argno == -3)
2460         pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
2461                                                       argno != -3);
2462     }
2463
2464   if (!pointers_compatible)
2465     {
2466       /* The two pointers are not exactly compatible.  Issue a warning, unless
2467          we are performing a silent comparison, in which case return 'false'
2468          instead.  */
2469       /* NB: For the time being, we shall make our warnings look like their
2470          C counterparts.  In the future, we may wish to make them more
2471          ObjC-specific.  */
2472       switch (argno)
2473         {
2474         case -5:
2475         case -4:
2476           return false;
2477
2478         case -3:
2479           warning (0, "comparison of distinct Objective-C types lacks a cast");
2480           break;
2481
2482         case -2:
2483           warning (0, "initialization from distinct Objective-C type");
2484           break;
2485
2486         case -1:
2487           warning (0, "assignment from distinct Objective-C type");
2488           break;
2489
2490         case 0:
2491           warning (0, "distinct Objective-C type in return");
2492           break;
2493
2494         default:
2495           warning (0, "passing argument %d of %qE from distinct "
2496                    "Objective-C type", argno, callee);
2497           break;
2498         }
2499     }
2500
2501   return true;
2502 }
2503
2504 /* This routine is similar to objc_compare_types except that function-pointers are
2505    excluded. This is because, caller assumes that common types are of (id, Object*)
2506    variety and calls objc_common_type to obtain a common type. There is no commonolty
2507    between two function-pointers in this regard. */
2508
2509 bool 
2510 objc_have_common_type (tree ltyp, tree rtyp, int argno, tree callee)
2511 {
2512   if (objc_compare_types (ltyp, rtyp, argno, callee))
2513     {
2514       /* exclude function-pointer types. */
2515       do
2516         {
2517           ltyp = TREE_TYPE (ltyp);  /* Remove indirections.  */
2518           rtyp = TREE_TYPE (rtyp);
2519         }
2520       while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
2521       return !(TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE);
2522     }
2523   return false;
2524 }
2525
2526 /* Check if LTYP and RTYP have the same type qualifiers.  If either type
2527    lives in the volatilized hash table, ignore the 'volatile' bit when
2528    making the comparison.  */
2529
2530 bool
2531 objc_type_quals_match (tree ltyp, tree rtyp)
2532 {
2533   int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
2534
2535   if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp)))
2536     lquals &= ~TYPE_QUAL_VOLATILE;
2537
2538   if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp)))
2539     rquals &= ~TYPE_QUAL_VOLATILE;
2540
2541   return (lquals == rquals);
2542 }
2543
2544 #ifndef OBJCPLUS
2545 /* Determine if CHILD is derived from PARENT.  The routine assumes that
2546    both parameters are RECORD_TYPEs, and is non-reflexive.  */
2547
2548 static bool
2549 objc_derived_from_p (tree parent, tree child)
2550 {
2551   parent = TYPE_MAIN_VARIANT (parent);
2552
2553   for (child = TYPE_MAIN_VARIANT (child);
2554        TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
2555     {
2556       child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
2557                                              (TYPE_BINFO (child),
2558                                               0)));
2559
2560       if (child == parent)
2561         return true;
2562     }
2563
2564   return false;
2565 }
2566 #endif
2567
2568 static tree
2569 objc_build_component_ref (tree datum, tree component)
2570 {
2571   /* If COMPONENT is NULL, the caller is referring to the anonymous
2572      base class field.  */
2573   if (!component)
2574     {
2575       tree base = TYPE_FIELDS (TREE_TYPE (datum));
2576
2577       return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
2578     }
2579
2580   /* The 'build_component_ref' routine has been removed from the C++
2581      front-end, but 'finish_class_member_access_expr' seems to be
2582      a worthy substitute.  */
2583 #ifdef OBJCPLUS
2584   return finish_class_member_access_expr (datum, component, false,
2585                                           tf_warning_or_error);
2586 #else
2587   return build_component_ref (input_location, datum, component);
2588 #endif
2589 }
2590
2591 /* Recursively copy inheritance information rooted at BINFO.  To do this,
2592    we emulate the song and dance performed by cp/tree.c:copy_binfo().  */
2593
2594 static tree
2595 objc_copy_binfo (tree binfo)
2596 {
2597   tree btype = BINFO_TYPE (binfo);
2598   tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
2599   tree base_binfo;
2600   int ix;
2601
2602   BINFO_TYPE (binfo2) = btype;
2603   BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
2604   BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
2605
2606   /* Recursively copy base binfos of BINFO.  */
2607   for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
2608     {
2609       tree base_binfo2 = objc_copy_binfo (base_binfo);
2610
2611       BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
2612       BINFO_BASE_APPEND (binfo2, base_binfo2);
2613     }
2614
2615   return binfo2;
2616 }
2617
2618 /* Record superclass information provided in BASETYPE for ObjC class REF.
2619    This is loosely based on cp/decl.c:xref_basetypes().  */
2620
2621 static void
2622 objc_xref_basetypes (tree ref, tree basetype)
2623 {
2624   tree binfo = make_tree_binfo (basetype ? 1 : 0);
2625
2626   TYPE_BINFO (ref) = binfo;
2627   BINFO_OFFSET (binfo) = size_zero_node;
2628   BINFO_TYPE (binfo) = ref;
2629
2630   if (basetype)
2631     {
2632       tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
2633
2634       BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
2635       BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
2636       BINFO_BASE_APPEND (binfo, base_binfo);
2637       BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
2638     }
2639 }
2640
2641 /* Called from finish_decl.  */
2642
2643 void
2644 objc_check_decl (tree decl)
2645 {
2646   tree type = TREE_TYPE (decl);
2647
2648   if (TREE_CODE (type) != RECORD_TYPE)
2649     return;
2650   if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
2651     error ("statically allocated instance of Objective-C class %qE",
2652            type);
2653 }
2654
2655 void
2656 objc_check_global_decl (tree decl)
2657 {
2658   tree id = DECL_NAME (decl);
2659   if (objc_is_class_name (id) && global_bindings_p())
2660     error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
2661 }
2662
2663 /* Return a non-volatalized version of TYPE. */
2664
2665 tree
2666 objc_non_volatilized_type (tree type)
2667 {
2668   if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type)))
2669     type = build_qualified_type (type, (TYPE_QUALS (type) & ~TYPE_QUAL_VOLATILE));
2670   return type;
2671 }
2672
2673 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
2674    either name an Objective-C class, or refer to the special 'id' or 'Class'
2675    types.  If INTERFACE is not a valid ObjC type, just return it unchanged.  */
2676
2677 tree
2678 objc_get_protocol_qualified_type (tree interface, tree protocols)
2679 {
2680   /* If INTERFACE is not provided, default to 'id'.  */
2681   tree type = (interface ? objc_is_id (interface) : objc_object_type);
2682   bool is_ptr = (type != NULL_TREE);
2683
2684   if (!is_ptr)
2685     {
2686       type = objc_is_class_name (interface);
2687
2688       if (type)
2689         {
2690           /* If looking at a typedef, retrieve the precise type it
2691              describes.  */
2692           if (TREE_CODE (interface) == IDENTIFIER_NODE)
2693             interface = identifier_global_value (interface);
2694
2695           type = ((interface && TREE_CODE (interface) == TYPE_DECL
2696                    && DECL_ORIGINAL_TYPE (interface))
2697                   ? DECL_ORIGINAL_TYPE (interface)
2698                   : xref_tag (RECORD_TYPE, type));
2699         }
2700       else
2701         {
2702           /* This case happens when we are given an 'interface' which
2703              is not a valid class name.  For example if a typedef was
2704              used, and 'interface' really is the identifier of the
2705              typedef, but when you resolve it you don't get an
2706              Objective-C class, but something else, such as 'int'.
2707              This is an error; protocols make no sense unless you use
2708              them with Objective-C objects.  */
2709           error_at (input_location, "only Objective-C object types can be qualified with a protocol");
2710
2711           /* Try to recover.  Ignore the invalid class name, and treat
2712              the object as an 'id' to silence further warnings about
2713              the class.  */
2714           type = objc_object_type;
2715           is_ptr = true;
2716         }
2717     }
2718
2719   if (protocols)
2720     {
2721       type = build_variant_type_copy (type);
2722
2723       /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
2724          to the pointee.  */
2725       if (is_ptr)
2726         {
2727           tree orig_pointee_type = TREE_TYPE (type);
2728           TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
2729
2730           /* Set up the canonical type information. */
2731           TYPE_CANONICAL (type) 
2732             = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
2733
2734           TYPE_POINTER_TO (TREE_TYPE (type)) = type;
2735           type = TREE_TYPE (type);
2736         }
2737
2738       /* Look up protocols and install in lang specific list.  */
2739       DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
2740       TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
2741
2742       /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
2743          return the pointer to the new pointee variant.  */
2744       if (is_ptr)
2745         type = TYPE_POINTER_TO (type);
2746       else
2747         TYPE_OBJC_INTERFACE (type)
2748           = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
2749     }
2750
2751   return type;
2752 }
2753
2754 /* Check for circular dependencies in protocols.  The arguments are
2755    PROTO, the protocol to check, and LIST, a list of protocol it
2756    conforms to.  */
2757
2758 static void
2759 check_protocol_recursively (tree proto, tree list)
2760 {
2761   tree p;
2762
2763   for (p = list; p; p = TREE_CHAIN (p))
2764     {
2765       tree pp = TREE_VALUE (p);
2766
2767       if (TREE_CODE (pp) == IDENTIFIER_NODE)
2768         pp = lookup_protocol (pp);
2769
2770       if (pp == proto)
2771         fatal_error ("protocol %qE has circular dependency",
2772                      PROTOCOL_NAME (pp));
2773       if (pp)
2774         check_protocol_recursively (proto, PROTOCOL_LIST (pp));
2775     }
2776 }
2777
2778 /* Look up PROTOCOLS, and return a list of those that are found.
2779    If none are found, return NULL.  */
2780
2781 static tree
2782 lookup_and_install_protocols (tree protocols)
2783 {
2784   tree proto;
2785   tree return_value = NULL_TREE;
2786
2787   if (protocols == error_mark_node)
2788     return NULL;
2789
2790   for (proto = protocols; proto; proto = TREE_CHAIN (proto))
2791     {
2792       tree ident = TREE_VALUE (proto);
2793       tree p = lookup_protocol (ident);
2794
2795       if (p)
2796         return_value = chainon (return_value,
2797                                 build_tree_list (NULL_TREE, p));
2798       else if (ident != error_mark_node)
2799         error ("cannot find protocol declaration for %qE",
2800                ident);
2801     }
2802
2803   return return_value;
2804 }
2805
2806 /* Create a declaration for field NAME of a given TYPE.  */
2807
2808 static tree
2809 create_field_decl (tree type, const char *name)
2810 {
2811   return build_decl (input_location,
2812                      FIELD_DECL, get_identifier (name), type);
2813 }
2814
2815 /* Create a global, static declaration for variable NAME of a given TYPE.  The
2816    finish_var_decl() routine will need to be called on it afterwards.  */
2817
2818 static tree
2819 start_var_decl (tree type, const char *name)
2820 {
2821   tree var = build_decl (input_location,
2822                          VAR_DECL, get_identifier (name), type);
2823
2824   TREE_STATIC (var) = 1;
2825   DECL_INITIAL (var) = error_mark_node;  /* A real initializer is coming... */
2826   DECL_IGNORED_P (var) = 1;
2827   DECL_ARTIFICIAL (var) = 1;
2828   DECL_CONTEXT (var) = NULL_TREE;
2829 #ifdef OBJCPLUS
2830   DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
2831 #endif
2832
2833   return var;
2834 }
2835
2836 /* Finish off the variable declaration created by start_var_decl().  */
2837
2838 static void
2839 finish_var_decl (tree var, tree initializer)
2840 {
2841   finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
2842 }
2843
2844 /* Find the decl for the constant string class reference.  This is only
2845    used for the NeXT runtime.  */
2846
2847 static tree
2848 setup_string_decl (void)
2849 {
2850   char *name;
2851   size_t length;
2852
2853   /* %s in format will provide room for terminating null */
2854   length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
2855            + strlen (constant_string_class_name);
2856   name = XNEWVEC (char, length);
2857   sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
2858            constant_string_class_name);
2859   constant_string_global_id = get_identifier (name);
2860   string_class_decl = lookup_name (constant_string_global_id);
2861
2862   return string_class_decl;
2863 }
2864
2865 /* Purpose: "play" parser, creating/installing representations
2866    of the declarations that are required by Objective-C.
2867
2868    Model:
2869
2870         type_spec--------->sc_spec
2871         (tree_list)        (tree_list)
2872             |                  |
2873             |                  |
2874         identifier_node    identifier_node  */
2875
2876 static void
2877 synth_module_prologue (void)
2878 {
2879   tree type;
2880   enum debug_info_type save_write_symbols = write_symbols;
2881   const struct gcc_debug_hooks *const save_hooks = debug_hooks;
2882
2883   /* Suppress outputting debug symbols, because
2884      dbxout_init hasn't been called yet.  */
2885   write_symbols = NO_DEBUG;
2886   debug_hooks = &do_nothing_debug_hooks;
2887
2888 #ifdef OBJCPLUS
2889   push_lang_context (lang_name_c); /* extern "C" */
2890 #endif
2891
2892   /* The following are also defined in <objc/objc.h> and friends.  */
2893
2894   objc_object_id = get_identifier (TAG_OBJECT);
2895   objc_class_id = get_identifier (TAG_CLASS);
2896
2897   objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
2898   objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
2899
2900   objc_object_type = build_pointer_type (objc_object_reference);
2901   objc_class_type = build_pointer_type (objc_class_reference);
2902
2903   objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
2904   objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
2905
2906   /* Declare the 'id' and 'Class' typedefs.  */
2907
2908   type = lang_hooks.decls.pushdecl (build_decl (input_location,
2909                                                 TYPE_DECL,
2910                                                 objc_object_name,
2911                                                 objc_object_type));
2912   TREE_NO_WARNING (type) = 1;
2913   type = lang_hooks.decls.pushdecl (build_decl (input_location,
2914                                                 TYPE_DECL,
2915                                                 objc_class_name,
2916                                                 objc_class_type));
2917   TREE_NO_WARNING (type) = 1;
2918
2919   /* Forward-declare '@interface Protocol'.  */
2920
2921   type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
2922   objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
2923   objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
2924                                 type));
2925
2926   /* Declare type of selector-objects that represent an operation name.  */
2927
2928   if (flag_next_runtime)
2929     /* `struct objc_selector *' */
2930     objc_selector_type
2931       = build_pointer_type (xref_tag (RECORD_TYPE,
2932                                       get_identifier (TAG_SELECTOR)));
2933   else
2934     /* `const struct objc_selector *' */
2935     objc_selector_type
2936       = build_pointer_type
2937         (build_qualified_type (xref_tag (RECORD_TYPE,
2938                                          get_identifier (TAG_SELECTOR)),
2939                                TYPE_QUAL_CONST));
2940
2941   /* Declare receiver type used for dispatching messages to 'super'.  */
2942
2943   /* `struct objc_super *' */
2944   objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
2945                                                   get_identifier (TAG_SUPER)));
2946
2947   /* Declare pointers to method and ivar lists.  */
2948   objc_method_list_ptr = build_pointer_type
2949                          (xref_tag (RECORD_TYPE,
2950                                     get_identifier (UTAG_METHOD_LIST)));
2951   objc_method_proto_list_ptr
2952     = build_pointer_type (xref_tag (RECORD_TYPE,
2953                                     get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2954   objc_ivar_list_ptr = build_pointer_type
2955                        (xref_tag (RECORD_TYPE,
2956                                   get_identifier (UTAG_IVAR_LIST)));
2957
2958   /* TREE_NOTHROW is cleared for the message-sending functions,
2959      because the function that gets called can throw in Obj-C++, or
2960      could itself call something that can throw even in Obj-C.  */
2961
2962   if (flag_next_runtime)
2963     {
2964       /* NB: In order to call one of the ..._stret (struct-returning)
2965       functions, the function *MUST* first be cast to a signature that
2966       corresponds to the actual ObjC method being invoked.  This is
2967       what is done by the build_objc_method_call() routine below.  */
2968
2969       /* id objc_msgSend (id, SEL, ...); */
2970       /* id objc_msgSendNonNil (id, SEL, ...); */
2971       /* id objc_msgSend_stret (id, SEL, ...); */
2972       /* id objc_msgSendNonNil_stret (id, SEL, ...); */
2973       type
2974         = build_varargs_function_type_list (objc_object_type,
2975                                             objc_object_type,
2976                                             objc_selector_type,
2977                                             NULL_TREE);
2978       umsg_decl = add_builtin_function (TAG_MSGSEND,
2979                                         type, 0, NOT_BUILT_IN,
2980                                         NULL, NULL_TREE);
2981       umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
2982                                                type, 0, NOT_BUILT_IN,
2983                                                NULL, NULL_TREE);
2984       umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
2985                                               type, 0, NOT_BUILT_IN,
2986                                               NULL, NULL_TREE);
2987       umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
2988                                                      type, 0, NOT_BUILT_IN,
2989                                                      NULL, NULL_TREE);
2990
2991       /* These can throw, because the function that gets called can throw
2992          in Obj-C++, or could itself call something that can throw even
2993          in Obj-C.  */
2994       TREE_NOTHROW (umsg_decl) = 0;
2995       TREE_NOTHROW (umsg_nonnil_decl) = 0;
2996       TREE_NOTHROW (umsg_stret_decl) = 0;
2997       TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
2998
2999       /* id objc_msgSend_Fast (id, SEL, ...)
3000            __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
3001 #ifdef OFFS_MSGSEND_FAST
3002       umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
3003                                              type, 0, NOT_BUILT_IN,
3004                                              NULL, NULL_TREE);
3005       TREE_NOTHROW (umsg_fast_decl) = 0;
3006       DECL_ATTRIBUTES (umsg_fast_decl)
3007         = tree_cons (get_identifier ("hard_coded_address"),
3008                      build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
3009                      NULL_TREE);
3010 #else
3011       /* No direct dispatch available.  */
3012       umsg_fast_decl = umsg_decl;
3013 #endif
3014
3015       /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
3016       /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
3017       type
3018         = build_varargs_function_type_list (objc_object_type,
3019                                             objc_super_type,
3020                                             objc_selector_type,
3021                                             NULL_TREE);
3022       umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
3023                                               type, 0, NOT_BUILT_IN,
3024                                               NULL, NULL_TREE);
3025       umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
3026                                                     type, 0, NOT_BUILT_IN, 0,
3027                                                     NULL_TREE);
3028       TREE_NOTHROW (umsg_super_decl) = 0;
3029       TREE_NOTHROW (umsg_super_stret_decl) = 0;
3030     }
3031   else
3032     {
3033       /* GNU runtime messenger entry points.  */
3034
3035       /* typedef id (*IMP)(id, SEL, ...); */
3036       tree ftype =
3037         build_varargs_function_type_list (objc_object_type,
3038                                           objc_object_type,
3039                                           objc_selector_type,
3040                                           NULL_TREE);
3041       tree IMP_type = build_pointer_type (ftype);
3042
3043       /* IMP objc_msg_lookup (id, SEL); */
3044       type = build_function_type_list (IMP_type,
3045                                        objc_object_type,
3046                                        objc_selector_type,
3047                                        NULL_TREE);
3048       umsg_decl = add_builtin_function (TAG_MSGSEND,
3049                                         type, 0, NOT_BUILT_IN,
3050                                         NULL, NULL_TREE);
3051       TREE_NOTHROW (umsg_decl) = 0;
3052
3053       /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
3054       type
3055         = build_function_type_list (IMP_type,
3056                                     objc_super_type,
3057                                     objc_selector_type,
3058                                     NULL_TREE);
3059       umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
3060                                               type, 0, NOT_BUILT_IN,
3061                                               NULL, NULL_TREE);
3062       TREE_NOTHROW (umsg_super_decl) = 0;
3063
3064       /* The following GNU runtime entry point is called to initialize
3065          each module:
3066
3067          __objc_exec_class (void *); */
3068       type
3069         = build_function_type_list (void_type_node,
3070                                     ptr_type_node,
3071                                     NULL_TREE);
3072       execclass_decl = add_builtin_function (TAG_EXECCLASS,
3073                                              type, 0, NOT_BUILT_IN,
3074                                              NULL, NULL_TREE);
3075     }
3076
3077   /* id objc_getClass (const char *); */
3078
3079   type = build_function_type_list (objc_object_type,
3080                                    const_string_type_node,
3081                                    NULL_TREE);
3082
3083   objc_get_class_decl
3084     = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
3085                             NULL, NULL_TREE);
3086
3087   /* id objc_getMetaClass (const char *); */
3088
3089   objc_get_meta_class_decl
3090     = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3091
3092   build_class_template ();
3093   build_super_template ();
3094   build_protocol_template ();
3095   build_category_template ();
3096   build_objc_exception_stuff ();
3097
3098   /* Declare objc_getProperty, object_setProperty and other property
3099      accessor helpers.  */
3100   build_objc_property_accessor_helpers ();
3101
3102   if (flag_next_runtime)
3103     build_next_objc_exception_stuff ();
3104
3105   /* static SEL _OBJC_SELECTOR_TABLE[]; */
3106
3107   if (! flag_next_runtime)
3108     build_selector_table_decl ();
3109
3110   /* Forward declare constant_string_id and constant_string_type.  */
3111   if (!constant_string_class_name)
3112     constant_string_class_name = default_constant_string_class_name;
3113
3114   constant_string_id = get_identifier (constant_string_class_name);
3115   objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
3116
3117   /* Pre-build the following entities - for speed/convenience.  */
3118   self_id = get_identifier ("self");
3119   ucmd_id = get_identifier ("_cmd");
3120
3121   /* Declare struct _objc_fast_enumeration_state { ... };  */
3122   build_fast_enumeration_state_template ();
3123   
3124   /* void objc_enumeration_mutation (id) */
3125   type = build_function_type (void_type_node,
3126                               tree_cons (NULL_TREE, objc_object_type, NULL_TREE));
3127   objc_enumeration_mutation_decl 
3128     = add_builtin_function (TAG_ENUMERATION_MUTATION, type, 0, NOT_BUILT_IN, 
3129                             NULL, NULL_TREE);
3130   TREE_NOTHROW (objc_enumeration_mutation_decl) = 0;
3131
3132 #ifdef OBJCPLUS
3133   pop_lang_context ();
3134 #endif
3135
3136   write_symbols = save_write_symbols;
3137   debug_hooks = save_hooks;
3138 }
3139
3140 /* Ensure that the ivar list for NSConstantString/NXConstantString
3141    (or whatever was specified via `-fconstant-string-class')
3142    contains fields at least as large as the following three, so that
3143    the runtime can stomp on them with confidence:
3144
3145    struct STRING_OBJECT_CLASS_NAME
3146    {
3147      Object isa;
3148      char *cString;
3149      unsigned int length;
3150    }; */
3151
3152 static int
3153 check_string_class_template (void)
3154 {
3155   tree field_decl = objc_get_class_ivars (constant_string_id);
3156
3157 #define AT_LEAST_AS_LARGE_AS(F, T) \
3158   (F && TREE_CODE (F) == FIELD_DECL \
3159      && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
3160          >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
3161
3162   if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
3163     return 0;
3164
3165   field_decl = DECL_CHAIN (field_decl);
3166   if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
3167     return 0;
3168
3169   field_decl = DECL_CHAIN (field_decl);
3170   return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
3171
3172 #undef AT_LEAST_AS_LARGE_AS
3173 }
3174
3175 /* Avoid calling `check_string_class_template ()' more than once.  */
3176 static GTY(()) int string_layout_checked;
3177
3178 /* Construct an internal string layout to be used as a template for
3179    creating NSConstantString/NXConstantString instances.  */
3180
3181 static tree
3182 objc_build_internal_const_str_type (void)
3183 {
3184   tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
3185   tree fields = build_decl (input_location,
3186                             FIELD_DECL, NULL_TREE, ptr_type_node);
3187   tree field = build_decl (input_location,
3188                            FIELD_DECL, NULL_TREE, ptr_type_node);
3189
3190   DECL_CHAIN (field) = fields; fields = field;
3191   field = build_decl (input_location,
3192                       FIELD_DECL, NULL_TREE, unsigned_type_node);
3193   DECL_CHAIN (field) = fields; fields = field;
3194   /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
3195      reverse order!  */
3196   finish_builtin_struct (type, "__builtin_ObjCString",
3197                          fields, NULL_TREE);
3198
3199   return type;
3200 }
3201
3202 /* Custom build_string which sets TREE_TYPE!  */
3203
3204 static tree
3205 my_build_string (int len, const char *str)
3206 {
3207   return fix_string_type (build_string (len, str));
3208 }
3209
3210 /* Build a string with contents STR and length LEN and convert it to a
3211    pointer.  */
3212
3213 static tree
3214 my_build_string_pointer (int len, const char *str)
3215 {
3216   tree string = my_build_string (len, str);
3217   tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
3218   return build1 (ADDR_EXPR, ptrtype, string);
3219 }
3220
3221 static hashval_t
3222 string_hash (const void *ptr)
3223 {
3224   const_tree const str = ((const struct string_descriptor *)ptr)->literal;
3225   const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
3226   int i, len = TREE_STRING_LENGTH (str);
3227   hashval_t h = len;
3228
3229   for (i = 0; i < len; i++)
3230     h = ((h * 613) + p[i]);
3231
3232   return h;
3233 }
3234
3235 static int
3236 string_eq (const void *ptr1, const void *ptr2)
3237 {
3238   const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
3239   const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
3240   int len1 = TREE_STRING_LENGTH (str1);
3241
3242   return (len1 == TREE_STRING_LENGTH (str2)
3243           && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
3244                       len1));
3245 }
3246
3247 /* Given a chain of STRING_CST's, build a static instance of
3248    NXConstantString which points at the concatenation of those
3249    strings.  We place the string object in the __string_objects
3250    section of the __OBJC segment.  The Objective-C runtime will
3251    initialize the isa pointers of the string objects to point at the
3252    NXConstantString class object.  */
3253
3254 tree
3255 objc_build_string_object (tree string)
3256 {
3257   tree constant_string_class;
3258   int length;
3259   tree fields, addr;
3260   struct string_descriptor *desc, key;
3261   void **loc;
3262
3263   /* Prep the string argument.  */
3264   string = fix_string_type (string);
3265   TREE_SET_CODE (string, STRING_CST);
3266   length = TREE_STRING_LENGTH (string) - 1;
3267
3268   /* The target may have different ideas on how to construct an ObjC string 
3269      literal.  On Darwin (Mac OS X), for example, we may wish to obtain a 
3270      constant CFString reference instead.
3271      At present, this is only supported for the NeXT runtime.  */
3272   if (flag_next_runtime && targetcm.objc_construct_string_object)
3273     {
3274       tree constructor = (*targetcm.objc_construct_string_object) (string);
3275       if (constructor)
3276         return build1 (NOP_EXPR, objc_object_type, constructor);
3277     }
3278
3279   /* Check whether the string class being used actually exists and has the
3280      correct ivar layout.  */
3281   if (!string_layout_checked)
3282     {
3283       string_layout_checked = -1;
3284       constant_string_class = lookup_interface (constant_string_id);
3285       internal_const_str_type = objc_build_internal_const_str_type ();
3286
3287       if (!constant_string_class
3288           || !(constant_string_type
3289                = CLASS_STATIC_TEMPLATE (constant_string_class)))
3290         error ("cannot find interface declaration for %qE",
3291                constant_string_id);
3292       /* The NSConstantString/NXConstantString ivar layout is now known.  */
3293       else if (!check_string_class_template ())
3294         error ("interface %qE does not have valid constant string layout",
3295                constant_string_id);
3296       /* For the NeXT runtime, we can generate a literal reference
3297          to the string class, don't need to run a constructor.  */
3298       else if (flag_next_runtime && !setup_string_decl ())
3299         error ("cannot find reference tag for class %qE",
3300                constant_string_id);
3301       else
3302         {
3303           string_layout_checked = 1;  /* Success!  */
3304           add_class_reference (constant_string_id);
3305         }
3306     }
3307
3308   if (string_layout_checked == -1)
3309     return error_mark_node;
3310
3311   /* Perhaps we already constructed a constant string just like this one? */
3312   key.literal = string;
3313   loc = htab_find_slot (string_htab, &key, INSERT);
3314   desc = (struct string_descriptor *) *loc;
3315
3316   if (!desc)
3317     {
3318       tree var, constructor;
3319       VEC(constructor_elt,gc) *v = NULL;
3320       *loc = desc = ggc_alloc_string_descriptor ();
3321       desc->literal = string;
3322
3323       /* GNU:    (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length })  */
3324       /* NeXT:   (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length })   */
3325       fields = TYPE_FIELDS (internal_const_str_type);
3326       CONSTRUCTOR_APPEND_ELT (v, fields,
3327                               flag_next_runtime
3328                               ? build_unary_op (input_location,
3329                                                 ADDR_EXPR, string_class_decl, 0)
3330                               : build_int_cst (NULL_TREE, 0));
3331       fields = DECL_CHAIN (fields);
3332       CONSTRUCTOR_APPEND_ELT (v, fields,
3333                               build_unary_op (input_location,
3334                                               ADDR_EXPR, string, 1));
3335       fields = DECL_CHAIN (fields);
3336       CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
3337       constructor = objc_build_constructor (internal_const_str_type, v);
3338
3339       if (!flag_next_runtime)
3340         constructor
3341           = objc_add_static_instance (constructor, constant_string_type);
3342       else
3343         {
3344           var = build_decl (input_location,
3345                             CONST_DECL, NULL, TREE_TYPE (constructor));
3346           DECL_INITIAL (var) = constructor;
3347           TREE_STATIC (var) = 1;
3348           pushdecl_top_level (var);
3349           constructor = var;
3350         }
3351       desc->constructor = constructor;
3352     }
3353
3354   addr = convert (build_pointer_type (constant_string_type),
3355                   build_unary_op (input_location,
3356                                   ADDR_EXPR, desc->constructor, 1));
3357
3358   return addr;
3359 }
3360
3361 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR.  */
3362
3363 static GTY(()) int num_static_inst;
3364
3365 static tree
3366 objc_add_static_instance (tree constructor, tree class_decl)
3367 {
3368   tree *chain, decl;
3369   char buf[256];
3370
3371   /* Find the list of static instances for the CLASS_DECL.  Create one if
3372      not found.  */
3373   for (chain = &objc_static_instances;
3374        *chain && TREE_VALUE (*chain) != class_decl;
3375        chain = &TREE_CHAIN (*chain));
3376   if (!*chain)
3377     {
3378       *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
3379       add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
3380     }
3381
3382   sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
3383   decl = build_decl (input_location,
3384                      VAR_DECL, get_identifier (buf), class_decl);
3385   TREE_STATIC (decl) = 1;
3386   DECL_ARTIFICIAL (decl) = 1;
3387   TREE_USED (decl) = 1;
3388   DECL_INITIAL (decl) = constructor;
3389
3390   /* We may be writing something else just now.
3391      Postpone till end of input.  */
3392   DECL_DEFER_OUTPUT (decl) = 1;
3393   pushdecl_top_level (decl);
3394   rest_of_decl_compilation (decl, 1, 0);
3395
3396   /* Add the DECL to the head of this CLASS' list.  */
3397   TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
3398
3399   return decl;
3400 }
3401
3402 /* Build a static constant CONSTRUCTOR
3403    with type TYPE and elements ELTS.  */
3404
3405 static tree
3406 objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts)
3407 {
3408   tree constructor = build_constructor (type, elts);
3409
3410   TREE_CONSTANT (constructor) = 1;
3411   TREE_STATIC (constructor) = 1;
3412   TREE_READONLY (constructor) = 1;
3413
3414 #ifdef OBJCPLUS
3415   /* Adjust for impedance mismatch.  We should figure out how to build
3416      CONSTRUCTORs that consistently please both the C and C++ gods.  */
3417   if (!VEC_index (constructor_elt, elts, 0)->index)
3418     TREE_TYPE (constructor) = init_list_type_node;
3419 #endif
3420
3421   return constructor;
3422 }
3423 \f
3424 /* Take care of defining and initializing _OBJC_SYMBOLS.  */
3425
3426 /* Predefine the following data type:
3427
3428    struct _objc_symtab
3429    {
3430      long sel_ref_cnt;
3431      SEL *refs;
3432      short cls_def_cnt;
3433      short cat_def_cnt;
3434      void *defs[cls_def_cnt + cat_def_cnt];
3435    }; */
3436
3437 static void
3438 build_objc_symtab_template (void)
3439 {
3440   tree fields, *chain = NULL;
3441
3442   objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
3443
3444   /* long sel_ref_cnt; */
3445   fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
3446
3447   /* SEL *refs; */
3448   add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
3449
3450   /* short cls_def_cnt; */
3451   add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
3452
3453   /* short cat_def_cnt; */
3454   add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
3455
3456   if (imp_count || cat_count || !flag_next_runtime)
3457     {
3458       /* void *defs[imp_count + cat_count (+ 1)]; */
3459       /* NB: The index is one less than the size of the array.  */
3460       int index = imp_count + cat_count + (flag_next_runtime ? -1: 0);
3461       tree array_type = build_sized_array_type (ptr_type_node, index + 1);
3462       add_field_decl (array_type, "defs", &chain);
3463     }
3464
3465   objc_finish_struct (objc_symtab_template, fields);
3466 }
3467
3468 /* Create the initial value for the `defs' field of _objc_symtab.
3469    This is a CONSTRUCTOR.  */
3470
3471 static tree
3472 init_def_list (tree type)
3473 {
3474   tree expr;
3475   struct imp_entry *impent;
3476   VEC(constructor_elt,gc) *v = NULL;
3477
3478   if (imp_count)
3479     for (impent = imp_list; impent; impent = impent->next)
3480       {
3481         if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
3482           {
3483             expr = build_unary_op (input_location,
3484                                    ADDR_EXPR, impent->class_decl, 0);
3485             CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3486           }
3487       }
3488
3489   if (cat_count)
3490     for (impent = imp_list; impent; impent = impent->next)
3491       {
3492         if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
3493           {
3494             expr = build_unary_op (input_location,
3495                                    ADDR_EXPR, impent->class_decl, 0);
3496             CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3497           }
3498       }
3499
3500   if (!flag_next_runtime)
3501     {
3502       /* statics = { ..., _OBJC_STATIC_INSTANCES, ... }  */
3503       if (static_instances_decl)
3504         expr = build_unary_op (input_location,
3505                                ADDR_EXPR, static_instances_decl, 0);
3506       else
3507         expr = integer_zero_node;
3508
3509       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3510     }
3511
3512   return objc_build_constructor (type, v);
3513 }
3514
3515 /* Construct the initial value for all of _objc_symtab.  */
3516
3517 static tree
3518 init_objc_symtab (tree type)
3519 {
3520   VEC(constructor_elt,gc) *v = NULL;
3521
3522   /* sel_ref_cnt = { ..., 5, ... } */
3523
3524   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3525                           build_int_cst (long_integer_type_node, 0));
3526
3527   /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
3528
3529   if (flag_next_runtime || ! sel_ref_chain)
3530     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (
3531                                         build_pointer_type (objc_selector_type),
3532                                                         integer_zero_node));
3533   else
3534     {
3535       tree expr = build_unary_op (input_location, ADDR_EXPR,
3536                                   UOBJC_SELECTOR_TABLE_decl, 1);
3537
3538       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3539                               convert (build_pointer_type (objc_selector_type),
3540                                        expr));
3541     }
3542
3543   /* cls_def_cnt = { ..., 5, ... } */
3544
3545   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 
3546                           build_int_cst (short_integer_type_node, imp_count));
3547
3548   /* cat_def_cnt = { ..., 5, ... } */
3549
3550   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 
3551                           build_int_cst (short_integer_type_node, cat_count));
3552
3553   /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
3554
3555   if (imp_count || cat_count || !flag_next_runtime)
3556     {
3557
3558       tree field = TYPE_FIELDS (type);
3559       field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
3560
3561       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
3562     }
3563
3564   return objc_build_constructor (type, v);
3565 }
3566
3567 /* Generate forward declarations for metadata such as
3568   'OBJC_CLASS_...'.  */
3569
3570 static tree
3571 build_metadata_decl (const char *name, tree type)
3572 {
3573   tree decl;
3574
3575   /* struct TYPE NAME_<name>; */
3576   decl = start_var_decl (type, synth_id_with_class_suffix
3577                                (name,
3578                                 objc_implementation_context));
3579
3580   return decl;
3581 }
3582
3583 /* Push forward-declarations of all the categories so that
3584    init_def_list can use them in a CONSTRUCTOR.  */
3585
3586 static void
3587 forward_declare_categories (void)
3588 {
3589   struct imp_entry *impent;
3590   tree sav = objc_implementation_context;
3591
3592   for (impent = imp_list; impent; impent = impent->next)
3593     {
3594       if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
3595         {
3596           /* Set an invisible arg to synth_id_with_class_suffix.  */
3597           objc_implementation_context = impent->imp_context;
3598           /* extern struct objc_category _OBJC_CATEGORY_<name>; */
3599           impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
3600                                                     objc_category_template);
3601         }
3602     }
3603   objc_implementation_context = sav;
3604 }
3605
3606 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
3607    and initialized appropriately.  */
3608
3609 static void
3610 generate_objc_symtab_decl (void)
3611 {
3612  
3613   build_objc_symtab_template ();
3614   UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
3615   finish_var_decl (UOBJC_SYMBOLS_decl,
3616                    init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
3617 }
3618 \f
3619 static tree
3620 init_module_descriptor (tree type)
3621 {
3622   tree expr;
3623   VEC(constructor_elt,gc) *v = NULL;
3624
3625   /* version = { 1, ... } */
3626
3627   expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
3628   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3629
3630   /* size = { ..., sizeof (struct _objc_module), ... } */
3631
3632   expr = convert (long_integer_type_node,
3633                   size_in_bytes (objc_module_template));
3634   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3635
3636   /* Don't provide any file name for security reasons. */
3637   /* name = { ..., "", ... } */
3638
3639   expr = add_objc_string (get_identifier (""), class_names);
3640   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3641
3642   /* symtab = { ..., _OBJC_SYMBOLS, ... } */
3643
3644   if (UOBJC_SYMBOLS_decl)
3645     expr = build_unary_op (input_location,
3646                            ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
3647   else
3648     expr = null_pointer_node;
3649   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3650
3651   return objc_build_constructor (type, v);
3652 }
3653
3654 /* Write out the data structures to describe Objective C classes defined.
3655
3656    struct _objc_module { ... } _OBJC_MODULE = { ... };   */
3657
3658 static void
3659 build_module_descriptor (void)
3660 {
3661   tree decls, *chain = NULL;
3662
3663 #ifdef OBJCPLUS
3664   push_lang_context (lang_name_c); /* extern "C" */
3665 #endif
3666
3667   objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
3668
3669   /* long version; */
3670   decls = add_field_decl (long_integer_type_node, "version", &chain);
3671
3672   /* long size; */
3673   add_field_decl (long_integer_type_node, "size", &chain);
3674
3675   /* char *name; */
3676   add_field_decl (string_type_node, "name", &chain);
3677
3678   /* struct _objc_symtab *symtab; */
3679   add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
3680                                                 get_identifier (UTAG_SYMTAB))),
3681                   "symtab", &chain);
3682
3683   objc_finish_struct (objc_module_template, decls);
3684
3685   /* Create an instance of "_objc_module".  */
3686   UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
3687   /* This is the root of the metadata for defined classes and categories, it
3688      is referenced by the runtime and, therefore, needed.  */
3689   DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
3690   finish_var_decl (UOBJC_MODULES_decl,
3691                    init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
3692
3693 #ifdef OBJCPLUS
3694   pop_lang_context ();
3695 #endif
3696 }
3697
3698 /* The GNU runtime requires us to provide a static initializer function
3699    for each module:
3700
3701    static void __objc_gnu_init (void) {
3702      __objc_exec_class (&L_OBJC_MODULES);
3703    }  */
3704
3705 static void
3706 build_module_initializer_routine (void)
3707 {
3708   tree body;
3709
3710 #ifdef OBJCPLUS
3711   push_lang_context (lang_name_c); /* extern "C" */
3712 #endif
3713
3714   objc_push_parm (build_decl (input_location,
3715                               PARM_DECL, NULL_TREE, void_type_node));
3716 #ifdef OBJCPLUS
3717   objc_start_function (get_identifier (TAG_GNUINIT),
3718                        build_function_type_list (void_type_node, NULL_TREE),
3719                        NULL_TREE, NULL_TREE);
3720 #else
3721   objc_start_function (get_identifier (TAG_GNUINIT),
3722                        build_function_type_list (void_type_node, NULL_TREE),
3723                        NULL_TREE, objc_get_parm_info (0));
3724 #endif
3725   body = c_begin_compound_stmt (true);
3726   add_stmt (build_function_call
3727             (input_location,
3728              execclass_decl,
3729              build_tree_list
3730              (NULL_TREE,
3731               build_unary_op (input_location, ADDR_EXPR,
3732                               UOBJC_MODULES_decl, 0))));
3733   add_stmt (c_end_compound_stmt (input_location, body, true));
3734
3735   TREE_PUBLIC (current_function_decl) = 0;
3736
3737 #ifndef OBJCPLUS
3738   /* For Objective-C++, we will need to call __objc_gnu_init
3739      from objc_generate_static_init_call() below.  */
3740   DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
3741 #endif
3742
3743   GNU_INIT_decl = current_function_decl;
3744   finish_function ();
3745
3746 #ifdef OBJCPLUS
3747     pop_lang_context ();
3748 #endif
3749 }
3750
3751 #ifdef OBJCPLUS
3752 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
3753    to be called by the module initializer routine.  */
3754
3755 int
3756 objc_static_init_needed_p (void)
3757 {
3758   return (GNU_INIT_decl != NULL_TREE);
3759 }
3760
3761 /* Generate a call to the __objc_gnu_init initializer function.  */
3762
3763 tree
3764 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
3765 {
3766   add_stmt (build_stmt (input_location, EXPR_STMT,
3767                         build_function_call (input_location,
3768                                              GNU_INIT_decl, NULL_TREE)));
3769
3770   return ctors;
3771 }
3772 #endif /* OBJCPLUS */
3773
3774 /* Return the DECL of the string IDENT in the SECTION.  */
3775
3776 static tree
3777 get_objc_string_decl (tree ident, enum string_section section)
3778 {
3779   tree chain;
3780
3781   switch (section)
3782     {
3783     case class_names:
3784       chain = class_names_chain;
3785       break;
3786     case meth_var_names:
3787       chain = meth_var_names_chain;
3788       break;
3789     case meth_var_types:
3790       chain = meth_var_types_chain;
3791       break;
3792     default:
3793       gcc_unreachable ();
3794     }
3795
3796   for (; chain != 0; chain = TREE_CHAIN (chain))
3797     if (TREE_VALUE (chain) == ident)
3798       return (TREE_PURPOSE (chain));
3799
3800   gcc_unreachable ();
3801   return NULL_TREE;
3802 }
3803
3804 /* Output references to all statically allocated objects.  Return the DECL
3805    for the array built.  */
3806
3807 static void
3808 generate_static_references (void)
3809 {
3810   tree expr = NULL_TREE;
3811   tree class_name, klass, decl;
3812   tree cl_chain, in_chain, type
3813     = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
3814   int num_inst, num_class;
3815   char buf[256];
3816   VEC(constructor_elt,gc) *decls = NULL;
3817
3818   if (flag_next_runtime)
3819     gcc_unreachable ();
3820
3821   for (cl_chain = objc_static_instances, num_class = 0;
3822        cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
3823     {
3824       VEC(constructor_elt,gc) *v = NULL;
3825
3826       for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
3827            in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
3828
3829       sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
3830       decl = start_var_decl (type, buf);
3831
3832       /* Output {class_name, ...}.  */
3833       klass = TREE_VALUE (cl_chain);
3834       class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
3835       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3836                               build_unary_op (input_location, 
3837                                               ADDR_EXPR, class_name, 1));
3838
3839       /* Output {..., instance, ...}.  */
3840       for (in_chain = TREE_PURPOSE (cl_chain);
3841            in_chain; in_chain = TREE_CHAIN (in_chain))
3842         {
3843           expr = build_unary_op (input_location,
3844                                  ADDR_EXPR, TREE_VALUE (in_chain), 1);
3845           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3846         }
3847
3848       /* Output {..., NULL}.  */
3849       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
3850
3851       expr = objc_build_constructor (TREE_TYPE (decl), v);
3852       finish_var_decl (decl, expr);
3853       CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
3854                               build_unary_op (input_location,
3855                                               ADDR_EXPR, decl, 1));
3856     }
3857
3858   CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
3859   expr = objc_build_constructor (type, decls);
3860   static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
3861   finish_var_decl (static_instances_decl, expr);
3862 }
3863
3864 static GTY(()) int selector_reference_idx;
3865
3866 static tree
3867 build_selector_reference_decl (void)
3868 {
3869   tree decl;
3870   char buf[256];
3871
3872   sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
3873   decl = start_var_decl (objc_selector_type, buf);
3874
3875   return decl;
3876 }
3877
3878 static void
3879 build_selector_table_decl (void)
3880 {
3881   tree temp;
3882
3883   if (flag_typed_selectors)
3884     {
3885       build_selector_template ();
3886       temp = build_array_type (objc_selector_template, NULL_TREE);
3887     }
3888   else
3889     temp = build_array_type (objc_selector_type, NULL_TREE);
3890
3891   UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
3892 }
3893
3894 /* Just a handy wrapper for add_objc_string.  */
3895
3896 static tree
3897 build_selector (tree ident)
3898 {
3899   return convert (objc_selector_type,
3900                   add_objc_string (ident, meth_var_names));
3901 }
3902
3903 /* Used only by build_*_selector_translation_table (). */
3904 static void
3905 diagnose_missing_method (tree meth, location_t here)
3906 {
3907   tree method_chain;
3908   bool found = false;
3909   for (method_chain = meth_var_names_chain;
3910        method_chain;
3911        method_chain = TREE_CHAIN (method_chain))
3912     {
3913       if (TREE_VALUE (method_chain) == meth)
3914         {
3915           found = true;
3916           break;
3917         }
3918      }
3919
3920   if (!found)
3921     warning_at (here, 0, "creating selector for nonexistent method %qE",
3922                         meth);
3923 }
3924
3925 static void
3926 build_next_selector_translation_table (void)
3927 {
3928   tree chain;
3929   for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
3930     {
3931       tree expr;
3932       tree decl = TREE_PURPOSE (chain);
3933       if (warn_selector && objc_implementation_context)
3934         {
3935           location_t loc;
3936           if (decl) 
3937             loc = DECL_SOURCE_LOCATION (decl);
3938           else
3939             loc = input_location;
3940           diagnose_missing_method (TREE_VALUE (chain), loc);
3941         }
3942
3943       expr = build_selector (TREE_VALUE (chain));
3944
3945       if (decl)
3946         {
3947           /* Entries of this form are used for references to methods.
3948           The runtime re-writes these on start-up, but the compiler can't see 
3949           that and optimizes it away unless we force it.  */
3950           DECL_PRESERVE_P (decl) = 1;
3951           finish_var_decl (decl, expr);
3952         }
3953     }
3954 }
3955
3956 static void
3957 build_gnu_selector_translation_table (void)
3958 {
3959   tree chain;
3960 /*  int offset = 0;
3961   tree decl = NULL_TREE;*/
3962   VEC(constructor_elt,gc) *inits = NULL;
3963
3964   for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
3965     {
3966       tree expr;
3967
3968       if (warn_selector && objc_implementation_context)
3969         diagnose_missing_method (TREE_VALUE (chain), input_location);
3970
3971       expr = build_selector (TREE_VALUE (chain));
3972       /* add one for the '\0' character 
3973       offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
3974
3975         {
3976           if (flag_typed_selectors)
3977             {
3978               VEC(constructor_elt,gc) *v = NULL;
3979               tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
3980               CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3981               CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
3982               expr = objc_build_constructor (objc_selector_template, v);
3983             }
3984
3985           CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
3986         }
3987     } /* each element in the chain */
3988
3989     {
3990       /* Cause the selector table (previously forward-declared)
3991          to be actually output.  */
3992       tree expr;
3993
3994       if (flag_typed_selectors)
3995         {
3996           VEC(constructor_elt,gc) *v = NULL;
3997           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
3998           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
3999           expr = objc_build_constructor (objc_selector_template, v);
4000         }
4001       else
4002         expr = integer_zero_node;
4003
4004       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
4005       expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
4006                                      inits);
4007       finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
4008     }
4009 }
4010
4011 static tree
4012 get_proto_encoding (tree proto)
4013 {
4014   tree encoding;
4015   if (proto)
4016     {
4017       if (! METHOD_ENCODING (proto))
4018         {
4019           encoding = encode_method_prototype (proto);
4020           METHOD_ENCODING (proto) = encoding;
4021         }
4022       else
4023         encoding = METHOD_ENCODING (proto);
4024
4025       return add_objc_string (encoding, meth_var_types);
4026     }
4027   else
4028     return build_int_cst (NULL_TREE, 0);
4029 }
4030
4031 /* sel_ref_chain is a list whose "value" fields will be instances of
4032    identifier_node that represent the selector.  LOC is the location of
4033    the @selector.  */
4034
4035 static tree
4036 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
4037 {
4038   tree *chain = &sel_ref_chain;
4039   tree expr;
4040   int index = 0;
4041
4042   while (*chain)
4043     {
4044       if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
4045         goto return_at_index;
4046
4047       index++;
4048       chain = &TREE_CHAIN (*chain);
4049     }
4050
4051   *chain = tree_cons (prototype, ident, NULL_TREE);
4052
4053  return_at_index:
4054   expr = build_unary_op (loc, ADDR_EXPR,
4055                          build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
4056                                           build_int_cst (NULL_TREE, index)),
4057                          1);
4058   return convert (objc_selector_type, expr);
4059 }
4060
4061 static tree
4062 build_selector_reference (location_t loc, tree ident)
4063 {
4064   tree *chain = &sel_ref_chain;
4065   tree expr;
4066   int index = 0;
4067
4068   while (*chain)
4069     {
4070       if (TREE_VALUE (*chain) == ident)
4071         return (flag_next_runtime
4072                 ? TREE_PURPOSE (*chain)
4073                 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
4074                                    build_int_cst (NULL_TREE, index)));
4075
4076       index++;
4077       chain = &TREE_CHAIN (*chain);
4078     }
4079
4080   expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
4081
4082   *chain = tree_cons (expr, ident, NULL_TREE);
4083
4084   return (flag_next_runtime
4085           ? expr
4086           : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
4087                              build_int_cst (NULL_TREE, index)));
4088 }
4089
4090 static GTY(()) int class_reference_idx;
4091
4092 static tree
4093 build_class_reference_decl (void)
4094 {
4095   tree decl;
4096   char buf[256];
4097
4098   sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
4099   decl = start_var_decl (objc_class_type, buf);
4100
4101   return decl;
4102 }
4103
4104 /* Create a class reference, but don't create a variable to reference
4105    it.  */
4106
4107 static void
4108 add_class_reference (tree ident)
4109 {
4110   tree chain;
4111
4112   if ((chain = cls_ref_chain))
4113     {
4114       tree tail;
4115       do
4116         {
4117           if (ident == TREE_VALUE (chain))
4118             return;
4119
4120           tail = chain;
4121           chain = TREE_CHAIN (chain);
4122         }
4123       while (chain);
4124
4125       /* Append to the end of the list */
4126       TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
4127     }
4128   else
4129     cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
4130 }
4131
4132 /* Get a class reference, creating it if necessary.  Also create the
4133    reference variable.  */
4134
4135 tree
4136 objc_get_class_reference (tree ident)
4137 {
4138   tree orig_ident = (DECL_P (ident)
4139                      ? DECL_NAME (ident)
4140                      : TYPE_P (ident)
4141                      ? OBJC_TYPE_NAME (ident)
4142                      : ident);
4143   bool local_scope = false;
4144
4145 #ifdef OBJCPLUS
4146   if (processing_template_decl)
4147     /* Must wait until template instantiation time.  */
4148     return build_min_nt (CLASS_REFERENCE_EXPR, ident);
4149 #endif
4150
4151   if (TREE_CODE (ident) == TYPE_DECL)
4152     ident = (DECL_ORIGINAL_TYPE (ident)
4153              ? DECL_ORIGINAL_TYPE (ident)
4154              : TREE_TYPE (ident));
4155
4156 #ifdef OBJCPLUS
4157   if (TYPE_P (ident)
4158       && CP_TYPE_CONTEXT (ident) != global_namespace)
4159     local_scope = true;
4160 #endif
4161
4162   if (local_scope || !(ident = objc_is_class_name (ident)))
4163     {
4164       error ("%qE is not an Objective-C class name or alias",
4165              orig_ident);
4166       return error_mark_node;
4167     }
4168
4169   if (flag_next_runtime && !flag_zero_link)
4170     {
4171       tree *chain;
4172       tree decl;
4173
4174       for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
4175         if (TREE_VALUE (*chain) == ident)
4176           {
4177             if (! TREE_PURPOSE (*chain))
4178               TREE_PURPOSE (*chain) = build_class_reference_decl ();
4179
4180             return TREE_PURPOSE (*chain);
4181           }
4182
4183       decl = build_class_reference_decl ();
4184       *chain = tree_cons (decl, ident, NULL_TREE);
4185       return decl;
4186     }
4187   else
4188     {
4189       tree params;
4190
4191       add_class_reference (ident);
4192
4193       params = build_tree_list (NULL_TREE,
4194                                 my_build_string_pointer
4195                                 (IDENTIFIER_LENGTH (ident) + 1,
4196                                  IDENTIFIER_POINTER (ident)));
4197
4198       assemble_external (objc_get_class_decl);
4199       return build_function_call (input_location, objc_get_class_decl, params);
4200     }
4201 }
4202
4203 /* For each string section we have a chain which maps identifier nodes
4204    to decls for the strings.  */
4205
4206 static GTY(()) int class_names_idx;
4207 static GTY(()) int meth_var_names_idx;
4208 static GTY(()) int meth_var_types_idx;
4209
4210 static tree
4211 add_objc_string (tree ident, enum string_section section)
4212 {
4213   tree *chain, decl, type, string_expr;
4214   char buf[256];
4215   
4216   buf[0] = 0;
4217   switch (section)
4218     {
4219     case class_names:
4220       chain = &class_names_chain;
4221       sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
4222       break;
4223     case meth_var_names:
4224       chain = &meth_var_names_chain;
4225       sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
4226       break;
4227     case meth_var_types:
4228       chain = &meth_var_types_chain;
4229       sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
4230       break;
4231     default:
4232       gcc_unreachable ();
4233     }
4234
4235   while (*chain)
4236     {
4237       if (TREE_VALUE (*chain) == ident)
4238         return convert (string_type_node,
4239                         build_unary_op (input_location,
4240                                         ADDR_EXPR, TREE_PURPOSE (*chain), 1));
4241
4242       chain = &TREE_CHAIN (*chain);
4243     }
4244
4245   type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
4246   decl = start_var_decl (type, buf);
4247   string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
4248                                  IDENTIFIER_POINTER (ident));
4249   TREE_CONSTANT (decl) = 1;
4250   finish_var_decl (decl, string_expr);
4251
4252   *chain = tree_cons (decl, ident, NULL_TREE);
4253
4254   return convert (string_type_node, build_unary_op (input_location,
4255                                                     ADDR_EXPR, decl, 1));
4256 }
4257
4258 void
4259 objc_declare_alias (tree alias_ident, tree class_ident)
4260 {
4261   tree underlying_class;
4262
4263 #ifdef OBJCPLUS
4264   if (current_namespace != global_namespace) {
4265     error ("Objective-C declarations may only appear in global scope");
4266   }
4267 #endif /* OBJCPLUS */
4268
4269   if (!(underlying_class = objc_is_class_name (class_ident)))
4270     warning (0, "cannot find class %qE", class_ident);
4271   else if (objc_is_class_name (alias_ident))
4272     warning (0, "class %qE already exists", alias_ident);
4273   else
4274     {
4275       /* Implement @compatibility_alias as a typedef.  */
4276 #ifdef OBJCPLUS
4277       push_lang_context (lang_name_c); /* extern "C" */
4278 #endif
4279       lang_hooks.decls.pushdecl (build_decl
4280                                  (input_location,
4281                                   TYPE_DECL,
4282                                   alias_ident,
4283                                   xref_tag (RECORD_TYPE, underlying_class)));
4284 #ifdef OBJCPLUS
4285       pop_lang_context ();
4286 #endif
4287       hash_class_name_enter (als_name_hash_list, alias_ident, 
4288                              underlying_class);
4289     }
4290 }
4291
4292 void
4293 objc_declare_class (tree ident_list)
4294 {
4295   tree list;
4296 #ifdef OBJCPLUS
4297   if (current_namespace != global_namespace) {
4298     error ("Objective-C declarations may only appear in global scope");
4299   }
4300 #endif /* OBJCPLUS */
4301
4302   for (list = ident_list; list; list = TREE_CHAIN (list))
4303     {
4304       tree ident = TREE_VALUE (list);
4305
4306       if (! objc_is_class_name (ident))
4307         {
4308           tree record = lookup_name (ident), type = record;
4309
4310           if (record)
4311             {
4312               if (TREE_CODE (record) == TYPE_DECL)
4313                 type = DECL_ORIGINAL_TYPE (record) ? 
4314                         DECL_ORIGINAL_TYPE (record) : 
4315                         TREE_TYPE (record);
4316
4317               if (!TYPE_HAS_OBJC_INFO (type)
4318                   || !TYPE_OBJC_INTERFACE (type))
4319                 {
4320                   error ("%qE redeclared as different kind of symbol",
4321                          ident);
4322                   error ("previous declaration of %q+D",
4323                          record);
4324                 }
4325             }
4326
4327           record = xref_tag (RECORD_TYPE, ident);
4328           INIT_TYPE_OBJC_INFO (record);
4329           TYPE_OBJC_INTERFACE (record) = ident;
4330           hash_class_name_enter (cls_name_hash_list, ident, NULL_TREE);
4331         }
4332     }
4333 }
4334
4335 tree
4336 objc_is_class_name (tree ident)
4337 {
4338   hash target;
4339
4340   if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
4341       && identifier_global_value (ident))
4342     ident = identifier_global_value (ident);
4343   while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
4344     ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
4345
4346   if (ident && TREE_CODE (ident) == RECORD_TYPE)
4347     ident = OBJC_TYPE_NAME (ident);
4348 #ifdef OBJCPLUS
4349   if (ident && TREE_CODE (ident) == TYPE_DECL)
4350     {
4351       tree type = TREE_TYPE (ident);
4352       if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
4353         return NULL_TREE;
4354       ident = DECL_NAME (ident);
4355     }
4356 #endif
4357   if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
4358     return NULL_TREE;
4359
4360   if (lookup_interface (ident))
4361     return ident;
4362
4363   target = hash_class_name_lookup (cls_name_hash_list, ident);
4364   if (target)
4365     return target->key;
4366
4367   target = hash_class_name_lookup (als_name_hash_list, ident);
4368   if (target)
4369     {
4370       gcc_assert (target->list && target->list->value);
4371       return target->list->value;
4372     }
4373
4374   return 0;
4375 }
4376
4377 /* Check whether TYPE is either 'id' or 'Class'.  */
4378
4379 tree
4380 objc_is_id (tree type)
4381 {
4382   if (type && TREE_CODE (type) == IDENTIFIER_NODE
4383       && identifier_global_value (type))
4384     type = identifier_global_value (type);
4385
4386   if (type && TREE_CODE (type) == TYPE_DECL)
4387     type = TREE_TYPE (type);
4388
4389   /* NB: This function may be called before the ObjC front-end has
4390      been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL.  */
4391   return (objc_object_type && type
4392           && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
4393           ? type
4394           : NULL_TREE);
4395 }
4396
4397 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
4398    class instance.  This is needed by other parts of the compiler to
4399    handle ObjC types gracefully.  */
4400
4401 tree
4402 objc_is_object_ptr (tree type)
4403 {
4404   tree ret;
4405
4406   type = TYPE_MAIN_VARIANT (type);
4407   if (!POINTER_TYPE_P (type))
4408     return 0;
4409
4410   ret = objc_is_id (type);
4411   if (!ret)
4412     ret = objc_is_class_name (TREE_TYPE (type));
4413
4414   return ret;
4415 }
4416
4417 static int
4418 objc_is_gcable_type (tree type, int or_strong_p)
4419 {
4420   tree name;
4421
4422   if (!TYPE_P (type))
4423     return 0;
4424   if (objc_is_id (TYPE_MAIN_VARIANT (type)))
4425     return 1;
4426   if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
4427     return 1;
4428   if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
4429     return 0;
4430   type = TREE_TYPE (type);
4431   if (TREE_CODE (type) != RECORD_TYPE)
4432     return 0;
4433   name = TYPE_NAME (type);
4434   return (objc_is_class_name (name) != NULL_TREE);
4435 }
4436
4437 static tree
4438 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
4439 {
4440   if (expr == oldexpr)
4441     return newexpr;
4442
4443   switch (TREE_CODE (expr))
4444     {
4445     case COMPONENT_REF:
4446       return objc_build_component_ref
4447              (objc_substitute_decl (TREE_OPERAND (expr, 0),
4448                                     oldexpr,
4449                                     newexpr),
4450               DECL_NAME (TREE_OPERAND (expr, 1)));
4451     case ARRAY_REF:
4452       return build_array_ref (input_location,
4453                               objc_substitute_decl (TREE_OPERAND (expr, 0),
4454                                                     oldexpr,
4455                                                     newexpr),
4456                               TREE_OPERAND (expr, 1));
4457     case INDIRECT_REF:
4458       return build_indirect_ref (input_location,
4459                                  objc_substitute_decl (TREE_OPERAND (expr, 0),
4460                                                        oldexpr,
4461                                                        newexpr), RO_ARROW);
4462     default:
4463       return expr;
4464     }
4465 }
4466
4467 static tree
4468 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
4469 {
4470   tree func_params;
4471   /* The LHS parameter contains the expression 'outervar->memberspec';
4472      we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
4473      where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
4474   */
4475   tree offs
4476     = objc_substitute_decl
4477       (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
4478   tree func
4479     = (flag_objc_direct_dispatch
4480        ? objc_assign_ivar_fast_decl
4481        : objc_assign_ivar_decl);
4482
4483   offs = convert (integer_type_node, build_unary_op (input_location,
4484                                                      ADDR_EXPR, offs, 0));
4485   offs = fold (offs);
4486   func_params = tree_cons (NULL_TREE,
4487         convert (objc_object_type, rhs),
4488             tree_cons (NULL_TREE, convert (objc_object_type, outervar),
4489                 tree_cons (NULL_TREE, offs,
4490                     NULL_TREE)));
4491
4492   assemble_external (func);
4493   return build_function_call (input_location, func, func_params);
4494 }
4495
4496 static tree
4497 objc_build_global_assignment (tree lhs, tree rhs)
4498 {
4499   tree func_params = tree_cons (NULL_TREE,
4500         convert (objc_object_type, rhs),
4501             tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
4502                       build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
4503                     NULL_TREE));
4504
4505   assemble_external (objc_assign_global_decl);
4506   return build_function_call (input_location, 
4507                               objc_assign_global_decl, func_params);
4508 }
4509
4510 static tree
4511 objc_build_strong_cast_assignment (tree lhs, tree rhs)
4512 {
4513   tree func_params = tree_cons (NULL_TREE,
4514         convert (objc_object_type, rhs),
4515             tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
4516                       build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
4517                     NULL_TREE));
4518
4519   assemble_external (objc_assign_strong_cast_decl);
4520   return build_function_call (input_location,
4521                               objc_assign_strong_cast_decl, func_params);
4522 }
4523
4524 static int
4525 objc_is_gcable_p (tree expr)
4526 {
4527   return (TREE_CODE (expr) == COMPONENT_REF
4528           ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
4529           : TREE_CODE (expr) == ARRAY_REF
4530           ? (objc_is_gcable_p (TREE_TYPE (expr))
4531              || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
4532           : TREE_CODE (expr) == ARRAY_TYPE
4533           ? objc_is_gcable_p (TREE_TYPE (expr))
4534           : TYPE_P (expr)
4535           ? objc_is_gcable_type (expr, 1)
4536           : (objc_is_gcable_p (TREE_TYPE (expr))
4537              || (DECL_P (expr)
4538                  && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
4539 }
4540
4541 static int
4542 objc_is_ivar_reference_p (tree expr)
4543 {
4544   return (TREE_CODE (expr) == ARRAY_REF
4545           ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
4546           : TREE_CODE (expr) == COMPONENT_REF
4547           ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
4548           : 0);
4549 }
4550
4551 static int
4552 objc_is_global_reference_p (tree expr)
4553 {
4554   return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
4555           ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
4556           : DECL_P (expr)
4557           ? (DECL_FILE_SCOPE_P (expr) || TREE_STATIC (expr))
4558           : 0);
4559 }
4560
4561 tree
4562 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
4563 {
4564   tree result = NULL_TREE, outer;
4565   int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
4566
4567   /* See if we have any lhs casts, and strip them out.  NB: The lvalue casts
4568      will have been transformed to the form '*(type *)&expr'.  */
4569   if (TREE_CODE (lhs) == INDIRECT_REF)
4570     {
4571       outer = TREE_OPERAND (lhs, 0);
4572
4573       while (!strong_cast_p
4574              && (CONVERT_EXPR_P (outer)
4575                  || TREE_CODE (outer) == NON_LVALUE_EXPR))
4576         {
4577           tree lhstype = TREE_TYPE (outer);
4578
4579           /* Descend down the cast chain, and record the first objc_gc
4580              attribute found.  */
4581           if (POINTER_TYPE_P (lhstype))
4582             {
4583               tree attr
4584                 = lookup_attribute ("objc_gc",
4585                                     TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
4586
4587               if (attr)
4588                 strong_cast_p = 1;
4589             }
4590
4591           outer = TREE_OPERAND (outer, 0);
4592         }
4593     }
4594
4595   /* If we have a __strong cast, it trumps all else.  */
4596   if (strong_cast_p)
4597     {
4598       if (modifycode != NOP_EXPR)
4599         goto invalid_pointer_arithmetic;
4600
4601       if (warn_assign_intercept)
4602         warning (0, "strong-cast assignment has been intercepted");
4603
4604       result = objc_build_strong_cast_assignment (lhs, rhs);
4605
4606       goto exit_point;
4607     }
4608
4609   /* the lhs must be of a suitable type, regardless of its underlying
4610      structure.  */
4611   if (!objc_is_gcable_p (lhs))
4612     goto exit_point;
4613
4614   outer = lhs;
4615
4616   while (outer
4617          && (TREE_CODE (outer) == COMPONENT_REF
4618              || TREE_CODE (outer) == ARRAY_REF))
4619     outer = TREE_OPERAND (outer, 0);
4620
4621   if (TREE_CODE (outer) == INDIRECT_REF)
4622     {
4623       outer = TREE_OPERAND (outer, 0);
4624       indirect_p = 1;
4625     }
4626
4627   outer_gc_p = objc_is_gcable_p (outer);
4628
4629   /* Handle ivar assignments. */
4630   if (objc_is_ivar_reference_p (lhs))
4631     {
4632       /* if the struct to the left of the ivar is not an Objective-C object (__strong
4633          doesn't cut it here), the best we can do here is suggest a cast.  */
4634       if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
4635         {
4636           /* We may still be able to use the global write barrier... */
4637           if (!indirect_p && objc_is_global_reference_p (outer))
4638             goto global_reference;
4639
4640          suggest_cast:
4641           if (modifycode == NOP_EXPR)
4642             {
4643               if (warn_assign_intercept)
4644                 warning (0, "strong-cast may possibly be needed");
4645             }
4646
4647           goto exit_point;
4648         }
4649
4650       if (modifycode != NOP_EXPR)
4651         goto invalid_pointer_arithmetic;
4652
4653       if (warn_assign_intercept)
4654         warning (0, "instance variable assignment has been intercepted");
4655
4656       result = objc_build_ivar_assignment (outer, lhs, rhs);
4657
4658       goto exit_point;
4659     }
4660
4661   /* Likewise, intercept assignment to global/static variables if their type is
4662      GC-marked.  */
4663   if (objc_is_global_reference_p (outer))
4664     {
4665       if (indirect_p)
4666         goto suggest_cast;
4667
4668      global_reference:
4669       if (modifycode != NOP_EXPR)
4670         {
4671          invalid_pointer_arithmetic:
4672           if (outer_gc_p)
4673             warning (0, "pointer arithmetic for garbage-collected objects not allowed");
4674
4675           goto exit_point;
4676         }
4677
4678       if (warn_assign_intercept)
4679         warning (0, "global/static variable assignment has been intercepted");
4680
4681       result = objc_build_global_assignment (lhs, rhs);
4682     }
4683
4684   /* In all other cases, fall back to the normal mechanism.  */
4685  exit_point:
4686   return result;
4687 }
4688
4689 struct GTY(()) interface_tuple {
4690   tree id;
4691   tree class_name;
4692 };
4693
4694 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
4695
4696 static hashval_t
4697 hash_interface (const void *p)
4698 {
4699   const struct interface_tuple *d = (const struct interface_tuple *) p;
4700   return IDENTIFIER_HASH_VALUE (d->id);
4701 }
4702
4703 static int
4704 eq_interface (const void *p1, const void *p2)
4705 {
4706   const struct interface_tuple *d = (const struct interface_tuple *) p1;
4707   return d->id == p2;
4708 }
4709
4710 static tree
4711 lookup_interface (tree ident)
4712 {
4713 #ifdef OBJCPLUS
4714   if (ident && TREE_CODE (ident) == TYPE_DECL)
4715     ident = DECL_NAME (ident);
4716 #endif
4717
4718   if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
4719     return NULL_TREE;
4720
4721   {
4722     struct interface_tuple **slot;
4723     tree i = NULL_TREE;
4724
4725     if (interface_htab)
4726       {
4727         slot = (struct interface_tuple **)
4728           htab_find_slot_with_hash (interface_htab, ident,
4729                                     IDENTIFIER_HASH_VALUE (ident),
4730                                     NO_INSERT);
4731         if (slot && *slot)
4732           i = (*slot)->class_name;
4733       }
4734     return i;
4735   }
4736 }
4737
4738 /* Implement @defs (<classname>) within struct bodies.  */
4739
4740 tree
4741 objc_get_class_ivars (tree class_name)
4742 {
4743   tree interface = lookup_interface (class_name);
4744
4745   if (interface)
4746     return get_class_ivars (interface, true);
4747
4748   error ("cannot find interface declaration for %qE",
4749          class_name);
4750
4751   return error_mark_node;
4752 }
4753
4754 /* Called when checking the variables in a struct.  If we are not
4755    doing the ivars list inside an @interface context, then returns
4756    fieldlist unchanged.  Else, returns the list of class ivars.
4757 */
4758 tree
4759 objc_get_interface_ivars (tree fieldlist)
4760 {
4761   if (!objc_collecting_ivars || !objc_interface_context 
4762       || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE
4763       || CLASS_SUPER_NAME (objc_interface_context) == NULL_TREE)
4764     return fieldlist;
4765
4766   return get_class_ivars (objc_interface_context, true);
4767 }
4768
4769 /* Used by: build_private_template, continue_class,
4770    and for @defs constructs.  */
4771
4772 static tree
4773 get_class_ivars (tree interface, bool inherited)
4774 {
4775   tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
4776
4777   /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
4778      by the current class (i.e., they do not include super-class ivars).
4779      However, the CLASS_IVARS list will be side-effected by a call to
4780      finish_struct(), which will fill in field offsets.  */
4781   if (!CLASS_IVARS (interface))
4782     CLASS_IVARS (interface) = ivar_chain;
4783
4784   if (!inherited)
4785     return ivar_chain;
4786
4787   while (CLASS_SUPER_NAME (interface))
4788     {
4789       /* Prepend super-class ivars.  */
4790       interface = lookup_interface (CLASS_SUPER_NAME (interface));
4791       ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
4792                             ivar_chain);
4793     }
4794
4795   return ivar_chain;
4796 }
4797
4798 \f
4799 /* Exception handling constructs.  We begin by having the parser do most
4800    of the work and passing us blocks.  What we do next depends on whether
4801    we're doing "native" exception handling or legacy Darwin setjmp exceptions.
4802    We abstract all of this in a handful of appropriately named routines.  */
4803
4804 /* Stack of open try blocks.  */
4805
4806 struct objc_try_context
4807 {
4808   struct objc_try_context *outer;
4809
4810   /* Statements (or statement lists) as processed by the parser.  */
4811   tree try_body;
4812   tree finally_body;
4813
4814   /* Some file position locations.  */
4815   location_t try_locus;
4816   location_t end_try_locus;
4817   location_t end_catch_locus;
4818   location_t finally_locus;
4819   location_t end_finally_locus;
4820
4821   /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
4822      of a TRY_CATCH_EXPR.  Even when doing Darwin setjmp.  */
4823   tree catch_list;
4824
4825   /* The CATCH_EXPR of an open @catch clause.  */
4826   tree current_catch;
4827
4828   /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer.  */
4829   tree caught_decl;
4830   tree stack_decl;
4831   tree rethrow_decl;
4832 };
4833
4834 static struct objc_try_context *cur_try_context;
4835
4836 static GTY(()) tree objc_eh_personality_decl;
4837
4838 /* This hook, called via lang_eh_runtime_type, generates a runtime object
4839    that represents TYPE.  For Objective-C, this is just the class name.  */
4840 /* ??? Isn't there a class object or some such?  Is it easy to get?  */
4841
4842 #ifndef OBJCPLUS
4843 tree
4844 objc_eh_runtime_type (tree type)
4845 {
4846   return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
4847 }
4848
4849 tree
4850 objc_eh_personality (void)
4851 {
4852   if (!flag_objc_sjlj_exceptions && !objc_eh_personality_decl)
4853     objc_eh_personality_decl = build_personality_function ("gnu_objc");
4854   return objc_eh_personality_decl;
4855 }
4856 #endif
4857
4858 /* Build __builtin_eh_pointer, or the moral equivalent.  In the case
4859    of Darwin, we'll arrange for it to be initialized (and associated
4860    with a binding) later.  */
4861
4862 static tree
4863 objc_build_exc_ptr (void)
4864 {
4865   if (flag_objc_sjlj_exceptions)
4866     {
4867       tree var = cur_try_context->caught_decl;
4868       if (!var)
4869         {
4870           var = objc_create_temporary_var (objc_object_type, NULL);
4871           cur_try_context->caught_decl = var;
4872         }
4873       return var;
4874     }
4875   else
4876     {
4877       tree t;
4878       t = built_in_decls[BUILT_IN_EH_POINTER];
4879       t = build_call_expr (t, 1, integer_zero_node);
4880       return fold_convert (objc_object_type, t);
4881     }
4882 }
4883
4884 /* Build "objc_exception_try_exit(&_stack)".  */
4885
4886 static tree
4887 next_sjlj_build_try_exit (void)
4888 {
4889   tree t;
4890   t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4891   t = tree_cons (NULL, t, NULL);
4892   t = build_function_call (input_location,
4893                            objc_exception_try_exit_decl, t);
4894   return t;
4895 }
4896
4897 /* Build
4898         objc_exception_try_enter (&_stack);
4899         if (_setjmp(&_stack.buf))
4900           ;
4901         else
4902           ;
4903    Return the COND_EXPR.  Note that the THEN and ELSE fields are left
4904    empty, ready for the caller to fill them in.  */
4905
4906 static tree
4907 next_sjlj_build_enter_and_setjmp (void)
4908 {
4909   tree t, enter, sj, cond;
4910
4911   t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4912   t = tree_cons (NULL, t, NULL);
4913   enter = build_function_call (input_location,
4914                                objc_exception_try_enter_decl, t);
4915
4916   t = objc_build_component_ref (cur_try_context->stack_decl,
4917                                 get_identifier ("buf"));
4918   t = build_fold_addr_expr_loc (input_location, t);
4919 #ifdef OBJCPLUS
4920   /* Convert _setjmp argument to type that is expected.  */
4921   if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
4922     t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
4923   else
4924     t = convert (ptr_type_node, t);
4925 #else
4926   t = convert (ptr_type_node, t);
4927 #endif
4928   t = tree_cons (NULL, t, NULL);
4929   sj = build_function_call (input_location,
4930                             objc_setjmp_decl, t);
4931
4932   cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
4933   cond = c_common_truthvalue_conversion (input_location, cond);
4934
4935   return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
4936 }
4937
4938 /* Build:
4939
4940    DECL = objc_exception_extract(&_stack);  */
4941
4942 static tree
4943 next_sjlj_build_exc_extract (tree decl)
4944 {
4945   tree t;
4946
4947   t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4948   t = tree_cons (NULL, t, NULL);
4949   t = build_function_call (input_location,
4950                            objc_exception_extract_decl, t);
4951   t = convert (TREE_TYPE (decl), t);
4952   t = build2 (MODIFY_EXPR, void_type_node, decl, t);
4953
4954   return t;
4955 }
4956
4957 /* Build
4958         if (objc_exception_match(obj_get_class(TYPE), _caught)
4959           BODY
4960         else if (...)
4961           ...
4962         else
4963           {
4964             _rethrow = _caught;
4965             objc_exception_try_exit(&_stack);
4966           }
4967    from the sequence of CATCH_EXPRs in the current try context.  */
4968
4969 static tree
4970 next_sjlj_build_catch_list (void)
4971 {
4972   tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
4973   tree catch_seq, t;
4974   tree *last = &catch_seq;
4975   bool saw_id = false;
4976
4977   for (; !tsi_end_p (i); tsi_next (&i))
4978     {
4979       tree stmt = tsi_stmt (i);
4980       tree type = CATCH_TYPES (stmt);
4981       tree body = CATCH_BODY (stmt);
4982
4983       if (type == NULL)
4984         {
4985           *last = body;
4986           saw_id = true;
4987           break;
4988         }
4989       else
4990         {
4991           tree args, cond;
4992
4993           if (type == error_mark_node)
4994             cond = error_mark_node;
4995           else
4996             {
4997               args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
4998               t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
4999               args = tree_cons (NULL, t, args);
5000               t = build_function_call (input_location,
5001                                        objc_exception_match_decl, args);
5002               cond = c_common_truthvalue_conversion (input_location, t);
5003             }
5004           t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
5005           SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
5006
5007           *last = t;
5008           last = &COND_EXPR_ELSE (t);
5009         }
5010     }
5011
5012   if (!saw_id)
5013     {
5014       t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
5015                   cur_try_context->caught_decl);
5016       SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
5017       append_to_statement_list (t, last);
5018
5019       t = next_sjlj_build_try_exit ();
5020       SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
5021       append_to_statement_list (t, last);
5022     }
5023
5024   return catch_seq;
5025 }
5026
5027 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
5028    exception handling.  We aim to build:
5029
5030         {
5031           struct _objc_exception_data _stack;
5032           id _rethrow = 0;
5033           try
5034             {
5035               objc_exception_try_enter (&_stack);
5036               if (_setjmp(&_stack.buf))
5037                 {
5038                   id _caught = objc_exception_extract(&_stack);
5039                   objc_exception_try_enter (&_stack);
5040                   if (_setjmp(&_stack.buf))
5041                     _rethrow = objc_exception_extract(&_stack);
5042                   else
5043                     CATCH-LIST
5044                 }
5045               else
5046                 TRY-BLOCK
5047             }
5048           finally
5049             {
5050               if (!_rethrow)
5051                 objc_exception_try_exit(&_stack);
5052               FINALLY-BLOCK
5053               if (_rethrow)
5054                 objc_exception_throw(_rethrow);
5055             }
5056         }
5057
5058    If CATCH-LIST is empty, we can omit all of the block containing
5059    "_caught" except for the setting of _rethrow.  Note the use of
5060    a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
5061    but handles goto and other exits from the block.  */
5062
5063 static tree
5064 next_sjlj_build_try_catch_finally (void)
5065 {
5066   tree rethrow_decl, stack_decl, t;
5067   tree catch_seq, try_fin, bind;
5068
5069   /* Create the declarations involved.  */
5070   t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
5071   stack_decl = objc_create_temporary_var (t, NULL);
5072   cur_try_context->stack_decl = stack_decl;
5073
5074   rethrow_decl = objc_create_temporary_var (objc_object_type, NULL);
5075   cur_try_context->rethrow_decl = rethrow_decl;
5076   TREE_CHAIN (rethrow_decl) = stack_decl;
5077
5078   /* Build the outermost variable binding level.  */
5079   bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
5080   SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
5081   TREE_SIDE_EFFECTS (bind) = 1;
5082
5083   /* Initialize rethrow_decl.  */
5084   t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
5085               convert (objc_object_type, null_pointer_node));
5086   SET_EXPR_LOCATION (t, cur_try_context->try_locus);
5087   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
5088
5089   /* Build the outermost TRY_FINALLY_EXPR.  */
5090   try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
5091   SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
5092   TREE_SIDE_EFFECTS (try_fin) = 1;
5093   append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
5094
5095   /* Create the complete catch sequence.  */
5096   if (cur_try_context->catch_list)
5097     {
5098       tree caught_decl = objc_build_exc_ptr ();
5099       catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
5100       TREE_SIDE_EFFECTS (catch_seq) = 1;
5101
5102       t = next_sjlj_build_exc_extract (caught_decl);
5103       append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
5104
5105       t = next_sjlj_build_enter_and_setjmp ();
5106       COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
5107       COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
5108       append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
5109     }
5110   else
5111     catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
5112   SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
5113
5114   /* Build the main register-and-try if statement.  */
5115   t = next_sjlj_build_enter_and_setjmp ();
5116   SET_EXPR_LOCATION (t, cur_try_context->try_locus);
5117   COND_EXPR_THEN (t) = catch_seq;
5118   COND_EXPR_ELSE (t) = cur_try_context->try_body;
5119   TREE_OPERAND (try_fin, 0) = t;
5120
5121   /* Build the complete FINALLY statement list.  */
5122   t = next_sjlj_build_try_exit ();
5123   t = build_stmt (input_location, COND_EXPR,
5124                   c_common_truthvalue_conversion 
5125                     (input_location, rethrow_decl),
5126                   NULL, t);
5127   SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
5128   append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
5129
5130   append_to_statement_list (cur_try_context->finally_body,
5131                             &TREE_OPERAND (try_fin, 1));
5132
5133   t = tree_cons (NULL, rethrow_decl, NULL);
5134   t = build_function_call (input_location,
5135                            objc_exception_throw_decl, t);
5136   t = build_stmt (input_location, COND_EXPR,
5137                   c_common_truthvalue_conversion (input_location, 
5138                                                   rethrow_decl),
5139                   t, NULL);
5140   SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
5141   append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
5142
5143   return bind;
5144 }
5145
5146 /* Called just after parsing the @try and its associated BODY.  We now
5147    must prepare for the tricky bits -- handling the catches and finally.  */
5148
5149 void
5150 objc_begin_try_stmt (location_t try_locus, tree body)
5151 {
5152   struct objc_try_context *c = XCNEW (struct objc_try_context);
5153   c->outer = cur_try_context;
5154   c->try_body = body;
5155   c->try_locus = try_locus;
5156   c->end_try_locus = input_location;
5157   cur_try_context = c;
5158
5159   /* -fobjc-exceptions is required to enable Objective-C exceptions.
5160      For example, on Darwin, ObjC exceptions require a sufficiently
5161      recent version of the runtime, so the user must ask for them
5162      explicitly.  On other platforms, at the moment -fobjc-exceptions
5163      triggers -fexceptions which again is required for exceptions to
5164      work.
5165   */
5166   if (!flag_objc_exceptions)
5167     {
5168       error_at (try_locus, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
5169     }
5170
5171   if (flag_objc_sjlj_exceptions)
5172     objc_mark_locals_volatile (NULL);
5173 }
5174
5175 /* Called just after parsing "@catch (parm)".  Open a binding level,
5176    enter DECL into the binding level, and initialize it.  Leave the
5177    binding level open while the body of the compound statement is parsed.  */
5178
5179 void
5180 objc_begin_catch_clause (tree decl)
5181 {
5182   tree compound, type, t;
5183
5184   /* Begin a new scope that the entire catch clause will live in.  */
5185   compound = c_begin_compound_stmt (true);
5186
5187   /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL.  */
5188   decl = build_decl (input_location,
5189                      VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
5190   lang_hooks.decls.pushdecl (decl);
5191
5192   /* Since a decl is required here by syntax, don't warn if its unused.  */
5193   /* ??? As opposed to __attribute__((unused))?  Anyway, this appears to
5194      be what the previous objc implementation did.  */
5195   TREE_USED (decl) = 1;
5196   DECL_READ_P (decl) = 1;
5197
5198   /* Verify that the type of the catch is valid.  It must be a pointer
5199      to an Objective-C class, or "id" (which is catch-all).  */
5200   type = TREE_TYPE (decl);
5201
5202   if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
5203     type = NULL;
5204   else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
5205     {
5206       error ("@catch parameter is not a known Objective-C class type");
5207       type = error_mark_node;
5208     }
5209   else if (cur_try_context->catch_list)
5210     {
5211       /* Examine previous @catch clauses and see if we've already
5212          caught the type in question.  */
5213       tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
5214       for (; !tsi_end_p (i); tsi_next (&i))
5215         {
5216           tree stmt = tsi_stmt (i);
5217           t = CATCH_TYPES (stmt);
5218           if (t == error_mark_node)
5219             continue;
5220           if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
5221             {
5222               warning (0, "exception of type %<%T%> will be caught",
5223                        TREE_TYPE (type));
5224               warning_at  (EXPR_LOCATION (stmt), 0, "   by earlier handler for %<%T%>",
5225                            TREE_TYPE (t ? t : objc_object_type));
5226               break;
5227             }
5228         }
5229     }
5230
5231   /* Record the data for the catch in the try context so that we can
5232      finalize it later.  */
5233   t = build_stmt (input_location, CATCH_EXPR, type, compound);
5234   cur_try_context->current_catch = t;
5235
5236   /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime.  */
5237   t = objc_build_exc_ptr ();
5238   t = convert (TREE_TYPE (decl), t);
5239   t = build2 (MODIFY_EXPR, void_type_node, decl, t);
5240   add_stmt (t);
5241 }
5242
5243 /* Called just after parsing the closing brace of a @catch clause.  Close
5244    the open binding level, and record a CATCH_EXPR for it.  */
5245
5246 void
5247 objc_finish_catch_clause (void)
5248 {
5249   tree c = cur_try_context->current_catch;
5250   cur_try_context->current_catch = NULL;
5251   cur_try_context->end_catch_locus = input_location;
5252
5253   CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
5254   append_to_statement_list (c, &cur_try_context->catch_list);
5255 }
5256
5257 /* Called after parsing a @finally clause and its associated BODY.
5258    Record the body for later placement.  */
5259
5260 void
5261 objc_build_finally_clause (location_t finally_locus, tree body)
5262 {
5263   cur_try_context->finally_body = body;
5264   cur_try_context->finally_locus = finally_locus;
5265   cur_try_context->end_finally_locus = input_location;
5266 }
5267
5268 /* Called to finalize a @try construct.  */
5269
5270 tree
5271 objc_finish_try_stmt (void)
5272 {
5273   struct objc_try_context *c = cur_try_context;
5274   tree stmt;
5275
5276   if (c->catch_list == NULL && c->finally_body == NULL)
5277     error ("%<@try%> without %<@catch%> or %<@finally%>");
5278
5279   /* If we're doing Darwin setjmp exceptions, build the big nasty.  */
5280   if (flag_objc_sjlj_exceptions)
5281     {
5282       bool save = in_late_binary_op;
5283       in_late_binary_op = true;
5284       if (!cur_try_context->finally_body)
5285         {
5286           cur_try_context->finally_locus = input_location;
5287           cur_try_context->end_finally_locus = input_location;
5288         }
5289       stmt = next_sjlj_build_try_catch_finally ();
5290       in_late_binary_op = save;
5291     }
5292   else
5293     {
5294       /* Otherwise, nest the CATCH inside a FINALLY.  */
5295       stmt = c->try_body;
5296       if (c->catch_list)
5297         {
5298           stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
5299           SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
5300         }
5301       if (c->finally_body)
5302         {
5303           stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
5304           SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
5305         }
5306     }
5307   add_stmt (stmt);
5308
5309   cur_try_context = c->outer;
5310   free (c);
5311   return stmt;
5312 }
5313
5314 tree
5315 objc_build_throw_stmt (location_t loc, tree throw_expr)
5316 {
5317   tree args;
5318
5319   if (!flag_objc_exceptions)
5320     {
5321       error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
5322     }
5323
5324   if (throw_expr == NULL)
5325     {
5326       /* If we're not inside a @catch block, there is no "current
5327          exception" to be rethrown.  */
5328       if (cur_try_context == NULL
5329           || cur_try_context->current_catch == NULL)
5330         {
5331           error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
5332           return NULL_TREE;
5333         }
5334
5335       /* Otherwise the object is still sitting in the EXC_PTR_EXPR
5336          value that we get from the runtime.  */
5337       throw_expr = objc_build_exc_ptr ();
5338     }
5339
5340   /* A throw is just a call to the runtime throw function with the
5341      object as a parameter.  */
5342   args = tree_cons (NULL, throw_expr, NULL);
5343   return add_stmt (build_function_call (loc,
5344                                         objc_exception_throw_decl, args));
5345 }
5346
5347 tree
5348 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
5349 {
5350   tree args, call;
5351
5352   /* First lock the mutex.  */
5353   mutex = save_expr (mutex);
5354   args = tree_cons (NULL, mutex, NULL);
5355   call = build_function_call (input_location,
5356                               objc_sync_enter_decl, args);
5357   SET_EXPR_LOCATION (call, start_locus);
5358   add_stmt (call);
5359
5360   /* Build the mutex unlock.  */
5361   args = tree_cons (NULL, mutex, NULL);
5362   call = build_function_call (input_location,
5363                               objc_sync_exit_decl, args);
5364   SET_EXPR_LOCATION (call, input_location);
5365
5366   /* Put the that and the body in a TRY_FINALLY.  */
5367   objc_begin_try_stmt (start_locus, body);
5368   objc_build_finally_clause (input_location, call);
5369   return objc_finish_try_stmt ();
5370 }
5371
5372 \f
5373 /* Predefine the following data type:
5374
5375    struct _objc_exception_data
5376    {
5377      int buf[OBJC_JBLEN];
5378      void *pointers[4];
5379    }; */
5380
5381 /* The following yuckiness should prevent users from having to #include
5382    <setjmp.h> in their code... */
5383
5384 /* Define to a harmless positive value so the below code doesn't die.  */
5385 #ifndef OBJC_JBLEN
5386 #define OBJC_JBLEN 18
5387 #endif
5388
5389 static void
5390 build_next_objc_exception_stuff (void)
5391 {
5392   tree decls, temp_type, *chain = NULL;
5393
5394   objc_exception_data_template
5395     = objc_start_struct (get_identifier (UTAG_EXCDATA));
5396
5397   /* int buf[OBJC_JBLEN]; */
5398
5399   temp_type = build_sized_array_type (integer_type_node, OBJC_JBLEN);
5400   decls = add_field_decl (temp_type, "buf", &chain);
5401
5402   /* void *pointers[4]; */
5403
5404   temp_type = build_sized_array_type (ptr_type_node, 4);
5405   add_field_decl (temp_type, "pointers", &chain);
5406
5407   objc_finish_struct (objc_exception_data_template, decls);
5408
5409   /* int _setjmp(...); */
5410   /* If the user includes <setjmp.h>, this shall be superseded by
5411      'int _setjmp(jmp_buf);' */
5412   temp_type = build_varargs_function_type_list (integer_type_node, NULL_TREE);
5413   objc_setjmp_decl
5414     = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
5415
5416   /* id objc_exception_extract(struct _objc_exception_data *); */
5417   temp_type
5418     = build_function_type_list (objc_object_type,
5419                                 build_pointer_type (objc_exception_data_template),
5420                                 NULL_TREE);
5421   objc_exception_extract_decl
5422     = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
5423                             NULL_TREE);
5424   /* void objc_exception_try_enter(struct _objc_exception_data *); */
5425   /* void objc_exception_try_exit(struct _objc_exception_data *); */
5426   temp_type
5427     = build_function_type_list (void_type_node,
5428                                 build_pointer_type (objc_exception_data_template),
5429                                 NULL_TREE);
5430   objc_exception_try_enter_decl
5431     = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
5432                             NULL_TREE);
5433   objc_exception_try_exit_decl
5434     = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
5435                             NULL_TREE);
5436
5437   /* int objc_exception_match(id, id); */
5438   temp_type
5439     = build_function_type_list (integer_type_node,
5440                                 objc_object_type, objc_object_type, NULL_TREE);
5441   objc_exception_match_decl
5442     = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
5443                             NULL_TREE);
5444
5445   /* id objc_assign_ivar (id, id, unsigned int); */
5446   /* id objc_assign_ivar_Fast (id, id, unsigned int)
5447        __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
5448   temp_type
5449     = build_function_type_list (objc_object_type,
5450                                 objc_object_type,
5451                                 objc_object_type,
5452                                 unsigned_type_node,
5453                                 NULL_TREE);
5454   objc_assign_ivar_decl
5455     = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
5456                             NULL, NULL_TREE);
5457 #ifdef OFFS_ASSIGNIVAR_FAST
5458   objc_assign_ivar_fast_decl
5459     = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
5460                             NOT_BUILT_IN, NULL, NULL_TREE);
5461   DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
5462     = tree_cons (get_identifier ("hard_coded_address"),
5463                  build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
5464                  NULL_TREE);
5465 #else
5466   /* Default to slower ivar method.  */
5467   objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
5468 #endif
5469
5470   /* id objc_assign_global (id, id *); */
5471   /* id objc_assign_strongCast (id, id *); */
5472   temp_type = build_function_type_list (objc_object_type,
5473                                         objc_object_type,
5474                                         build_pointer_type (objc_object_type),
5475                                         NULL_TREE);
5476   objc_assign_global_decl
5477         = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
5478                                 NULL_TREE);
5479   objc_assign_strong_cast_decl
5480         = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
5481                                 NULL_TREE);
5482 }
5483
5484 static void
5485 build_objc_exception_stuff (void)
5486 {
5487   tree noreturn_list, nothrow_list, temp_type;
5488
5489   noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
5490   nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
5491
5492   /* void objc_exception_throw(id) __attribute__((noreturn)); */
5493   /* void objc_sync_enter(id); */
5494   /* void objc_sync_exit(id); */
5495   temp_type = build_function_type_list (void_type_node,
5496                                         objc_object_type,
5497                                         NULL_TREE);
5498   objc_exception_throw_decl
5499     = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
5500                             noreturn_list);
5501   objc_sync_enter_decl
5502     = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
5503                             NULL, nothrow_list);
5504   objc_sync_exit_decl
5505     = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
5506                             NULL, nothrow_list);
5507 }
5508
5509 /* Construct a C struct corresponding to ObjC class CLASS, with the same
5510    name as the class:
5511
5512    struct <classname> {
5513      struct _objc_class *isa;
5514      ...
5515    };  */
5516
5517 static void
5518 build_private_template (tree klass)
5519 {
5520   if (!CLASS_STATIC_TEMPLATE (klass))
5521     {
5522       tree record = objc_build_struct (klass,
5523                                        get_class_ivars (klass, false),
5524                                        CLASS_SUPER_NAME (klass));
5525
5526       /* Set the TREE_USED bit for this struct, so that stab generator
5527          can emit stabs for this struct type.  */
5528       if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
5529         TREE_USED (TYPE_STUB_DECL (record)) = 1;
5530     }
5531 }
5532 \f
5533 /* Begin code generation for protocols...  */
5534
5535 /* struct _objc_protocol {
5536      struct _objc_class *isa;
5537      char *protocol_name;
5538      struct _objc_protocol **protocol_list;
5539      struct _objc__method_prototype_list *instance_methods;
5540      struct _objc__method_prototype_list *class_methods;
5541    };  */
5542
5543 static void
5544 build_protocol_template (void)
5545 {
5546   tree ptype, decls, *chain = NULL;
5547
5548   objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
5549
5550   /* struct _objc_class *isa; */
5551   ptype = build_pointer_type (xref_tag (RECORD_TYPE,
5552                                         get_identifier (UTAG_CLASS)));
5553   decls = add_field_decl (ptype, "isa", &chain);
5554
5555   /* char *protocol_name; */
5556   add_field_decl (string_type_node, "protocol_name", &chain);
5557
5558   /* struct _objc_protocol **protocol_list; */
5559   ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
5560   add_field_decl (ptype, "protocol_list", &chain);
5561
5562   /* struct _objc__method_prototype_list *instance_methods; */
5563   add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
5564
5565   /* struct _objc__method_prototype_list *class_methods; */
5566   add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
5567
5568   objc_finish_struct (objc_protocol_template, decls);
5569 }
5570
5571 static tree
5572 build_descriptor_table_initializer (tree type, tree entries)
5573 {
5574   VEC(constructor_elt,gc) *inits = NULL;
5575
5576   do
5577     {
5578       VEC(constructor_elt,gc) *elts = NULL;
5579
5580       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
5581                               build_selector (METHOD_SEL_NAME (entries)));
5582       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
5583                               add_objc_string (METHOD_ENCODING (entries),
5584                                                meth_var_types));
5585
5586       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5587                               objc_build_constructor (type, elts));
5588
5589       entries = DECL_CHAIN (entries);
5590     }
5591   while (entries);
5592
5593   return objc_build_constructor (build_array_type (type, 0), inits);
5594 }
5595
5596 /* struct objc_method_prototype_list {
5597      int count;
5598      struct objc_method_prototype {
5599         SEL name;
5600         char *types;
5601      } list[1];
5602    };  */
5603
5604 static tree
5605 build_method_prototype_list_template (tree list_type, int size)
5606 {
5607   tree objc_ivar_list_record;
5608   tree array_type, decls, *chain = NULL;
5609
5610   /* Generate an unnamed struct definition.  */
5611
5612   objc_ivar_list_record = objc_start_struct (NULL_TREE);
5613
5614   /* int method_count; */
5615   decls = add_field_decl (integer_type_node, "method_count", &chain);
5616
5617   /* struct objc_method method_list[]; */
5618   array_type = build_sized_array_type (list_type, size);
5619   add_field_decl (array_type, "method_list", &chain);
5620
5621   objc_finish_struct (objc_ivar_list_record, decls);
5622
5623   return objc_ivar_list_record;
5624 }
5625
5626 static tree
5627 build_method_prototype_template (void)
5628 {
5629   tree proto_record;
5630   tree decls, *chain = NULL;
5631
5632   proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
5633
5634   /* SEL _cmd; */
5635   decls = add_field_decl (objc_selector_type, "_cmd", &chain);
5636
5637   /* char *method_types; */
5638   add_field_decl (string_type_node, "method_types", &chain);
5639
5640   objc_finish_struct (proto_record, decls);
5641
5642   return proto_record;
5643 }
5644
5645 static tree
5646 objc_method_parm_type (tree type)
5647 {
5648   type = TREE_VALUE (TREE_TYPE (type));
5649   if (TREE_CODE (type) == TYPE_DECL)
5650     type = TREE_TYPE (type);
5651   return type;
5652 }
5653
5654 static int
5655 objc_encoded_type_size (tree type)
5656 {
5657   int sz = int_size_in_bytes (type);
5658
5659   /* Make all integer and enum types at least as large
5660      as an int.  */
5661   if (sz > 0 && INTEGRAL_TYPE_P (type))
5662     sz = MAX (sz, int_size_in_bytes (integer_type_node));
5663   /* Treat arrays as pointers, since that's how they're
5664      passed in.  */
5665   else if (TREE_CODE (type) == ARRAY_TYPE)
5666     sz = int_size_in_bytes (ptr_type_node);
5667   return sz;
5668 }
5669
5670 /* Encode a method prototype.
5671
5672    The format is described in gcc/doc/objc.texi, section 'Method
5673    signatures'.
5674  */
5675 static tree
5676 encode_method_prototype (tree method_decl)
5677 {
5678   tree parms;
5679   int parm_offset, i;
5680   char buf[40];
5681   tree result;
5682
5683   /* ONEWAY and BYCOPY, for remote object are the only method qualifiers.  */
5684   encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
5685
5686   /* Encode return type.  */
5687   encode_type (objc_method_parm_type (method_decl),
5688                obstack_object_size (&util_obstack),
5689                OBJC_ENCODE_INLINE_DEFS);
5690
5691   /* Stack size.  */
5692   /* The first two arguments (self and _cmd) are pointers; account for
5693      their size.  */
5694   i = int_size_in_bytes (ptr_type_node);
5695   parm_offset = 2 * i;
5696   for (parms = METHOD_SEL_ARGS (method_decl); parms;
5697        parms = DECL_CHAIN (parms))
5698     {
5699       tree type = objc_method_parm_type (parms);
5700       int sz = objc_encoded_type_size (type);
5701
5702       /* If a type size is not known, bail out.  */
5703       if (sz < 0)
5704         {
5705           error ("type %q+D does not have a known size",
5706                  type);
5707           /* Pretend that the encoding succeeded; the compilation will
5708              fail nevertheless.  */
5709           goto finish_encoding;
5710         }
5711       parm_offset += sz;
5712     }
5713
5714   sprintf (buf, "%d@0:%d", parm_offset, i);
5715   obstack_grow (&util_obstack, buf, strlen (buf));
5716
5717   /* Argument types.  */
5718   parm_offset = 2 * i;
5719   for (parms = METHOD_SEL_ARGS (method_decl); parms;
5720        parms = DECL_CHAIN (parms))
5721     {
5722       tree type = objc_method_parm_type (parms);
5723
5724       /* Process argument qualifiers for user supplied arguments.  */
5725       encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
5726
5727       /* Type.  */
5728       encode_type (type, obstack_object_size (&util_obstack),
5729                    OBJC_ENCODE_INLINE_DEFS);
5730
5731       /* Compute offset.  */
5732       sprintf (buf, "%d", parm_offset);
5733       parm_offset += objc_encoded_type_size (type);
5734
5735       obstack_grow (&util_obstack, buf, strlen (buf));
5736     }
5737
5738   finish_encoding:
5739   obstack_1grow (&util_obstack, '\0');
5740   result = get_identifier (XOBFINISH (&util_obstack, char *));
5741   obstack_free (&util_obstack, util_firstobj);
5742   return result;
5743 }
5744
5745 static tree
5746 generate_descriptor_table (tree type, const char *name, int size, tree list,
5747                            tree proto)
5748 {
5749   tree decl;
5750   VEC(constructor_elt,gc) *v = NULL;
5751
5752   decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
5753
5754   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
5755   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
5756
5757   finish_var_decl (decl, objc_build_constructor (type, v));
5758
5759   return decl;
5760 }
5761
5762 static void
5763 generate_method_descriptors (tree protocol)
5764 {
5765   tree initlist, chain, method_list_template;
5766   int size;
5767
5768   if (!objc_method_prototype_template)
5769     objc_method_prototype_template = build_method_prototype_template ();
5770
5771   chain = PROTOCOL_CLS_METHODS (protocol);
5772   if (chain)
5773     {
5774       size = list_length (chain);
5775
5776       method_list_template
5777         = build_method_prototype_list_template (objc_method_prototype_template,
5778                                                 size);
5779
5780       initlist
5781         = build_descriptor_table_initializer (objc_method_prototype_template,
5782                                               chain);
5783
5784       UOBJC_CLASS_METHODS_decl
5785         = generate_descriptor_table (method_list_template,
5786                                      "_OBJC_PROTOCOL_CLASS_METHODS",
5787                                      size, initlist, protocol);
5788     }
5789   else
5790     UOBJC_CLASS_METHODS_decl = 0;
5791
5792   chain = PROTOCOL_NST_METHODS (protocol);
5793   if (chain)
5794     {
5795       size = list_length (chain);
5796
5797       method_list_template
5798         = build_method_prototype_list_template (objc_method_prototype_template,
5799                                                 size);
5800       initlist
5801         = build_descriptor_table_initializer (objc_method_prototype_template,
5802                                               chain);
5803
5804       UOBJC_INSTANCE_METHODS_decl
5805         = generate_descriptor_table (method_list_template,
5806                                      "_OBJC_PROTOCOL_INSTANCE_METHODS",
5807                                      size, initlist, protocol);
5808     }
5809   else
5810     UOBJC_INSTANCE_METHODS_decl = 0;
5811 }
5812
5813 static void
5814 generate_protocol_references (tree plist)
5815 {
5816   tree lproto;
5817
5818   /* Forward declare protocols referenced.  */
5819   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5820     {
5821       tree proto = TREE_VALUE (lproto);
5822
5823       if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
5824           && PROTOCOL_NAME (proto))
5825         {
5826           if (! PROTOCOL_FORWARD_DECL (proto))
5827             build_protocol_reference (proto);
5828
5829           if (PROTOCOL_LIST (proto))
5830             generate_protocol_references (PROTOCOL_LIST (proto));
5831         }
5832     }
5833 }
5834
5835 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
5836    current class.  */
5837 #ifdef OBJCPLUS
5838 static void
5839 objc_generate_cxx_ctor_or_dtor (bool dtor)
5840 {
5841   tree fn, body, compound_stmt, ivar;
5842
5843   /* - (id) .cxx_construct { ... return self; } */
5844   /* - (void) .cxx_construct { ... }            */
5845
5846   objc_start_method_definition
5847     (false /* is_class_method */,
5848      objc_build_method_signature (false /* is_class_method */,
5849                                   build_tree_list (NULL_TREE,
5850                                                    dtor
5851                                                    ? void_type_node
5852                                                    : objc_object_type),
5853                                   get_identifier (dtor
5854                                                   ? TAG_CXX_DESTRUCT
5855                                                   : TAG_CXX_CONSTRUCT),
5856                                   make_node (TREE_LIST),
5857                                   false), NULL);
5858   body = begin_function_body ();
5859   compound_stmt = begin_compound_stmt (0);
5860
5861   ivar = CLASS_IVARS (implementation_template);
5862   /* Destroy ivars in reverse order.  */
5863   if (dtor)
5864     ivar = nreverse (copy_list (ivar));
5865
5866   for (; ivar; ivar = TREE_CHAIN (ivar))
5867     {
5868       if (TREE_CODE (ivar) == FIELD_DECL)
5869         {
5870           tree type = TREE_TYPE (ivar);
5871
5872           /* Call the ivar's default constructor or destructor.  Do not
5873              call the destructor unless a corresponding constructor call
5874              has also been made (or is not needed).  */
5875           if (MAYBE_CLASS_TYPE_P (type)
5876               && (dtor
5877                   ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5878                      && (!TYPE_NEEDS_CONSTRUCTING (type)
5879                          || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5880                   : (TYPE_NEEDS_CONSTRUCTING (type)
5881                      && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
5882             finish_expr_stmt
5883              (build_special_member_call
5884               (build_ivar_reference (DECL_NAME (ivar)),
5885                dtor ? complete_dtor_identifier : complete_ctor_identifier,
5886                NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
5887         }
5888     }
5889
5890   /* The constructor returns 'self'.  */
5891   if (!dtor)
5892     finish_return_stmt (self_decl);
5893
5894   finish_compound_stmt (compound_stmt);
5895   finish_function_body (body);
5896   fn = current_function_decl;
5897   finish_function ();
5898   objc_finish_method_definition (fn);
5899 }
5900
5901 /* The following routine will examine the current @interface for any
5902    non-POD C++ ivars requiring non-trivial construction and/or
5903    destruction, and then synthesize special '- .cxx_construct' and/or
5904    '- .cxx_destruct' methods which will run the appropriate
5905    construction or destruction code.  Note that ivars inherited from
5906    super-classes are _not_ considered.  */
5907 static void
5908 objc_generate_cxx_cdtors (void)
5909 {
5910   bool need_ctor = false, need_dtor = false;
5911   tree ivar;
5912
5913   /* Error case, due to possibly an extra @end. */
5914   if (!objc_implementation_context)
5915     return;
5916
5917   /* We do not want to do this for categories, since they do not have
5918      their own ivars.  */
5919
5920   if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
5921     return;
5922
5923   /* First, determine if we even need a constructor and/or destructor.  */
5924
5925   for (ivar = CLASS_IVARS (implementation_template); ivar;
5926        ivar = TREE_CHAIN (ivar))
5927     {
5928       if (TREE_CODE (ivar) == FIELD_DECL)
5929         {
5930           tree type = TREE_TYPE (ivar);
5931
5932           if (MAYBE_CLASS_TYPE_P (type))
5933             {
5934               if (TYPE_NEEDS_CONSTRUCTING (type)
5935                   && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
5936                 /* NB: If a default constructor is not available, we will not
5937                    be able to initialize this ivar; the add_instance_variable()
5938                    routine will already have warned about this.  */
5939                 need_ctor = true;
5940
5941               if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5942                   && (!TYPE_NEEDS_CONSTRUCTING (type)
5943                       || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5944                 /* NB: If a default constructor is not available, we will not
5945                    call the destructor either, for symmetry.  */
5946                 need_dtor = true;
5947             }
5948         }
5949     }
5950
5951   /* Generate '- .cxx_construct' if needed.  */
5952
5953   if (need_ctor)
5954     objc_generate_cxx_ctor_or_dtor (false);
5955
5956   /* Generate '- .cxx_destruct' if needed.  */
5957
5958   if (need_dtor)
5959     objc_generate_cxx_ctor_or_dtor (true);
5960
5961   /* The 'imp_list' variable points at an imp_entry record for the current
5962      @implementation.  Record the existence of '- .cxx_construct' and/or
5963      '- .cxx_destruct' methods therein; it will be included in the
5964      metadata for the class.  */
5965   if (flag_next_runtime)
5966     imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
5967 }
5968 #endif
5969
5970 /* For each protocol which was referenced either from a @protocol()
5971    expression, or because a class/category implements it (then a
5972    pointer to the protocol is stored in the struct describing the
5973    class/category), we create a statically allocated instance of the
5974    Protocol class.  The code is written in such a way as to generate
5975    as few Protocol objects as possible; we generate a unique Protocol
5976    instance for each protocol, and we don't generate a Protocol
5977    instance if the protocol is never referenced (either from a
5978    @protocol() or from a class/category implementation).  These
5979    statically allocated objects can be referred to via the static
5980    (that is, private to this module) symbols _OBJC_PROTOCOL_n.
5981
5982    The statically allocated Protocol objects that we generate here
5983    need to be fixed up at runtime in order to be used: the 'isa'
5984    pointer of the objects need to be set up to point to the 'Protocol'
5985    class, as known at runtime.
5986
5987    The NeXT runtime fixes up all protocols at program startup time,
5988    before main() is entered.  It uses a low-level trick to look up all
5989    those symbols, then loops on them and fixes them up.
5990
5991    The GNU runtime as well fixes up all protocols before user code
5992    from the module is executed; it requires pointers to those symbols
5993    to be put in the objc_symtab (which is then passed as argument to
5994    the function __objc_exec_class() which the compiler sets up to be
5995    executed automatically when the module is loaded); setup of those
5996    Protocol objects happen in two ways in the GNU runtime: all
5997    Protocol objects referred to by a class or category implementation
5998    are fixed up when the class/category is loaded; all Protocol
5999    objects referred to by a @protocol() expression are added by the
6000    compiler to the list of statically allocated instances to fixup
6001    (the same list holding the statically allocated constant string
6002    objects).  Because, as explained above, the compiler generates as
6003    few Protocol objects as possible, some Protocol object might end up
6004    being referenced multiple times when compiled with the GNU runtime,
6005    and end up being fixed up multiple times at runtime initialization.
6006    But that doesn't hurt, it's just a little inefficient.  */
6007
6008 static void
6009 generate_protocols (void)
6010 {
6011   tree p, encoding;
6012   tree decl;
6013   tree initlist, protocol_name_expr, refs_decl, refs_expr;
6014
6015   /* If a protocol was directly referenced, pull in indirect references.  */
6016   for (p = protocol_chain; p; p = TREE_CHAIN (p))
6017     if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
6018       generate_protocol_references (PROTOCOL_LIST (p));
6019
6020   for (p = protocol_chain; p; p = TREE_CHAIN (p))
6021     {
6022       tree nst_methods = PROTOCOL_NST_METHODS (p);
6023       tree cls_methods = PROTOCOL_CLS_METHODS (p);
6024
6025       /* If protocol wasn't referenced, don't generate any code.  */
6026       decl = PROTOCOL_FORWARD_DECL (p);
6027
6028       if (!decl)
6029         continue;
6030
6031       /* Make sure we link in the Protocol class.  */
6032       add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6033
6034       while (nst_methods)
6035         {
6036           if (! METHOD_ENCODING (nst_methods))
6037             {
6038               encoding = encode_method_prototype (nst_methods);
6039               METHOD_ENCODING (nst_methods) = encoding;
6040             }
6041           nst_methods = DECL_CHAIN (nst_methods);
6042         }
6043
6044       while (cls_methods)
6045         {
6046           if (! METHOD_ENCODING (cls_methods))
6047             {
6048               encoding = encode_method_prototype (cls_methods);
6049               METHOD_ENCODING (cls_methods) = encoding;
6050             }
6051
6052           cls_methods = DECL_CHAIN (cls_methods);
6053         }
6054       generate_method_descriptors (p);
6055
6056       if (PROTOCOL_LIST (p))
6057         refs_decl = generate_protocol_list (p);
6058       else
6059         refs_decl = 0;
6060
6061       /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
6062       protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
6063
6064       if (refs_decl)
6065         refs_expr = convert (build_pointer_type (build_pointer_type
6066                                                  (objc_protocol_template)),
6067                              build_unary_op (input_location,
6068                                              ADDR_EXPR, refs_decl, 0));
6069       else
6070         refs_expr = build_int_cst (NULL_TREE, 0);
6071
6072       /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
6073          by generate_method_descriptors, which is called above.  */
6074       initlist = build_protocol_initializer (TREE_TYPE (decl),
6075                                              protocol_name_expr, refs_expr,
6076                                              UOBJC_INSTANCE_METHODS_decl,
6077                                              UOBJC_CLASS_METHODS_decl);
6078       finish_var_decl (decl, initlist);
6079     }
6080 }
6081
6082 static tree
6083 build_protocol_initializer (tree type, tree protocol_name,
6084                             tree protocol_list, tree instance_methods,
6085                             tree class_methods)
6086 {
6087   tree expr;
6088   tree cast_type = build_pointer_type
6089                    (xref_tag (RECORD_TYPE,
6090                               get_identifier (UTAG_CLASS)));
6091   VEC(constructor_elt,gc) *inits = NULL;
6092
6093   /* Filling the "isa" in with one allows the runtime system to
6094      detect that the version change...should remove before final release.  */
6095
6096   expr = build_int_cst (cast_type, PROTOCOL_VERSION);
6097   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
6098   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
6099   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
6100
6101   if (!instance_methods)
6102     CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
6103   else
6104     {
6105       expr = convert (objc_method_proto_list_ptr,
6106                       build_unary_op (input_location, 
6107                                       ADDR_EXPR, instance_methods, 0));
6108       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
6109     }
6110
6111   if (!class_methods)
6112     CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
6113   else
6114     {
6115       expr = convert (objc_method_proto_list_ptr,
6116                       build_unary_op (input_location, 
6117                                       ADDR_EXPR, class_methods, 0));
6118       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
6119     }
6120
6121   return objc_build_constructor (type, inits);
6122 }
6123 \f
6124 /* struct _objc_category {
6125      char *category_name;
6126      char *class_name;
6127      struct _objc_method_list *instance_methods;
6128      struct _objc_method_list *class_methods;
6129      struct _objc_protocol_list *protocols;
6130    };   */
6131
6132 static void
6133 build_category_template (void)
6134 {
6135   tree ptype, decls, *chain = NULL;
6136
6137   objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
6138
6139   /* char *category_name; */
6140   decls = add_field_decl (string_type_node, "category_name", &chain);
6141
6142   /* char *class_name; */
6143   add_field_decl (string_type_node, "class_name", &chain);
6144
6145   /* struct _objc_method_list *instance_methods; */
6146   add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
6147
6148   /* struct _objc_method_list *class_methods; */
6149   add_field_decl (objc_method_list_ptr, "class_methods", &chain);
6150
6151   /* struct _objc_protocol **protocol_list; */
6152   ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
6153   add_field_decl (ptype, "protocol_list", &chain);
6154
6155   objc_finish_struct (objc_category_template, decls);
6156 }
6157
6158 /* struct _objc_selector {
6159      SEL sel_id;
6160      char *sel_type;
6161    }; */
6162
6163 static void
6164 build_selector_template (void)
6165 {
6166   tree decls, *chain = NULL;
6167
6168   objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
6169
6170   /* SEL sel_id; */
6171   decls = add_field_decl (objc_selector_type, "sel_id", &chain);
6172
6173   /* char *sel_type; */
6174   add_field_decl (string_type_node, "sel_type", &chain);
6175
6176   objc_finish_struct (objc_selector_template, decls);
6177 }
6178
6179 /* struct _objc_class {
6180      struct _objc_class *isa;
6181      struct _objc_class *super_class;
6182      char *name;
6183      long version;
6184      long info;
6185      long instance_size;
6186      struct _objc_ivar_list *ivars;
6187      struct _objc_method_list *methods;
6188      #ifdef __NEXT_RUNTIME__
6189        struct objc_cache *cache;
6190      #else
6191        struct sarray *dtable;
6192        struct _objc_class *subclass_list;
6193        struct _objc_class *sibling_class;
6194      #endif
6195      struct _objc_protocol_list *protocols;
6196      #ifdef __NEXT_RUNTIME__
6197        void *sel_id;
6198      #endif
6199      void *gc_object_type;
6200    };  */
6201
6202 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
6203    the NeXT/Apple runtime; still, the compiler must generate them to
6204    maintain backward binary compatibility (and to allow for future
6205    expansion).  */
6206
6207 static void
6208 build_class_template (void)
6209 {
6210   tree ptype, decls, *chain = NULL;
6211
6212   objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
6213
6214   /* struct _objc_class *isa; */
6215   decls = add_field_decl (build_pointer_type (objc_class_template),
6216                           "isa", &chain);
6217
6218   /* struct _objc_class *super_class; */
6219   add_field_decl (build_pointer_type (objc_class_template),
6220                   "super_class", &chain);
6221
6222   /* char *name; */
6223   add_field_decl (string_type_node, "name", &chain);
6224
6225   /* long version; */
6226   add_field_decl (long_integer_type_node, "version", &chain);
6227
6228   /* long info; */
6229   add_field_decl (long_integer_type_node, "info", &chain);
6230
6231   /* long instance_size; */
6232   add_field_decl (long_integer_type_node, "instance_size", &chain);
6233
6234   /* struct _objc_ivar_list *ivars; */
6235   add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
6236
6237   /* struct _objc_method_list *methods; */
6238   add_field_decl (objc_method_list_ptr, "methods", &chain);
6239
6240   if (flag_next_runtime)
6241     {
6242       /* struct objc_cache *cache; */
6243       ptype = build_pointer_type (xref_tag (RECORD_TYPE,
6244                                             get_identifier ("objc_cache")));
6245       add_field_decl (ptype, "cache", &chain);
6246     }
6247   else
6248     {
6249       /* struct sarray *dtable; */
6250       ptype = build_pointer_type(xref_tag (RECORD_TYPE,
6251                                            get_identifier ("sarray")));
6252       add_field_decl (ptype, "dtable", &chain);
6253
6254       /* struct objc_class *subclass_list; */
6255       ptype = build_pointer_type (objc_class_template);
6256       add_field_decl (ptype, "subclass_list", &chain);
6257
6258       /* struct objc_class *sibling_class; */
6259       ptype = build_pointer_type (objc_class_template);
6260       add_field_decl (ptype, "sibling_class", &chain);
6261     }
6262
6263   /* struct _objc_protocol **protocol_list; */
6264   ptype = build_pointer_type (build_pointer_type
6265                               (xref_tag (RECORD_TYPE,
6266                                          get_identifier (UTAG_PROTOCOL))));
6267   add_field_decl (ptype, "protocol_list", &chain);
6268
6269   if (flag_next_runtime)
6270     {
6271       /* void *sel_id; */
6272       add_field_decl (build_pointer_type (void_type_node), "sel_id", &chain);
6273     }
6274
6275   /* void *gc_object_type; */
6276   add_field_decl (build_pointer_type (void_type_node),
6277                   "gc_object_type", &chain);
6278
6279   objc_finish_struct (objc_class_template, decls);
6280 }
6281
6282 /* Generate appropriate forward declarations for an implementation.  */
6283
6284 static void
6285 synth_forward_declarations (void)
6286 {
6287   tree an_id;
6288
6289   /* static struct objc_class _OBJC_CLASS_<my_name>; */
6290   UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
6291                                           objc_class_template);
6292
6293   /* static struct objc_class _OBJC_METACLASS_<my_name>; */
6294   UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
6295                                                   objc_class_template);
6296
6297   /* Pre-build the following entities - for speed/convenience.  */
6298
6299   an_id = get_identifier ("super_class");
6300   ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
6301   uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
6302 }
6303
6304 static void
6305 error_with_ivar (const char *message, tree decl)
6306 {
6307   error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
6308             message, identifier_to_locale (gen_declaration (decl)));
6309
6310 }
6311
6312 static void
6313 check_ivars (tree inter, tree imp)
6314 {
6315   tree intdecls = CLASS_RAW_IVARS (inter);
6316   tree impdecls = CLASS_RAW_IVARS (imp);
6317
6318   while (1)
6319     {
6320       tree t1, t2;
6321
6322 #ifdef OBJCPLUS
6323       if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
6324         intdecls = TREE_CHAIN (intdecls);
6325 #endif
6326       if (intdecls == 0 && impdecls == 0)
6327         break;
6328       if (intdecls == 0 || impdecls == 0)
6329         {
6330           error ("inconsistent instance variable specification");
6331           break;
6332         }
6333
6334       t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
6335
6336       if (!comptypes (t1, t2)
6337           || !tree_int_cst_equal (DECL_INITIAL (intdecls),
6338                                   DECL_INITIAL (impdecls)))
6339         {
6340           if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
6341             {
6342               error_with_ivar ("conflicting instance variable type",
6343                                impdecls);
6344               error_with_ivar ("previous declaration of",
6345                                intdecls);
6346             }
6347           else                  /* both the type and the name don't match */
6348             {
6349               error ("inconsistent instance variable specification");
6350               break;
6351             }
6352         }
6353
6354       else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
6355         {
6356           error_with_ivar ("conflicting instance variable name",
6357                            impdecls);
6358           error_with_ivar ("previous declaration of",
6359                            intdecls);
6360         }
6361
6362       intdecls = DECL_CHAIN (intdecls);
6363       impdecls = DECL_CHAIN (impdecls);
6364     }
6365 }
6366
6367 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
6368    This needs to be done just once per compilation.  */
6369
6370 /* struct _objc_super {
6371      struct _objc_object *self;
6372      struct _objc_class *super_class;
6373    };  */
6374
6375 static void
6376 build_super_template (void)
6377 {
6378   tree decls, *chain = NULL;
6379
6380   objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
6381
6382   /* struct _objc_object *self; */
6383   decls = add_field_decl (objc_object_type, "self", &chain);
6384
6385   /* struct _objc_class *super_class; */
6386   add_field_decl (build_pointer_type (objc_class_template),
6387                   "super_class", &chain);
6388
6389   objc_finish_struct (objc_super_template, decls);
6390 }
6391
6392 /* struct _objc_ivar {
6393      char *ivar_name;
6394      char *ivar_type;
6395      int ivar_offset;
6396    };  */
6397
6398 static tree
6399 build_ivar_template (void)
6400 {
6401   tree objc_ivar_id, objc_ivar_record;
6402   tree decls, *chain = NULL;
6403
6404   objc_ivar_id = get_identifier (UTAG_IVAR);
6405   objc_ivar_record = objc_start_struct (objc_ivar_id);
6406
6407   /* char *ivar_name; */
6408   decls = add_field_decl (string_type_node, "ivar_name", &chain);
6409
6410   /* char *ivar_type; */
6411   add_field_decl (string_type_node, "ivar_type", &chain);
6412
6413   /* int ivar_offset; */
6414   add_field_decl (integer_type_node, "ivar_offset", &chain);
6415
6416   objc_finish_struct (objc_ivar_record, decls);
6417
6418   return objc_ivar_record;
6419 }
6420
6421 /* struct {
6422      int ivar_count;
6423      struct objc_ivar ivar_list[ivar_count];
6424    };  */
6425
6426 static tree
6427 build_ivar_list_template (tree list_type, int size)
6428 {
6429   tree objc_ivar_list_record;
6430   tree array_type, decls, *chain = NULL;
6431
6432   objc_ivar_list_record = objc_start_struct (NULL_TREE);
6433
6434   /* int ivar_count; */
6435   decls = add_field_decl (integer_type_node, "ivar_count", &chain);
6436
6437   /* struct objc_ivar ivar_list[]; */
6438   array_type = build_sized_array_type (list_type, size);
6439   add_field_decl (array_type, "ivar_list", &chain);
6440
6441   objc_finish_struct (objc_ivar_list_record, decls);
6442
6443   return objc_ivar_list_record;
6444 }
6445
6446 /* struct {
6447      struct _objc__method_prototype_list *method_next;
6448      int method_count;
6449      struct objc_method method_list[method_count];
6450    };  */
6451
6452 static tree
6453 build_method_list_template (tree list_type, int size)
6454 {
6455   tree objc_ivar_list_record;
6456   tree array_type, decls, *chain = NULL;
6457
6458   objc_ivar_list_record = objc_start_struct (NULL_TREE);
6459
6460   /* struct _objc__method_prototype_list *method_next; */
6461   decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
6462
6463   /* int method_count; */
6464   add_field_decl (integer_type_node, "method_count", &chain);
6465
6466   /* struct objc_method method_list[]; */
6467   array_type = build_sized_array_type (list_type, size);
6468   add_field_decl (array_type, "method_list", &chain);
6469
6470   objc_finish_struct (objc_ivar_list_record, decls);
6471
6472   return objc_ivar_list_record;
6473 }
6474
6475 static tree
6476 build_ivar_list_initializer (tree type, tree field_decl)
6477 {
6478   VEC(constructor_elt,gc) *inits = NULL;
6479
6480   do
6481     {
6482       VEC(constructor_elt,gc) *ivar = NULL;
6483       tree id;
6484
6485       /* Set name.  */
6486       if (DECL_NAME (field_decl))
6487         CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
6488                                 add_objc_string (DECL_NAME (field_decl),
6489                                                  meth_var_names));
6490       else
6491         /* Unnamed bit-field ivar (yuck).  */
6492         CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
6493
6494       /* Set type.  */
6495       encode_field_decl (field_decl,
6496                          obstack_object_size (&util_obstack),
6497                          OBJC_ENCODE_DONT_INLINE_DEFS);
6498
6499       /* Null terminate string.  */
6500       obstack_1grow (&util_obstack, 0);
6501       id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
6502                             meth_var_types);
6503       CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
6504       obstack_free (&util_obstack, util_firstobj);
6505
6506       /* Set offset.  */
6507       CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
6508       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
6509                               objc_build_constructor (type, ivar));
6510       do
6511         field_decl = DECL_CHAIN (field_decl);
6512       while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
6513     }
6514   while (field_decl);
6515
6516   return objc_build_constructor (build_array_type (type, 0), inits);
6517 }
6518
6519 static tree
6520 generate_ivars_list (tree type, const char *name, int size, tree list)
6521 {
6522   tree decl;
6523   VEC(constructor_elt,gc) *inits = NULL;
6524
6525   decl = start_var_decl (type, synth_id_with_class_suffix
6526                                (name, objc_implementation_context));
6527
6528   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
6529   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, list);
6530
6531   finish_var_decl (decl,
6532                    objc_build_constructor (TREE_TYPE (decl), inits));
6533
6534   return decl;
6535 }
6536
6537 /* Count only the fields occurring in T.  */
6538
6539 static int
6540 ivar_list_length (tree t)
6541 {
6542   int count = 0;
6543
6544   for (; t; t = DECL_CHAIN (t))
6545     if (TREE_CODE (t) == FIELD_DECL)
6546       ++count;
6547
6548   return count;
6549 }
6550
6551 static void
6552 generate_ivar_lists (void)
6553 {
6554   tree initlist, ivar_list_template, chain;
6555   int size;
6556
6557   generating_instance_variables = 1;
6558
6559   if (!objc_ivar_template)
6560     objc_ivar_template = build_ivar_template ();
6561
6562   /* Only generate class variables for the root of the inheritance
6563      hierarchy since these will be the same for every class.  */
6564
6565   if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
6566       && (chain = TYPE_FIELDS (objc_class_template)))
6567     {
6568       size = ivar_list_length (chain);
6569
6570       ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
6571       initlist = build_ivar_list_initializer (objc_ivar_template, chain);
6572
6573       UOBJC_CLASS_VARIABLES_decl
6574         = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
6575                                size, initlist);
6576     }
6577   else
6578     UOBJC_CLASS_VARIABLES_decl = 0;
6579
6580   chain = CLASS_IVARS (implementation_template);
6581   if (chain)
6582     {
6583       size = ivar_list_length (chain);
6584       ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
6585       initlist = build_ivar_list_initializer (objc_ivar_template, chain);
6586
6587       UOBJC_INSTANCE_VARIABLES_decl
6588         = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
6589                                size, initlist);
6590     }
6591   else
6592     UOBJC_INSTANCE_VARIABLES_decl = 0;
6593
6594   generating_instance_variables = 0;
6595 }
6596
6597 static tree
6598 build_dispatch_table_initializer (tree type, tree entries)
6599 {
6600   VEC(constructor_elt,gc) *inits = NULL;
6601
6602   do
6603     {
6604       VEC(constructor_elt,gc) *elems = NULL;
6605       tree expr;
6606
6607       CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
6608                               build_selector (METHOD_SEL_NAME (entries)));
6609
6610       /* Generate the method encoding if we don't have one already.  */
6611       if (! METHOD_ENCODING (entries))
6612         METHOD_ENCODING (entries) =
6613           encode_method_prototype (entries);
6614
6615       CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
6616                               add_objc_string (METHOD_ENCODING (entries),
6617                                                meth_var_types));
6618
6619       expr = convert (ptr_type_node,
6620                       build_unary_op (input_location, ADDR_EXPR,
6621                                       METHOD_DEFINITION (entries), 1));
6622       CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
6623
6624       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
6625                               objc_build_constructor (type, elems));
6626
6627       entries = DECL_CHAIN (entries);
6628     }
6629   while (entries);
6630
6631   return objc_build_constructor (build_array_type (type, 0), inits);
6632 }
6633
6634 /* To accomplish method prototyping without generating all kinds of
6635    inane warnings, the definition of the dispatch table entries were
6636    changed from:
6637
6638         struct objc_method { SEL _cmd; ...; id (*_imp)(); };
6639    to:
6640         struct objc_method { SEL _cmd; ...; void *_imp; };  */
6641
6642 static tree
6643 build_method_template (void)
6644 {
6645   tree _SLT_record;
6646   tree decls, *chain = NULL;
6647
6648   _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
6649
6650   /* SEL _cmd; */
6651   decls = add_field_decl (objc_selector_type, "_cmd", &chain);
6652
6653   /* char *method_types; */
6654   add_field_decl (string_type_node, "method_types", &chain);
6655
6656   /* void *_imp; */
6657   add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
6658
6659   objc_finish_struct (_SLT_record, decls);
6660
6661   return _SLT_record;
6662 }
6663
6664
6665 static tree
6666 generate_dispatch_table (tree type, const char *name, int size, tree list)
6667 {
6668   tree decl;
6669   VEC(constructor_elt,gc) *v = NULL;
6670
6671   decl = start_var_decl (type, synth_id_with_class_suffix
6672                                (name, objc_implementation_context));
6673
6674   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
6675   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, size));
6676   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
6677
6678   finish_var_decl (decl,
6679                    objc_build_constructor (TREE_TYPE (decl), v));
6680
6681   return decl;
6682 }
6683
6684 static void
6685 mark_referenced_methods (void)
6686 {
6687   struct imp_entry *impent;
6688   tree chain;
6689
6690   for (impent = imp_list; impent; impent = impent->next)
6691     {
6692       chain = CLASS_CLS_METHODS (impent->imp_context);
6693       while (chain)
6694         {
6695           cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6696           chain = DECL_CHAIN (chain);
6697         }
6698
6699       chain = CLASS_NST_METHODS (impent->imp_context);
6700       while (chain)
6701         {
6702           cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6703           chain = DECL_CHAIN (chain);
6704         }
6705     }
6706 }
6707
6708 static void
6709 generate_dispatch_tables (void)
6710 {
6711   tree initlist, chain, method_list_template;
6712   int size;
6713
6714   if (!objc_method_template)
6715     objc_method_template = build_method_template ();
6716
6717   chain = CLASS_CLS_METHODS (objc_implementation_context);
6718   if (chain)
6719     {
6720       size = list_length (chain);
6721
6722       method_list_template
6723         = build_method_list_template (objc_method_template, size);
6724       initlist
6725         = build_dispatch_table_initializer (objc_method_template, chain);
6726
6727       UOBJC_CLASS_METHODS_decl
6728         = generate_dispatch_table (method_list_template,
6729                                    ((TREE_CODE (objc_implementation_context)
6730                                      == CLASS_IMPLEMENTATION_TYPE)
6731                                     ? "_OBJC_CLASS_METHODS"
6732                                     : "_OBJC_CATEGORY_CLASS_METHODS"),
6733                                    size, initlist);
6734     }
6735   else
6736     UOBJC_CLASS_METHODS_decl = 0;
6737
6738   chain = CLASS_NST_METHODS (objc_implementation_context);
6739   if (chain)
6740     {
6741       size = list_length (chain);
6742
6743       method_list_template
6744         = build_method_list_template (objc_method_template, size);
6745       initlist
6746         = build_dispatch_table_initializer (objc_method_template, chain);
6747
6748       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6749         UOBJC_INSTANCE_METHODS_decl
6750           = generate_dispatch_table (method_list_template,
6751                                      "_OBJC_INSTANCE_METHODS",
6752                                      size, initlist);
6753       else
6754         /* We have a category.  */
6755         UOBJC_INSTANCE_METHODS_decl
6756           = generate_dispatch_table (method_list_template,
6757                                      "_OBJC_CATEGORY_INSTANCE_METHODS",
6758                                      size, initlist);
6759     }
6760   else
6761     UOBJC_INSTANCE_METHODS_decl = 0;
6762 }
6763
6764 static tree
6765 generate_protocol_list (tree i_or_p)
6766 {
6767   tree array_type, ptype, refs_decl, lproto, e, plist;
6768   int size = 0;
6769   const char *ref_name;
6770   VEC(constructor_elt,gc) *v = NULL;
6771
6772   switch (TREE_CODE (i_or_p))
6773     {
6774     case CLASS_INTERFACE_TYPE:
6775     case CATEGORY_INTERFACE_TYPE:
6776       plist = CLASS_PROTOCOL_LIST (i_or_p);
6777       break;
6778     case PROTOCOL_INTERFACE_TYPE:
6779       plist = PROTOCOL_LIST (i_or_p);
6780       break;
6781     default:
6782       gcc_unreachable ();
6783     }
6784
6785   /* Compute size.  */
6786   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6787     if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
6788         && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
6789       size++;
6790
6791   /* Build initializer.  */
6792   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6793   e = build_int_cst (build_pointer_type (objc_protocol_template), size);
6794   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6795
6796   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6797     {
6798       tree pval = TREE_VALUE (lproto);
6799
6800       if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
6801           && PROTOCOL_FORWARD_DECL (pval))
6802         {
6803           e = build_unary_op (input_location, ADDR_EXPR, 
6804                               PROTOCOL_FORWARD_DECL (pval), 0);
6805           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6806         }
6807     }
6808
6809   /* static struct objc_protocol *refs[n]; */
6810
6811   switch (TREE_CODE (i_or_p))
6812     {
6813     case PROTOCOL_INTERFACE_TYPE:
6814       ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
6815       break;
6816     case CLASS_INTERFACE_TYPE:
6817       ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
6818       break;
6819     case CATEGORY_INTERFACE_TYPE:
6820       ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
6821       break;
6822     default:
6823       gcc_unreachable ();
6824     }
6825
6826   ptype = build_pointer_type (objc_protocol_template);
6827   array_type = build_sized_array_type (ptype, size + 3);
6828   refs_decl = start_var_decl (array_type, ref_name);
6829
6830   finish_var_decl (refs_decl,
6831                    objc_build_constructor (TREE_TYPE (refs_decl), v));
6832
6833   return refs_decl;
6834 }
6835
6836 static tree
6837 build_category_initializer (tree type, tree cat_name, tree class_name,
6838                             tree instance_methods, tree class_methods,
6839                             tree protocol_list)
6840 {
6841   tree expr;
6842   VEC(constructor_elt,gc) *v = NULL;
6843
6844   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
6845   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
6846
6847   if (!instance_methods)
6848     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6849   else
6850     {
6851       expr = convert (objc_method_list_ptr,
6852                       build_unary_op (input_location, ADDR_EXPR, 
6853                                       instance_methods, 0));
6854       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6855     }
6856   if (!class_methods)
6857     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6858   else
6859     {
6860       expr = convert (objc_method_list_ptr,
6861                       build_unary_op (input_location, ADDR_EXPR, 
6862                                       class_methods, 0));
6863       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6864     }
6865
6866   /* protocol_list = */
6867   if (!protocol_list)
6868     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6869   else
6870     {
6871       expr = convert (build_pointer_type
6872                       (build_pointer_type
6873                        (objc_protocol_template)),
6874                       build_unary_op (input_location, ADDR_EXPR, 
6875                                       protocol_list, 0));
6876       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6877     }
6878
6879   return objc_build_constructor (type, v);
6880 }
6881
6882 /* struct _objc_class {
6883      struct objc_class *isa;
6884      struct objc_class *super_class;
6885      char *name;
6886      long version;
6887      long info;
6888      long instance_size;
6889      struct objc_ivar_list *ivars;
6890      struct objc_method_list *methods;
6891      if (flag_next_runtime)
6892        struct objc_cache *cache;
6893      else {
6894        struct sarray *dtable;
6895        struct objc_class *subclass_list;
6896        struct objc_class *sibling_class;
6897      }
6898      struct objc_protocol_list *protocols;
6899      if (flag_next_runtime)
6900        void *sel_id;
6901      void *gc_object_type;
6902    };  */
6903
6904 static tree
6905 build_shared_structure_initializer (tree type, tree isa, tree super,
6906                                     tree name, tree size, int status,
6907                                     tree dispatch_table, tree ivar_list,
6908                                     tree protocol_list)
6909 {
6910   tree expr;
6911   VEC(constructor_elt,gc) *v = NULL;
6912
6913   /* isa = */
6914   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
6915
6916   /* super_class = */
6917   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
6918
6919   /* name = */
6920   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
6921
6922   /* version = */
6923   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6924                           build_int_cst (long_integer_type_node, 0));
6925
6926   /* info = */
6927   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6928                           build_int_cst (long_integer_type_node, status));
6929
6930   /* instance_size = */
6931   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6932                           convert (long_integer_type_node, size));
6933
6934   /* objc_ivar_list = */
6935   if (!ivar_list)
6936     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6937   else
6938     {
6939       expr = convert (objc_ivar_list_ptr,
6940                       build_unary_op (input_location, ADDR_EXPR, 
6941                                       ivar_list, 0));
6942       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6943     }
6944
6945   /* objc_method_list = */
6946   if (!dispatch_table)
6947     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6948   else
6949     {
6950       expr = convert (objc_method_list_ptr,
6951                       build_unary_op (input_location, ADDR_EXPR, 
6952                                       dispatch_table, 0));
6953       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6954     }
6955
6956   if (flag_next_runtime)
6957     /* method_cache = */
6958     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6959   else
6960     {
6961       /* dtable = */
6962       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6963
6964       /* subclass_list = */
6965       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6966
6967       /* sibling_class = */
6968       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6969     }
6970
6971   /* protocol_list = */
6972   if (! protocol_list)
6973     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6974   else
6975     {
6976       expr = convert (build_pointer_type
6977                       (build_pointer_type
6978                        (objc_protocol_template)),
6979                       build_unary_op (input_location, ADDR_EXPR, 
6980                                       protocol_list, 0));
6981       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6982     }
6983
6984   if (flag_next_runtime)
6985     /* sel_id = NULL */
6986     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6987
6988   /* gc_object_type = NULL */
6989   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6990
6991   return objc_build_constructor (type, v);
6992 }
6993
6994 /* Retrieve category interface CAT_NAME (if any) associated with CLASS.  */
6995
6996 static inline tree
6997 lookup_category (tree klass, tree cat_name)
6998 {
6999   tree category = CLASS_CATEGORY_LIST (klass);
7000
7001   while (category && CLASS_SUPER_NAME (category) != cat_name)
7002     category = CLASS_CATEGORY_LIST (category);
7003   return category;
7004 }
7005
7006 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... };  */
7007
7008 static void
7009 generate_category (struct imp_entry *impent)
7010 {
7011   tree initlist, cat_name_expr, class_name_expr;
7012   tree protocol_decl, category;
7013   tree cat = impent->imp_context;
7014
7015   implementation_template = impent->imp_template;
7016   UOBJC_CLASS_decl = impent->class_decl;
7017   UOBJC_METACLASS_decl = impent->meta_decl;
7018
7019   add_class_reference (CLASS_NAME (cat));
7020   cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
7021
7022   class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
7023
7024   category = lookup_category (implementation_template,
7025                                 CLASS_SUPER_NAME (cat));
7026
7027   if (category && CLASS_PROTOCOL_LIST (category))
7028     {
7029       generate_protocol_references (CLASS_PROTOCOL_LIST (category));
7030       protocol_decl = generate_protocol_list (category);
7031     }
7032   else
7033     protocol_decl = 0;
7034
7035   initlist = build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl),
7036                                          cat_name_expr, class_name_expr,
7037                                          UOBJC_INSTANCE_METHODS_decl,
7038                                          UOBJC_CLASS_METHODS_decl,
7039                                          protocol_decl);
7040   /* Finish and initialize the forward decl.  */
7041   finish_var_decl (UOBJC_CLASS_decl, initlist);
7042 }
7043
7044 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
7045    static struct objc_class _OBJC_CLASS_Foo={ ... };  */
7046
7047 static void
7048 generate_shared_structures (struct imp_entry *impent)
7049 {
7050   tree name_expr, super_expr, root_expr;
7051   tree my_root_id, my_super_id;
7052   tree cast_type, initlist, protocol_decl;
7053   int cls_flags;
7054   
7055   objc_implementation_context = impent->imp_context;
7056   implementation_template = impent->imp_template;
7057   UOBJC_CLASS_decl = impent->class_decl;
7058   UOBJC_METACLASS_decl = impent->meta_decl;
7059   cls_flags = impent->has_cxx_cdtors ? CLS_HAS_CXX_STRUCTORS : 0 ;
7060   
7061   my_super_id = CLASS_SUPER_NAME (implementation_template);
7062   if (my_super_id)
7063     {
7064       add_class_reference (my_super_id);
7065
7066       /* Compute "my_root_id" - this is required for code generation.
7067          the "isa" for all meta class structures points to the root of
7068          the inheritance hierarchy (e.g. "__Object")...  */
7069       my_root_id = my_super_id;
7070       do
7071         {
7072           tree my_root_int = lookup_interface (my_root_id);
7073
7074           if (my_root_int && CLASS_SUPER_NAME (my_root_int))
7075             my_root_id = CLASS_SUPER_NAME (my_root_int);
7076           else
7077             break;
7078         }
7079       while (1);
7080     }
7081   else
7082     /* No super class.  */
7083     my_root_id = CLASS_NAME (implementation_template);
7084
7085   cast_type = build_pointer_type (objc_class_template);
7086   name_expr = add_objc_string (CLASS_NAME (implementation_template),
7087                                class_names);
7088
7089   /* Install class `isa' and `super' pointers at runtime.  */
7090   if (my_super_id)
7091     super_expr = add_objc_string (my_super_id, class_names);
7092   else
7093     super_expr = integer_zero_node;
7094     
7095   super_expr = build_c_cast (input_location,
7096                                  cast_type, super_expr); /* cast! */
7097
7098   root_expr = add_objc_string (my_root_id, class_names);
7099   root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
7100
7101   if (CLASS_PROTOCOL_LIST (implementation_template))
7102     {
7103       generate_protocol_references
7104         (CLASS_PROTOCOL_LIST (implementation_template));
7105       protocol_decl = generate_protocol_list (implementation_template);
7106     }
7107   else
7108     protocol_decl = 0;
7109
7110   /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
7111
7112   initlist
7113     = build_shared_structure_initializer
7114       (TREE_TYPE (UOBJC_METACLASS_decl),
7115        root_expr, super_expr, name_expr,
7116        convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
7117        2 /*CLS_META*/,
7118        UOBJC_CLASS_METHODS_decl,
7119        UOBJC_CLASS_VARIABLES_decl,
7120        protocol_decl);
7121
7122   finish_var_decl (UOBJC_METACLASS_decl, initlist);
7123
7124   /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
7125
7126   initlist
7127     = build_shared_structure_initializer
7128       (TREE_TYPE (UOBJC_CLASS_decl),
7129        build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
7130        super_expr, name_expr,
7131        convert (integer_type_node,
7132                 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
7133                                 (implementation_template))),
7134        1 /*CLS_FACTORY*/ | cls_flags,
7135        UOBJC_INSTANCE_METHODS_decl,
7136        UOBJC_INSTANCE_VARIABLES_decl,
7137        protocol_decl);
7138
7139   finish_var_decl (UOBJC_CLASS_decl, initlist);
7140 }
7141
7142
7143 static const char *
7144 synth_id_with_class_suffix (const char *preamble, tree ctxt)
7145 {
7146   static char string[BUFSIZE];
7147
7148   switch (TREE_CODE (ctxt))
7149     {
7150     case CLASS_IMPLEMENTATION_TYPE:
7151     case CLASS_INTERFACE_TYPE:
7152       sprintf (string, "%s_%s", preamble,
7153                IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
7154       break;
7155     case CATEGORY_IMPLEMENTATION_TYPE:
7156     case CATEGORY_INTERFACE_TYPE:
7157       {
7158         /* We have a category.  */
7159         const char *const class_name
7160           = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7161         const char *const class_super_name
7162           = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
7163         sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
7164         break;
7165     }
7166     case PROTOCOL_INTERFACE_TYPE:
7167       {
7168         const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
7169         sprintf (string, "%s_%s", preamble, protocol_name);
7170         break;
7171       }
7172     default:
7173       gcc_unreachable ();
7174     }
7175
7176   return string;
7177 }
7178
7179 /* If type is empty or only type qualifiers are present, add default
7180    type of id (otherwise grokdeclarator will default to int).  */
7181 static inline tree
7182 adjust_type_for_id_default (tree type)
7183 {
7184   if (!type)
7185     type = make_node (TREE_LIST);
7186
7187   if (!TREE_VALUE (type))
7188     TREE_VALUE (type) = objc_object_type;
7189   else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
7190            && TYPED_OBJECT (TREE_VALUE (type)))
7191     error ("can not use an object as parameter to a method");
7192
7193   return type;
7194 }
7195
7196 /* Return a KEYWORD_DECL built using the specified key_name, arg_type,
7197    arg_name and attributes. (TODO: Rename KEYWORD_DECL to
7198    OBJC_METHOD_PARM_DECL ?)
7199
7200    A KEYWORD_DECL is a tree representing the declaration of a
7201    parameter of an Objective-C method.  It is produced when parsing a
7202    fragment of Objective-C method declaration of the form
7203
7204    keyworddecl:
7205      selector ':' '(' typename ')' identifier
7206
7207    For example, take the Objective-C method
7208
7209    -(NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type; 
7210
7211    the two fragments "pathForResource:(NSString *)resource" and
7212    "ofType:(NSString *)type" will generate a KEYWORD_DECL each.  The
7213    KEYWORD_DECL stores the 'key_name' (eg, identifier for
7214    "pathForResource"), the 'arg_type' (eg, tree representing a
7215    NSString *), the 'arg_name' (eg identifier for "resource") and
7216    potentially some attributes (for example, a tree representing
7217    __attribute__ ((unused)) if such an attribute was attached to a
7218    certain parameter).  You can access this information using the
7219    TREE_TYPE (for arg_type), KEYWORD_ARG_NAME (for arg_name),
7220    KEYWORD_KEY_NAME (for key_name), DECL_ATTRIBUTES (for attributes).
7221
7222    'key_name' is an identifier node (and is optional as you can omit
7223    it in Objective-C methods).
7224    'arg_type' is a tree list (and is optional too if no parameter type
7225    was specified).
7226    'arg_name' is an identifier node and is required.
7227    'attributes' is an optional tree containing parameter attributes.  */
7228 tree
7229 objc_build_keyword_decl (tree key_name, tree arg_type, 
7230                          tree arg_name, tree attributes)
7231 {
7232   tree keyword_decl;
7233
7234   if (flag_objc1_only && attributes)
7235     error_at (input_location, "method argument attributes are not available in Objective-C 1.0");
7236
7237   /* If no type is specified, default to "id".  */
7238   arg_type = adjust_type_for_id_default (arg_type);
7239
7240   keyword_decl = make_node (KEYWORD_DECL);
7241
7242   TREE_TYPE (keyword_decl) = arg_type;
7243   KEYWORD_ARG_NAME (keyword_decl) = arg_name;
7244   KEYWORD_KEY_NAME (keyword_decl) = key_name;
7245   DECL_ATTRIBUTES (keyword_decl) = attributes;
7246
7247   return keyword_decl;
7248 }
7249
7250 /* Given a chain of keyword_decl's, synthesize the full keyword selector.  */
7251 static tree
7252 build_keyword_selector (tree selector)
7253 {
7254   int len = 0;
7255   tree key_chain, key_name;
7256   char *buf;
7257
7258   /* Scan the selector to see how much space we'll need.  */
7259   for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
7260     {
7261       switch (TREE_CODE (selector))
7262         {
7263         case KEYWORD_DECL:
7264           key_name = KEYWORD_KEY_NAME (key_chain);
7265           break;
7266         case TREE_LIST:
7267           key_name = TREE_PURPOSE (key_chain);
7268           break;
7269         default:
7270           gcc_unreachable ();
7271         }
7272
7273       if (key_name)
7274         len += IDENTIFIER_LENGTH (key_name) + 1;
7275       else
7276         /* Just a ':' arg.  */
7277         len++;
7278     }
7279
7280   buf = (char *) alloca (len + 1);
7281   /* Start the buffer out as an empty string.  */
7282   buf[0] = '\0';
7283
7284   for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
7285     {
7286       switch (TREE_CODE (selector))
7287         {
7288         case KEYWORD_DECL:
7289           key_name = KEYWORD_KEY_NAME (key_chain);
7290           break;
7291         case TREE_LIST:
7292           key_name = TREE_PURPOSE (key_chain);
7293           /* The keyword decl chain will later be used as a function
7294              argument chain.  Unhook the selector itself so as to not
7295              confuse other parts of the compiler.  */
7296           TREE_PURPOSE (key_chain) = NULL_TREE;
7297           break;
7298         default:
7299           gcc_unreachable ();
7300         }
7301
7302       if (key_name)
7303         strcat (buf, IDENTIFIER_POINTER (key_name));
7304       strcat (buf, ":");
7305     }
7306
7307   return get_identifier (buf);
7308 }
7309
7310 /* Used for declarations and definitions.  */
7311
7312 static tree
7313 build_method_decl (enum tree_code code, tree ret_type, tree selector,
7314                    tree add_args, bool ellipsis)
7315 {
7316   tree method_decl;
7317
7318   /* If no type is specified, default to "id".  */
7319   ret_type = adjust_type_for_id_default (ret_type);
7320
7321   /* Note how a method_decl has a TREE_TYPE which is not the function
7322      type of the function implementing the method, but only the return
7323      type of the method.  We may want to change this, and store the
7324      entire function type in there (eg, it may be used to simplify
7325      dealing with attributes below).  */
7326   method_decl = make_node (code);
7327   TREE_TYPE (method_decl) = ret_type;
7328
7329   /* If we have a keyword selector, create an identifier_node that
7330      represents the full selector name (`:' included)...  */
7331   if (TREE_CODE (selector) == KEYWORD_DECL)
7332     {
7333       METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
7334       METHOD_SEL_ARGS (method_decl) = selector;
7335       METHOD_ADD_ARGS (method_decl) = add_args;
7336       METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
7337     }
7338   else
7339     {
7340       METHOD_SEL_NAME (method_decl) = selector;
7341       METHOD_SEL_ARGS (method_decl) = NULL_TREE;
7342       METHOD_ADD_ARGS (method_decl) = NULL_TREE;
7343     }
7344
7345   return method_decl;
7346 }
7347
7348 #define METHOD_DEF 0
7349 #define METHOD_REF 1
7350
7351 /* This routine processes objective-c method attributes. */
7352
7353 static void
7354 objc_decl_method_attributes (tree *node, tree attributes, int flags)
7355 {
7356   /* TODO: Replace the hackery below.  An idea would be to store the
7357      full function type in the method declaration (for example in
7358      TREE_TYPE) and then expose ObjC method declarations to c-family
7359      and they could deal with them by simply treating them as
7360      functions.  */
7361
7362   /* Because of the dangers in the hackery below, we filter out any
7363      attribute that we do not know about.  For the ones we know about,
7364      we know that they work with the hackery.  For the other ones,
7365      there is no guarantee, so we have to filter them out.  */
7366   tree filtered_attributes = NULL_TREE;
7367
7368   if (attributes)
7369     {
7370       tree attribute;
7371       for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
7372         {
7373           tree name = TREE_PURPOSE (attribute);
7374           
7375           if (is_attribute_p  ("deprecated", name)
7376               || is_attribute_p ("sentinel", name)
7377               || is_attribute_p ("noreturn", name))
7378             {
7379               /* An attribute that we support; add it to the filtered
7380                  attributes.  */
7381               filtered_attributes = chainon (filtered_attributes, 
7382                                              copy_node (attribute));
7383             }
7384           else if (is_attribute_p ("format", name))
7385             {
7386               /* "format" is special because before adding it to the
7387                  filtered attributes we need to adjust the specified
7388                  format by adding the hidden function parameters for
7389                  an Objective-C method (self, _cmd).  */
7390               tree new_attribute = copy_node (attribute);
7391
7392               /* Check the arguments specified with the attribute, and
7393                  modify them adding 2 for the two hidden arguments.
7394                  Note how this differs from C++; according to the
7395                  specs, C++ does not do it so you have to add the +1
7396                  yourself.  For Objective-C, instead, the compiler
7397                  adds the +2 for you.  */
7398
7399               /* The attribute arguments have not been checked yet, so
7400                  we need to be careful as they could be missing or
7401                  invalid.  If anything looks wrong, we skip the
7402                  process and the compiler will complain about it later
7403                  when it validates the attribute.  */
7404               /* Check that we have at least three arguments.  */
7405               if (TREE_VALUE (new_attribute)
7406                   && TREE_CHAIN (TREE_VALUE (new_attribute))
7407                   && TREE_CHAIN (TREE_CHAIN (TREE_VALUE (new_attribute))))
7408                 {
7409                   tree second_argument = TREE_CHAIN (TREE_VALUE (new_attribute));
7410                   tree third_argument = TREE_CHAIN (second_argument);
7411                   tree number;
7412
7413                   /* This is the second argument, the "string-index",
7414                      which specifies the index of the format string
7415                      argument.  Add 2.  */
7416                   number = TREE_VALUE (second_argument);
7417                   if (number
7418                       && TREE_CODE (number) == INTEGER_CST
7419                       && TREE_INT_CST_HIGH (number) == 0)
7420                     {
7421                       TREE_VALUE (second_argument) 
7422                         = build_int_cst (integer_type_node,
7423                                          TREE_INT_CST_LOW (number) + 2);
7424                     }
7425                   
7426                   /* This is the third argument, the "first-to-check",
7427                      which specifies the index of the first argument to
7428                      check.  This could be 0, meaning it is not available,
7429                      in which case we don't need to add 2.  Add 2 if not
7430                      0.  */
7431                   number = TREE_VALUE (third_argument);
7432                   if (number
7433                       && TREE_CODE (number) == INTEGER_CST
7434                       && TREE_INT_CST_HIGH (number) == 0
7435                       && TREE_INT_CST_LOW (number) != 0)
7436                     {
7437                       TREE_VALUE (third_argument) 
7438                         = build_int_cst (integer_type_node,
7439                                          TREE_INT_CST_LOW (number) + 2);
7440                     }
7441                 }
7442               filtered_attributes = chainon (filtered_attributes,
7443                                              new_attribute);
7444             }
7445           else
7446             warning (OPT_Wattributes, "%qE attribute directive ignored", name);
7447         }
7448     }
7449
7450   if (filtered_attributes)
7451     {
7452       /* This hackery changes the TREE_TYPE of the ObjC method
7453          declaration to be a function type, so that decl_attributes
7454          will treat the ObjC method as if it was a function.  Some
7455          attributes (sentinel, format) will be applied to the function
7456          type, changing it in place; so after calling decl_attributes,
7457          we extract the function type attributes and store them in
7458          METHOD_TYPE_ATTRIBUTES.  Some other attributes (noreturn,
7459          deprecated) are applied directly to the method declaration
7460          (by setting TREE_DEPRECATED and TREE_THIS_VOLATILE) so there
7461          is nothing to do.  */
7462       tree saved_type = TREE_TYPE (*node);
7463       TREE_TYPE (*node) = build_function_type 
7464         (TREE_VALUE (saved_type), get_arg_type_list (*node, METHOD_REF, 0));
7465       decl_attributes (node, filtered_attributes, flags);
7466       METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
7467       TREE_TYPE (*node) = saved_type;
7468     }
7469 }
7470
7471 bool 
7472 objc_method_decl (enum tree_code opcode)
7473 {
7474   return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
7475 }
7476
7477 /* Used by `build_objc_method_call' and `comp_proto_with_proto'.  Return
7478    an argument list for method METH.  CONTEXT is either METHOD_DEF or
7479    METHOD_REF, saying whether we are trying to define a method or call
7480    one.  SUPERFLAG says this is for a send to super; this makes a
7481    difference for the NeXT calling sequence in which the lookup and
7482    the method call are done together.  If METH is null, user-defined
7483    arguments (i.e., beyond self and _cmd) shall be represented by `...'.  */
7484
7485 static tree
7486 get_arg_type_list (tree meth, int context, int superflag)
7487 {
7488   tree arglist, akey;
7489
7490   /* Receiver type.  */
7491   if (flag_next_runtime && superflag)
7492     arglist = build_tree_list (NULL_TREE, objc_super_type);
7493   else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
7494     arglist = build_tree_list (NULL_TREE, objc_instance_type);
7495   else
7496     arglist = build_tree_list (NULL_TREE, objc_object_type);
7497
7498   /* Selector type - will eventually change to `int'.  */
7499   chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
7500
7501   /* No actual method prototype given -- assume that remaining arguments
7502      are `...'.  */
7503   if (!meth)
7504     return arglist;
7505
7506   /* Build a list of argument types.  */
7507   for (akey = METHOD_SEL_ARGS (meth); akey; akey = DECL_CHAIN (akey))
7508     {
7509       tree arg_type = TREE_VALUE (TREE_TYPE (akey));
7510
7511       /* Decay argument types for the underlying C function as appropriate.  */
7512       arg_type = objc_decay_parm_type (arg_type);
7513
7514       chainon (arglist, build_tree_list (NULL_TREE, arg_type));
7515     }
7516
7517   if (METHOD_ADD_ARGS (meth))
7518     {
7519       for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
7520            akey; akey = TREE_CHAIN (akey))
7521         {
7522           tree arg_type = TREE_TYPE (TREE_VALUE (akey));
7523
7524           arg_type = objc_decay_parm_type (arg_type);
7525
7526           chainon (arglist, build_tree_list (NULL_TREE, arg_type));
7527         }
7528
7529       if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
7530         goto lack_of_ellipsis;
7531     }
7532   else
7533     {
7534      lack_of_ellipsis:
7535       chainon (arglist, OBJC_VOID_AT_END);
7536     }
7537
7538   return arglist;
7539 }
7540
7541 static tree
7542 check_duplicates (hash hsh, int methods, int is_class)
7543 {
7544   tree meth = NULL_TREE;
7545
7546   if (hsh)
7547     {
7548       meth = hsh->key;
7549
7550       if (hsh->list)
7551         {
7552           /* We have two or more methods with the same name but
7553              different types.  */
7554           attr loop;
7555
7556           /* But just how different are those types?  If
7557              -Wno-strict-selector-match is specified, we shall not
7558              complain if the differences are solely among types with
7559              identical size and alignment.  */
7560           if (!warn_strict_selector_match)
7561             {
7562               for (loop = hsh->list; loop; loop = loop->next)
7563                 if (!comp_proto_with_proto (meth, loop->value, 0))
7564                   goto issue_warning;
7565
7566               return meth;
7567             }
7568
7569         issue_warning:
7570           if (methods)
7571             {
7572               bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
7573
7574               warning_at (input_location, 0,
7575                           "multiple methods named %<%c%E%> found",
7576                           (is_class ? '+' : '-'),
7577                           METHOD_SEL_NAME (meth));
7578               inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
7579                       (type ? '-' : '+'),
7580                       identifier_to_locale (gen_method_decl (meth)));
7581             }
7582           else
7583             {
7584               bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
7585
7586               warning_at (input_location, 0,
7587                           "multiple selectors named %<%c%E%> found",
7588                           (is_class ? '+' : '-'),
7589                           METHOD_SEL_NAME (meth));
7590               inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
7591                       (type ? '-' : '+'),
7592                       identifier_to_locale (gen_method_decl (meth)));
7593             }
7594
7595           for (loop = hsh->list; loop; loop = loop->next)
7596             {
7597               bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
7598
7599               inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
7600                       (type ? '-' : '+'),
7601                       identifier_to_locale (gen_method_decl (loop->value)));
7602             }
7603         }
7604     }
7605   return meth;
7606 }
7607
7608 /* If RECEIVER is a class reference, return the identifier node for
7609    the referenced class.  RECEIVER is created by objc_get_class_reference,
7610    so we check the exact form created depending on which runtimes are
7611    used.  */
7612
7613 static tree
7614 receiver_is_class_object (tree receiver, int self, int super)
7615 {
7616   tree chain, exp, arg;
7617
7618   /* The receiver is 'self' or 'super' in the context of a class method.  */
7619   if (objc_method_context
7620       && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
7621       && (self || super))
7622     return (super
7623             ? CLASS_SUPER_NAME (implementation_template)
7624             : CLASS_NAME (implementation_template));
7625
7626   if (flag_next_runtime)
7627     {
7628       /* The receiver is a variable created by
7629          build_class_reference_decl.  */
7630       if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
7631         /* Look up the identifier.  */
7632         for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
7633           if (TREE_PURPOSE (chain) == receiver)
7634             return TREE_VALUE (chain);
7635     }
7636
7637   /* The receiver is a function call that returns an id.  Check if
7638      it is a call to objc_getClass, if so, pick up the class name.  */
7639   if (TREE_CODE (receiver) == CALL_EXPR
7640       && (exp = CALL_EXPR_FN (receiver))
7641       && TREE_CODE (exp) == ADDR_EXPR
7642       && (exp = TREE_OPERAND (exp, 0))
7643       && TREE_CODE (exp) == FUNCTION_DECL
7644       /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
7645          prototypes for objc_get_class().  Thankfully, they seem to share the
7646          same function type.  */
7647       && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
7648       && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
7649       /* We have a call to objc_get_class/objc_getClass!  */
7650       && (arg = CALL_EXPR_ARG (receiver, 0)))
7651     {
7652       STRIP_NOPS (arg);
7653       if (TREE_CODE (arg) == ADDR_EXPR
7654           && (arg = TREE_OPERAND (arg, 0))
7655           && TREE_CODE (arg) == STRING_CST)
7656         /* Finally, we have the class name.  */
7657         return get_identifier (TREE_STRING_POINTER (arg));
7658     }
7659   return 0;
7660 }
7661 \f
7662 /* If we are currently building a message expr, this holds
7663    the identifier of the selector of the message.  This is
7664    used when printing warnings about argument mismatches.  */
7665
7666 static tree current_objc_message_selector = 0;
7667
7668 tree
7669 objc_message_selector (void)
7670 {
7671   return current_objc_message_selector;
7672 }
7673
7674 /* Construct an expression for sending a message.
7675    MESS has the object to send to in TREE_PURPOSE
7676    and the argument list (including selector) in TREE_VALUE.
7677
7678    (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
7679    (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...);  */
7680
7681 tree
7682 objc_build_message_expr (tree mess)
7683 {
7684   tree receiver = TREE_PURPOSE (mess);
7685   tree sel_name;
7686 #ifdef OBJCPLUS
7687   tree args = TREE_PURPOSE (TREE_VALUE (mess));
7688 #else
7689   tree args = TREE_VALUE (mess);
7690 #endif
7691   tree method_params = NULL_TREE;
7692
7693   if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
7694     return error_mark_node;
7695
7696   /* Obtain the full selector name.  */
7697   switch (TREE_CODE (args))
7698     {
7699     case IDENTIFIER_NODE:
7700       /* A unary selector.  */
7701       sel_name = args;
7702       break;
7703     case TREE_LIST:
7704       sel_name = build_keyword_selector (args);
7705       break;
7706     default:
7707       gcc_unreachable ();
7708     }
7709
7710   /* Build the parameter list to give to the method.  */
7711   if (TREE_CODE (args) == TREE_LIST)
7712 #ifdef OBJCPLUS
7713     method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
7714 #else
7715     {
7716       tree chain = args, prev = NULL_TREE;
7717
7718       /* We have a keyword selector--check for comma expressions.  */
7719       while (chain)
7720         {
7721           tree element = TREE_VALUE (chain);
7722
7723           /* We have a comma expression, must collapse...  */
7724           if (TREE_CODE (element) == TREE_LIST)
7725             {
7726               if (prev)
7727                 TREE_CHAIN (prev) = element;
7728               else
7729                 args = element;
7730             }
7731           prev = chain;
7732           chain = TREE_CHAIN (chain);
7733         }
7734       method_params = args;
7735     }
7736 #endif
7737
7738 #ifdef OBJCPLUS
7739   if (processing_template_decl)
7740     /* Must wait until template instantiation time.  */
7741     return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
7742                          method_params);
7743 #endif
7744
7745   return objc_finish_message_expr (receiver, sel_name, method_params);
7746 }
7747
7748 /* Look up method SEL_NAME that would be suitable for receiver
7749    of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
7750    nonzero), and report on any duplicates.  */
7751
7752 static tree
7753 lookup_method_in_hash_lists (tree sel_name, int is_class)
7754 {
7755   hash method_prototype = NULL;
7756
7757   if (!is_class)
7758     method_prototype = hash_lookup (nst_method_hash_list,
7759                                     sel_name);
7760
7761   if (!method_prototype)
7762     {
7763       method_prototype = hash_lookup (cls_method_hash_list,
7764                                       sel_name);
7765       is_class = 1;
7766     }
7767
7768   return check_duplicates (method_prototype, 1, is_class);
7769 }
7770
7771 /* The 'objc_finish_message_expr' routine is called from within
7772    'objc_build_message_expr' for non-template functions.  In the case of
7773    C++ template functions, it is called from 'build_expr_from_tree'
7774    (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded.  */
7775
7776 tree
7777 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
7778 {
7779   tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
7780   tree selector, retval, class_tree;
7781   int self, super, have_cast;
7782
7783   /* We have used the receiver, so mark it as read.  */
7784   mark_exp_read (receiver);
7785
7786   /* Extract the receiver of the message, as well as its type
7787      (where the latter may take the form of a cast or be inferred
7788      from the implementation context).  */
7789   rtype = receiver;
7790   while (TREE_CODE (rtype) == COMPOUND_EXPR
7791               || TREE_CODE (rtype) == MODIFY_EXPR
7792               || CONVERT_EXPR_P (rtype)
7793               || TREE_CODE (rtype) == COMPONENT_REF)
7794     rtype = TREE_OPERAND (rtype, 0);
7795
7796   self = (rtype == self_decl);
7797   super = (rtype == UOBJC_SUPER_decl);
7798   rtype = TREE_TYPE (receiver);
7799
7800   have_cast = (TREE_CODE (receiver) == NOP_EXPR
7801                || (TREE_CODE (receiver) == COMPOUND_EXPR
7802                    && !IS_SUPER (rtype)));
7803
7804   /* If we are calling [super dealloc], reset our warning flag.  */
7805   if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
7806     should_call_super_dealloc = 0;
7807
7808   /* If the receiver is a class object, retrieve the corresponding
7809      @interface, if one exists. */
7810   class_tree = receiver_is_class_object (receiver, self, super);
7811
7812   /* Now determine the receiver type (if an explicit cast has not been
7813      provided).  */
7814   if (!have_cast)
7815     {
7816       if (class_tree)
7817         rtype = lookup_interface (class_tree);
7818       /* Handle `self' and `super'.  */
7819       else if (super)
7820         {
7821           if (!CLASS_SUPER_NAME (implementation_template))
7822             {
7823               error ("no super class declared in @interface for %qE",
7824                      CLASS_NAME (implementation_template));
7825               return error_mark_node;
7826             }
7827           rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
7828         }
7829       else if (self)
7830         rtype = lookup_interface (CLASS_NAME (implementation_template));
7831     }
7832
7833   /* If receiver is of type `id' or `Class' (or if the @interface for a
7834      class is not visible), we shall be satisfied with the existence of
7835      any instance or class method. */
7836   if (objc_is_id (rtype))
7837     {
7838       class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
7839       rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
7840                  ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
7841                  : NULL_TREE);
7842       rtype = NULL_TREE;
7843
7844       if (rprotos)
7845         {
7846           /* If messaging 'id <Protos>' or 'Class <Proto>', first search
7847              in protocols themselves for the method prototype.  */
7848           method_prototype
7849             = lookup_method_in_protocol_list (rprotos, sel_name,
7850                                               class_tree != NULL_TREE);
7851
7852           /* If messaging 'Class <Proto>' but did not find a class method
7853              prototype, search for an instance method instead, and warn
7854              about having done so.  */
7855           if (!method_prototype && !rtype && class_tree != NULL_TREE)
7856             {
7857               method_prototype
7858                 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7859
7860               if (method_prototype)
7861                 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
7862                          sel_name, sel_name);
7863             }
7864         }
7865     }
7866   else if (rtype)
7867     {
7868       tree orig_rtype = rtype;
7869
7870       if (TREE_CODE (rtype) == POINTER_TYPE)
7871         rtype = TREE_TYPE (rtype);
7872       /* Traverse typedef aliases */
7873       while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
7874              && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
7875              && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
7876         rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
7877       if (TYPED_OBJECT (rtype))
7878         {
7879           rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
7880           rtype = TYPE_OBJC_INTERFACE (rtype);
7881         }
7882       /* If we could not find an @interface declaration, we must have
7883          only seen a @class declaration; so, we cannot say anything
7884          more intelligent about which methods the receiver will
7885          understand. */
7886       if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
7887         {
7888           rtype = NULL_TREE;
7889           /* We could not find an @interface declaration, yet Message maybe in a 
7890              @class's protocol. */
7891           if (!method_prototype && rprotos)
7892             method_prototype
7893               = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7894         }
7895       else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
7896           || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
7897         {
7898           /* We have a valid ObjC class name.  Look up the method name
7899              in the published @interface for the class (and its
7900              superclasses). */
7901           method_prototype
7902             = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
7903
7904           /* If the method was not found in the @interface, it may still
7905              exist locally as part of the @implementation.  */
7906           if (!method_prototype && objc_implementation_context
7907              && CLASS_NAME (objc_implementation_context)
7908                 == OBJC_TYPE_NAME (rtype))
7909             method_prototype
7910               = lookup_method
7911                 ((class_tree
7912                   ? CLASS_CLS_METHODS (objc_implementation_context)
7913                   : CLASS_NST_METHODS (objc_implementation_context)),
7914                   sel_name);
7915
7916           /* If we haven't found a candidate method by now, try looking for
7917              it in the protocol list.  */
7918           if (!method_prototype && rprotos)
7919             method_prototype
7920               = lookup_method_in_protocol_list (rprotos, sel_name,
7921                                                 class_tree != NULL_TREE);
7922         }
7923       else
7924         {
7925           warning (0, "invalid receiver type %qs",
7926                    identifier_to_locale (gen_type_name (orig_rtype)));
7927           /* After issuing the "invalid receiver" warning, perform method
7928              lookup as if we were messaging 'id'.  */
7929           rtype = rprotos = NULL_TREE;
7930         }
7931     }
7932
7933
7934   /* For 'id' or 'Class' receivers, search in the global hash table
7935      as a last resort.  For all receivers, warn if protocol searches
7936      have failed.  */
7937   if (!method_prototype)
7938     {
7939       if (rprotos)
7940         warning (0, "%<%c%E%> not found in protocol(s)",
7941                  (class_tree ? '+' : '-'),
7942                  sel_name);
7943
7944       if (!rtype)
7945         method_prototype
7946           = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
7947     }
7948
7949   if (!method_prototype) 
7950     {
7951       static bool warn_missing_methods = false;
7952
7953       if (rtype)
7954         warning (0, "%qE may not respond to %<%c%E%>",
7955                  OBJC_TYPE_NAME (rtype),
7956                  (class_tree ? '+' : '-'),
7957                  sel_name);
7958       /* If we are messaging an 'id' or 'Class' object and made it here,
7959          then we have failed to find _any_ instance or class method,
7960          respectively.  */
7961       else
7962         warning (0, "no %<%c%E%> method found",
7963                  (class_tree ? '+' : '-'),
7964                  sel_name);
7965
7966       if (!warn_missing_methods)
7967         {
7968           warning_at (input_location, 
7969                       0, "(Messages without a matching method signature");
7970           warning_at (input_location, 
7971                       0, "will be assumed to return %<id%> and accept");
7972           warning_at (input_location, 
7973                       0, "%<...%> as arguments.)");
7974           warn_missing_methods = true;
7975         }
7976     }
7977   else
7978     {
7979       /* Warn if the method is deprecated, but not if the receiver is
7980          a generic 'id'.  'id' is used to cast an object to a generic
7981          object of an unspecified class; in that case, we'll use
7982          whatever method prototype we can find to get the method
7983          argument and return types, but it is not appropriate to
7984          produce deprecation warnings since we don't know the class
7985          that the object will be of at runtime.  The @interface(s) for
7986          that class may not even be available to the compiler right
7987          now, and it is perfectly possible that the method is marked
7988          as non-deprecated in such @interface(s).
7989
7990          In practice this makes sense since casting an object to 'id'
7991          is often used precisely to turn off warnings associated with
7992          the object being of a particular class.  */
7993       if (TREE_DEPRECATED (method_prototype)  &&  rtype != NULL_TREE)
7994         warn_deprecated_use (method_prototype, NULL_TREE);
7995     }
7996
7997
7998   /* Save the selector name for printing error messages.  */
7999   current_objc_message_selector = sel_name;
8000
8001   /* Build the parameters list for looking up the method.
8002      These are the object itself and the selector.  */
8003
8004   if (flag_typed_selectors)
8005     selector = build_typed_selector_reference (input_location,
8006                                                sel_name, method_prototype);
8007   else
8008     selector = build_selector_reference (input_location, sel_name);
8009
8010   retval = build_objc_method_call (input_location, super, method_prototype,
8011                                    receiver,
8012                                    selector, method_params);
8013
8014   current_objc_message_selector = 0;
8015
8016   return retval;
8017 }
8018 \f
8019 /* Build a tree expression to send OBJECT the operation SELECTOR,
8020    looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
8021    assuming the method has prototype METHOD_PROTOTYPE.
8022    (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
8023    LOC is the location of the expression to build.
8024    Use METHOD_PARAMS as list of args to pass to the method.
8025    If SUPER_FLAG is nonzero, we look up the superclass's method.  */
8026
8027 static tree
8028 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
8029                         tree lookup_object, tree selector,
8030                         tree method_params)
8031 {
8032   tree sender = (super_flag ? umsg_super_decl :
8033                  (!flag_next_runtime || flag_nil_receivers
8034                   ? (flag_objc_direct_dispatch
8035                      ? umsg_fast_decl
8036                      : umsg_decl)
8037                   : umsg_nonnil_decl));
8038   tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
8039   VEC(tree, gc) *parms = NULL;
8040   unsigned nparm = (method_params ? list_length (method_params) : 0);
8041
8042   /* If a prototype for the method to be called exists, then cast
8043      the sender's return type and arguments to match that of the method.
8044      Otherwise, leave sender as is.  */
8045   tree ret_type
8046     = (method_prototype
8047        ? TREE_VALUE (TREE_TYPE (method_prototype))
8048        : objc_object_type);
8049
8050   tree method_param_types = 
8051                 get_arg_type_list (method_prototype, METHOD_REF, super_flag);
8052   tree ftype = build_function_type (ret_type, method_param_types);
8053   tree sender_cast;
8054   tree method, t;
8055
8056   if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
8057     ftype = build_type_attribute_variant (ftype, 
8058                                           METHOD_TYPE_ATTRIBUTES 
8059                                           (method_prototype));
8060
8061   sender_cast = build_pointer_type (ftype);
8062
8063   lookup_object = build_c_cast (loc, rcv_p, lookup_object);
8064
8065   /* Use SAVE_EXPR to avoid evaluating the receiver twice.  */
8066   lookup_object = save_expr (lookup_object);
8067
8068   /* Param list + 2 slots for object and selector.  */
8069   parms = VEC_alloc (tree, gc, nparm + 2);
8070
8071   if (flag_next_runtime)
8072     {
8073       /* If we are returning a struct in memory, and the address
8074          of that memory location is passed as a hidden first
8075          argument, then change which messenger entry point this
8076          expr will call.  NB: Note that sender_cast remains
8077          unchanged (it already has a struct return type).  */
8078       if (!targetm.calls.struct_value_rtx (0, 0)
8079           && (TREE_CODE (ret_type) == RECORD_TYPE
8080               || TREE_CODE (ret_type) == UNION_TYPE)
8081           && targetm.calls.return_in_memory (ret_type, 0))
8082         sender = (super_flag ? umsg_super_stret_decl :
8083                 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
8084
8085       method = build_fold_addr_expr_loc (input_location, sender);
8086       /* Pass the object to the method.  */
8087       VEC_quick_push (tree, parms, lookup_object);
8088     }
8089   else
8090     {
8091       /* This is the portable (GNU) way.  */
8092       /* First, call the lookup function to get a pointer to the method,
8093          then cast the pointer, then call it with the method arguments.  */
8094       VEC(tree, gc) *tv = VEC_alloc (tree, gc, 2);
8095       VEC_quick_push (tree, tv, lookup_object);
8096       VEC_quick_push (tree, tv, selector);
8097       method = build_function_call_vec (loc, sender, tv, NULL);
8098       VEC_free (tree, gc, tv);
8099
8100       /* Pass the appropriate object to the method.  */
8101       VEC_quick_push (tree, parms, (super_flag ? self_decl : lookup_object));
8102     }
8103
8104   /* Pass the selector to the method.  */
8105   VEC_quick_push (tree, parms, selector);
8106   /* Now append the remainder of the parms.  */
8107   if (nparm)
8108     for (; method_params; method_params = TREE_CHAIN (method_params))
8109       VEC_quick_push (tree, parms, TREE_VALUE (method_params));
8110
8111   /* Build an obj_type_ref, with the correct cast for the method call.  */
8112   t = build3 (OBJ_TYPE_REF, sender_cast, method, 
8113                             lookup_object, size_zero_node);
8114   t = build_function_call_vec (loc, t, parms, NULL);\
8115   VEC_free (tree, gc, parms);
8116   return t;
8117 }
8118
8119 static void
8120 build_protocol_reference (tree p)
8121 {
8122   tree decl;
8123   const char *proto_name;
8124
8125   /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
8126
8127   proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
8128   decl = start_var_decl (objc_protocol_template, proto_name);
8129
8130   PROTOCOL_FORWARD_DECL (p) = decl;
8131 }
8132
8133 /* This function is called by the parser when (and only when) a
8134    @protocol() expression is found, in order to compile it.  */
8135 tree
8136 objc_build_protocol_expr (tree protoname)
8137 {
8138   tree expr;
8139   tree p = lookup_protocol (protoname);
8140
8141   if (!p)
8142     {
8143       error ("cannot find protocol declaration for %qE",
8144              protoname);
8145       return error_mark_node;
8146     }
8147
8148   if (!PROTOCOL_FORWARD_DECL (p))
8149     build_protocol_reference (p);
8150
8151   expr = build_unary_op (input_location, 
8152                          ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
8153
8154   /* ??? Ideally we'd build the reference with objc_protocol_type directly,
8155      if we have it, rather than converting it here.  */
8156   expr = convert (objc_protocol_type, expr);
8157
8158   /* The @protocol() expression is being compiled into a pointer to a
8159      statically allocated instance of the Protocol class.  To become
8160      usable at runtime, the 'isa' pointer of the instance need to be
8161      fixed up at runtime by the runtime library, to point to the
8162      actual 'Protocol' class.  */
8163
8164   /* For the GNU runtime, put the static Protocol instance in the list
8165      of statically allocated instances, so that we make sure that its
8166      'isa' pointer is fixed up at runtime by the GNU runtime library
8167      to point to the Protocol class (at runtime, when loading the
8168      module, the GNU runtime library loops on the statically allocated
8169      instances (as found in the defs field in objc_symtab) and fixups
8170      all the 'isa' pointers of those objects).  */
8171   if (! flag_next_runtime)
8172     {
8173       /* This type is a struct containing the fields of a Protocol
8174         object.  (Cfr. objc_protocol_type instead is the type of a pointer
8175         to such a struct).  */
8176       tree protocol_struct_type = xref_tag
8177        (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
8178       tree *chain;
8179
8180       /* Look for the list of Protocol statically allocated instances
8181         to fixup at runtime.  Create a new list to hold Protocol
8182         statically allocated instances, if the list is not found.  At
8183         present there is only another list, holding NSConstantString
8184         static instances to be fixed up at runtime.  */
8185       for (chain = &objc_static_instances;
8186            *chain && TREE_VALUE (*chain) != protocol_struct_type;
8187            chain = &TREE_CHAIN (*chain));
8188       if (!*chain)
8189         {
8190          *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
8191          add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
8192                           class_names);
8193        }
8194
8195       /* Add this statically allocated instance to the Protocol list.  */
8196       TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
8197                                          PROTOCOL_FORWARD_DECL (p),
8198                                          TREE_PURPOSE (*chain));
8199     }
8200
8201
8202   return expr;
8203 }
8204
8205 /* This function is called by the parser when a @selector() expression
8206    is found, in order to compile it.  It is only called by the parser
8207    and only to compile a @selector().  LOC is the location of the
8208    @selector.  */
8209 tree
8210 objc_build_selector_expr (location_t loc, tree selnamelist)
8211 {
8212   tree selname;
8213
8214   /* Obtain the full selector name.  */
8215   switch (TREE_CODE (selnamelist))
8216     {
8217     case IDENTIFIER_NODE:
8218       /* A unary selector.  */
8219       selname = selnamelist;
8220       break;
8221     case TREE_LIST:
8222       selname = build_keyword_selector (selnamelist);
8223       break;
8224     default:
8225       gcc_unreachable ();
8226     }
8227
8228   /* If we are required to check @selector() expressions as they
8229      are found, check that the selector has been declared.  */
8230   if (warn_undeclared_selector)
8231     {
8232       /* Look the selector up in the list of all known class and
8233          instance methods (up to this line) to check that the selector
8234          exists.  */
8235       hash hsh;
8236
8237       /* First try with instance methods.  */
8238       hsh = hash_lookup (nst_method_hash_list, selname);
8239
8240       /* If not found, try with class methods.  */
8241       if (!hsh)
8242         {
8243           hsh = hash_lookup (cls_method_hash_list, selname);
8244         }
8245
8246       /* If still not found, print out a warning.  */
8247       if (!hsh)
8248         {
8249           warning (0, "undeclared selector %qE", selname);
8250         }
8251     }
8252
8253
8254   if (flag_typed_selectors)
8255     return build_typed_selector_reference (loc, selname, 0);
8256   else
8257     return build_selector_reference (loc, selname);
8258 }
8259
8260 /* This is used to implement @encode().  See gcc/doc/objc.texi,
8261    section '@encode'.  */
8262 tree
8263 objc_build_encode_expr (tree type)
8264 {
8265   tree result;
8266   const char *string;
8267
8268   encode_type (type, obstack_object_size (&util_obstack),
8269                OBJC_ENCODE_INLINE_DEFS);
8270   obstack_1grow (&util_obstack, 0);    /* null terminate string */
8271   string = XOBFINISH (&util_obstack, const char *);
8272
8273   /* Synthesize a string that represents the encoded struct/union.  */
8274   result = my_build_string (strlen (string) + 1, string);
8275   obstack_free (&util_obstack, util_firstobj);
8276   return result;
8277 }
8278
8279 static tree
8280 build_ivar_reference (tree id)
8281 {
8282   if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8283     {
8284       /* Historically, a class method that produced objects (factory
8285          method) would assign `self' to the instance that it
8286          allocated.  This would effectively turn the class method into
8287          an instance method.  Following this assignment, the instance
8288          variables could be accessed.  That practice, while safe,
8289          violates the simple rule that a class method should not refer
8290          to an instance variable.  It's better to catch the cases
8291          where this is done unknowingly than to support the above
8292          paradigm.  */
8293       warning (0, "instance variable %qE accessed in class method",
8294                id);
8295       self_decl = convert (objc_instance_type, self_decl); /* cast */
8296     }
8297
8298   return objc_build_component_ref (build_indirect_ref (input_location,
8299                                                        self_decl, RO_ARROW),
8300                                    id);
8301 }
8302 \f
8303 /* Compute a hash value for a given method SEL_NAME.  */
8304
8305 static size_t
8306 hash_func (tree sel_name)
8307 {
8308   const unsigned char *s
8309     = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
8310   size_t h = 0;
8311
8312   while (*s)
8313     h = h * 67 + *s++ - 113;
8314   return h;
8315 }
8316
8317 static void
8318 hash_init (void)
8319 {
8320   nst_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8321   cls_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8322
8323   cls_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8324   als_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8325
8326   /* Initialize the hash table used to hold the constant string objects.  */
8327   string_htab = htab_create_ggc (31, string_hash,
8328                                    string_eq, NULL);
8329 }
8330
8331 /* This routine adds sel_name to the hash list. sel_name  is a class or alias
8332    name for the class. If alias name, then value is its underlying class.
8333    If class, the value is NULL_TREE. */
8334
8335 static void
8336 hash_class_name_enter (hash *hashlist, tree sel_name, tree value)
8337 {
8338   hash obj;
8339   int slot = hash_func (sel_name) % SIZEHASHTABLE;
8340
8341   obj = ggc_alloc_hashed_entry ();
8342   if (value != NULL_TREE)
8343     {
8344       /* Save the underlying class for the 'alias' in the hash table */
8345       attr obj_attr = ggc_alloc_hashed_attribute ();
8346       obj_attr->value = value;
8347       obj->list = obj_attr;
8348     }
8349   else
8350     obj->list = 0;
8351   obj->next = hashlist[slot];
8352   obj->key = sel_name;
8353
8354   hashlist[slot] = obj;         /* append to front */
8355
8356 }
8357
8358 /*
8359    Searches in the hash table looking for a match for class or alias name.
8360 */
8361
8362 static hash
8363 hash_class_name_lookup (hash *hashlist, tree sel_name)
8364 {
8365   hash target;
8366
8367   target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
8368
8369   while (target)
8370     {
8371       if (sel_name == target->key)
8372         return target;
8373
8374       target = target->next;
8375     }
8376   return 0;
8377 }
8378
8379 /* WARNING!!!!  hash_enter is called with a method, and will peek
8380    inside to find its selector!  But hash_lookup is given a selector
8381    directly, and looks for the selector that's inside the found
8382    entry's key (method) for comparison.  */
8383
8384 static void
8385 hash_enter (hash *hashlist, tree method)
8386 {
8387   hash obj;
8388   int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
8389
8390   obj = ggc_alloc_hashed_entry ();
8391   obj->list = 0;
8392   obj->next = hashlist[slot];
8393   obj->key = method;
8394
8395   hashlist[slot] = obj;         /* append to front */
8396 }
8397
8398 static hash
8399 hash_lookup (hash *hashlist, tree sel_name)
8400 {
8401   hash target;
8402
8403   target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
8404
8405   while (target)
8406     {
8407       if (sel_name == METHOD_SEL_NAME (target->key))
8408         return target;
8409
8410       target = target->next;
8411     }
8412   return 0;
8413 }
8414
8415 static void
8416 hash_add_attr (hash entry, tree value)
8417 {
8418   attr obj;
8419
8420   obj = ggc_alloc_hashed_attribute ();
8421   obj->next = entry->list;
8422   obj->value = value;
8423
8424   entry->list = obj;            /* append to front */
8425 }
8426 \f
8427 static tree
8428 lookup_method (tree mchain, tree method)
8429 {
8430   tree key;
8431
8432   if (TREE_CODE (method) == IDENTIFIER_NODE)
8433     key = method;
8434   else
8435     key = METHOD_SEL_NAME (method);
8436
8437   while (mchain)
8438     {
8439       if (METHOD_SEL_NAME (mchain) == key)
8440         return mchain;
8441
8442       mchain = DECL_CHAIN (mchain);
8443     }
8444   return NULL_TREE;
8445 }
8446
8447 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance
8448    method in INTERFACE, along with any categories and protocols
8449    attached thereto.  If method is not found, and the
8450    OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS, recursively examine the
8451    INTERFACE's superclass.  If OBJC_LOOKUP_CLASS is set,
8452    OBJC_LOOKUP_NO_SUPER is clear, and no suitable class method could
8453    be found in INTERFACE or any of its superclasses, look for an
8454    _instance_ method of the same name in the root class as a last
8455    resort.  This behaviour can be turned off by using
8456    OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS.
8457
8458    If a suitable method cannot be found, return NULL_TREE.  */
8459
8460 static tree
8461 lookup_method_static (tree interface, tree ident, int flags)
8462 {
8463   tree meth = NULL_TREE, root_inter = NULL_TREE;
8464   tree inter = interface;
8465   int is_class = (flags & OBJC_LOOKUP_CLASS);
8466   int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
8467   int no_instance_methods_of_root_class = (flags & OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS);
8468
8469   while (inter)
8470     {
8471       tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
8472       tree category = inter;
8473
8474       /* First, look up the method in the class itself.  */
8475       if ((meth = lookup_method (chain, ident)))
8476         return meth;
8477
8478       /* Failing that, look for the method in each category of the class.  */
8479       while ((category = CLASS_CATEGORY_LIST (category)))
8480         {
8481           chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
8482
8483           /* Check directly in each category.  */
8484           if ((meth = lookup_method (chain, ident)))
8485             return meth;
8486
8487           /* Failing that, check in each category's protocols.  */
8488           if (CLASS_PROTOCOL_LIST (category))
8489             {
8490               if ((meth = (lookup_method_in_protocol_list
8491                            (CLASS_PROTOCOL_LIST (category), ident, is_class))))
8492                 return meth;
8493             }
8494         }
8495
8496       /* If not found in categories, check in protocols of the main class.  */
8497       if (CLASS_PROTOCOL_LIST (inter))
8498         {
8499           if ((meth = (lookup_method_in_protocol_list
8500                        (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
8501             return meth;
8502         }
8503
8504       /* If we were instructed not to look in superclasses, don't.  */
8505       if (no_superclasses)
8506         return NULL_TREE;
8507
8508       /* Failing that, climb up the inheritance hierarchy.  */
8509       root_inter = inter;
8510       inter = lookup_interface (CLASS_SUPER_NAME (inter));
8511     }
8512   while (inter);
8513
8514   if (is_class && !no_instance_methods_of_root_class)
8515     {
8516       /* If no class (factory) method was found, check if an _instance_
8517          method of the same name exists in the root class.  This is what
8518          the Objective-C runtime will do.  */
8519       return lookup_method_static (root_inter, ident, 0);
8520     }
8521   else
8522     {
8523       /* If an instance method was not found, return 0.  */      
8524       return NULL_TREE;
8525     }
8526 }
8527
8528 /* Add the method to the hash list if it doesn't contain an identical
8529    method already. */
8530
8531 static void
8532 add_method_to_hash_list (hash *hash_list, tree method)
8533 {
8534   hash hsh;
8535
8536   if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
8537     {
8538       /* Install on a global chain.  */
8539       hash_enter (hash_list, method);
8540     }
8541   else
8542     {
8543       /* Check types against those; if different, add to a list.  */
8544       attr loop;
8545       int already_there = comp_proto_with_proto (method, hsh->key, 1);
8546       for (loop = hsh->list; !already_there && loop; loop = loop->next)
8547         already_there |= comp_proto_with_proto (method, loop->value, 1);
8548       if (!already_there)
8549         hash_add_attr (hsh, method);
8550     }
8551 }
8552
8553 static tree
8554 objc_add_method (tree klass, tree method, int is_class, bool is_optional)
8555 {
8556   tree mth;
8557
8558   /* @optional methods are added to protocol's OPTIONAL list */
8559   if (is_optional)
8560     {
8561       gcc_assert (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE);
8562       if (!(mth = lookup_method (is_class
8563                                 ? PROTOCOL_OPTIONAL_CLS_METHODS (klass)
8564                                 : PROTOCOL_OPTIONAL_NST_METHODS (klass), 
8565                                                                 method)))
8566         {
8567           if (is_class)
8568             {
8569               TREE_CHAIN (method) = PROTOCOL_OPTIONAL_CLS_METHODS (klass);
8570               PROTOCOL_OPTIONAL_CLS_METHODS (klass) = method;
8571             }
8572           else
8573             {
8574               TREE_CHAIN (method) = PROTOCOL_OPTIONAL_NST_METHODS (klass);
8575               PROTOCOL_OPTIONAL_NST_METHODS (klass) = method;
8576             }
8577         }
8578     }
8579   else if (!(mth = lookup_method (is_class
8580                              ? CLASS_CLS_METHODS (klass)
8581                              : CLASS_NST_METHODS (klass), method)))
8582     {
8583       /* put method on list in reverse order */
8584       if (is_class)
8585         {
8586           DECL_CHAIN (method) = CLASS_CLS_METHODS (klass);
8587           CLASS_CLS_METHODS (klass) = method;
8588         }
8589       else
8590         {
8591           DECL_CHAIN (method) = CLASS_NST_METHODS (klass);
8592           CLASS_NST_METHODS (klass) = method;
8593         }
8594     }
8595   else
8596     {
8597       /* When processing an @interface for a class or category, give hard
8598          errors on methods with identical selectors but differing argument
8599          and/or return types. We do not do this for @implementations, because
8600          C/C++ will do it for us (i.e., there will be duplicate function
8601          definition errors).  */
8602       if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
8603            || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
8604           && !comp_proto_with_proto (method, mth, 1))
8605         error ("duplicate declaration of method %<%c%E%>",
8606                 is_class ? '+' : '-',
8607                 METHOD_SEL_NAME (mth));
8608     }
8609
8610   if (is_class)
8611     add_method_to_hash_list (cls_method_hash_list, method);
8612   else
8613     {
8614       add_method_to_hash_list (nst_method_hash_list, method);
8615
8616       /* Instance methods in root classes (and categories thereof)
8617          may act as class methods as a last resort.  We also add
8618          instance methods listed in @protocol declarations to
8619          the class hash table, on the assumption that @protocols
8620          may be adopted by root classes or categories.  */
8621       if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
8622           || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
8623         klass = lookup_interface (CLASS_NAME (klass));
8624
8625       if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
8626           || !CLASS_SUPER_NAME (klass))
8627         add_method_to_hash_list (cls_method_hash_list, method);
8628     }
8629
8630   return method;
8631 }
8632
8633 static tree
8634 add_class (tree class_name, tree name)
8635 {
8636   struct interface_tuple **slot;
8637
8638   /* Put interfaces on list in reverse order.  */
8639   TREE_CHAIN (class_name) = interface_chain;
8640   interface_chain = class_name;
8641
8642   if (interface_htab == NULL)
8643     interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
8644   slot = (struct interface_tuple **)
8645     htab_find_slot_with_hash (interface_htab, name,
8646                               IDENTIFIER_HASH_VALUE (name),
8647                               INSERT);
8648   if (!*slot)
8649     {
8650       *slot = ggc_alloc_cleared_interface_tuple ();
8651       (*slot)->id = name;
8652     }
8653   (*slot)->class_name = class_name;
8654
8655   return interface_chain;
8656 }
8657
8658 static void
8659 add_category (tree klass, tree category)
8660 {
8661   /* Put categories on list in reverse order.  */
8662   tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
8663
8664   if (cat)
8665     {
8666       warning (0, "duplicate interface declaration for category %<%E(%E)%>",
8667                CLASS_NAME (klass),
8668                CLASS_SUPER_NAME (category));
8669     }
8670   else
8671     {
8672       CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
8673       CLASS_CATEGORY_LIST (klass) = category;
8674     }
8675 }
8676
8677 /* Called after parsing each instance variable declaration. Necessary to
8678    preserve typedefs and implement public/private...
8679
8680    VISIBILITY is 1 for public, 0 for protected, and 2 for private.  */
8681
8682 static tree
8683 add_instance_variable (tree klass, objc_ivar_visibility_kind visibility, 
8684                        tree field_decl)
8685 {
8686   tree field_type = TREE_TYPE (field_decl);
8687   const char *ivar_name = DECL_NAME (field_decl)
8688                           ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
8689                           : _("<unnamed>");
8690
8691 #ifdef OBJCPLUS
8692   if (TREE_CODE (field_type) == REFERENCE_TYPE)
8693     {
8694       error ("illegal reference type specified for instance variable %qs",
8695              ivar_name);
8696       /* Return class as is without adding this ivar.  */
8697       return klass;
8698     }
8699 #endif
8700
8701   if (field_type == error_mark_node || !TYPE_SIZE (field_type)
8702       || TYPE_SIZE (field_type) == error_mark_node)
8703       /* 'type[0]' is allowed, but 'type[]' is not! */
8704     {
8705       error ("instance variable %qs has unknown size", ivar_name);
8706       /* Return class as is without adding this ivar.  */
8707       return klass;
8708     }
8709
8710 #ifdef OBJCPLUS
8711   /* Check if the ivar being added has a non-POD C++ type.   If so, we will
8712      need to either (1) warn the user about it or (2) generate suitable
8713      constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
8714      methods (if '-fobjc-call-cxx-cdtors' was specified).  */
8715   if (MAYBE_CLASS_TYPE_P (field_type)
8716       && (TYPE_NEEDS_CONSTRUCTING (field_type)
8717           || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
8718           || TYPE_POLYMORPHIC_P (field_type)))
8719     {
8720       tree type_name = OBJC_TYPE_NAME (field_type);
8721
8722       if (flag_objc_call_cxx_cdtors)
8723         {
8724           /* Since the ObjC runtime will be calling the constructors and
8725              destructors for us, the only thing we can't handle is the lack
8726              of a default constructor.  */
8727           if (TYPE_NEEDS_CONSTRUCTING (field_type)
8728               && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
8729             {
8730               warning (0, "type %qE has no default constructor to call",
8731                        type_name);
8732
8733               /* If we cannot call a constructor, we should also avoid
8734                  calling the destructor, for symmetry.  */
8735               if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
8736                 warning (0, "destructor for %qE shall not be run either",
8737                          type_name);
8738             }
8739         }
8740       else
8741         {
8742           static bool warn_cxx_ivars = false;
8743
8744           if (TYPE_POLYMORPHIC_P (field_type))
8745             {
8746               /* Vtable pointers are Real Bad(tm), since Obj-C cannot
8747                  initialize them.  */
8748               error ("type %qE has virtual member functions", type_name);
8749               error ("illegal aggregate type %qE specified "
8750                      "for instance variable %qs",
8751                      type_name, ivar_name);
8752               /* Return class as is without adding this ivar.  */
8753               return klass;
8754             }
8755
8756           /* User-defined constructors and destructors are not known to Obj-C
8757              and hence will not be called.  This may or may not be a problem. */
8758           if (TYPE_NEEDS_CONSTRUCTING (field_type))
8759             warning (0, "type %qE has a user-defined constructor", type_name);
8760           if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
8761             warning (0, "type %qE has a user-defined destructor", type_name);
8762
8763           if (!warn_cxx_ivars)
8764             {
8765               warning (0, "C++ constructors and destructors will not "
8766                        "be invoked for Objective-C fields");
8767               warn_cxx_ivars = true;
8768             }
8769         }
8770     }
8771 #endif
8772
8773   /* Overload the public attribute, it is not used for FIELD_DECLs.  */
8774   switch (visibility)
8775     {
8776     case OBJC_IVAR_VIS_PROTECTED:
8777       TREE_PUBLIC (field_decl) = 0;
8778       TREE_PRIVATE (field_decl) = 0;
8779       TREE_PROTECTED (field_decl) = 1;
8780       break;
8781
8782     case OBJC_IVAR_VIS_PACKAGE:
8783     /* TODO: Implement the package variant.  */
8784     case OBJC_IVAR_VIS_PUBLIC:
8785       TREE_PUBLIC (field_decl) = 1;
8786       TREE_PRIVATE (field_decl) = 0;
8787       TREE_PROTECTED (field_decl) = 0;
8788       break;
8789
8790     case OBJC_IVAR_VIS_PRIVATE:
8791       TREE_PUBLIC (field_decl) = 0;
8792       TREE_PRIVATE (field_decl) = 1;
8793       TREE_PROTECTED (field_decl) = 0;
8794       break;
8795
8796     }
8797
8798   CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
8799
8800   return klass;
8801 }
8802 \f
8803
8804 static tree
8805 is_ivar (tree decl_chain, tree ident)
8806 {
8807   for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
8808     if (DECL_NAME (decl_chain) == ident)
8809       return decl_chain;
8810   return NULL_TREE;
8811 }
8812
8813 /* True if the ivar is private and we are not in its implementation.  */
8814
8815 static int
8816 is_private (tree decl)
8817 {
8818   return (TREE_PRIVATE (decl)
8819           && ! is_ivar (CLASS_IVARS (implementation_template),
8820                         DECL_NAME (decl)));
8821 }
8822
8823 /* We have an instance variable reference;, check to see if it is public.  */
8824
8825 int
8826 objc_is_public (tree expr, tree identifier)
8827 {
8828   tree basetype, decl;
8829
8830 #ifdef OBJCPLUS
8831   if (processing_template_decl)
8832     return 1;
8833 #endif
8834
8835   if (TREE_TYPE (expr) == error_mark_node)
8836     return 1;
8837
8838   basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
8839
8840   if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
8841     {
8842       if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
8843         {
8844           tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
8845
8846           if (!klass)
8847             {
8848               error ("cannot find interface declaration for %qE",
8849                      OBJC_TYPE_NAME (basetype));
8850               return 0;
8851             }
8852
8853           if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
8854             {
8855               if (TREE_PUBLIC (decl))
8856                 return 1;
8857
8858               /* Important difference between the Stepstone translator:
8859                  all instance variables should be public within the context
8860                  of the implementation.  */
8861               if (objc_implementation_context
8862                  && ((TREE_CODE (objc_implementation_context)
8863                       == CLASS_IMPLEMENTATION_TYPE)
8864                      || (TREE_CODE (objc_implementation_context)
8865                          == CATEGORY_IMPLEMENTATION_TYPE)))
8866                 {
8867                   tree curtype = TYPE_MAIN_VARIANT
8868                                  (CLASS_STATIC_TEMPLATE
8869                                   (implementation_template));
8870
8871                   if (basetype == curtype
8872                       || DERIVED_FROM_P (basetype, curtype))
8873                     {
8874                       int priv = is_private (decl);
8875
8876                       if (priv)
8877                         error ("instance variable %qE is declared private",
8878                                DECL_NAME (decl));
8879
8880                       return !priv;
8881                     }
8882                 }
8883
8884               /* The 2.95.2 compiler sometimes allowed C functions to access
8885                  non-@public ivars.  We will let this slide for now...  */
8886               if (!objc_method_context)
8887               {
8888                 warning (0, "instance variable %qE is %s; "
8889                          "this will be a hard error in the future",
8890                          identifier,
8891                          TREE_PRIVATE (decl) ? "@private" : "@protected");
8892                 return 1;
8893               }
8894
8895               error ("instance variable %qE is declared %s",
8896                      identifier,
8897                      TREE_PRIVATE (decl) ? "private" : "protected");
8898               return 0;
8899             }
8900         }
8901     }
8902
8903   return 1;
8904 }
8905 \f
8906 /* Make sure all methods in CHAIN (a list of method declarations from
8907    an @interface or a @protocol) are in IMPLEMENTATION (the
8908    implementation context).  This is used to check for example that
8909    all methods declared in an @interface were implemented in an
8910    @implementation.
8911
8912    Some special methods (property setters/getters) are special and if
8913    they are not found in IMPLEMENTATION, we look them up in its
8914    superclasses.  */
8915
8916 static int
8917 check_methods (tree chain, tree implementation, int mtype)
8918 {
8919   int first = 1;
8920   tree list;
8921
8922   if (mtype == (int)'+')
8923     list = CLASS_CLS_METHODS (implementation);
8924   else
8925     list = CLASS_NST_METHODS (implementation);
8926
8927   while (chain)
8928     {
8929       /* If the method is associated with a dynamic property, then it
8930          is Ok not to have the method implementation, as it will be
8931          generated dynamically at runtime.  To decide if the method is
8932          associated with a @dynamic property, we search the list of
8933          @synthesize and @dynamic for this implementation, and look
8934          for any @dynamic property with the same setter or getter name
8935          as this method.  */
8936       tree x;
8937       for (x = IMPL_PROPERTY_DECL (implementation); x; x = TREE_CHAIN (x))
8938         if (PROPERTY_DYNAMIC (x)
8939             && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
8940                 || PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
8941           break;
8942       
8943       if (x != NULL_TREE)
8944         {
8945           chain = TREE_CHAIN (chain); /* next method...  */
8946           continue;
8947         }
8948
8949       if (!lookup_method (list, chain))
8950         {
8951           /* If the method is a property setter/getter, we'll still
8952              allow it to be missing if it is implemented by
8953              'interface' or any of its superclasses.  */
8954           tree property = METHOD_PROPERTY_CONTEXT (chain);
8955           if (property)
8956             {
8957               /* Note that since this is a property getter/setter, it
8958                  is obviously an instance method.  */
8959               tree interface = NULL_TREE;
8960
8961               /* For a category, first check the main class
8962                  @interface.  */
8963               if (TREE_CODE (implementation) == CATEGORY_IMPLEMENTATION_TYPE)
8964                 {
8965                   interface = lookup_interface (CLASS_NAME (implementation));
8966
8967                   /* If the method is found in the main class, it's Ok.  */
8968                   if (lookup_method (CLASS_NST_METHODS (interface), chain))
8969                     {
8970                       chain = DECL_CHAIN (chain);
8971                       continue;               
8972                     }
8973
8974                   /* Else, get the superclass.  */
8975                   if (CLASS_SUPER_NAME (interface))
8976                     interface = lookup_interface (CLASS_SUPER_NAME (interface));
8977                   else
8978                     interface = NULL_TREE;
8979                 }
8980
8981               /* Get the superclass for classes.  */
8982               if (TREE_CODE (implementation) == CLASS_IMPLEMENTATION_TYPE)
8983                 {
8984                   if (CLASS_SUPER_NAME (implementation))
8985                     interface = lookup_interface (CLASS_SUPER_NAME (implementation));
8986                   else
8987                     interface = NULL_TREE;
8988                 }
8989
8990               /* Now, interface is the superclass, if any; go check it.  */
8991               if (interface)
8992                 {
8993                   if (lookup_method_static (interface, chain, 0))
8994                     {
8995                       chain = DECL_CHAIN (chain);
8996                       continue;
8997                     }
8998                 }
8999               /* Else, fall through - warn.  */
9000             }
9001           if (first)
9002             {
9003               switch (TREE_CODE (implementation))
9004                 {
9005                 case CLASS_IMPLEMENTATION_TYPE:
9006                   warning (0, "incomplete implementation of class %qE",
9007                            CLASS_NAME (implementation));
9008                   break;
9009                 case CATEGORY_IMPLEMENTATION_TYPE:
9010                   warning (0, "incomplete implementation of category %qE",
9011                            CLASS_SUPER_NAME (implementation));
9012                   break;
9013                 default:
9014                   gcc_unreachable ();
9015                 }
9016               first = 0;
9017             }
9018
9019           warning (0, "method definition for %<%c%E%> not found",
9020                    mtype, METHOD_SEL_NAME (chain));
9021         }
9022
9023       chain = DECL_CHAIN (chain);
9024     }
9025
9026     return first;
9027 }
9028
9029 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL.  */
9030
9031 static int
9032 conforms_to_protocol (tree klass, tree protocol)
9033 {
9034    if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
9035      {
9036        tree p = CLASS_PROTOCOL_LIST (klass);
9037        while (p && TREE_VALUE (p) != protocol)
9038          p = TREE_CHAIN (p);
9039
9040        if (!p)
9041          {
9042            tree super = (CLASS_SUPER_NAME (klass)
9043                          ? lookup_interface (CLASS_SUPER_NAME (klass))
9044                          : NULL_TREE);
9045            int tmp = super ? conforms_to_protocol (super, protocol) : 0;
9046            if (!tmp)
9047              return 0;
9048          }
9049      }
9050
9051    return 1;
9052 }
9053
9054 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
9055    CONTEXT.  This is one of two mechanisms to check protocol integrity.  */
9056
9057 static int
9058 check_methods_accessible (tree chain, tree context, int mtype)
9059 {
9060   int first = 1;
9061   tree list;
9062   tree base_context = context;
9063
9064   while (chain)
9065     {
9066       /* If the method is associated with a dynamic property, then it
9067          is Ok not to have the method implementation, as it will be
9068          generated dynamically at runtime.  Search for any @dynamic
9069          property with the same setter or getter name as this
9070          method.  TODO: Use a hashtable lookup.  */
9071       tree x;
9072       for (x = IMPL_PROPERTY_DECL (base_context); x; x = TREE_CHAIN (x))
9073         if (PROPERTY_DYNAMIC (x)
9074             && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
9075                 || PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
9076           break;
9077       
9078       if (x != NULL_TREE)
9079         {
9080           chain = TREE_CHAIN (chain); /* next method...  */
9081           continue;
9082         }       
9083
9084       context = base_context;
9085       while (context)
9086         {
9087           if (mtype == '+')
9088             list = CLASS_CLS_METHODS (context);
9089           else
9090             list = CLASS_NST_METHODS (context);
9091
9092           if (lookup_method (list, chain))
9093               break;
9094
9095           switch (TREE_CODE (context))
9096             {
9097             case CLASS_IMPLEMENTATION_TYPE:
9098             case CLASS_INTERFACE_TYPE:
9099               context = (CLASS_SUPER_NAME (context)
9100                          ? lookup_interface (CLASS_SUPER_NAME (context))
9101                          : NULL_TREE);
9102               break;
9103             case CATEGORY_IMPLEMENTATION_TYPE:
9104             case CATEGORY_INTERFACE_TYPE:
9105               context = (CLASS_NAME (context)
9106                          ? lookup_interface (CLASS_NAME (context))
9107                          : NULL_TREE);
9108               break;
9109             default:
9110               gcc_unreachable ();
9111             }
9112         }
9113
9114       if (context == NULL_TREE)
9115         {
9116           if (first)
9117             {
9118               switch (TREE_CODE (objc_implementation_context))
9119                 {
9120                 case CLASS_IMPLEMENTATION_TYPE:
9121                   warning (0, "incomplete implementation of class %qE",
9122                            CLASS_NAME (objc_implementation_context));
9123                   break;
9124                 case CATEGORY_IMPLEMENTATION_TYPE:
9125                   warning (0, "incomplete implementation of category %qE",
9126                            CLASS_SUPER_NAME (objc_implementation_context));
9127                   break;
9128                 default:
9129                   gcc_unreachable ();
9130                 }
9131               first = 0;
9132             }
9133           warning (0, "method definition for %<%c%E%> not found",
9134                    mtype, METHOD_SEL_NAME (chain));
9135         }
9136
9137       chain = TREE_CHAIN (chain); /* next method...  */
9138     }
9139   return first;
9140 }
9141
9142 /* Check whether the current interface (accessible via
9143    'objc_implementation_context') actually implements protocol P, along
9144    with any protocols that P inherits.  */
9145
9146 static void
9147 check_protocol (tree p, const char *type, tree name)
9148 {
9149   if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
9150     {
9151       int f1, f2;
9152
9153       /* Ensure that all protocols have bodies!  */
9154       if (warn_protocol)
9155         {
9156           f1 = check_methods (PROTOCOL_CLS_METHODS (p),
9157                               objc_implementation_context,
9158                               '+');
9159           f2 = check_methods (PROTOCOL_NST_METHODS (p),
9160                               objc_implementation_context,
9161                               '-');
9162         }
9163       else
9164         {
9165           f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
9166                                          objc_implementation_context,
9167                                          '+');
9168           f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
9169                                          objc_implementation_context,
9170                                          '-');
9171         }
9172
9173       if (!f1 || !f2)
9174         warning (0, "%s %qE does not fully implement the %qE protocol",
9175                  type, name, PROTOCOL_NAME (p));
9176     }
9177
9178   /* Check protocols recursively.  */
9179   if (PROTOCOL_LIST (p))
9180     {
9181       tree subs = PROTOCOL_LIST (p);
9182       tree super_class =
9183         lookup_interface (CLASS_SUPER_NAME (implementation_template));
9184
9185       while (subs)
9186         {
9187           tree sub = TREE_VALUE (subs);
9188
9189           /* If the superclass does not conform to the protocols
9190              inherited by P, then we must!  */
9191           if (!super_class || !conforms_to_protocol (super_class, sub))
9192             check_protocol (sub, type, name);
9193           subs = TREE_CHAIN (subs);
9194         }
9195     }
9196 }
9197
9198 /* Check whether the current interface (accessible via
9199    'objc_implementation_context') actually implements the protocols listed
9200    in PROTO_LIST.  */
9201
9202 static void
9203 check_protocols (tree proto_list, const char *type, tree name)
9204 {
9205   for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
9206     {
9207       tree p = TREE_VALUE (proto_list);
9208
9209       check_protocol (p, type, name);
9210     }
9211 }
9212 \f
9213 /* Make sure that the class CLASS_NAME is defined
9214    CODE says which kind of thing CLASS_NAME ought to be.
9215    It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
9216    CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.  */
9217
9218 static tree
9219 start_class (enum tree_code code, tree class_name, tree super_name,
9220              tree protocol_list)
9221 {
9222   tree klass, decl;
9223
9224 #ifdef OBJCPLUS
9225   if (current_namespace != global_namespace) {
9226     error ("Objective-C declarations may only appear in global scope");
9227   }
9228 #endif /* OBJCPLUS */
9229
9230   if (objc_implementation_context)
9231     {
9232       warning (0, "%<@end%> missing in implementation context");
9233       finish_class (objc_implementation_context);
9234       objc_ivar_chain = NULL_TREE;
9235       objc_implementation_context = NULL_TREE;
9236     }
9237
9238   klass = make_node (code);
9239   TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
9240
9241   /* Check for existence of the super class, if one was specified.  Note
9242      that we must have seen an @interface, not just a @class.  If we
9243      are looking at a @compatibility_alias, traverse it first.  */
9244   if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
9245       && super_name)
9246     {
9247       tree super = objc_is_class_name (super_name);
9248
9249       if (!super || !lookup_interface (super))
9250         {
9251           error ("cannot find interface declaration for %qE, superclass of %qE",
9252                  super ? super : super_name,
9253                  class_name);
9254           super_name = NULL_TREE;
9255         }
9256       else
9257         super_name = super;
9258     }
9259
9260   CLASS_NAME (klass) = class_name;
9261   CLASS_SUPER_NAME (klass) = super_name;
9262   CLASS_CLS_METHODS (klass) = NULL_TREE;
9263
9264   if (! objc_is_class_name (class_name)
9265       && (decl = lookup_name (class_name)))
9266     {
9267       error ("%qE redeclared as different kind of symbol",
9268              class_name);
9269       error ("previous declaration of %q+D",
9270              decl);
9271     }
9272
9273   switch (code)
9274     {
9275     case CLASS_IMPLEMENTATION_TYPE:
9276       {
9277         tree chain;
9278         
9279         for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
9280           if (TREE_VALUE (chain) == class_name)
9281             {
9282               error ("reimplementation of class %qE",
9283                      class_name);
9284               return error_mark_node;
9285             }
9286         implemented_classes = tree_cons (NULL_TREE, class_name,
9287                                          implemented_classes);
9288       }
9289
9290       /* Reset for multiple classes per file.  */
9291       method_slot = 0;
9292
9293       objc_implementation_context = klass;
9294
9295       /* Lookup the interface for this implementation.  */
9296
9297       if (!(implementation_template = lookup_interface (class_name)))
9298         {
9299           warning (0, "cannot find interface declaration for %qE",
9300                    class_name);
9301           add_class (implementation_template = objc_implementation_context,
9302                      class_name);
9303         }
9304
9305       /* If a super class has been specified in the implementation,
9306          insure it conforms to the one specified in the interface.  */
9307
9308       if (super_name
9309           && (super_name != CLASS_SUPER_NAME (implementation_template)))
9310         {
9311           tree previous_name = CLASS_SUPER_NAME (implementation_template);
9312           error ("conflicting super class name %qE",
9313                  super_name);
9314           if (previous_name)
9315             error ("previous declaration of %qE", previous_name);
9316           else
9317             error ("previous declaration");
9318         }
9319
9320       else if (! super_name)
9321         {
9322           CLASS_SUPER_NAME (objc_implementation_context)
9323             = CLASS_SUPER_NAME (implementation_template);
9324         }
9325       break;
9326
9327     case CLASS_INTERFACE_TYPE:
9328       if (lookup_interface (class_name))
9329 #ifdef OBJCPLUS
9330         error ("duplicate interface declaration for class %qE", class_name);
9331 #else
9332         warning (0, "duplicate interface declaration for class %qE", class_name);
9333 #endif
9334       else
9335         add_class (klass, class_name);
9336        
9337       if (protocol_list)
9338         CLASS_PROTOCOL_LIST (klass)
9339           = lookup_and_install_protocols (protocol_list);
9340       break;     
9341
9342     case CATEGORY_INTERFACE_TYPE:
9343       {
9344         tree class_category_is_assoc_with;
9345         
9346         /* For a category, class_name is really the name of the class that
9347            the following set of methods will be associated with. We must
9348            find the interface so that can derive the objects template.  */
9349         if (!(class_category_is_assoc_with = lookup_interface (class_name)))
9350           {
9351             error ("cannot find interface declaration for %qE",
9352                    class_name);
9353             exit (FATAL_EXIT_CODE);
9354           }
9355         else
9356           add_category (class_category_is_assoc_with, klass);
9357         
9358         if (protocol_list)
9359           CLASS_PROTOCOL_LIST (klass)
9360             = lookup_and_install_protocols (protocol_list);
9361       }
9362       break;
9363
9364     case CATEGORY_IMPLEMENTATION_TYPE:
9365       /* Reset for multiple classes per file.  */
9366       method_slot = 0;
9367
9368       objc_implementation_context = klass;
9369
9370       /* For a category, class_name is really the name of the class that
9371          the following set of methods will be associated with.  We must
9372          find the interface so that can derive the objects template.  */
9373
9374       if (!(implementation_template = lookup_interface (class_name)))
9375         {
9376           error ("cannot find interface declaration for %qE",
9377                  class_name);
9378           exit (FATAL_EXIT_CODE);
9379         }
9380       break;
9381     default:
9382       gcc_unreachable ();
9383     }
9384   return klass;
9385 }
9386
9387 static tree
9388 continue_class (tree klass)
9389 {
9390   switch (TREE_CODE (klass))
9391     {
9392     case CLASS_IMPLEMENTATION_TYPE:
9393     case CATEGORY_IMPLEMENTATION_TYPE:
9394       {
9395         struct imp_entry *imp_entry;
9396
9397         /* Check consistency of the instance variables.  */
9398
9399         if (CLASS_RAW_IVARS (klass))
9400           check_ivars (implementation_template, klass);
9401         
9402         /* code generation */
9403 #ifdef OBJCPLUS
9404         push_lang_context (lang_name_c);
9405 #endif
9406         build_private_template (implementation_template);
9407         uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
9408         objc_instance_type = build_pointer_type (uprivate_record);
9409
9410         imp_entry = ggc_alloc_imp_entry ();
9411
9412         imp_entry->next = imp_list;
9413         imp_entry->imp_context = klass;
9414         imp_entry->imp_template = implementation_template;
9415
9416         synth_forward_declarations ();
9417         imp_entry->class_decl = UOBJC_CLASS_decl;
9418         imp_entry->meta_decl = UOBJC_METACLASS_decl;
9419         imp_entry->has_cxx_cdtors = 0;
9420
9421         /* Append to front and increment count.  */
9422         imp_list = imp_entry;
9423         if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
9424           imp_count++;
9425         else
9426           cat_count++;
9427 #ifdef OBJCPLUS
9428         pop_lang_context ();
9429 #endif /* OBJCPLUS */
9430         
9431         return get_class_ivars (implementation_template, true);
9432         break;
9433       }
9434     case CLASS_INTERFACE_TYPE:
9435       {
9436 #ifdef OBJCPLUS
9437         push_lang_context (lang_name_c);
9438 #endif /* OBJCPLUS */
9439         objc_collecting_ivars = 1;
9440         build_private_template (klass);
9441         objc_collecting_ivars = 0;
9442 #ifdef OBJCPLUS
9443         pop_lang_context ();
9444 #endif /* OBJCPLUS */
9445         return NULL_TREE;
9446         break;
9447       }
9448     default:
9449       return error_mark_node;
9450     }
9451 }
9452
9453 /* This routine builds name of the setter synthesized function. */
9454 static char *
9455 objc_build_property_setter_name (tree ident)
9456 {
9457   /* TODO: Use alloca to allocate buffer of appropriate size.  */
9458   static char string[BUFSIZE];
9459   sprintf (string, "set%s:", IDENTIFIER_POINTER (ident));
9460   string[3] = TOUPPER (string[3]);
9461   return string;
9462 }
9463
9464 /* This routine prepares the declarations of the property accessor
9465    helper functions (objc_getProperty(), etc) that are used when
9466    @synthesize is used.  */
9467 static void 
9468 build_objc_property_accessor_helpers (void)
9469 {
9470   tree type;
9471
9472   /* Declare the following function:
9473      id
9474      objc_getProperty (id self, SEL _cmd, 
9475                        ptrdiff_t offset, BOOL is_atomic);  */
9476   type = build_function_type_list (objc_object_type,
9477                                    objc_object_type,
9478                                    objc_selector_type,
9479                                    ptrdiff_type_node,
9480                                    boolean_type_node,
9481                                    NULL_TREE);
9482   objc_getProperty_decl = add_builtin_function ("objc_getProperty",
9483                                                 type, 0, NOT_BUILT_IN,
9484                                                 NULL, NULL_TREE);
9485   TREE_NOTHROW (objc_getProperty_decl) = 0;
9486   
9487   /* Declare the following function:
9488      void
9489      objc_setProperty (id self, SEL _cmd, 
9490                        ptrdiff_t offset, id new_value, 
9491                        BOOL is_atomic, BOOL should_copy);  */
9492   type = build_function_type_list (void_type_node,
9493                                    objc_object_type,
9494                                    objc_selector_type,
9495                                    ptrdiff_type_node,
9496                                    objc_object_type,
9497                                    boolean_type_node,
9498                                    boolean_type_node,
9499                                    NULL_TREE);
9500   objc_setProperty_decl = add_builtin_function ("objc_setProperty",
9501                                                 type, 0, NOT_BUILT_IN,
9502                                                 NULL, NULL_TREE);
9503   TREE_NOTHROW (objc_setProperty_decl) = 0;
9504
9505   /* This is the type of all of the following functions
9506      (objc_copyStruct(), objc_getPropertyStruct() and
9507      objc_setPropertyStruct()).  */
9508   type = build_function_type_list (void_type_node,
9509                                    ptr_type_node,
9510                                    const_ptr_type_node,
9511                                    ptrdiff_type_node,       
9512                                    boolean_type_node,
9513                                    boolean_type_node,
9514                                    NULL_TREE);
9515
9516   if (flag_next_runtime)
9517     {
9518       /* Declare the following function:
9519          void
9520          objc_copyStruct (void *destination, const void *source, 
9521                           ptrdiff_t size, BOOL is_atomic, BOOL has_strong);  */
9522       objc_copyStruct_decl = add_builtin_function ("objc_copyStruct",
9523                                                    type, 0, NOT_BUILT_IN,
9524                                                    NULL, NULL_TREE);
9525       TREE_NOTHROW (objc_copyStruct_decl) = 0;
9526       objc_getPropertyStruct_decl = NULL_TREE;
9527       objc_setPropertyStruct_decl = NULL_TREE;
9528     }
9529   else
9530     {
9531       objc_copyStruct_decl = NULL_TREE;
9532
9533       /* Declare the following function:
9534          void
9535          objc_getPropertyStruct (void *destination, const void *source, 
9536                                  ptrdiff_t size, BOOL is_atomic, BOOL has_strong);  */
9537       objc_getPropertyStruct_decl = add_builtin_function ("objc_getPropertyStruct",
9538                                                           type, 0, NOT_BUILT_IN,
9539                                                           NULL, NULL_TREE);
9540       TREE_NOTHROW (objc_getPropertyStruct_decl) = 0;
9541       /* Declare the following function:
9542          void
9543          objc_setPropertyStruct (void *destination, const void *source, 
9544                                  ptrdiff_t size, BOOL is_atomic, BOOL has_strong);  */
9545       objc_setPropertyStruct_decl = add_builtin_function ("objc_setPropertyStruct",
9546                                                           type, 0, NOT_BUILT_IN,
9547                                                           NULL, NULL_TREE);
9548       TREE_NOTHROW (objc_setPropertyStruct_decl) = 0;
9549     }
9550 }
9551
9552 /* This looks up an ivar in a class (including superclasses).  */
9553 static tree
9554 lookup_ivar (tree interface, tree instance_variable_name)
9555 {
9556   while (interface)
9557     {
9558       tree decl_chain;
9559       
9560       for (decl_chain = CLASS_IVARS (interface); decl_chain; decl_chain = DECL_CHAIN (decl_chain))
9561         if (DECL_NAME (decl_chain) == instance_variable_name)
9562           return decl_chain;
9563       
9564       /* Not found.  Search superclass if any.  */
9565       if (CLASS_SUPER_NAME (interface))
9566         interface = lookup_interface (CLASS_SUPER_NAME (interface));
9567     }
9568   
9569   return NULL_TREE;
9570 }
9571
9572 /* This routine synthesizes a 'getter' method.  This is only called
9573    for @synthesize properties.  */
9574 static void
9575 objc_synthesize_getter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
9576 {
9577   location_t location = DECL_SOURCE_LOCATION (property);
9578   tree fn, decl;
9579   tree body;
9580   tree ret_val;
9581
9582   /* If user has implemented a getter with same name then do nothing.  */
9583   if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
9584                      PROPERTY_GETTER_NAME (property)))
9585     return;
9586
9587   /* Find declaration of the property getter in the interface (or
9588      superclass, or protocol). There must be one.  */
9589   decl = lookup_method_static (klass, PROPERTY_GETTER_NAME (property), 0);
9590
9591   /* If one not declared in the interface, this condition has already
9592      been reported as user error (because property was not declared in
9593      the interface).  */
9594   if (!decl)
9595     return;
9596
9597   /* Adapt the 'decl'.  Use the source location of the @synthesize
9598      statement for error messages.  */
9599   decl = copy_node (decl);
9600   DECL_SOURCE_LOCATION (decl) = location;
9601
9602   objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE);
9603   body = c_begin_compound_stmt (true);
9604
9605   /* Now we need to decide how we build the getter.  There are three
9606      cases:
9607
9608      for 'copy' or 'retain' properties we need to use the
9609      objc_getProperty() accessor helper which knows about retain and
9610      copy.  It supports both 'nonatomic' and 'atomic' access.
9611
9612      for 'nonatomic, assign' properties we can access the instance
9613      variable directly.  'nonatomic' means we don't have to use locks,
9614      and 'assign' means we don't have to worry about retain or copy.
9615      If you combine the two, it means we can just access the instance
9616      variable directly.
9617
9618      for 'atomic, assign' properties we use objc_copyStruct() (for the
9619      next runtime) or objc_getPropertyStruct() (for the GNU runtime).  */
9620   switch (PROPERTY_ASSIGN_SEMANTICS (property))
9621     {
9622     case OBJC_PROPERTY_RETAIN:
9623     case OBJC_PROPERTY_COPY:
9624       {
9625         /* We build "return objc_getProperty (self, _cmd, offset, is_atomic);"  */
9626         tree cmd, ivar, offset, is_atomic;
9627         cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
9628
9629         /* Find the ivar to compute the offset.  */
9630         ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
9631         if (!ivar || is_private (ivar))
9632           {
9633             /* This should never happen.  */
9634             error_at (location,
9635                       "can not find instance variable associated with property");
9636             ret_val = error_mark_node;
9637             break;
9638           }
9639         offset = byte_position (ivar);
9640
9641         if (PROPERTY_NONATOMIC (property))
9642           is_atomic = boolean_false_node;
9643         else
9644           is_atomic = boolean_true_node;
9645
9646         ret_val = build_function_call
9647           (location,
9648            /* Function prototype.  */
9649            objc_getProperty_decl,
9650            /* Parameters.  */
9651            tree_cons    /* self */
9652            (NULL_TREE, self_decl,
9653             tree_cons   /* _cmd */
9654             (NULL_TREE, cmd,
9655              tree_cons  /* offset */
9656              (NULL_TREE, offset,
9657               tree_cons /* is_atomic */
9658               (NULL_TREE, is_atomic, NULL_TREE)))));
9659       }
9660       break;
9661     case OBJC_PROPERTY_ASSIGN:    
9662       if (PROPERTY_NONATOMIC (property))
9663         {
9664           /* We build "return self->PROPERTY_IVAR_NAME;"  */
9665           ret_val = objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property));
9666           break;
9667         }
9668       else
9669         {
9670           /* We build
9671                <property type> __objc_property_temp;
9672                objc_getPropertyStruct (&__objc_property_temp,
9673                                        &(self->PROPERTY_IVAR_NAME),
9674                                        sizeof (type of self->PROPERTY_IVAR_NAME),
9675                                        is_atomic,
9676                                        false)
9677                return __objc_property_temp;
9678
9679              For the NeXT runtime, we need to use objc_copyStruct
9680              instead of objc_getPropertyStruct.  */
9681           tree objc_property_temp_decl, function_decl, function_call;
9682           tree size_of, is_atomic;
9683
9684           objc_property_temp_decl = objc_create_temporary_var (TREE_TYPE (property), "__objc_property_temp");
9685           DECL_SOURCE_LOCATION (objc_property_temp_decl) = location;
9686           objc_property_temp_decl = lang_hooks.decls.pushdecl (objc_property_temp_decl);
9687
9688           /* sizeof (ivar type).  Since the ivar and the property have
9689              the same type, there is no need to lookup the ivar.  */
9690           size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
9691                                               true /* is_sizeof */,
9692                                               false /* complain */);
9693           
9694           if (PROPERTY_NONATOMIC (property))
9695             is_atomic = boolean_false_node;
9696           else
9697             is_atomic = boolean_true_node;
9698           
9699           if (flag_next_runtime)
9700             function_decl = objc_copyStruct_decl;
9701           else
9702             function_decl = objc_getPropertyStruct_decl;
9703
9704           function_call = build_function_call
9705             (location,
9706              /* Function prototype.  */
9707              function_decl,
9708              /* Parameters.  */
9709              tree_cons /* &__objc_property_temp_decl */
9710              /* Warning: note that using build_fold_addr_expr_loc()
9711                 here causes invalid code to be generated.  */
9712              (NULL_TREE, build_unary_op (location, ADDR_EXPR, objc_property_temp_decl, 0),
9713               tree_cons /* &(self->PROPERTY_IVAR_NAME); */
9714               (NULL_TREE, build_fold_addr_expr_loc (location, 
9715                                                     objc_lookup_ivar 
9716                                                     (NULL_TREE, PROPERTY_IVAR_NAME (property))),
9717                tree_cons /* sizeof (PROPERTY_IVAR) */
9718                (NULL_TREE, size_of,
9719                 tree_cons /* is_atomic */
9720                 (NULL_TREE, is_atomic,
9721                  /* TODO: This is currently ignored by the GNU
9722                     runtime, but what about the next one ? */
9723                  tree_cons /* has_strong */
9724                  (NULL_TREE, boolean_true_node, NULL_TREE))))));
9725
9726           add_stmt (function_call);
9727
9728           ret_val = objc_property_temp_decl;
9729         }
9730       break;
9731     default:
9732       gcc_unreachable ();
9733     }
9734
9735   gcc_assert (ret_val);
9736
9737 #ifdef OBJCPLUS
9738   finish_return_stmt (ret_val);
9739 #else
9740   c_finish_return (location, ret_val, NULL_TREE);
9741 #endif
9742
9743   add_stmt (c_end_compound_stmt (location, body, true));
9744   fn = current_function_decl;
9745 #ifdef OBJCPLUS
9746   finish_function ();
9747 #endif
9748   objc_finish_method_definition (fn);
9749 }
9750
9751 /* This routine synthesizes a 'setter' method.  */
9752
9753 static void
9754 objc_synthesize_setter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
9755 {
9756   location_t location = DECL_SOURCE_LOCATION (property);
9757   tree fn, decl;
9758   tree body;
9759   tree new_value, statement;
9760
9761   /* If user has implemented a setter with same name then do nothing.  */
9762   if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
9763                      PROPERTY_SETTER_NAME (property)))
9764     return;
9765
9766   /* Find declaration of the property setter in the interface (or
9767      superclass, or protocol). There must be one.  */
9768   decl = lookup_method_static (klass, PROPERTY_SETTER_NAME (property), 0);
9769
9770   /* If one not declared in the interface, this condition has already
9771      been reported as user error (because property was not declared in
9772      the interface).  */
9773   if (!decl)
9774     return;
9775
9776   /* Adapt the 'decl'.  Use the source location of the @synthesize
9777      statement for error messages.  */
9778   decl = copy_node (decl);
9779   DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (property);
9780
9781   objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE);
9782
9783   body = c_begin_compound_stmt (true);
9784
9785   /* The 'new_value' is the only argument to the method, which is the
9786      3rd argument of the function, after self and _cmd.  We use twice
9787      TREE_CHAIN to move forward two arguments.  */
9788   new_value = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)));
9789
9790   /* This would presumably happen if the user has specified a
9791      prototype for the setter that does not have an argument!  */
9792   if (new_value == NULL_TREE)
9793     {
9794       /* TODO: This should be caught much earlier than this.  */
9795       error_at (DECL_SOURCE_LOCATION (decl), "invalid setter, it must have one argument");
9796       /* Try to recover somehow.  */
9797       new_value = error_mark_node;
9798     }
9799
9800   /* Now we need to decide how we build the setter.  There are three
9801      cases:
9802
9803      for 'copy' or 'retain' properties we need to use the
9804      objc_setProperty() accessor helper which knows about retain and
9805      copy.  It supports both 'nonatomic' and 'atomic' access.
9806
9807      for 'nonatomic, assign' properties we can access the instance
9808      variable directly.  'nonatomic' means we don't have to use locks,
9809      and 'assign' means we don't have to worry about retain or copy.
9810      If you combine the two, it means we can just access the instance
9811      variable directly.
9812
9813      for 'atomic, assign' properties we use objc_copyStruct() (for the
9814      next runtime) or objc_setPropertyStruct() (for the GNU runtime).  */
9815   switch (PROPERTY_ASSIGN_SEMANTICS (property))
9816     {
9817     case OBJC_PROPERTY_RETAIN:
9818     case OBJC_PROPERTY_COPY:
9819       {
9820         /* We build "objc_setProperty (self, _cmd, new_value, offset, is_atomic, should_copy);"  */
9821         tree cmd, ivar, offset, is_atomic, should_copy;
9822         cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
9823
9824         /* Find the ivar to compute the offset.  */
9825         ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
9826         if (!ivar || is_private (ivar))
9827           {
9828             error_at (location,
9829                       "can not find instance variable associated with property");
9830             statement = error_mark_node;
9831             break;
9832           }
9833         offset = byte_position (ivar);
9834
9835         if (PROPERTY_NONATOMIC (property))
9836           is_atomic = boolean_false_node;
9837         else
9838           is_atomic = boolean_true_node;
9839         
9840         if (PROPERTY_ASSIGN_SEMANTICS (property) == OBJC_PROPERTY_COPY)
9841           should_copy = boolean_true_node;
9842         else
9843           should_copy = boolean_false_node;
9844
9845         statement = build_function_call
9846           (location,
9847            /* Function prototype.  */
9848            objc_setProperty_decl,
9849            /* Parameters.  */
9850            tree_cons    /* self */
9851            (NULL_TREE, self_decl,
9852             tree_cons   /* _cmd */
9853             (NULL_TREE, cmd,
9854              tree_cons  /* offset */
9855              (NULL_TREE, offset,
9856               tree_cons /* new_value */
9857               (NULL_TREE, new_value,
9858                tree_cons /* is_atomic */
9859                (NULL_TREE, is_atomic, 
9860                 tree_cons /* should_copy */
9861                 (NULL_TREE, should_copy, NULL_TREE)))))));
9862       }
9863       break;
9864     case OBJC_PROPERTY_ASSIGN:    
9865       if (PROPERTY_NONATOMIC (property))
9866         {
9867           /* We build "self->PROPERTY_IVAR_NAME = new_value;"  */
9868           statement = build_modify_expr
9869             (location,
9870              objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property)),
9871              NULL_TREE, NOP_EXPR, 
9872              location, new_value, NULL_TREE);
9873           break;
9874         }
9875       else
9876         {
9877           /* We build
9878                objc_setPropertyStruct (&(self->PROPERTY_IVAR_NAME),
9879                                        &new_value,
9880                                        sizeof (type of self->PROPERTY_IVAR_NAME),
9881                                        is_atomic,
9882                                        false)
9883
9884              For the NeXT runtime, we need to use objc_copyStruct
9885              instead of objc_getPropertyStruct.  */
9886           tree function_decl, size_of, is_atomic;
9887
9888           /* sizeof (ivar type).  Since the ivar and the property have
9889              the same type, there is no need to lookup the ivar.  */
9890           size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
9891                                               true /* is_sizeof */,
9892                                               false /* complain */);
9893           
9894           if (PROPERTY_NONATOMIC (property))
9895             is_atomic = boolean_false_node;
9896           else
9897             is_atomic = boolean_true_node;
9898           
9899           if (flag_next_runtime)
9900             function_decl = objc_copyStruct_decl;
9901           else
9902             function_decl = objc_setPropertyStruct_decl;
9903
9904           statement = build_function_call 
9905             (location,
9906              /* Function prototype.  */
9907              function_decl,
9908              /* Parameters.  */
9909              tree_cons /* &(self->PROPERTY_IVAR_NAME); */
9910              (NULL_TREE, build_fold_addr_expr_loc (location, 
9911                                                    objc_lookup_ivar 
9912                                                    (NULL_TREE, PROPERTY_IVAR_NAME (property))),
9913               tree_cons /* &new_value */
9914               (NULL_TREE, build_fold_addr_expr_loc (location, new_value),
9915                tree_cons /* sizeof (PROPERTY_IVAR) */
9916                (NULL_TREE, size_of,
9917                 tree_cons /* is_atomic */
9918                 (NULL_TREE, is_atomic,
9919                  /* TODO: This is currently ignored by the GNU
9920                     runtime, but what about the next one ? */
9921                  tree_cons /* has_strong */
9922                  (NULL_TREE, boolean_true_node, NULL_TREE))))));
9923         }
9924       break;
9925     default:
9926       gcc_unreachable ();
9927     }
9928   gcc_assert (statement);
9929
9930   add_stmt (statement);  
9931   add_stmt (c_end_compound_stmt (location, body, true));
9932   fn = current_function_decl;
9933 #ifdef OBJCPLUS
9934   finish_function ();
9935 #endif
9936   objc_finish_method_definition (fn);
9937 }
9938
9939 /* This function is a sub-routine of objc_add_synthesize_declaration.
9940    It is called for each property to synthesize once we have
9941    determined that the context is Ok.  */
9942 static void
9943 objc_add_synthesize_declaration_for_property (location_t location, tree interface,
9944                                               tree property_name, tree ivar_name)
9945 {
9946   /* Find the @property declaration.  */
9947   tree property;
9948   tree x;
9949
9950   /* Check that synthesize or dynamic has not already been used for
9951      the same property.  */
9952   for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
9953     if (PROPERTY_NAME (property) == property_name)
9954       {
9955         location_t original_location = DECL_SOURCE_LOCATION (property);
9956         
9957         if (PROPERTY_DYNAMIC (property))
9958           error_at (location, "property %qs already specified in %<@dynamic%>", 
9959                     IDENTIFIER_POINTER (property_name));
9960         else
9961           error_at (location, "property %qs already specified in %<@synthesize%>", 
9962                     IDENTIFIER_POINTER (property_name));
9963         
9964         if (original_location != UNKNOWN_LOCATION)
9965           inform (original_location, "originally specified here");
9966         return;
9967       }
9968
9969   /* Check that the property is declared in the interface.  It could
9970      also be declared in a superclass or protocol.  */
9971   property = lookup_property (interface, property_name);
9972
9973   if (!property)
9974     {
9975       error_at (location, "no declaration of property %qs found in the interface", 
9976                 IDENTIFIER_POINTER (property_name));
9977       return;
9978     }
9979   else
9980     {
9981       /* We have to copy the property, because we want to chain it to
9982          the implementation context, and we want to store the source
9983          location of the @synthesize, not of the original
9984          @property.  */
9985       property = copy_node (property);
9986       DECL_SOURCE_LOCATION (property) = location;
9987     }
9988
9989   /* Determine PROPERTY_IVAR_NAME.  */
9990   if (ivar_name == NULL_TREE)
9991     ivar_name = property_name;
9992
9993   /* Check that the instance variable exists.  You can only use an
9994      instance variable from the same class, not one from the
9995      superclass (this makes sense as it allows us to check that an
9996      instance variable is only used in one synthesized property).  */
9997   {
9998     tree ivar = is_ivar (CLASS_IVARS (interface), ivar_name);
9999     tree type_of_ivar;
10000     if (!ivar)
10001       {
10002         error_at (location, "ivar %qs used by %<@synthesize%> declaration must be an existing ivar", 
10003                   IDENTIFIER_POINTER (property_name));
10004         return;
10005       }
10006
10007     if (DECL_BIT_FIELD_TYPE (ivar))
10008       type_of_ivar = DECL_BIT_FIELD_TYPE (ivar);
10009     else
10010       type_of_ivar = TREE_TYPE (ivar);
10011     
10012     /* If the instance variable has a different C type, we throw an error ...  */
10013     if (!comptypes (TREE_TYPE (property), type_of_ivar)
10014         /* ... unless the property is readonly, in which case we allow
10015            the instance variable to be more specialized (this means we
10016            can generate the getter all right and it works).  */
10017         && (!PROPERTY_READONLY (property)
10018             || !objc_compare_types (TREE_TYPE (property),
10019                                     type_of_ivar, -5, NULL_TREE)))
10020       {
10021         location_t original_location = DECL_SOURCE_LOCATION (ivar);
10022         
10023         error_at (location, "property %qs is using instance variable %qs of incompatible type",
10024                   IDENTIFIER_POINTER (property_name),
10025                   IDENTIFIER_POINTER (ivar_name));
10026         
10027         if (original_location != UNKNOWN_LOCATION)
10028           inform (original_location, "originally specified here");
10029       }
10030
10031     /* If the instance variable is a bitfield, the property must be
10032        'assign', 'nonatomic' because the runtime getter/setter helper
10033        do not work with bitfield instance variables.  */
10034     if (DECL_BIT_FIELD_TYPE (ivar))
10035       {
10036         /* If there is an error, we return and not generate any
10037            getter/setter because trying to set up the runtime
10038            getter/setter helper calls with bitfields is at high risk
10039            of ICE.  */
10040
10041         if (PROPERTY_ASSIGN_SEMANTICS (property) != OBJC_PROPERTY_ASSIGN)
10042           {
10043             location_t original_location = DECL_SOURCE_LOCATION (ivar);
10044             
10045             error_at (location, "'assign' property %qs is using bit-field instance variable %qs",
10046                       IDENTIFIER_POINTER (property_name),
10047                       IDENTIFIER_POINTER (ivar_name));
10048         
10049             if (original_location != UNKNOWN_LOCATION)
10050               inform (original_location, "originally specified here");
10051             return;
10052           }
10053
10054         if (!PROPERTY_NONATOMIC (property))
10055           {
10056             location_t original_location = DECL_SOURCE_LOCATION (ivar);
10057             
10058             error_at (location, "'atomic' property %qs is using bit-field instance variable %qs",
10059                       IDENTIFIER_POINTER (property_name),
10060                       IDENTIFIER_POINTER (ivar_name));
10061             
10062             if (original_location != UNKNOWN_LOCATION)
10063               inform (original_location, "originally specified here");
10064             return;
10065           }
10066       }
10067   }
10068
10069   /* Check that no other property is using the same instance
10070      variable.  */
10071   for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
10072     if (PROPERTY_IVAR_NAME (x) == ivar_name)
10073       {
10074         location_t original_location = DECL_SOURCE_LOCATION (x);
10075         
10076         error_at (location, "property %qs is using the same instance variable as property %qs",
10077                   IDENTIFIER_POINTER (property_name),
10078                   IDENTIFIER_POINTER (PROPERTY_NAME (x)));
10079         
10080         if (original_location != UNKNOWN_LOCATION)
10081           inform (original_location, "originally specified here");
10082         
10083         /* We keep going on.  This won't cause the compiler to fail;
10084            the failure would most likely be at runtime.  */
10085       }
10086
10087   /* Note that a @synthesize (and only a @synthesize) always sets
10088      PROPERTY_IVAR_NAME to a non-NULL_TREE.  You can recognize a
10089      @synthesize by that.  */
10090   PROPERTY_IVAR_NAME (property) = ivar_name;
10091   
10092   /* PROPERTY_SETTER_NAME and PROPERTY_GETTER_NAME are copied from the
10093      original declaration; they are always set (with the exception of
10094      PROPERTY_SETTER_NAME not being set if PROPERTY_READONLY == 1).  */
10095
10096   /* Add the property to the list of properties for current implementation. */
10097   TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
10098   IMPL_PROPERTY_DECL (objc_implementation_context) = property;
10099
10100   /* Note how we don't actually synthesize the getter/setter here; it
10101      would be very natural, but we may miss the fact that the user has
10102      implemented his own getter/setter later on in the @implementation
10103      (in which case we shouldn't generate getter/setter).  We wait
10104      until we have parsed it all before generating the code.  */
10105 }
10106
10107 /* This function is called by the parser after a @synthesize
10108    expression is parsed.  'location' is the location of the
10109    @synthesize expression, and 'property_and_ivar_list' is a chained
10110    list of the property and ivar names.  */
10111 void
10112 objc_add_synthesize_declaration (location_t location, tree property_and_ivar_list)
10113 {
10114   tree interface, chain;
10115
10116   if (flag_objc1_only)
10117     error_at (input_location, "%<@synthesize%> is not available in Objective-C 1.0");
10118
10119   if (property_and_ivar_list == error_mark_node)
10120     return;
10121
10122   if (!objc_implementation_context)
10123     {
10124       /* We can get here only in Objective-C; the Objective-C++ parser
10125          detects the problem while parsing, outputs the error
10126          "misplaced '@synthesize' Objective-C++ construct" and skips
10127          the declaration.  */
10128       error_at (location, "%<@synthesize%> not in @implementation context");
10129       return;
10130     }
10131
10132   if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
10133     {
10134       error_at (location, "%<@synthesize%> can not be used in categories");
10135       return;
10136     }
10137
10138   interface = lookup_interface (CLASS_NAME (objc_implementation_context));
10139   if (!interface)
10140     {
10141       /* I can't see how this could happen, but it is good as a safety check.  */
10142       error_at (location, 
10143                 "%<@synthesize%> requires the @interface of the class to be available");
10144       return;
10145     }
10146
10147   /* Now, iterate over the properties and do each of them.  */
10148   for (chain = property_and_ivar_list; chain; chain = TREE_CHAIN (chain))
10149     {
10150       objc_add_synthesize_declaration_for_property (location, interface, TREE_VALUE (chain), 
10151                                                     TREE_PURPOSE (chain));
10152     }
10153 }
10154
10155 /* This function is a sub-routine of objc_add_dynamic_declaration.  It
10156    is called for each property to mark as dynamic once we have
10157    determined that the context is Ok.  */
10158 static void
10159 objc_add_dynamic_declaration_for_property (location_t location, tree interface,
10160                                            tree property_name)
10161 {
10162   /* Find the @property declaration.  */
10163   tree property;
10164
10165   /* Check that synthesize or dynamic has not already been used for
10166      the same property.  */
10167   for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
10168     if (PROPERTY_NAME (property) == property_name)
10169       {
10170         location_t original_location = DECL_SOURCE_LOCATION (property);
10171         
10172         if (PROPERTY_DYNAMIC (property))
10173           error_at (location, "property %qs already specified in %<@dynamic%>", 
10174                     IDENTIFIER_POINTER (property_name));
10175         else
10176           error_at (location, "property %qs already specified in %<@synthesize%>",
10177                     IDENTIFIER_POINTER (property_name));
10178
10179         if (original_location != UNKNOWN_LOCATION)
10180           inform (original_location, "originally specified here");
10181         return;
10182       }
10183
10184   /* Check that the property is declared in the interface.  It could
10185      also be declared in a superclass or protocol.  */
10186   property = lookup_property (interface, property_name);
10187
10188   if (!property)
10189     {
10190       error_at (location, "no declaration of property %qs found in the interface",
10191                 IDENTIFIER_POINTER (property_name));
10192       return;
10193     }
10194   else
10195     {
10196       /* We have to copy the property, because we want to chain it to
10197          the implementation context, and we want to store the source
10198          location of the @synthesize, not of the original
10199          @property.  */
10200       property = copy_node (property);
10201       DECL_SOURCE_LOCATION (property) = location;
10202     }
10203
10204   /* Note that a @dynamic (and only a @dynamic) always sets
10205      PROPERTY_DYNAMIC to 1.  You can recognize a @dynamic by that.
10206      (actually, as explained above, PROPERTY_DECL generated by
10207      @property and associated with a @dynamic property are also marked
10208      as PROPERTY_DYNAMIC).  */
10209   PROPERTY_DYNAMIC (property) = 1;
10210
10211   /* Add the property to the list of properties for current implementation. */
10212   TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
10213   IMPL_PROPERTY_DECL (objc_implementation_context) = property;
10214 }
10215
10216 /* This function is called by the parser after a @dynamic expression
10217    is parsed.  'location' is the location of the @dynamic expression,
10218    and 'property_list' is a chained list of all the property
10219    names.  */
10220 void
10221 objc_add_dynamic_declaration (location_t location, tree property_list)
10222 {
10223   tree interface, chain;
10224
10225   if (flag_objc1_only)
10226     error_at (input_location, "%<@dynamic%> is not available in Objective-C 1.0");
10227
10228   if (property_list == error_mark_node)
10229     return;
10230
10231   if (!objc_implementation_context)
10232     {
10233       /* We can get here only in Objective-C; the Objective-C++ parser
10234          detects the problem while parsing, outputs the error
10235          "misplaced '@dynamic' Objective-C++ construct" and skips the
10236          declaration.  */
10237       error_at (location, "%<@dynamic%> not in @implementation context");
10238       return;
10239     }
10240
10241   /* @dynamic is allowed in categories.  */
10242   switch (TREE_CODE (objc_implementation_context))
10243     {
10244     case CLASS_IMPLEMENTATION_TYPE:
10245       interface = lookup_interface (CLASS_NAME (objc_implementation_context));
10246       break;
10247     case CATEGORY_IMPLEMENTATION_TYPE:
10248       interface = lookup_category (implementation_template, 
10249                                    CLASS_SUPER_NAME (objc_implementation_context));
10250       break;
10251     default:
10252       gcc_unreachable ();
10253     }
10254
10255   if (!interface)
10256     {
10257       /* I can't see how this could happen, but it is good as a safety check.  */
10258       error_at (location,
10259                 "%<@dynamic%> requires the @interface of the class to be available");
10260       return;
10261     }
10262
10263   /* Now, iterate over the properties and do each of them.  */
10264   for (chain = property_list; chain; chain = TREE_CHAIN (chain))
10265     {
10266       objc_add_dynamic_declaration_for_property (location, interface, TREE_VALUE (chain));
10267     }
10268 }
10269
10270 /* Main routine to generate code/data for all the property information for 
10271    current implementation (class or category). CLASS is the interface where
10272    ivars are declared.  CLASS_METHODS is where methods are found which
10273    could be a class or a category depending on whether we are implementing
10274    property of a class or a category.  */
10275
10276 static void
10277 objc_gen_property_data (tree klass, tree class_methods)
10278 {
10279   tree x;
10280
10281   for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
10282     {
10283       /* @dynamic property - nothing to check or synthesize.  */
10284       if (PROPERTY_DYNAMIC (x))
10285         continue;
10286       
10287       /* @synthesize property - need to synthesize the accessors.  */
10288       if (PROPERTY_IVAR_NAME (x))
10289         {
10290           objc_synthesize_getter (klass, class_methods, x);
10291           
10292           if (PROPERTY_READONLY (x) == 0)
10293             objc_synthesize_setter (klass, class_methods, x);
10294
10295           continue;
10296         }
10297
10298       gcc_unreachable ();
10299     }
10300 }
10301
10302 /* This is called once we see the "@end" in an interface/implementation.  */
10303
10304 static void
10305 finish_class (tree klass)
10306 {
10307   switch (TREE_CODE (klass))
10308     {
10309     case CLASS_IMPLEMENTATION_TYPE:
10310       {
10311         /* All code generation is done in finish_objc.  */
10312         
10313         /* Generate what needed for property; setters, getters, etc. */
10314         objc_gen_property_data (implementation_template, implementation_template);
10315
10316         if (implementation_template != objc_implementation_context)
10317           {
10318             /* Ensure that all method listed in the interface contain bodies.  */
10319             check_methods (CLASS_CLS_METHODS (implementation_template),
10320                            objc_implementation_context, '+');
10321             check_methods (CLASS_NST_METHODS (implementation_template),
10322                            objc_implementation_context, '-');
10323
10324             if (CLASS_PROTOCOL_LIST (implementation_template))
10325               check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
10326                                "class",
10327                                CLASS_NAME (objc_implementation_context));
10328           }
10329         break;
10330       }
10331     case CATEGORY_IMPLEMENTATION_TYPE:
10332       {
10333         tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
10334         
10335         if (category)
10336           {
10337             /* Generate what needed for property; setters, getters, etc. */
10338             objc_gen_property_data (implementation_template, category);
10339
10340             /* Ensure all method listed in the interface contain bodies.  */
10341             check_methods (CLASS_CLS_METHODS (category),
10342                            objc_implementation_context, '+');
10343             check_methods (CLASS_NST_METHODS (category),
10344                            objc_implementation_context, '-');
10345             
10346             if (CLASS_PROTOCOL_LIST (category))
10347               check_protocols (CLASS_PROTOCOL_LIST (category),
10348                                "category",
10349                                CLASS_SUPER_NAME (objc_implementation_context));
10350           }
10351         break;
10352       }
10353     case CLASS_INTERFACE_TYPE:
10354     case CATEGORY_INTERFACE_TYPE:
10355     case PROTOCOL_INTERFACE_TYPE:
10356       {
10357         /* Process properties of the class. */
10358         tree x;
10359         for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
10360           {
10361             /* Now we check that the appropriate getter is declared,
10362                and if not, we declare one ourselves.  */
10363             tree getter_decl = lookup_method (CLASS_NST_METHODS (klass),
10364                                               PROPERTY_GETTER_NAME (x));
10365             
10366             if (getter_decl)
10367               {
10368                 /* TODO: Check that the declaration is consistent with the property.  */
10369                 ;
10370               }
10371             else
10372               {
10373                 /* Generate an instance method declaration for the
10374                    getter; for example "- (id) name;".  In general it
10375                    will be of the form
10376                    -(type)property_getter_name;  */
10377                 tree rettype = build_tree_list (NULL_TREE, TREE_TYPE (x));
10378                 getter_decl = build_method_decl (INSTANCE_METHOD_DECL, 
10379                                                  rettype, PROPERTY_GETTER_NAME (x), 
10380                                                  NULL_TREE, false);
10381                 objc_add_method (objc_interface_context, getter_decl, false, false);
10382                 METHOD_PROPERTY_CONTEXT (getter_decl) = x;
10383               }
10384
10385             if (PROPERTY_READONLY (x) == 0)
10386               {
10387                 /* Now we check that the appropriate setter is declared,
10388                    and if not, we declare on ourselves.  */
10389                 tree setter_decl = lookup_method (CLASS_NST_METHODS (klass), 
10390                                                   PROPERTY_SETTER_NAME (x));
10391                 
10392                 if (setter_decl)
10393                   {
10394                     /* TODO: Check that the declaration is consistent with the property.  */
10395                     ;
10396                   }
10397                 else
10398                   {
10399                     /* The setter name is something like 'setName:'.
10400                        We need the substring 'setName' to build the
10401                        method declaration due to how the declaration
10402                        works.  TODO: build_method_decl() will then
10403                        generate back 'setName:' from 'setName'; it
10404                        would be more efficient to hook into there.  */
10405                     const char *full_setter_name = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x));
10406                     size_t length = strlen (full_setter_name);
10407                     char *setter_name = (char *) alloca (length);
10408                     tree ret_type, selector, arg_type, arg_name;
10409                     
10410                     strcpy (setter_name, full_setter_name);
10411                     setter_name[length - 1] = '\0';
10412                     ret_type = build_tree_list (NULL_TREE, void_type_node);
10413                     arg_type = build_tree_list (NULL_TREE, TREE_TYPE (x));
10414                     arg_name = get_identifier ("_value");
10415                     selector = objc_build_keyword_decl (get_identifier (setter_name),
10416                                                         arg_type, arg_name, NULL);
10417                     setter_decl = build_method_decl (INSTANCE_METHOD_DECL, 
10418                                                      ret_type, selector,
10419                                                      build_tree_list (NULL_TREE, NULL_TREE),
10420                                                      false);
10421                     objc_add_method (objc_interface_context, setter_decl, false, false);
10422                     METHOD_PROPERTY_CONTEXT (setter_decl) = x;
10423                   }            
10424               }
10425           }
10426         break;
10427       }
10428     default:
10429       gcc_unreachable ();
10430       break;
10431     }
10432 }
10433
10434 static tree
10435 add_protocol (tree protocol)
10436 {
10437   /* Put protocol on list in reverse order.  */
10438   TREE_CHAIN (protocol) = protocol_chain;
10439   protocol_chain = protocol;
10440   return protocol_chain;
10441 }
10442
10443 static tree
10444 lookup_protocol (tree ident)
10445 {
10446   tree chain;
10447
10448   for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
10449     if (ident == PROTOCOL_NAME (chain))
10450       return chain;
10451
10452   return NULL_TREE;
10453 }
10454
10455 /* This function forward declares the protocols named by NAMES.  If
10456    they are already declared or defined, the function has no effect.  */
10457
10458 void
10459 objc_declare_protocols (tree names)
10460 {
10461   tree list;
10462
10463 #ifdef OBJCPLUS
10464   if (current_namespace != global_namespace) {
10465     error ("Objective-C declarations may only appear in global scope");
10466   }
10467 #endif /* OBJCPLUS */
10468
10469   for (list = names; list; list = TREE_CHAIN (list))
10470     {
10471       tree name = TREE_VALUE (list);
10472
10473       if (lookup_protocol (name) == NULL_TREE)
10474         {
10475           tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
10476
10477           TYPE_LANG_SLOT_1 (protocol)
10478             = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
10479           PROTOCOL_NAME (protocol) = name;
10480           PROTOCOL_LIST (protocol) = NULL_TREE;
10481           add_protocol (protocol);
10482           PROTOCOL_DEFINED (protocol) = 0;
10483           PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
10484         }
10485     }
10486 }
10487
10488 static tree
10489 start_protocol (enum tree_code code, tree name, tree list)
10490 {
10491   tree protocol;
10492
10493 #ifdef OBJCPLUS
10494   if (current_namespace != global_namespace) {
10495     error ("Objective-C declarations may only appear in global scope");
10496   }
10497 #endif /* OBJCPLUS */
10498
10499   protocol = lookup_protocol (name);
10500
10501   if (!protocol)
10502     {
10503       protocol = make_node (code);
10504       TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
10505
10506       PROTOCOL_NAME (protocol) = name;
10507       PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
10508       add_protocol (protocol);
10509       PROTOCOL_DEFINED (protocol) = 1;
10510       PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
10511
10512       check_protocol_recursively (protocol, list);
10513     }
10514   else if (! PROTOCOL_DEFINED (protocol))
10515     {
10516       PROTOCOL_DEFINED (protocol) = 1;
10517       PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
10518
10519       check_protocol_recursively (protocol, list);
10520     }
10521   else
10522     {
10523       warning (0, "duplicate declaration for protocol %qE",
10524                name);
10525     }
10526   return protocol;
10527 }
10528
10529 \f
10530 /* "Encode" a data type into a string, which grows in util_obstack.
10531
10532    The format is described in gcc/doc/objc.texi, section 'Type
10533    encoding'.
10534
10535    Most of the encode_xxx functions have a 'type' argument, which is
10536    the type to encode, and an integer 'curtype' argument, which is the
10537    index in the encoding string of the beginning of the encoding of
10538    the current type, and allows you to find what characters have
10539    already been written for the current type (they are the ones in the
10540    current encoding string starting from 'curtype').
10541
10542    For example, if we are encoding a method which returns 'int' and
10543    takes a 'char **' argument, then when we get to the point of
10544    encoding the 'char **' argument, the encoded string already
10545    contains 'i12@0:4' (assuming a pointer size of 4 bytes).  So,
10546    'curtype' will be set to 7 when starting to encode 'char **'.
10547    During the whole of the encoding of 'char **', 'curtype' will be
10548    fixed at 7, so the routine encoding the second pointer can find out
10549    that it's actually encoding a pointer to a pointer by looking
10550    backwards at what has already been encoded for the current type,
10551    and seeing there is a "^" (meaning a pointer) in there.
10552 */
10553
10554
10555 /* Encode type qualifiers encodes one of the "PQ" Objective-C
10556    keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
10557    'const', instead, is encoded directly as part of the type.
10558  */
10559
10560 static void
10561 encode_type_qualifiers (tree declspecs)
10562 {
10563   tree spec;
10564
10565   for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
10566     {
10567       /* FIXME: Shouldn't we use token->keyword here ? */
10568       if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
10569         obstack_1grow (&util_obstack, 'n');
10570       else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
10571         obstack_1grow (&util_obstack, 'N');
10572       else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
10573         obstack_1grow (&util_obstack, 'o');
10574       else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
10575         obstack_1grow (&util_obstack, 'O');
10576       else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
10577         obstack_1grow (&util_obstack, 'R');
10578       else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
10579         obstack_1grow (&util_obstack, 'V');
10580       else
10581         gcc_unreachable ();
10582     }
10583 }
10584
10585 /* Determine if a pointee is marked read-only.  Only used by the NeXT
10586    runtime to be compatible with gcc-3.3.  */
10587
10588 static bool
10589 pointee_is_readonly (tree pointee)
10590 {
10591   while (POINTER_TYPE_P (pointee))
10592     pointee = TREE_TYPE (pointee);
10593
10594   return TYPE_READONLY (pointee);
10595 }
10596
10597 /* Encode a pointer type.  */
10598
10599 static void
10600 encode_pointer (tree type, int curtype, int format)
10601 {
10602   tree pointer_to = TREE_TYPE (type);
10603
10604   if (flag_next_runtime)
10605     {
10606       /* This code is used to be compatible with gcc-3.3.  */
10607       /* For historical/compatibility reasons, the read-only qualifier
10608          of the pointee gets emitted _before_ the '^'.  The read-only
10609          qualifier of the pointer itself gets ignored, _unless_ we are
10610          looking at a typedef!  Also, do not emit the 'r' for anything
10611          but the outermost type!  */
10612       if (!generating_instance_variables
10613           && (obstack_object_size (&util_obstack) - curtype <= 1)
10614           && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
10615               ? TYPE_READONLY (type)
10616               : pointee_is_readonly (pointer_to)))
10617         obstack_1grow (&util_obstack, 'r');
10618     }
10619
10620   if (TREE_CODE (pointer_to) == RECORD_TYPE)
10621     {
10622       if (OBJC_TYPE_NAME (pointer_to)
10623           && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
10624         {
10625           const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
10626
10627           if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
10628             {
10629               obstack_1grow (&util_obstack, '@');
10630               return;
10631             }
10632           else if (TYPE_HAS_OBJC_INFO (pointer_to)
10633                    && TYPE_OBJC_INTERFACE (pointer_to))
10634             {
10635               if (generating_instance_variables)
10636                 {
10637                   obstack_1grow (&util_obstack, '@');
10638                   obstack_1grow (&util_obstack, '"');
10639                   obstack_grow (&util_obstack, name, strlen (name));
10640                   obstack_1grow (&util_obstack, '"');
10641                   return;
10642                 }
10643               else
10644                 {
10645                   obstack_1grow (&util_obstack, '@');
10646                   return;
10647                 }
10648             }
10649           else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
10650             {
10651               obstack_1grow (&util_obstack, '#');
10652               return;
10653             }
10654           else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
10655             {
10656               obstack_1grow (&util_obstack, ':');
10657               return;
10658             }
10659         }
10660     }
10661   else if (TREE_CODE (pointer_to) == INTEGER_TYPE
10662            && TYPE_MODE (pointer_to) == QImode)
10663     {
10664       tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
10665                   ? OBJC_TYPE_NAME (pointer_to)
10666                   : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
10667
10668       /* (BOOL *) are an exception and are encoded as ^c, while all
10669          other pointers to char are encoded as *.   */
10670       if (strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
10671         {
10672           if (!flag_next_runtime)
10673             {
10674               /* The NeXT runtime adds the 'r' before getting here.  */
10675
10676               /* It appears that "r*" means "const char *" rather than
10677                  "char *const".  "char *const" is encoded as "*",
10678                  which is identical to "char *", so the "const" is
10679                  unfortunately lost.  */                 
10680               if (TYPE_READONLY (pointer_to))
10681                 obstack_1grow (&util_obstack, 'r');
10682             }
10683
10684           obstack_1grow (&util_obstack, '*');
10685           return;
10686         }
10687     }
10688
10689   /* We have a normal pointer type that does not get special treatment.  */
10690   obstack_1grow (&util_obstack, '^');
10691   encode_type (pointer_to, curtype, format);
10692 }
10693
10694 static void
10695 encode_array (tree type, int curtype, int format)
10696 {
10697   tree an_int_cst = TYPE_SIZE (type);
10698   tree array_of = TREE_TYPE (type);
10699   char buffer[40];
10700   
10701   if (an_int_cst == NULL)
10702     {
10703       /* We are trying to encode an incomplete array.  An incomplete
10704          array is forbidden as part of an instance variable.  */
10705       if (generating_instance_variables)
10706         {
10707           /* TODO: Detect this error earlier.  */
10708           error ("instance variable has unknown size");
10709           return;
10710         }
10711
10712       /* So the only case in which an incomplete array could occur is
10713          if we are encoding the arguments or return value of a method.
10714          In that case, an incomplete array argument or return value
10715          (eg, -(void)display: (char[])string) is treated like a
10716          pointer because that is how the compiler does the function
10717          call.  A special, more complicated case, is when the
10718          incomplete array is the last member of a struct (eg, if we
10719          are encoding "struct { unsigned long int a;double b[];}"),
10720          which is again part of a method argument/return value.  In
10721          that case, we really need to communicate to the runtime that
10722          there is an incomplete array (not a pointer!) there.  So, we
10723          detect that special case and encode it as a zero-length
10724          array.
10725
10726          Try to detect that we are part of a struct.  We do this by
10727          searching for '=' in the type encoding for the current type.
10728          NB: This hack assumes that you can't use '=' as part of a C
10729          identifier.
10730       */
10731       {
10732         char *enc = obstack_base (&util_obstack) + curtype;
10733         if (memchr (enc, '=', 
10734                     obstack_object_size (&util_obstack) - curtype) == NULL)
10735           {
10736             /* We are not inside a struct.  Encode the array as a
10737                pointer.  */
10738             encode_pointer (type, curtype, format);
10739             return;
10740           }
10741       }
10742
10743       /* Else, we are in a struct, and we encode it as a zero-length
10744          array.  */
10745       sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
10746     }
10747   else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
10748    sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
10749   else
10750     sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
10751              TREE_INT_CST_LOW (an_int_cst)
10752               / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
10753
10754   obstack_grow (&util_obstack, buffer, strlen (buffer));
10755   encode_type (array_of, curtype, format);
10756   obstack_1grow (&util_obstack, ']');
10757   return;
10758 }
10759
10760 /* Encode a vector.  The vector type is a GCC extension to C.  */
10761 static void
10762 encode_vector (tree type, int curtype, int format)
10763 {
10764   tree vector_of = TREE_TYPE (type);
10765   char buffer[40];
10766
10767   /* Vectors are like simple fixed-size arrays.  */
10768
10769   /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
10770      alignment of the vector, and <code> is the base type.  Eg, int
10771      __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
10772      assuming that the alignment is 32 bytes.  We include size and
10773      alignment in bytes so that the runtime does not have to have any
10774      knowledge of the actual types.
10775   */
10776   sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d",
10777            /* We want to compute the equivalent of sizeof (<vector>).
10778               Code inspired by c_sizeof_or_alignof_type.  */
10779            ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type)) 
10780              / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))),
10781            /* We want to compute the equivalent of __alignof__
10782               (<vector>).  Code inspired by
10783               c_sizeof_or_alignof_type.  */
10784            TYPE_ALIGN_UNIT (type));
10785   obstack_grow (&util_obstack, buffer, strlen (buffer));
10786   encode_type (vector_of, curtype, format);
10787   obstack_1grow (&util_obstack, ']');
10788   return;
10789 }
10790 \f
10791 static void
10792 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format)
10793 {
10794   tree field = TYPE_FIELDS (type);
10795
10796   for (; field; field = DECL_CHAIN (field))
10797     {
10798 #ifdef OBJCPLUS
10799       /* C++ static members, and things that are not field at all,
10800          should not appear in the encoding.  */
10801       if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
10802         continue;
10803 #endif
10804
10805       /* Recursively encode fields of embedded base classes.  */
10806       if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
10807           && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
10808         {
10809           encode_aggregate_fields (TREE_TYPE (field),
10810                                    pointed_to, curtype, format);
10811           continue;
10812         }
10813
10814       if (generating_instance_variables && !pointed_to)
10815         {
10816           tree fname = DECL_NAME (field);
10817
10818           obstack_1grow (&util_obstack, '"');
10819
10820           if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
10821             obstack_grow (&util_obstack,
10822                           IDENTIFIER_POINTER (fname),
10823                           strlen (IDENTIFIER_POINTER (fname)));
10824
10825           obstack_1grow (&util_obstack, '"');
10826         }
10827
10828       encode_field_decl (field, curtype, format);
10829     }
10830 }
10831
10832 static void
10833 encode_aggregate_within (tree type, int curtype, int format, int left,
10834                          int right)
10835 {
10836   tree name;
10837   /* NB: aggregates that are pointed to have slightly different encoding
10838      rules in that you never encode the names of instance variables.  */
10839   int ob_size = obstack_object_size (&util_obstack);
10840   bool inline_contents = false;
10841   bool pointed_to = false;
10842
10843   if (flag_next_runtime)
10844     {
10845       if (ob_size > 0  &&  *(obstack_next_free (&util_obstack) - 1) == '^')
10846         pointed_to = true;
10847
10848       if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
10849           && (!pointed_to || ob_size - curtype == 1
10850               || (ob_size - curtype == 2
10851                   && *(obstack_next_free (&util_obstack) - 2) == 'r')))
10852         inline_contents = true;
10853     }
10854   else
10855     {
10856       /* c0 and c1 are the last two characters in the encoding of the
10857          current type; if the last two characters were '^' or '^r',
10858          then we are encoding an aggregate that is "pointed to".  The
10859          comment above applies: in that case we should avoid encoding
10860          the names of instance variables.
10861       */
10862       char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
10863       char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
10864       
10865       if (c0 == '^' || (c1 == '^' && c0 == 'r'))
10866         pointed_to = true;
10867       
10868       if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
10869         {
10870           if (!pointed_to)
10871             inline_contents = true;
10872           else
10873             {
10874               /* Note that the check (ob_size - curtype < 2) prevents
10875                  infinite recursion when encoding a structure which is
10876                  a linked list (eg, struct node { struct node *next;
10877                  }).  Each time we follow a pointer, we add one
10878                  character to ob_size, and curtype is fixed, so after
10879                  at most two pointers we stop inlining contents and
10880                  break the loop.
10881
10882                  The other case where we don't inline is "^r", which
10883                  is a pointer to a constant struct.
10884               */
10885               if ((ob_size - curtype <= 2) && !(c0 == 'r'))
10886                 inline_contents = true;
10887             }
10888         }
10889     }
10890
10891   /* Traverse struct aliases; it is important to get the
10892      original struct and its tag name (if any).  */
10893   type = TYPE_MAIN_VARIANT (type);
10894   name = OBJC_TYPE_NAME (type);
10895   /* Open parenth/bracket.  */
10896   obstack_1grow (&util_obstack, left);
10897
10898   /* Encode the struct/union tag name, or '?' if a tag was
10899      not provided.  Typedef aliases do not qualify.  */
10900 #ifdef OBJCPLUS
10901   /* For compatibility with the NeXT runtime, ObjC++ encodes template
10902      args as a composite struct tag name. */
10903   if (name && TREE_CODE (name) == IDENTIFIER_NODE
10904       /* Did this struct have a tag?  */
10905       && !TYPE_WAS_ANONYMOUS (type))
10906     obstack_grow (&util_obstack,
10907                   decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
10908                   strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
10909 #else
10910   if (name && TREE_CODE (name) == IDENTIFIER_NODE)
10911     obstack_grow (&util_obstack,
10912                   IDENTIFIER_POINTER (name),
10913                   strlen (IDENTIFIER_POINTER (name)));
10914 #endif
10915   else
10916     obstack_1grow (&util_obstack, '?');
10917
10918   /* Encode the types (and possibly names) of the inner fields,
10919      if required.  */
10920   if (inline_contents)
10921     {
10922       obstack_1grow (&util_obstack, '=');
10923       encode_aggregate_fields (type, pointed_to, curtype, format);
10924     }
10925   /* Close parenth/bracket.  */
10926   obstack_1grow (&util_obstack, right);
10927 }
10928
10929 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
10930    field type.  */
10931
10932 static void
10933 encode_next_bitfield (int width)
10934 {
10935   char buffer[40];
10936   sprintf (buffer, "b%d", width);
10937   obstack_grow (&util_obstack, buffer, strlen (buffer));
10938 }
10939 \f
10940
10941 /* Encodes 'type', ignoring type qualifiers (which you should encode
10942    beforehand if needed) with the exception of 'const', which is
10943    encoded by encode_type.  See above for the explanation of
10944    'curtype'.  'format' can be OBJC_ENCODE_INLINE_DEFS or
10945    OBJC_ENCODE_DONT_INLINE_DEFS.
10946 */
10947 static void
10948 encode_type (tree type, int curtype, int format)
10949 {
10950   enum tree_code code = TREE_CODE (type);
10951
10952   /* Ignore type qualifiers other than 'const' when encoding a
10953      type.  */
10954
10955   if (type == error_mark_node)
10956     return;
10957
10958   if (!flag_next_runtime)
10959     {
10960       if (TYPE_READONLY (type))
10961         obstack_1grow (&util_obstack, 'r');
10962     }
10963
10964   switch (code)
10965     {
10966     case ENUMERAL_TYPE:
10967       if (flag_next_runtime)
10968         {
10969           /* Kludge for backwards-compatibility with gcc-3.3: enums
10970              are always encoded as 'i' no matter what type they
10971              actually are (!).  */
10972           obstack_1grow (&util_obstack, 'i');
10973           break;
10974         }
10975       /* Else, they are encoded exactly like the integer type that is
10976          used by the compiler to store them.  */
10977     case INTEGER_TYPE:
10978       {
10979         char c;
10980         switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
10981           {
10982           case 8:  c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
10983           case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
10984           case 32:
10985             {
10986               tree int_type = type;
10987               if (flag_next_runtime)
10988                 {
10989                   /* Another legacy kludge for compatiblity with
10990                      gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
10991                      but not always.  For typedefs, we need to use 'i'
10992                      or 'I' instead if encoding a struct field, or a
10993                      pointer!  */
10994                   int_type =  ((!generating_instance_variables
10995                                 && (obstack_object_size (&util_obstack)
10996                                     == (unsigned) curtype))
10997                                ? TYPE_MAIN_VARIANT (type)
10998                                : type);
10999                 }
11000               if (int_type == long_unsigned_type_node
11001                   || int_type == long_integer_type_node)
11002                 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
11003               else
11004                 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
11005             }
11006             break;
11007           case 64:  c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
11008           case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
11009           default: gcc_unreachable ();
11010           }
11011         obstack_1grow (&util_obstack, c);
11012         break;
11013       }
11014     case REAL_TYPE:
11015       {
11016         char c;
11017         /* Floating point types.  */
11018         switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
11019           {
11020           case 32:  c = 'f'; break;
11021           case 64:  c = 'd'; break;
11022           case 96:
11023           case 128: c = 'D'; break;
11024           default: gcc_unreachable ();
11025           }
11026         obstack_1grow (&util_obstack, c);
11027         break;
11028       }
11029     case VOID_TYPE:
11030       obstack_1grow (&util_obstack, 'v');
11031       break;
11032
11033     case BOOLEAN_TYPE:
11034       obstack_1grow (&util_obstack, 'B');
11035       break;
11036
11037     case ARRAY_TYPE:
11038       encode_array (type, curtype, format);
11039       break;
11040
11041     case POINTER_TYPE:
11042 #ifdef OBJCPLUS
11043     case REFERENCE_TYPE:
11044 #endif
11045       encode_pointer (type, curtype, format);
11046       break;
11047
11048     case RECORD_TYPE:
11049       encode_aggregate_within (type, curtype, format, '{', '}');
11050       break;
11051
11052     case UNION_TYPE:
11053       encode_aggregate_within (type, curtype, format, '(', ')');
11054       break;
11055
11056     case FUNCTION_TYPE: /* '?' means an unknown type.  */
11057       obstack_1grow (&util_obstack, '?');
11058       break;
11059
11060     case COMPLEX_TYPE:
11061       /* A complex is encoded as 'j' followed by the inner type (eg,
11062          "_Complex int" is encoded as 'ji').  */
11063       obstack_1grow (&util_obstack, 'j');
11064       encode_type (TREE_TYPE (type), curtype, format);
11065       break;
11066
11067     case VECTOR_TYPE:
11068       encode_vector (type, curtype, format);
11069       break;
11070
11071     default:
11072       warning (0, "unknown type %s found during Objective-C encoding",
11073                gen_type_name (type));
11074       obstack_1grow (&util_obstack, '?');
11075       break;
11076     }
11077   
11078   if (flag_next_runtime)
11079     {
11080       /* Super-kludge.  Some ObjC qualifier and type combinations need
11081          to be rearranged for compatibility with gcc-3.3.  */
11082       if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
11083         {
11084           char *enc = obstack_base (&util_obstack) + curtype;
11085           
11086           /* Rewrite "in const" from "nr" to "rn".  */
11087           if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
11088             strncpy (enc - 1, "rn", 2);
11089         }
11090     }
11091 }
11092
11093 static void
11094 encode_gnu_bitfield (int position, tree type, int size)
11095 {
11096   enum tree_code code = TREE_CODE (type);
11097   char buffer[40];
11098   char charType = '?';
11099
11100   /* This code is only executed for the GNU runtime, so we can ignore
11101      the NeXT runtime kludge of always encoding enums as 'i' no matter
11102      what integers they actually are.  */
11103   if (code == INTEGER_TYPE  ||  code == ENUMERAL_TYPE)
11104     {
11105       if (integer_zerop (TYPE_MIN_VALUE (type)))
11106         /* Unsigned integer types.  */
11107         {
11108           switch (TYPE_MODE (type))
11109             {
11110             case QImode:
11111               charType = 'C'; break;
11112             case HImode:
11113               charType = 'S'; break;
11114             case SImode:
11115               {
11116                 if (type == long_unsigned_type_node)
11117                   charType = 'L';
11118                 else
11119                   charType = 'I';
11120                 break;
11121               }
11122             case DImode:
11123               charType = 'Q'; break;
11124             default:
11125               gcc_unreachable ();
11126             }
11127         }
11128       else
11129         /* Signed integer types.  */
11130         {
11131           switch (TYPE_MODE (type))
11132             {
11133             case QImode:
11134               charType = 'c'; break;
11135             case HImode:
11136               charType = 's'; break;
11137             case SImode:
11138               {
11139                 if (type == long_integer_type_node)
11140                   charType = 'l';
11141                 else
11142                   charType = 'i';
11143                 break;
11144               }
11145             case DImode:
11146               charType = 'q'; break;
11147             default:
11148               gcc_unreachable ();
11149             }
11150         }
11151     }
11152   else
11153     {
11154       /* Do not do any encoding, produce an error and keep going.  */
11155       error ("trying to encode non-integer type as a bitfield");
11156       return;
11157     }
11158
11159   sprintf (buffer, "b%d%c%d", position, charType, size);
11160   obstack_grow (&util_obstack, buffer, strlen (buffer));
11161 }
11162
11163 static void
11164 encode_field_decl (tree field_decl, int curtype, int format)
11165 {
11166 #ifdef OBJCPLUS
11167   /* C++ static members, and things that are not fields at all,
11168      should not appear in the encoding.  */
11169   if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
11170     return;
11171 #endif
11172
11173   /* Generate the bitfield typing information, if needed.  Note the difference
11174      between GNU and NeXT runtimes.  */
11175   if (DECL_BIT_FIELD_TYPE (field_decl))
11176     {
11177       int size = tree_low_cst (DECL_SIZE (field_decl), 1);
11178
11179       if (flag_next_runtime)
11180         encode_next_bitfield (size);
11181       else
11182         encode_gnu_bitfield (int_bit_position (field_decl),
11183                              DECL_BIT_FIELD_TYPE (field_decl), size);
11184     }
11185   else
11186     encode_type (TREE_TYPE (field_decl), curtype, format);
11187 }
11188
11189 /* Decay array and function parameters into pointers.  */
11190
11191 static tree
11192 objc_decay_parm_type (tree type)
11193 {
11194   if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == FUNCTION_TYPE)
11195     type = build_pointer_type (TREE_CODE (type) == ARRAY_TYPE
11196                                ? TREE_TYPE (type)
11197                                : type);
11198
11199   return type;
11200 }
11201
11202 static GTY(()) tree objc_parmlist = NULL_TREE;
11203
11204 /* Append PARM to a list of formal parameters of a method, making a necessary
11205    array-to-pointer adjustment along the way.  */
11206
11207 static void
11208 objc_push_parm (tree parm)
11209 {
11210   tree type;
11211
11212   if (TREE_TYPE (parm) == error_mark_node)
11213     {
11214       objc_parmlist = chainon (objc_parmlist, parm);
11215       return;
11216     }
11217
11218   /* Decay arrays and functions into pointers.  */
11219   type = objc_decay_parm_type (TREE_TYPE (parm));
11220
11221   /* If the parameter type has been decayed, a new PARM_DECL needs to be
11222      built as well.  */
11223   if (type != TREE_TYPE (parm))
11224     parm = build_decl (input_location, PARM_DECL, DECL_NAME (parm), type);
11225
11226   DECL_ARG_TYPE (parm)
11227     = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
11228
11229   /* Record constancy and volatility.  */
11230   c_apply_type_quals_to_decl
11231   ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
11232    | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
11233    | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
11234
11235   objc_parmlist = chainon (objc_parmlist, parm);
11236 }
11237
11238 /* Retrieve the formal parameter list constructed via preceding calls to
11239    objc_push_parm().  */
11240
11241 #ifdef OBJCPLUS
11242 static tree
11243 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
11244 #else
11245 static struct c_arg_info *
11246 objc_get_parm_info (int have_ellipsis)
11247 #endif
11248 {
11249 #ifdef OBJCPLUS
11250   tree parm_info = objc_parmlist;
11251   objc_parmlist = NULL_TREE;
11252
11253   return parm_info;
11254 #else
11255   tree parm_info = objc_parmlist;
11256   struct c_arg_info *arg_info;
11257   /* The C front-end requires an elaborate song and dance at
11258      this point.  */
11259   push_scope ();
11260   declare_parm_level ();
11261   while (parm_info)
11262     {
11263       tree next = DECL_CHAIN (parm_info);
11264
11265       DECL_CHAIN (parm_info) = NULL_TREE;
11266       parm_info = pushdecl (parm_info);
11267       finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
11268       parm_info = next;
11269     }
11270   arg_info = get_parm_info (have_ellipsis);
11271   pop_scope ();
11272   objc_parmlist = NULL_TREE;
11273   return arg_info;
11274 #endif
11275 }
11276
11277 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
11278    method definitions.  In the case of instance methods, we can be more
11279    specific as to the type of 'self'.  */
11280
11281 static void
11282 synth_self_and_ucmd_args (void)
11283 {
11284   tree self_type;
11285
11286   if (objc_method_context
11287       && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
11288     self_type = objc_instance_type;
11289   else
11290     /* Really a `struct objc_class *'. However, we allow people to
11291        assign to self, which changes its type midstream.  */
11292     self_type = objc_object_type;
11293
11294   /* id self; */
11295   objc_push_parm (build_decl (input_location,
11296                               PARM_DECL, self_id, self_type));
11297
11298   /* SEL _cmd; */
11299   objc_push_parm (build_decl (input_location,
11300                               PARM_DECL, ucmd_id, objc_selector_type));
11301 }
11302
11303 /* Transform an Objective-C method definition into a static C function
11304    definition, synthesizing the first two arguments, "self" and "_cmd",
11305    in the process.  */
11306
11307 static void
11308 start_method_def (tree method)
11309 {
11310   tree parmlist;
11311 #ifdef OBJCPLUS
11312   tree parm_info;
11313 #else
11314   struct c_arg_info *parm_info;
11315 #endif
11316   int have_ellipsis = 0;
11317
11318   /* If we are defining a "dealloc" method in a non-root class, we
11319      will need to check if a [super dealloc] is missing, and warn if
11320      it is.  */
11321   if(CLASS_SUPER_NAME (objc_implementation_context)
11322      && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
11323     should_call_super_dealloc = 1;
11324   else
11325     should_call_super_dealloc = 0;
11326
11327   /* Required to implement _msgSuper.  */
11328   objc_method_context = method;
11329   UOBJC_SUPER_decl = NULL_TREE;
11330
11331   /* Generate prototype declarations for arguments..."new-style".  */
11332   synth_self_and_ucmd_args ();
11333
11334   /* Generate argument declarations if a keyword_decl.  */
11335   parmlist = METHOD_SEL_ARGS (method);
11336   while (parmlist)
11337     {
11338       /* parmlist is a KEYWORD_DECL.  */
11339       tree type = TREE_VALUE (TREE_TYPE (parmlist));
11340       tree parm;
11341
11342       parm = build_decl (input_location,
11343                          PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
11344       decl_attributes (&parm, DECL_ATTRIBUTES (parmlist), 0);
11345       objc_push_parm (parm);
11346       parmlist = DECL_CHAIN (parmlist);
11347     }
11348
11349   if (METHOD_ADD_ARGS (method))
11350     {
11351       tree akey;
11352
11353       for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
11354            akey; akey = TREE_CHAIN (akey))
11355         {
11356           objc_push_parm (TREE_VALUE (akey));
11357         }
11358
11359       if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
11360         have_ellipsis = 1;
11361     }
11362
11363   parm_info = objc_get_parm_info (have_ellipsis);
11364
11365   really_start_method (objc_method_context, parm_info);
11366 }
11367
11368 /* Return 1 if TYPE1 is equivalent to TYPE2
11369    for purposes of method overloading.  */
11370
11371 static int
11372 objc_types_are_equivalent (tree type1, tree type2)
11373 {
11374   if (type1 == type2)
11375     return 1;
11376
11377   /* Strip away indirections.  */
11378   while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
11379          && (TREE_CODE (type1) == TREE_CODE (type2)))
11380     type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
11381   if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
11382     return 0;
11383
11384   type1 = (TYPE_HAS_OBJC_INFO (type1)
11385            ? TYPE_OBJC_PROTOCOL_LIST (type1)
11386            : NULL_TREE);
11387   type2 = (TYPE_HAS_OBJC_INFO (type2)
11388            ? TYPE_OBJC_PROTOCOL_LIST (type2)
11389            : NULL_TREE);
11390
11391   if (list_length (type1) == list_length (type2))
11392     {
11393       for (; type2; type2 = TREE_CHAIN (type2))
11394         if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
11395           return 0;
11396       return 1;
11397     }
11398   return 0;
11399 }
11400
11401 /* Return 1 if TYPE1 has the same size and alignment as TYPE2.  */
11402
11403 static int
11404 objc_types_share_size_and_alignment (tree type1, tree type2)
11405 {
11406   return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
11407           && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
11408 }
11409
11410 /* Return 1 if PROTO1 is equivalent to PROTO2
11411    for purposes of method overloading.  Ordinarily, the type signatures
11412    should match up exactly, unless STRICT is zero, in which case we
11413    shall allow differences in which the size and alignment of a type
11414    is the same.  */
11415
11416 static int
11417 comp_proto_with_proto (tree proto1, tree proto2, int strict)
11418 {
11419   /* The following test is needed in case there are hashing
11420      collisions.  */
11421   if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
11422     return 0;
11423
11424   return match_proto_with_proto (proto1, proto2, strict);
11425 }
11426
11427 static int
11428 match_proto_with_proto (tree proto1, tree proto2, int strict)
11429 {
11430   tree type1, type2;
11431
11432   /* Compare return types.  */
11433   type1 = TREE_VALUE (TREE_TYPE (proto1));
11434   type2 = TREE_VALUE (TREE_TYPE (proto2));
11435
11436   if (!objc_types_are_equivalent (type1, type2)
11437       && (strict || !objc_types_share_size_and_alignment (type1, type2)))
11438     return 0;
11439
11440   /* Compare argument types.  */
11441   for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
11442        type2 = get_arg_type_list (proto2, METHOD_REF, 0);
11443        type1 && type2;
11444        type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
11445     {
11446       if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
11447           && (strict
11448               || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
11449                                                        TREE_VALUE (type2))))
11450         return 0;
11451     }
11452
11453   return (!type1 && !type2);
11454 }
11455
11456 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
11457    this occurs.  ObjC method dispatches are _not_ like C++ virtual
11458    member function dispatches, and we account for the difference here.  */
11459 tree
11460 #ifdef OBJCPLUS
11461 objc_fold_obj_type_ref (tree ref, tree known_type)
11462 #else
11463 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
11464                         tree known_type ATTRIBUTE_UNUSED)
11465 #endif
11466 {
11467 #ifdef OBJCPLUS
11468   tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
11469
11470   /* If the receiver does not have virtual member functions, there
11471      is nothing we can (or need to) do here.  */
11472   if (!v)
11473     return NULL_TREE;
11474
11475   /* Let C++ handle C++ virtual functions.  */
11476   return cp_fold_obj_type_ref (ref, known_type);
11477 #else
11478   /* For plain ObjC, we currently do not need to do anything.  */
11479   return NULL_TREE;
11480 #endif
11481 }
11482
11483 static void
11484 objc_start_function (tree name, tree type, tree attrs,
11485 #ifdef OBJCPLUS
11486                      tree params
11487 #else
11488                      struct c_arg_info *params
11489 #endif
11490                      )
11491 {
11492   tree fndecl = build_decl (input_location,
11493                             FUNCTION_DECL, name, type);
11494
11495 #ifdef OBJCPLUS
11496   DECL_ARGUMENTS (fndecl) = params;
11497   DECL_INITIAL (fndecl) = error_mark_node;
11498   DECL_EXTERNAL (fndecl) = 0;
11499   TREE_STATIC (fndecl) = 1;
11500   retrofit_lang_decl (fndecl);
11501   cplus_decl_attributes (&fndecl, attrs, 0);
11502   start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
11503 #else
11504   current_function_returns_value = 0;  /* Assume, until we see it does.  */
11505   current_function_returns_null = 0;
11506   decl_attributes (&fndecl, attrs, 0);
11507   announce_function (fndecl);
11508   DECL_INITIAL (fndecl) = error_mark_node;
11509   DECL_EXTERNAL (fndecl) = 0;
11510   TREE_STATIC (fndecl) = 1;
11511   current_function_decl = pushdecl (fndecl);
11512   push_scope ();
11513   declare_parm_level ();
11514   DECL_RESULT (current_function_decl)
11515     = build_decl (input_location,
11516                   RESULT_DECL, NULL_TREE,
11517                   TREE_TYPE (TREE_TYPE (current_function_decl)));
11518   DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
11519   DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
11520   start_fname_decls ();
11521   store_parm_decls_from (params);
11522 #endif
11523
11524   TREE_USED (current_function_decl) = 1;
11525 }
11526
11527 /* - Generate an identifier for the function. the format is "_n_cls",
11528      where 1 <= n <= nMethods, and cls is the name the implementation we
11529      are processing.
11530    - Install the return type from the method declaration.
11531    - If we have a prototype, check for type consistency.  */
11532
11533 static void
11534 really_start_method (tree method,
11535 #ifdef OBJCPLUS
11536                      tree parmlist
11537 #else
11538                      struct c_arg_info *parmlist
11539 #endif
11540                      )
11541 {
11542   tree ret_type, meth_type;
11543   tree method_id;
11544   const char *sel_name, *class_name, *cat_name;
11545   char *buf;
11546
11547   /* Synth the storage class & assemble the return type.  */
11548   ret_type = TREE_VALUE (TREE_TYPE (method));
11549
11550   sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
11551   class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
11552   cat_name = ((TREE_CODE (objc_implementation_context)
11553                == CLASS_IMPLEMENTATION_TYPE)
11554               ? NULL
11555               : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
11556   method_slot++;
11557
11558   /* Make sure this is big enough for any plausible method label.  */
11559   buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
11560                          + (cat_name ? strlen (cat_name) : 0));
11561
11562   OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
11563                          class_name, cat_name, sel_name, method_slot);
11564
11565   method_id = get_identifier (buf);
11566
11567 #ifdef OBJCPLUS
11568   /* Objective-C methods cannot be overloaded, so we don't need
11569      the type encoding appended.  It looks bad anyway... */
11570   push_lang_context (lang_name_c);
11571 #endif
11572
11573   meth_type
11574     = build_function_type (ret_type,
11575                            get_arg_type_list (method, METHOD_DEF, 0));
11576   objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
11577
11578   /* Set self_decl from the first argument.  */
11579   self_decl = DECL_ARGUMENTS (current_function_decl);
11580
11581   /* Suppress unused warnings.  */
11582   TREE_USED (self_decl) = 1;
11583   DECL_READ_P (self_decl) = 1;
11584   TREE_USED (DECL_CHAIN (self_decl)) = 1;
11585   DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
11586 #ifdef OBJCPLUS
11587   pop_lang_context ();
11588 #endif
11589
11590   METHOD_DEFINITION (method) = current_function_decl;
11591
11592   /* Check consistency...start_function, pushdecl, duplicate_decls.  */
11593
11594   if (implementation_template != objc_implementation_context)
11595     {
11596       tree proto
11597         = lookup_method_static (implementation_template,
11598                                 METHOD_SEL_NAME (method),
11599                                 ((TREE_CODE (method) == CLASS_METHOD_DECL)
11600                                  | OBJC_LOOKUP_NO_SUPER));
11601
11602       if (proto)
11603         {
11604           if (!comp_proto_with_proto (method, proto, 1))
11605             {
11606               bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
11607
11608               warning_at (DECL_SOURCE_LOCATION (method), 0,
11609                           "conflicting types for %<%c%s%>",
11610                           (type ? '-' : '+'),
11611                           identifier_to_locale (gen_method_decl (method)));
11612               inform (DECL_SOURCE_LOCATION (proto),
11613                       "previous declaration of %<%c%s%>",
11614                       (type ? '-' : '+'),
11615                       identifier_to_locale (gen_method_decl (proto)));
11616             }
11617           else
11618             {
11619               /* If the method in the @interface was deprecated, mark
11620                  the implemented method as deprecated too.  It should
11621                  never be used for messaging (when the deprecation
11622                  warnings are produced), but just in case.  */
11623               if (TREE_DEPRECATED (proto))
11624                 TREE_DEPRECATED (method) = 1;
11625
11626               /* If the method in the @interface was marked as
11627                  'noreturn', mark the function implementing the method
11628                  as 'noreturn' too.  */
11629               TREE_THIS_VOLATILE (current_function_decl) = TREE_THIS_VOLATILE (proto);
11630             }
11631         }
11632       else
11633         {
11634           /* We have a method @implementation even though we did not
11635              see a corresponding @interface declaration (which is allowed
11636              by Objective-C rules).  Go ahead and place the method in
11637              the @interface anyway, so that message dispatch lookups
11638              will see it.  */
11639           tree interface = implementation_template;
11640
11641           if (TREE_CODE (objc_implementation_context)
11642               == CATEGORY_IMPLEMENTATION_TYPE)
11643             interface = lookup_category
11644                         (interface,
11645                          CLASS_SUPER_NAME (objc_implementation_context));
11646
11647           if (interface)
11648             objc_add_method (interface, copy_node (method),
11649                              TREE_CODE (method) == CLASS_METHOD_DECL, 
11650                              /* is_optional= */ false);
11651         }
11652     }
11653 }
11654
11655 static void *UOBJC_SUPER_scope = 0;
11656
11657 /* _n_Method (id self, SEL sel, ...)
11658      {
11659        struct objc_super _S;
11660        _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
11661      }  */
11662
11663 static tree
11664 get_super_receiver (void)
11665 {
11666   if (objc_method_context)
11667     {
11668       tree super_expr, super_expr_list;
11669
11670       if (!UOBJC_SUPER_decl)
11671       {
11672         UOBJC_SUPER_decl = build_decl (input_location,
11673                                        VAR_DECL, get_identifier (TAG_SUPER),
11674                                        objc_super_template);
11675         /* This prevents `unused variable' warnings when compiling with -Wall.  */
11676         TREE_USED (UOBJC_SUPER_decl) = 1;
11677         DECL_READ_P (UOBJC_SUPER_decl) = 1;
11678         lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
11679         finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
11680                      NULL_TREE);
11681         UOBJC_SUPER_scope = objc_get_current_scope ();
11682       }
11683
11684       /* Set receiver to self.  */
11685       super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
11686       super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
11687                                       NOP_EXPR, input_location, self_decl,
11688                                       NULL_TREE);
11689       super_expr_list = super_expr;
11690
11691       /* Set class to begin searching.  */
11692       super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
11693                                              get_identifier ("super_class"));
11694
11695       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
11696         {
11697           /* [_cls, __cls]Super are "pre-built" in
11698              synth_forward_declarations.  */
11699
11700           super_expr = build_modify_expr (input_location, super_expr,
11701                                           NULL_TREE, NOP_EXPR,
11702                                           input_location,
11703                                           ((TREE_CODE (objc_method_context)
11704                                             == INSTANCE_METHOD_DECL)
11705                                            ? ucls_super_ref
11706                                            : uucls_super_ref),
11707                                           NULL_TREE);
11708         }
11709
11710       else
11711         /* We have a category.  */
11712         {
11713           tree super_name = CLASS_SUPER_NAME (implementation_template);
11714           tree super_class;
11715
11716           /* Barf if super used in a category of Object.  */
11717           if (!super_name)
11718             {
11719               error ("no super class declared in interface for %qE",
11720                      CLASS_NAME (implementation_template));
11721               return error_mark_node;
11722             }
11723
11724           if (flag_next_runtime && !flag_zero_link)
11725             {
11726               super_class = objc_get_class_reference (super_name);
11727               if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
11728                 /* If we are in a class method, we must retrieve the
11729                    _metaclass_ for the current class, pointed at by
11730                    the class's "isa" pointer.  The following assumes that
11731                    "isa" is the first ivar in a class (which it must be).  */
11732                 super_class
11733                   = build_indirect_ref
11734                       (input_location,
11735                        build_c_cast (input_location,
11736                                      build_pointer_type (objc_class_type),
11737                                      super_class), RO_UNARY_STAR);
11738             }
11739           else
11740             {
11741               add_class_reference (super_name);
11742               super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
11743                              ? objc_get_class_decl : objc_get_meta_class_decl);
11744               assemble_external (super_class);
11745               super_class
11746                 = build_function_call
11747                   (input_location,
11748                    super_class,
11749                    build_tree_list
11750                    (NULL_TREE,
11751                     my_build_string_pointer
11752                     (IDENTIFIER_LENGTH (super_name) + 1,
11753                      IDENTIFIER_POINTER (super_name))));
11754             }
11755
11756           super_expr
11757             = build_modify_expr (input_location, super_expr, NULL_TREE,
11758                                  NOP_EXPR,
11759                                  input_location,
11760                                  build_c_cast (input_location, 
11761                                                TREE_TYPE (super_expr),
11762                                                super_class),
11763                                  NULL_TREE);
11764         }
11765
11766       super_expr_list = build_compound_expr (input_location, 
11767                                              super_expr_list, super_expr);
11768
11769       super_expr = build_unary_op (input_location, 
11770                                    ADDR_EXPR, UOBJC_SUPER_decl, 0);
11771       super_expr_list = build_compound_expr (input_location,
11772                                              super_expr_list, super_expr);
11773
11774       return super_expr_list;
11775     }
11776   else
11777     {
11778       error ("[super ...] must appear in a method context");
11779       return error_mark_node;
11780     }
11781 }
11782
11783 /* When exiting a scope, sever links to a 'super' declaration (if any)
11784    therein contained.  */
11785
11786 void
11787 objc_clear_super_receiver (void)
11788 {
11789   if (objc_method_context
11790       && UOBJC_SUPER_scope == objc_get_current_scope ()) {
11791     UOBJC_SUPER_decl = 0;
11792     UOBJC_SUPER_scope = 0;
11793   }
11794 }
11795
11796 void
11797 objc_finish_method_definition (tree fndecl)
11798 {
11799   /* We cannot validly inline ObjC methods, at least not without a language
11800      extension to declare that a method need not be dynamically
11801      dispatched, so suppress all thoughts of doing so.  */
11802   DECL_UNINLINABLE (fndecl) = 1;
11803
11804 #ifndef OBJCPLUS
11805   /* The C++ front-end will have called finish_function() for us.  */
11806   finish_function ();
11807 #endif
11808
11809   METHOD_ENCODING (objc_method_context)
11810     = encode_method_prototype (objc_method_context);
11811
11812   /* Required to implement _msgSuper. This must be done AFTER finish_function,
11813      since the optimizer may find "may be used before set" errors.  */
11814   objc_method_context = NULL_TREE;
11815
11816   if (should_call_super_dealloc)
11817     warning (0, "method possibly missing a [super dealloc] call");
11818 }
11819
11820 /* Given a tree DECL node, produce a printable description of it in the given
11821    buffer, overwriting the buffer.  */
11822
11823 static char *
11824 gen_declaration (tree decl)
11825 {
11826   errbuf[0] = '\0';
11827
11828   if (DECL_P (decl))
11829     {
11830       gen_type_name_0 (TREE_TYPE (decl));
11831
11832       if (DECL_NAME (decl))
11833         {
11834           if (!POINTER_TYPE_P (TREE_TYPE (decl)))
11835             strcat (errbuf, " ");
11836
11837           strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
11838         }
11839
11840       if (DECL_INITIAL (decl)
11841           && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
11842         sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
11843                  TREE_INT_CST_LOW (DECL_INITIAL (decl)));
11844     }
11845
11846   return errbuf;
11847 }
11848
11849 /* Given a tree TYPE node, produce a printable description of it in the given
11850    buffer, overwriting the buffer.  */
11851
11852 static char *
11853 gen_type_name_0 (tree type)
11854 {
11855   tree orig = type, proto;
11856
11857   if (TYPE_P (type) && TYPE_NAME (type))
11858     type = TYPE_NAME (type);
11859   else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
11860     {
11861       tree inner = TREE_TYPE (type);
11862
11863       while (TREE_CODE (inner) == ARRAY_TYPE)
11864         inner = TREE_TYPE (inner);
11865
11866       gen_type_name_0 (inner);
11867
11868       if (!POINTER_TYPE_P (inner))
11869         strcat (errbuf, " ");
11870
11871       if (POINTER_TYPE_P (type))
11872         strcat (errbuf, "*");
11873       else
11874         while (type != inner)
11875           {
11876             strcat (errbuf, "[");
11877
11878             if (TYPE_DOMAIN (type))
11879               {
11880                 char sz[20];
11881
11882                 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
11883                          (TREE_INT_CST_LOW
11884                           (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
11885                 strcat (errbuf, sz);
11886               }
11887
11888             strcat (errbuf, "]");
11889             type = TREE_TYPE (type);
11890           }
11891
11892       goto exit_function;
11893     }
11894
11895   if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
11896     type = DECL_NAME (type);
11897
11898   strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
11899                   ? IDENTIFIER_POINTER (type)
11900                   : "");
11901
11902   /* For 'id' and 'Class', adopted protocols are stored in the pointee.  */
11903   if (objc_is_id (orig))
11904     orig = TREE_TYPE (orig);
11905
11906   proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
11907
11908   if (proto)
11909     {
11910       strcat (errbuf, " <");
11911
11912       while (proto) {
11913         strcat (errbuf,
11914                 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
11915         proto = TREE_CHAIN (proto);
11916         strcat (errbuf, proto ? ", " : ">");
11917       }
11918     }
11919
11920  exit_function:
11921   return errbuf;
11922 }
11923
11924 static char *
11925 gen_type_name (tree type)
11926 {
11927   errbuf[0] = '\0';
11928
11929   return gen_type_name_0 (type);
11930 }
11931
11932 /* Given a method tree, put a printable description into the given
11933    buffer (overwriting) and return a pointer to the buffer.  */
11934
11935 static char *
11936 gen_method_decl (tree method)
11937 {
11938   tree chain;
11939
11940   strcpy (errbuf, "(");  /* NB: Do _not_ call strcat() here.  */
11941   gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
11942   strcat (errbuf, ")");
11943   chain = METHOD_SEL_ARGS (method);
11944
11945   if (chain)
11946     {
11947       /* We have a chain of keyword_decls.  */
11948       do
11949         {
11950           if (KEYWORD_KEY_NAME (chain))
11951             strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
11952
11953           strcat (errbuf, ":(");
11954           gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
11955           strcat (errbuf, ")");
11956
11957           strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
11958           if ((chain = DECL_CHAIN (chain)))
11959             strcat (errbuf, " ");
11960         }
11961       while (chain);
11962
11963       if (METHOD_ADD_ARGS (method))
11964         {
11965           chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
11966
11967           /* Know we have a chain of parm_decls.  */
11968           while (chain)
11969             {
11970               strcat (errbuf, ", ");
11971               gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
11972               chain = TREE_CHAIN (chain);
11973             }
11974
11975           if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
11976             strcat (errbuf, ", ...");
11977         }
11978     }
11979
11980   else
11981     /* We have a unary selector.  */
11982     strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
11983
11984   return errbuf;
11985 }
11986 \f
11987 /* Debug info.  */
11988
11989
11990 /* Dump an @interface declaration of the supplied class CHAIN to the
11991    supplied file FP.  Used to implement the -gen-decls option (which
11992    prints out an @interface declaration of all classes compiled in
11993    this run); potentially useful for debugging the compiler too.  */
11994 static void
11995 dump_interface (FILE *fp, tree chain)
11996 {
11997   /* FIXME: A heap overflow here whenever a method (or ivar)
11998      declaration is so long that it doesn't fit in the buffer.  The
11999      code and all the related functions should be rewritten to avoid
12000      using fixed size buffers.  */
12001   const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
12002   tree ivar_decls = CLASS_RAW_IVARS (chain);
12003   tree nst_methods = CLASS_NST_METHODS (chain);
12004   tree cls_methods = CLASS_CLS_METHODS (chain);
12005
12006   fprintf (fp, "\n@interface %s", my_name);
12007
12008   /* CLASS_SUPER_NAME is used to store the superclass name for
12009      classes, and the category name for categories.  */
12010   if (CLASS_SUPER_NAME (chain))
12011     {
12012       const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
12013
12014       switch (TREE_CODE (chain))
12015         {
12016         case CATEGORY_IMPLEMENTATION_TYPE:
12017         case CATEGORY_INTERFACE_TYPE:
12018           fprintf (fp, " (%s)\n", name);
12019           break;
12020         default:
12021           fprintf (fp, " : %s\n", name);
12022           break;
12023         }
12024     }
12025   else
12026     fprintf (fp, "\n");
12027
12028   /* FIXME - the following doesn't seem to work at the moment.  */
12029   if (ivar_decls)
12030     {
12031       fprintf (fp, "{\n");
12032       do
12033         {
12034           fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
12035           ivar_decls = TREE_CHAIN (ivar_decls);
12036         }
12037       while (ivar_decls);
12038       fprintf (fp, "}\n");
12039     }
12040
12041   while (nst_methods)
12042     {
12043       fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
12044       nst_methods = TREE_CHAIN (nst_methods);
12045     }
12046
12047   while (cls_methods)
12048     {
12049       fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
12050       cls_methods = TREE_CHAIN (cls_methods);
12051     }
12052
12053   fprintf (fp, "@end\n");
12054 }
12055
12056 #if 0
12057 /* Produce the pretty printing for an Objective-C method.  This is
12058    currently unused, but could be handy while reorganizing the pretty
12059    printing to be more robust.  */
12060 static const char *
12061 objc_pretty_print_method (bool is_class_method,
12062                           const char *class_name,
12063                           const char *category_name,
12064                           const char *selector)
12065 {
12066   if (category_name)
12067     {
12068       char *result = XNEWVEC (char, strlen (class_name) + strlen (category_name) 
12069                               + strlen (selector) + 7);
12070
12071       if (is_class_method)
12072         sprintf (result, "+[%s(%s) %s]", class_name, category_name, selector);
12073       else
12074         sprintf (result, "-[%s(%s) %s]", class_name, category_name, selector);
12075
12076       return result;
12077     }
12078   else
12079     {
12080       char *result = XNEWVEC (char, strlen (class_name)
12081                               + strlen (selector) + 5);
12082
12083       if (is_class_method)
12084         sprintf (result, "+[%s %s]", class_name, selector);
12085       else
12086         sprintf (result, "-[%s %s]", class_name, selector);
12087
12088       return result;      
12089     }
12090 }
12091 #endif
12092
12093 /* Demangle function for Objective-C.  Attempt to demangle the
12094    function name associated with a method (eg, going from
12095    "_i_NSObject__class" to "-[NSObject class]"); usually for the
12096    purpose of pretty printing or error messages.  Return the demangled
12097    name, or NULL if the string is not an Objective-C mangled method
12098    name.
12099
12100    Because of how the mangling is done, any method that has a '_' in
12101    its original name is at risk of being demangled incorrectly.  In
12102    some cases there are multiple valid ways to demangle a method name
12103    and there is no way we can decide.
12104
12105    TODO: objc_demangle() can't always get it right; the right way to
12106    get this correct for all method names would be to store the
12107    Objective-C method name somewhere in the function decl.  Then,
12108    there is no demangling to do; we'd just pull the method name out of
12109    the decl.  As an additional bonus, when printing error messages we
12110    could check for such a method name, and if we find it, we know the
12111    function is actually an Objective-C method and we could print error
12112    messages saying "In method '+[NSObject class]" instead of "In
12113    function '+[NSObject class]" as we do now.  */
12114 static const char *
12115 objc_demangle (const char *mangled)
12116 {
12117   char *demangled, *cp;
12118
12119   if (mangled[0] == '_' &&
12120       (mangled[1] == 'i' || mangled[1] == 'c') &&
12121       mangled[2] == '_')
12122     {
12123       cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
12124       if (mangled[1] == 'i')
12125         *cp++ = '-';            /* for instance method */
12126       else
12127         *cp++ = '+';            /* for class method */
12128       *cp++ = '[';              /* opening left brace */
12129       strcpy(cp, mangled+3);    /* tack on the rest of the mangled name */
12130       while (*cp && *cp == '_')
12131         cp++;                   /* skip any initial underbars in class name */
12132       cp = strchr(cp, '_');     /* find first non-initial underbar */
12133       if (cp == NULL)
12134         {
12135           free(demangled);      /* not mangled name */
12136           return NULL;
12137         }
12138       if (cp[1] == '_')  /* easy case: no category name */
12139         {
12140           *cp++ = ' ';            /* replace two '_' with one ' ' */
12141           strcpy(cp, mangled + (cp - demangled) + 2);
12142         }
12143       else
12144         {
12145           *cp++ = '(';            /* less easy case: category name */
12146           cp = strchr(cp, '_');
12147           if (cp == 0)
12148             {
12149               free(demangled);    /* not mangled name */
12150               return NULL;
12151             }
12152           *cp++ = ')';
12153           *cp++ = ' ';            /* overwriting 1st char of method name... */
12154           strcpy(cp, mangled + (cp - demangled)); /* get it back */
12155         }
12156       /* Now we have the method name.  We need to generally replace
12157          '_' with ':' but trying to preserve '_' if it could only have
12158          been in the mangled string because it was already in the
12159          original name.  In cases where it's ambiguous, we assume that
12160          any '_' originated from a ':'.  */
12161
12162       /* Initial '_'s in method name can't have been generating by
12163          converting ':'s.  Skip them.  */
12164       while (*cp && *cp == '_')
12165         cp++;
12166
12167       /* If the method name does not end with '_', then it has no
12168          arguments and there was no replacement of ':'s with '_'s
12169          during mangling.  Check for that case, and skip any
12170          replacement if so.  This at least guarantees that methods
12171          with no arguments are always demangled correctly (unless the
12172          original name ends with '_').  */
12173       if (*(mangled + strlen (mangled) - 1) != '_')
12174         {
12175           /* Skip to the end.  */
12176           for (; *cp; cp++)
12177             ;
12178         }
12179       else
12180         {
12181           /* Replace remaining '_' with ':'.  This may get it wrong if
12182              there were '_'s in the original name.  In most cases it
12183              is impossible to disambiguate.  */
12184           for (; *cp; cp++)
12185             if (*cp == '_')
12186               *cp = ':';         
12187         }
12188       *cp++ = ']';              /* closing right brace */
12189       *cp++ = 0;                /* string terminator */
12190       return demangled;
12191     }
12192   else
12193     return NULL;             /* not an objc mangled name */
12194 }
12195
12196 /* Try to pretty-print a decl.  If the 'decl' is an Objective-C
12197    specific decl, return the printable name for it.  If not, return
12198    NULL.  */
12199 const char *
12200 objc_maybe_printable_name (tree decl, int v ATTRIBUTE_UNUSED)
12201 {
12202   switch (TREE_CODE (decl))
12203     {
12204     case FUNCTION_DECL:
12205       return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
12206       break;
12207
12208       /* The following happens when we are printing a deprecation
12209          warning for a method.  The warn_deprecation() will end up
12210          trying to print the decl for INSTANCE_METHOD_DECL or
12211          CLASS_METHOD_DECL.  It would be nice to be able to print
12212          "-[NSObject autorelease] is deprecated", but to do that, we'd
12213          need to store the class and method name in the method decl,
12214          which we currently don't do.  For now, just return the name
12215          of the method.  We don't return NULL, because that may
12216          trigger further attempts to pretty-print the decl in C/C++,
12217          but they wouldn't know how to pretty-print it.  */
12218     case INSTANCE_METHOD_DECL:
12219     case CLASS_METHOD_DECL:
12220       return IDENTIFIER_POINTER (DECL_NAME (decl));
12221       break;
12222       /* This happens when printing a deprecation warning for a
12223          property.  We may want to consider some sort of pretty
12224          printing (eg, include the class name where it was declared
12225          ?).  */
12226     case PROPERTY_DECL:
12227       return IDENTIFIER_POINTER (PROPERTY_NAME (decl));
12228       break;
12229     default:
12230       return NULL;
12231       break;
12232     }
12233 }
12234
12235 /* Return a printable name for 'decl'.  This first tries
12236    objc_maybe_printable_name(), and if that fails, it returns the name
12237    in the decl.  This is used as LANG_HOOKS_DECL_PRINTABLE_NAME for
12238    Objective-C; in Objective-C++, setting the hook is not enough
12239    because lots of C++ Front-End code calls cxx_printable_name,
12240    dump_decl and other C++ functions directly.  So instead we have
12241    modified dump_decl to call objc_maybe_printable_name directly.  */
12242 const char *
12243 objc_printable_name (tree decl, int v)
12244 {
12245   const char *demangled_name = objc_maybe_printable_name (decl, v);
12246
12247   if (demangled_name != NULL)
12248     return demangled_name;
12249   else
12250     return IDENTIFIER_POINTER (DECL_NAME (decl));
12251 }
12252
12253 static void
12254 init_objc (void)
12255 {
12256   gcc_obstack_init (&util_obstack);
12257   util_firstobj = (char *) obstack_finish (&util_obstack);
12258
12259   errbuf = XNEWVEC (char, 1024 * 10);
12260   hash_init ();
12261   synth_module_prologue ();
12262 }
12263 \f
12264 static void
12265 finish_objc (void)
12266 {
12267   struct imp_entry *impent;
12268   tree chain;
12269   /* The internally generated initializers appear to have missing braces.
12270      Don't warn about this.  */
12271   int save_warn_missing_braces = warn_missing_braces;
12272   warn_missing_braces = 0;
12273
12274   /* A missing @end may not be detected by the parser.  */
12275   if (objc_implementation_context)
12276     {
12277       warning (0, "%<@end%> missing in implementation context");
12278       finish_class (objc_implementation_context);
12279       objc_ivar_chain = NULL_TREE;
12280       objc_implementation_context = NULL_TREE;
12281     }
12282
12283   /* Process the static instances here because initialization of objc_symtab
12284      depends on them.  */
12285   if (objc_static_instances)
12286     generate_static_references ();
12287
12288   /* forward declare categories */
12289   if (cat_count)
12290     forward_declare_categories ();
12291
12292   for (impent = imp_list; impent; impent = impent->next)
12293     {
12294       objc_implementation_context = impent->imp_context;
12295       implementation_template = impent->imp_template;
12296
12297       /* FIXME: This needs reworking to be more obvious.  */
12298
12299       UOBJC_CLASS_decl = impent->class_decl;
12300       UOBJC_METACLASS_decl = impent->meta_decl;
12301
12302       /* Dump the @interface of each class as we compile it, if the
12303          -gen-decls option is in use.  TODO: Dump the classes in the
12304          order they were found, rather than in reverse order as we
12305          are doing now.  */
12306       if (flag_gen_declaration)
12307         {
12308           dump_interface (gen_declaration_file, objc_implementation_context);
12309         }
12310
12311       if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
12312         {
12313           /* all of the following reference the string pool...  */
12314           generate_ivar_lists ();
12315           generate_dispatch_tables ();
12316           generate_shared_structures (impent);
12317         }
12318       else
12319         {
12320           generate_dispatch_tables ();
12321           generate_category (impent);
12322         }
12323
12324       impent->class_decl = UOBJC_CLASS_decl;
12325       impent->meta_decl = UOBJC_METACLASS_decl;
12326     }
12327
12328   /* If we are using an array of selectors, we must always
12329      finish up the array decl even if no selectors were used.  */
12330   if (flag_next_runtime)
12331     build_next_selector_translation_table ();
12332   else
12333     build_gnu_selector_translation_table ();
12334
12335   if (protocol_chain)
12336     generate_protocols ();
12337
12338   if (flag_next_runtime)
12339     generate_objc_image_info ();
12340
12341   if (imp_list || class_names_chain
12342       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
12343     generate_objc_symtab_decl ();
12344
12345   /* Arrange for ObjC data structures to be initialized at run time.  */
12346   if (objc_implementation_context || class_names_chain || objc_static_instances
12347       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
12348     {
12349       build_module_descriptor ();
12350
12351       if (!flag_next_runtime)
12352         build_module_initializer_routine ();
12353     }
12354
12355   /* Dump the class references.  This forces the appropriate classes
12356      to be linked into the executable image, preserving unix archive
12357      semantics.  This can be removed when we move to a more dynamically
12358      linked environment.  */
12359
12360   for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
12361     {
12362       handle_class_ref (chain);
12363       if (TREE_PURPOSE (chain))
12364         generate_classref_translation_entry (chain);
12365     }
12366
12367   for (impent = imp_list; impent; impent = impent->next)
12368     handle_impent (impent);
12369
12370   if (warn_selector)
12371     {
12372       int slot;
12373       hash hsh;
12374
12375       /* Run through the selector hash tables and print a warning for any
12376          selector which has multiple methods.  */
12377
12378       for (slot = 0; slot < SIZEHASHTABLE; slot++)
12379         {
12380           for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
12381             check_duplicates (hsh, 0, 1);
12382           for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
12383             check_duplicates (hsh, 0, 1);
12384         }
12385     }
12386
12387   warn_missing_braces = save_warn_missing_braces;
12388 }
12389 \f
12390 /* Subroutines of finish_objc.  */
12391
12392 static void
12393 generate_classref_translation_entry (tree chain)
12394 {
12395   tree expr, decl, type;
12396
12397   decl = TREE_PURPOSE (chain);
12398   type = TREE_TYPE (decl);
12399
12400   expr = add_objc_string (TREE_VALUE (chain), class_names);
12401   expr = convert (type, expr); /* cast! */
12402
12403   /* This is a class reference.  It is re-written by the runtime,
12404      but will be optimized away unless we force it.  */
12405   DECL_PRESERVE_P (decl) = 1;
12406   finish_var_decl (decl, expr);
12407   return;
12408 }
12409
12410 static void
12411 handle_class_ref (tree chain)
12412 {
12413   const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
12414   char *string = (char *) alloca (strlen (name) + 30);
12415   tree decl;
12416   tree exp;
12417
12418   sprintf (string, "%sobjc_class_name_%s",
12419            (flag_next_runtime ? "." : "__"), name);
12420
12421 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
12422   if (flag_next_runtime)
12423     {
12424       ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
12425       return;
12426     }
12427 #endif
12428
12429   /* Make a decl for this name, so we can use its address in a tree.  */
12430   decl = build_decl (input_location,
12431                      VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
12432   DECL_EXTERNAL (decl) = 1;
12433   TREE_PUBLIC (decl) = 1;
12434   pushdecl (decl);
12435   finish_var_decl (decl, 0);
12436
12437   /* Make a decl for the address.  */
12438   sprintf (string, "%sobjc_class_ref_%s",
12439            (flag_next_runtime ? "." : "__"), name);
12440   exp = build1 (ADDR_EXPR, string_type_node, decl);
12441   decl = build_decl (input_location,
12442                      VAR_DECL, get_identifier (string), string_type_node);
12443   TREE_STATIC (decl) = 1;
12444   TREE_USED (decl) = 1;
12445   DECL_READ_P (decl) = 1;
12446   DECL_ARTIFICIAL (decl) = 1;
12447   DECL_INITIAL (decl) = error_mark_node;
12448  
12449   /* We must force the reference.  */
12450   DECL_PRESERVE_P (decl) = 1;
12451
12452   pushdecl (decl);
12453   finish_var_decl (decl, exp);
12454 }
12455
12456 static void
12457 handle_impent (struct imp_entry *impent)
12458 {
12459   char *string;
12460
12461   objc_implementation_context = impent->imp_context;
12462   implementation_template = impent->imp_template;
12463
12464   switch (TREE_CODE (impent->imp_context))
12465     {
12466     case CLASS_IMPLEMENTATION_TYPE:
12467       {
12468         const char *const class_name =
12469           IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
12470         
12471         string = (char *) alloca (strlen (class_name) + 30);
12472         
12473         sprintf (string, "%sobjc_class_name_%s",
12474                  (flag_next_runtime ? "." : "__"), class_name);
12475         break;
12476       }
12477     case CATEGORY_IMPLEMENTATION_TYPE:
12478       {
12479         const char *const class_name =
12480           IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
12481         const char *const class_super_name =
12482           IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
12483         
12484         string = (char *) alloca (strlen (class_name)
12485                                   + strlen (class_super_name) + 30);
12486         
12487         /* Do the same for categories.  Even though no references to
12488            these symbols are generated automatically by the compiler,
12489            it gives you a handle to pull them into an archive by
12490            hand.  */
12491         sprintf (string, "*%sobjc_category_name_%s_%s",
12492                  (flag_next_runtime ? "." : "__"), class_name, class_super_name);
12493         break;
12494       }
12495     default:
12496       return;
12497     }
12498
12499 #ifdef ASM_DECLARE_CLASS_REFERENCE
12500   if (flag_next_runtime)
12501     {
12502       ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
12503       return;
12504     }
12505   else
12506 #endif
12507     {
12508       tree decl, init;
12509
12510       init = integer_zero_node;
12511       decl = build_decl (input_location,
12512                          VAR_DECL, get_identifier (string), TREE_TYPE (init));
12513       TREE_PUBLIC (decl) = 1;
12514       TREE_READONLY (decl) = 1;
12515       TREE_USED (decl) = 1;
12516       TREE_CONSTANT (decl) = 1;
12517       DECL_CONTEXT (decl) = NULL_TREE;
12518       DECL_ARTIFICIAL (decl) = 1;
12519       TREE_STATIC (decl) = 1;
12520       DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
12521       /* We must force the reference.  */
12522       DECL_PRESERVE_P (decl) = 1;
12523
12524       finish_var_decl(decl, init) ;
12525     }
12526 }
12527 \f
12528 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
12529    later requires that ObjC translation units participating in F&C be
12530    specially marked.  The following routine accomplishes this.  */
12531
12532 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
12533
12534 static void
12535 generate_objc_image_info (void)
12536 {
12537   tree decl;
12538   int flags
12539     = ((flag_replace_objc_classes && imp_count ? 1 : 0)
12540        | (flag_objc_gc ? 2 : 0));
12541   VEC(constructor_elt,gc) *v = NULL;
12542   tree array_type;
12543   
12544    if (!flags)
12545     return; /* No need for an image_info entry.  */
12546   
12547   array_type  = build_sized_array_type (integer_type_node, 2);
12548
12549   decl = start_var_decl (array_type, "_OBJC_IMAGE_INFO");
12550
12551   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
12552   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags));
12553   /* If we need this (determined above) it is because the runtime wants to
12554      refer to it in a manner hidden from the compiler.  So we must force the 
12555      output.  */
12556   DECL_PRESERVE_P (decl) = 1;
12557   finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
12558 }
12559
12560 /* Routine is called to issue diagnostic when reference to a private 
12561    ivar is made and no other variable with same name is found in 
12562    current scope.  */
12563 bool
12564 objc_diagnose_private_ivar (tree id)
12565 {
12566   tree ivar;
12567   if (!objc_method_context)
12568     return false;
12569   ivar = is_ivar (objc_ivar_chain, id);
12570   if (ivar && is_private (ivar))
12571     {
12572       error ("instance variable %qs is declared private", 
12573              IDENTIFIER_POINTER (id));
12574       return true;
12575     }
12576   return false;
12577 }
12578
12579 /* Look up ID as an instance variable.  OTHER contains the result of
12580    the C or C++ lookup, which we may want to use instead.  */
12581 /* To use properties inside an instance method, use self.property.  */
12582 tree
12583 objc_lookup_ivar (tree other, tree id)
12584 {
12585   tree ivar;
12586
12587   /* If we are not inside of an ObjC method, ivar lookup makes no sense.  */
12588   if (!objc_method_context)
12589     return other;
12590
12591   if (!strcmp (IDENTIFIER_POINTER (id), "super"))
12592     /* We have a message to super.  */
12593     return get_super_receiver ();
12594
12595   /* In a class method, look up an instance variable only as a last
12596      resort.  */
12597   if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
12598       && other && other != error_mark_node)
12599     return other;
12600
12601   /* Look up the ivar, but do not use it if it is not accessible.  */
12602   ivar = is_ivar (objc_ivar_chain, id);
12603   
12604   if (!ivar || is_private (ivar))
12605     return other;
12606
12607   /* In an instance method, a local variable (or parameter) may hide the
12608      instance variable.  */
12609   if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
12610       && other && other != error_mark_node
12611 #ifdef OBJCPLUS
12612       && CP_DECL_CONTEXT (other) != global_namespace)
12613 #else
12614       && !DECL_FILE_SCOPE_P (other))
12615 #endif
12616     {
12617       warning (0, "local declaration of %qE hides instance variable", id);
12618
12619       return other;
12620     }
12621
12622   /* At this point, we are either in an instance method with no obscuring
12623      local definitions, or in a class method with no alternate definitions
12624      at all.  */
12625   return build_ivar_reference (id);
12626 }
12627
12628 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression.  This
12629    needs to be done if we are calling a function through a cast.  */
12630
12631 tree
12632 objc_rewrite_function_call (tree function, tree first_param)
12633 {
12634   if (TREE_CODE (function) == NOP_EXPR
12635       && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
12636       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
12637          == FUNCTION_DECL)
12638     {
12639       function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
12640                          TREE_OPERAND (function, 0),
12641                          first_param, size_zero_node);
12642     }
12643
12644   return function;
12645 }
12646
12647 /* This is called to "gimplify" a PROPERTY_REF node.  It builds the
12648    corresponding 'getter' function call.  Note that we assume the
12649    PROPERTY_REF to be valid since we generated it while parsing.  */
12650 static void
12651 objc_gimplify_property_ref (tree *expr_p)
12652 {
12653   tree getter = PROPERTY_REF_GETTER_CALL (*expr_p);
12654   tree call_exp;
12655
12656   if (getter == NULL_TREE)
12657     {
12658       tree property_decl = PROPERTY_REF_PROPERTY_DECL (*expr_p);
12659       /* This can happen if DECL_ARTIFICIAL (*expr_p), but
12660          should be impossible for real properties, which always
12661          have a getter.  */
12662       error_at (EXPR_LOCATION (*expr_p), "no %qs getter found",
12663                 IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
12664       /* Try to recover from the error to prevent an ICE.  We take
12665          zero and cast it to the type of the property.  */
12666       *expr_p = convert (TREE_TYPE (property_decl),
12667                          integer_zero_node);
12668       return;
12669     }
12670
12671   call_exp = getter;
12672 #ifdef OBJCPLUS
12673   /* In C++, a getter which returns an aggregate value results in a
12674      target_expr which initializes a temporary to the call
12675      expression.  */
12676   if (TREE_CODE (getter) == TARGET_EXPR)
12677     {
12678       gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter)));
12679       gcc_assert (TREE_CODE (TREE_OPERAND (getter, 0)) == VAR_DECL);
12680       call_exp = TREE_OPERAND (getter, 1);
12681     }
12682 #endif
12683   gcc_assert (TREE_CODE (call_exp) == CALL_EXPR);
12684   
12685   *expr_p = call_exp;
12686 }
12687
12688 /* This is called when "gimplifying" the trees.  We need to gimplify
12689    the Objective-C/Objective-C++ specific trees, then hand over the
12690    process to C/C++.  */
12691 int
12692 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
12693 {
12694   enum tree_code code = TREE_CODE (*expr_p);
12695   switch (code)
12696     {
12697       /* Look for the special case of OBJC_TYPE_REF with the address
12698          of a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend
12699          or one of its cousins).  */
12700     case OBJ_TYPE_REF:
12701       if (TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
12702           && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
12703           == FUNCTION_DECL)
12704         {
12705           enum gimplify_status r0, r1;
12706
12707           /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
12708              value of the OBJ_TYPE_REF, so force them to be emitted
12709              during subexpression evaluation rather than after the
12710              OBJ_TYPE_REF. This permits objc_msgSend calls in
12711              Objective C to use direct rather than indirect calls when
12712              the object expression has a postincrement.  */
12713           r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
12714                               is_gimple_val, fb_rvalue);
12715           r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
12716                               is_gimple_val, fb_rvalue);
12717           
12718           return MIN (r0, r1);
12719         }
12720       break;
12721     case PROPERTY_REF:
12722       objc_gimplify_property_ref (expr_p);
12723       /* Do not return yet; let C/C++ gimplify the resulting expression.  */
12724       break;
12725     default:
12726       break;
12727     }
12728
12729 #ifdef OBJCPLUS
12730   return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
12731 #else
12732   return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
12733 #endif
12734 }
12735
12736 /* This routine returns true if TYPE is a valid objc object type,
12737    suitable for messaging; false otherwise.  If 'accept_class' is
12738    'true', then a Class object is considered valid for messaging and
12739    'true' is returned if 'type' refers to a Class.  If 'accept_class'
12740    is 'false', then a Class object is not considered valid for
12741    messaging and 'false' is returned in that case.  */
12742
12743 static bool
12744 objc_type_valid_for_messaging (tree type, bool accept_classes)
12745 {
12746   if (!POINTER_TYPE_P (type))
12747     return false;
12748
12749   /* Remove the pointer indirection; don't remove more than one
12750      otherwise we'd consider "NSObject **" a valid type for messaging,
12751      which it isn't.  */
12752   type = TREE_TYPE (type);
12753
12754   if (TREE_CODE (type) != RECORD_TYPE)
12755     return false;
12756
12757   if (objc_is_object_id (type))
12758     return true;
12759
12760   if (objc_is_class_id (type))
12761     return accept_classes;
12762
12763   if (TYPE_HAS_OBJC_INFO (type))
12764     return true;
12765
12766   return false;
12767 }
12768
12769 /* Begin code generation for fast enumeration (foreach) ... */
12770
12771 /* Defines
12772
12773   struct __objcFastEnumerationState
12774    {
12775      unsigned long state;
12776      id            *itemsPtr;
12777      unsigned long *mutationsPtr;
12778      unsigned long extra[5];
12779    };
12780
12781    Confusingly enough, NSFastEnumeration is then defined by libraries
12782    to be the same structure.  
12783 */
12784
12785 static void
12786 build_fast_enumeration_state_template (void)
12787 {
12788   tree decls, *chain = NULL;
12789
12790   /* { */
12791   objc_fast_enumeration_state_template = objc_start_struct (get_identifier 
12792                                                             (TAG_FAST_ENUMERATION_STATE));
12793
12794   /* unsigned long state; */
12795   decls = add_field_decl (long_unsigned_type_node, "state", &chain);
12796
12797   /* id            *itemsPtr; */
12798   add_field_decl (build_pointer_type (objc_object_type), 
12799                   "itemsPtr", &chain);
12800
12801   /* unsigned long *mutationsPtr; */
12802   add_field_decl (build_pointer_type (long_unsigned_type_node), 
12803                   "mutationsPtr", &chain);
12804
12805   /* unsigned long extra[5]; */
12806   add_field_decl (build_sized_array_type (long_unsigned_type_node, 5), 
12807                   "extra", &chain);
12808
12809   /* } */
12810   objc_finish_struct (objc_fast_enumeration_state_template, decls);
12811 }
12812
12813 /*
12814   'objc_finish_foreach_loop()' generates the code for an Objective-C
12815   foreach loop.  The 'location' argument is the location of the 'for'
12816   that starts the loop.  The 'object_expression' is the expression of
12817   the 'object' that iterates; the 'collection_expression' is the
12818   expression of the collection that we iterate over (we need to make
12819   sure we evaluate this only once); the 'for_body' is the set of
12820   statements to be executed in each iteration; 'break_label' and
12821   'continue_label' are the break and continue labels which we need to
12822   emit since the <statements> may be jumping to 'break_label' (if they
12823   contain 'break') or to 'continue_label' (if they contain
12824   'continue').
12825
12826   The syntax is
12827   
12828   for (<object expression> in <collection expression>)
12829     <statements>
12830
12831   which is compiled into the following blurb:
12832
12833   {
12834     id __objc_foreach_collection;
12835     __objc_fast_enumeration_state __objc_foreach_enum_state;
12836     unsigned long __objc_foreach_batchsize;
12837     id __objc_foreach_items[16];
12838     __objc_foreach_collection = <collection expression>;
12839     __objc_foreach_enum_state = { 0 };
12840     __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16];
12841     
12842     if (__objc_foreach_batchsize == 0)
12843       <object expression> = nil;
12844     else
12845       {
12846         unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
12847         next_batch:
12848           {
12849             unsigned long __objc_foreach_index;
12850             __objc_foreach_index = 0;
12851
12852             next_object:
12853             if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
12854             <object expression> = enumState.itemsPtr[__objc_foreach_index];
12855             <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
12856
12857             continue_label:
12858             __objc_foreach_index++;
12859             if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
12860             __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16];
12861          }
12862        if (__objc_foreach_batchsize != 0) goto next_batch;
12863        <object expression> = nil;
12864        break_label:
12865       }
12866   }
12867
12868   'statements' may contain a 'continue' or 'break' instruction, which
12869   the user expects to 'continue' or 'break' the entire foreach loop.
12870   We are provided the labels that 'break' and 'continue' jump to, so
12871   we place them where we want them to jump to when they pick them.
12872   
12873   Optimization TODO: we could cache the IMP of
12874   countByEnumeratingWithState:objects:count:.
12875 */
12876
12877 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line.  */
12878 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
12879
12880 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
12881 #include "tree-pretty-print.h"
12882 #endif
12883
12884 void
12885 objc_finish_foreach_loop (location_t location, tree object_expression, tree collection_expression, tree for_body, 
12886                           tree break_label, tree continue_label)
12887 {
12888   /* A tree representing the __objcFastEnumerationState struct type,
12889      or NSFastEnumerationState struct, whatever we are using.  */
12890   tree objc_fast_enumeration_state_type;
12891
12892   /* The trees representing the declarations of each of the local variables.  */
12893   tree objc_foreach_collection_decl;
12894   tree objc_foreach_enum_state_decl;
12895   tree objc_foreach_items_decl;
12896   tree objc_foreach_batchsize_decl;
12897   tree objc_foreach_mutations_pointer_decl;
12898   tree objc_foreach_index_decl;
12899
12900   /* A tree representing the selector countByEnumeratingWithState:objects:count:.  */
12901   tree selector_name;
12902
12903   /* A tree representing the local bind.  */
12904   tree bind;
12905
12906   /* A tree representing the external 'if (__objc_foreach_batchsize)' */
12907   tree first_if;
12908
12909   /* A tree representing the 'else' part of 'first_if'  */
12910   tree first_else;
12911
12912   /* A tree representing the 'next_batch' label.  */
12913   tree next_batch_label_decl;
12914
12915   /* A tree representing the binding after the 'next_batch' label.  */
12916   tree next_batch_bind;
12917
12918   /* A tree representing the 'next_object' label.  */
12919   tree next_object_label_decl;
12920
12921   /* Temporary variables.  */
12922   tree t;
12923   int i;
12924
12925   if (flag_objc1_only)
12926     error_at (location, "fast enumeration is not available in Objective-C 1.0");
12927
12928   if (object_expression == error_mark_node)
12929     return;
12930
12931   if (collection_expression == error_mark_node)
12932     return;
12933
12934   if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression), true))
12935     {
12936       error ("iterating variable in fast enumeration is not an object");
12937       return;
12938     }
12939
12940   if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression), true))
12941     {
12942       error ("collection in fast enumeration is not an object");
12943       return;
12944     }
12945
12946   /* TODO: Check that object_expression is either a variable
12947      declaration, or an lvalue.  */
12948
12949   /* This kludge is an idea from apple.  We use the
12950      __objcFastEnumerationState struct implicitly defined by the
12951      compiler, unless a NSFastEnumerationState struct has been defined
12952      (by a Foundation library such as GNUstep Base) in which case, we
12953      use that one.
12954   */
12955   objc_fast_enumeration_state_type = objc_fast_enumeration_state_template;
12956   {
12957     tree objc_NSFastEnumeration_type = lookup_name (get_identifier ("NSFastEnumerationState"));
12958
12959     if (objc_NSFastEnumeration_type)
12960       {
12961         /* TODO: We really need to check that
12962            objc_NSFastEnumeration_type is the same as ours!  */
12963         if (TREE_CODE (objc_NSFastEnumeration_type) == TYPE_DECL)
12964           {
12965             /* If it's a typedef, use the original type.  */
12966             if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type))
12967               objc_fast_enumeration_state_type = DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type);
12968             else
12969               objc_fast_enumeration_state_type = TREE_TYPE (objc_NSFastEnumeration_type);             
12970           }
12971       }
12972   }
12973
12974   /* { */
12975   /* Done by c-parser.c.  */
12976
12977   /* type object; */
12978   /* Done by c-parser.c.  */
12979
12980   /*  id __objc_foreach_collection */
12981   objc_foreach_collection_decl = objc_create_temporary_var (objc_object_type, "__objc_foreach_collection");
12982
12983   /*  __objcFastEnumerationState __objc_foreach_enum_state; */
12984   objc_foreach_enum_state_decl = objc_create_temporary_var (objc_fast_enumeration_state_type, "__objc_foreach_enum_state");
12985   TREE_CHAIN (objc_foreach_enum_state_decl) = objc_foreach_collection_decl;
12986
12987   /* id __objc_foreach_items[16]; */
12988   objc_foreach_items_decl = objc_create_temporary_var (build_sized_array_type (objc_object_type, 16), "__objc_foreach_items");
12989   TREE_CHAIN (objc_foreach_items_decl) = objc_foreach_enum_state_decl;
12990
12991   /* unsigned long __objc_foreach_batchsize; */
12992   objc_foreach_batchsize_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_batchsize");
12993   TREE_CHAIN (objc_foreach_batchsize_decl) = objc_foreach_items_decl;
12994
12995   /* Generate the local variable binding.  */
12996   bind = build3 (BIND_EXPR, void_type_node, objc_foreach_batchsize_decl, NULL, NULL);
12997   SET_EXPR_LOCATION (bind, location);
12998   TREE_SIDE_EFFECTS (bind) = 1;
12999   
13000   /*  __objc_foreach_collection = <collection expression>; */
13001   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_collection_decl, collection_expression);
13002   SET_EXPR_LOCATION (t, location);
13003   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13004
13005   /*  __objc_foreach_enum_state.state = 0; */
13006   t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl, 
13007                                                                      get_identifier ("state")),
13008               build_int_cst (long_unsigned_type_node, 0));
13009   SET_EXPR_LOCATION (t, location);
13010   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13011
13012   /*  __objc_foreach_enum_state.itemsPtr = NULL; */
13013   t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl, 
13014                                                                      get_identifier ("itemsPtr")),
13015               null_pointer_node);
13016   SET_EXPR_LOCATION (t, location);
13017   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13018
13019   /*  __objc_foreach_enum_state.mutationsPtr = NULL; */
13020   t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl, 
13021                                                                      get_identifier ("mutationsPtr")),
13022               null_pointer_node);
13023   SET_EXPR_LOCATION (t, location);
13024   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13025
13026   /*  __objc_foreach_enum_state.extra[0] = 0; */
13027   /*  __objc_foreach_enum_state.extra[1] = 0; */
13028   /*  __objc_foreach_enum_state.extra[2] = 0; */
13029   /*  __objc_foreach_enum_state.extra[3] = 0; */
13030   /*  __objc_foreach_enum_state.extra[4] = 0; */
13031   for (i = 0; i < 5 ; i++)
13032     {
13033       t = build2 (MODIFY_EXPR, void_type_node,
13034                   build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl, 
13035                                                                        get_identifier ("extra")),
13036                                    build_int_cst (NULL_TREE, i)),
13037                   build_int_cst (long_unsigned_type_node, 0));
13038       SET_EXPR_LOCATION (t, location);
13039       append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13040     }
13041     
13042   /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16]; */
13043   selector_name = get_identifier ("countByEnumeratingWithState:objects:count:");
13044 #ifdef OBJCPLUS
13045   t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13046                                 /* Parameters.  */
13047                                 tree_cons    /* &__objc_foreach_enum_state */
13048                                 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13049                                  tree_cons   /* __objc_foreach_items  */
13050                                  (NULL_TREE, objc_foreach_items_decl,
13051                                   tree_cons  /* 16 */
13052                                   (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13053 #else
13054   /* In C, we need to decay the __objc_foreach_items array that we are passing.  */
13055   {
13056     struct c_expr array;
13057     array.value = objc_foreach_items_decl;
13058     t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13059                                   /* Parameters.  */
13060                                   tree_cons    /* &__objc_foreach_enum_state */
13061                                   (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13062                                    tree_cons   /* __objc_foreach_items  */
13063                                    (NULL_TREE, default_function_array_conversion (location, array).value,
13064                                     tree_cons  /* 16 */
13065                                     (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13066   }
13067 #endif
13068   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
13069               convert (long_unsigned_type_node, t));
13070   SET_EXPR_LOCATION (t, location);
13071   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13072
13073   /* if (__objc_foreach_batchsize == 0) */
13074   first_if = build3 (COND_EXPR, void_type_node, 
13075                      /* Condition.  */
13076                      c_fully_fold 
13077                      (c_common_truthvalue_conversion 
13078                       (location, 
13079                        build_binary_op (location,
13080                                         EQ_EXPR, 
13081                                         objc_foreach_batchsize_decl,
13082                                         build_int_cst (long_unsigned_type_node, 0), 1)),
13083                       false, NULL),
13084                      /* Then block (we fill it in later).  */
13085                      NULL_TREE,
13086                      /* Else block (we fill it in later).  */
13087                      NULL_TREE);
13088   SET_EXPR_LOCATION (first_if, location);
13089   append_to_statement_list (first_if, &BIND_EXPR_BODY (bind));
13090
13091   /* then <object expression> = nil; */
13092   t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
13093   SET_EXPR_LOCATION (t, location);
13094   COND_EXPR_THEN (first_if) = t;
13095
13096   /* Now we build the 'else' part of the if; once we finish building
13097      it, we attach it to first_if as the 'else' part.  */
13098
13099   /* else */
13100   /* { */
13101
13102   /* unsigned long __objc_foreach_mutations_pointer; */
13103   objc_foreach_mutations_pointer_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_mutations_pointer");
13104
13105   /* Generate the local variable binding.  */
13106   first_else = build3 (BIND_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, NULL, NULL);
13107   SET_EXPR_LOCATION (first_else, location);
13108   TREE_SIDE_EFFECTS (first_else) = 1;
13109
13110   /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
13111   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, 
13112               build_indirect_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl, 
13113                                                                       get_identifier ("mutationsPtr")),
13114                                   RO_UNARY_STAR));
13115   SET_EXPR_LOCATION (t, location);
13116   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13117
13118   /* next_batch: */
13119   next_batch_label_decl = create_artificial_label (location);
13120   t = build1 (LABEL_EXPR, void_type_node, next_batch_label_decl); 
13121   SET_EXPR_LOCATION (t, location);
13122   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13123   
13124   /* { */
13125
13126   /* unsigned long __objc_foreach_index; */
13127   objc_foreach_index_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_index");
13128
13129   /* Generate the local variable binding.  */
13130   next_batch_bind = build3 (BIND_EXPR, void_type_node, objc_foreach_index_decl, NULL, NULL);
13131   SET_EXPR_LOCATION (next_batch_bind, location);
13132   TREE_SIDE_EFFECTS (next_batch_bind) = 1;
13133   append_to_statement_list (next_batch_bind, &BIND_EXPR_BODY (first_else));
13134
13135   /* __objc_foreach_index = 0; */
13136   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
13137               build_int_cst (long_unsigned_type_node, 0));
13138   SET_EXPR_LOCATION (t, location);
13139   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13140
13141   /* next_object: */
13142   next_object_label_decl = create_artificial_label (location);
13143   t = build1 (LABEL_EXPR, void_type_node, next_object_label_decl);
13144   SET_EXPR_LOCATION (t, location);
13145   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13146
13147   /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
13148   t = build3 (COND_EXPR, void_type_node, 
13149               /* Condition.  */
13150               c_fully_fold 
13151               (c_common_truthvalue_conversion 
13152                (location, 
13153                 build_binary_op 
13154                 (location,
13155                  NE_EXPR, 
13156                  objc_foreach_mutations_pointer_decl,
13157                  build_indirect_ref (location, 
13158                                      objc_build_component_ref (objc_foreach_enum_state_decl, 
13159                                                                get_identifier ("mutationsPtr")),
13160                                      RO_UNARY_STAR), 1)),
13161                false, NULL),
13162               /* Then block.  */
13163               build_function_call (input_location,
13164                                    objc_enumeration_mutation_decl,
13165                                    tree_cons (NULL, collection_expression, NULL)),
13166               /* Else block.  */
13167               NULL_TREE);
13168   SET_EXPR_LOCATION (t, location);
13169   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13170
13171   /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
13172   t = build2 (MODIFY_EXPR, void_type_node, object_expression, 
13173               build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl, 
13174                                                                    get_identifier ("itemsPtr")),
13175                                objc_foreach_index_decl));
13176   SET_EXPR_LOCATION (t, location);
13177   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13178
13179   /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
13180   append_to_statement_list (for_body, &BIND_EXPR_BODY (next_batch_bind));
13181
13182   /* continue_label: */
13183   if (continue_label)
13184     {
13185       t = build1 (LABEL_EXPR, void_type_node, continue_label);
13186       SET_EXPR_LOCATION (t, location);
13187       append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13188     }
13189
13190   /* __objc_foreach_index++; */
13191   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl, 
13192               build_binary_op (location,
13193                                PLUS_EXPR,
13194                                objc_foreach_index_decl,
13195                                build_int_cst (long_unsigned_type_node, 1), 1));
13196   SET_EXPR_LOCATION (t, location);
13197   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13198
13199   /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
13200   t = build3 (COND_EXPR, void_type_node, 
13201               /* Condition.  */
13202               c_fully_fold 
13203               (c_common_truthvalue_conversion 
13204                (location, 
13205                 build_binary_op (location,
13206                                  LT_EXPR, 
13207                                  objc_foreach_index_decl,
13208                                  objc_foreach_batchsize_decl, 1)),
13209                false, NULL),
13210               /* Then block.  */
13211               build1 (GOTO_EXPR, void_type_node, next_object_label_decl),
13212               /* Else block.  */
13213               NULL_TREE);
13214   SET_EXPR_LOCATION (t, location);
13215   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13216   
13217   /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state  objects: __objc_foreach_items  count: 16]; */
13218 #ifdef OBJCPLUS
13219   t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13220                                 /* Parameters.  */
13221                                 tree_cons    /* &__objc_foreach_enum_state */
13222                                 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13223                                  tree_cons   /* __objc_foreach_items  */
13224                                  (NULL_TREE, objc_foreach_items_decl,
13225                                   tree_cons  /* 16 */
13226                                   (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13227 #else
13228   /* In C, we need to decay the __objc_foreach_items array that we are passing.  */
13229   {
13230     struct c_expr array;
13231     array.value = objc_foreach_items_decl;
13232     t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13233                                   /* Parameters.  */
13234                                   tree_cons    /* &__objc_foreach_enum_state */
13235                                   (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13236                                    tree_cons   /* __objc_foreach_items  */
13237                                    (NULL_TREE, default_function_array_conversion (location, array).value,
13238                                     tree_cons  /* 16 */
13239                                     (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13240   }
13241 #endif
13242   t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl, 
13243               convert (long_unsigned_type_node, t));
13244   SET_EXPR_LOCATION (t, location);
13245   append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13246
13247   /* } */
13248
13249   /* if (__objc_foreach_batchsize != 0) goto next_batch; */
13250   t = build3 (COND_EXPR, void_type_node, 
13251               /* Condition.  */
13252               c_fully_fold 
13253               (c_common_truthvalue_conversion 
13254                (location, 
13255                 build_binary_op (location,
13256                                  NE_EXPR, 
13257                                  objc_foreach_batchsize_decl,
13258                                  build_int_cst (long_unsigned_type_node, 0), 1)),
13259                false, NULL),
13260               /* Then block.  */
13261               build1 (GOTO_EXPR, void_type_node, next_batch_label_decl),
13262               /* Else block.  */
13263               NULL_TREE);
13264   SET_EXPR_LOCATION (t, location);
13265   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13266
13267   /* <object expression> = nil; */
13268   t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
13269   SET_EXPR_LOCATION (t, location);
13270   append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13271
13272   /* break_label: */
13273   if (break_label)
13274     {
13275       t = build1 (LABEL_EXPR, void_type_node, break_label);
13276       SET_EXPR_LOCATION (t, location);
13277       append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13278     }
13279
13280   /* } */
13281   COND_EXPR_ELSE (first_if) = first_else;
13282
13283   /* Do the whole thing.  */
13284   add_stmt (bind);
13285
13286 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
13287   /* This will print to stderr the whole blurb generated by the
13288      compiler while compiling (assuming the compiler doesn't crash
13289      before getting here).
13290    */
13291   debug_generic_stmt (bind);
13292 #endif
13293
13294   /* } */
13295   /* Done by c-parser.c  */
13296 }
13297
13298 /* Return true if we have an NxString object pointer.  */
13299
13300 bool
13301 objc_string_ref_type_p (tree strp)
13302 {
13303   tree tmv;
13304   if (!strp || TREE_CODE (strp) != POINTER_TYPE)
13305     return false;
13306
13307   tmv = TYPE_MAIN_VARIANT (TREE_TYPE (strp));
13308   tmv = OBJC_TYPE_NAME (tmv);
13309   return (tmv
13310           && TREE_CODE (tmv) == IDENTIFIER_NODE
13311           && IDENTIFIER_POINTER (tmv)
13312           && !strncmp (IDENTIFIER_POINTER (tmv), "NSString", 8));
13313 }
13314
13315 /* At present the behavior of this is undefined and it does nothing.  */
13316 void
13317 objc_check_format_arg (tree ARG_UNUSED (format_arg), 
13318                        tree ARG_UNUSED (args_list))
13319 {
13320 }
13321
13322 #include "gt-objc-objc-act.h"