OSDN Git Service

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