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