OSDN Git Service

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