OSDN Git Service

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