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