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