OSDN Git Service

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