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