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