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