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