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