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