OSDN Git Service

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