OSDN Git Service

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