OSDN Git Service

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