OSDN Git Service

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