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