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