OSDN Git Service

f760aad700a9d49e9b190d5502e94a2087487557
[pf3gnuchains/gcc-fork.git] / gcc / objc / objc-act.c
1 /* Implement classes and message passing for Objective C.
2    Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3    2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
4    Free Software Foundation, Inc.
5    Contributed by Steve Naroff.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
13
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
28
29 #ifdef OBJCPLUS
30 #include "cp-tree.h"
31 #else
32 #include "c-tree.h"
33 #include "c-lang.h"
34 #endif
35
36 #include "c-family/c-common.h"
37 #include "c-family/c-objc.h"
38 #include "c-family/c-pragma.h"
39 #include "c-family/c-format.h"
40 #include "flags.h"
41 #include "langhooks.h"
42 #include "objc-act.h"
43 #include "input.h"
44 #include "function.h"
45 #include "output.h"
46 #include "toplev.h"
47 #include "ggc.h"
48 #include "debug.h"
49 #include "target.h"
50 #include "diagnostic-core.h"
51 #include "intl.h"
52 #include "cgraph.h"
53 #include "tree-iterator.h"
54 #include "hashtab.h"
55 #include "langhooks-def.h"
56
57 /* For default_tree_printer ().  */
58 #include "tree-pretty-print.h"
59
60 /* For enum gimplify_status */
61 #include "gimple.h"
62
63 #define OBJC_VOID_AT_END        void_list_node
64
65 static unsigned int should_call_super_dealloc = 0;
66
67 /* When building Objective-C++, we are not linking against the C front-end
68    and so need to replicate the C tree-construction functions in some way.  */
69 #ifdef OBJCPLUS
70 #define OBJCP_REMAP_FUNCTIONS
71 #include "objcp-decl.h"
72 #endif  /* OBJCPLUS */
73
74 /* This is the default way of generating a method name.  */
75 /* This has the problem that "test_method:argument:" and
76    "test:method_argument:" will generate the same name
77    ("_i_Test__test_method_argument_" for an instance method of the
78    class "Test"), so you can't have them both in the same class!
79    Moreover, the demangling (going from
80    "_i_Test__test_method_argument" back to the original name) is
81    undefined because there are two correct ways of demangling the
82    name.  */
83 #ifndef OBJC_GEN_METHOD_LABEL
84 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
85   do {                                      \
86     char *temp;                             \
87     sprintf ((BUF), "_%s_%s_%s_%s",         \
88              ((IS_INST) ? "i" : "c"),       \
89              (CLASS_NAME),                  \
90              ((CAT_NAME)? (CAT_NAME) : ""), \
91              (SEL_NAME));                   \
92     for (temp = (BUF); *temp; temp++)       \
93       if (*temp == ':') *temp = '_';        \
94   } while (0)
95 #endif
96
97 /* These need specifying.  */
98 #ifndef OBJC_FORWARDING_STACK_OFFSET
99 #define OBJC_FORWARDING_STACK_OFFSET 0
100 #endif
101
102 #ifndef OBJC_FORWARDING_MIN_OFFSET
103 #define OBJC_FORWARDING_MIN_OFFSET 0
104 #endif
105 \f
106 /* Set up for use of obstacks.  */
107
108 #include "obstack.h"
109
110 /* This obstack is used to accumulate the encoding of a data type.  */
111 static struct obstack util_obstack;
112
113 /* This points to the beginning of obstack contents, so we can free
114    the whole contents.  */
115 char *util_firstobj;
116
117 /* The version identifies which language generation and runtime
118    the module (file) was compiled for, and is recorded in the
119    module descriptor.  */
120
121 #define OBJC_VERSION    (flag_next_runtime ? 6 : 8)
122 #define PROTOCOL_VERSION 2
123
124 /* (Decide if these can ever be validly changed.) */
125 #define OBJC_ENCODE_INLINE_DEFS         0
126 #define OBJC_ENCODE_DONT_INLINE_DEFS    1
127
128 /*** Private Interface (procedures) ***/
129
130 /* Used by compile_file.  */
131
132 static void init_objc (void);
133 static void finish_objc (void);
134
135 /* Code generation.  */
136
137 static tree objc_build_constructor (tree, VEC(constructor_elt,gc) *);
138 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
139 static tree get_proto_encoding (tree);
140 static tree lookup_interface (tree);
141 static tree objc_add_static_instance (tree, tree);
142
143 static tree start_class (enum tree_code, tree, tree, tree, tree);
144 static tree continue_class (tree);
145 static void finish_class (tree);
146 static void start_method_def (tree);
147 #ifdef OBJCPLUS
148 static void objc_start_function (tree, tree, tree, tree);
149 #else
150 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
151 #endif
152 static tree start_protocol (enum tree_code, tree, tree, tree);
153 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
154 static tree objc_add_method (tree, tree, int, bool);
155 static tree add_instance_variable (tree, objc_ivar_visibility_kind, tree);
156 static tree build_ivar_reference (tree);
157 static tree is_ivar (tree, tree);
158
159 static void build_objc_exception_stuff (void);
160 static void build_next_objc_exception_stuff (void);
161
162 /* We only need the following for ObjC; ObjC++ will use C++'s definition
163    of DERIVED_FROM_P.  */
164 #ifndef OBJCPLUS
165 static bool objc_derived_from_p (tree, tree);
166 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
167 #endif
168
169 /* Property.  */
170 static void objc_gen_property_data (tree, tree);
171 static void objc_synthesize_getter (tree, tree, tree);
172 static void objc_synthesize_setter (tree, tree, tree);
173 static char *objc_build_property_setter_name (tree);
174 static int match_proto_with_proto (tree, tree, int);
175 static tree lookup_property (tree, tree);
176 static tree lookup_property_in_list (tree, tree);
177 static tree lookup_property_in_protocol_list (tree, tree);
178 static void build_objc_property_accessor_helpers (void);
179
180 static void objc_xref_basetypes (tree, tree);
181
182 static void build_class_template (void);
183 static void build_selector_template (void);
184 static void build_category_template (void);
185 static void build_super_template (void);
186 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
187 static tree get_class_ivars (tree, bool);
188 static tree generate_protocol_list (tree);
189 static void build_protocol_reference (tree);
190
191 static void build_fast_enumeration_state_template (void);
192
193 #ifdef OBJCPLUS
194 static void objc_generate_cxx_cdtors (void);
195 #endif
196
197 /* objc attribute */
198 static void objc_decl_method_attributes (tree*, tree, int); 
199 static tree build_keyword_selector (tree);
200 static const char *synth_id_with_class_suffix (const char *, tree);
201
202 /* Hash tables to manage the global pool of method prototypes.  */
203
204 hash *nst_method_hash_list = 0;
205 hash *cls_method_hash_list = 0;
206
207 /* Hash tables to manage the global pool of class names.  */
208
209 hash *cls_name_hash_list = 0;
210 hash *als_name_hash_list = 0;
211
212 static void hash_class_name_enter (hash *, tree, tree);
213 static hash hash_class_name_lookup (hash *, tree);
214
215 static hash hash_lookup (hash *, tree);
216 static tree lookup_method (tree, tree);
217 static tree lookup_method_static (tree, tree, int);
218
219 static tree add_class (tree, tree);
220 static void add_category (tree, tree);
221 static inline tree lookup_category (tree, tree);
222
223 enum string_section
224 {
225   class_names,          /* class, category, protocol, module names */
226   meth_var_names,       /* method and variable names */
227   meth_var_types        /* method and variable type descriptors */
228 };
229
230 static tree add_objc_string (tree, enum string_section);
231 static void build_selector_table_decl (void);
232
233 /* Protocols.  */
234
235 static tree lookup_protocol (tree, bool);
236 static tree lookup_and_install_protocols (tree);
237
238 /* Type encoding.  */
239
240 static void encode_type_qualifiers (tree);
241 static void encode_type (tree, int, int);
242 static void encode_field_decl (tree, int, int);
243
244 #ifdef OBJCPLUS
245 static void really_start_method (tree, tree);
246 #else
247 static void really_start_method (tree, struct c_arg_info *);
248 #endif
249 static int comp_proto_with_proto (tree, tree, int);
250 static tree get_arg_type_list (tree, int, int);
251 static tree objc_decay_parm_type (tree);
252 static void objc_push_parm (tree);
253 #ifdef OBJCPLUS
254 static tree objc_get_parm_info (int);
255 #else
256 static struct c_arg_info *objc_get_parm_info (int);
257 #endif
258
259 /* Utilities for debugging and error diagnostics.  */
260
261 static char *gen_type_name (tree);
262 static char *gen_type_name_0 (tree);
263 static char *gen_method_decl (tree);
264 static char *gen_declaration (tree);
265
266 /* Everything else.  */
267
268 static tree create_field_decl (tree, const char *);
269 static void add_class_reference (tree);
270 static void build_protocol_template (void);
271 static tree encode_method_prototype (tree);
272 static void generate_classref_translation_entry (tree);
273 static void handle_class_ref (tree);
274 static void generate_struct_by_value_array (void)
275      ATTRIBUTE_NORETURN;
276 static void mark_referenced_methods (void);
277 static void generate_objc_image_info (void);
278 static bool objc_type_valid_for_messaging (tree type, bool allow_classes);
279
280 /*** Private Interface (data) ***/
281
282 /* Reserved tag definitions.  */
283
284 #define OBJECT_TYPEDEF_NAME             "id"
285 #define CLASS_TYPEDEF_NAME              "Class"
286
287 #define TAG_OBJECT                      "objc_object"
288 #define TAG_CLASS                       "objc_class"
289 #define TAG_SUPER                       "objc_super"
290 #define TAG_SELECTOR                    "objc_selector"
291
292 #define UTAG_CLASS                      "_objc_class"
293 #define UTAG_IVAR                       "_objc_ivar"
294 #define UTAG_IVAR_LIST                  "_objc_ivar_list"
295 #define UTAG_METHOD                     "_objc_method"
296 #define UTAG_METHOD_LIST                "_objc_method_list"
297 #define UTAG_CATEGORY                   "_objc_category"
298 #define UTAG_MODULE                     "_objc_module"
299 #define UTAG_SYMTAB                     "_objc_symtab"
300 #define UTAG_SUPER                      "_objc_super"
301 #define UTAG_SELECTOR                   "_objc_selector"
302
303 #define UTAG_PROTOCOL                   "_objc_protocol"
304 #define UTAG_METHOD_PROTOTYPE           "_objc_method_prototype"
305 #define UTAG_METHOD_PROTOTYPE_LIST      "_objc__method_prototype_list"
306
307 /* Note that the string object global name is only needed for the
308    NeXT runtime.  */
309 #define STRING_OBJECT_GLOBAL_FORMAT     "_%sClassReference"
310
311 #define PROTOCOL_OBJECT_CLASS_NAME      "Protocol"
312
313 #define TAG_ENUMERATION_MUTATION        "objc_enumerationMutation"
314 #define TAG_FAST_ENUMERATION_STATE      "__objcFastEnumerationState"
315
316 static const char *TAG_GETCLASS;
317 static const char *TAG_GETMETACLASS;
318 static const char *TAG_MSGSEND;
319 static const char *TAG_MSGSENDSUPER;
320 /* The NeXT Objective-C messenger may have two extra entry points, for use
321    when returning a structure. */
322 static const char *TAG_MSGSEND_STRET;
323 static const char *TAG_MSGSENDSUPER_STRET;
324 static const char *default_constant_string_class_name;
325
326 /* Runtime metadata flags.  */
327 #define CLS_FACTORY                     0x0001L
328 #define CLS_META                        0x0002L
329 #define CLS_HAS_CXX_STRUCTORS           0x2000L
330
331 #define OBJC_MODIFIER_STATIC            0x00000001
332 #define OBJC_MODIFIER_FINAL             0x00000002
333 #define OBJC_MODIFIER_PUBLIC            0x00000004
334 #define OBJC_MODIFIER_PRIVATE           0x00000008
335 #define OBJC_MODIFIER_PROTECTED         0x00000010
336 #define OBJC_MODIFIER_NATIVE            0x00000020
337 #define OBJC_MODIFIER_SYNCHRONIZED      0x00000040
338 #define OBJC_MODIFIER_ABSTRACT          0x00000080
339 #define OBJC_MODIFIER_VOLATILE          0x00000100
340 #define OBJC_MODIFIER_TRANSIENT         0x00000200
341 #define OBJC_MODIFIER_NONE_SPECIFIED    0x80000000
342
343 /* NeXT-specific tags.  */
344
345 #define TAG_MSGSEND_NONNIL              "objc_msgSendNonNil"
346 #define TAG_MSGSEND_NONNIL_STRET        "objc_msgSendNonNil_stret"
347 #define TAG_EXCEPTIONEXTRACT            "objc_exception_extract"
348 #define TAG_EXCEPTIONTRYENTER           "objc_exception_try_enter"
349 #define TAG_EXCEPTIONTRYEXIT            "objc_exception_try_exit"
350 #define TAG_EXCEPTIONMATCH              "objc_exception_match"
351 #define TAG_EXCEPTIONTHROW              "objc_exception_throw"
352 #define TAG_SYNCENTER                   "objc_sync_enter"
353 #define TAG_SYNCEXIT                    "objc_sync_exit"
354 #define TAG_SETJMP                      "_setjmp"
355 #define UTAG_EXCDATA                    "_objc_exception_data"
356
357 #define TAG_ASSIGNIVAR                  "objc_assign_ivar"
358 #define TAG_ASSIGNGLOBAL                "objc_assign_global"
359 #define TAG_ASSIGNSTRONGCAST            "objc_assign_strongCast"
360
361 /* Branch entry points.  All that matters here are the addresses;
362    functions with these names do not really exist in libobjc.  */
363
364 #define TAG_MSGSEND_FAST                "objc_msgSend_Fast"
365 #define TAG_ASSIGNIVAR_FAST             "objc_assign_ivar_Fast"
366
367 #define TAG_CXX_CONSTRUCT               ".cxx_construct"
368 #define TAG_CXX_DESTRUCT                ".cxx_destruct"
369
370 /* GNU-specific tags.  */
371
372 #define TAG_EXECCLASS                   "__objc_exec_class"
373 #define TAG_GNUINIT                     "__objc_gnu_init"
374
375 /* Flags for lookup_method_static().  */
376
377 /* Look for class methods.  */
378 #define OBJC_LOOKUP_CLASS       1
379 /* Do not examine superclasses.  */
380 #define OBJC_LOOKUP_NO_SUPER    2
381 /* Disable returning an instance method of a root class when a class
382    method can't be found.  */
383 #define OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS 4 
384
385 /* The OCTI_... enumeration itself is in objc/objc-act.h.  */
386 tree objc_global_trees[OCTI_MAX];
387
388 static void handle_impent (struct imp_entry *);
389
390 struct imp_entry *imp_list = 0;
391 int imp_count = 0;      /* `@implementation' */
392 int cat_count = 0;      /* `@category' */
393
394 objc_ivar_visibility_kind objc_ivar_visibility;
395
396 /* Use to generate method labels.  */
397 static int method_slot = 0;
398
399 /* Flag to say whether methods in a protocol are optional or
400    required.  */
401 static bool objc_method_optional_flag = false;
402
403 static int objc_collecting_ivars = 0;
404
405 #define BUFSIZE         1024
406
407 static char *errbuf;    /* Buffer for error diagnostics */
408
409 /* An array of all the local variables in the current function that
410    need to be marked as volatile.  */
411 VEC(tree,gc) *local_variables_to_volatilize = NULL;
412
413 \f
414 static int flag_typed_selectors;
415
416 /* Store all constructed constant strings in a hash table so that
417    they get uniqued properly.  */
418
419 struct GTY(()) string_descriptor {
420   /* The literal argument .  */
421   tree literal;
422
423   /* The resulting constant string.  */
424   tree constructor;
425 };
426
427 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
428
429 FILE *gen_declaration_file;
430
431 /* Tells "encode_pointer/encode_aggregate" whether we are generating
432    type descriptors for instance variables (as opposed to methods).
433    Type descriptors for instance variables contain more information
434    than methods (for static typing and embedded structures).  */
435
436 static int generating_instance_variables = 0;
437
438 /* For building an objc struct.  These may not be used when this file
439    is compiled as part of obj-c++.  */
440
441 static bool objc_building_struct;
442 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
443
444 /* Start building a struct for objc.  */
445
446 static tree
447 objc_start_struct (tree name)
448 {
449   gcc_assert (!objc_building_struct);
450   objc_building_struct = true;
451   return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
452 }
453
454 /* Finish building a struct for objc.  */
455
456 static tree
457 objc_finish_struct (tree type, tree fieldlist)
458 {
459   gcc_assert (objc_building_struct);
460   objc_building_struct = false;
461   return finish_struct (input_location, type, fieldlist, NULL_TREE,
462                         objc_struct_info);
463 }
464
465 static tree
466 build_sized_array_type (tree base_type, int size)
467 {
468   tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
469   return build_array_type (base_type, index_type);
470 }
471
472 static tree
473 add_field_decl (tree type, const char *name, tree **chain)
474 {
475   tree field = create_field_decl (type, name);
476
477   if (*chain != NULL)
478     **chain = field;
479   *chain = &DECL_CHAIN (field);
480
481   return field;
482 }
483
484 /* Create a temporary variable of type 'type'.  If 'name' is set, uses
485    the specified name, else use no name.  Returns the declaration of
486    the type.  The 'name' is mostly useful for debugging.
487 */
488 static tree
489 objc_create_temporary_var (tree type, const char *name)
490 {
491   tree decl;
492
493   if (name != NULL)
494     {
495       decl = build_decl (input_location,
496                          VAR_DECL, get_identifier (name), type);
497     }
498   else
499     {
500       decl = build_decl (input_location,
501                          VAR_DECL, NULL_TREE, type);
502     }
503   TREE_USED (decl) = 1;
504   DECL_ARTIFICIAL (decl) = 1;
505   DECL_IGNORED_P (decl) = 1;
506   DECL_CONTEXT (decl) = current_function_decl;
507
508   return decl;
509 }
510
511 /* Some platforms pass small structures through registers versus
512    through an invisible pointer.  Determine at what size structure is
513    the transition point between the two possibilities.  */
514
515 static void
516 generate_struct_by_value_array (void)
517 {
518   tree type;
519   tree decls;
520   int i, j;
521   int aggregate_in_mem[32];
522   int found = 0;
523
524   /* Presumably no platform passes 32 byte structures in a register.  */
525   for (i = 1; i < 32; i++)
526     {
527       char buffer[5];
528       tree *chain = NULL;
529
530       /* Create an unnamed struct that has `i' character components */
531       type = objc_start_struct (NULL_TREE);
532
533       strcpy (buffer, "c1");
534       decls = add_field_decl (char_type_node, buffer, &chain);
535
536       for (j = 1; j < i; j++)
537         {
538           sprintf (buffer, "c%d", j + 1);
539           add_field_decl (char_type_node, buffer, &chain);
540         }
541       objc_finish_struct (type, decls);
542
543       aggregate_in_mem[i] = aggregate_value_p (type, 0);
544       if (!aggregate_in_mem[i])
545         found = 1;
546     }
547
548   /* We found some structures that are returned in registers instead of memory
549      so output the necessary data.  */
550   if (found)
551     {
552       for (i = 31; i >= 0;  i--)
553         if (!aggregate_in_mem[i])
554           break;
555       printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
556
557       /* The first member of the structure is always 0 because we don't handle
558          structures with 0 members */
559       printf ("static int struct_forward_array[] = {\n  0");
560
561       for (j = 1; j <= i; j++)
562         printf (", %d", aggregate_in_mem[j]);
563       printf ("\n};\n");
564     }
565
566   exit (0);
567 }
568
569 bool
570 objc_init (void)
571 {
572 #ifdef OBJCPLUS
573   if (cxx_init () == false)
574 #else
575   if (c_objc_common_init () == false)
576 #endif
577     return false;
578
579   /* If gen_declaration desired, open the output file.  */
580   if (flag_gen_declaration)
581     {
582       register char * const dumpname = concat (dump_base_name, ".decl", NULL);
583       gen_declaration_file = fopen (dumpname, "w");
584       if (gen_declaration_file == 0)
585         fatal_error ("can%'t open %s: %m", dumpname);
586       free (dumpname);
587     }
588
589   if (flag_next_runtime)
590     {
591       TAG_GETCLASS = "objc_getClass";
592       TAG_GETMETACLASS = "objc_getMetaClass";
593       TAG_MSGSEND = "objc_msgSend";
594       TAG_MSGSENDSUPER = "objc_msgSendSuper";
595       TAG_MSGSEND_STRET = "objc_msgSend_stret";
596       TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
597       default_constant_string_class_name = "NSConstantString";
598     }
599   else
600     {
601       TAG_GETCLASS = "objc_get_class";
602       TAG_GETMETACLASS = "objc_get_meta_class";
603       TAG_MSGSEND = "objc_msg_lookup";
604       TAG_MSGSENDSUPER = "objc_msg_lookup_super";
605       /* GNU runtime does not provide special functions to support
606          structure-returning methods.  */
607       default_constant_string_class_name = "NXConstantString";
608       flag_typed_selectors = 1;
609       /* GNU runtime does not need the compiler to change code
610          in order to do GC. */
611       if (flag_objc_gc)
612         {
613           warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
614           flag_objc_gc=0;
615         }
616     }
617
618   init_objc ();
619
620   if (print_struct_values && !flag_compare_debug)
621     generate_struct_by_value_array ();
622
623   return true;
624 }
625
626 /* This is called automatically (at the very end of compilation) by
627    c_write_global_declarations and cp_write_global_declarations.  */
628 void
629 objc_write_global_declarations (void)
630 {
631   mark_referenced_methods ();
632
633   /* Finalize Objective-C runtime data.  */
634   finish_objc ();
635
636   if (gen_declaration_file)
637     fclose (gen_declaration_file);
638 }
639 \f
640 /* Return the first occurrence of a method declaration corresponding
641    to sel_name in rproto_list.  Search rproto_list recursively.
642    If is_class is 0, search for instance methods, otherwise for class
643    methods.  */
644 static tree
645 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
646                                 int is_class)
647 {
648   tree rproto, p, m;
649
650    for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
651      {
652        p = TREE_VALUE (rproto);
653        m = NULL_TREE;
654
655         if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
656           {
657             /* First, search the @required protocol methods.  */
658             if (is_class)
659               m = lookup_method (PROTOCOL_CLS_METHODS (p),  sel_name);
660             else
661               m = lookup_method (PROTOCOL_NST_METHODS (p), sel_name);
662
663             if (m)
664               return m;
665
666             /* If still not found, search the @optional protocol methods.  */
667             if (is_class)
668               m = lookup_method (PROTOCOL_OPTIONAL_CLS_METHODS (p), sel_name);
669             else
670               m = lookup_method (PROTOCOL_OPTIONAL_NST_METHODS (p), sel_name);
671
672             if (m)
673               return m;
674
675             /* If still not found, search the attached protocols.  */
676             if (PROTOCOL_LIST (p))
677               m = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
678                                                   sel_name, is_class);
679             if (m)
680               return m;
681           }
682         else
683           {
684             ; /* An identifier...if we could not find a protocol.  */
685           }
686      }
687
688    return 0;
689 }
690
691 static tree
692 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
693 {
694   tree rproto, p;
695
696   /* Make sure the protocol is supported by the object on the rhs.  */
697   if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
698     {
699       tree fnd = 0;
700       for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
701         {
702           p = TREE_VALUE (rproto);
703
704           if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
705             {
706               if (lproto == p)
707                 fnd = lproto;
708
709               else if (PROTOCOL_LIST (p))
710                 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
711             }
712
713           if (fnd)
714             return fnd;
715         }
716     }
717   else
718     {
719       ; /* An identifier...if we could not find a protocol.  */
720     }
721
722   return 0;
723 }
724
725 void
726 objc_start_class_interface (tree klass, tree super_class,
727                             tree protos, tree attributes)
728 {
729   if (flag_objc1_only && attributes)
730     error_at (input_location, "class attributes are not available in Objective-C 1.0"); 
731
732   objc_interface_context
733     = objc_ivar_context
734     = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos, attributes);
735   objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
736 }
737
738 void
739 objc_start_category_interface (tree klass, tree categ,
740                                tree protos, tree attributes)
741 {
742   if (attributes)
743     {
744       if (flag_objc1_only)
745         error_at (input_location, "category attributes are not available in Objective-C 1.0");
746       else
747         warning_at (input_location, OPT_Wattributes, 
748                     "category attributes are not available in this version"
749                     " of the compiler, (ignored)");
750     }
751   objc_interface_context
752     = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos, NULL_TREE);
753   objc_ivar_chain
754     = continue_class (objc_interface_context);
755 }
756
757 void
758 objc_start_protocol (tree name, tree protos, tree attributes)
759 {
760   if (flag_objc1_only && attributes)
761     error_at (input_location, "protocol attributes are not available in Objective-C 1.0");      
762
763   objc_interface_context
764     = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos, attributes);
765   objc_method_optional_flag = false;
766 }
767
768 void
769 objc_continue_interface (void)
770 {
771   objc_ivar_chain
772     = continue_class (objc_interface_context);
773 }
774
775 void
776 objc_finish_interface (void)
777 {
778   finish_class (objc_interface_context);
779   objc_interface_context = NULL_TREE;
780   objc_method_optional_flag = false;
781 }
782
783 void
784 objc_start_class_implementation (tree klass, tree super_class)
785 {
786   objc_implementation_context
787     = objc_ivar_context
788     = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE,
789                    NULL_TREE);
790   objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
791 }
792
793 void
794 objc_start_category_implementation (tree klass, tree categ)
795 {
796   objc_implementation_context
797     = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE,
798                    NULL_TREE);
799   objc_ivar_chain
800     = continue_class (objc_implementation_context);
801 }
802
803 void
804 objc_continue_implementation (void)
805 {
806   objc_ivar_chain
807     = continue_class (objc_implementation_context);
808 }
809
810 void
811 objc_finish_implementation (void)
812 {
813 #ifdef OBJCPLUS
814   if (flag_objc_call_cxx_cdtors)
815     objc_generate_cxx_cdtors ();
816 #endif
817
818   if (objc_implementation_context)
819     {
820       finish_class (objc_implementation_context);
821       objc_ivar_chain = NULL_TREE;
822       objc_implementation_context = NULL_TREE;
823     }
824   else
825     warning (0, "%<@end%> must appear in an @implementation context");
826 }
827
828 void
829 objc_set_visibility (objc_ivar_visibility_kind visibility)
830 {
831   if (visibility == OBJC_IVAR_VIS_PACKAGE)
832     {
833       if (flag_objc1_only)
834         error ("%<@package%> is not available in Objective-C 1.0");
835       else
836         warning (0, "%<@package%> presently has the same effect as %<@public%>");
837     }
838   objc_ivar_visibility = visibility;
839 }
840
841 void
842 objc_set_method_opt (bool optional)
843 {
844   if (flag_objc1_only)
845     error_at (input_location, "@optional/@required are not available in Objective-C 1.0");      
846
847   objc_method_optional_flag = optional;
848   if (!objc_interface_context 
849       || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
850     {
851       error ("@optional/@required is allowed in @protocol context only");
852       objc_method_optional_flag = false;
853     }
854 }
855
856 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
857    PROTOCOL.  */
858 static tree
859 lookup_property_in_list (tree chain, tree property)
860 {
861   tree x;
862   for (x = CLASS_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
863     if (PROPERTY_NAME (x) == property)
864       return x;
865   return NULL_TREE;
866 }
867
868 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
869 static tree lookup_property_in_protocol_list (tree rproto_list, tree property)
870 {
871   tree rproto, x;
872   for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
873     {
874       tree p = TREE_VALUE (rproto);
875       if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
876         {
877           if ((x = lookup_property_in_list (p, property)))
878             return x;
879           if (PROTOCOL_LIST (p))
880             return lookup_property_in_protocol_list (PROTOCOL_LIST (p), property);
881         }
882       else
883         {
884           ; /* An identifier...if we could not find a protocol.  */
885         }
886     }
887   return NULL_TREE;
888 }
889
890 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
891    chain of interface hierarchy.  */
892 static tree
893 lookup_property (tree interface_type, tree property)
894 {
895   tree inter = interface_type;
896   while (inter)
897     {
898       tree x, category;
899       if ((x = lookup_property_in_list (inter, property)))
900         return x;
901       /* Failing that, look for the property in each category of the class.  */
902       category = inter;
903       while ((category = CLASS_CATEGORY_LIST (category)))
904         {
905           if ((x = lookup_property_in_list (category, property)))
906             return x;
907
908           /* When checking a category, also check the protocols
909              attached with the category itself.  */
910           if (CLASS_PROTOCOL_LIST (category)
911               && (x = lookup_property_in_protocol_list
912                   (CLASS_PROTOCOL_LIST (category), property)))
913             return x;
914         }
915
916       /*  Failing to find in categories, look for property in protocol list. */
917       if (CLASS_PROTOCOL_LIST (inter) 
918           && (x = lookup_property_in_protocol_list
919               (CLASS_PROTOCOL_LIST (inter), property)))
920         return x;
921       
922       /* Failing that, climb up the inheritance hierarchy.  */
923       inter = lookup_interface (CLASS_SUPER_NAME (inter));
924     }
925   return inter;
926 }
927
928 /* This routine is called by the parser when a
929    @property... declaration is found.  'decl' is the declaration of
930    the property (type/identifier), and the other arguments represent
931    property attributes that may have been specified in the Objective-C
932    declaration.  'parsed_property_readonly' is 'true' if the attribute
933    'readonly' was specified, and 'false' if not; similarly for the
934    other bool parameters.  'parsed_property_getter_ident' is NULL_TREE
935    if the attribute 'getter' was not specified, and is the identifier
936    corresponding to the specified getter if it was; similarly for
937    'parsed_property_setter_ident'.  */
938 void
939 objc_add_property_declaration (location_t location, tree decl,
940                                bool parsed_property_readonly, bool parsed_property_readwrite,
941                                bool parsed_property_assign, bool parsed_property_retain,
942                                bool parsed_property_copy, bool parsed_property_nonatomic,
943                                tree parsed_property_getter_ident, tree parsed_property_setter_ident)
944 {
945   tree property_decl;
946   tree x;
947   /* 'property_readonly' and 'property_assign_semantics' are the final
948      attributes of the property after all parsed attributes have been
949      considered (eg, if we parsed no 'readonly' and no 'readwrite', ie
950      parsed_property_readonly = false and parsed_property_readwrite =
951      false, then property_readonly will be false because the default
952      is readwrite).  */
953   bool property_readonly = false;
954   objc_property_assign_semantics property_assign_semantics = OBJC_PROPERTY_ASSIGN;
955
956   if (flag_objc1_only)
957     error_at (input_location, "%<@property%> is not available in Objective-C 1.0");
958
959   if (parsed_property_readonly && parsed_property_readwrite)
960     {
961       error_at (location, "%<readonly%> attribute conflicts with %<readwrite%> attribute");
962       /* In case of conflicting attributes (here and below), after
963          producing an error, we pick one of the attributes and keep
964          going.  */
965       property_readonly = false;
966     }
967   else
968     {
969       if (parsed_property_readonly)
970         property_readonly = true;
971   
972       if (parsed_property_readwrite)
973         property_readonly = false;
974     }
975
976   if (parsed_property_readonly && parsed_property_setter_ident)
977     {
978       error_at (location, "%<readonly%> attribute conflicts with %<setter%> attribute");
979       property_readonly = false;
980     }
981
982   if (parsed_property_assign && parsed_property_retain)
983     {
984       error_at (location, "%<assign%> attribute conflicts with %<retain%> attribute");
985       property_assign_semantics = OBJC_PROPERTY_RETAIN;
986     }
987   else if (parsed_property_assign && parsed_property_copy)
988     {
989       error_at (location, "%<assign%> attribute conflicts with %<copy%> attribute");
990       property_assign_semantics = OBJC_PROPERTY_COPY;
991     }
992   else if (parsed_property_retain && parsed_property_copy)
993     {
994       error_at (location, "%<retain%> attribute conflicts with %<copy%> attribute");
995       property_assign_semantics = OBJC_PROPERTY_COPY;
996     }
997   else
998     {
999       if (parsed_property_assign)
1000         property_assign_semantics = OBJC_PROPERTY_ASSIGN;
1001
1002       if (parsed_property_retain)
1003         property_assign_semantics = OBJC_PROPERTY_RETAIN;
1004
1005       if (parsed_property_copy)
1006         property_assign_semantics = OBJC_PROPERTY_COPY;
1007     }
1008
1009   if (!objc_interface_context)
1010     {
1011       error_at (location, "property declaration not in @interface or @protocol context");
1012       return;
1013     }
1014
1015   /* At this point we know that we are either in an interface, a
1016      category, or a protocol.  */
1017
1018   /* We expect a FIELD_DECL from the parser.  Make sure we didn't get
1019      something else, as that would confuse the checks below.  */
1020   if (TREE_CODE (decl) != FIELD_DECL)
1021     {
1022       error_at (location, "invalid property declaration");
1023       return;      
1024     }
1025
1026   /* Do some spot-checks for the most obvious invalid types.  */
1027
1028   if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1029     {
1030       error_at (location, "property can not be an array");
1031       return;
1032     }
1033
1034   /* The C++/ObjC++ parser seems to reject the ':' for a bitfield when
1035      parsing, while the C/ObjC parser accepts it and gives us a
1036      FIELD_DECL with a DECL_INITIAL set.  So we use the DECL_INITIAL
1037      to check for a bitfield when doing ObjC.  */
1038 #ifndef OBJCPLUS
1039   if (DECL_INITIAL (decl))
1040     {
1041       /* A @property is not an actual variable, but it is a way to
1042          describe a pair of accessor methods, so its type (which is
1043          the type of the return value of the getter and the first
1044          argument of the setter) can't be a bitfield (as return values
1045          and arguments of functions can not be bitfields).  The
1046          underlying instance variable could be a bitfield, but that is
1047          a different matter.  */
1048       error_at (location, "property can not be a bit-field");
1049       return;      
1050     }
1051 #endif
1052
1053   /* TODO: Check that the property type is an Objective-C object or a
1054      "POD".  */
1055
1056   /* Implement -Wproperty-assign-default (which is enabled by default).  */
1057   if (warn_property_assign_default
1058       /* If garbage collection is not being used, then 'assign' is
1059          valid for objects (and typically used for delegates) but it
1060          is wrong in most cases (since most objects need to be
1061          retained or copied in setters).  Warn users when 'assign' is
1062          used implicitly.  */
1063       && property_assign_semantics == OBJC_PROPERTY_ASSIGN
1064       /* Read-only properties are never assigned, so the assignment
1065          semantics do not matter in that case.  */
1066       && !property_readonly
1067       && !flag_objc_gc)
1068     {
1069       /* Please note that it would make sense to default to 'assign'
1070          for non-{Objective-C objects}, and to 'retain' for
1071          Objective-C objects.  But that would break compatibility with
1072          other compilers.  */
1073       if (!parsed_property_assign && !parsed_property_retain && !parsed_property_copy)
1074         {
1075           /* Use 'false' so we do not warn for Class objects.  */
1076           if (objc_type_valid_for_messaging (TREE_TYPE (decl), false))
1077             {
1078               warning_at (location, 
1079                           0,
1080                           "object property %qD has no %<assign%>, %<retain%> or %<copy%> attribute; assuming %<assign%>", 
1081                           decl);
1082               inform (location, 
1083                       "%<assign%> can be unsafe for Objective-C objects; please state explicitly if you need it");
1084             }
1085         }
1086     }
1087   
1088   if (property_assign_semantics == OBJC_PROPERTY_RETAIN
1089       && !objc_type_valid_for_messaging (TREE_TYPE (decl), true))
1090     error_at (location, "%<retain%> attribute is only valid for Objective-C objects");
1091   
1092   if (property_assign_semantics == OBJC_PROPERTY_COPY
1093       && !objc_type_valid_for_messaging (TREE_TYPE (decl), true))
1094     error_at (location, "%<copy%> attribute is only valid for Objective-C objects");
1095
1096   /* Now determine the final property getter and setter names.  They
1097      will be stored in the PROPERTY_DECL, from which they'll always be
1098      extracted and used.  */
1099
1100   /* Adjust, or fill in, setter and getter names.  We overwrite the
1101      parsed_property_setter_ident and parsed_property_getter_ident
1102      with the final setter and getter identifiers that will be
1103      used.  */
1104   if (parsed_property_setter_ident)
1105     {
1106       /* The setter should be terminated by ':', but the parser only
1107          gives us an identifier without ':'.  So, we need to add ':'
1108          at the end.  */
1109       const char *parsed_setter = IDENTIFIER_POINTER (parsed_property_setter_ident);
1110       size_t length = strlen (parsed_setter);
1111       char *final_setter = (char *)alloca (length + 2);
1112
1113       sprintf (final_setter, "%s:", parsed_setter);
1114       parsed_property_setter_ident = get_identifier (final_setter);
1115     }
1116   else
1117     {
1118       if (!property_readonly)
1119         parsed_property_setter_ident = get_identifier (objc_build_property_setter_name 
1120                                                        (DECL_NAME (decl)));
1121     }
1122
1123   if (!parsed_property_getter_ident)
1124     parsed_property_getter_ident = DECL_NAME (decl);
1125
1126   /* Check for duplicate property declarations.  We first check the
1127      immediate context for a property with the same name.  Any such
1128      declarations are an error.  */
1129   for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
1130     {
1131       if (PROPERTY_NAME (x) == DECL_NAME (decl))
1132         {
1133           location_t original_location = DECL_SOURCE_LOCATION (x);
1134           
1135           error_at (location, "redeclaration of property %qD", decl);
1136
1137           if (original_location != UNKNOWN_LOCATION)
1138             inform (original_location, "originally specified here");
1139           return;
1140       }
1141     }
1142
1143   /* We now need to check for existing property declarations (in the
1144      superclass, other categories or protocols) and check that the new
1145      declaration is not in conflict with existing ones.  */
1146
1147   /* Search for a previous, existing declaration of a property with
1148      the same name in superclasses, protocols etc.  If one is found,
1149      it will be in the 'x' variable.  */
1150   x = NULL_TREE;
1151
1152   /* Note that, for simplicity, the following may search again the
1153      local context.  That's Ok as nothing will be found (else we'd
1154      have thrown an error above); it's only a little inefficient, but
1155      the code is simpler.  */
1156   switch (TREE_CODE (objc_interface_context))
1157     {
1158     case CLASS_INTERFACE_TYPE:
1159       /* Look up the property in the current @interface (which will
1160          find nothing), then its protocols and categories and
1161          superclasses.  */
1162       x = lookup_property (objc_interface_context, DECL_NAME (decl));
1163       break;
1164     case CATEGORY_INTERFACE_TYPE:
1165       /* Look up the property in the main @interface, then protocols
1166          and categories (one of them is ours, and will find nothing)
1167          and superclasses.  */
1168       x = lookup_property (lookup_interface (CLASS_NAME (objc_interface_context)),
1169                            DECL_NAME (decl));
1170       break;
1171     case PROTOCOL_INTERFACE_TYPE:
1172       /* Looks up the property in any protocols attached to the
1173          current protocol.  */
1174       if (PROTOCOL_LIST (objc_interface_context))
1175         {
1176           x = lookup_property_in_protocol_list (PROTOCOL_LIST (objc_interface_context),
1177                                                 DECL_NAME (decl));
1178         }
1179       break;
1180     default:
1181       gcc_unreachable ();
1182     }
1183
1184   if (x != NULL_TREE)
1185     {
1186       /* An existing property was found; check that it has the same
1187          types, or it is compatible.  */
1188       location_t original_location = DECL_SOURCE_LOCATION (x);
1189
1190       if (PROPERTY_NONATOMIC (x) != parsed_property_nonatomic)
1191         {
1192           warning_at (location, 0,
1193                       "'nonatomic' attribute of property %qD conflicts with previous declaration", decl);
1194       
1195           if (original_location != UNKNOWN_LOCATION)
1196             inform (original_location, "originally specified here");
1197           return;
1198         }
1199
1200       if (PROPERTY_GETTER_NAME (x) != parsed_property_getter_ident)
1201         {
1202           warning_at (location, 0,
1203                       "'getter' attribute of property %qD conflicts with previous declaration", decl);
1204       
1205           if (original_location != UNKNOWN_LOCATION)
1206             inform (original_location, "originally specified here");
1207           return;
1208         }
1209
1210       /* We can only compare the setter names if both the old and new property have a setter.  */
1211       if (!property_readonly  &&  !PROPERTY_READONLY(x))
1212         {
1213           if (PROPERTY_SETTER_NAME (x) != parsed_property_setter_ident)
1214             {
1215               warning_at (location, 0,
1216                           "'setter' attribute of property %qD conflicts with previous declaration", decl);
1217               
1218               if (original_location != UNKNOWN_LOCATION)
1219                 inform (original_location, "originally specified here");
1220               return;
1221             }
1222         }
1223
1224       if (PROPERTY_ASSIGN_SEMANTICS (x) != property_assign_semantics)
1225         {
1226           warning_at (location, 0,
1227                       "assign semantics attributes of property %qD conflict with previous declaration", decl);
1228       
1229           if (original_location != UNKNOWN_LOCATION)
1230             inform (original_location, "originally specified here");
1231           return;
1232         }
1233
1234       /* It's ok to have a readonly property that becomes a readwrite, but not vice versa.  */
1235       if (PROPERTY_READONLY (x) == 0  &&  property_readonly == 1)
1236         {
1237           warning_at (location, 0,
1238                       "'readonly' attribute of property %qD conflicts with previous declaration", decl);
1239       
1240           if (original_location != UNKNOWN_LOCATION)
1241             inform (original_location, "originally specified here");
1242           return;
1243         }
1244
1245       /* We now check that the new and old property declarations have
1246          the same types (or compatible one).  In the Objective-C
1247          tradition of loose type checking, we do type-checking but
1248          only generate warnings (not errors) if they do not match.
1249          For non-readonly properties, the types must match exactly;
1250          for readonly properties, it is allowed to use a "more
1251          specialized" type in the new property declaration.  Eg, the
1252          superclass has a getter returning (NSArray *) and the
1253          subclass a getter returning (NSMutableArray *).  The object's
1254          getter returns an (NSMutableArray *); but if you cast the
1255          object to the superclass, which is allowed, you'd still
1256          expect the getter to return an (NSArray *), which works since
1257          an (NSMutableArray *) is an (NSArray *) too.  So, the set of
1258          objects belonging to the type of the new @property should be
1259          a subset of the set of objects belonging to the type of the
1260          old @property.  This is what "specialization" means.  And the
1261          reason it only applies to readonly properties is that for a
1262          readwrite property the setter would have the opposite
1263          requirement - ie that the superclass type is more specialized
1264          then the subclass one; hence the only way to satisfy both
1265          constraints is that the types match.  */
1266
1267       /* If the types are not the same in the C sense, we warn ...  */
1268       if (!comptypes (TREE_TYPE (x), TREE_TYPE (decl))
1269           /* ... unless the property is readonly, in which case we
1270              allow a new, more specialized, declaration.  */
1271           && (!property_readonly 
1272               || !objc_compare_types (TREE_TYPE (x),
1273                                       TREE_TYPE (decl), -5, NULL_TREE)))
1274         {
1275           warning_at (location, 0,
1276                       "type of property %qD conflicts with previous declaration", decl);
1277           if (original_location != UNKNOWN_LOCATION)
1278             inform (original_location, "originally specified here");
1279           return;
1280         }
1281     }
1282
1283   /* Create a PROPERTY_DECL node.  */
1284   property_decl = make_node (PROPERTY_DECL);
1285
1286   /* Copy the basic information from the original decl.  */
1287   TREE_TYPE (property_decl) = TREE_TYPE (decl);
1288   DECL_SOURCE_LOCATION (property_decl) = DECL_SOURCE_LOCATION (decl);
1289   TREE_DEPRECATED (property_decl) = TREE_DEPRECATED (decl);
1290   
1291   /* Add property-specific information.  */
1292   PROPERTY_NAME (property_decl) = DECL_NAME (decl);
1293   PROPERTY_GETTER_NAME (property_decl) = parsed_property_getter_ident;
1294   PROPERTY_SETTER_NAME (property_decl) = parsed_property_setter_ident;
1295   PROPERTY_READONLY (property_decl) = property_readonly;
1296   PROPERTY_NONATOMIC (property_decl) = parsed_property_nonatomic;
1297   PROPERTY_ASSIGN_SEMANTICS (property_decl) = property_assign_semantics;
1298   PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
1299   PROPERTY_DYNAMIC (property_decl) = 0;
1300
1301   /* Remember the fact that the property was found in the @optional
1302      section in a @protocol, or not.  */
1303   if (objc_method_optional_flag)
1304     PROPERTY_OPTIONAL (property_decl) = 1;
1305   else
1306     PROPERTY_OPTIONAL (property_decl) = 0;
1307
1308   /* Note that PROPERTY_GETTER_NAME is always set for all
1309      PROPERTY_DECLs, and PROPERTY_SETTER_NAME is always set for all
1310      PROPERTY_DECLs where PROPERTY_READONLY == 0.  Any time we deal
1311      with a getter or setter, we should get the PROPERTY_DECL and use
1312      PROPERTY_GETTER_NAME and PROPERTY_SETTER_NAME to know the correct
1313      names.  */
1314
1315   /* Add the PROPERTY_DECL to the list of properties for the class.  */
1316   TREE_CHAIN (property_decl) = CLASS_PROPERTY_DECL (objc_interface_context);
1317   CLASS_PROPERTY_DECL (objc_interface_context) = property_decl;
1318 }
1319
1320 /* This is a subroutine of objc_maybe_build_component_ref.  Search the
1321    list of methods in the interface (and, failing that, the local list
1322    in the implementation, and failing that, the protocol list)
1323    provided for a 'setter' or 'getter' for 'component' with default
1324    names (ie, if 'component' is "name", then search for "name" and
1325    "setName:").  It is also possible to specify a different
1326    'getter_name' (this is used for @optional readonly properties).  If
1327    any is found, then create an artificial property that uses them.
1328    Return NULL_TREE if 'getter' or 'setter' could not be found.  */
1329 static tree
1330 maybe_make_artificial_property_decl (tree interface, tree implementation, 
1331                                      tree protocol_list, tree component, bool is_class,
1332                                      tree getter_name)
1333 {
1334   tree setter_name = get_identifier (objc_build_property_setter_name (component));
1335   tree getter = NULL_TREE;
1336   tree setter = NULL_TREE;
1337
1338   if (getter_name == NULL_TREE)
1339     getter_name = component;
1340
1341   /* First, check the @interface and all superclasses.  */
1342   if (interface)
1343     {
1344       int flags = 0;
1345
1346       /* Using instance methods of the root class as accessors is most
1347          likely unwanted and can be extremely confusing (and, most
1348          importantly, other Objective-C 2.0 compilers do not do it).
1349          Turn it off.  */
1350       if (is_class)
1351         flags = OBJC_LOOKUP_CLASS | OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS;
1352       
1353       getter = lookup_method_static (interface, getter_name, flags);
1354       setter = lookup_method_static (interface, setter_name, flags);
1355     }
1356
1357   /* Second, check the local @implementation context.  */
1358   if (!getter && !setter)
1359     {
1360       if (implementation)
1361         {
1362           if (is_class)
1363             {
1364               getter = lookup_method (CLASS_CLS_METHODS (implementation), getter_name);
1365               setter = lookup_method (CLASS_CLS_METHODS (implementation), setter_name);
1366             }
1367           else
1368             {
1369               getter = lookup_method (CLASS_NST_METHODS (implementation), getter_name);
1370               setter = lookup_method (CLASS_NST_METHODS (implementation), setter_name);       
1371             }
1372         }
1373     }
1374
1375   /* Try the protocol_list if we didn't find anything in the
1376      @interface and in the @implementation.  */
1377   if (!getter && !setter)
1378     {
1379       getter = lookup_method_in_protocol_list (protocol_list, getter_name, is_class);
1380       setter = lookup_method_in_protocol_list (protocol_list, setter_name, is_class);
1381     }
1382
1383   /* There needs to be at least a getter or setter for this to be a
1384      valid 'object.component' syntax.  */
1385   if (getter || setter)
1386     {
1387       /* Yes ... determine the type of the expression.  */
1388       tree property_decl;
1389       tree type;
1390       
1391       if (getter)
1392         type = TREE_VALUE (TREE_TYPE (getter));
1393       else
1394         type = TREE_VALUE (TREE_TYPE (METHOD_SEL_ARGS (setter)));
1395       
1396       /* Create an artificial property declaration with the
1397          information we collected on the type and getter/setter
1398          names.  */
1399       property_decl = make_node (PROPERTY_DECL);
1400       
1401       TREE_TYPE (property_decl) = type;
1402       DECL_SOURCE_LOCATION (property_decl) = input_location;
1403       TREE_DEPRECATED (property_decl) = 0;
1404       DECL_ARTIFICIAL (property_decl) = 1;
1405               
1406       /* Add property-specific information.  Note that one of
1407          PROPERTY_GETTER_NAME or PROPERTY_SETTER_NAME may refer to a
1408          non-existing method; this will generate an error when the
1409          expression is later compiled.  At this stage we don't know if
1410          the getter or setter will be used, so we can't generate an
1411          error.  */
1412       PROPERTY_NAME (property_decl) = component;
1413       PROPERTY_GETTER_NAME (property_decl) = getter_name;
1414       PROPERTY_SETTER_NAME (property_decl) = setter_name;
1415       PROPERTY_READONLY (property_decl) = 0;
1416       PROPERTY_NONATOMIC (property_decl) = 0;
1417       PROPERTY_ASSIGN_SEMANTICS (property_decl) = 0;
1418       PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
1419       PROPERTY_DYNAMIC (property_decl) = 0;
1420       PROPERTY_OPTIONAL (property_decl) = 0;
1421
1422       if (!getter)
1423         PROPERTY_HAS_NO_GETTER (property_decl) = 1;
1424
1425       /* The following is currently unused, but it's nice to have
1426          there.  We may use it if we need in the future.  */
1427       if (!setter)
1428         PROPERTY_HAS_NO_SETTER (property_decl) = 1;
1429
1430       return property_decl;
1431     }
1432
1433   return NULL_TREE;
1434 }
1435
1436 /* This hook routine is invoked by the parser when an expression such
1437    as 'xxx.yyy' is parsed.  We get a chance to process these
1438    expressions in a way that is specified to Objective-C (to implement
1439    the Objective-C 2.0 dot-syntax, properties, or non-fragile ivars).
1440    If the expression is not an Objective-C specified expression, we
1441    should return NULL_TREE; else we return the expression.
1442
1443    At the moment this only implements dot-syntax and properties (not
1444    non-fragile ivars yet), ie 'object.property' or 'object.component'
1445    where 'component' is not a declared property, but a valid getter or
1446    setter for it could be found.  */
1447 tree
1448 objc_maybe_build_component_ref (tree object, tree property_ident)
1449 {
1450   tree x = NULL_TREE;
1451   tree rtype;
1452
1453   /* If we are in Objective-C 1.0 mode, dot-syntax and properties are
1454      not available.  */
1455   if (flag_objc1_only)
1456     return NULL_TREE;
1457
1458   /* Try to determine if 'object' is an Objective-C object or not.  If
1459      not, return.  */
1460   if (object == NULL_TREE || object == error_mark_node 
1461       || (rtype = TREE_TYPE (object)) == NULL_TREE)
1462     return NULL_TREE;
1463   
1464   if (property_ident == NULL_TREE || property_ident == error_mark_node
1465       || TREE_CODE (property_ident) != IDENTIFIER_NODE)
1466     return NULL_TREE;
1467
1468   /* The following analysis of 'object' is similar to the one used for
1469      the 'receiver' of a method invocation.  We need to determine what
1470      'object' is and find the appropriate property (either declared,
1471      or artificial) for it (in the same way as we need to find the
1472      appropriate method prototype for a method invocation).  There are
1473      some simplifications here though: "object.property" is invalid if
1474      "object" has a type of "id" or "Class"; it must at least have a
1475      protocol attached to it, and "object" is never a class name as
1476      that is done by objc_build_class_component_ref.  Finally, we
1477      don't know if this really is a dot-syntax expression, so we want
1478      to make a quick exit if it is not; for this reason, we try to
1479      postpone checks after determining that 'object' looks like an
1480      Objective-C object.  */
1481
1482   if (objc_is_id (rtype))
1483     {
1484       /* This is the case that the 'object' is of type 'id' or
1485          'Class'.  */
1486
1487       /* Check if at least it is of type 'id <Protocol>' or 'Class
1488          <Protocol>'; if so, look the property up in the
1489          protocols.  */
1490       if (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype)))
1491         {
1492           tree rprotos = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype));
1493           
1494           if (rprotos)
1495             {
1496               /* No point looking up declared @properties if we are
1497                  dealing with a class.  Classes have no declared
1498                  properties.  */
1499               if (!IS_CLASS (rtype))
1500                 x = lookup_property_in_protocol_list (rprotos, property_ident);
1501
1502               if (x == NULL_TREE)
1503                 {
1504                   /* Ok, no property.  Maybe it was an
1505                      object.component dot-syntax without a declared
1506                      property (this is valid for classes too).  Look
1507                      for getter/setter methods and internally declare
1508                      an artifical property based on them if found.  */
1509                   x = maybe_make_artificial_property_decl (NULL_TREE,
1510                                                            NULL_TREE,
1511                                                            rprotos, 
1512                                                            property_ident,
1513                                                            IS_CLASS (rtype),
1514                                                            NULL_TREE);
1515                 }
1516               else if (PROPERTY_OPTIONAL (x) && PROPERTY_READONLY (x))
1517                 {
1518                   /* This is a special, complicated case.  If the
1519                      property is optional, and is read-only, then the
1520                      property is always used for reading, but an
1521                      eventual existing non-property setter can be used
1522                      for writing.  We create an artificial property
1523                      decl copying the getter from the optional
1524                      property, and looking up the setter in the
1525                      interface.  */
1526                   x = maybe_make_artificial_property_decl (NULL_TREE,
1527                                                            NULL_TREE,
1528                                                            rprotos,
1529                                                            property_ident,
1530                                                            false,
1531                                                            PROPERTY_GETTER_NAME (x));             
1532                 }
1533             }
1534         }
1535       else if (objc_method_context)
1536         {
1537           /* Else, if we are inside a method it could be the case of
1538              'super' or 'self'.  */
1539           tree interface_type = NULL_TREE;
1540           tree t = object;
1541           while (TREE_CODE (t) == COMPOUND_EXPR
1542                  || TREE_CODE (t) == MODIFY_EXPR
1543                  || CONVERT_EXPR_P (t)
1544                  || TREE_CODE (t) == COMPONENT_REF)
1545             t = TREE_OPERAND (t, 0);
1546           
1547           if (t == UOBJC_SUPER_decl)    
1548             interface_type = lookup_interface (CLASS_SUPER_NAME (implementation_template));
1549           else if (t == self_decl)
1550             interface_type = lookup_interface (CLASS_NAME (implementation_template));
1551
1552           if (interface_type)
1553             {
1554               if (TREE_CODE (objc_method_context) != CLASS_METHOD_DECL)
1555                 x = lookup_property (interface_type, property_ident);
1556         
1557               if (x == NULL_TREE)
1558                 {
1559                   /* Try the dot-syntax without a declared property.
1560                      If this is an access to 'self', it is possible
1561                      that they may refer to a setter/getter that is
1562                      not declared in the interface, but exists locally
1563                      in the implementation.  In that case, get the
1564                      implementation context and use it.  */
1565                   tree implementation = NULL_TREE;
1566
1567                   if (t == self_decl)
1568                     implementation = objc_implementation_context;
1569                   
1570                   x = maybe_make_artificial_property_decl 
1571                     (interface_type, implementation, NULL_TREE,
1572                      property_ident,
1573                      (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL),
1574                      NULL_TREE);
1575                 }
1576               else if (PROPERTY_OPTIONAL (x) && PROPERTY_READONLY (x))
1577                 {
1578                   tree implementation = NULL_TREE;
1579                   
1580                   if (t == self_decl)
1581                     implementation = objc_implementation_context;
1582                   
1583                   x = maybe_make_artificial_property_decl (interface_type,
1584                                                            implementation,
1585                                                            NULL_TREE,
1586                                                            property_ident,
1587                                                            false,
1588                                                            PROPERTY_GETTER_NAME (x));             
1589                 }
1590             }
1591         }
1592     }
1593   else
1594     {
1595       /* This is the case where we have more information on 'rtype'.  */
1596       tree basetype = TYPE_MAIN_VARIANT (rtype);
1597
1598       /* Skip the pointer - if none, it's not an Objective-C object or
1599          class.  */
1600       if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE)
1601         basetype = TREE_TYPE (basetype);
1602       else
1603         return NULL_TREE;
1604
1605       /* Traverse typedefs.  */
1606       while (basetype != NULL_TREE
1607              && TREE_CODE (basetype) == RECORD_TYPE 
1608              && OBJC_TYPE_NAME (basetype)
1609              && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
1610              && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
1611         basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
1612
1613       if (basetype != NULL_TREE && TYPED_OBJECT (basetype))
1614         {
1615           tree interface_type = TYPE_OBJC_INTERFACE (basetype);
1616           tree protocol_list = TYPE_OBJC_PROTOCOL_LIST (basetype);
1617
1618           if (interface_type 
1619               && (TREE_CODE (interface_type) == CLASS_INTERFACE_TYPE
1620                   || TREE_CODE (interface_type) == CATEGORY_INTERFACE_TYPE
1621                   || TREE_CODE (interface_type) == PROTOCOL_INTERFACE_TYPE))
1622             {
1623               /* Not sure 'rtype' could ever be a class here!  Just
1624                  for safety we keep the checks.  */
1625               if (!IS_CLASS (rtype))
1626                 {
1627                   x = lookup_property (interface_type, property_ident);
1628                   
1629                   if (x == NULL_TREE)
1630                     x = lookup_property_in_protocol_list (protocol_list, 
1631                                                           property_ident);
1632                 }
1633               
1634               if (x == NULL_TREE)
1635                 {
1636                   /* Try the dot-syntax without a declared property.
1637                      If we are inside a method implementation, it is
1638                      possible that they may refer to a setter/getter
1639                      that is not declared in the interface, but exists
1640                      locally in the implementation.  In that case, get
1641                      the implementation context and use it.  */
1642                   tree implementation = NULL_TREE;
1643
1644                   if (objc_implementation_context
1645                       && CLASS_NAME (objc_implementation_context) 
1646                       == OBJC_TYPE_NAME (interface_type))
1647                     implementation = objc_implementation_context;
1648                   
1649                   x = maybe_make_artificial_property_decl (interface_type,
1650                                                            implementation,
1651                                                            protocol_list, 
1652                                                            property_ident,
1653                                                            IS_CLASS (rtype),
1654                                                            NULL_TREE);
1655                 }
1656               else if (PROPERTY_OPTIONAL (x) && PROPERTY_READONLY (x))
1657                 {
1658                   tree implementation = NULL_TREE;
1659
1660                   if (objc_implementation_context
1661                       && CLASS_NAME (objc_implementation_context) 
1662                       == OBJC_TYPE_NAME (interface_type))
1663                     implementation = objc_implementation_context;
1664                   
1665                   x = maybe_make_artificial_property_decl (interface_type,
1666                                                            implementation,
1667                                                            protocol_list,
1668                                                            property_ident,
1669                                                            false,
1670                                                            PROPERTY_GETTER_NAME (x));             
1671                 }             
1672             }
1673         }
1674     }
1675
1676   if (x)
1677     {
1678       tree expression;
1679       tree getter_call;
1680
1681       /* We have an additional nasty problem here; if this
1682          PROPERTY_REF needs to become a 'getter', then the conversion
1683          from PROPERTY_REF into a getter call happens in gimplify,
1684          after the selector table has already been generated and when
1685          it is too late to add another selector to it.  To work around
1686          the problem, we always create the getter call at this stage,
1687          which puts the selector in the table.  Note that if the
1688          PROPERTY_REF becomes a 'setter' instead of a 'getter', then
1689          we have added a selector too many to the selector table.
1690          This is a little inefficient.
1691
1692          Also note that method calls to 'self' and 'super' require the
1693          context (self_decl, UOBJS_SUPER_decl,
1694          objc_implementation_context etc) to be built correctly; this
1695          is yet another reason why building the call at the gimplify
1696          stage (when this context has been lost) is not very
1697          practical.  If we build it at this stage, we know it will
1698          always be built correctly.
1699
1700          If the PROPERTY_HAS_NO_GETTER() (ie, it is an artificial
1701          property decl created to deal with a dotsyntax not really
1702          referring to an existing property) then do not try to build a
1703          call to the getter as there is no getter.  */
1704       if (PROPERTY_HAS_NO_GETTER (x))
1705         getter_call = NULL_TREE;
1706       else
1707         getter_call = objc_finish_message_expr (object,
1708                                                 PROPERTY_GETTER_NAME (x),
1709                                                 NULL_TREE);
1710
1711       if (TREE_DEPRECATED (x))
1712         warn_deprecated_use (x, NULL_TREE);
1713
1714       expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call);
1715       SET_EXPR_LOCATION (expression, input_location);
1716       TREE_SIDE_EFFECTS (expression) = 1;
1717       
1718       return expression;
1719     }
1720
1721   return NULL_TREE;
1722 }
1723
1724 /* This hook routine is invoked by the parser when an expression such
1725    as 'xxx.yyy' is parsed, and 'xxx' is a class name.  This is the
1726    Objective-C 2.0 dot-syntax applied to classes, so we need to
1727    convert it into a setter/getter call on the class.  */
1728 tree
1729 objc_build_class_component_ref (tree class_name, tree property_ident)
1730 {
1731   tree x = NULL_TREE;
1732   tree object, rtype;
1733   
1734   if (flag_objc1_only)
1735     error_at (input_location, "the dot syntax is not available in Objective-C 1.0");
1736   
1737   if (class_name == NULL_TREE || class_name == error_mark_node
1738       || TREE_CODE (class_name) != IDENTIFIER_NODE)
1739     return error_mark_node;
1740   
1741   if (property_ident == NULL_TREE || property_ident == error_mark_node
1742       || TREE_CODE (property_ident) != IDENTIFIER_NODE)
1743     return NULL_TREE;
1744   
1745   object = objc_get_class_reference (class_name);
1746   if (!object)
1747     {
1748       /* We know that 'class_name' is an Objective-C class name as the
1749          parser won't call this function if it is not.  This is only a
1750          double-check for safety.  */
1751       error_at (input_location, "could not find class %qE", class_name); 
1752       return error_mark_node;
1753     }
1754
1755   rtype = lookup_interface (class_name);
1756   if (!rtype)
1757     {
1758       /* Again, this should never happen, but we do check.  */
1759       error_at (input_location, "could not find interface for class %qE", class_name); 
1760       return error_mark_node;
1761     }
1762   else
1763     {
1764       if (TREE_DEPRECATED (rtype))
1765         warning (OPT_Wdeprecated_declarations, "class %qE is deprecated", class_name);    
1766     }
1767
1768   x = maybe_make_artificial_property_decl (rtype, NULL_TREE, NULL_TREE,
1769                                            property_ident,
1770                                            true, NULL_TREE);
1771   
1772   if (x)
1773     {
1774       tree expression;
1775       tree getter_call;
1776
1777       if (PROPERTY_HAS_NO_GETTER (x))
1778         getter_call = NULL_TREE;
1779       else
1780         getter_call = objc_finish_message_expr (object,
1781                                                 PROPERTY_GETTER_NAME (x),
1782                                                 NULL_TREE);
1783       if (TREE_DEPRECATED (x))
1784         warn_deprecated_use (x, NULL_TREE);
1785
1786       expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call);
1787       SET_EXPR_LOCATION (expression, input_location);
1788       TREE_SIDE_EFFECTS (expression) = 1;
1789
1790       return expression;
1791     }
1792   else
1793     {
1794       error_at (input_location, "could not find setter/getter for %qE in class %qE", 
1795                 property_ident, class_name); 
1796       return error_mark_node;
1797     }
1798
1799   return NULL_TREE;
1800 }
1801
1802
1803
1804 /* This is used because we don't want to expose PROPERTY_REF to the
1805    C/C++ frontends.  Maybe we should!  */
1806 bool
1807 objc_is_property_ref (tree node)
1808 {
1809   if (node  &&  TREE_CODE (node) == PROPERTY_REF)
1810     return true;
1811   else
1812     return false;
1813 }
1814
1815 /* This function builds a setter call for a PROPERTY_REF (real, for a
1816    declared property, or artificial, for a dot-syntax accessor which
1817    is not corresponding to a property).  'lhs' must be a PROPERTY_REF
1818    (the caller must check this beforehand).  'rhs' is the value to
1819    assign to the property.  A plain setter call is returned, or
1820    error_mark_node if the property is readonly.  */
1821
1822 static tree
1823 objc_build_setter_call (tree lhs, tree rhs)
1824 {
1825   tree object_expr = PROPERTY_REF_OBJECT (lhs);
1826   tree property_decl = PROPERTY_REF_PROPERTY_DECL (lhs);
1827   
1828   if (PROPERTY_READONLY (property_decl))
1829     {
1830       error ("readonly property can not be set");         
1831       return error_mark_node;
1832     }
1833   else
1834     {
1835       tree setter_argument = build_tree_list (NULL_TREE, rhs);
1836       tree setter;
1837       
1838       /* TODO: Check that the setter return type is 'void'.  */
1839
1840       /* TODO: Decay arguments in C.  */
1841       setter = objc_finish_message_expr (object_expr, 
1842                                          PROPERTY_SETTER_NAME (property_decl),
1843                                          setter_argument);
1844       return setter;
1845     }
1846
1847   /* Unreachable, but the compiler may not realize.  */
1848   return error_mark_node;
1849 }
1850
1851 /* This hook routine is called when a MODIFY_EXPR is being built.  We
1852    check what is being modified; if it is a PROPERTY_REF, we need to
1853    generate a 'setter' function call for the property.  If this is not
1854    a PROPERTY_REF, we return NULL_TREE and the C/C++ frontend will go
1855    on creating their MODIFY_EXPR.
1856
1857    This is used for example if you write
1858
1859    object.count = 1;
1860
1861    where 'count' is a property.  The left-hand side creates a
1862    PROPERTY_REF, and then the compiler tries to generate a MODIFY_EXPR
1863    to assign something to it.  We intercept that here, and generate a
1864    call to the 'setter' method instead.  */
1865 tree
1866 objc_maybe_build_modify_expr (tree lhs, tree rhs)
1867 {
1868   if (lhs && TREE_CODE (lhs) == PROPERTY_REF)
1869     {
1870       /* Building a simple call to the setter method would work for cases such as
1871
1872       object.count = 1;
1873
1874       but wouldn't work for cases such as
1875
1876       count = object2.count = 1;
1877
1878       to get these to work with very little effort, we build a
1879       compound statement which does the setter call (to set the
1880       property to 'rhs'), but which can also be evaluated returning
1881       the 'rhs'.  So, we want to create the following:
1882
1883       (temp = rhs; [object setProperty: temp]; temp)
1884       */
1885       tree temp_variable_decl, bind;
1886       /* s1, s2 and s3 are the tree statements that we need in the
1887          compound expression.  */
1888       tree s1, s2, s3, compound_expr;
1889       
1890       /* TODO: If 'rhs' is a constant, we could maybe do without the
1891          'temp' variable ? */
1892
1893       /* Declare __objc_property_temp in a local bind.  */
1894       temp_variable_decl = objc_create_temporary_var (TREE_TYPE (rhs), "__objc_property_temp");
1895       DECL_SOURCE_LOCATION (temp_variable_decl) = input_location;
1896       bind = build3 (BIND_EXPR, void_type_node, temp_variable_decl, NULL, NULL);
1897       SET_EXPR_LOCATION (bind, input_location);
1898       TREE_SIDE_EFFECTS (bind) = 1;
1899       add_stmt (bind);
1900       
1901       /* Now build the compound statement.  */
1902       
1903       /* s1: __objc_property_temp = rhs */
1904       s1 = build_modify_expr (input_location, temp_variable_decl, NULL_TREE,
1905                               NOP_EXPR,
1906                               input_location, rhs, NULL_TREE);
1907       SET_EXPR_LOCATION (s1, input_location);
1908   
1909       /* s2: [object setProperty: __objc_property_temp] */
1910       s2 = objc_build_setter_call (lhs, temp_variable_decl);
1911
1912       /* This happens if building the setter failed because the property
1913          is readonly.  */
1914       if (s2 == error_mark_node)
1915         return error_mark_node;
1916
1917       SET_EXPR_LOCATION (s2, input_location);
1918   
1919       /* s3: __objc_property_temp */
1920       s3 = convert (TREE_TYPE (lhs), temp_variable_decl);
1921
1922       /* Now build the compound statement (s1, s2, s3) */
1923       compound_expr = build_compound_expr (input_location, build_compound_expr (input_location, s1, s2), s3);
1924
1925       /* Without this, with -Wall you get a 'valued computed is not
1926          used' every time there is a "object.property = x" where the
1927          value of the resulting MODIFY_EXPR is not used.  That is
1928          correct (maybe a more sophisticated implementation could
1929          avoid generating the compound expression if not needed), but
1930          we need to turn it off.  */
1931       TREE_NO_WARNING (compound_expr) = 1;
1932       return compound_expr;
1933     }
1934   else
1935     return NULL_TREE;
1936 }
1937
1938 /* This hook is called by the frontend when one of the four unary
1939    expressions PREINCREMENT_EXPR, POSTINCREMENT_EXPR,
1940    PREDECREMENT_EXPR and POSTDECREMENT_EXPR is being built with an
1941    argument which is a PROPERTY_REF.  For example, this happens if you have
1942
1943    object.count++;
1944
1945    where 'count' is a property.  We need to use the 'getter' and
1946    'setter' for the property in an appropriate way to build the
1947    appropriate expression.  'code' is the code for the expression (one
1948    of the four mentioned above); 'argument' is the PROPERTY_REF, and
1949    'increment' is how much we need to add or subtract.  */   
1950 tree
1951 objc_build_incr_expr_for_property_ref (location_t location,
1952                                        enum tree_code code, 
1953                                        tree argument, tree increment)
1954 {
1955   /* Here are the expressions that we want to build:
1956
1957      For PREINCREMENT_EXPR / PREDECREMENT_EXPR:
1958     (temp = [object property] +/- increment, [object setProperty: temp], temp)
1959     
1960     For POSTINCREMENT_EXPR / POSTECREMENT_EXPR:
1961     (temp = [object property], [object setProperty: temp +/- increment], temp) */
1962   
1963   tree temp_variable_decl, bind;
1964   /* s1, s2 and s3 are the tree statements that we need in the
1965      compound expression.  */
1966   tree s1, s2, s3, compound_expr;
1967   
1968   /* Safety check.  */
1969   if (!argument || TREE_CODE (argument) != PROPERTY_REF)
1970     return error_mark_node;
1971
1972   /* Declare __objc_property_temp in a local bind.  */
1973   temp_variable_decl = objc_create_temporary_var (TREE_TYPE (argument), "__objc_property_temp");
1974   DECL_SOURCE_LOCATION (temp_variable_decl) = location;
1975   bind = build3 (BIND_EXPR, void_type_node, temp_variable_decl, NULL, NULL);
1976   SET_EXPR_LOCATION (bind, location);
1977   TREE_SIDE_EFFECTS (bind) = 1;
1978   add_stmt (bind);
1979   
1980   /* Now build the compound statement.  */
1981   
1982   /* Note that the 'getter' is generated at gimplify time; at this
1983      time, we can simply put the property_ref (ie, argument) wherever
1984      we want the getter ultimately to be.  */
1985   
1986   /* s1: __objc_property_temp = [object property] <+/- increment> */
1987   switch (code)
1988     {
1989     case PREINCREMENT_EXPR:      
1990       /* __objc_property_temp = [object property] + increment */
1991       s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
1992                               NOP_EXPR,
1993                               location, build2 (PLUS_EXPR, TREE_TYPE (argument), 
1994                                                 argument, increment), NULL_TREE);
1995       break;
1996     case PREDECREMENT_EXPR:
1997       /* __objc_property_temp = [object property] - increment */
1998       s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
1999                               NOP_EXPR,
2000                               location, build2 (MINUS_EXPR, TREE_TYPE (argument), 
2001                                                 argument, increment), NULL_TREE);
2002       break;
2003     case POSTINCREMENT_EXPR:
2004     case POSTDECREMENT_EXPR:
2005       /* __objc_property_temp = [object property] */
2006       s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
2007                               NOP_EXPR,
2008                               location, argument, NULL_TREE);
2009       break;
2010     default:
2011       gcc_unreachable ();
2012     }
2013   
2014   /* s2: [object setProperty: __objc_property_temp <+/- increment>] */
2015   switch (code)
2016     {
2017     case PREINCREMENT_EXPR:      
2018     case PREDECREMENT_EXPR:
2019       /* [object setProperty: __objc_property_temp] */
2020       s2 = objc_build_setter_call (argument, temp_variable_decl);
2021       break;
2022     case POSTINCREMENT_EXPR:
2023       /* [object setProperty: __objc_property_temp + increment] */
2024       s2 = objc_build_setter_call (argument,
2025                                    build2 (PLUS_EXPR, TREE_TYPE (argument), 
2026                                            temp_variable_decl, increment));
2027       break;
2028     case POSTDECREMENT_EXPR:
2029       /* [object setProperty: __objc_property_temp - increment] */
2030       s2 = objc_build_setter_call (argument,
2031                                    build2 (MINUS_EXPR, TREE_TYPE (argument), 
2032                                            temp_variable_decl, increment));
2033       break;
2034     default:
2035       gcc_unreachable ();
2036     }
2037
2038   /* This happens if building the setter failed because the property
2039      is readonly.  */
2040   if (s2 == error_mark_node)
2041     return error_mark_node;
2042
2043   SET_EXPR_LOCATION (s2, location); 
2044   
2045   /* s3: __objc_property_temp */
2046   s3 = convert (TREE_TYPE (argument), temp_variable_decl);
2047   
2048   /* Now build the compound statement (s1, s2, s3) */
2049   compound_expr = build_compound_expr (location, build_compound_expr (location, s1, s2), s3);
2050
2051   /* Prevent C++ from warning with -Wall that "right operand of comma
2052      operator has no effect".  */
2053   TREE_NO_WARNING (compound_expr) = 1;
2054   return compound_expr;
2055 }
2056
2057 tree
2058 objc_build_method_signature (bool is_class_method, tree rettype, tree selector,
2059                              tree optparms, bool ellipsis)
2060 {
2061   if (is_class_method)
2062     return build_method_decl (CLASS_METHOD_DECL, rettype, selector,
2063                               optparms, ellipsis);
2064   else
2065     return build_method_decl (INSTANCE_METHOD_DECL, rettype, selector,
2066                               optparms, ellipsis);
2067 }
2068
2069 void
2070 objc_add_method_declaration (bool is_class_method, tree decl, tree attributes)
2071 {
2072   if (!objc_interface_context)
2073     {
2074       /* PS: At the moment, due to how the parser works, it should be
2075          impossible to get here.  But it's good to have the check in
2076          case the parser changes.
2077       */
2078       fatal_error ("method declaration not in @interface context");
2079     }
2080
2081   if (flag_objc1_only && attributes)
2082     error_at (input_location, "method attributes are not available in Objective-C 1.0");
2083
2084   objc_decl_method_attributes (&decl, attributes, 0);
2085   objc_add_method (objc_interface_context,
2086                    decl,
2087                    is_class_method,
2088                    objc_method_optional_flag);
2089 }
2090
2091 /* Return 'true' if the method definition could be started, and
2092    'false' if not (because we are outside an @implementation context).
2093 */
2094 bool
2095 objc_start_method_definition (bool is_class_method, tree decl, tree attributes)
2096 {
2097   if (!objc_implementation_context)
2098     {
2099       error ("method definition not in @implementation context");
2100       return false;
2101     }
2102
2103   if (decl != NULL_TREE  && METHOD_SEL_NAME (decl) == error_mark_node)
2104     return false;
2105
2106 #ifndef OBJCPLUS
2107   /* Indicate no valid break/continue context by setting these variables
2108      to some non-null, non-label value.  We'll notice and emit the proper
2109      error message in c_finish_bc_stmt.  */
2110   c_break_label = c_cont_label = size_zero_node;
2111 #endif
2112
2113   if (attributes)
2114     warning_at (input_location, 0, "method attributes can not be specified in @implementation context");
2115   else
2116     objc_decl_method_attributes (&decl, attributes, 0);
2117
2118   objc_add_method (objc_implementation_context,
2119                    decl,
2120                    is_class_method,
2121                    /* is optional */ false);
2122   start_method_def (decl);
2123   return true;
2124 }
2125
2126 void
2127 objc_add_instance_variable (tree decl)
2128 {
2129   (void) add_instance_variable (objc_ivar_context,
2130                                 objc_ivar_visibility,
2131                                 decl);
2132 }
2133
2134 /* Return true if TYPE is 'id'.  */
2135
2136 static bool
2137 objc_is_object_id (tree type)
2138 {
2139   return OBJC_TYPE_NAME (type) == objc_object_id;
2140 }
2141
2142 static bool
2143 objc_is_class_id (tree type)
2144 {
2145   return OBJC_TYPE_NAME (type) == objc_class_id;
2146 }
2147
2148 /* Construct a C struct with same name as KLASS, a base struct with tag
2149    SUPER_NAME (if any), and FIELDS indicated.  */
2150
2151 static tree
2152 objc_build_struct (tree klass, tree fields, tree super_name)
2153 {
2154   tree name = CLASS_NAME (klass);
2155   tree s = objc_start_struct (name);
2156   tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
2157   tree t;
2158   VEC(tree,heap) *objc_info = NULL;
2159   int i;
2160
2161   if (super)
2162     {
2163       /* Prepend a packed variant of the base class into the layout.  This
2164          is necessary to preserve ObjC ABI compatibility.  */
2165       tree base = build_decl (input_location,
2166                               FIELD_DECL, NULL_TREE, super);
2167       tree field = TYPE_FIELDS (super);
2168
2169       while (field && DECL_CHAIN (field)
2170              && TREE_CODE (DECL_CHAIN (field)) == FIELD_DECL)
2171         field = DECL_CHAIN (field);
2172
2173       /* For ObjC ABI purposes, the "packed" size of a base class is
2174          the sum of the offset and the size (in bits) of the last field
2175          in the class.  */
2176       DECL_SIZE (base)
2177         = (field && TREE_CODE (field) == FIELD_DECL
2178            ? size_binop (PLUS_EXPR,
2179                          size_binop (PLUS_EXPR,
2180                                      size_binop
2181                                      (MULT_EXPR,
2182                                       convert (bitsizetype,
2183                                                DECL_FIELD_OFFSET (field)),
2184                                       bitsize_int (BITS_PER_UNIT)),
2185                                      DECL_FIELD_BIT_OFFSET (field)),
2186                          DECL_SIZE (field))
2187            : bitsize_zero_node);
2188       DECL_SIZE_UNIT (base)
2189         = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
2190                       size_int (BITS_PER_UNIT));
2191       DECL_ARTIFICIAL (base) = 1;
2192       DECL_ALIGN (base) = 1;
2193       DECL_FIELD_CONTEXT (base) = s;
2194 #ifdef OBJCPLUS
2195       DECL_FIELD_IS_BASE (base) = 1;
2196
2197       if (fields)
2198         TREE_NO_WARNING (fields) = 1;   /* Suppress C++ ABI warnings -- we   */
2199 #endif                                  /* are following the ObjC ABI here.  */
2200       DECL_CHAIN (base) = fields;
2201       fields = base;
2202     }
2203
2204   /* NB: Calling finish_struct() may cause type TYPE_OBJC_INFO
2205      information in all variants of this RECORD_TYPE to be destroyed
2206      (this is because the C frontend manipulates TYPE_LANG_SPECIFIC
2207      for something else and then will change all variants to use the
2208      same resulting TYPE_LANG_SPECIFIC, ignoring the fact that we use
2209      it for ObjC protocols and that such propagation will make all
2210      variants use the same objc_info), but it is therein that we store
2211      protocol conformance info (e.g., 'NSObject <MyProtocol>').
2212      Hence, we must save the ObjC-specific information before calling
2213      finish_struct(), and then reinstate it afterwards.  */
2214
2215   for (t = TYPE_MAIN_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
2216     {
2217       INIT_TYPE_OBJC_INFO (t);
2218       VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t));
2219     }
2220
2221   s = objc_finish_struct (s, fields);
2222
2223   for (i = 0, t = TYPE_MAIN_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
2224     {
2225       /* We now want to restore the different TYPE_OBJC_INFO, but we
2226          have the additional problem that the C frontend doesn't just
2227          copy TYPE_LANG_SPECIFIC from one variant to the other; it
2228          actually makes all of them the *same* TYPE_LANG_SPECIFIC.  As
2229          we need a different TYPE_OBJC_INFO for each (and
2230          TYPE_OBJC_INFO is a field in TYPE_LANG_SPECIFIC), we need to
2231          make a copy of each TYPE_LANG_SPECIFIC before we modify
2232          TYPE_OBJC_INFO.  */
2233       if (TYPE_LANG_SPECIFIC (t))
2234         {
2235           /* Create a copy of TYPE_LANG_SPECIFIC.  */
2236           struct lang_type *old_lang_type = TYPE_LANG_SPECIFIC (t);
2237           ALLOC_OBJC_TYPE_LANG_SPECIFIC (t);
2238           memcpy (TYPE_LANG_SPECIFIC (t), old_lang_type,
2239                   SIZEOF_OBJC_TYPE_LANG_SPECIFIC);
2240         }
2241       else
2242         {
2243           /* Just create a new one.  */
2244           ALLOC_OBJC_TYPE_LANG_SPECIFIC (t);
2245         }
2246       /* Replace TYPE_OBJC_INFO with the saved one.  This restores any
2247          protocol information that may have been associated with the
2248          type.  */
2249       TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i);
2250       /* Replace the IDENTIFIER_NODE with an actual @interface now
2251          that we have it.  */
2252       TYPE_OBJC_INTERFACE (t) = klass;
2253     }
2254   VEC_free (tree, heap, objc_info);
2255
2256   /* Use TYPE_BINFO structures to point at the super class, if any.  */
2257   objc_xref_basetypes (s, super);
2258
2259   /* Mark this struct as a class template.  */
2260   CLASS_STATIC_TEMPLATE (klass) = s;
2261
2262   return s;
2263 }
2264
2265 /* Mark DECL as being 'volatile' for purposes of Darwin
2266    _setjmp()/_longjmp() exception handling.  Called from
2267    objc_mark_locals_volatile().  */
2268 void
2269 objc_volatilize_decl (tree decl)
2270 {
2271   /* Do not mess with variables that are 'static' or (already)
2272      'volatile'.  */
2273   if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
2274       && (TREE_CODE (decl) == VAR_DECL
2275           || TREE_CODE (decl) == PARM_DECL))
2276     {
2277       if (local_variables_to_volatilize == NULL)
2278         local_variables_to_volatilize = VEC_alloc (tree, gc, 8);
2279
2280       VEC_safe_push (tree, gc, local_variables_to_volatilize, decl);
2281     }
2282 }
2283
2284 /* Called when parsing of a function completes; if any local variables
2285    in the function were marked as variables to volatilize, change them
2286    to volatile.  We do this at the end of the function when the
2287    warnings about discarding 'volatile' have already been produced.
2288    We are making the variables as volatile just to force the compiler
2289    to preserve them between setjmp/longjmp, but we don't want warnings
2290    for them as they aren't really volatile.  */
2291 void
2292 objc_finish_function (void)
2293 {
2294   /* If there are any local variables to volatilize, volatilize them.  */
2295   if (local_variables_to_volatilize)
2296     {
2297       int i;
2298       tree decl;
2299       FOR_EACH_VEC_ELT (tree, local_variables_to_volatilize, i, decl)
2300         {
2301           tree t = TREE_TYPE (decl);
2302
2303           t = build_qualified_type (t, TYPE_QUALS (t) | TYPE_QUAL_VOLATILE);
2304           TREE_TYPE (decl) = t;
2305           TREE_THIS_VOLATILE (decl) = 1;
2306           TREE_SIDE_EFFECTS (decl) = 1;
2307           DECL_REGISTER (decl) = 0;
2308 #ifndef OBJCPLUS
2309           C_DECL_REGISTER (decl) = 0;
2310 #endif
2311         }
2312
2313       /* Now we delete the vector.  This sets it to NULL as well.  */
2314       VEC_free (tree, gc, local_variables_to_volatilize);
2315     }
2316 }
2317
2318 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
2319    (including its categories and superclasses) or by object type TYP.
2320    Issue a warning if PROTO is not adopted anywhere and WARN is set.  */
2321
2322 static bool
2323 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
2324 {
2325   bool class_type = (cls != NULL_TREE);
2326
2327   while (cls)
2328     {
2329       tree c;
2330
2331       /* Check protocols adopted by the class and its categories.  */
2332       for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
2333         {
2334           if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
2335             return true;
2336         }
2337
2338       /* Repeat for superclasses.  */
2339       cls = lookup_interface (CLASS_SUPER_NAME (cls));
2340     }
2341
2342   /* Check for any protocols attached directly to the object type.  */
2343   if (TYPE_HAS_OBJC_INFO (typ))
2344     {
2345       if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
2346         return true;
2347     }
2348
2349   if (warn)
2350     {
2351       *errbuf = 0;
2352       gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
2353       /* NB: Types 'id' and 'Class' cannot reasonably be described as
2354          "implementing" a given protocol, since they do not have an
2355          implementation.  */
2356       if (class_type)
2357         warning (0, "class %qs does not implement the %qE protocol",
2358                  identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
2359       else
2360         warning (0, "type %qs does not conform to the %qE protocol",
2361                  identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
2362     }
2363
2364   return false;
2365 }
2366
2367 /* Check if class RCLS and instance struct type RTYP conform to at least the
2368    same protocols that LCLS and LTYP conform to.  */
2369
2370 static bool
2371 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
2372 {
2373   tree p;
2374   bool have_lproto = false;
2375
2376   while (lcls)
2377     {
2378       /* NB: We do _not_ look at categories defined for LCLS; these may or
2379          may not get loaded in, and therefore it is unreasonable to require
2380          that RCLS/RTYP must implement any of their protocols.  */
2381       for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
2382         {
2383           have_lproto = true;
2384
2385           if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
2386             return warn;
2387         }
2388
2389       /* Repeat for superclasses.  */
2390       lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
2391     }
2392
2393   /* Check for any protocols attached directly to the object type.  */
2394   if (TYPE_HAS_OBJC_INFO (ltyp))
2395     {
2396       for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
2397         {
2398           have_lproto = true;
2399
2400           if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
2401             return warn;
2402         }
2403     }
2404
2405   /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
2406      vacuously, _unless_ RTYP is a protocol-qualified 'id'.  We can get
2407      away with simply checking for 'id' or 'Class' (!RCLS), since this
2408      routine will not get called in other cases.  */
2409   return have_lproto || (rcls != NULL_TREE);
2410 }
2411
2412 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
2413    Both TYPE1 and TYPE2 must be pointers, and already determined to be
2414    compatible by objc_compare_types() below.  */
2415
2416 tree
2417 objc_common_type (tree type1, tree type2)
2418 {
2419   tree inner1 = TREE_TYPE (type1), inner2 = TREE_TYPE (type2);
2420
2421   while (POINTER_TYPE_P (inner1))
2422     {
2423       inner1 = TREE_TYPE (inner1);
2424       inner2 = TREE_TYPE (inner2);
2425     }
2426
2427   /* If one type is derived from another, return the base type.  */
2428   if (DERIVED_FROM_P (inner1, inner2))
2429     return type1;
2430   else if (DERIVED_FROM_P (inner2, inner1))
2431     return type2;
2432
2433   /* If both types are 'Class', return 'Class'.  */
2434   if (objc_is_class_id (inner1) && objc_is_class_id (inner2))
2435     return objc_class_type;
2436
2437   /* Otherwise, return 'id'.  */
2438   return objc_object_type;
2439 }
2440
2441 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
2442    an instance of RTYP to an instance of LTYP or to compare the two
2443    (if ARGNO is equal to -3), per ObjC type system rules.  Before
2444    returning 'true', this routine may issue warnings related to, e.g.,
2445    protocol conformance.  When returning 'false', the routine must
2446    produce absolutely no warnings; the C or C++ front-end will do so
2447    instead, if needed.  If either LTYP or RTYP is not an Objective-C
2448    type, the routine must return 'false'.
2449
2450    The ARGNO parameter is encoded as follows:
2451      >= 1       Parameter number (CALLEE contains function being called);
2452      0          Return value;
2453      -1         Assignment;
2454      -2         Initialization;
2455      -3         Comparison (LTYP and RTYP may match in either direction);
2456      -4         Silent comparison (for C++ overload resolution);
2457      -5         Silent "specialization" comparison for RTYP to be a "specialization" 
2458                 of LTYP (a specialization means that RTYP is LTYP plus some constraints, 
2459                 so that each object of type RTYP is also of type LTYP).  This is used
2460                 when comparing property types.  */
2461
2462 bool
2463 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
2464 {
2465   tree lcls, rcls, lproto, rproto;
2466   bool pointers_compatible;
2467
2468   /* We must be dealing with pointer types */
2469   if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
2470     return false;
2471
2472   do
2473     {
2474       ltyp = TREE_TYPE (ltyp);  /* Remove indirections.  */
2475       rtyp = TREE_TYPE (rtyp);
2476     }
2477   while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
2478
2479   /* We must also handle function pointers, since ObjC is a bit more
2480      lenient than C or C++ on this.  */
2481   if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
2482     {
2483       /* Return types must be covariant.  */
2484       if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
2485           && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
2486                                   argno, callee))
2487       return false;
2488
2489       /* Argument types must be contravariant.  */
2490       for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
2491            ltyp && rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
2492         {
2493           if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
2494               && !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
2495                                       argno, callee))
2496             return false;
2497       }
2498
2499       return (ltyp == rtyp);
2500     }
2501
2502   /* Past this point, we are only interested in ObjC class instances,
2503      or 'id' or 'Class'.  */
2504   if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
2505     return false;
2506
2507   if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
2508       && !TYPE_HAS_OBJC_INFO (ltyp))
2509     return false;
2510
2511   if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
2512       && !TYPE_HAS_OBJC_INFO (rtyp))
2513     return false;
2514
2515   /* Past this point, we are committed to returning 'true' to the caller
2516      (unless performing a silent comparison; see below).  However, we can
2517      still warn about type and/or protocol mismatches.  */
2518
2519   if (TYPE_HAS_OBJC_INFO (ltyp))
2520     {
2521       lcls = TYPE_OBJC_INTERFACE (ltyp);
2522       lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
2523     }
2524   else
2525     lcls = lproto = NULL_TREE;
2526
2527   if (TYPE_HAS_OBJC_INFO (rtyp))
2528     {
2529       rcls = TYPE_OBJC_INTERFACE (rtyp);
2530       rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
2531     }
2532   else
2533     rcls = rproto = NULL_TREE;
2534
2535   /* If we could not find an @interface declaration, we must have
2536      only seen a @class declaration; for purposes of type comparison,
2537      treat it as a stand-alone (root) class.  */
2538
2539   if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
2540     lcls = NULL_TREE;
2541
2542   if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
2543     rcls = NULL_TREE;
2544
2545   /* If either type is an unqualified 'id', we're done.  This is because
2546      an 'id' can be assigned to or from any type with no warnings.  */
2547   if (argno != -5)
2548     {
2549       if ((!lproto && objc_is_object_id (ltyp))
2550           || (!rproto && objc_is_object_id (rtyp)))
2551         return true;
2552     }
2553   else
2554     {
2555       /* For property checks, though, an 'id' is considered the most
2556          general type of object, hence if you try to specialize an
2557          'NSArray *' (ltyp) property with an 'id' (rtyp) one, we need
2558          to warn.  */
2559       if (!lproto && objc_is_object_id (ltyp))
2560         return true;
2561     }
2562   
2563   pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
2564
2565   /* If the underlying types are the same, and at most one of them has
2566      a protocol list, we do not need to issue any diagnostics.  */
2567   if (pointers_compatible && (!lproto || !rproto))
2568     return true;
2569
2570   /* If exactly one of the types is 'Class', issue a diagnostic; any
2571      exceptions of this rule have already been handled.  */
2572   if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
2573     pointers_compatible = false;
2574   /* Otherwise, check for inheritance relations.  */
2575   else
2576     {
2577       if (!pointers_compatible)
2578         {
2579           /* Again, if any of the two is an 'id', we're satisfied,
2580              unless we're comparing properties, in which case only an
2581              'id' on the left-hand side (old property) is good
2582              enough.  */
2583           if (argno != -5)
2584             pointers_compatible
2585               = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
2586           else
2587             pointers_compatible = objc_is_object_id (ltyp);         
2588         }
2589
2590       if (!pointers_compatible)
2591         pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
2592
2593       if (!pointers_compatible && (argno == -3 || argno == -4))
2594         pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
2595     }
2596
2597   /* If the pointers match modulo protocols, check for protocol conformance
2598      mismatches.  */
2599   if (pointers_compatible)
2600     {
2601       pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
2602                                                     argno != -3);
2603
2604       if (!pointers_compatible && argno == -3)
2605         pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
2606                                                       argno != -3);
2607     }
2608
2609   if (!pointers_compatible)
2610     {
2611       /* The two pointers are not exactly compatible.  Issue a warning, unless
2612          we are performing a silent comparison, in which case return 'false'
2613          instead.  */
2614       /* NB: For the time being, we shall make our warnings look like their
2615          C counterparts.  In the future, we may wish to make them more
2616          ObjC-specific.  */
2617       switch (argno)
2618         {
2619         case -5:
2620         case -4:
2621           return false;
2622
2623         case -3:
2624           warning (0, "comparison of distinct Objective-C types lacks a cast");
2625           break;
2626
2627         case -2:
2628           warning (0, "initialization from distinct Objective-C type");
2629           break;
2630
2631         case -1:
2632           warning (0, "assignment from distinct Objective-C type");
2633           break;
2634
2635         case 0:
2636           warning (0, "distinct Objective-C type in return");
2637           break;
2638
2639         default:
2640           warning (0, "passing argument %d of %qE from distinct "
2641                    "Objective-C type", argno, callee);
2642           break;
2643         }
2644     }
2645
2646   return true;
2647 }
2648
2649 /* This routine is similar to objc_compare_types except that function-pointers are
2650    excluded. This is because, caller assumes that common types are of (id, Object*)
2651    variety and calls objc_common_type to obtain a common type. There is no commonolty
2652    between two function-pointers in this regard. */
2653
2654 bool 
2655 objc_have_common_type (tree ltyp, tree rtyp, int argno, tree callee)
2656 {
2657   if (objc_compare_types (ltyp, rtyp, argno, callee))
2658     {
2659       /* exclude function-pointer types. */
2660       do
2661         {
2662           ltyp = TREE_TYPE (ltyp);  /* Remove indirections.  */
2663           rtyp = TREE_TYPE (rtyp);
2664         }
2665       while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
2666       return !(TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE);
2667     }
2668   return false;
2669 }
2670
2671 #ifndef OBJCPLUS
2672 /* Determine if CHILD is derived from PARENT.  The routine assumes that
2673    both parameters are RECORD_TYPEs, and is non-reflexive.  */
2674
2675 static bool
2676 objc_derived_from_p (tree parent, tree child)
2677 {
2678   parent = TYPE_MAIN_VARIANT (parent);
2679
2680   for (child = TYPE_MAIN_VARIANT (child);
2681        TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
2682     {
2683       child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
2684                                              (TYPE_BINFO (child),
2685                                               0)));
2686
2687       if (child == parent)
2688         return true;
2689     }
2690
2691   return false;
2692 }
2693 #endif
2694
2695 static tree
2696 objc_build_component_ref (tree datum, tree component)
2697 {
2698   /* If COMPONENT is NULL, the caller is referring to the anonymous
2699      base class field.  */
2700   if (!component)
2701     {
2702       tree base = TYPE_FIELDS (TREE_TYPE (datum));
2703
2704       return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
2705     }
2706
2707   /* The 'build_component_ref' routine has been removed from the C++
2708      front-end, but 'finish_class_member_access_expr' seems to be
2709      a worthy substitute.  */
2710 #ifdef OBJCPLUS
2711   return finish_class_member_access_expr (datum, component, false,
2712                                           tf_warning_or_error);
2713 #else
2714   return build_component_ref (input_location, datum, component);
2715 #endif
2716 }
2717
2718 /* Recursively copy inheritance information rooted at BINFO.  To do this,
2719    we emulate the song and dance performed by cp/tree.c:copy_binfo().  */
2720
2721 static tree
2722 objc_copy_binfo (tree binfo)
2723 {
2724   tree btype = BINFO_TYPE (binfo);
2725   tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
2726   tree base_binfo;
2727   int ix;
2728
2729   BINFO_TYPE (binfo2) = btype;
2730   BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
2731   BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
2732
2733   /* Recursively copy base binfos of BINFO.  */
2734   for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
2735     {
2736       tree base_binfo2 = objc_copy_binfo (base_binfo);
2737
2738       BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
2739       BINFO_BASE_APPEND (binfo2, base_binfo2);
2740     }
2741
2742   return binfo2;
2743 }
2744
2745 /* Record superclass information provided in BASETYPE for ObjC class REF.
2746    This is loosely based on cp/decl.c:xref_basetypes().  */
2747
2748 static void
2749 objc_xref_basetypes (tree ref, tree basetype)
2750 {
2751   tree binfo = make_tree_binfo (basetype ? 1 : 0);
2752
2753   TYPE_BINFO (ref) = binfo;
2754   BINFO_OFFSET (binfo) = size_zero_node;
2755   BINFO_TYPE (binfo) = ref;
2756
2757   if (basetype)
2758     {
2759       tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
2760
2761       BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
2762       BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
2763       BINFO_BASE_APPEND (binfo, base_binfo);
2764       BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
2765     }
2766 }
2767
2768 /* Called from finish_decl.  */
2769
2770 void
2771 objc_check_decl (tree decl)
2772 {
2773   tree type = TREE_TYPE (decl);
2774
2775   if (TREE_CODE (type) != RECORD_TYPE)
2776     return;
2777   if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
2778     error ("statically allocated instance of Objective-C class %qE",
2779            type);
2780 }
2781
2782 void
2783 objc_check_global_decl (tree decl)
2784 {
2785   tree id = DECL_NAME (decl);
2786   if (objc_is_class_name (id) && global_bindings_p())
2787     error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
2788 }
2789
2790 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where
2791    INTERFACE may either name an Objective-C class, or refer to the
2792    special 'id' or 'Class' types.  If INTERFACE is not a valid ObjC
2793    type, just return it unchanged.  This function is often called when
2794    PROTOCOLS is NULL_TREE, in which case we simply look up the
2795    appropriate INTERFACE.  */
2796
2797 tree
2798 objc_get_protocol_qualified_type (tree interface, tree protocols)
2799 {
2800   /* If INTERFACE is not provided, default to 'id'.  */
2801   tree type = (interface ? objc_is_id (interface) : objc_object_type);
2802   bool is_ptr = (type != NULL_TREE);
2803
2804   if (!is_ptr)
2805     {
2806       type = objc_is_class_name (interface);
2807
2808       if (type)
2809         {
2810           /* If looking at a typedef, retrieve the precise type it
2811              describes.  */
2812           if (TREE_CODE (interface) == IDENTIFIER_NODE)
2813             interface = identifier_global_value (interface);
2814
2815           type = ((interface && TREE_CODE (interface) == TYPE_DECL
2816                    && DECL_ORIGINAL_TYPE (interface))
2817                   ? DECL_ORIGINAL_TYPE (interface)
2818                   : xref_tag (RECORD_TYPE, type));
2819         }
2820       else
2821         {
2822           /* This case happens when we are given an 'interface' which
2823              is not a valid class name.  For example if a typedef was
2824              used, and 'interface' really is the identifier of the
2825              typedef, but when you resolve it you don't get an
2826              Objective-C class, but something else, such as 'int'.
2827              This is an error; protocols make no sense unless you use
2828              them with Objective-C objects.  */
2829           error_at (input_location, "only Objective-C object types can be qualified with a protocol");
2830
2831           /* Try to recover.  Ignore the invalid class name, and treat
2832              the object as an 'id' to silence further warnings about
2833              the class.  */
2834           type = objc_object_type;
2835           is_ptr = true;
2836         }
2837     }
2838
2839   if (protocols)
2840     {
2841       type = build_variant_type_copy (type);
2842
2843       /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
2844          to the pointee.  */
2845       if (is_ptr)
2846         {
2847           tree orig_pointee_type = TREE_TYPE (type);
2848           TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
2849
2850           /* Set up the canonical type information. */
2851           TYPE_CANONICAL (type) 
2852             = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
2853
2854           TYPE_POINTER_TO (TREE_TYPE (type)) = type;
2855           type = TREE_TYPE (type);
2856         }
2857
2858       /* Look up protocols and install in lang specific list.  */
2859       DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
2860       TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
2861
2862       /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
2863          return the pointer to the new pointee variant.  */
2864       if (is_ptr)
2865         type = TYPE_POINTER_TO (type);
2866       else
2867         TYPE_OBJC_INTERFACE (type)
2868           = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
2869     }
2870
2871   return type;
2872 }
2873
2874 /* Check for circular dependencies in protocols.  The arguments are
2875    PROTO, the protocol to check, and LIST, a list of protocol it
2876    conforms to.  */
2877
2878 static void
2879 check_protocol_recursively (tree proto, tree list)
2880 {
2881   tree p;
2882
2883   for (p = list; p; p = TREE_CHAIN (p))
2884     {
2885       tree pp = TREE_VALUE (p);
2886
2887       if (TREE_CODE (pp) == IDENTIFIER_NODE)
2888         pp = lookup_protocol (pp, /* warn if deprecated */ false);
2889
2890       if (pp == proto)
2891         fatal_error ("protocol %qE has circular dependency",
2892                      PROTOCOL_NAME (pp));
2893       if (pp)
2894         check_protocol_recursively (proto, PROTOCOL_LIST (pp));
2895     }
2896 }
2897
2898 /* Look up PROTOCOLS, and return a list of those that are found.  If
2899    none are found, return NULL.  Note that this function will emit a
2900    warning if a protocol is found and is deprecated.  */
2901
2902 static tree
2903 lookup_and_install_protocols (tree protocols)
2904 {
2905   tree proto;
2906   tree return_value = NULL_TREE;
2907
2908   if (protocols == error_mark_node)
2909     return NULL;
2910
2911   for (proto = protocols; proto; proto = TREE_CHAIN (proto))
2912     {
2913       tree ident = TREE_VALUE (proto);
2914       tree p = lookup_protocol (ident, /* warn_if_deprecated */ true);
2915
2916       if (p)
2917         return_value = chainon (return_value,
2918                                 build_tree_list (NULL_TREE, p));
2919       else if (ident != error_mark_node)
2920         error ("cannot find protocol declaration for %qE",
2921                ident);
2922     }
2923
2924   return return_value;
2925 }
2926
2927 /* Create a declaration for field NAME of a given TYPE.  */
2928
2929 static tree
2930 create_field_decl (tree type, const char *name)
2931 {
2932   return build_decl (input_location,
2933                      FIELD_DECL, get_identifier (name), type);
2934 }
2935
2936 /* Create a global, static declaration for variable NAME of a given TYPE.  The
2937    finish_var_decl() routine will need to be called on it afterwards.  */
2938
2939 static tree
2940 start_var_decl (tree type, const char *name)
2941 {
2942   tree var = build_decl (input_location,
2943                          VAR_DECL, get_identifier (name), type);
2944
2945   TREE_STATIC (var) = 1;
2946   DECL_INITIAL (var) = error_mark_node;  /* A real initializer is coming... */
2947   DECL_IGNORED_P (var) = 1;
2948   DECL_ARTIFICIAL (var) = 1;
2949   DECL_CONTEXT (var) = NULL_TREE;
2950 #ifdef OBJCPLUS
2951   DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
2952 #endif
2953
2954   return var;
2955 }
2956
2957 /* Finish off the variable declaration created by start_var_decl().  */
2958
2959 static void
2960 finish_var_decl (tree var, tree initializer)
2961 {
2962   finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
2963 }
2964
2965 /* Find the decl for the constant string class reference.  This is only
2966    used for the NeXT runtime.  */
2967
2968 static tree
2969 setup_string_decl (void)
2970 {
2971   char *name;
2972   size_t length;
2973
2974   /* %s in format will provide room for terminating null */
2975   length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
2976            + strlen (constant_string_class_name);
2977   name = XNEWVEC (char, length);
2978   sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
2979            constant_string_class_name);
2980   constant_string_global_id = get_identifier (name);
2981   string_class_decl = lookup_name (constant_string_global_id);
2982
2983   return string_class_decl;
2984 }
2985
2986 /* Purpose: "play" parser, creating/installing representations
2987    of the declarations that are required by Objective-C.
2988
2989    Model:
2990
2991         type_spec--------->sc_spec
2992         (tree_list)        (tree_list)
2993             |                  |
2994             |                  |
2995         identifier_node    identifier_node  */
2996
2997 static void
2998 synth_module_prologue (void)
2999 {
3000   tree type;
3001   enum debug_info_type save_write_symbols = write_symbols;
3002   const struct gcc_debug_hooks *const save_hooks = debug_hooks;
3003
3004   /* Suppress outputting debug symbols, because
3005      dbxout_init hasn't been called yet.  */
3006   write_symbols = NO_DEBUG;
3007   debug_hooks = &do_nothing_debug_hooks;
3008
3009 #ifdef OBJCPLUS
3010   push_lang_context (lang_name_c); /* extern "C" */
3011 #endif
3012
3013   /* The following are also defined in <objc/objc.h> and friends.  */
3014
3015   objc_object_id = get_identifier (TAG_OBJECT);
3016   objc_class_id = get_identifier (TAG_CLASS);
3017
3018   objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
3019   objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
3020
3021   objc_object_type = build_pointer_type (objc_object_reference);
3022   objc_class_type = build_pointer_type (objc_class_reference);
3023
3024   objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
3025   objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
3026
3027   /* Declare the 'id' and 'Class' typedefs.  */
3028
3029   type = lang_hooks.decls.pushdecl (build_decl (input_location,
3030                                                 TYPE_DECL,
3031                                                 objc_object_name,
3032                                                 objc_object_type));
3033   TREE_NO_WARNING (type) = 1;
3034   type = lang_hooks.decls.pushdecl (build_decl (input_location,
3035                                                 TYPE_DECL,
3036                                                 objc_class_name,
3037                                                 objc_class_type));
3038   TREE_NO_WARNING (type) = 1;
3039
3040   /* Forward-declare '@interface Protocol'.  */
3041
3042   type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
3043   objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
3044   objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
3045                                 type));
3046
3047   /* Declare type of selector-objects that represent an operation name.  */
3048
3049   if (flag_next_runtime)
3050     /* `struct objc_selector *' */
3051     objc_selector_type
3052       = build_pointer_type (xref_tag (RECORD_TYPE,
3053                                       get_identifier (TAG_SELECTOR)));
3054   else
3055     /* `const struct objc_selector *' */
3056     objc_selector_type
3057       = build_pointer_type
3058         (build_qualified_type (xref_tag (RECORD_TYPE,
3059                                          get_identifier (TAG_SELECTOR)),
3060                                TYPE_QUAL_CONST));
3061
3062   /* Declare receiver type used for dispatching messages to 'super'.  */
3063
3064   /* `struct objc_super *' */
3065   objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
3066                                                   get_identifier (TAG_SUPER)));
3067
3068   /* Declare pointers to method and ivar lists.  */
3069   objc_method_list_ptr = build_pointer_type
3070                          (xref_tag (RECORD_TYPE,
3071                                     get_identifier (UTAG_METHOD_LIST)));
3072   objc_method_proto_list_ptr
3073     = build_pointer_type (xref_tag (RECORD_TYPE,
3074                                     get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3075   objc_ivar_list_ptr = build_pointer_type
3076                        (xref_tag (RECORD_TYPE,
3077                                   get_identifier (UTAG_IVAR_LIST)));
3078
3079   /* TREE_NOTHROW is cleared for the message-sending functions,
3080      because the function that gets called can throw in Obj-C++, or
3081      could itself call something that can throw even in Obj-C.  */
3082
3083   if (flag_next_runtime)
3084     {
3085       /* NB: In order to call one of the ..._stret (struct-returning)
3086       functions, the function *MUST* first be cast to a signature that
3087       corresponds to the actual ObjC method being invoked.  This is
3088       what is done by the build_objc_method_call() routine below.  */
3089
3090       /* id objc_msgSend (id, SEL, ...); */
3091       /* id objc_msgSendNonNil (id, SEL, ...); */
3092       /* id objc_msgSend_stret (id, SEL, ...); */
3093       /* id objc_msgSendNonNil_stret (id, SEL, ...); */
3094       type
3095         = build_varargs_function_type_list (objc_object_type,
3096                                             objc_object_type,
3097                                             objc_selector_type,
3098                                             NULL_TREE);
3099       umsg_decl = add_builtin_function (TAG_MSGSEND,
3100                                         type, 0, NOT_BUILT_IN,
3101                                         NULL, NULL_TREE);
3102       umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
3103                                                type, 0, NOT_BUILT_IN,
3104                                                NULL, NULL_TREE);
3105       umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
3106                                               type, 0, NOT_BUILT_IN,
3107                                               NULL, NULL_TREE);
3108       umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
3109                                                      type, 0, NOT_BUILT_IN,
3110                                                      NULL, NULL_TREE);
3111
3112       /* These can throw, because the function that gets called can throw
3113          in Obj-C++, or could itself call something that can throw even
3114          in Obj-C.  */
3115       TREE_NOTHROW (umsg_decl) = 0;
3116       TREE_NOTHROW (umsg_nonnil_decl) = 0;
3117       TREE_NOTHROW (umsg_stret_decl) = 0;
3118       TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
3119
3120       /* id objc_msgSend_Fast (id, SEL, ...)
3121            __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
3122 #ifdef OFFS_MSGSEND_FAST
3123       umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
3124                                              type, 0, NOT_BUILT_IN,
3125                                              NULL, NULL_TREE);
3126       TREE_NOTHROW (umsg_fast_decl) = 0;
3127       DECL_ATTRIBUTES (umsg_fast_decl)
3128         = tree_cons (get_identifier ("hard_coded_address"),
3129                      build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
3130                      NULL_TREE);
3131 #else
3132       /* No direct dispatch available.  */
3133       umsg_fast_decl = umsg_decl;
3134 #endif
3135
3136       /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
3137       /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
3138       type
3139         = build_varargs_function_type_list (objc_object_type,
3140                                             objc_super_type,
3141                                             objc_selector_type,
3142                                             NULL_TREE);
3143       umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
3144                                               type, 0, NOT_BUILT_IN,
3145                                               NULL, NULL_TREE);
3146       umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
3147                                                     type, 0, NOT_BUILT_IN, 0,
3148                                                     NULL_TREE);
3149       TREE_NOTHROW (umsg_super_decl) = 0;
3150       TREE_NOTHROW (umsg_super_stret_decl) = 0;
3151     }
3152   else
3153     {
3154       /* GNU runtime messenger entry points.  */
3155
3156       /* typedef id (*IMP)(id, SEL, ...); */
3157       tree ftype =
3158         build_varargs_function_type_list (objc_object_type,
3159                                           objc_object_type,
3160                                           objc_selector_type,
3161                                           NULL_TREE);
3162       tree IMP_type = build_pointer_type (ftype);
3163
3164       /* IMP objc_msg_lookup (id, SEL); */
3165       type = build_function_type_list (IMP_type,
3166                                        objc_object_type,
3167                                        objc_selector_type,
3168                                        NULL_TREE);
3169       umsg_decl = add_builtin_function (TAG_MSGSEND,
3170                                         type, 0, NOT_BUILT_IN,
3171                                         NULL, NULL_TREE);
3172       TREE_NOTHROW (umsg_decl) = 0;
3173
3174       /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
3175       type
3176         = build_function_type_list (IMP_type,
3177                                     objc_super_type,
3178                                     objc_selector_type,
3179                                     NULL_TREE);
3180       umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
3181                                               type, 0, NOT_BUILT_IN,
3182                                               NULL, NULL_TREE);
3183       TREE_NOTHROW (umsg_super_decl) = 0;
3184
3185       /* The following GNU runtime entry point is called to initialize
3186          each module:
3187
3188          __objc_exec_class (void *); */
3189       type
3190         = build_function_type_list (void_type_node,
3191                                     ptr_type_node,
3192                                     NULL_TREE);
3193       execclass_decl = add_builtin_function (TAG_EXECCLASS,
3194                                              type, 0, NOT_BUILT_IN,
3195                                              NULL, NULL_TREE);
3196     }
3197
3198   /* id objc_getClass (const char *); */
3199
3200   type = build_function_type_list (objc_object_type,
3201                                    const_string_type_node,
3202                                    NULL_TREE);
3203
3204   objc_get_class_decl
3205     = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
3206                             NULL, NULL_TREE);
3207
3208   /* id objc_getMetaClass (const char *); */
3209
3210   objc_get_meta_class_decl
3211     = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3212
3213   build_class_template ();
3214   build_super_template ();
3215   build_protocol_template ();
3216   build_category_template ();
3217   build_objc_exception_stuff ();
3218
3219   /* Declare objc_getProperty, object_setProperty and other property
3220      accessor helpers.  */
3221   build_objc_property_accessor_helpers ();
3222
3223   if (flag_next_runtime)
3224     build_next_objc_exception_stuff ();
3225
3226   /* static SEL _OBJC_SELECTOR_TABLE[]; */
3227
3228   if (! flag_next_runtime)
3229     build_selector_table_decl ();
3230
3231   /* Forward declare constant_string_id and constant_string_type.  */
3232   if (!constant_string_class_name)
3233     constant_string_class_name = default_constant_string_class_name;
3234
3235   constant_string_id = get_identifier (constant_string_class_name);
3236   objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
3237
3238   /* Pre-build the following entities - for speed/convenience.  */
3239   self_id = get_identifier ("self");
3240   ucmd_id = get_identifier ("_cmd");
3241
3242   /* Declare struct _objc_fast_enumeration_state { ... };  */
3243   build_fast_enumeration_state_template ();
3244   
3245   /* void objc_enumeration_mutation (id) */
3246   type = build_function_type (void_type_node,
3247                               tree_cons (NULL_TREE, objc_object_type, NULL_TREE));
3248   objc_enumeration_mutation_decl 
3249     = add_builtin_function (TAG_ENUMERATION_MUTATION, type, 0, NOT_BUILT_IN, 
3250                             NULL, NULL_TREE);
3251   TREE_NOTHROW (objc_enumeration_mutation_decl) = 0;
3252
3253 #ifdef OBJCPLUS
3254   pop_lang_context ();
3255 #endif
3256
3257   write_symbols = save_write_symbols;
3258   debug_hooks = save_hooks;
3259 }
3260
3261 /* Ensure that the ivar list for NSConstantString/NXConstantString
3262    (or whatever was specified via `-fconstant-string-class')
3263    contains fields at least as large as the following three, so that
3264    the runtime can stomp on them with confidence:
3265
3266    struct STRING_OBJECT_CLASS_NAME
3267    {
3268      Object isa;
3269      char *cString;
3270      unsigned int length;
3271    }; */
3272
3273 static int
3274 check_string_class_template (void)
3275 {
3276   tree field_decl = objc_get_class_ivars (constant_string_id);
3277
3278 #define AT_LEAST_AS_LARGE_AS(F, T) \
3279   (F && TREE_CODE (F) == FIELD_DECL \
3280      && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
3281          >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
3282
3283   if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
3284     return 0;
3285
3286   field_decl = DECL_CHAIN (field_decl);
3287   if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
3288     return 0;
3289
3290   field_decl = DECL_CHAIN (field_decl);
3291   return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
3292
3293 #undef AT_LEAST_AS_LARGE_AS
3294 }
3295
3296 /* Avoid calling `check_string_class_template ()' more than once.  */
3297 static GTY(()) int string_layout_checked;
3298
3299 /* Construct an internal string layout to be used as a template for
3300    creating NSConstantString/NXConstantString instances.  */
3301
3302 static tree
3303 objc_build_internal_const_str_type (void)
3304 {
3305   tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
3306   tree fields = build_decl (input_location,
3307                             FIELD_DECL, NULL_TREE, ptr_type_node);
3308   tree field = build_decl (input_location,
3309                            FIELD_DECL, NULL_TREE, ptr_type_node);
3310
3311   DECL_CHAIN (field) = fields; fields = field;
3312   field = build_decl (input_location,
3313                       FIELD_DECL, NULL_TREE, unsigned_type_node);
3314   DECL_CHAIN (field) = fields; fields = field;
3315   /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
3316      reverse order!  */
3317   finish_builtin_struct (type, "__builtin_ObjCString",
3318                          fields, NULL_TREE);
3319
3320   return type;
3321 }
3322
3323 /* Custom build_string which sets TREE_TYPE!  */
3324
3325 static tree
3326 my_build_string (int len, const char *str)
3327 {
3328   return fix_string_type (build_string (len, str));
3329 }
3330
3331 /* Build a string with contents STR and length LEN and convert it to a
3332    pointer.  */
3333
3334 static tree
3335 my_build_string_pointer (int len, const char *str)
3336 {
3337   tree string = my_build_string (len, str);
3338   tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
3339   return build1 (ADDR_EXPR, ptrtype, string);
3340 }
3341
3342 static hashval_t
3343 string_hash (const void *ptr)
3344 {
3345   const_tree const str = ((const struct string_descriptor *)ptr)->literal;
3346   const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
3347   int i, len = TREE_STRING_LENGTH (str);
3348   hashval_t h = len;
3349
3350   for (i = 0; i < len; i++)
3351     h = ((h * 613) + p[i]);
3352
3353   return h;
3354 }
3355
3356 static int
3357 string_eq (const void *ptr1, const void *ptr2)
3358 {
3359   const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
3360   const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
3361   int len1 = TREE_STRING_LENGTH (str1);
3362
3363   return (len1 == TREE_STRING_LENGTH (str2)
3364           && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
3365                       len1));
3366 }
3367
3368 /* Given a chain of STRING_CST's, build a static instance of
3369    NXConstantString which points at the concatenation of those
3370    strings.  We place the string object in the __string_objects
3371    section of the __OBJC segment.  The Objective-C runtime will
3372    initialize the isa pointers of the string objects to point at the
3373    NXConstantString class object.  */
3374
3375 tree
3376 objc_build_string_object (tree string)
3377 {
3378   tree constant_string_class;
3379   int length;
3380   tree fields, addr;
3381   struct string_descriptor *desc, key;
3382   void **loc;
3383
3384   /* Prep the string argument.  */
3385   string = fix_string_type (string);
3386   TREE_SET_CODE (string, STRING_CST);
3387   length = TREE_STRING_LENGTH (string) - 1;
3388
3389   /* The target may have different ideas on how to construct an ObjC string 
3390      literal.  On Darwin (Mac OS X), for example, we may wish to obtain a 
3391      constant CFString reference instead.
3392      At present, this is only supported for the NeXT runtime.  */
3393   if (flag_next_runtime && targetcm.objc_construct_string_object)
3394     {
3395       tree constructor = (*targetcm.objc_construct_string_object) (string);
3396       if (constructor)
3397         return build1 (NOP_EXPR, objc_object_type, constructor);
3398     }
3399
3400   /* Check whether the string class being used actually exists and has the
3401      correct ivar layout.  */
3402   if (!string_layout_checked)
3403     {
3404       string_layout_checked = -1;
3405       constant_string_class = lookup_interface (constant_string_id);
3406       internal_const_str_type = objc_build_internal_const_str_type ();
3407
3408       if (!constant_string_class
3409           || !(constant_string_type
3410                = CLASS_STATIC_TEMPLATE (constant_string_class)))
3411         error ("cannot find interface declaration for %qE",
3412                constant_string_id);
3413       /* The NSConstantString/NXConstantString ivar layout is now known.  */
3414       else if (!check_string_class_template ())
3415         error ("interface %qE does not have valid constant string layout",
3416                constant_string_id);
3417       /* For the NeXT runtime, we can generate a literal reference
3418          to the string class, don't need to run a constructor.  */
3419       else if (flag_next_runtime && !setup_string_decl ())
3420         error ("cannot find reference tag for class %qE",
3421                constant_string_id);
3422       else
3423         {
3424           string_layout_checked = 1;  /* Success!  */
3425           add_class_reference (constant_string_id);
3426         }
3427     }
3428
3429   if (string_layout_checked == -1)
3430     return error_mark_node;
3431
3432   /* Perhaps we already constructed a constant string just like this one? */
3433   key.literal = string;
3434   loc = htab_find_slot (string_htab, &key, INSERT);
3435   desc = (struct string_descriptor *) *loc;
3436
3437   if (!desc)
3438     {
3439       tree var, constructor;
3440       VEC(constructor_elt,gc) *v = NULL;
3441       *loc = desc = ggc_alloc_string_descriptor ();
3442       desc->literal = string;
3443
3444       /* GNU:    (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length })  */
3445       /* NeXT:   (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length })   */
3446       fields = TYPE_FIELDS (internal_const_str_type);
3447       CONSTRUCTOR_APPEND_ELT (v, fields,
3448                               flag_next_runtime
3449                               ? build_unary_op (input_location,
3450                                                 ADDR_EXPR, string_class_decl, 0)
3451                               : build_int_cst (NULL_TREE, 0));
3452       fields = DECL_CHAIN (fields);
3453       CONSTRUCTOR_APPEND_ELT (v, fields,
3454                               build_unary_op (input_location,
3455                                               ADDR_EXPR, string, 1));
3456       fields = DECL_CHAIN (fields);
3457       CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
3458       constructor = objc_build_constructor (internal_const_str_type, v);
3459
3460       if (!flag_next_runtime)
3461         constructor
3462           = objc_add_static_instance (constructor, constant_string_type);
3463       else
3464         {
3465           var = build_decl (input_location,
3466                             CONST_DECL, NULL, TREE_TYPE (constructor));
3467           DECL_INITIAL (var) = constructor;
3468           TREE_STATIC (var) = 1;
3469           pushdecl_top_level (var);
3470           constructor = var;
3471         }
3472       desc->constructor = constructor;
3473     }
3474
3475   addr = convert (build_pointer_type (constant_string_type),
3476                   build_unary_op (input_location,
3477                                   ADDR_EXPR, desc->constructor, 1));
3478
3479   return addr;
3480 }
3481
3482 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR.  */
3483
3484 static GTY(()) int num_static_inst;
3485
3486 static tree
3487 objc_add_static_instance (tree constructor, tree class_decl)
3488 {
3489   tree *chain, decl;
3490   char buf[256];
3491
3492   /* Find the list of static instances for the CLASS_DECL.  Create one if
3493      not found.  */
3494   for (chain = &objc_static_instances;
3495        *chain && TREE_VALUE (*chain) != class_decl;
3496        chain = &TREE_CHAIN (*chain));
3497   if (!*chain)
3498     {
3499       *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
3500       add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
3501     }
3502
3503   sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
3504   decl = build_decl (input_location,
3505                      VAR_DECL, get_identifier (buf), class_decl);
3506   TREE_STATIC (decl) = 1;
3507   DECL_ARTIFICIAL (decl) = 1;
3508   TREE_USED (decl) = 1;
3509   DECL_INITIAL (decl) = constructor;
3510
3511   /* We may be writing something else just now.
3512      Postpone till end of input.  */
3513   DECL_DEFER_OUTPUT (decl) = 1;
3514   pushdecl_top_level (decl);
3515   rest_of_decl_compilation (decl, 1, 0);
3516
3517   /* Add the DECL to the head of this CLASS' list.  */
3518   TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
3519
3520   return decl;
3521 }
3522
3523 /* Build a static constant CONSTRUCTOR
3524    with type TYPE and elements ELTS.  */
3525
3526 static tree
3527 objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts)
3528 {
3529   tree constructor = build_constructor (type, elts);
3530
3531   TREE_CONSTANT (constructor) = 1;
3532   TREE_STATIC (constructor) = 1;
3533   TREE_READONLY (constructor) = 1;
3534
3535 #ifdef OBJCPLUS
3536   /* Adjust for impedance mismatch.  We should figure out how to build
3537      CONSTRUCTORs that consistently please both the C and C++ gods.  */
3538   if (!VEC_index (constructor_elt, elts, 0)->index)
3539     TREE_TYPE (constructor) = init_list_type_node;
3540 #endif
3541
3542   return constructor;
3543 }
3544 \f
3545 /* Take care of defining and initializing _OBJC_SYMBOLS.  */
3546
3547 /* Predefine the following data type:
3548
3549    struct _objc_symtab
3550    {
3551      long sel_ref_cnt;
3552      SEL *refs;
3553      short cls_def_cnt;
3554      short cat_def_cnt;
3555      void *defs[cls_def_cnt + cat_def_cnt];
3556    }; */
3557
3558 static void
3559 build_objc_symtab_template (void)
3560 {
3561   tree fields, *chain = NULL;
3562
3563   objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
3564
3565   /* long sel_ref_cnt; */
3566   fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
3567
3568   /* SEL *refs; */
3569   add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
3570
3571   /* short cls_def_cnt; */
3572   add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
3573
3574   /* short cat_def_cnt; */
3575   add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
3576
3577   if (imp_count || cat_count || !flag_next_runtime)
3578     {
3579       /* void *defs[imp_count + cat_count (+ 1)]; */
3580       /* NB: The index is one less than the size of the array.  */
3581       int index = imp_count + cat_count + (flag_next_runtime ? -1: 0);
3582       tree array_type = build_sized_array_type (ptr_type_node, index + 1);
3583       add_field_decl (array_type, "defs", &chain);
3584     }
3585
3586   objc_finish_struct (objc_symtab_template, fields);
3587 }
3588
3589 /* Create the initial value for the `defs' field of _objc_symtab.
3590    This is a CONSTRUCTOR.  */
3591
3592 static tree
3593 init_def_list (tree type)
3594 {
3595   tree expr;
3596   struct imp_entry *impent;
3597   VEC(constructor_elt,gc) *v = NULL;
3598
3599   if (imp_count)
3600     for (impent = imp_list; impent; impent = impent->next)
3601       {
3602         if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
3603           {
3604             expr = build_unary_op (input_location,
3605                                    ADDR_EXPR, impent->class_decl, 0);
3606             CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3607           }
3608       }
3609
3610   if (cat_count)
3611     for (impent = imp_list; impent; impent = impent->next)
3612       {
3613         if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
3614           {
3615             expr = build_unary_op (input_location,
3616                                    ADDR_EXPR, impent->class_decl, 0);
3617             CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3618           }
3619       }
3620
3621   if (!flag_next_runtime)
3622     {
3623       /* statics = { ..., _OBJC_STATIC_INSTANCES, ... }  */
3624       if (static_instances_decl)
3625         expr = build_unary_op (input_location,
3626                                ADDR_EXPR, static_instances_decl, 0);
3627       else
3628         expr = integer_zero_node;
3629
3630       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3631     }
3632
3633   return objc_build_constructor (type, v);
3634 }
3635
3636 /* Construct the initial value for all of _objc_symtab.  */
3637
3638 static tree
3639 init_objc_symtab (tree type)
3640 {
3641   VEC(constructor_elt,gc) *v = NULL;
3642
3643   /* sel_ref_cnt = { ..., 5, ... } */
3644
3645   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3646                           build_int_cst (long_integer_type_node, 0));
3647
3648   /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
3649
3650   if (flag_next_runtime || ! sel_ref_chain)
3651     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (
3652                                         build_pointer_type (objc_selector_type),
3653                                                         integer_zero_node));
3654   else
3655     {
3656       tree expr = build_unary_op (input_location, ADDR_EXPR,
3657                                   UOBJC_SELECTOR_TABLE_decl, 1);
3658
3659       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3660                               convert (build_pointer_type (objc_selector_type),
3661                                        expr));
3662     }
3663
3664   /* cls_def_cnt = { ..., 5, ... } */
3665
3666   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 
3667                           build_int_cst (short_integer_type_node, imp_count));
3668
3669   /* cat_def_cnt = { ..., 5, ... } */
3670
3671   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 
3672                           build_int_cst (short_integer_type_node, cat_count));
3673
3674   /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
3675
3676   if (imp_count || cat_count || !flag_next_runtime)
3677     {
3678
3679       tree field = TYPE_FIELDS (type);
3680       field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
3681
3682       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
3683     }
3684
3685   return objc_build_constructor (type, v);
3686 }
3687
3688 /* Generate forward declarations for metadata such as
3689   'OBJC_CLASS_...'.  */
3690
3691 static tree
3692 build_metadata_decl (const char *name, tree type)
3693 {
3694   tree decl;
3695
3696   /* struct TYPE NAME_<name>; */
3697   decl = start_var_decl (type, synth_id_with_class_suffix
3698                                (name,
3699                                 objc_implementation_context));
3700
3701   return decl;
3702 }
3703
3704 /* Push forward-declarations of all the categories so that
3705    init_def_list can use them in a CONSTRUCTOR.  */
3706
3707 static void
3708 forward_declare_categories (void)
3709 {
3710   struct imp_entry *impent;
3711   tree sav = objc_implementation_context;
3712
3713   for (impent = imp_list; impent; impent = impent->next)
3714     {
3715       if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
3716         {
3717           /* Set an invisible arg to synth_id_with_class_suffix.  */
3718           objc_implementation_context = impent->imp_context;
3719           /* extern struct objc_category _OBJC_CATEGORY_<name>; */
3720           impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
3721                                                     objc_category_template);
3722         }
3723     }
3724   objc_implementation_context = sav;
3725 }
3726
3727 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
3728    and initialized appropriately.  */
3729
3730 static void
3731 generate_objc_symtab_decl (void)
3732 {
3733  
3734   build_objc_symtab_template ();
3735   UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
3736   finish_var_decl (UOBJC_SYMBOLS_decl,
3737                    init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
3738 }
3739 \f
3740 static tree
3741 init_module_descriptor (tree type)
3742 {
3743   tree expr;
3744   VEC(constructor_elt,gc) *v = NULL;
3745
3746   /* version = { 1, ... } */
3747
3748   expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
3749   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3750
3751   /* size = { ..., sizeof (struct _objc_module), ... } */
3752
3753   expr = convert (long_integer_type_node,
3754                   size_in_bytes (objc_module_template));
3755   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3756
3757   /* Don't provide any file name for security reasons. */
3758   /* name = { ..., "", ... } */
3759
3760   expr = add_objc_string (get_identifier (""), class_names);
3761   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3762
3763   /* symtab = { ..., _OBJC_SYMBOLS, ... } */
3764
3765   if (UOBJC_SYMBOLS_decl)
3766     expr = build_unary_op (input_location,
3767                            ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
3768   else
3769     expr = null_pointer_node;
3770   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3771
3772   return objc_build_constructor (type, v);
3773 }
3774
3775 /* Write out the data structures to describe Objective C classes defined.
3776
3777    struct _objc_module { ... } _OBJC_MODULE = { ... };   */
3778
3779 static void
3780 build_module_descriptor (void)
3781 {
3782   tree decls, *chain = NULL;
3783
3784 #ifdef OBJCPLUS
3785   push_lang_context (lang_name_c); /* extern "C" */
3786 #endif
3787
3788   objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
3789
3790   /* long version; */
3791   decls = add_field_decl (long_integer_type_node, "version", &chain);
3792
3793   /* long size; */
3794   add_field_decl (long_integer_type_node, "size", &chain);
3795
3796   /* char *name; */
3797   add_field_decl (string_type_node, "name", &chain);
3798
3799   /* struct _objc_symtab *symtab; */
3800   add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
3801                                                 get_identifier (UTAG_SYMTAB))),
3802                   "symtab", &chain);
3803
3804   objc_finish_struct (objc_module_template, decls);
3805
3806   /* Create an instance of "_objc_module".  */
3807   UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
3808   /* This is the root of the metadata for defined classes and categories, it
3809      is referenced by the runtime and, therefore, needed.  */
3810   DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
3811   finish_var_decl (UOBJC_MODULES_decl,
3812                    init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
3813
3814 #ifdef OBJCPLUS
3815   pop_lang_context ();
3816 #endif
3817 }
3818
3819 /* The GNU runtime requires us to provide a static initializer function
3820    for each module:
3821
3822    static void __objc_gnu_init (void) {
3823      __objc_exec_class (&L_OBJC_MODULES);
3824    }  */
3825
3826 static void
3827 build_module_initializer_routine (void)
3828 {
3829   tree body;
3830
3831 #ifdef OBJCPLUS
3832   push_lang_context (lang_name_c); /* extern "C" */
3833 #endif
3834
3835   objc_push_parm (build_decl (input_location,
3836                               PARM_DECL, NULL_TREE, void_type_node));
3837 #ifdef OBJCPLUS
3838   objc_start_function (get_identifier (TAG_GNUINIT),
3839                        build_function_type_list (void_type_node, NULL_TREE),
3840                        NULL_TREE, NULL_TREE);
3841 #else
3842   objc_start_function (get_identifier (TAG_GNUINIT),
3843                        build_function_type_list (void_type_node, NULL_TREE),
3844                        NULL_TREE, objc_get_parm_info (0));
3845 #endif
3846   body = c_begin_compound_stmt (true);
3847   add_stmt (build_function_call
3848             (input_location,
3849              execclass_decl,
3850              build_tree_list
3851              (NULL_TREE,
3852               build_unary_op (input_location, ADDR_EXPR,
3853                               UOBJC_MODULES_decl, 0))));
3854   add_stmt (c_end_compound_stmt (input_location, body, true));
3855
3856   TREE_PUBLIC (current_function_decl) = 0;
3857
3858 #ifndef OBJCPLUS
3859   /* For Objective-C++, we will need to call __objc_gnu_init
3860      from objc_generate_static_init_call() below.  */
3861   DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
3862 #endif
3863
3864   GNU_INIT_decl = current_function_decl;
3865   finish_function ();
3866
3867 #ifdef OBJCPLUS
3868     pop_lang_context ();
3869 #endif
3870 }
3871
3872 #ifdef OBJCPLUS
3873 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
3874    to be called by the module initializer routine.  */
3875
3876 int
3877 objc_static_init_needed_p (void)
3878 {
3879   return (GNU_INIT_decl != NULL_TREE);
3880 }
3881
3882 /* Generate a call to the __objc_gnu_init initializer function.  */
3883
3884 tree
3885 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
3886 {
3887   add_stmt (build_stmt (input_location, EXPR_STMT,
3888                         build_function_call (input_location,
3889                                              GNU_INIT_decl, NULL_TREE)));
3890
3891   return ctors;
3892 }
3893 #endif /* OBJCPLUS */
3894
3895 /* Return the DECL of the string IDENT in the SECTION.  */
3896
3897 static tree
3898 get_objc_string_decl (tree ident, enum string_section section)
3899 {
3900   tree chain;
3901
3902   switch (section)
3903     {
3904     case class_names:
3905       chain = class_names_chain;
3906       break;
3907     case meth_var_names:
3908       chain = meth_var_names_chain;
3909       break;
3910     case meth_var_types:
3911       chain = meth_var_types_chain;
3912       break;
3913     default:
3914       gcc_unreachable ();
3915     }
3916
3917   for (; chain != 0; chain = TREE_CHAIN (chain))
3918     if (TREE_VALUE (chain) == ident)
3919       return (TREE_PURPOSE (chain));
3920
3921   gcc_unreachable ();
3922   return NULL_TREE;
3923 }
3924
3925 /* Output references to all statically allocated objects.  Return the DECL
3926    for the array built.  */
3927
3928 static void
3929 generate_static_references (void)
3930 {
3931   tree expr = NULL_TREE;
3932   tree class_name, klass, decl;
3933   tree cl_chain, in_chain, type
3934     = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
3935   int num_inst, num_class;
3936   char buf[256];
3937   VEC(constructor_elt,gc) *decls = NULL;
3938
3939   if (flag_next_runtime)
3940     gcc_unreachable ();
3941
3942   for (cl_chain = objc_static_instances, num_class = 0;
3943        cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
3944     {
3945       VEC(constructor_elt,gc) *v = NULL;
3946
3947       for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
3948            in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
3949
3950       sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
3951       decl = start_var_decl (type, buf);
3952
3953       /* Output {class_name, ...}.  */
3954       klass = TREE_VALUE (cl_chain);
3955       class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
3956       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3957                               build_unary_op (input_location, 
3958                                               ADDR_EXPR, class_name, 1));
3959
3960       /* Output {..., instance, ...}.  */
3961       for (in_chain = TREE_PURPOSE (cl_chain);
3962            in_chain; in_chain = TREE_CHAIN (in_chain))
3963         {
3964           expr = build_unary_op (input_location,
3965                                  ADDR_EXPR, TREE_VALUE (in_chain), 1);
3966           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3967         }
3968
3969       /* Output {..., NULL}.  */
3970       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
3971
3972       expr = objc_build_constructor (TREE_TYPE (decl), v);
3973       finish_var_decl (decl, expr);
3974       CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
3975                               build_unary_op (input_location,
3976                                               ADDR_EXPR, decl, 1));
3977     }
3978
3979   CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
3980   expr = objc_build_constructor (type, decls);
3981   static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
3982   finish_var_decl (static_instances_decl, expr);
3983 }
3984
3985 static GTY(()) int selector_reference_idx;
3986
3987 static tree
3988 build_selector_reference_decl (void)
3989 {
3990   tree decl;
3991   char buf[256];
3992
3993   sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
3994   decl = start_var_decl (objc_selector_type, buf);
3995
3996   return decl;
3997 }
3998
3999 static void
4000 build_selector_table_decl (void)
4001 {
4002   tree temp;
4003
4004   if (flag_typed_selectors)
4005     {
4006       build_selector_template ();
4007       temp = build_array_type (objc_selector_template, NULL_TREE);
4008     }
4009   else
4010     temp = build_array_type (objc_selector_type, NULL_TREE);
4011
4012   UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
4013 }
4014
4015 /* Just a handy wrapper for add_objc_string.  */
4016
4017 static tree
4018 build_selector (tree ident)
4019 {
4020   return convert (objc_selector_type,
4021                   add_objc_string (ident, meth_var_names));
4022 }
4023