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