2005-01-22 Thomas Koenig <Thomas.Koenig@online.de>
[official-gcc.git] / gcc / objc / objc-act.c
blob65af654cb5d1d88084cd36d2fa1555703d76d03a
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 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
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.
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.
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. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
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.
38 code generation `options':
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"
51 #ifdef OBJCPLUS
52 #include "cp-tree.h"
53 #else
54 #include "c-tree.h"
55 #endif
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"
77 #define OBJC_VOID_AT_END void_list_node
79 /* When building Objective-C++, we are not linking against the C front-end
80 and so need to replicate the C tree-construction functions in some way. */
81 #ifdef OBJCPLUS
82 #define OBJCP_REMAP_FUNCTIONS
83 #include "objcp-decl.h"
84 #endif /* OBJCPLUS */
86 /* This is the default way of generating a method name. */
87 /* I am not sure it is really correct.
88 Perhaps there's a danger that it will make name conflicts
89 if method names contain underscores. -- rms. */
90 #ifndef OBJC_GEN_METHOD_LABEL
91 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
92 do { \
93 char *temp; \
94 sprintf ((BUF), "_%s_%s_%s_%s", \
95 ((IS_INST) ? "i" : "c"), \
96 (CLASS_NAME), \
97 ((CAT_NAME)? (CAT_NAME) : ""), \
98 (SEL_NAME)); \
99 for (temp = (BUF); *temp; temp++) \
100 if (*temp == ':') *temp = '_'; \
101 } while (0)
102 #endif
104 /* These need specifying. */
105 #ifndef OBJC_FORWARDING_STACK_OFFSET
106 #define OBJC_FORWARDING_STACK_OFFSET 0
107 #endif
109 #ifndef OBJC_FORWARDING_MIN_OFFSET
110 #define OBJC_FORWARDING_MIN_OFFSET 0
111 #endif
113 /* Set up for use of obstacks. */
115 #include "obstack.h"
117 /* This obstack is used to accumulate the encoding of a data type. */
118 static struct obstack util_obstack;
120 /* This points to the beginning of obstack contents, so we can free
121 the whole contents. */
122 char *util_firstobj;
124 /* The version identifies which language generation and runtime
125 the module (file) was compiled for, and is recorded in the
126 module descriptor. */
128 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
129 #define PROTOCOL_VERSION 2
131 /* (Decide if these can ever be validly changed.) */
132 #define OBJC_ENCODE_INLINE_DEFS 0
133 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
135 /*** Private Interface (procedures) ***/
137 /* Used by compile_file. */
139 static void init_objc (void);
140 static void finish_objc (void);
142 /* Code generation. */
144 static void synth_module_prologue (void);
145 static tree objc_build_constructor (tree, tree);
146 static void build_module_descriptor (void);
147 static void build_module_initializer_routine (void);
148 static tree init_module_descriptor (tree);
149 static tree build_objc_method_call (int, tree, tree, tree, tree);
150 static void generate_strings (void);
151 static tree get_proto_encoding (tree);
152 static void build_selector_translation_table (void);
153 static tree lookup_interface (tree);
154 static tree objc_add_static_instance (tree, tree);
156 static tree start_class (enum tree_code, tree, tree, tree);
157 static tree continue_class (tree);
158 static void finish_class (tree);
159 static void start_method_def (tree);
160 #ifdef OBJCPLUS
161 static void objc_start_function (tree, tree, tree, tree);
162 #else
163 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
164 #endif
165 static tree start_protocol (enum tree_code, tree, tree);
166 static tree build_method_decl (enum tree_code, tree, tree, tree);
167 static tree objc_add_method (tree, tree, int);
168 static tree add_instance_variable (tree, int, tree);
169 static tree build_ivar_reference (tree);
170 static tree is_ivar (tree, tree);
171 static int is_private (tree);
172 static tree get_super_receiver (void);
174 static void build_objc_exception_stuff (void);
175 static void build_next_objc_exception_stuff (void);
177 static tree build_ivar_template (void);
178 static tree build_method_template (void);
179 static void build_private_template (tree);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static tree lookup_method_in_hash_lists (tree, int);
184 static void build_super_template (void);
185 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
186 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
187 static void synth_forward_declarations (void);
188 static int ivar_list_length (tree);
189 static tree get_class_ivars (tree);
190 static void generate_ivar_lists (void);
191 static void generate_dispatch_tables (void);
192 static void generate_shared_structures (void);
193 static tree generate_protocol_list (tree);
194 static void build_protocol_reference (tree);
196 static tree build_keyword_selector (tree);
197 static const char *synth_id_with_class_suffix (const char *, tree);
199 static void generate_static_references (void);
200 static int check_methods_accessible (tree, tree, int);
201 static void encode_aggregate_within (tree, int, int, int, int);
202 static const char *objc_demangle (const char *);
204 /* Hash tables to manage the global pool of method prototypes. */
206 hash *nst_method_hash_list = 0;
207 hash *cls_method_hash_list = 0;
209 static size_t hash_func (tree);
210 static void hash_init (void);
211 static void hash_enter (hash *, tree);
212 static hash hash_lookup (hash *, tree);
213 static void hash_add_attr (hash, tree);
214 static tree lookup_method (tree, tree);
215 static tree lookup_method_static (tree, tree, int);
216 static void add_method_to_hash_list (hash *, tree);
217 static tree add_class (tree);
218 static void add_category (tree, tree);
219 static inline tree lookup_category (tree, tree);
221 enum string_section
223 class_names, /* class, category, protocol, module names */
224 meth_var_names, /* method and variable names */
225 meth_var_types /* method and variable type descriptors */
228 static tree add_objc_string (tree, enum string_section);
229 static tree get_objc_string_decl (tree, enum string_section);
230 static tree build_objc_string_decl (enum string_section);
231 static tree build_selector_reference_decl (void);
232 static void build_selector_table_decl (void);
234 /* Protocol additions. */
236 static tree add_protocol (tree);
237 static tree lookup_protocol (tree);
238 static void check_protocol_recursively (tree, tree);
239 static tree lookup_and_install_protocols (tree);
241 /* Type encoding. */
243 static void encode_type_qualifiers (tree);
244 static void encode_pointer (tree, int, int);
245 static void encode_array (tree, int, int);
246 static void encode_aggregate (tree, int, int);
247 static void encode_next_bitfield (int);
248 static void encode_gnu_bitfield (int, tree, int);
249 static void encode_type (tree, int, int);
250 static void encode_field_decl (tree, int, int);
252 #ifdef OBJCPLUS
253 static void really_start_method (tree, tree);
254 #else
255 static void really_start_method (tree, struct c_arg_info *);
256 #endif
257 static int objc_types_are_equivalent (tree, tree);
258 static int comp_proto_with_proto (tree, tree);
259 static tree get_arg_type_list (tree, int, int);
260 static void objc_push_parm (tree);
261 #ifdef OBJCPLUS
262 static tree objc_get_parm_info (int);
263 #else
264 static struct c_arg_info *objc_get_parm_info (int);
265 #endif
266 static void synth_self_and_ucmd_args (void);
268 /* Utilities for debugging and error diagnostics. */
270 static void warn_with_method (const char *, int, tree);
271 static void error_with_ivar (const char *, tree);
272 static char *gen_type_name (tree);
273 static char *gen_type_name_0 (tree);
274 static char *gen_method_decl (tree);
275 static char *gen_declaration (tree);
276 static void dump_interface (FILE *, tree);
278 /* Everything else. */
280 static tree lookup_method_in_protocol_list (tree, tree, int);
281 static tree lookup_protocol_in_reflist (tree, tree);
282 static tree start_var_decl (tree, const char *);
283 static void finish_var_decl (tree, tree);
284 static tree create_field_decl (tree, const char *);
285 static tree setup_string_decl (void);
286 static int check_string_class_template (void);
287 static tree my_build_string (int, const char *);
288 static void build_objc_symtab_template (void);
289 static tree init_def_list (tree);
290 static tree init_objc_symtab (tree);
291 static tree build_metadata_decl (const char *, tree);
292 static void forward_declare_categories (void);
293 static void generate_objc_symtab_decl (void);
294 static tree build_selector (tree);
295 static tree build_typed_selector_reference (tree, tree);
296 static tree build_selector_reference (tree);
297 static tree build_class_reference_decl (void);
298 static void add_class_reference (tree);
299 static void build_protocol_template (void);
300 static tree build_descriptor_table_initializer (tree, tree);
301 static tree build_method_prototype_list_template (tree, int);
302 static tree build_method_prototype_template (void);
303 static tree objc_method_parm_type (tree);
304 static int objc_encoded_type_size (tree);
305 static tree encode_method_prototype (tree);
306 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
307 static void generate_method_descriptors (tree);
308 static void generate_protocol_references (tree);
309 static void generate_protocols (void);
310 static void check_ivars (tree, tree);
311 static tree build_ivar_list_template (tree, int);
312 static tree build_method_list_template (tree, int);
313 static tree build_ivar_list_initializer (tree, tree);
314 static tree generate_ivars_list (tree, const char *, int, tree);
315 static tree build_dispatch_table_initializer (tree, tree);
316 static tree generate_dispatch_table (tree, const char *, int, tree);
317 static tree build_shared_structure_initializer (tree, tree, tree, tree,
318 tree, int, tree, tree, tree);
319 static void generate_category (tree);
320 static tree adjust_type_for_id_default (tree);
321 static tree check_duplicates (hash, int, int);
322 static tree receiver_is_class_object (tree, int, int);
323 static int check_methods (tree, tree, int);
324 static int conforms_to_protocol (tree, tree);
325 static void check_protocol (tree, const char *, const char *);
326 static void check_protocols (tree, const char *, const char *);
327 static void generate_classref_translation_entry (tree);
328 static void handle_class_ref (tree);
329 static void generate_struct_by_value_array (void)
330 ATTRIBUTE_NORETURN;
331 static void mark_referenced_methods (void);
332 static void generate_objc_image_info (void);
334 /*** Private Interface (data) ***/
336 /* Reserved tag definitions. */
338 #define OBJECT_TYPEDEF_NAME "id"
339 #define CLASS_TYPEDEF_NAME "Class"
341 #define TAG_OBJECT "objc_object"
342 #define TAG_CLASS "objc_class"
343 #define TAG_SUPER "objc_super"
344 #define TAG_SELECTOR "objc_selector"
346 #define UTAG_CLASS "_objc_class"
347 #define UTAG_IVAR "_objc_ivar"
348 #define UTAG_IVAR_LIST "_objc_ivar_list"
349 #define UTAG_METHOD "_objc_method"
350 #define UTAG_METHOD_LIST "_objc_method_list"
351 #define UTAG_CATEGORY "_objc_category"
352 #define UTAG_MODULE "_objc_module"
353 #define UTAG_SYMTAB "_objc_symtab"
354 #define UTAG_SUPER "_objc_super"
355 #define UTAG_SELECTOR "_objc_selector"
357 #define UTAG_PROTOCOL "_objc_protocol"
358 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
359 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
361 /* Note that the string object global name is only needed for the
362 NeXT runtime. */
363 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
365 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
367 static const char *TAG_GETCLASS;
368 static const char *TAG_GETMETACLASS;
369 static const char *TAG_MSGSEND;
370 static const char *TAG_MSGSENDSUPER;
371 /* The NeXT Objective-C messenger may have two extra entry points, for use
372 when returning a structure. */
373 static const char *TAG_MSGSEND_STRET;
374 static const char *TAG_MSGSENDSUPER_STRET;
375 static const char *default_constant_string_class_name;
377 /* Runtime metadata flags. */
378 #define CLS_FACTORY 0x0001L
379 #define CLS_META 0x0002L
381 #define OBJC_MODIFIER_STATIC 0x00000001
382 #define OBJC_MODIFIER_FINAL 0x00000002
383 #define OBJC_MODIFIER_PUBLIC 0x00000004
384 #define OBJC_MODIFIER_PRIVATE 0x00000008
385 #define OBJC_MODIFIER_PROTECTED 0x00000010
386 #define OBJC_MODIFIER_NATIVE 0x00000020
387 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
388 #define OBJC_MODIFIER_ABSTRACT 0x00000080
389 #define OBJC_MODIFIER_VOLATILE 0x00000100
390 #define OBJC_MODIFIER_TRANSIENT 0x00000200
391 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
393 /* NeXT-specific tags. */
395 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
396 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
397 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
398 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
399 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
400 #define TAG_EXCEPTIONMATCH "objc_exception_match"
401 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
402 #define TAG_SYNCENTER "objc_sync_enter"
403 #define TAG_SYNCEXIT "objc_sync_exit"
404 #define TAG_SETJMP "_setjmp"
405 #define UTAG_EXCDATA "_objc_exception_data"
407 /* GNU-specific tags. */
409 #define TAG_EXECCLASS "__objc_exec_class"
410 #define TAG_GNUINIT "__objc_gnu_init"
412 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
413 tree objc_global_trees[OCTI_MAX];
415 static void handle_impent (struct imp_entry *);
417 struct imp_entry *imp_list = 0;
418 int imp_count = 0; /* `@implementation' */
419 int cat_count = 0; /* `@category' */
421 enum tree_code objc_inherit_code;
422 int objc_public_flag;
424 /* Use to generate method labels. */
425 static int method_slot = 0;
427 #define BUFSIZE 1024
429 static char *errbuf; /* Buffer for error diagnostics */
431 /* Data imported from tree.c. */
433 extern enum debug_info_type write_symbols;
435 /* Data imported from toplev.c. */
437 extern const char *dump_base_name;
439 static int flag_typed_selectors;
441 /* Store all constructed constant strings in a hash table so that
442 they get uniqued properly. */
444 struct string_descriptor GTY(())
446 /* The literal argument . */
447 tree literal;
449 /* The resulting constant string. */
450 tree constructor;
453 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
455 static hashval_t string_hash (const void *);
456 static int string_eq (const void *, const void *);
458 FILE *gen_declaration_file;
460 /* Tells "encode_pointer/encode_aggregate" whether we are generating
461 type descriptors for instance variables (as opposed to methods).
462 Type descriptors for instance variables contain more information
463 than methods (for static typing and embedded structures). */
465 static int generating_instance_variables = 0;
467 /* Some platforms pass small structures through registers versus
468 through an invisible pointer. Determine at what size structure is
469 the transition point between the two possibilities. */
471 static void
472 generate_struct_by_value_array (void)
474 tree type;
475 tree field_decl, field_decl_chain;
476 int i, j;
477 int aggregate_in_mem[32];
478 int found = 0;
480 /* Presumably no platform passes 32 byte structures in a register. */
481 for (i = 1; i < 32; i++)
483 char buffer[5];
485 /* Create an unnamed struct that has `i' character components */
486 type = start_struct (RECORD_TYPE, NULL_TREE);
488 strcpy (buffer, "c1");
489 field_decl = create_field_decl (char_type_node,
490 buffer);
491 field_decl_chain = field_decl;
493 for (j = 1; j < i; j++)
495 sprintf (buffer, "c%d", j + 1);
496 field_decl = create_field_decl (char_type_node,
497 buffer);
498 chainon (field_decl_chain, field_decl);
500 finish_struct (type, field_decl_chain, NULL_TREE);
502 aggregate_in_mem[i] = aggregate_value_p (type, 0);
503 if (!aggregate_in_mem[i])
504 found = 1;
507 /* We found some structures that are returned in registers instead of memory
508 so output the necessary data. */
509 if (found)
511 for (i = 31; i >= 0; i--)
512 if (!aggregate_in_mem[i])
513 break;
514 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
516 /* The first member of the structure is always 0 because we don't handle
517 structures with 0 members */
518 printf ("static int struct_forward_array[] = {\n 0");
520 for (j = 1; j <= i; j++)
521 printf (", %d", aggregate_in_mem[j]);
522 printf ("\n};\n");
525 exit (0);
528 bool
529 objc_init (void)
531 #ifdef OBJCPLUS
532 if (cxx_init () == false)
533 #else
534 if (c_objc_common_init () == false)
535 #endif
536 return false;
538 #ifndef USE_MAPPED_LOCATION
539 /* Force the line number back to 0; check_newline will have
540 raised it to 1, which will make the builtin functions appear
541 not to be built in. */
542 input_line = 0;
543 #endif
545 /* If gen_declaration desired, open the output file. */
546 if (flag_gen_declaration)
548 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
549 gen_declaration_file = fopen (dumpname, "w");
550 if (gen_declaration_file == 0)
551 fatal_error ("can't open %s: %m", dumpname);
552 free (dumpname);
555 if (flag_next_runtime)
557 TAG_GETCLASS = "objc_getClass";
558 TAG_GETMETACLASS = "objc_getMetaClass";
559 TAG_MSGSEND = "objc_msgSend";
560 TAG_MSGSENDSUPER = "objc_msgSendSuper";
561 TAG_MSGSEND_STRET = "objc_msgSend_stret";
562 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
563 default_constant_string_class_name = "NSConstantString";
565 else
567 TAG_GETCLASS = "objc_get_class";
568 TAG_GETMETACLASS = "objc_get_meta_class";
569 TAG_MSGSEND = "objc_msg_lookup";
570 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
571 /* GNU runtime does not provide special functions to support
572 structure-returning methods. */
573 default_constant_string_class_name = "NXConstantString";
574 flag_typed_selectors = 1;
577 init_objc ();
579 if (print_struct_values)
580 generate_struct_by_value_array ();
582 return true;
585 void
586 objc_finish_file (void)
588 mark_referenced_methods ();
590 #ifdef OBJCPLUS
591 /* We need to instantiate templates _before_ we emit ObjC metadata;
592 if we do not, some metadata (such as selectors) may go missing. */
593 instantiate_pending_templates (0);
594 #endif
596 /* Finalize Objective-C runtime data. No need to generate tables
597 and code if only checking syntax. */
598 if (!flag_syntax_only)
599 finish_objc ();
601 if (gen_declaration_file)
602 fclose (gen_declaration_file);
604 #ifdef OBJCPLUS
605 cp_finish_file ();
606 #endif
609 /* Return the first occurrence of a method declaration corresponding
610 to sel_name in rproto_list. Search rproto_list recursively.
611 If is_class is 0, search for instance methods, otherwise for class
612 methods. */
613 static tree
614 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
615 int is_class)
617 tree rproto, p;
618 tree fnd = 0;
620 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
622 p = TREE_VALUE (rproto);
624 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
626 if ((fnd = lookup_method (is_class
627 ? PROTOCOL_CLS_METHODS (p)
628 : PROTOCOL_NST_METHODS (p), sel_name)))
630 else if (PROTOCOL_LIST (p))
631 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
632 sel_name, is_class);
634 else
636 ; /* An identifier...if we could not find a protocol. */
639 if (fnd)
640 return fnd;
643 return 0;
646 static tree
647 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
649 tree rproto, p;
651 /* Make sure the protocol is supported by the object on the rhs. */
652 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
654 tree fnd = 0;
655 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
657 p = TREE_VALUE (rproto);
659 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
661 if (lproto == p)
662 fnd = lproto;
664 else if (PROTOCOL_LIST (p))
665 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
668 if (fnd)
669 return fnd;
672 else
674 ; /* An identifier...if we could not find a protocol. */
677 return 0;
680 void
681 objc_start_class_interface (tree class, tree super_class, tree protos)
683 objc_interface_context
684 = objc_ivar_context
685 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
686 objc_public_flag = 0;
689 void
690 objc_start_category_interface (tree class, tree categ, tree protos)
692 objc_interface_context
693 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
694 objc_ivar_chain
695 = continue_class (objc_interface_context);
698 void
699 objc_start_protocol (tree name, tree protos)
701 objc_interface_context
702 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
705 void
706 objc_continue_interface (void)
708 objc_ivar_chain
709 = continue_class (objc_interface_context);
712 void
713 objc_finish_interface (void)
715 finish_class (objc_interface_context);
716 objc_interface_context = NULL_TREE;
719 void
720 objc_start_class_implementation (tree class, tree super_class)
722 objc_implementation_context
723 = objc_ivar_context
724 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
725 objc_public_flag = 0;
728 void
729 objc_start_category_implementation (tree class, tree categ)
731 objc_implementation_context
732 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
733 objc_ivar_chain
734 = continue_class (objc_implementation_context);
737 void
738 objc_continue_implementation (void)
740 objc_ivar_chain
741 = continue_class (objc_implementation_context);
744 void
745 objc_finish_implementation (void)
747 if (objc_implementation_context)
749 finish_class (objc_implementation_context);
750 objc_ivar_chain = NULL_TREE;
751 objc_implementation_context = NULL_TREE;
753 else
754 warning ("%<@end%> must appear in an @implementation context");
757 void
758 objc_set_visibility (int visibility)
760 objc_public_flag = visibility;
763 void
764 objc_set_method_type (enum tree_code type)
766 objc_inherit_code = (type == PLUS_EXPR
767 ? CLASS_METHOD_DECL
768 : INSTANCE_METHOD_DECL);
771 tree
772 objc_build_method_signature (tree rettype, tree selector, tree optparms)
774 return build_method_decl (objc_inherit_code, rettype, selector, optparms);
777 void
778 objc_add_method_declaration (tree decl)
780 if (!objc_interface_context)
781 fatal_error ("method declaration not in @interface context");
783 objc_add_method (objc_interface_context,
784 decl,
785 objc_inherit_code == CLASS_METHOD_DECL);
788 void
789 objc_start_method_definition (tree decl)
791 if (!objc_implementation_context)
792 fatal_error ("method definition not in @implementation context");
794 objc_add_method (objc_implementation_context,
795 decl,
796 objc_inherit_code == CLASS_METHOD_DECL);
797 start_method_def (decl);
800 void
801 objc_add_instance_variable (tree decl)
803 (void) add_instance_variable (objc_ivar_context,
804 objc_public_flag,
805 decl);
808 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
809 an '@'. */
812 objc_is_reserved_word (tree ident)
814 unsigned char code = C_RID_CODE (ident);
816 return (OBJC_IS_AT_KEYWORD (code)
817 #ifdef OBJCPLUS
818 || code == RID_CLASS || code == RID_PUBLIC
819 || code == RID_PROTECTED || code == RID_PRIVATE
820 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
821 #endif
825 /* Return true if TYPE is 'id'. */
827 static bool
828 objc_is_object_id (tree type)
830 return OBJC_TYPE_NAME (type) == objc_object_id;
833 static bool
834 objc_is_class_id (tree type)
836 return OBJC_TYPE_NAME (type) == objc_class_id;
839 /* Return 1 if LHS and RHS are compatible types for assignment or
840 various other operations. Return 0 if they are incompatible, and
841 return -1 if we choose to not decide (because the types are really
842 just C types, not ObjC specific ones). When the operation is
843 REFLEXIVE (typically comparisons), check for compatibility in
844 either direction; when it's not (typically assignments), don't.
846 This function is called in two cases: when both lhs and rhs are
847 pointers to records (in which case we check protocols too), and
848 when both lhs and rhs are records (in which case we check class
849 inheritance only).
851 Warnings about classes/protocols not implementing a protocol are
852 emitted here (multiple of those warnings might be emitted for a
853 single line!); generic warnings about incompatible assignments and
854 lacks of casts in comparisons are/must be emitted by the caller if
855 we return 0.
859 objc_comptypes (tree lhs, tree rhs, int reflexive)
861 /* New clause for protocols. */
863 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
864 manage the ObjC ones, and leave the rest to the C code. */
865 if (TREE_CODE (lhs) == POINTER_TYPE
866 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
867 && TREE_CODE (rhs) == POINTER_TYPE
868 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
870 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_UNTYPED (lhs);
871 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_UNTYPED (rhs);
873 if (lhs_is_proto)
875 tree lproto, lproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (lhs));
876 tree rproto, rproto_list;
877 tree p;
879 /* <Protocol> = <Protocol> */
880 if (rhs_is_proto)
882 /* Class <Protocol> != id <Protocol>;
883 id <Protocol> != Class <Protocol> */
884 if (IS_ID (lhs) != IS_ID (rhs))
885 return 0;
887 rproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs));
889 if (!reflexive)
891 /* An assignment between objects of type 'id
892 <Protocol>'; make sure the protocol on the lhs is
893 supported by the object on the rhs. */
894 for (lproto = lproto_list; lproto;
895 lproto = TREE_CHAIN (lproto))
897 p = TREE_VALUE (lproto);
898 rproto = lookup_protocol_in_reflist (rproto_list, p);
900 if (!rproto)
901 warning
902 ("object does not conform to the %qs protocol",
903 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
905 return 1;
907 else
909 /* Obscure case - a comparison between two objects
910 of type 'id <Protocol>'. Check that either the
911 protocol on the lhs is supported by the object on
912 the rhs, or viceversa. */
914 /* Check if the protocol on the lhs is supported by the
915 object on the rhs. */
916 for (lproto = lproto_list; lproto;
917 lproto = TREE_CHAIN (lproto))
919 p = TREE_VALUE (lproto);
920 rproto = lookup_protocol_in_reflist (rproto_list, p);
922 if (!rproto)
924 /* Check failed - check if the protocol on the rhs
925 is supported by the object on the lhs. */
926 for (rproto = rproto_list; rproto;
927 rproto = TREE_CHAIN (rproto))
929 p = TREE_VALUE (rproto);
930 lproto = lookup_protocol_in_reflist (lproto_list,
933 if (!lproto)
935 /* This check failed too: incompatible */
936 return 0;
939 return 1;
942 return 1;
945 /* <Protocol> = <class> * */
946 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
948 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
949 tree rinter;
951 /* Class <Protocol> != <class> * */
952 if (IS_CLASS (lhs))
953 return 0;
955 /* Make sure the protocol is supported by the object on
956 the rhs. */
957 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
959 p = TREE_VALUE (lproto);
960 rproto = 0;
961 rinter = lookup_interface (rname);
963 while (rinter && !rproto)
965 tree cat;
967 rproto_list = CLASS_PROTOCOL_LIST (rinter);
968 rproto = lookup_protocol_in_reflist (rproto_list, p);
969 /* If the underlying ObjC class does not have
970 the protocol we're looking for, check for "one-off"
971 protocols (e.g., `NSObject<MyProt> *foo;') attached
972 to the rhs. */
973 if (!rproto && TYPE_HAS_OBJC_INFO (TREE_TYPE (rhs)))
975 rproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs));
976 rproto = lookup_protocol_in_reflist (rproto_list, p);
979 /* Check for protocols adopted by categories. */
980 cat = CLASS_CATEGORY_LIST (rinter);
981 while (cat && !rproto)
983 rproto_list = CLASS_PROTOCOL_LIST (cat);
984 rproto = lookup_protocol_in_reflist (rproto_list, p);
985 cat = CLASS_CATEGORY_LIST (cat);
988 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
991 if (!rproto)
992 warning ("class %qs does not implement the %qs protocol",
993 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
994 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
996 return 1;
998 /* id <Protocol> = id; Class <Protocol> = id */
999 else if (objc_is_object_id (TREE_TYPE (rhs)))
1001 return 1;
1003 /* id <Protocol> != Class; Class <Protocol> = Class */
1004 else if (objc_is_class_id (TREE_TYPE (rhs)))
1006 return IS_CLASS (lhs);
1008 /* <Protocol> = ?? : let comptypes decide. */
1009 return -1;
1011 else if (rhs_is_proto)
1013 /* <class> * = <Protocol> */
1014 if (TYPED_OBJECT (TREE_TYPE (lhs)))
1016 /* <class> * != Class <Protocol> */
1017 if (IS_CLASS (rhs))
1018 return 0;
1020 if (reflexive)
1022 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
1023 tree rinter;
1024 tree rproto, rproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs));
1026 /* Make sure the protocol is supported by the object on
1027 the lhs. */
1028 for (rproto = rproto_list; rproto;
1029 rproto = TREE_CHAIN (rproto))
1031 tree p = TREE_VALUE (rproto);
1032 tree lproto = 0;
1033 rinter = lookup_interface (rname);
1035 while (rinter && !lproto)
1037 tree cat;
1039 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
1040 lproto = lookup_protocol_in_reflist (lproto_list, p);
1041 /* If the underlying ObjC class does not
1042 have the protocol we're looking for,
1043 check for "one-off" protocols (e.g.,
1044 `NSObject<MyProt> *foo;') attached to the
1045 lhs. */
1046 if (!lproto && TYPE_HAS_OBJC_INFO (TREE_TYPE (lhs)))
1048 lproto_list = TYPE_OBJC_PROTOCOL_LIST
1049 (TREE_TYPE (lhs));
1050 lproto = lookup_protocol_in_reflist
1051 (lproto_list, p);
1054 /* Check for protocols adopted by categories. */
1055 cat = CLASS_CATEGORY_LIST (rinter);
1056 while (cat && !lproto)
1058 lproto_list = CLASS_PROTOCOL_LIST (cat);
1059 lproto = lookup_protocol_in_reflist (lproto_list,
1061 cat = CLASS_CATEGORY_LIST (cat);
1064 rinter = lookup_interface (CLASS_SUPER_NAME
1065 (rinter));
1068 if (!lproto)
1069 warning ("class %qs does not implement the %qs protocol",
1070 IDENTIFIER_POINTER (OBJC_TYPE_NAME
1071 (TREE_TYPE (lhs))),
1072 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1074 return 1;
1076 else
1077 return 0;
1079 /* id = id <Protocol>; id = Class <Protocol> */
1080 else if (objc_is_object_id (TREE_TYPE (lhs)))
1082 return 1;
1084 /* Class != id <Protocol>; Class = Class <Protocol> */
1085 else if (objc_is_class_id (TREE_TYPE (lhs)))
1087 return IS_CLASS (rhs);
1089 /* ??? = <Protocol> : let comptypes decide */
1090 else
1092 return -1;
1095 else
1097 /* Attention: we shouldn't defer to comptypes here. One bad
1098 side effect would be that we might loose the REFLEXIVE
1099 information.
1101 lhs = TREE_TYPE (lhs);
1102 rhs = TREE_TYPE (rhs);
1106 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
1108 /* Nothing to do with ObjC - let immediately comptypes take
1109 responsibility for checking. */
1110 return -1;
1113 /* `id' = `<class> *' `<class> *' = `id': always allow it.
1114 Please note that
1115 'Object *o = [[Object alloc] init]; falls
1116 in the case <class> * = `id'.
1118 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
1119 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
1120 return 1;
1122 /* `id' = `Class', `Class' = `id' */
1124 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
1125 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
1126 return 1;
1128 /* `Class' != `<class> *' && `<class> *' != `Class'! */
1129 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
1130 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
1131 return 0;
1133 /* `<class> *' = `<class> *' */
1135 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1137 tree lname = OBJC_TYPE_NAME (lhs);
1138 tree rname = OBJC_TYPE_NAME (rhs);
1139 tree inter;
1141 if (lname == rname)
1142 return 1;
1144 /* If the left hand side is a super class of the right hand side,
1145 allow it. */
1146 for (inter = lookup_interface (rname); inter;
1147 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1148 if (lname == CLASS_SUPER_NAME (inter))
1149 return 1;
1151 /* Allow the reverse when reflexive. */
1152 if (reflexive)
1153 for (inter = lookup_interface (lname); inter;
1154 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1155 if (rname == CLASS_SUPER_NAME (inter))
1156 return 1;
1158 return 0;
1160 else
1161 /* Not an ObjC type - let comptypes do the check. */
1162 return -1;
1165 /* Called from finish_decl. */
1167 void
1168 objc_check_decl (tree decl)
1170 tree type = TREE_TYPE (decl);
1172 if (TREE_CODE (type) != RECORD_TYPE)
1173 return;
1174 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1175 error ("statically allocated instance of Objective-C class %qs",
1176 IDENTIFIER_POINTER (type));
1179 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1180 either name an Objective-C class, or refer to the special 'id' or 'Class'
1181 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1183 tree
1184 objc_get_protocol_qualified_type (tree interface, tree protocols)
1186 /* If INTERFACE is not provided, default to 'id'. */
1187 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1188 bool is_ptr = (type != NULL_TREE);
1190 if (!is_ptr)
1192 type = objc_is_class_name (interface);
1194 if (type)
1195 type = xref_tag (RECORD_TYPE, type);
1196 else
1197 return interface;
1200 if (protocols)
1202 type = build_variant_type_copy (type);
1204 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1205 to the pointee. */
1206 if (is_ptr)
1208 TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
1209 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1210 type = TREE_TYPE (type);
1213 /* Look up protocols and install in lang specific list. */
1214 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1215 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1217 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1218 return the pointer to the new pointee variant. */
1219 if (is_ptr)
1220 type = TYPE_POINTER_TO (type);
1221 else
1222 TYPE_OBJC_INTERFACE (type)
1223 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1226 return type;
1229 /* Check for circular dependencies in protocols. The arguments are
1230 PROTO, the protocol to check, and LIST, a list of protocol it
1231 conforms to. */
1233 static void
1234 check_protocol_recursively (tree proto, tree list)
1236 tree p;
1238 for (p = list; p; p = TREE_CHAIN (p))
1240 tree pp = TREE_VALUE (p);
1242 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1243 pp = lookup_protocol (pp);
1245 if (pp == proto)
1246 fatal_error ("protocol %qs has circular dependency",
1247 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1248 if (pp)
1249 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1253 /* Look up PROTOCOLS, and return a list of those that are found.
1254 If none are found, return NULL. */
1256 static tree
1257 lookup_and_install_protocols (tree protocols)
1259 tree proto;
1260 tree return_value = NULL_TREE;
1262 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1264 tree ident = TREE_VALUE (proto);
1265 tree p = lookup_protocol (ident);
1267 if (!p)
1268 error ("cannot find protocol declaration for %qs",
1269 IDENTIFIER_POINTER (ident));
1270 else
1271 return_value = chainon (return_value,
1272 build_tree_list (NULL_TREE, p));
1275 return return_value;
1278 /* Create a declaration for field NAME of a given TYPE. */
1280 static tree
1281 create_field_decl (tree type, const char *name)
1283 return build_decl (FIELD_DECL, get_identifier (name), type);
1286 /* Create a global, static declaration for variable NAME of a given TYPE. The
1287 finish_var_decl() routine will need to be called on it afterwards. */
1289 static tree
1290 start_var_decl (tree type, const char *name)
1292 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1294 TREE_STATIC (var) = 1;
1295 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1296 DECL_IGNORED_P (var) = 1;
1297 DECL_ARTIFICIAL (var) = 1;
1298 DECL_CONTEXT (var) = NULL_TREE;
1299 #ifdef OBJCPLUS
1300 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1301 #endif
1303 return var;
1306 /* Finish off the variable declaration created by start_var_decl(). */
1308 static void
1309 finish_var_decl (tree var, tree initializer)
1311 finish_decl (var, initializer, NULL_TREE);
1312 /* Ensure that the variable actually gets output. */
1313 mark_decl_referenced (var);
1314 /* Mark the decl to avoid "defined but not used" warning. */
1315 TREE_USED (var) = 1;
1318 /* Find the decl for the constant string class reference. This is only
1319 used for the NeXT runtime. */
1321 static tree
1322 setup_string_decl (void)
1324 char *name;
1325 size_t length;
1327 /* %s in format will provide room for terminating null */
1328 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1329 + strlen (constant_string_class_name);
1330 name = xmalloc (length);
1331 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1332 constant_string_class_name);
1333 constant_string_global_id = get_identifier (name);
1334 string_class_decl = lookup_name (constant_string_global_id);
1336 return string_class_decl;
1339 /* Purpose: "play" parser, creating/installing representations
1340 of the declarations that are required by Objective-C.
1342 Model:
1344 type_spec--------->sc_spec
1345 (tree_list) (tree_list)
1348 identifier_node identifier_node */
1350 static void
1351 synth_module_prologue (void)
1353 tree type;
1354 enum debug_info_type save_write_symbols = write_symbols;
1355 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1357 /* Suppress outputting debug symbols, because
1358 dbxout_init hasn'r been called yet. */
1359 write_symbols = NO_DEBUG;
1360 debug_hooks = &do_nothing_debug_hooks;
1362 #ifdef OBJCPLUS
1363 push_lang_context (lang_name_c); /* extern "C" */
1364 #endif
1366 /* The following are also defined in <objc/objc.h> and friends. */
1368 objc_object_id = get_identifier (TAG_OBJECT);
1369 objc_class_id = get_identifier (TAG_CLASS);
1371 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1372 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1374 objc_object_type = build_pointer_type (objc_object_reference);
1375 objc_class_type = build_pointer_type (objc_class_reference);
1377 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1378 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1380 /* Declare the 'id' and 'Class' typedefs. */
1382 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1383 objc_object_name,
1384 objc_object_type));
1385 DECL_IN_SYSTEM_HEADER (type) = 1;
1386 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1387 objc_class_name,
1388 objc_class_type));
1389 DECL_IN_SYSTEM_HEADER (type) = 1;
1391 /* Forward-declare '@interface Protocol'. */
1393 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1394 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1395 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1396 type));
1398 /* Declare type of selector-objects that represent an operation name. */
1400 if (flag_next_runtime)
1401 /* `struct objc_selector *' */
1402 objc_selector_type
1403 = build_pointer_type (xref_tag (RECORD_TYPE,
1404 get_identifier (TAG_SELECTOR)));
1405 else
1406 /* `const struct objc_selector *' */
1407 objc_selector_type
1408 = build_pointer_type
1409 (build_qualified_type (xref_tag (RECORD_TYPE,
1410 get_identifier (TAG_SELECTOR)),
1411 TYPE_QUAL_CONST));
1413 /* Declare receiver type used for dispatching messages to 'super'. */
1415 /* `struct objc_super *' */
1416 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1417 get_identifier (TAG_SUPER)));
1419 if (flag_next_runtime)
1421 /* NB: In order to call one of the ..._stret (struct-returning)
1422 functions, the function *MUST* first be cast to a signature that
1423 corresponds to the actual ObjC method being invoked. This is
1424 what is done by the build_objc_method_call() routine below. */
1426 /* id objc_msgSend (id, SEL, ...); */
1427 /* id objc_msgSendNonNil (id, SEL, ...); */
1428 /* id objc_msgSend_stret (id, SEL, ...); */
1429 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1430 type
1431 = build_function_type (objc_object_type,
1432 tree_cons (NULL_TREE, objc_object_type,
1433 tree_cons (NULL_TREE, objc_selector_type,
1434 NULL_TREE)));
1435 umsg_decl = builtin_function (TAG_MSGSEND,
1436 type, 0, NOT_BUILT_IN,
1437 NULL, NULL_TREE);
1438 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1439 type, 0, NOT_BUILT_IN,
1440 NULL, NULL_TREE);
1441 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1442 type, 0, NOT_BUILT_IN,
1443 NULL, NULL_TREE);
1444 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1445 type, 0, NOT_BUILT_IN,
1446 NULL, NULL_TREE);
1448 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1449 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1450 type
1451 = build_function_type (objc_object_type,
1452 tree_cons (NULL_TREE, objc_super_type,
1453 tree_cons (NULL_TREE, objc_selector_type,
1454 NULL_TREE)));
1455 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1456 type, 0, NOT_BUILT_IN,
1457 NULL, NULL_TREE);
1458 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1459 type, 0, NOT_BUILT_IN, 0,
1460 NULL_TREE);
1462 else
1464 /* GNU runtime messenger entry points. */
1466 /* typedef id (*IMP)(id, SEL, ...); */
1467 tree IMP_type
1468 = build_pointer_type
1469 (build_function_type (objc_object_type,
1470 tree_cons (NULL_TREE, objc_object_type,
1471 tree_cons (NULL_TREE, objc_selector_type,
1472 NULL_TREE))));
1474 /* IMP objc_msg_lookup (id, SEL); */
1475 type
1476 = build_function_type (IMP_type,
1477 tree_cons (NULL_TREE, objc_object_type,
1478 tree_cons (NULL_TREE, objc_selector_type,
1479 OBJC_VOID_AT_END)));
1480 umsg_decl = builtin_function (TAG_MSGSEND,
1481 type, 0, NOT_BUILT_IN,
1482 NULL, NULL_TREE);
1484 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1485 type
1486 = build_function_type (IMP_type,
1487 tree_cons (NULL_TREE, objc_super_type,
1488 tree_cons (NULL_TREE, objc_selector_type,
1489 OBJC_VOID_AT_END)));
1490 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1491 type, 0, NOT_BUILT_IN,
1492 NULL, NULL_TREE);
1494 /* The following GNU runtime entry point is called to initialize
1495 each module:
1497 __objc_exec_class (void *); */
1498 type
1499 = build_function_type (void_type_node,
1500 tree_cons (NULL_TREE, ptr_type_node,
1501 OBJC_VOID_AT_END));
1502 execclass_decl = builtin_function (TAG_EXECCLASS,
1503 type, 0, NOT_BUILT_IN,
1504 NULL, NULL_TREE);
1507 /* id objc_getClass (const char *); */
1509 type = build_function_type (objc_object_type,
1510 tree_cons (NULL_TREE,
1511 const_string_type_node,
1512 OBJC_VOID_AT_END));
1514 objc_get_class_decl
1515 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1516 NULL, NULL_TREE);
1518 /* id objc_getMetaClass (const char *); */
1520 objc_get_meta_class_decl
1521 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1523 build_class_template ();
1524 build_super_template ();
1525 build_protocol_template ();
1526 build_category_template ();
1527 build_objc_exception_stuff ();
1529 if (flag_next_runtime)
1530 build_next_objc_exception_stuff ();
1532 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1534 if (! flag_next_runtime)
1535 build_selector_table_decl ();
1537 /* Forward declare constant_string_id and constant_string_type. */
1538 if (!constant_string_class_name)
1539 constant_string_class_name = default_constant_string_class_name;
1541 constant_string_id = get_identifier (constant_string_class_name);
1542 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1544 /* Pre-build the following entities - for speed/convenience. */
1545 self_id = get_identifier ("self");
1546 ucmd_id = get_identifier ("_cmd");
1547 #ifndef OBJCPLUS
1548 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1549 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1550 #endif
1552 #ifdef OBJCPLUS
1553 pop_lang_context ();
1554 #endif
1556 write_symbols = save_write_symbols;
1557 debug_hooks = save_hooks;
1560 /* Ensure that the ivar list for NSConstantString/NXConstantString
1561 (or whatever was specified via `-fconstant-string-class')
1562 contains fields at least as large as the following three, so that
1563 the runtime can stomp on them with confidence:
1565 struct STRING_OBJECT_CLASS_NAME
1567 Object isa;
1568 char *cString;
1569 unsigned int length;
1570 }; */
1572 static int
1573 check_string_class_template (void)
1575 tree field_decl = TYPE_FIELDS (constant_string_type);
1577 #define AT_LEAST_AS_LARGE_AS(F, T) \
1578 (F && TREE_CODE (F) == FIELD_DECL \
1579 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1580 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1582 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1583 return 0;
1585 field_decl = TREE_CHAIN (field_decl);
1586 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1587 return 0;
1589 field_decl = TREE_CHAIN (field_decl);
1590 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1592 #undef AT_LEAST_AS_LARGE_AS
1595 /* Avoid calling `check_string_class_template ()' more than once. */
1596 static GTY(()) int string_layout_checked;
1598 /* Custom build_string which sets TREE_TYPE! */
1600 static tree
1601 my_build_string (int len, const char *str)
1603 return fix_string_type (build_string (len, str));
1607 static hashval_t
1608 string_hash (const void *ptr)
1610 tree str = ((struct string_descriptor *)ptr)->literal;
1611 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1612 int i, len = TREE_STRING_LENGTH (str);
1613 hashval_t h = len;
1615 for (i = 0; i < len; i++)
1616 h = ((h * 613) + p[i]);
1618 return h;
1621 static int
1622 string_eq (const void *ptr1, const void *ptr2)
1624 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1625 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1626 int len1 = TREE_STRING_LENGTH (str1);
1628 return (len1 == TREE_STRING_LENGTH (str2)
1629 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1630 len1));
1633 /* Given a chain of STRING_CST's, build a static instance of
1634 NXConstantString which points at the concatenation of those
1635 strings. We place the string object in the __string_objects
1636 section of the __OBJC segment. The Objective-C runtime will
1637 initialize the isa pointers of the string objects to point at the
1638 NXConstantString class object. */
1640 tree
1641 objc_build_string_object (tree string)
1643 tree initlist, constructor, constant_string_class;
1644 int length;
1645 tree fields, addr;
1646 struct string_descriptor *desc, key;
1647 void **loc;
1649 /* Prep the string argument. */
1650 string = fix_string_type (string);
1651 TREE_SET_CODE (string, STRING_CST);
1652 length = TREE_STRING_LENGTH (string) - 1;
1654 /* Check whether the string class being used actually exists and has the
1655 correct ivar layout. */
1656 if (!string_layout_checked)
1658 string_layout_checked = -1;
1659 constant_string_class = lookup_interface (constant_string_id);
1661 if (!constant_string_class
1662 || !(constant_string_type
1663 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1664 error ("cannot find interface declaration for %qs",
1665 IDENTIFIER_POINTER (constant_string_id));
1666 /* The NSConstantString/NXConstantString ivar layout is now known. */
1667 else if (!check_string_class_template ())
1668 error ("interface %qs does not have valid constant string layout",
1669 IDENTIFIER_POINTER (constant_string_id));
1670 /* For the NeXT runtime, we can generate a literal reference
1671 to the string class, don't need to run a constructor. */
1672 else if (flag_next_runtime && !setup_string_decl ())
1673 error ("cannot find reference tag for class %qs",
1674 IDENTIFIER_POINTER (constant_string_id));
1675 else
1677 string_layout_checked = 1; /* Success! */
1678 add_class_reference (constant_string_id);
1682 if (string_layout_checked == -1)
1683 return error_mark_node;
1685 /* Perhaps we already constructed a constant string just like this one? */
1686 key.literal = string;
1687 loc = htab_find_slot (string_htab, &key, INSERT);
1688 desc = *loc;
1690 if (!desc)
1692 tree var;
1693 *loc = desc = ggc_alloc (sizeof (*desc));
1694 desc->literal = string;
1696 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1697 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1698 fields = TYPE_FIELDS (constant_string_type);
1699 initlist
1700 = build_tree_list (fields,
1701 flag_next_runtime
1702 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1703 : build_int_cst (NULL_TREE, 0));
1704 fields = TREE_CHAIN (fields);
1705 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1706 initlist);
1707 fields = TREE_CHAIN (fields);
1708 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1709 initlist);
1710 constructor = objc_build_constructor (constant_string_type,
1711 nreverse (initlist));
1712 TREE_INVARIANT (constructor) = true;
1714 if (!flag_next_runtime)
1715 constructor
1716 = objc_add_static_instance (constructor, constant_string_type);
1717 else
1719 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1720 DECL_INITIAL (var) = constructor;
1721 TREE_STATIC (var) = 1;
1722 pushdecl_top_level (var);
1723 constructor = var;
1725 desc->constructor = constructor;
1728 addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
1730 return addr;
1733 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1735 static GTY(()) int num_static_inst;
1737 static tree
1738 objc_add_static_instance (tree constructor, tree class_decl)
1740 tree *chain, decl;
1741 char buf[256];
1743 /* Find the list of static instances for the CLASS_DECL. Create one if
1744 not found. */
1745 for (chain = &objc_static_instances;
1746 *chain && TREE_VALUE (*chain) != class_decl;
1747 chain = &TREE_CHAIN (*chain));
1748 if (!*chain)
1750 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1751 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1754 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1755 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1756 DECL_COMMON (decl) = 1;
1757 TREE_STATIC (decl) = 1;
1758 DECL_ARTIFICIAL (decl) = 1;
1759 DECL_INITIAL (decl) = constructor;
1761 /* We may be writing something else just now.
1762 Postpone till end of input. */
1763 DECL_DEFER_OUTPUT (decl) = 1;
1764 pushdecl_top_level (decl);
1765 rest_of_decl_compilation (decl, 1, 0);
1767 /* Add the DECL to the head of this CLASS' list. */
1768 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1770 return decl;
1773 /* Build a static constant CONSTRUCTOR
1774 with type TYPE and elements ELTS. */
1776 static tree
1777 objc_build_constructor (tree type, tree elts)
1779 tree constructor = build_constructor (type, elts);
1781 TREE_CONSTANT (constructor) = 1;
1782 TREE_STATIC (constructor) = 1;
1783 TREE_READONLY (constructor) = 1;
1785 #ifdef OBJCPLUS
1786 /* Adjust for impedance mismatch. We should figure out how to build
1787 CONSTRUCTORs that consistently please both the C and C++ gods. */
1788 if (!TREE_PURPOSE (elts))
1789 TREE_TYPE (constructor) = NULL_TREE;
1790 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1791 #endif
1793 return constructor;
1796 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1798 /* Predefine the following data type:
1800 struct _objc_symtab
1802 long sel_ref_cnt;
1803 SEL *refs;
1804 short cls_def_cnt;
1805 short cat_def_cnt;
1806 void *defs[cls_def_cnt + cat_def_cnt];
1807 }; */
1809 static void
1810 build_objc_symtab_template (void)
1812 tree field_decl, field_decl_chain;
1814 objc_symtab_template
1815 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1817 /* long sel_ref_cnt; */
1818 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
1819 field_decl_chain = field_decl;
1821 /* SEL *refs; */
1822 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
1823 "refs");
1824 chainon (field_decl_chain, field_decl);
1826 /* short cls_def_cnt; */
1827 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
1828 chainon (field_decl_chain, field_decl);
1830 /* short cat_def_cnt; */
1831 field_decl = create_field_decl (short_integer_type_node,
1832 "cat_def_cnt");
1833 chainon (field_decl_chain, field_decl);
1835 if (imp_count || cat_count || !flag_next_runtime)
1837 /* void *defs[imp_count + cat_count (+ 1)]; */
1838 /* NB: The index is one less than the size of the array. */
1839 int index = imp_count + cat_count
1840 + (flag_next_runtime? -1: 0);
1841 field_decl = create_field_decl
1842 (build_array_type
1843 (ptr_type_node,
1844 build_index_type (build_int_cst (NULL_TREE, index))),
1845 "defs");
1846 chainon (field_decl_chain, field_decl);
1849 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1852 /* Create the initial value for the `defs' field of _objc_symtab.
1853 This is a CONSTRUCTOR. */
1855 static tree
1856 init_def_list (tree type)
1858 tree expr, initlist = NULL_TREE;
1859 struct imp_entry *impent;
1861 if (imp_count)
1862 for (impent = imp_list; impent; impent = impent->next)
1864 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1866 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1867 initlist = tree_cons (NULL_TREE, expr, initlist);
1871 if (cat_count)
1872 for (impent = imp_list; impent; impent = impent->next)
1874 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1876 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1877 initlist = tree_cons (NULL_TREE, expr, initlist);
1881 if (!flag_next_runtime)
1883 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1884 tree expr;
1886 if (static_instances_decl)
1887 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1888 else
1889 expr = build_int_cst (NULL_TREE, 0);
1891 initlist = tree_cons (NULL_TREE, expr, initlist);
1894 return objc_build_constructor (type, nreverse (initlist));
1897 /* Construct the initial value for all of _objc_symtab. */
1899 static tree
1900 init_objc_symtab (tree type)
1902 tree initlist;
1904 /* sel_ref_cnt = { ..., 5, ... } */
1906 initlist = build_tree_list (NULL_TREE,
1907 build_int_cst (long_integer_type_node, 0));
1909 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1911 if (flag_next_runtime || ! sel_ref_chain)
1912 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
1913 else
1914 initlist
1915 = tree_cons (NULL_TREE,
1916 convert (build_pointer_type (objc_selector_type),
1917 build_unary_op (ADDR_EXPR,
1918 UOBJC_SELECTOR_TABLE_decl, 1)),
1919 initlist);
1921 /* cls_def_cnt = { ..., 5, ... } */
1923 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
1925 /* cat_def_cnt = { ..., 5, ... } */
1927 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
1929 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1931 if (imp_count || cat_count || !flag_next_runtime)
1934 tree field = TYPE_FIELDS (type);
1935 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1937 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1938 initlist);
1941 return objc_build_constructor (type, nreverse (initlist));
1944 /* Generate forward declarations for metadata such as
1945 'OBJC_CLASS_...'. */
1947 static tree
1948 build_metadata_decl (const char *name, tree type)
1950 tree decl;
1952 /* struct TYPE NAME_<name>; */
1953 decl = start_var_decl (type, synth_id_with_class_suffix
1954 (name,
1955 objc_implementation_context));
1957 return decl;
1960 /* Push forward-declarations of all the categories so that
1961 init_def_list can use them in a CONSTRUCTOR. */
1963 static void
1964 forward_declare_categories (void)
1966 struct imp_entry *impent;
1967 tree sav = objc_implementation_context;
1969 for (impent = imp_list; impent; impent = impent->next)
1971 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1973 /* Set an invisible arg to synth_id_with_class_suffix. */
1974 objc_implementation_context = impent->imp_context;
1975 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1976 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1977 objc_category_template);
1980 objc_implementation_context = sav;
1983 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1984 and initialized appropriately. */
1986 static void
1987 generate_objc_symtab_decl (void)
1989 /* forward declare categories */
1990 if (cat_count)
1991 forward_declare_categories ();
1993 build_objc_symtab_template ();
1994 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
1995 finish_var_decl (UOBJC_SYMBOLS_decl,
1996 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
1999 static tree
2000 init_module_descriptor (tree type)
2002 tree initlist, expr;
2004 /* version = { 1, ... } */
2006 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2007 initlist = build_tree_list (NULL_TREE, expr);
2009 /* size = { ..., sizeof (struct _objc_module), ... } */
2011 expr = convert (long_integer_type_node,
2012 size_in_bytes (objc_module_template));
2013 initlist = tree_cons (NULL_TREE, expr, initlist);
2015 /* name = { ..., "foo.m", ... } */
2017 expr = add_objc_string (get_identifier (input_filename), class_names);
2018 initlist = tree_cons (NULL_TREE, expr, initlist);
2020 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2022 if (UOBJC_SYMBOLS_decl)
2023 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2024 else
2025 expr = build_int_cst (NULL_TREE, 0);
2026 initlist = tree_cons (NULL_TREE, expr, initlist);
2028 return objc_build_constructor (type, nreverse (initlist));
2031 /* Write out the data structures to describe Objective C classes defined.
2033 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2035 static void
2036 build_module_descriptor (void)
2038 tree field_decl, field_decl_chain;
2040 #ifdef OBJCPLUS
2041 push_lang_context (lang_name_c); /* extern "C" */
2042 #endif
2044 objc_module_template
2045 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2047 /* long version; */
2048 field_decl = create_field_decl (long_integer_type_node, "version");
2049 field_decl_chain = field_decl;
2051 /* long size; */
2052 field_decl = create_field_decl (long_integer_type_node, "size");
2053 chainon (field_decl_chain, field_decl);
2055 /* char *name; */
2056 field_decl = create_field_decl (string_type_node, "name");
2057 chainon (field_decl_chain, field_decl);
2059 /* struct _objc_symtab *symtab; */
2060 field_decl
2061 = create_field_decl (build_pointer_type
2062 (xref_tag (RECORD_TYPE,
2063 get_identifier (UTAG_SYMTAB))),
2064 "symtab");
2065 chainon (field_decl_chain, field_decl);
2067 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2069 /* Create an instance of "_objc_module". */
2070 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2071 finish_var_decl (UOBJC_MODULES_decl,
2072 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2074 #ifdef OBJCPLUS
2075 pop_lang_context ();
2076 #endif
2079 /* The GNU runtime requires us to provide a static initializer function
2080 for each module:
2082 static void __objc_gnu_init (void) {
2083 __objc_exec_class (&L_OBJC_MODULES);
2084 } */
2086 static void
2087 build_module_initializer_routine (void)
2089 tree body;
2091 #ifdef OBJCPLUS
2092 push_lang_context (lang_name_c); /* extern "C" */
2093 #endif
2095 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2096 objc_start_function (get_identifier (TAG_GNUINIT),
2097 build_function_type (void_type_node,
2098 OBJC_VOID_AT_END),
2099 NULL_TREE, objc_get_parm_info (0));
2101 body = c_begin_compound_stmt (true);
2102 add_stmt (build_function_call
2103 (execclass_decl,
2104 build_tree_list
2105 (NULL_TREE,
2106 build_unary_op (ADDR_EXPR,
2107 UOBJC_MODULES_decl, 0))));
2108 add_stmt (c_end_compound_stmt (body, true));
2110 TREE_PUBLIC (current_function_decl) = 0;
2112 #ifndef OBJCPLUS
2113 /* For Objective-C++, we will need to call __objc_gnu_init
2114 from objc_generate_static_init_call() below. */
2115 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2116 #endif
2118 GNU_INIT_decl = current_function_decl;
2119 finish_function ();
2121 #ifdef OBJCPLUS
2122 pop_lang_context ();
2123 #endif
2126 #ifdef OBJCPLUS
2127 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2128 to be called by the module initializer routine. */
2131 objc_static_init_needed_p (void)
2133 return (GNU_INIT_decl != NULL_TREE);
2136 /* Generate a call to the __objc_gnu_init initializer function. */
2138 tree
2139 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2141 add_stmt (build_stmt (EXPR_STMT,
2142 build_function_call (GNU_INIT_decl, NULL_TREE)));
2144 return ctors;
2146 #endif /* OBJCPLUS */
2148 /* Return the DECL of the string IDENT in the SECTION. */
2150 static tree
2151 get_objc_string_decl (tree ident, enum string_section section)
2153 tree chain;
2155 if (section == class_names)
2156 chain = class_names_chain;
2157 else if (section == meth_var_names)
2158 chain = meth_var_names_chain;
2159 else if (section == meth_var_types)
2160 chain = meth_var_types_chain;
2161 else
2162 abort ();
2164 for (; chain != 0; chain = TREE_CHAIN (chain))
2165 if (TREE_VALUE (chain) == ident)
2166 return (TREE_PURPOSE (chain));
2168 abort ();
2169 return NULL_TREE;
2172 /* Output references to all statically allocated objects. Return the DECL
2173 for the array built. */
2175 static void
2176 generate_static_references (void)
2178 tree decls = NULL_TREE, expr = NULL_TREE;
2179 tree class_name, class, decl, initlist;
2180 tree cl_chain, in_chain, type
2181 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2182 int num_inst, num_class;
2183 char buf[256];
2185 if (flag_next_runtime)
2186 abort ();
2188 for (cl_chain = objc_static_instances, num_class = 0;
2189 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2191 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2192 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2194 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2195 decl = start_var_decl (type, buf);
2197 /* Output {class_name, ...}. */
2198 class = TREE_VALUE (cl_chain);
2199 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2200 initlist = build_tree_list (NULL_TREE,
2201 build_unary_op (ADDR_EXPR, class_name, 1));
2203 /* Output {..., instance, ...}. */
2204 for (in_chain = TREE_PURPOSE (cl_chain);
2205 in_chain; in_chain = TREE_CHAIN (in_chain))
2207 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2208 initlist = tree_cons (NULL_TREE, expr, initlist);
2211 /* Output {..., NULL}. */
2212 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2214 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2215 finish_var_decl (decl, expr);
2216 decls
2217 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2220 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2221 expr = objc_build_constructor (type, nreverse (decls));
2222 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2223 finish_var_decl (static_instances_decl, expr);
2226 /* Output all strings. */
2228 static void
2229 generate_strings (void)
2231 tree chain, string_expr;
2232 tree string, decl, type;
2234 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2236 string = TREE_VALUE (chain);
2237 decl = TREE_PURPOSE (chain);
2238 type = build_array_type
2239 (char_type_node,
2240 build_index_type
2241 (build_int_cst (NULL_TREE,
2242 IDENTIFIER_LENGTH (string))));
2243 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2244 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2245 IDENTIFIER_POINTER (string));
2246 finish_var_decl (decl, string_expr);
2249 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2251 string = TREE_VALUE (chain);
2252 decl = TREE_PURPOSE (chain);
2253 type = build_array_type
2254 (char_type_node,
2255 build_index_type
2256 (build_int_cst (NULL_TREE,
2257 IDENTIFIER_LENGTH (string))));
2258 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2259 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2260 IDENTIFIER_POINTER (string));
2261 finish_var_decl (decl, string_expr);
2264 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2266 string = TREE_VALUE (chain);
2267 decl = TREE_PURPOSE (chain);
2268 type = build_array_type
2269 (char_type_node,
2270 build_index_type
2271 (build_int_cst (NULL_TREE,
2272 IDENTIFIER_LENGTH (string))));
2273 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2274 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2275 IDENTIFIER_POINTER (string));
2276 finish_var_decl (decl, string_expr);
2280 static GTY(()) int selector_reference_idx;
2282 static tree
2283 build_selector_reference_decl (void)
2285 tree decl;
2286 char buf[256];
2288 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2289 decl = start_var_decl (objc_selector_type, buf);
2291 return decl;
2294 static void
2295 build_selector_table_decl (void)
2297 tree temp;
2299 if (flag_typed_selectors)
2301 build_selector_template ();
2302 temp = build_array_type (objc_selector_template, NULL_TREE);
2304 else
2305 temp = build_array_type (objc_selector_type, NULL_TREE);
2307 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2310 /* Just a handy wrapper for add_objc_string. */
2312 static tree
2313 build_selector (tree ident)
2315 return convert (objc_selector_type,
2316 add_objc_string (ident, meth_var_names));
2319 static void
2320 build_selector_translation_table (void)
2322 tree chain, initlist = NULL_TREE;
2323 int offset = 0;
2324 tree decl = NULL_TREE;
2326 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2328 tree expr;
2330 if (warn_selector && objc_implementation_context)
2332 tree method_chain;
2333 bool found = false;
2334 for (method_chain = meth_var_names_chain;
2335 method_chain;
2336 method_chain = TREE_CHAIN (method_chain))
2338 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2340 found = true;
2341 break;
2344 if (!found)
2345 warning ("%Jcreating selector for nonexistent method %qE",
2346 TREE_PURPOSE (chain), TREE_VALUE (chain));
2349 expr = build_selector (TREE_VALUE (chain));
2350 /* add one for the '\0' character */
2351 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2353 if (flag_next_runtime)
2355 decl = TREE_PURPOSE (chain);
2356 finish_var_decl (decl, expr);
2358 else
2360 if (flag_typed_selectors)
2362 tree eltlist = NULL_TREE;
2363 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2364 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2365 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2366 expr = objc_build_constructor (objc_selector_template,
2367 nreverse (eltlist));
2370 initlist = tree_cons (NULL_TREE, expr, initlist);
2374 if (! flag_next_runtime)
2376 /* Cause the selector table (previously forward-declared)
2377 to be actually output. */
2378 initlist = tree_cons (NULL_TREE,
2379 flag_typed_selectors
2380 ? objc_build_constructor
2381 (objc_selector_template,
2382 tree_cons (NULL_TREE,
2383 build_int_cst (NULL_TREE, 0),
2384 tree_cons (NULL_TREE,
2385 build_int_cst (NULL_TREE, 0),
2386 NULL_TREE)))
2387 : build_int_cst (NULL_TREE, 0), initlist);
2388 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2389 nreverse (initlist));
2390 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2394 static tree
2395 get_proto_encoding (tree proto)
2397 tree encoding;
2398 if (proto)
2400 if (! METHOD_ENCODING (proto))
2402 encoding = encode_method_prototype (proto);
2403 METHOD_ENCODING (proto) = encoding;
2405 else
2406 encoding = METHOD_ENCODING (proto);
2408 return add_objc_string (encoding, meth_var_types);
2410 else
2411 return build_int_cst (NULL_TREE, 0);
2414 /* sel_ref_chain is a list whose "value" fields will be instances of
2415 identifier_node that represent the selector. */
2417 static tree
2418 build_typed_selector_reference (tree ident, tree prototype)
2420 tree *chain = &sel_ref_chain;
2421 tree expr;
2422 int index = 0;
2424 while (*chain)
2426 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2427 goto return_at_index;
2429 index++;
2430 chain = &TREE_CHAIN (*chain);
2433 *chain = tree_cons (prototype, ident, NULL_TREE);
2435 return_at_index:
2436 expr = build_unary_op (ADDR_EXPR,
2437 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2438 build_int_cst (NULL_TREE, index)),
2440 return convert (objc_selector_type, expr);
2443 static tree
2444 build_selector_reference (tree ident)
2446 tree *chain = &sel_ref_chain;
2447 tree expr;
2448 int index = 0;
2450 while (*chain)
2452 if (TREE_VALUE (*chain) == ident)
2453 return (flag_next_runtime
2454 ? TREE_PURPOSE (*chain)
2455 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2456 build_int_cst (NULL_TREE, index)));
2458 index++;
2459 chain = &TREE_CHAIN (*chain);
2462 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2464 *chain = tree_cons (expr, ident, NULL_TREE);
2466 return (flag_next_runtime
2467 ? expr
2468 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2469 build_int_cst (NULL_TREE, index)));
2472 static GTY(()) int class_reference_idx;
2474 static tree
2475 build_class_reference_decl (void)
2477 tree decl;
2478 char buf[256];
2480 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2481 decl = start_var_decl (objc_class_type, buf);
2483 return decl;
2486 /* Create a class reference, but don't create a variable to reference
2487 it. */
2489 static void
2490 add_class_reference (tree ident)
2492 tree chain;
2494 if ((chain = cls_ref_chain))
2496 tree tail;
2499 if (ident == TREE_VALUE (chain))
2500 return;
2502 tail = chain;
2503 chain = TREE_CHAIN (chain);
2505 while (chain);
2507 /* Append to the end of the list */
2508 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2510 else
2511 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2514 /* Get a class reference, creating it if necessary. Also create the
2515 reference variable. */
2517 tree
2518 objc_get_class_reference (tree ident)
2520 tree orig_ident;
2522 #ifdef OBJCPLUS
2523 if (processing_template_decl)
2524 /* Must wait until template instantiation time. */
2525 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2526 if (TREE_CODE (ident) == TYPE_DECL)
2527 ident = DECL_NAME (ident);
2528 #endif
2529 orig_ident = ident;
2531 if (!(ident = objc_is_class_name (ident)))
2533 error ("%qs is not an Objective-C class name or alias",
2534 IDENTIFIER_POINTER (orig_ident));
2535 return error_mark_node;
2538 if (flag_next_runtime && !flag_zero_link)
2540 tree *chain;
2541 tree decl;
2543 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2544 if (TREE_VALUE (*chain) == ident)
2546 if (! TREE_PURPOSE (*chain))
2547 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2549 return TREE_PURPOSE (*chain);
2552 decl = build_class_reference_decl ();
2553 *chain = tree_cons (decl, ident, NULL_TREE);
2554 return decl;
2556 else
2558 tree params;
2560 add_class_reference (ident);
2562 params = build_tree_list (NULL_TREE,
2563 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2564 IDENTIFIER_POINTER (ident)));
2566 assemble_external (objc_get_class_decl);
2567 return build_function_call (objc_get_class_decl, params);
2571 /* For each string section we have a chain which maps identifier nodes
2572 to decls for the strings. */
2574 static tree
2575 add_objc_string (tree ident, enum string_section section)
2577 tree *chain, decl;
2579 if (section == class_names)
2580 chain = &class_names_chain;
2581 else if (section == meth_var_names)
2582 chain = &meth_var_names_chain;
2583 else if (section == meth_var_types)
2584 chain = &meth_var_types_chain;
2585 else
2586 abort ();
2588 while (*chain)
2590 if (TREE_VALUE (*chain) == ident)
2591 return convert (string_type_node,
2592 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2594 chain = &TREE_CHAIN (*chain);
2597 decl = build_objc_string_decl (section);
2599 *chain = tree_cons (decl, ident, NULL_TREE);
2601 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2604 static GTY(()) int class_names_idx;
2605 static GTY(()) int meth_var_names_idx;
2606 static GTY(()) int meth_var_types_idx;
2608 static tree
2609 build_objc_string_decl (enum string_section section)
2611 tree decl, ident;
2612 char buf[256];
2614 if (section == class_names)
2615 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2616 else if (section == meth_var_names)
2617 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2618 else if (section == meth_var_types)
2619 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2621 ident = get_identifier (buf);
2623 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2624 DECL_EXTERNAL (decl) = 1;
2625 TREE_PUBLIC (decl) = 0;
2626 TREE_USED (decl) = 1;
2627 TREE_CONSTANT (decl) = 1;
2628 DECL_CONTEXT (decl) = 0;
2629 DECL_ARTIFICIAL (decl) = 1;
2630 #ifdef OBJCPLUS
2631 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2632 #endif
2634 make_decl_rtl (decl);
2635 pushdecl_top_level (decl);
2637 return decl;
2641 void
2642 objc_declare_alias (tree alias_ident, tree class_ident)
2644 tree underlying_class;
2646 #ifdef OBJCPLUS
2647 if (current_namespace != global_namespace) {
2648 error ("Objective-C declarations may only appear in global scope");
2650 #endif /* OBJCPLUS */
2652 if (!(underlying_class = objc_is_class_name (class_ident)))
2653 warning ("cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2654 else if (objc_is_class_name (alias_ident))
2655 warning ("class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2656 else
2657 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2660 void
2661 objc_declare_class (tree ident_list)
2663 tree list;
2664 #ifdef OBJCPLUS
2665 if (current_namespace != global_namespace) {
2666 error ("Objective-C declarations may only appear in global scope");
2668 #endif /* OBJCPLUS */
2670 for (list = ident_list; list; list = TREE_CHAIN (list))
2672 tree ident = TREE_VALUE (list);
2674 if (! objc_is_class_name (ident))
2676 tree record = lookup_name (ident), type = record;
2678 if (record)
2680 if (TREE_CODE (record) == TYPE_DECL)
2681 type = DECL_ORIGINAL_TYPE (record);
2683 if (!TYPE_HAS_OBJC_INFO (type)
2684 || !TYPE_OBJC_INTERFACE (type))
2686 error ("%qs redeclared as different kind of symbol",
2687 IDENTIFIER_POINTER (ident));
2688 error ("%Jprevious declaration of '%D'",
2689 record, record);
2693 record = xref_tag (RECORD_TYPE, ident);
2694 INIT_TYPE_OBJC_INFO (record);
2695 TYPE_OBJC_INTERFACE (record) = ident;
2696 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2701 tree
2702 objc_is_class_name (tree ident)
2704 tree chain;
2706 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2707 && identifier_global_value (ident))
2708 ident = identifier_global_value (ident);
2709 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2710 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2712 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2713 ident = OBJC_TYPE_NAME (ident);
2714 #ifdef OBJCPLUS
2715 if (ident && TREE_CODE (ident) == TYPE_DECL)
2716 ident = DECL_NAME (ident);
2717 #endif
2718 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2719 return NULL_TREE;
2721 if (lookup_interface (ident))
2722 return ident;
2724 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2726 if (ident == TREE_VALUE (chain))
2727 return ident;
2730 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2732 if (ident == TREE_VALUE (chain))
2733 return TREE_PURPOSE (chain);
2736 return 0;
2739 /* Check whether TYPE is either 'id' or 'Class'. */
2741 tree
2742 objc_is_id (tree type)
2744 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2745 && identifier_global_value (type))
2746 type = identifier_global_value (type);
2748 if (type && TREE_CODE (type) == TYPE_DECL)
2749 type = TREE_TYPE (type);
2751 /* NB: This function may be called before the ObjC front-end has
2752 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2753 return (objc_object_type && type
2754 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2755 ? type
2756 : NULL_TREE);
2759 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2760 class instance. This is needed by other parts of the compiler to
2761 handle ObjC types gracefully. */
2763 tree
2764 objc_is_object_ptr (tree type)
2766 tree ret;
2768 type = TYPE_MAIN_VARIANT (type);
2769 if (!POINTER_TYPE_P (type))
2770 return 0;
2772 ret = objc_is_id (type);
2773 if (!ret)
2774 ret = objc_is_class_name (TREE_TYPE (type));
2776 return ret;
2779 static tree
2780 lookup_interface (tree ident)
2782 tree chain;
2784 #ifdef OBJCPLUS
2785 if (ident && TREE_CODE (ident) == TYPE_DECL)
2786 ident = DECL_NAME (ident);
2787 #endif
2788 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2790 if (ident == CLASS_NAME (chain))
2791 return chain;
2793 return NULL_TREE;
2796 /* Implement @defs (<classname>) within struct bodies. */
2798 tree
2799 objc_get_class_ivars (tree class_name)
2801 tree interface = lookup_interface (class_name);
2803 if (interface)
2804 return get_class_ivars (interface);
2806 error ("cannot find interface declaration for %qs",
2807 IDENTIFIER_POINTER (class_name));
2809 return error_mark_node;
2812 /* Used by: build_private_template, continue_class,
2813 and for @defs constructs. */
2815 static tree
2816 get_class_ivars (tree interface)
2818 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
2820 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
2821 by the current class (i.e., they do not include super-class ivars).
2822 However, the CLASS_IVARS list will be side-effected by a call to
2823 finish_struct(), which will fill in field offsets. */
2824 if (!CLASS_IVARS (interface))
2825 CLASS_IVARS (interface) = ivar_chain;
2827 while (CLASS_SUPER_NAME (interface))
2829 /* Prepend super-class ivars. */
2830 interface = lookup_interface (CLASS_SUPER_NAME (interface));
2831 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
2832 ivar_chain);
2835 return ivar_chain;
2838 static tree
2839 objc_create_temporary_var (tree type)
2841 tree decl;
2843 decl = build_decl (VAR_DECL, NULL_TREE, type);
2844 TREE_USED (decl) = 1;
2845 DECL_ARTIFICIAL (decl) = 1;
2846 DECL_IGNORED_P (decl) = 1;
2847 DECL_CONTEXT (decl) = current_function_decl;
2849 return decl;
2852 /* Exception handling constructs. We begin by having the parser do most
2853 of the work and passing us blocks. What we do next depends on whether
2854 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2855 We abstract all of this in a handful of appropriately named routines. */
2857 /* Stack of open try blocks. */
2859 struct objc_try_context
2861 struct objc_try_context *outer;
2863 /* Statements (or statement lists) as processed by the parser. */
2864 tree try_body;
2865 tree finally_body;
2867 /* Some file position locations. */
2868 location_t try_locus;
2869 location_t end_try_locus;
2870 location_t end_catch_locus;
2871 location_t finally_locus;
2872 location_t end_finally_locus;
2874 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2875 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2876 tree catch_list;
2878 /* The CATCH_EXPR of an open @catch clause. */
2879 tree current_catch;
2881 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2882 tree caught_decl;
2883 tree stack_decl;
2884 tree rethrow_decl;
2887 static struct objc_try_context *cur_try_context;
2889 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2890 that represents TYPE. For Objective-C, this is just the class name. */
2891 /* ??? Isn't there a class object or some such? Is it easy to get? */
2893 #ifndef OBJCPLUS
2894 static tree
2895 objc_eh_runtime_type (tree type)
2897 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
2899 #endif
2901 /* Initialize exception handling. */
2903 static void
2904 objc_init_exceptions (void)
2906 static bool done = false;
2907 if (done)
2908 return;
2909 done = true;
2911 if (flag_objc_sjlj_exceptions)
2913 /* On Darwin, ObjC exceptions require a sufficiently recent
2914 version of the runtime, so the user must ask for them explicitly. */
2915 if (!flag_objc_exceptions)
2916 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2917 "exception syntax");
2919 #ifndef OBJCPLUS
2920 else
2922 c_eh_initialized_p = true;
2923 eh_personality_libfunc
2924 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2925 ? "__gnu_objc_personality_sj0"
2926 : "__gnu_objc_personality_v0");
2927 using_eh_for_cleanups ();
2928 lang_eh_runtime_type = objc_eh_runtime_type;
2930 #endif
2933 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2934 we'll arrange for it to be initialized (and associated with a binding)
2935 later. */
2937 static tree
2938 objc_build_exc_ptr (void)
2940 if (flag_objc_sjlj_exceptions)
2942 tree var = cur_try_context->caught_decl;
2943 if (!var)
2945 var = objc_create_temporary_var (objc_object_type);
2946 cur_try_context->caught_decl = var;
2948 return var;
2950 else
2951 return build (EXC_PTR_EXPR, objc_object_type);
2954 /* Build "objc_exception_try_exit(&_stack)". */
2956 static tree
2957 next_sjlj_build_try_exit (void)
2959 tree t;
2960 t = build_fold_addr_expr (cur_try_context->stack_decl);
2961 t = tree_cons (NULL, t, NULL);
2962 t = build_function_call (objc_exception_try_exit_decl, t);
2963 return t;
2966 /* Build
2967 objc_exception_try_enter (&_stack);
2968 if (_setjmp(&_stack.buf))
2970 else
2972 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2973 empty, ready for the caller to fill them in. */
2975 static tree
2976 next_sjlj_build_enter_and_setjmp (void)
2978 tree t, enter, sj, cond;
2980 t = build_fold_addr_expr (cur_try_context->stack_decl);
2981 t = tree_cons (NULL, t, NULL);
2982 enter = build_function_call (objc_exception_try_enter_decl, t);
2984 t = build_component_ref (cur_try_context->stack_decl,
2985 get_identifier ("buf"));
2986 t = build_fold_addr_expr (t);
2987 t = convert (ptr_type_node, t);
2988 t = tree_cons (NULL, t, NULL);
2989 sj = build_function_call (objc_setjmp_decl, t);
2991 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
2992 cond = lang_hooks.truthvalue_conversion (cond);
2994 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
2997 /* Build
2998 DECL = objc_exception_extract(&_stack);
3001 static tree
3002 next_sjlj_build_exc_extract (tree decl)
3004 tree t;
3006 t = build_fold_addr_expr (cur_try_context->stack_decl);
3007 t = tree_cons (NULL, t, NULL);
3008 t = build_function_call (objc_exception_extract_decl, t);
3009 t = convert (TREE_TYPE (decl), t);
3010 t = build (MODIFY_EXPR, void_type_node, decl, t);
3012 return t;
3015 /* Build
3016 if (objc_exception_match(obj_get_class(TYPE), _caught)
3017 BODY
3018 else if (...)
3020 else
3022 _rethrow = _caught;
3023 objc_exception_try_exit(&_stack);
3025 from the sequence of CATCH_EXPRs in the current try context. */
3027 static tree
3028 next_sjlj_build_catch_list (void)
3030 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3031 tree catch_seq, t;
3032 tree *last = &catch_seq;
3033 bool saw_id = false;
3035 for (; !tsi_end_p (i); tsi_next (&i))
3037 tree stmt = tsi_stmt (i);
3038 tree type = CATCH_TYPES (stmt);
3039 tree body = CATCH_BODY (stmt);
3041 if (type == NULL)
3043 *last = body;
3044 saw_id = true;
3045 break;
3047 else
3049 tree args, cond;
3051 if (type == error_mark_node)
3052 cond = error_mark_node;
3053 else
3055 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3056 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3057 args = tree_cons (NULL, t, args);
3058 t = build_function_call (objc_exception_match_decl, args);
3059 cond = lang_hooks.truthvalue_conversion (t);
3061 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3062 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3064 *last = t;
3065 last = &COND_EXPR_ELSE (t);
3069 if (!saw_id)
3071 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3072 cur_try_context->caught_decl);
3073 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3074 append_to_statement_list (t, last);
3076 t = next_sjlj_build_try_exit ();
3077 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3078 append_to_statement_list (t, last);
3081 return catch_seq;
3084 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3085 exception handling. We aim to build:
3088 struct _objc_exception_data _stack;
3089 id volatile _rethrow = 0;
3092 objc_exception_try_enter (&_stack);
3093 if (_setjmp(&_stack.buf))
3095 id _caught = objc_exception_extract(&_stack);
3096 objc_exception_try_enter (&_stack);
3097 if (_setjmp(&_stack.buf))
3098 _rethrow = objc_exception_extract(&_stack);
3099 else
3100 CATCH-LIST
3102 else
3103 TRY-BLOCK
3105 finally
3107 if (!_rethrow)
3108 objc_exception_try_exit(&_stack);
3109 FINALLY-BLOCK
3110 if (_rethrow)
3111 objc_exception_throw(_rethrow);
3115 If CATCH-LIST is empty, we can omit all of the block containing
3116 "_caught" except for the setting of _rethrow. Note the use of
3117 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3118 but handles goto and other exits from the block. */
3120 static tree
3121 next_sjlj_build_try_catch_finally (void)
3123 tree rethrow_decl, stack_decl, t;
3124 tree catch_seq, try_fin, bind;
3126 /* Create the declarations involved. */
3127 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3128 stack_decl = objc_create_temporary_var (t);
3129 cur_try_context->stack_decl = stack_decl;
3131 rethrow_decl = objc_create_temporary_var (objc_object_type);
3132 cur_try_context->rethrow_decl = rethrow_decl;
3133 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3134 TREE_CHAIN (rethrow_decl) = stack_decl;
3136 /* Build the outermost variable binding level. */
3137 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3138 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3139 TREE_SIDE_EFFECTS (bind) = 1;
3141 /* Initialize rethrow_decl. */
3142 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
3143 convert (objc_object_type, null_pointer_node));
3144 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3145 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3147 /* Build the outermost TRY_FINALLY_EXPR. */
3148 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3149 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3150 TREE_SIDE_EFFECTS (try_fin) = 1;
3151 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3153 /* Create the complete catch sequence. */
3154 if (cur_try_context->catch_list)
3156 tree caught_decl = objc_build_exc_ptr ();
3157 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3159 t = next_sjlj_build_exc_extract (caught_decl);
3160 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3162 t = next_sjlj_build_enter_and_setjmp ();
3163 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3164 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3165 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3167 else
3168 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3169 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3171 /* Build the main register-and-try if statement. */
3172 t = next_sjlj_build_enter_and_setjmp ();
3173 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3174 COND_EXPR_THEN (t) = catch_seq;
3175 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3176 TREE_OPERAND (try_fin, 0) = t;
3178 /* Build the complete FINALLY statement list. */
3179 t = next_sjlj_build_try_exit ();
3180 t = build_stmt (COND_EXPR,
3181 lang_hooks.truthvalue_conversion (rethrow_decl),
3182 NULL, t);
3183 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3184 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3186 append_to_statement_list (cur_try_context->finally_body,
3187 &TREE_OPERAND (try_fin, 1));
3189 t = tree_cons (NULL, rethrow_decl, NULL);
3190 t = build_function_call (objc_exception_throw_decl, t);
3191 t = build_stmt (COND_EXPR,
3192 lang_hooks.truthvalue_conversion (rethrow_decl),
3193 t, NULL);
3194 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3195 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3197 return bind;
3200 /* Called just after parsing the @try and its associated BODY. We now
3201 must prepare for the tricky bits -- handling the catches and finally. */
3203 void
3204 objc_begin_try_stmt (location_t try_locus, tree body)
3206 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3207 c->outer = cur_try_context;
3208 c->try_body = body;
3209 c->try_locus = try_locus;
3210 c->end_try_locus = input_location;
3211 cur_try_context = c;
3213 objc_init_exceptions ();
3216 /* Called just after parsing "@catch (parm)". Open a binding level,
3217 enter DECL into the binding level, and initialize it. Leave the
3218 binding level open while the body of the compound statement is parsed. */
3220 void
3221 objc_begin_catch_clause (tree decl)
3223 tree compound, type, t;
3225 /* Begin a new scope that the entire catch clause will live in. */
3226 compound = c_begin_compound_stmt (true);
3228 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3229 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3230 lang_hooks.decls.pushdecl (decl);
3232 /* Since a decl is required here by syntax, don't warn if its unused. */
3233 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3234 be what the previous objc implementation did. */
3235 TREE_USED (decl) = 1;
3237 /* Verify that the type of the catch is valid. It must be a pointer
3238 to an Objective-C class, or "id" (which is catch-all). */
3239 type = TREE_TYPE (decl);
3241 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3242 type = NULL;
3243 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3245 error ("@catch parameter is not a known Objective-C class type");
3246 type = error_mark_node;
3248 else if (cur_try_context->catch_list)
3250 /* Examine previous @catch clauses and see if we've already
3251 caught the type in question. */
3252 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3253 for (; !tsi_end_p (i); tsi_next (&i))
3255 tree stmt = tsi_stmt (i);
3256 t = CATCH_TYPES (stmt);
3257 if (t == error_mark_node)
3258 continue;
3259 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3261 warning ("exception of type %<%T%> will be caught",
3262 TREE_TYPE (type));
3263 warning ("%H by earlier handler for %<%T%>",
3264 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3265 break;
3270 /* Record the data for the catch in the try context so that we can
3271 finalize it later. */
3272 t = build_stmt (CATCH_EXPR, type, compound);
3273 cur_try_context->current_catch = t;
3275 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3276 t = objc_build_exc_ptr ();
3277 t = convert (TREE_TYPE (decl), t);
3278 t = build (MODIFY_EXPR, void_type_node, decl, t);
3279 add_stmt (t);
3282 /* Called just after parsing the closing brace of a @catch clause. Close
3283 the open binding level, and record a CATCH_EXPR for it. */
3285 void
3286 objc_finish_catch_clause (void)
3288 tree c = cur_try_context->current_catch;
3289 cur_try_context->current_catch = NULL;
3290 cur_try_context->end_catch_locus = input_location;
3292 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3293 append_to_statement_list (c, &cur_try_context->catch_list);
3296 /* Called after parsing a @finally clause and its associated BODY.
3297 Record the body for later placement. */
3299 void
3300 objc_build_finally_clause (location_t finally_locus, tree body)
3302 cur_try_context->finally_body = body;
3303 cur_try_context->finally_locus = finally_locus;
3304 cur_try_context->end_finally_locus = input_location;
3307 /* Called to finalize a @try construct. */
3309 void
3310 objc_finish_try_stmt (void)
3312 struct objc_try_context *c = cur_try_context;
3313 tree stmt;
3315 if (c->catch_list == NULL && c->finally_body == NULL)
3316 error ("%<@try%> without %<@catch%> or %<@finally%>");
3318 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3319 if (flag_objc_sjlj_exceptions)
3321 if (!cur_try_context->finally_body)
3323 cur_try_context->finally_locus = input_location;
3324 cur_try_context->end_finally_locus = input_location;
3326 stmt = next_sjlj_build_try_catch_finally ();
3328 else
3330 /* Otherwise, nest the CATCH inside a FINALLY. */
3331 stmt = c->try_body;
3332 if (c->catch_list)
3334 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3335 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3337 if (c->finally_body)
3339 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3340 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3343 add_stmt (stmt);
3345 cur_try_context = c->outer;
3346 free (c);
3349 tree
3350 objc_build_throw_stmt (tree throw_expr)
3352 tree args;
3354 objc_init_exceptions ();
3356 if (throw_expr == NULL)
3358 /* If we're not inside a @catch block, there is no "current
3359 exception" to be rethrown. */
3360 if (cur_try_context == NULL
3361 || cur_try_context->current_catch == NULL)
3363 error ("%<@throw%> (rethrow) used outside of a @catch block");
3364 return NULL_TREE;
3367 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3368 value that we get from the runtime. */
3369 throw_expr = objc_build_exc_ptr ();
3372 /* A throw is just a call to the runtime throw function with the
3373 object as a parameter. */
3374 args = tree_cons (NULL, throw_expr, NULL);
3375 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3378 void
3379 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3381 tree args, call;
3383 /* First lock the mutex. */
3384 mutex = save_expr (mutex);
3385 args = tree_cons (NULL, mutex, NULL);
3386 call = build_function_call (objc_sync_enter_decl, args);
3387 SET_EXPR_LOCATION (call, start_locus);
3388 add_stmt (call);
3390 /* Build the mutex unlock. */
3391 args = tree_cons (NULL, mutex, NULL);
3392 call = build_function_call (objc_sync_exit_decl, args);
3393 SET_EXPR_LOCATION (call, input_location);
3395 /* Put the that and the body in a TRY_FINALLY. */
3396 objc_begin_try_stmt (start_locus, body);
3397 objc_build_finally_clause (input_location, call);
3398 objc_finish_try_stmt ();
3402 /* Predefine the following data type:
3404 struct _objc_exception_data
3406 int buf[_JBLEN];
3407 void *pointers[4];
3408 }; */
3410 /* The following yuckiness should prevent users from having to #include
3411 <setjmp.h> in their code... */
3413 #ifdef TARGET_POWERPC
3414 /* snarfed from /usr/include/ppc/setjmp.h */
3415 #define _JBLEN (26 + 36 + 129 + 1)
3416 #else
3417 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3418 #define _JBLEN 18
3419 #endif
3421 static void
3422 build_next_objc_exception_stuff (void)
3424 tree field_decl, field_decl_chain, index, temp_type;
3426 objc_exception_data_template
3427 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3429 /* int buf[_JBLEN]; */
3431 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3432 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3433 "buf");
3434 field_decl_chain = field_decl;
3436 /* void *pointers[4]; */
3438 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3439 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3440 "pointers");
3441 chainon (field_decl_chain, field_decl);
3443 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3445 /* int _setjmp(...); */
3446 /* If the user includes <setjmp.h>, this shall be superseded by
3447 'int _setjmp(jmp_buf);' */
3448 temp_type = build_function_type (integer_type_node, NULL_TREE);
3449 objc_setjmp_decl
3450 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3452 /* id objc_exception_extract(struct _objc_exception_data *); */
3453 temp_type
3454 = build_function_type (objc_object_type,
3455 tree_cons (NULL_TREE,
3456 build_pointer_type (objc_exception_data_template),
3457 OBJC_VOID_AT_END));
3458 objc_exception_extract_decl
3459 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3460 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3461 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3462 temp_type
3463 = build_function_type (void_type_node,
3464 tree_cons (NULL_TREE,
3465 build_pointer_type (objc_exception_data_template),
3466 OBJC_VOID_AT_END));
3467 objc_exception_try_enter_decl
3468 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3469 objc_exception_try_exit_decl
3470 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3472 /* int objc_exception_match(id, id); */
3473 temp_type
3474 = build_function_type (integer_type_node,
3475 tree_cons (NULL_TREE, objc_object_type,
3476 tree_cons (NULL_TREE, objc_object_type,
3477 OBJC_VOID_AT_END)));
3478 objc_exception_match_decl
3479 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3482 static void
3483 build_objc_exception_stuff (void)
3485 tree noreturn_list, nothrow_list, temp_type;
3487 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3488 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3490 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3491 /* void objc_sync_enter(id); */
3492 /* void objc_sync_exit(id); */
3493 temp_type = build_function_type (void_type_node,
3494 tree_cons (NULL_TREE, objc_object_type,
3495 OBJC_VOID_AT_END));
3496 objc_exception_throw_decl
3497 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3498 noreturn_list);
3499 objc_sync_enter_decl
3500 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3501 NULL, nothrow_list);
3502 objc_sync_exit_decl
3503 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3504 NULL, nothrow_list);
3507 /* Construct a C struct corresponding to ObjC class CLASS, with the same
3508 name as the class:
3510 struct <classname> {
3511 struct _objc_class *isa;
3513 }; */
3515 static void
3516 build_private_template (tree class)
3518 if (!CLASS_STATIC_TEMPLATE (class))
3520 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3522 finish_struct (record, get_class_ivars (class), NULL_TREE);
3523 /* mark this record as class template - for class type checking */
3524 INIT_TYPE_OBJC_INFO (record);
3525 TYPE_OBJC_INTERFACE (record) = class;
3526 CLASS_STATIC_TEMPLATE (class) = record;
3530 /* Begin code generation for protocols... */
3532 /* struct _objc_protocol {
3533 struct _objc_class *isa;
3534 char *protocol_name;
3535 struct _objc_protocol **protocol_list;
3536 struct _objc__method_prototype_list *instance_methods;
3537 struct _objc__method_prototype_list *class_methods;
3538 }; */
3540 static void
3541 build_protocol_template (void)
3543 tree field_decl, field_decl_chain;
3545 objc_protocol_template = start_struct (RECORD_TYPE,
3546 get_identifier (UTAG_PROTOCOL));
3548 /* struct _objc_class *isa; */
3549 field_decl = create_field_decl (build_pointer_type
3550 (xref_tag (RECORD_TYPE,
3551 get_identifier (UTAG_CLASS))),
3552 "isa");
3553 field_decl_chain = field_decl;
3555 /* char *protocol_name; */
3556 field_decl = create_field_decl (string_type_node, "protocol_name");
3557 chainon (field_decl_chain, field_decl);
3559 /* struct _objc_protocol **protocol_list; */
3560 field_decl = create_field_decl (build_pointer_type
3561 (build_pointer_type
3562 (objc_protocol_template)),
3563 "protocol_list");
3564 chainon (field_decl_chain, field_decl);
3566 /* struct objc_method_list *instance_methods; */
3567 field_decl = create_field_decl (build_pointer_type
3568 (xref_tag (RECORD_TYPE,
3569 get_identifier
3570 (UTAG_METHOD_PROTOTYPE_LIST))),
3571 "instance_methods");
3572 chainon (field_decl_chain, field_decl);
3574 /* struct objc_method_list *class_methods; */
3575 field_decl = create_field_decl (build_pointer_type
3576 (xref_tag (RECORD_TYPE,
3577 get_identifier
3578 (UTAG_METHOD_PROTOTYPE_LIST))),
3579 "class_methods");
3580 chainon (field_decl_chain, field_decl);
3582 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
3585 static tree
3586 build_descriptor_table_initializer (tree type, tree entries)
3588 tree initlist = NULL_TREE;
3592 tree eltlist = NULL_TREE;
3594 eltlist
3595 = tree_cons (NULL_TREE,
3596 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3597 eltlist
3598 = tree_cons (NULL_TREE,
3599 add_objc_string (METHOD_ENCODING (entries),
3600 meth_var_types),
3601 eltlist);
3603 initlist
3604 = tree_cons (NULL_TREE,
3605 objc_build_constructor (type, nreverse (eltlist)),
3606 initlist);
3608 entries = TREE_CHAIN (entries);
3610 while (entries);
3612 return objc_build_constructor (build_array_type (type, 0),
3613 nreverse (initlist));
3616 /* struct objc_method_prototype_list {
3617 int count;
3618 struct objc_method_prototype {
3619 SEL name;
3620 char *types;
3621 } list[1];
3622 }; */
3624 static tree
3625 build_method_prototype_list_template (tree list_type, int size)
3627 tree objc_ivar_list_record;
3628 tree field_decl, field_decl_chain;
3630 /* Generate an unnamed struct definition. */
3632 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3634 /* int method_count; */
3635 field_decl = create_field_decl (integer_type_node, "method_count");
3636 field_decl_chain = field_decl;
3638 /* struct objc_method method_list[]; */
3639 field_decl = create_field_decl (build_array_type
3640 (list_type,
3641 build_index_type
3642 (build_int_cst (NULL_TREE, size - 1))),
3643 "method_list");
3644 chainon (field_decl_chain, field_decl);
3646 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3648 return objc_ivar_list_record;
3651 static tree
3652 build_method_prototype_template (void)
3654 tree proto_record;
3655 tree field_decl, field_decl_chain;
3657 proto_record
3658 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3660 /* SEL _cmd; */
3661 field_decl = create_field_decl (objc_selector_type, "_cmd");
3662 field_decl_chain = field_decl;
3664 /* char *method_types; */
3665 field_decl = create_field_decl (string_type_node, "method_types");
3666 chainon (field_decl_chain, field_decl);
3668 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3670 return proto_record;
3673 static tree
3674 objc_method_parm_type (tree type)
3676 type = TREE_VALUE (TREE_TYPE (type));
3677 if (TREE_CODE (type) == TYPE_DECL)
3678 type = TREE_TYPE (type);
3679 return TYPE_MAIN_VARIANT (type);
3682 static int
3683 objc_encoded_type_size (tree type)
3685 int sz = int_size_in_bytes (type);
3687 /* Make all integer and enum types at least as large
3688 as an int. */
3689 if (sz > 0 && INTEGRAL_TYPE_P (type))
3690 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3691 /* Treat arrays as pointers, since that's how they're
3692 passed in. */
3693 else if (TREE_CODE (type) == ARRAY_TYPE)
3694 sz = int_size_in_bytes (ptr_type_node);
3695 return sz;
3698 static tree
3699 encode_method_prototype (tree method_decl)
3701 tree parms;
3702 int parm_offset, i;
3703 char buf[40];
3704 tree result;
3706 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3707 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3709 /* Encode return type. */
3710 encode_type (objc_method_parm_type (method_decl),
3711 obstack_object_size (&util_obstack),
3712 OBJC_ENCODE_INLINE_DEFS);
3714 /* Stack size. */
3715 /* The first two arguments (self and _cmd) are pointers; account for
3716 their size. */
3717 i = int_size_in_bytes (ptr_type_node);
3718 parm_offset = 2 * i;
3719 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3720 parms = TREE_CHAIN (parms))
3722 tree type = objc_method_parm_type (parms);
3723 int sz = objc_encoded_type_size (type);
3725 /* If a type size is not known, bail out. */
3726 if (sz < 0)
3728 error ("%Jtype '%D' does not have a known size",
3729 type, type);
3730 /* Pretend that the encoding succeeded; the compilation will
3731 fail nevertheless. */
3732 goto finish_encoding;
3734 parm_offset += sz;
3737 sprintf (buf, "%d@0:%d", parm_offset, i);
3738 obstack_grow (&util_obstack, buf, strlen (buf));
3740 /* Argument types. */
3741 parm_offset = 2 * i;
3742 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3743 parms = TREE_CHAIN (parms))
3745 tree type = objc_method_parm_type (parms);
3747 /* Process argument qualifiers for user supplied arguments. */
3748 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3750 /* Type. */
3751 encode_type (type, obstack_object_size (&util_obstack),
3752 OBJC_ENCODE_INLINE_DEFS);
3754 /* Compute offset. */
3755 sprintf (buf, "%d", parm_offset);
3756 parm_offset += objc_encoded_type_size (type);
3758 obstack_grow (&util_obstack, buf, strlen (buf));
3761 finish_encoding:
3762 obstack_1grow (&util_obstack, '\0');
3763 result = get_identifier (obstack_finish (&util_obstack));
3764 obstack_free (&util_obstack, util_firstobj);
3765 return result;
3768 static tree
3769 generate_descriptor_table (tree type, const char *name, int size, tree list,
3770 tree proto)
3772 tree decl, initlist;
3774 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
3776 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
3777 initlist = tree_cons (NULL_TREE, list, initlist);
3779 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
3781 return decl;
3784 static void
3785 generate_method_descriptors (tree protocol)
3787 tree initlist, chain, method_list_template;
3788 int size;
3790 if (!objc_method_prototype_template)
3791 objc_method_prototype_template = build_method_prototype_template ();
3793 chain = PROTOCOL_CLS_METHODS (protocol);
3794 if (chain)
3796 size = list_length (chain);
3798 method_list_template
3799 = build_method_prototype_list_template (objc_method_prototype_template,
3800 size);
3802 initlist
3803 = build_descriptor_table_initializer (objc_method_prototype_template,
3804 chain);
3806 UOBJC_CLASS_METHODS_decl
3807 = generate_descriptor_table (method_list_template,
3808 "_OBJC_PROTOCOL_CLASS_METHODS",
3809 size, initlist, protocol);
3811 else
3812 UOBJC_CLASS_METHODS_decl = 0;
3814 chain = PROTOCOL_NST_METHODS (protocol);
3815 if (chain)
3817 size = list_length (chain);
3819 method_list_template
3820 = build_method_prototype_list_template (objc_method_prototype_template,
3821 size);
3822 initlist
3823 = build_descriptor_table_initializer (objc_method_prototype_template,
3824 chain);
3826 UOBJC_INSTANCE_METHODS_decl
3827 = generate_descriptor_table (method_list_template,
3828 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3829 size, initlist, protocol);
3831 else
3832 UOBJC_INSTANCE_METHODS_decl = 0;
3835 static void
3836 generate_protocol_references (tree plist)
3838 tree lproto;
3840 /* Forward declare protocols referenced. */
3841 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3843 tree proto = TREE_VALUE (lproto);
3845 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3846 && PROTOCOL_NAME (proto))
3848 if (! PROTOCOL_FORWARD_DECL (proto))
3849 build_protocol_reference (proto);
3851 if (PROTOCOL_LIST (proto))
3852 generate_protocol_references (PROTOCOL_LIST (proto));
3857 /* For each protocol which was referenced either from a @protocol()
3858 expression, or because a class/category implements it (then a
3859 pointer to the protocol is stored in the struct describing the
3860 class/category), we create a statically allocated instance of the
3861 Protocol class. The code is written in such a way as to generate
3862 as few Protocol objects as possible; we generate a unique Protocol
3863 instance for each protocol, and we don't generate a Protocol
3864 instance if the protocol is never referenced (either from a
3865 @protocol() or from a class/category implementation). These
3866 statically allocated objects can be referred to via the static
3867 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3869 The statically allocated Protocol objects that we generate here
3870 need to be fixed up at runtime in order to be used: the 'isa'
3871 pointer of the objects need to be set up to point to the 'Protocol'
3872 class, as known at runtime.
3874 The NeXT runtime fixes up all protocols at program startup time,
3875 before main() is entered. It uses a low-level trick to look up all
3876 those symbols, then loops on them and fixes them up.
3878 The GNU runtime as well fixes up all protocols before user code
3879 from the module is executed; it requires pointers to those symbols
3880 to be put in the objc_symtab (which is then passed as argument to
3881 the function __objc_exec_class() which the compiler sets up to be
3882 executed automatically when the module is loaded); setup of those
3883 Protocol objects happen in two ways in the GNU runtime: all
3884 Protocol objects referred to by a class or category implementation
3885 are fixed up when the class/category is loaded; all Protocol
3886 objects referred to by a @protocol() expression are added by the
3887 compiler to the list of statically allocated instances to fixup
3888 (the same list holding the statically allocated constant string
3889 objects). Because, as explained above, the compiler generates as
3890 few Protocol objects as possible, some Protocol object might end up
3891 being referenced multiple times when compiled with the GNU runtime,
3892 and end up being fixed up multiple times at runtime initialization.
3893 But that doesn't hurt, it's just a little inefficient. */
3895 static void
3896 generate_protocols (void)
3898 tree p, encoding;
3899 tree decl;
3900 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3902 /* If a protocol was directly referenced, pull in indirect references. */
3903 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3904 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3905 generate_protocol_references (PROTOCOL_LIST (p));
3907 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3909 tree nst_methods = PROTOCOL_NST_METHODS (p);
3910 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3912 /* If protocol wasn't referenced, don't generate any code. */
3913 decl = PROTOCOL_FORWARD_DECL (p);
3915 if (!decl)
3916 continue;
3918 /* Make sure we link in the Protocol class. */
3919 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3921 while (nst_methods)
3923 if (! METHOD_ENCODING (nst_methods))
3925 encoding = encode_method_prototype (nst_methods);
3926 METHOD_ENCODING (nst_methods) = encoding;
3928 nst_methods = TREE_CHAIN (nst_methods);
3931 while (cls_methods)
3933 if (! METHOD_ENCODING (cls_methods))
3935 encoding = encode_method_prototype (cls_methods);
3936 METHOD_ENCODING (cls_methods) = encoding;
3939 cls_methods = TREE_CHAIN (cls_methods);
3941 generate_method_descriptors (p);
3943 if (PROTOCOL_LIST (p))
3944 refs_decl = generate_protocol_list (p);
3945 else
3946 refs_decl = 0;
3948 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3949 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3951 if (refs_decl)
3952 refs_expr = convert (build_pointer_type (build_pointer_type
3953 (objc_protocol_template)),
3954 build_unary_op (ADDR_EXPR, refs_decl, 0));
3955 else
3956 refs_expr = build_int_cst (NULL_TREE, 0);
3958 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3959 by generate_method_descriptors, which is called above. */
3960 initlist = build_protocol_initializer (TREE_TYPE (decl),
3961 protocol_name_expr, refs_expr,
3962 UOBJC_INSTANCE_METHODS_decl,
3963 UOBJC_CLASS_METHODS_decl);
3964 finish_var_decl (decl, initlist);
3968 static tree
3969 build_protocol_initializer (tree type, tree protocol_name,
3970 tree protocol_list, tree instance_methods,
3971 tree class_methods)
3973 tree initlist = NULL_TREE, expr;
3974 tree cast_type = build_pointer_type
3975 (xref_tag (RECORD_TYPE,
3976 get_identifier (UTAG_CLASS)));
3978 /* Filling the "isa" in with one allows the runtime system to
3979 detect that the version change...should remove before final release. */
3981 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
3982 initlist = tree_cons (NULL_TREE, expr, initlist);
3983 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3984 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3986 if (!instance_methods)
3987 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
3988 else
3990 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3991 initlist = tree_cons (NULL_TREE, expr, initlist);
3994 if (!class_methods)
3995 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
3996 else
3998 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3999 initlist = tree_cons (NULL_TREE, expr, initlist);
4002 return objc_build_constructor (type, nreverse (initlist));
4005 /* struct _objc_category {
4006 char *category_name;
4007 char *class_name;
4008 struct _objc_method_list *instance_methods;
4009 struct _objc_method_list *class_methods;
4010 struct _objc_protocol_list *protocols;
4011 }; */
4013 static void
4014 build_category_template (void)
4016 tree field_decl, field_decl_chain;
4018 objc_category_template = start_struct (RECORD_TYPE,
4019 get_identifier (UTAG_CATEGORY));
4021 /* char *category_name; */
4022 field_decl = create_field_decl (string_type_node, "category_name");
4023 field_decl_chain = field_decl;
4025 /* char *class_name; */
4026 field_decl = create_field_decl (string_type_node, "class_name");
4027 chainon (field_decl_chain, field_decl);
4029 /* struct _objc_method_list *instance_methods; */
4030 field_decl = create_field_decl (build_pointer_type
4031 (xref_tag (RECORD_TYPE,
4032 get_identifier
4033 (UTAG_METHOD_LIST))),
4034 "instance_methods");
4035 chainon (field_decl_chain, field_decl);
4037 /* struct _objc_method_list *class_methods; */
4038 field_decl = create_field_decl (build_pointer_type
4039 (xref_tag (RECORD_TYPE,
4040 get_identifier
4041 (UTAG_METHOD_LIST))),
4042 "class_methods");
4043 chainon (field_decl_chain, field_decl);
4045 /* struct _objc_protocol **protocol_list; */
4046 field_decl = create_field_decl (build_pointer_type
4047 (build_pointer_type
4048 (objc_protocol_template)),
4049 "protocol_list");
4050 chainon (field_decl_chain, field_decl);
4052 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4055 /* struct _objc_selector {
4056 SEL sel_id;
4057 char *sel_type;
4058 }; */
4060 static void
4061 build_selector_template (void)
4064 tree field_decl, field_decl_chain;
4066 objc_selector_template
4067 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4069 /* SEL sel_id; */
4070 field_decl = create_field_decl (objc_selector_type, "sel_id");
4071 field_decl_chain = field_decl;
4073 /* char *sel_type; */
4074 field_decl = create_field_decl (string_type_node, "sel_type");
4075 chainon (field_decl_chain, field_decl);
4077 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4080 /* struct _objc_class {
4081 struct _objc_class *isa;
4082 struct _objc_class *super_class;
4083 char *name;
4084 long version;
4085 long info;
4086 long instance_size;
4087 struct _objc_ivar_list *ivars;
4088 struct _objc_method_list *methods;
4089 #ifdef __NEXT_RUNTIME__
4090 struct objc_cache *cache;
4091 #else
4092 struct sarray *dtable;
4093 struct _objc_class *subclass_list;
4094 struct _objc_class *sibling_class;
4095 #endif
4096 struct _objc_protocol_list *protocols;
4097 #ifdef __NEXT_RUNTIME__
4098 void *sel_id;
4099 #endif
4100 void *gc_object_type;
4101 }; */
4103 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4104 the NeXT/Apple runtime; still, the compiler must generate them to
4105 maintain backward binary compatibility (and to allow for future
4106 expansion). */
4108 static void
4109 build_class_template (void)
4111 tree field_decl, field_decl_chain;
4113 objc_class_template
4114 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4116 /* struct _objc_class *isa; */
4117 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4118 "isa");
4119 field_decl_chain = field_decl;
4121 /* struct _objc_class *super_class; */
4122 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4123 "super_class");
4124 chainon (field_decl_chain, field_decl);
4126 /* char *name; */
4127 field_decl = create_field_decl (string_type_node, "name");
4128 chainon (field_decl_chain, field_decl);
4130 /* long version; */
4131 field_decl = create_field_decl (long_integer_type_node, "version");
4132 chainon (field_decl_chain, field_decl);
4134 /* long info; */
4135 field_decl = create_field_decl (long_integer_type_node, "info");
4136 chainon (field_decl_chain, field_decl);
4138 /* long instance_size; */
4139 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4140 chainon (field_decl_chain, field_decl);
4142 /* struct _objc_ivar_list *ivars; */
4143 field_decl = create_field_decl (build_pointer_type
4144 (xref_tag (RECORD_TYPE,
4145 get_identifier
4146 (UTAG_IVAR_LIST))),
4147 "ivars");
4148 chainon (field_decl_chain, field_decl);
4150 /* struct _objc_method_list *methods; */
4151 field_decl = create_field_decl (build_pointer_type
4152 (xref_tag (RECORD_TYPE,
4153 get_identifier
4154 (UTAG_METHOD_LIST))),
4155 "methods");
4156 chainon (field_decl_chain, field_decl);
4158 if (flag_next_runtime)
4160 /* struct objc_cache *cache; */
4161 field_decl = create_field_decl (build_pointer_type
4162 (xref_tag (RECORD_TYPE,
4163 get_identifier
4164 ("objc_cache"))),
4165 "cache");
4166 chainon (field_decl_chain, field_decl);
4168 else
4170 /* struct sarray *dtable; */
4171 field_decl = create_field_decl (build_pointer_type
4172 (xref_tag (RECORD_TYPE,
4173 get_identifier
4174 ("sarray"))),
4175 "dtable");
4176 chainon (field_decl_chain, field_decl);
4178 /* struct objc_class *subclass_list; */
4179 field_decl = create_field_decl (build_pointer_type
4180 (objc_class_template),
4181 "subclass_list");
4182 chainon (field_decl_chain, field_decl);
4184 /* struct objc_class *sibling_class; */
4185 field_decl = create_field_decl (build_pointer_type
4186 (objc_class_template),
4187 "sibling_class");
4188 chainon (field_decl_chain, field_decl);
4191 /* struct _objc_protocol **protocol_list; */
4192 field_decl = create_field_decl (build_pointer_type
4193 (build_pointer_type
4194 (xref_tag (RECORD_TYPE,
4195 get_identifier
4196 (UTAG_PROTOCOL)))),
4197 "protocol_list");
4198 chainon (field_decl_chain, field_decl);
4200 if (flag_next_runtime)
4202 /* void *sel_id; */
4203 field_decl = create_field_decl (build_pointer_type (void_type_node),
4204 "sel_id");
4205 chainon (field_decl_chain, field_decl);
4208 /* void *gc_object_type; */
4209 field_decl = create_field_decl (build_pointer_type (void_type_node),
4210 "gc_object_type");
4211 chainon (field_decl_chain, field_decl);
4213 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4216 /* Generate appropriate forward declarations for an implementation. */
4218 static void
4219 synth_forward_declarations (void)
4221 tree an_id;
4223 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4224 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4225 objc_class_template);
4227 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4228 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4229 objc_class_template);
4231 /* Pre-build the following entities - for speed/convenience. */
4233 an_id = get_identifier ("super_class");
4234 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4235 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4238 static void
4239 error_with_ivar (const char *message, tree decl)
4241 error ("%J%s %qs", decl,
4242 message, gen_declaration (decl));
4246 static void
4247 check_ivars (tree inter, tree imp)
4249 tree intdecls = CLASS_RAW_IVARS (inter);
4250 tree impdecls = CLASS_RAW_IVARS (imp);
4252 while (1)
4254 tree t1, t2;
4256 #ifdef OBJCPLUS
4257 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4258 intdecls = TREE_CHAIN (intdecls);
4259 #endif
4260 if (intdecls == 0 && impdecls == 0)
4261 break;
4262 if (intdecls == 0 || impdecls == 0)
4264 error ("inconsistent instance variable specification");
4265 break;
4268 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4270 if (!comptypes (t1, t2)
4271 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4272 DECL_INITIAL (impdecls)))
4274 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4276 error_with_ivar ("conflicting instance variable type",
4277 impdecls);
4278 error_with_ivar ("previous declaration of",
4279 intdecls);
4281 else /* both the type and the name don't match */
4283 error ("inconsistent instance variable specification");
4284 break;
4288 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4290 error_with_ivar ("conflicting instance variable name",
4291 impdecls);
4292 error_with_ivar ("previous declaration of",
4293 intdecls);
4296 intdecls = TREE_CHAIN (intdecls);
4297 impdecls = TREE_CHAIN (impdecls);
4301 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4302 This needs to be done just once per compilation. */
4304 /* struct _objc_super {
4305 struct _objc_object *self;
4306 struct _objc_class *super_class;
4307 }; */
4309 static void
4310 build_super_template (void)
4312 tree field_decl, field_decl_chain;
4314 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4316 /* struct _objc_object *self; */
4317 field_decl = create_field_decl (objc_object_type, "self");
4318 field_decl_chain = field_decl;
4320 /* struct _objc_class *super_class; */
4321 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4322 "super_class");
4323 chainon (field_decl_chain, field_decl);
4325 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4328 /* struct _objc_ivar {
4329 char *ivar_name;
4330 char *ivar_type;
4331 int ivar_offset;
4332 }; */
4334 static tree
4335 build_ivar_template (void)
4337 tree objc_ivar_id, objc_ivar_record;
4338 tree field_decl, field_decl_chain;
4340 objc_ivar_id = get_identifier (UTAG_IVAR);
4341 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4343 /* char *ivar_name; */
4344 field_decl = create_field_decl (string_type_node, "ivar_name");
4345 field_decl_chain = field_decl;
4347 /* char *ivar_type; */
4348 field_decl = create_field_decl (string_type_node, "ivar_type");
4349 chainon (field_decl_chain, field_decl);
4351 /* int ivar_offset; */
4352 field_decl = create_field_decl (integer_type_node, "ivar_offset");
4353 chainon (field_decl_chain, field_decl);
4355 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4357 return objc_ivar_record;
4360 /* struct {
4361 int ivar_count;
4362 struct objc_ivar ivar_list[ivar_count];
4363 }; */
4365 static tree
4366 build_ivar_list_template (tree list_type, int size)
4368 tree objc_ivar_list_record;
4369 tree field_decl, field_decl_chain;
4371 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4373 /* int ivar_count; */
4374 field_decl = create_field_decl (integer_type_node, "ivar_count");
4375 field_decl_chain = field_decl;
4377 /* struct objc_ivar ivar_list[]; */
4378 field_decl = create_field_decl (build_array_type
4379 (list_type,
4380 build_index_type
4381 (build_int_cst (NULL_TREE, size - 1))),
4382 "ivar_list");
4383 chainon (field_decl_chain, field_decl);
4385 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4387 return objc_ivar_list_record;
4390 /* struct {
4391 struct _objc__method_prototype_list *method_next;
4392 int method_count;
4393 struct objc_method method_list[method_count];
4394 }; */
4396 static tree
4397 build_method_list_template (tree list_type, int size)
4399 tree objc_ivar_list_record;
4400 tree field_decl, field_decl_chain;
4402 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4404 /* struct _objc__method_prototype_list *method_next; */
4405 field_decl = create_field_decl (build_pointer_type
4406 (xref_tag (RECORD_TYPE,
4407 get_identifier
4408 (UTAG_METHOD_PROTOTYPE_LIST))),
4409 "method_next");
4410 field_decl_chain = field_decl;
4412 /* int method_count; */
4413 field_decl = create_field_decl (integer_type_node, "method_count");
4414 chainon (field_decl_chain, field_decl);
4416 /* struct objc_method method_list[]; */
4417 field_decl = create_field_decl (build_array_type
4418 (list_type,
4419 build_index_type
4420 (build_int_cst (NULL_TREE, size - 1))),
4421 "method_list");
4422 chainon (field_decl_chain, field_decl);
4424 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4426 return objc_ivar_list_record;
4429 static tree
4430 build_ivar_list_initializer (tree type, tree field_decl)
4432 tree initlist = NULL_TREE;
4436 tree ivar = NULL_TREE;
4438 /* Set name. */
4439 if (DECL_NAME (field_decl))
4440 ivar = tree_cons (NULL_TREE,
4441 add_objc_string (DECL_NAME (field_decl),
4442 meth_var_names),
4443 ivar);
4444 else
4445 /* Unnamed bit-field ivar (yuck). */
4446 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
4448 /* Set type. */
4449 encode_field_decl (field_decl,
4450 obstack_object_size (&util_obstack),
4451 OBJC_ENCODE_DONT_INLINE_DEFS);
4453 /* Null terminate string. */
4454 obstack_1grow (&util_obstack, 0);
4455 ivar
4456 = tree_cons
4457 (NULL_TREE,
4458 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4459 meth_var_types),
4460 ivar);
4461 obstack_free (&util_obstack, util_firstobj);
4463 /* Set offset. */
4464 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4465 initlist = tree_cons (NULL_TREE,
4466 objc_build_constructor (type, nreverse (ivar)),
4467 initlist);
4469 field_decl = TREE_CHAIN (field_decl);
4470 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4472 while (field_decl);
4474 return objc_build_constructor (build_array_type (type, 0),
4475 nreverse (initlist));
4478 static tree
4479 generate_ivars_list (tree type, const char *name, int size, tree list)
4481 tree decl, initlist;
4483 decl = start_var_decl (type, synth_id_with_class_suffix
4484 (name, objc_implementation_context));
4486 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4487 initlist = tree_cons (NULL_TREE, list, initlist);
4489 finish_var_decl (decl,
4490 objc_build_constructor (TREE_TYPE (decl),
4491 nreverse (initlist)));
4493 return decl;
4496 /* Count only the fields occurring in T. */
4497 static int
4498 ivar_list_length (tree t)
4500 int count = 0;
4502 for (; t; t = TREE_CHAIN (t))
4503 if (TREE_CODE (t) == FIELD_DECL)
4504 ++count;
4506 return count;
4509 static void
4510 generate_ivar_lists (void)
4512 tree initlist, ivar_list_template, chain;
4513 int size;
4515 generating_instance_variables = 1;
4517 if (!objc_ivar_template)
4518 objc_ivar_template = build_ivar_template ();
4520 /* Only generate class variables for the root of the inheritance
4521 hierarchy since these will be the same for every class. */
4523 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4524 && (chain = TYPE_FIELDS (objc_class_template)))
4526 size = ivar_list_length (chain);
4528 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4529 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4531 UOBJC_CLASS_VARIABLES_decl
4532 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4533 size, initlist);
4535 else
4536 UOBJC_CLASS_VARIABLES_decl = 0;
4538 chain = CLASS_IVARS (implementation_template);
4539 if (chain)
4541 size = ivar_list_length (chain);
4542 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4543 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4545 UOBJC_INSTANCE_VARIABLES_decl
4546 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4547 size, initlist);
4549 else
4550 UOBJC_INSTANCE_VARIABLES_decl = 0;
4552 generating_instance_variables = 0;
4555 static tree
4556 build_dispatch_table_initializer (tree type, tree entries)
4558 tree initlist = NULL_TREE;
4562 tree elemlist = NULL_TREE;
4564 elemlist = tree_cons (NULL_TREE,
4565 build_selector (METHOD_SEL_NAME (entries)),
4566 NULL_TREE);
4568 /* Generate the method encoding if we don't have one already. */
4569 if (! METHOD_ENCODING (entries))
4570 METHOD_ENCODING (entries) =
4571 encode_method_prototype (entries);
4573 elemlist = tree_cons (NULL_TREE,
4574 add_objc_string (METHOD_ENCODING (entries),
4575 meth_var_types),
4576 elemlist);
4578 elemlist
4579 = tree_cons (NULL_TREE,
4580 convert (ptr_type_node,
4581 build_unary_op (ADDR_EXPR,
4582 METHOD_DEFINITION (entries), 1)),
4583 elemlist);
4585 initlist = tree_cons (NULL_TREE,
4586 objc_build_constructor (type, nreverse (elemlist)),
4587 initlist);
4589 entries = TREE_CHAIN (entries);
4591 while (entries);
4593 return objc_build_constructor (build_array_type (type, 0),
4594 nreverse (initlist));
4597 /* To accomplish method prototyping without generating all kinds of
4598 inane warnings, the definition of the dispatch table entries were
4599 changed from:
4601 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4603 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4605 static tree
4606 build_method_template (void)
4608 tree _SLT_record;
4609 tree field_decl, field_decl_chain;
4611 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4613 /* SEL _cmd; */
4614 field_decl = create_field_decl (objc_selector_type, "_cmd");
4615 field_decl_chain = field_decl;
4617 /* char *method_types; */
4618 field_decl = create_field_decl (string_type_node, "method_types");
4619 chainon (field_decl_chain, field_decl);
4621 /* void *_imp; */
4622 field_decl = create_field_decl (build_pointer_type (void_type_node),
4623 "_imp");
4624 chainon (field_decl_chain, field_decl);
4626 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4628 return _SLT_record;
4632 static tree
4633 generate_dispatch_table (tree type, const char *name, int size, tree list)
4635 tree decl, initlist;
4637 decl = start_var_decl (type, synth_id_with_class_suffix
4638 (name, objc_implementation_context));
4640 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
4641 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
4642 initlist = tree_cons (NULL_TREE, list, initlist);
4644 finish_var_decl (decl,
4645 objc_build_constructor (TREE_TYPE (decl),
4646 nreverse (initlist)));
4648 return decl;
4651 static void
4652 mark_referenced_methods (void)
4654 struct imp_entry *impent;
4655 tree chain;
4657 for (impent = imp_list; impent; impent = impent->next)
4659 chain = CLASS_CLS_METHODS (impent->imp_context);
4660 while (chain)
4662 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4663 chain = TREE_CHAIN (chain);
4666 chain = CLASS_NST_METHODS (impent->imp_context);
4667 while (chain)
4669 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4670 chain = TREE_CHAIN (chain);
4675 static void
4676 generate_dispatch_tables (void)
4678 tree initlist, chain, method_list_template;
4679 int size;
4681 if (!objc_method_template)
4682 objc_method_template = build_method_template ();
4684 chain = CLASS_CLS_METHODS (objc_implementation_context);
4685 if (chain)
4687 size = list_length (chain);
4689 method_list_template
4690 = build_method_list_template (objc_method_template, size);
4691 initlist
4692 = build_dispatch_table_initializer (objc_method_template, chain);
4694 UOBJC_CLASS_METHODS_decl
4695 = generate_dispatch_table (method_list_template,
4696 ((TREE_CODE (objc_implementation_context)
4697 == CLASS_IMPLEMENTATION_TYPE)
4698 ? "_OBJC_CLASS_METHODS"
4699 : "_OBJC_CATEGORY_CLASS_METHODS"),
4700 size, initlist);
4702 else
4703 UOBJC_CLASS_METHODS_decl = 0;
4705 chain = CLASS_NST_METHODS (objc_implementation_context);
4706 if (chain)
4708 size = list_length (chain);
4710 method_list_template
4711 = build_method_list_template (objc_method_template, size);
4712 initlist
4713 = build_dispatch_table_initializer (objc_method_template, chain);
4715 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4716 UOBJC_INSTANCE_METHODS_decl
4717 = generate_dispatch_table (method_list_template,
4718 "_OBJC_INSTANCE_METHODS",
4719 size, initlist);
4720 else
4721 /* We have a category. */
4722 UOBJC_INSTANCE_METHODS_decl
4723 = generate_dispatch_table (method_list_template,
4724 "_OBJC_CATEGORY_INSTANCE_METHODS",
4725 size, initlist);
4727 else
4728 UOBJC_INSTANCE_METHODS_decl = 0;
4731 static tree
4732 generate_protocol_list (tree i_or_p)
4734 tree initlist;
4735 tree refs_decl, lproto, e, plist;
4736 int size = 0;
4737 const char *ref_name;
4739 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4740 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4741 plist = CLASS_PROTOCOL_LIST (i_or_p);
4742 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4743 plist = PROTOCOL_LIST (i_or_p);
4744 else
4745 abort ();
4747 /* Compute size. */
4748 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4749 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4750 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4751 size++;
4753 /* Build initializer. */
4754 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
4755 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
4756 initlist = tree_cons (NULL_TREE, e, initlist);
4758 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4760 tree pval = TREE_VALUE (lproto);
4762 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4763 && PROTOCOL_FORWARD_DECL (pval))
4765 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4766 initlist = tree_cons (NULL_TREE, e, initlist);
4770 /* static struct objc_protocol *refs[n]; */
4772 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4773 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
4774 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4775 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
4776 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4777 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
4778 else
4779 abort ();
4781 refs_decl = start_var_decl
4782 (build_array_type
4783 (build_pointer_type (objc_protocol_template),
4784 build_index_type (build_int_cst (NULL_TREE, size + 2))),
4785 ref_name);
4787 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4788 nreverse (initlist)));
4790 return refs_decl;
4793 static tree
4794 build_category_initializer (tree type, tree cat_name, tree class_name,
4795 tree instance_methods, tree class_methods,
4796 tree protocol_list)
4798 tree initlist = NULL_TREE, expr;
4800 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4801 initlist = tree_cons (NULL_TREE, class_name, initlist);
4803 if (!instance_methods)
4804 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4805 else
4807 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4808 initlist = tree_cons (NULL_TREE, expr, initlist);
4810 if (!class_methods)
4811 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4812 else
4814 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4815 initlist = tree_cons (NULL_TREE, expr, initlist);
4818 /* protocol_list = */
4819 if (!protocol_list)
4820 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4821 else
4823 expr = convert (build_pointer_type
4824 (build_pointer_type
4825 (objc_protocol_template)),
4826 build_unary_op (ADDR_EXPR, protocol_list, 0));
4827 initlist = tree_cons (NULL_TREE, expr, initlist);
4830 return objc_build_constructor (type, nreverse (initlist));
4833 /* struct _objc_class {
4834 struct objc_class *isa;
4835 struct objc_class *super_class;
4836 char *name;
4837 long version;
4838 long info;
4839 long instance_size;
4840 struct objc_ivar_list *ivars;
4841 struct objc_method_list *methods;
4842 if (flag_next_runtime)
4843 struct objc_cache *cache;
4844 else {
4845 struct sarray *dtable;
4846 struct objc_class *subclass_list;
4847 struct objc_class *sibling_class;
4849 struct objc_protocol_list *protocols;
4850 if (flag_next_runtime)
4851 void *sel_id;
4852 void *gc_object_type;
4853 }; */
4855 static tree
4856 build_shared_structure_initializer (tree type, tree isa, tree super,
4857 tree name, tree size, int status,
4858 tree dispatch_table, tree ivar_list,
4859 tree protocol_list)
4861 tree initlist = NULL_TREE, expr;
4863 /* isa = */
4864 initlist = tree_cons (NULL_TREE, isa, initlist);
4866 /* super_class = */
4867 initlist = tree_cons (NULL_TREE, super, initlist);
4869 /* name = */
4870 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4872 /* version = */
4873 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
4874 initlist);
4876 /* info = */
4877 initlist = tree_cons (NULL_TREE,
4878 build_int_cst (long_integer_type_node, status),
4879 initlist);
4881 /* instance_size = */
4882 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
4883 initlist);
4885 /* objc_ivar_list = */
4886 if (!ivar_list)
4887 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4888 else
4890 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4891 initlist = tree_cons (NULL_TREE, expr, initlist);
4894 /* objc_method_list = */
4895 if (!dispatch_table)
4896 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4897 else
4899 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4900 initlist = tree_cons (NULL_TREE, expr, initlist);
4903 if (flag_next_runtime)
4904 /* method_cache = */
4905 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4906 else
4908 /* dtable = */
4909 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4911 /* subclass_list = */
4912 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4914 /* sibling_class = */
4915 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4918 /* protocol_list = */
4919 if (! protocol_list)
4920 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4921 else
4923 expr = convert (build_pointer_type
4924 (build_pointer_type
4925 (objc_protocol_template)),
4926 build_unary_op (ADDR_EXPR, protocol_list, 0));
4927 initlist = tree_cons (NULL_TREE, expr, initlist);
4930 if (flag_next_runtime)
4931 /* sel_id = NULL */
4932 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4934 /* gc_object_type = NULL */
4935 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4937 return objc_build_constructor (type, nreverse (initlist));
4940 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
4942 static inline tree
4943 lookup_category (tree class, tree cat_name)
4945 tree category = CLASS_CATEGORY_LIST (class);
4947 while (category && CLASS_SUPER_NAME (category) != cat_name)
4948 category = CLASS_CATEGORY_LIST (category);
4949 return category;
4952 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4954 static void
4955 generate_category (tree cat)
4957 tree decl;
4958 tree initlist, cat_name_expr, class_name_expr;
4959 tree protocol_decl, category;
4961 add_class_reference (CLASS_NAME (cat));
4962 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4964 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4966 category = lookup_category (implementation_template,
4967 CLASS_SUPER_NAME (cat));
4969 if (category && CLASS_PROTOCOL_LIST (category))
4971 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4972 protocol_decl = generate_protocol_list (category);
4974 else
4975 protocol_decl = 0;
4977 decl = start_var_decl (objc_category_template,
4978 synth_id_with_class_suffix
4979 ("_OBJC_CATEGORY", objc_implementation_context));
4981 initlist = build_category_initializer (TREE_TYPE (decl),
4982 cat_name_expr, class_name_expr,
4983 UOBJC_INSTANCE_METHODS_decl,
4984 UOBJC_CLASS_METHODS_decl,
4985 protocol_decl);
4987 finish_var_decl (decl, initlist);
4990 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4991 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4993 static void
4994 generate_shared_structures (void)
4996 tree sc_spec, decl_specs, decl;
4997 tree name_expr, super_expr, root_expr;
4998 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4999 tree cast_type, initlist, protocol_decl;
5001 my_super_id = CLASS_SUPER_NAME (implementation_template);
5002 if (my_super_id)
5004 add_class_reference (my_super_id);
5006 /* Compute "my_root_id" - this is required for code generation.
5007 the "isa" for all meta class structures points to the root of
5008 the inheritance hierarchy (e.g. "__Object")... */
5009 my_root_id = my_super_id;
5012 tree my_root_int = lookup_interface (my_root_id);
5014 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5015 my_root_id = CLASS_SUPER_NAME (my_root_int);
5016 else
5017 break;
5019 while (1);
5021 else
5022 /* No super class. */
5023 my_root_id = CLASS_NAME (implementation_template);
5025 cast_type = build_pointer_type (objc_class_template);
5026 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5027 class_names);
5029 /* Install class `isa' and `super' pointers at runtime. */
5030 if (my_super_id)
5032 super_expr = add_objc_string (my_super_id, class_names);
5033 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5035 else
5036 super_expr = build_int_cst (NULL_TREE, 0);
5038 root_expr = add_objc_string (my_root_id, class_names);
5039 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5041 if (CLASS_PROTOCOL_LIST (implementation_template))
5043 generate_protocol_references
5044 (CLASS_PROTOCOL_LIST (implementation_template));
5045 protocol_decl = generate_protocol_list (implementation_template);
5047 else
5048 protocol_decl = 0;
5050 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5052 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5053 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5055 decl = start_var_decl (objc_class_template,
5056 IDENTIFIER_POINTER
5057 (DECL_NAME (UOBJC_METACLASS_decl)));
5059 initlist
5060 = build_shared_structure_initializer
5061 (TREE_TYPE (decl),
5062 root_expr, super_expr, name_expr,
5063 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5064 2 /*CLS_META*/,
5065 UOBJC_CLASS_METHODS_decl,
5066 UOBJC_CLASS_VARIABLES_decl,
5067 protocol_decl);
5069 finish_var_decl (decl, initlist);
5071 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5073 decl = start_var_decl (objc_class_template,
5074 IDENTIFIER_POINTER
5075 (DECL_NAME (UOBJC_CLASS_decl)));
5077 initlist
5078 = build_shared_structure_initializer
5079 (TREE_TYPE (decl),
5080 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5081 super_expr, name_expr,
5082 convert (integer_type_node,
5083 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5084 (implementation_template))),
5085 1 /*CLS_FACTORY*/,
5086 UOBJC_INSTANCE_METHODS_decl,
5087 UOBJC_INSTANCE_VARIABLES_decl,
5088 protocol_decl);
5090 finish_var_decl (decl, initlist);
5094 static const char *
5095 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5097 static char string[BUFSIZE];
5099 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5100 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5102 sprintf (string, "%s_%s", preamble,
5103 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5105 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5106 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5108 /* We have a category. */
5109 const char *const class_name
5110 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5111 const char *const class_super_name
5112 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5113 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5115 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5117 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5118 sprintf (string, "%s_%s", preamble, protocol_name);
5120 else
5121 abort ();
5123 return string;
5126 /* If type is empty or only type qualifiers are present, add default
5127 type of id (otherwise grokdeclarator will default to int). */
5129 static tree
5130 adjust_type_for_id_default (tree type)
5132 if (!type)
5133 type = make_node (TREE_LIST);
5135 if (!TREE_VALUE (type))
5136 TREE_VALUE (type) = objc_object_type;
5137 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5138 && TYPED_OBJECT (TREE_VALUE (type)))
5139 error ("can not use an object as parameter to a method");
5141 return type;
5144 /* Usage:
5145 keyworddecl:
5146 selector ':' '(' typename ')' identifier
5148 Purpose:
5149 Transform an Objective-C keyword argument into
5150 the C equivalent parameter declarator.
5152 In: key_name, an "identifier_node" (optional).
5153 arg_type, a "tree_list" (optional).
5154 arg_name, an "identifier_node".
5156 Note: It would be really nice to strongly type the preceding
5157 arguments in the function prototype; however, then I
5158 could not use the "accessor" macros defined in "tree.h".
5160 Out: an instance of "keyword_decl". */
5162 tree
5163 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5165 tree keyword_decl;
5167 /* If no type is specified, default to "id". */
5168 arg_type = adjust_type_for_id_default (arg_type);
5170 keyword_decl = make_node (KEYWORD_DECL);
5172 TREE_TYPE (keyword_decl) = arg_type;
5173 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5174 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5176 return keyword_decl;
5179 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5181 static tree
5182 build_keyword_selector (tree selector)
5184 int len = 0;
5185 tree key_chain, key_name;
5186 char *buf;
5188 /* Scan the selector to see how much space we'll need. */
5189 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5191 if (TREE_CODE (selector) == KEYWORD_DECL)
5192 key_name = KEYWORD_KEY_NAME (key_chain);
5193 else if (TREE_CODE (selector) == TREE_LIST)
5194 key_name = TREE_PURPOSE (key_chain);
5195 else
5196 abort ();
5198 if (key_name)
5199 len += IDENTIFIER_LENGTH (key_name) + 1;
5200 else
5201 /* Just a ':' arg. */
5202 len++;
5205 buf = (char *) alloca (len + 1);
5206 /* Start the buffer out as an empty string. */
5207 buf[0] = '\0';
5209 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5211 if (TREE_CODE (selector) == KEYWORD_DECL)
5212 key_name = KEYWORD_KEY_NAME (key_chain);
5213 else if (TREE_CODE (selector) == TREE_LIST)
5215 key_name = TREE_PURPOSE (key_chain);
5216 /* The keyword decl chain will later be used as a function argument
5217 chain. Unhook the selector itself so as to not confuse other
5218 parts of the compiler. */
5219 TREE_PURPOSE (key_chain) = NULL_TREE;
5221 else
5222 abort ();
5224 if (key_name)
5225 strcat (buf, IDENTIFIER_POINTER (key_name));
5226 strcat (buf, ":");
5229 return get_identifier (buf);
5232 /* Used for declarations and definitions. */
5234 static tree
5235 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5236 tree add_args)
5238 tree method_decl;
5240 /* If no type is specified, default to "id". */
5241 ret_type = adjust_type_for_id_default (ret_type);
5243 method_decl = make_node (code);
5244 TREE_TYPE (method_decl) = ret_type;
5246 /* If we have a keyword selector, create an identifier_node that
5247 represents the full selector name (`:' included)... */
5248 if (TREE_CODE (selector) == KEYWORD_DECL)
5250 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5251 METHOD_SEL_ARGS (method_decl) = selector;
5252 METHOD_ADD_ARGS (method_decl) = add_args;
5254 else
5256 METHOD_SEL_NAME (method_decl) = selector;
5257 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5258 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5261 return method_decl;
5264 #define METHOD_DEF 0
5265 #define METHOD_REF 1
5267 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5268 an argument list for method METH. CONTEXT is either METHOD_DEF or
5269 METHOD_REF, saying whether we are trying to define a method or call
5270 one. SUPERFLAG says this is for a send to super; this makes a
5271 difference for the NeXT calling sequence in which the lookup and
5272 the method call are done together. If METH is null, user-defined
5273 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5275 static tree
5276 get_arg_type_list (tree meth, int context, int superflag)
5278 tree arglist, akey;
5280 /* Receiver type. */
5281 if (flag_next_runtime && superflag)
5282 arglist = build_tree_list (NULL_TREE, objc_super_type);
5283 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5284 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5285 else
5286 arglist = build_tree_list (NULL_TREE, objc_object_type);
5288 /* Selector type - will eventually change to `int'. */
5289 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5291 /* No actual method prototype given -- assume that remaining arguments
5292 are `...'. */
5293 if (!meth)
5294 return arglist;
5296 /* Build a list of argument types. */
5297 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5299 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
5301 /* Decay arrays and functions into pointers. */
5302 if (TREE_CODE (arg_type) == ARRAY_TYPE)
5303 arg_type = build_pointer_type (TREE_TYPE (arg_type));
5304 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
5305 arg_type = build_pointer_type (arg_type);
5307 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5310 if (METHOD_ADD_ARGS (meth))
5312 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5313 akey; akey = TREE_CHAIN (akey))
5315 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
5317 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5320 if (!TREE_OVERFLOW (METHOD_ADD_ARGS (meth)))
5321 goto lack_of_ellipsis;
5323 else
5325 lack_of_ellipsis:
5326 chainon (arglist, OBJC_VOID_AT_END);
5329 return arglist;
5332 static tree
5333 check_duplicates (hash hsh, int methods, int is_class)
5335 tree meth = NULL_TREE;
5337 if (hsh)
5339 meth = hsh->key;
5341 if (hsh->list)
5343 /* We have two or more methods with the same name but
5344 different types. */
5345 attr loop;
5347 warning ("multiple %s named %<%c%s%> found",
5348 methods ? "methods" : "selectors",
5349 (is_class ? '+' : '-'),
5350 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5352 warn_with_method (methods ? "using" : "found",
5353 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5354 ? '-'
5355 : '+'),
5356 meth);
5357 for (loop = hsh->list; loop; loop = loop->next)
5358 warn_with_method ("also found",
5359 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5360 ? '-'
5361 : '+'),
5362 loop->value);
5365 return meth;
5368 /* If RECEIVER is a class reference, return the identifier node for
5369 the referenced class. RECEIVER is created by objc_get_class_reference,
5370 so we check the exact form created depending on which runtimes are
5371 used. */
5373 static tree
5374 receiver_is_class_object (tree receiver, int self, int super)
5376 tree chain, exp, arg;
5378 /* The receiver is 'self' or 'super' in the context of a class method. */
5379 if (objc_method_context
5380 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5381 && (self || super))
5382 return (super
5383 ? CLASS_SUPER_NAME (implementation_template)
5384 : CLASS_NAME (implementation_template));
5386 if (flag_next_runtime)
5388 /* The receiver is a variable created by
5389 build_class_reference_decl. */
5390 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
5391 /* Look up the identifier. */
5392 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5393 if (TREE_PURPOSE (chain) == receiver)
5394 return TREE_VALUE (chain);
5397 /* The receiver is a function call that returns an id. Check if
5398 it is a call to objc_getClass, if so, pick up the class name. */
5399 if (TREE_CODE (receiver) == CALL_EXPR
5400 && (exp = TREE_OPERAND (receiver, 0))
5401 && TREE_CODE (exp) == ADDR_EXPR
5402 && (exp = TREE_OPERAND (exp, 0))
5403 && TREE_CODE (exp) == FUNCTION_DECL
5404 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5405 prototypes for objc_get_class(). Thankfully, they seem to share the
5406 same function type. */
5407 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5408 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5409 /* We have a call to objc_get_class/objc_getClass! */
5410 && (arg = TREE_OPERAND (receiver, 1))
5411 && TREE_CODE (arg) == TREE_LIST
5412 && (arg = TREE_VALUE (arg)))
5414 STRIP_NOPS (arg);
5415 if (TREE_CODE (arg) == ADDR_EXPR
5416 && (arg = TREE_OPERAND (arg, 0))
5417 && TREE_CODE (arg) == STRING_CST)
5418 /* Finally, we have the class name. */
5419 return get_identifier (TREE_STRING_POINTER (arg));
5421 return 0;
5424 /* If we are currently building a message expr, this holds
5425 the identifier of the selector of the message. This is
5426 used when printing warnings about argument mismatches. */
5428 static tree current_objc_message_selector = 0;
5430 tree
5431 objc_message_selector (void)
5433 return current_objc_message_selector;
5436 /* Construct an expression for sending a message.
5437 MESS has the object to send to in TREE_PURPOSE
5438 and the argument list (including selector) in TREE_VALUE.
5440 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5441 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5443 tree
5444 objc_build_message_expr (tree mess)
5446 tree receiver = TREE_PURPOSE (mess);
5447 tree sel_name;
5448 #ifdef OBJCPLUS
5449 tree args = TREE_PURPOSE (TREE_VALUE (mess));
5450 #else
5451 tree args = TREE_VALUE (mess);
5452 #endif
5453 tree method_params = NULL_TREE;
5455 if (TREE_CODE (receiver) == ERROR_MARK)
5456 return error_mark_node;
5458 /* Obtain the full selector name. */
5459 if (TREE_CODE (args) == IDENTIFIER_NODE)
5460 /* A unary selector. */
5461 sel_name = args;
5462 else if (TREE_CODE (args) == TREE_LIST)
5463 sel_name = build_keyword_selector (args);
5464 else
5465 abort ();
5467 /* Build the parameter list to give to the method. */
5468 if (TREE_CODE (args) == TREE_LIST)
5469 #ifdef OBJCPLUS
5470 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
5471 #else
5473 tree chain = args, prev = NULL_TREE;
5475 /* We have a keyword selector--check for comma expressions. */
5476 while (chain)
5478 tree element = TREE_VALUE (chain);
5480 /* We have a comma expression, must collapse... */
5481 if (TREE_CODE (element) == TREE_LIST)
5483 if (prev)
5484 TREE_CHAIN (prev) = element;
5485 else
5486 args = element;
5488 prev = chain;
5489 chain = TREE_CHAIN (chain);
5491 method_params = args;
5493 #endif
5495 #ifdef OBJCPLUS
5496 if (processing_template_decl)
5497 /* Must wait until template instantiation time. */
5498 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5499 method_params);
5500 #endif
5502 return objc_finish_message_expr (receiver, sel_name, method_params);
5505 /* Look up method SEL_NAME that would be suitable for receiver
5506 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5507 nonzero), and report on any duplicates. */
5509 static tree
5510 lookup_method_in_hash_lists (tree sel_name, int is_class)
5512 hash method_prototype = NULL;
5514 if (!is_class)
5515 method_prototype = hash_lookup (nst_method_hash_list,
5516 sel_name);
5518 if (!method_prototype)
5520 method_prototype = hash_lookup (cls_method_hash_list,
5521 sel_name);
5522 is_class = 1;
5525 return check_duplicates (method_prototype, 1, is_class);
5528 /* The 'objc_finish_message_expr' routine is called from within
5529 'objc_build_message_expr' for non-template functions. In the case of
5530 C++ template functions, it is called from 'build_expr_from_tree'
5531 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5533 tree
5534 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
5536 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5537 tree selector, retval, class_tree;
5538 int self, super, have_cast;
5540 /* Extract the receiver of the message, as well as its type
5541 (where the latter may take the form of a cast or be inferred
5542 from the implementation context). */
5543 rtype = receiver;
5544 while (TREE_CODE (rtype) == COMPOUND_EXPR
5545 || TREE_CODE (rtype) == MODIFY_EXPR
5546 || TREE_CODE (rtype) == NOP_EXPR
5547 || TREE_CODE (rtype) == CONVERT_EXPR
5548 || TREE_CODE (rtype) == COMPONENT_REF)
5549 rtype = TREE_OPERAND (rtype, 0);
5550 self = (rtype == self_decl);
5551 super = (rtype == UOBJC_SUPER_decl);
5552 rtype = TREE_TYPE (receiver);
5553 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5554 || (TREE_CODE (receiver) == COMPOUND_EXPR
5555 && !IS_SUPER (rtype)));
5557 /* If the receiver is a class object, retrieve the corresponding
5558 @interface, if one exists. */
5559 class_tree = receiver_is_class_object (receiver, self, super);
5561 /* Now determine the receiver type (if an explicit cast has not been
5562 provided). */
5563 if (!have_cast)
5565 if (class_tree)
5566 rtype = lookup_interface (class_tree);
5567 /* Handle `self' and `super'. */
5568 else if (super)
5570 if (!CLASS_SUPER_NAME (implementation_template))
5572 error ("no super class declared in @interface for %qs",
5573 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5574 return error_mark_node;
5576 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5578 else if (self)
5579 rtype = lookup_interface (CLASS_NAME (implementation_template));
5582 /* If receiver is of type `id' or `Class' (or if the @interface for a
5583 class is not visible), we shall be satisfied with the existence of
5584 any instance or class method. */
5585 if (!rtype || objc_is_id (rtype))
5587 if (!rtype)
5588 rtype = xref_tag (RECORD_TYPE, class_tree);
5589 else
5591 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
5592 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
5593 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
5594 : NULL_TREE);
5595 rtype = NULL_TREE;
5598 if (rprotos)
5600 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
5601 in protocols themselves for the method prototype. */
5602 method_prototype
5603 = lookup_method_in_protocol_list (rprotos, sel_name,
5604 class_tree != NULL_TREE);
5606 /* If messaging 'Class <Proto>' but did not find a class method
5607 prototype, search for an instance method instead, and warn
5608 about having done so. */
5609 if (!method_prototype && !rtype && class_tree != NULL_TREE)
5611 method_prototype
5612 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
5614 if (method_prototype)
5615 warning ("found %<-%s%> instead of %<+%s%> in protocol(s)",
5616 IDENTIFIER_POINTER (sel_name),
5617 IDENTIFIER_POINTER (sel_name));
5621 else
5623 tree orig_rtype = rtype, saved_rtype;
5625 if (TREE_CODE (rtype) == POINTER_TYPE)
5626 rtype = TREE_TYPE (rtype);
5627 /* Traverse typedef aliases */
5628 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
5629 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
5630 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
5631 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
5632 saved_rtype = rtype;
5633 if (TYPED_OBJECT (rtype))
5635 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
5636 rtype = TYPE_OBJC_INTERFACE (rtype);
5638 /* If we could not find an @interface declaration, we must have
5639 only seen a @class declaration; so, we cannot say anything
5640 more intelligent about which methods the receiver will
5641 understand. */
5642 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
5643 rtype = saved_rtype;
5644 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5645 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5647 /* We have a valid ObjC class name. Look up the method name
5648 in the published @interface for the class (and its
5649 superclasses). */
5650 method_prototype
5651 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
5653 /* If the method was not found in the @interface, it may still
5654 exist locally as part of the @implementation. */
5655 if (!method_prototype && objc_implementation_context
5656 && CLASS_NAME (objc_implementation_context)
5657 == OBJC_TYPE_NAME (rtype))
5658 method_prototype
5659 = lookup_method
5660 ((class_tree
5661 ? CLASS_CLS_METHODS (objc_implementation_context)
5662 : CLASS_NST_METHODS (objc_implementation_context)),
5663 sel_name);
5665 /* If we haven't found a candidate method by now, try looking for
5666 it in the protocol list. */
5667 if (!method_prototype && rprotos)
5668 method_prototype
5669 = lookup_method_in_protocol_list (rprotos, sel_name,
5670 class_tree != NULL_TREE);
5672 else
5674 warning ("invalid receiver type %qs",
5675 gen_type_name (orig_rtype));
5676 /* After issuing the "invalid receiver" warning, perform method
5677 lookup as if we were messaging 'id'. */
5678 rtype = rprotos = NULL_TREE;
5683 /* For 'id' or 'Class' receivers, search in the global hash table
5684 as a last resort. For all receivers, warn if protocol searches
5685 have failed. */
5686 if (!method_prototype)
5688 if (rprotos)
5689 warning ("%<%c%s%> not found in protocol(s)",
5690 (class_tree ? '+' : '-'),
5691 IDENTIFIER_POINTER (sel_name));
5693 if (!rtype)
5694 method_prototype
5695 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
5698 if (!method_prototype)
5700 static bool warn_missing_methods = false;
5702 if (rtype)
5703 warning ("%qs may not respond to %<%c%s%>",
5704 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5705 (class_tree ? '+' : '-'),
5706 IDENTIFIER_POINTER (sel_name));
5707 /* If we are messaging an 'id' or 'Class' object and made it here,
5708 then we have failed to find _any_ instance or class method,
5709 respectively. */
5710 else
5711 warning ("no %<%c%s%> method found",
5712 (class_tree ? '+' : '-'),
5713 IDENTIFIER_POINTER (sel_name));
5715 if (!warn_missing_methods)
5717 warning ("(Messages without a matching method signature");
5718 warning ("will be assumed to return %<id%> and accept");
5719 warning ("%<...%> as arguments.)");
5720 warn_missing_methods = true;
5724 /* Save the selector name for printing error messages. */
5725 current_objc_message_selector = sel_name;
5727 /* Build the parameters list for looking up the method.
5728 These are the object itself and the selector. */
5730 if (flag_typed_selectors)
5731 selector = build_typed_selector_reference (sel_name, method_prototype);
5732 else
5733 selector = build_selector_reference (sel_name);
5735 retval = build_objc_method_call (super, method_prototype,
5736 receiver,
5737 selector, method_params);
5739 current_objc_message_selector = 0;
5741 return retval;
5744 /* Build a tree expression to send OBJECT the operation SELECTOR,
5745 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5746 assuming the method has prototype METHOD_PROTOTYPE.
5747 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5748 Use METHOD_PARAMS as list of args to pass to the method.
5749 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5751 static tree
5752 build_objc_method_call (int super_flag, tree method_prototype,
5753 tree lookup_object, tree selector,
5754 tree method_params)
5756 tree sender = (super_flag ? umsg_super_decl :
5757 (!flag_next_runtime || flag_nil_receivers
5758 ? umsg_decl
5759 : umsg_nonnil_decl));
5760 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
5762 /* If a prototype for the method to be called exists, then cast
5763 the sender's return type and arguments to match that of the method.
5764 Otherwise, leave sender as is. */
5765 tree ret_type
5766 = (method_prototype
5767 ? TREE_VALUE (TREE_TYPE (method_prototype))
5768 : objc_object_type);
5769 tree sender_cast
5770 = build_pointer_type
5771 (build_function_type
5772 (ret_type,
5773 get_arg_type_list
5774 (method_prototype, METHOD_REF, super_flag)));
5775 tree method, t;
5777 lookup_object = build_c_cast (rcv_p, lookup_object);
5779 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
5780 lookup_object = save_expr (lookup_object);
5782 if (flag_next_runtime)
5784 /* If we are returning a struct in memory, and the address
5785 of that memory location is passed as a hidden first
5786 argument, then change which messenger entry point this
5787 expr will call. NB: Note that sender_cast remains
5788 unchanged (it already has a struct return type). */
5789 if (!targetm.calls.struct_value_rtx (0, 0)
5790 && (TREE_CODE (ret_type) == RECORD_TYPE
5791 || TREE_CODE (ret_type) == UNION_TYPE)
5792 && targetm.calls.return_in_memory (ret_type, 0))
5793 sender = (super_flag ? umsg_super_stret_decl :
5794 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5796 method_params = tree_cons (NULL_TREE, lookup_object,
5797 tree_cons (NULL_TREE, selector,
5798 method_params));
5799 method = build_fold_addr_expr (sender);
5801 else
5803 /* This is the portable (GNU) way. */
5804 tree object;
5806 /* First, call the lookup function to get a pointer to the method,
5807 then cast the pointer, then call it with the method arguments. */
5809 object = (super_flag ? self_decl : lookup_object);
5811 t = tree_cons (NULL_TREE, selector, NULL_TREE);
5812 t = tree_cons (NULL_TREE, lookup_object, t);
5813 method = build_function_call (sender, t);
5815 /* Pass the object to the method. */
5816 method_params = tree_cons (NULL_TREE, object,
5817 tree_cons (NULL_TREE, selector,
5818 method_params));
5821 /* ??? Selector is not at this point something we can use inside
5822 the compiler itself. Set it to garbage for the nonce. */
5823 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
5824 return build_function_call (t, method_params);
5827 static void
5828 build_protocol_reference (tree p)
5830 tree decl;
5831 const char *proto_name;
5833 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
5835 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5836 decl = start_var_decl (objc_protocol_template, proto_name);
5838 PROTOCOL_FORWARD_DECL (p) = decl;
5841 /* This function is called by the parser when (and only when) a
5842 @protocol() expression is found, in order to compile it. */
5843 tree
5844 objc_build_protocol_expr (tree protoname)
5846 tree expr;
5847 tree p = lookup_protocol (protoname);
5849 if (!p)
5851 error ("cannot find protocol declaration for %qs",
5852 IDENTIFIER_POINTER (protoname));
5853 return error_mark_node;
5856 if (!PROTOCOL_FORWARD_DECL (p))
5857 build_protocol_reference (p);
5859 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5861 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5862 if we have it, rather than converting it here. */
5863 expr = convert (objc_protocol_type, expr);
5865 /* The @protocol() expression is being compiled into a pointer to a
5866 statically allocated instance of the Protocol class. To become
5867 usable at runtime, the 'isa' pointer of the instance need to be
5868 fixed up at runtime by the runtime library, to point to the
5869 actual 'Protocol' class. */
5871 /* For the GNU runtime, put the static Protocol instance in the list
5872 of statically allocated instances, so that we make sure that its
5873 'isa' pointer is fixed up at runtime by the GNU runtime library
5874 to point to the Protocol class (at runtime, when loading the
5875 module, the GNU runtime library loops on the statically allocated
5876 instances (as found in the defs field in objc_symtab) and fixups
5877 all the 'isa' pointers of those objects). */
5878 if (! flag_next_runtime)
5880 /* This type is a struct containing the fields of a Protocol
5881 object. (Cfr. objc_protocol_type instead is the type of a pointer
5882 to such a struct). */
5883 tree protocol_struct_type = xref_tag
5884 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5885 tree *chain;
5887 /* Look for the list of Protocol statically allocated instances
5888 to fixup at runtime. Create a new list to hold Protocol
5889 statically allocated instances, if the list is not found. At
5890 present there is only another list, holding NSConstantString
5891 static instances to be fixed up at runtime. */
5892 for (chain = &objc_static_instances;
5893 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5894 chain = &TREE_CHAIN (*chain));
5895 if (!*chain)
5897 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5898 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
5899 class_names);
5902 /* Add this statically allocated instance to the Protocol list. */
5903 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5904 PROTOCOL_FORWARD_DECL (p),
5905 TREE_PURPOSE (*chain));
5909 return expr;
5912 /* This function is called by the parser when a @selector() expression
5913 is found, in order to compile it. It is only called by the parser
5914 and only to compile a @selector(). */
5915 tree
5916 objc_build_selector_expr (tree selnamelist)
5918 tree selname;
5920 /* Obtain the full selector name. */
5921 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5922 /* A unary selector. */
5923 selname = selnamelist;
5924 else if (TREE_CODE (selnamelist) == TREE_LIST)
5925 selname = build_keyword_selector (selnamelist);
5926 else
5927 abort ();
5929 /* If we are required to check @selector() expressions as they
5930 are found, check that the selector has been declared. */
5931 if (warn_undeclared_selector)
5933 /* Look the selector up in the list of all known class and
5934 instance methods (up to this line) to check that the selector
5935 exists. */
5936 hash hsh;
5938 /* First try with instance methods. */
5939 hsh = hash_lookup (nst_method_hash_list, selname);
5941 /* If not found, try with class methods. */
5942 if (!hsh)
5944 hsh = hash_lookup (cls_method_hash_list, selname);
5947 /* If still not found, print out a warning. */
5948 if (!hsh)
5950 warning ("undeclared selector %qs", IDENTIFIER_POINTER (selname));
5955 if (flag_typed_selectors)
5956 return build_typed_selector_reference (selname, 0);
5957 else
5958 return build_selector_reference (selname);
5961 tree
5962 objc_build_encode_expr (tree type)
5964 tree result;
5965 const char *string;
5967 encode_type (type, obstack_object_size (&util_obstack),
5968 OBJC_ENCODE_INLINE_DEFS);
5969 obstack_1grow (&util_obstack, 0); /* null terminate string */
5970 string = obstack_finish (&util_obstack);
5972 /* Synthesize a string that represents the encoded struct/union. */
5973 result = my_build_string (strlen (string) + 1, string);
5974 obstack_free (&util_obstack, util_firstobj);
5975 return result;
5978 static tree
5979 build_ivar_reference (tree id)
5981 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5983 /* Historically, a class method that produced objects (factory
5984 method) would assign `self' to the instance that it
5985 allocated. This would effectively turn the class method into
5986 an instance method. Following this assignment, the instance
5987 variables could be accessed. That practice, while safe,
5988 violates the simple rule that a class method should not refer
5989 to an instance variable. It's better to catch the cases
5990 where this is done unknowingly than to support the above
5991 paradigm. */
5992 warning ("instance variable %qs accessed in class method",
5993 IDENTIFIER_POINTER (id));
5994 self_decl = convert (objc_instance_type, self_decl); /* cast */
5997 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6000 /* Compute a hash value for a given method SEL_NAME. */
6002 static size_t
6003 hash_func (tree sel_name)
6005 const unsigned char *s
6006 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6007 size_t h = 0;
6009 while (*s)
6010 h = h * 67 + *s++ - 113;
6011 return h;
6014 static void
6015 hash_init (void)
6017 nst_method_hash_list
6018 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6019 cls_method_hash_list
6020 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6022 /* Initialize the hash table used to hold the constant string objects. */
6023 string_htab = htab_create_ggc (31, string_hash,
6024 string_eq, NULL);
6027 /* WARNING!!!! hash_enter is called with a method, and will peek
6028 inside to find its selector! But hash_lookup is given a selector
6029 directly, and looks for the selector that's inside the found
6030 entry's key (method) for comparison. */
6032 static void
6033 hash_enter (hash *hashlist, tree method)
6035 hash obj;
6036 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6038 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6039 obj->list = 0;
6040 obj->next = hashlist[slot];
6041 obj->key = method;
6043 hashlist[slot] = obj; /* append to front */
6046 static hash
6047 hash_lookup (hash *hashlist, tree sel_name)
6049 hash target;
6051 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6053 while (target)
6055 if (sel_name == METHOD_SEL_NAME (target->key))
6056 return target;
6058 target = target->next;
6060 return 0;
6063 static void
6064 hash_add_attr (hash entry, tree value)
6066 attr obj;
6068 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6069 obj->next = entry->list;
6070 obj->value = value;
6072 entry->list = obj; /* append to front */
6075 static tree
6076 lookup_method (tree mchain, tree method)
6078 tree key;
6080 if (TREE_CODE (method) == IDENTIFIER_NODE)
6081 key = method;
6082 else
6083 key = METHOD_SEL_NAME (method);
6085 while (mchain)
6087 if (METHOD_SEL_NAME (mchain) == key)
6088 return mchain;
6090 mchain = TREE_CHAIN (mchain);
6092 return NULL_TREE;
6095 static tree
6096 lookup_method_static (tree interface, tree ident, int is_class)
6098 tree meth = NULL_TREE, root_inter = NULL_TREE;
6099 tree inter = interface;
6101 while (inter)
6103 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6104 tree category = inter;
6106 /* First, look up the method in the class itself. */
6107 if ((meth = lookup_method (chain, ident)))
6108 return meth;
6110 /* Failing that, look for the method in each category of the class. */
6111 while ((category = CLASS_CATEGORY_LIST (category)))
6113 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6115 /* Check directly in each category. */
6116 if ((meth = lookup_method (chain, ident)))
6117 return meth;
6119 /* Failing that, check in each category's protocols. */
6120 if (CLASS_PROTOCOL_LIST (category))
6122 if ((meth = (lookup_method_in_protocol_list
6123 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6124 return meth;
6128 /* If not found in categories, check in protocols of the main class. */
6129 if (CLASS_PROTOCOL_LIST (inter))
6131 if ((meth = (lookup_method_in_protocol_list
6132 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6133 return meth;
6136 /* Failing that, climb up the inheritance hierarchy. */
6137 root_inter = inter;
6138 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6140 while (inter);
6142 /* If no class (factory) method was found, check if an _instance_
6143 method of the same name exists in the root class. This is what
6144 the Objective-C runtime will do. If an instance method was not
6145 found, return 0. */
6146 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6149 /* Add the method to the hash list if it doesn't contain an identical
6150 method already. */
6151 static void
6152 add_method_to_hash_list (hash *hash_list, tree method)
6154 hash hsh;
6156 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6158 /* Install on a global chain. */
6159 hash_enter (hash_list, method);
6161 else
6163 /* Check types against those; if different, add to a list. */
6164 attr loop;
6165 int already_there = comp_proto_with_proto (method, hsh->key);
6166 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6167 already_there |= comp_proto_with_proto (method, loop->value);
6168 if (!already_there)
6169 hash_add_attr (hsh, method);
6173 static tree
6174 objc_add_method (tree class, tree method, int is_class)
6176 tree mth;
6178 if (!(mth = lookup_method (is_class
6179 ? CLASS_CLS_METHODS (class)
6180 : CLASS_NST_METHODS (class), method)))
6182 /* put method on list in reverse order */
6183 if (is_class)
6185 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6186 CLASS_CLS_METHODS (class) = method;
6188 else
6190 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6191 CLASS_NST_METHODS (class) = method;
6194 else
6196 /* When processing an @interface for a class or category, give hard
6197 errors on methods with identical selectors but differing argument
6198 and/or return types. We do not do this for @implementations, because
6199 C/C++ will do it for us (i.e., there will be duplicate function
6200 definition errors). */
6201 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6202 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6203 && !comp_proto_with_proto (method, mth))
6204 error ("duplicate declaration of method %<%c%s%>",
6205 is_class ? '+' : '-',
6206 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6209 if (is_class)
6210 add_method_to_hash_list (cls_method_hash_list, method);
6211 else
6213 add_method_to_hash_list (nst_method_hash_list, method);
6215 /* Instance methods in root classes (and categories thereof)
6216 may act as class methods as a last resort. We also add
6217 instance methods listed in @protocol declarations to
6218 the class hash table, on the assumption that @protocols
6219 may be adopted by root classes or categories. */
6220 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6221 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6222 class = lookup_interface (CLASS_NAME (class));
6224 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6225 || !CLASS_SUPER_NAME (class))
6226 add_method_to_hash_list (cls_method_hash_list, method);
6229 return method;
6232 static tree
6233 add_class (tree class)
6235 /* Put interfaces on list in reverse order. */
6236 TREE_CHAIN (class) = interface_chain;
6237 interface_chain = class;
6238 return interface_chain;
6241 static void
6242 add_category (tree class, tree category)
6244 /* Put categories on list in reverse order. */
6245 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6247 if (cat)
6249 warning ("duplicate interface declaration for category %<%s(%s)%>",
6250 IDENTIFIER_POINTER (CLASS_NAME (class)),
6251 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6253 else
6255 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6256 CLASS_CATEGORY_LIST (class) = category;
6260 /* Called after parsing each instance variable declaration. Necessary to
6261 preserve typedefs and implement public/private...
6263 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6265 static tree
6266 add_instance_variable (tree class, int public, tree field_decl)
6268 tree field_type = TREE_TYPE (field_decl);
6269 const char *ivar_name = DECL_NAME (field_decl)
6270 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6271 : "<unnamed>";
6273 #ifdef OBJCPLUS
6274 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6276 error ("illegal reference type specified for instance variable %qs",
6277 ivar_name);
6278 /* Return class as is without adding this ivar. */
6279 return class;
6281 #endif
6283 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6284 || TYPE_SIZE (field_type) == error_mark_node)
6285 /* 'type[0]' is allowed, but 'type[]' is not! */
6287 error ("instance variable %qs has unknown size", ivar_name);
6288 /* Return class as is without adding this ivar. */
6289 return class;
6292 #ifdef OBJCPLUS
6293 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6294 cannot be ivars; ditto for classes with vtables. */
6295 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6296 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6298 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6299 if(TYPE_POLYMORPHIC_P (field_type)) {
6300 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6301 error ("type %qs has virtual member functions", type_name);
6302 error ("illegal aggregate type %qs specified for instance variable %qs",
6303 type_name, ivar_name);
6304 /* Return class as is without adding this ivar. */
6305 return class;
6307 /* user-defined constructors and destructors are not known to Obj-C and
6308 hence will not be called. This may or may not be a problem. */
6309 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6310 warning ("type %qs has a user-defined constructor", type_name);
6311 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6312 warning ("type %qs has a user-defined destructor", type_name);
6313 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6315 #endif
6317 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6318 switch (public)
6320 case 0:
6321 TREE_PUBLIC (field_decl) = 0;
6322 TREE_PRIVATE (field_decl) = 0;
6323 TREE_PROTECTED (field_decl) = 1;
6324 break;
6326 case 1:
6327 TREE_PUBLIC (field_decl) = 1;
6328 TREE_PRIVATE (field_decl) = 0;
6329 TREE_PROTECTED (field_decl) = 0;
6330 break;
6332 case 2:
6333 TREE_PUBLIC (field_decl) = 0;
6334 TREE_PRIVATE (field_decl) = 1;
6335 TREE_PROTECTED (field_decl) = 0;
6336 break;
6340 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
6342 return class;
6345 static tree
6346 is_ivar (tree decl_chain, tree ident)
6348 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6349 if (DECL_NAME (decl_chain) == ident)
6350 return decl_chain;
6351 return NULL_TREE;
6354 /* True if the ivar is private and we are not in its implementation. */
6356 static int
6357 is_private (tree decl)
6359 return (TREE_PRIVATE (decl)
6360 && ! is_ivar (CLASS_IVARS (implementation_template),
6361 DECL_NAME (decl)));
6364 /* We have an instance variable reference;, check to see if it is public. */
6367 objc_is_public (tree expr, tree identifier)
6369 tree basetype = TREE_TYPE (expr);
6370 enum tree_code code = TREE_CODE (basetype);
6371 tree decl;
6373 if (code == RECORD_TYPE)
6375 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
6377 if (TREE_CODE (TYPE_OBJC_INTERFACE (basetype)) == IDENTIFIER_NODE)
6379 error ("cannot find interface declaration for %qs",
6380 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6381 return 0;
6384 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6386 if (TREE_PUBLIC (decl))
6387 return 1;
6389 /* Important difference between the Stepstone translator:
6390 all instance variables should be public within the context
6391 of the implementation. */
6392 if (objc_implementation_context
6393 && (((TREE_CODE (objc_implementation_context)
6394 == CLASS_IMPLEMENTATION_TYPE)
6395 || (TREE_CODE (objc_implementation_context)
6396 == CATEGORY_IMPLEMENTATION_TYPE))
6397 && (CLASS_NAME (objc_implementation_context)
6398 == OBJC_TYPE_NAME (basetype))))
6400 int private = is_private (decl);
6402 if (private)
6403 error ("instance variable %qs is declared private",
6404 IDENTIFIER_POINTER (DECL_NAME (decl)));
6405 return !private;
6408 /* The 2.95.2 compiler sometimes allowed C functions to access
6409 non-@public ivars. We will let this slide for now... */
6410 if (!objc_method_context)
6412 warning ("instance variable %qs is %s; "
6413 "this will be a hard error in the future",
6414 IDENTIFIER_POINTER (identifier),
6415 TREE_PRIVATE (decl) ? "@private" : "@protected");
6416 return 1;
6419 error ("instance variable %qs is declared %s",
6420 IDENTIFIER_POINTER (identifier),
6421 TREE_PRIVATE (decl) ? "private" : "protected");
6422 return 0;
6426 else if (objc_implementation_context && (basetype == objc_object_reference))
6428 expr = convert (uprivate_record, expr);
6429 warning ("static access to object of type %<id%>");
6433 return 1;
6436 /* Make sure all entries in CHAIN are also in LIST. */
6438 static int
6439 check_methods (tree chain, tree list, int mtype)
6441 int first = 1;
6443 while (chain)
6445 if (!lookup_method (list, chain))
6447 if (first)
6449 if (TREE_CODE (objc_implementation_context)
6450 == CLASS_IMPLEMENTATION_TYPE)
6451 warning ("incomplete implementation of class %qs",
6452 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6453 else if (TREE_CODE (objc_implementation_context)
6454 == CATEGORY_IMPLEMENTATION_TYPE)
6455 warning ("incomplete implementation of category %qs",
6456 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6457 first = 0;
6460 warning ("method definition for %<%c%s%> not found",
6461 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6464 chain = TREE_CHAIN (chain);
6467 return first;
6470 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6472 static int
6473 conforms_to_protocol (tree class, tree protocol)
6475 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6477 tree p = CLASS_PROTOCOL_LIST (class);
6478 while (p && TREE_VALUE (p) != protocol)
6479 p = TREE_CHAIN (p);
6481 if (!p)
6483 tree super = (CLASS_SUPER_NAME (class)
6484 ? lookup_interface (CLASS_SUPER_NAME (class))
6485 : NULL_TREE);
6486 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6487 if (!tmp)
6488 return 0;
6492 return 1;
6495 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6496 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6498 static int
6499 check_methods_accessible (tree chain, tree context, int mtype)
6501 int first = 1;
6502 tree list;
6503 tree base_context = context;
6505 while (chain)
6507 context = base_context;
6508 while (context)
6510 if (mtype == '+')
6511 list = CLASS_CLS_METHODS (context);
6512 else
6513 list = CLASS_NST_METHODS (context);
6515 if (lookup_method (list, chain))
6516 break;
6518 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6519 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6520 context = (CLASS_SUPER_NAME (context)
6521 ? lookup_interface (CLASS_SUPER_NAME (context))
6522 : NULL_TREE);
6524 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6525 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6526 context = (CLASS_NAME (context)
6527 ? lookup_interface (CLASS_NAME (context))
6528 : NULL_TREE);
6529 else
6530 abort ();
6533 if (context == NULL_TREE)
6535 if (first)
6537 if (TREE_CODE (objc_implementation_context)
6538 == CLASS_IMPLEMENTATION_TYPE)
6539 warning ("incomplete implementation of class %qs",
6540 IDENTIFIER_POINTER
6541 (CLASS_NAME (objc_implementation_context)));
6542 else if (TREE_CODE (objc_implementation_context)
6543 == CATEGORY_IMPLEMENTATION_TYPE)
6544 warning ("incomplete implementation of category %qs",
6545 IDENTIFIER_POINTER
6546 (CLASS_SUPER_NAME (objc_implementation_context)));
6547 first = 0;
6549 warning ("method definition for %<%c%s%> not found",
6550 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6553 chain = TREE_CHAIN (chain); /* next method... */
6555 return first;
6558 /* Check whether the current interface (accessible via
6559 'objc_implementation_context') actually implements protocol P, along
6560 with any protocols that P inherits. */
6562 static void
6563 check_protocol (tree p, const char *type, const char *name)
6565 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6567 int f1, f2;
6569 /* Ensure that all protocols have bodies! */
6570 if (warn_protocol)
6572 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6573 CLASS_CLS_METHODS (objc_implementation_context),
6574 '+');
6575 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6576 CLASS_NST_METHODS (objc_implementation_context),
6577 '-');
6579 else
6581 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6582 objc_implementation_context,
6583 '+');
6584 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6585 objc_implementation_context,
6586 '-');
6589 if (!f1 || !f2)
6590 warning ("%s %qs does not fully implement the %qs protocol",
6591 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6594 /* Check protocols recursively. */
6595 if (PROTOCOL_LIST (p))
6597 tree subs = PROTOCOL_LIST (p);
6598 tree super_class =
6599 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6601 while (subs)
6603 tree sub = TREE_VALUE (subs);
6605 /* If the superclass does not conform to the protocols
6606 inherited by P, then we must! */
6607 if (!super_class || !conforms_to_protocol (super_class, sub))
6608 check_protocol (sub, type, name);
6609 subs = TREE_CHAIN (subs);
6614 /* Check whether the current interface (accessible via
6615 'objc_implementation_context') actually implements the protocols listed
6616 in PROTO_LIST. */
6618 static void
6619 check_protocols (tree proto_list, const char *type, const char *name)
6621 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6623 tree p = TREE_VALUE (proto_list);
6625 check_protocol (p, type, name);
6629 /* Make sure that the class CLASS_NAME is defined
6630 CODE says which kind of thing CLASS_NAME ought to be.
6631 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6632 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6634 static tree
6635 start_class (enum tree_code code, tree class_name, tree super_name,
6636 tree protocol_list)
6638 tree class, decl;
6640 #ifdef OBJCPLUS
6641 if (current_namespace != global_namespace) {
6642 error ("Objective-C declarations may only appear in global scope");
6644 #endif /* OBJCPLUS */
6646 if (objc_implementation_context)
6648 warning ("%<@end%> missing in implementation context");
6649 finish_class (objc_implementation_context);
6650 objc_ivar_chain = NULL_TREE;
6651 objc_implementation_context = NULL_TREE;
6654 class = make_node (code);
6655 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
6657 /* Check for existence of the super class, if one was specified. */
6658 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
6659 && super_name && !objc_is_class_name (super_name))
6661 error ("cannot find interface declaration for %qs, superclass of %qs",
6662 IDENTIFIER_POINTER (super_name),
6663 IDENTIFIER_POINTER (class_name));
6664 super_name = NULL_TREE;
6667 CLASS_NAME (class) = class_name;
6668 CLASS_SUPER_NAME (class) = super_name;
6669 CLASS_CLS_METHODS (class) = NULL_TREE;
6671 if (! objc_is_class_name (class_name)
6672 && (decl = lookup_name (class_name)))
6674 error ("%qs redeclared as different kind of symbol",
6675 IDENTIFIER_POINTER (class_name));
6676 error ("%Jprevious declaration of '%D'",
6677 decl, decl);
6680 if (code == CLASS_IMPLEMENTATION_TYPE)
6683 tree chain;
6685 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6686 if (TREE_VALUE (chain) == class_name)
6688 error ("reimplementation of class %qs",
6689 IDENTIFIER_POINTER (class_name));
6690 return error_mark_node;
6692 implemented_classes = tree_cons (NULL_TREE, class_name,
6693 implemented_classes);
6696 /* Reset for multiple classes per file. */
6697 method_slot = 0;
6699 objc_implementation_context = class;
6701 /* Lookup the interface for this implementation. */
6703 if (!(implementation_template = lookup_interface (class_name)))
6705 warning ("cannot find interface declaration for %qs",
6706 IDENTIFIER_POINTER (class_name));
6707 add_class (implementation_template = objc_implementation_context);
6710 /* If a super class has been specified in the implementation,
6711 insure it conforms to the one specified in the interface. */
6713 if (super_name
6714 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6716 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6717 const char *const name =
6718 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6719 error ("conflicting super class name %qs",
6720 IDENTIFIER_POINTER (super_name));
6721 error ("previous declaration of %qs", name);
6724 else if (! super_name)
6726 CLASS_SUPER_NAME (objc_implementation_context)
6727 = CLASS_SUPER_NAME (implementation_template);
6731 else if (code == CLASS_INTERFACE_TYPE)
6733 if (lookup_interface (class_name))
6734 #ifdef OBJCPLUS
6735 error ("duplicate interface declaration for class %qs",
6736 #else
6737 warning ("duplicate interface declaration for class %qs",
6738 #endif
6739 IDENTIFIER_POINTER (class_name));
6740 else
6741 add_class (class);
6743 if (protocol_list)
6744 CLASS_PROTOCOL_LIST (class)
6745 = lookup_and_install_protocols (protocol_list);
6748 else if (code == CATEGORY_INTERFACE_TYPE)
6750 tree class_category_is_assoc_with;
6752 /* For a category, class_name is really the name of the class that
6753 the following set of methods will be associated with. We must
6754 find the interface so that can derive the objects template. */
6756 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6758 error ("cannot find interface declaration for %qs",
6759 IDENTIFIER_POINTER (class_name));
6760 exit (FATAL_EXIT_CODE);
6762 else
6763 add_category (class_category_is_assoc_with, class);
6765 if (protocol_list)
6766 CLASS_PROTOCOL_LIST (class)
6767 = lookup_and_install_protocols (protocol_list);
6770 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6772 /* Reset for multiple classes per file. */
6773 method_slot = 0;
6775 objc_implementation_context = class;
6777 /* For a category, class_name is really the name of the class that
6778 the following set of methods will be associated with. We must
6779 find the interface so that can derive the objects template. */
6781 if (!(implementation_template = lookup_interface (class_name)))
6783 error ("cannot find interface declaration for %qs",
6784 IDENTIFIER_POINTER (class_name));
6785 exit (FATAL_EXIT_CODE);
6788 return class;
6791 static tree
6792 continue_class (tree class)
6794 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6795 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6797 struct imp_entry *imp_entry;
6798 tree ivar_context;
6800 /* Check consistency of the instance variables. */
6802 if (CLASS_RAW_IVARS (class))
6803 check_ivars (implementation_template, class);
6805 /* code generation */
6807 #ifdef OBJCPLUS
6808 push_lang_context (lang_name_c);
6809 #endif
6811 build_private_template (implementation_template);
6812 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
6813 ivar_context = TYPE_FIELDS (uprivate_record);
6814 objc_instance_type = build_pointer_type (uprivate_record);
6816 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6818 imp_entry->next = imp_list;
6819 imp_entry->imp_context = class;
6820 imp_entry->imp_template = implementation_template;
6822 synth_forward_declarations ();
6823 imp_entry->class_decl = UOBJC_CLASS_decl;
6824 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6826 /* Append to front and increment count. */
6827 imp_list = imp_entry;
6828 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6829 imp_count++;
6830 else
6831 cat_count++;
6833 #ifdef OBJCPLUS
6834 pop_lang_context ();
6835 #endif /* OBJCPLUS */
6837 return ivar_context;
6840 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6842 #ifdef OBJCPLUS
6843 push_lang_context (lang_name_c);
6844 #endif /* OBJCPLUS */
6846 build_private_template (class);
6848 #ifdef OBJCPLUS
6849 pop_lang_context ();
6850 #endif /* OBJCPLUS */
6852 return NULL_TREE;
6855 else
6856 return error_mark_node;
6859 /* This is called once we see the "@end" in an interface/implementation. */
6861 static void
6862 finish_class (tree class)
6864 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6866 /* All code generation is done in finish_objc. */
6868 if (implementation_template != objc_implementation_context)
6870 /* Ensure that all method listed in the interface contain bodies. */
6871 check_methods (CLASS_CLS_METHODS (implementation_template),
6872 CLASS_CLS_METHODS (objc_implementation_context), '+');
6873 check_methods (CLASS_NST_METHODS (implementation_template),
6874 CLASS_NST_METHODS (objc_implementation_context), '-');
6876 if (CLASS_PROTOCOL_LIST (implementation_template))
6877 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6878 "class",
6879 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6883 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6885 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6887 if (category)
6889 /* Ensure all method listed in the interface contain bodies. */
6890 check_methods (CLASS_CLS_METHODS (category),
6891 CLASS_CLS_METHODS (objc_implementation_context), '+');
6892 check_methods (CLASS_NST_METHODS (category),
6893 CLASS_NST_METHODS (objc_implementation_context), '-');
6895 if (CLASS_PROTOCOL_LIST (category))
6896 check_protocols (CLASS_PROTOCOL_LIST (category),
6897 "category",
6898 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6903 static tree
6904 add_protocol (tree protocol)
6906 /* Put protocol on list in reverse order. */
6907 TREE_CHAIN (protocol) = protocol_chain;
6908 protocol_chain = protocol;
6909 return protocol_chain;
6912 static tree
6913 lookup_protocol (tree ident)
6915 tree chain;
6917 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6918 if (ident == PROTOCOL_NAME (chain))
6919 return chain;
6921 return NULL_TREE;
6924 /* This function forward declares the protocols named by NAMES. If
6925 they are already declared or defined, the function has no effect. */
6927 void
6928 objc_declare_protocols (tree names)
6930 tree list;
6932 #ifdef OBJCPLUS
6933 if (current_namespace != global_namespace) {
6934 error ("Objective-C declarations may only appear in global scope");
6936 #endif /* OBJCPLUS */
6938 for (list = names; list; list = TREE_CHAIN (list))
6940 tree name = TREE_VALUE (list);
6942 if (lookup_protocol (name) == NULL_TREE)
6944 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6946 TYPE_LANG_SLOT_1 (protocol)
6947 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
6948 PROTOCOL_NAME (protocol) = name;
6949 PROTOCOL_LIST (protocol) = NULL_TREE;
6950 add_protocol (protocol);
6951 PROTOCOL_DEFINED (protocol) = 0;
6952 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6957 static tree
6958 start_protocol (enum tree_code code, tree name, tree list)
6960 tree protocol;
6962 #ifdef OBJCPLUS
6963 if (current_namespace != global_namespace) {
6964 error ("Objective-C declarations may only appear in global scope");
6966 #endif /* OBJCPLUS */
6968 protocol = lookup_protocol (name);
6970 if (!protocol)
6972 protocol = make_node (code);
6973 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
6975 PROTOCOL_NAME (protocol) = name;
6976 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6977 add_protocol (protocol);
6978 PROTOCOL_DEFINED (protocol) = 1;
6979 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6981 check_protocol_recursively (protocol, list);
6983 else if (! PROTOCOL_DEFINED (protocol))
6985 PROTOCOL_DEFINED (protocol) = 1;
6986 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6988 check_protocol_recursively (protocol, list);
6990 else
6992 warning ("duplicate declaration for protocol %qs",
6993 IDENTIFIER_POINTER (name));
6995 return protocol;
6999 /* "Encode" a data type into a string, which grows in util_obstack.
7000 ??? What is the FORMAT? Someone please document this! */
7002 static void
7003 encode_type_qualifiers (tree declspecs)
7005 tree spec;
7007 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7009 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7010 obstack_1grow (&util_obstack, 'n');
7011 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7012 obstack_1grow (&util_obstack, 'N');
7013 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7014 obstack_1grow (&util_obstack, 'o');
7015 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7016 obstack_1grow (&util_obstack, 'O');
7017 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7018 obstack_1grow (&util_obstack, 'R');
7019 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7020 obstack_1grow (&util_obstack, 'V');
7024 /* Encode a pointer type. */
7026 static void
7027 encode_pointer (tree type, int curtype, int format)
7029 tree pointer_to = TREE_TYPE (type);
7031 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7033 if (OBJC_TYPE_NAME (pointer_to)
7034 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7036 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7038 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7040 obstack_1grow (&util_obstack, '@');
7041 return;
7043 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7044 && TYPE_OBJC_INTERFACE (pointer_to))
7046 if (generating_instance_variables)
7048 obstack_1grow (&util_obstack, '@');
7049 obstack_1grow (&util_obstack, '"');
7050 obstack_grow (&util_obstack, name, strlen (name));
7051 obstack_1grow (&util_obstack, '"');
7052 return;
7054 else
7056 obstack_1grow (&util_obstack, '@');
7057 return;
7060 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7062 obstack_1grow (&util_obstack, '#');
7063 return;
7065 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7067 obstack_1grow (&util_obstack, ':');
7068 return;
7072 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7073 && TYPE_MODE (pointer_to) == QImode)
7075 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7076 ? OBJC_TYPE_NAME (pointer_to)
7077 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7079 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7081 /* It appears that "r*" means "const char *" rather than
7082 "char *const". */
7083 if (TYPE_READONLY (pointer_to))
7084 obstack_1grow (&util_obstack, 'r');
7086 obstack_1grow (&util_obstack, '*');
7087 return;
7091 /* We have a type that does not get special treatment. */
7093 /* NeXT extension */
7094 obstack_1grow (&util_obstack, '^');
7095 encode_type (pointer_to, curtype, format);
7098 static void
7099 encode_array (tree type, int curtype, int format)
7101 tree an_int_cst = TYPE_SIZE (type);
7102 tree array_of = TREE_TYPE (type);
7103 char buffer[40];
7105 /* An incomplete array is treated like a pointer. */
7106 if (an_int_cst == NULL)
7108 encode_pointer (type, curtype, format);
7109 return;
7112 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7113 (TREE_INT_CST_LOW (an_int_cst)
7114 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7116 obstack_grow (&util_obstack, buffer, strlen (buffer));
7117 encode_type (array_of, curtype, format);
7118 obstack_1grow (&util_obstack, ']');
7119 return;
7122 static void
7123 encode_aggregate_within (tree type, int curtype, int format, int left,
7124 int right)
7126 tree name;
7127 /* NB: aggregates that are pointed to have slightly different encoding
7128 rules in that you never encode the names of instance variables. */
7129 int pointed_to
7130 = (obstack_object_size (&util_obstack) > 0
7131 && *(obstack_next_free (&util_obstack) - 1) == '^');
7132 int inline_contents
7133 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7134 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7136 /* Traverse struct aliases; it is important to get the
7137 original struct and its tag name (if any). */
7138 type = TYPE_MAIN_VARIANT (type);
7139 name = OBJC_TYPE_NAME (type);
7140 /* Open parenth/bracket. */
7141 obstack_1grow (&util_obstack, left);
7143 /* Encode the struct/union tag name, or '?' if a tag was
7144 not provided. Typedef aliases do not qualify. */
7145 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7146 #ifdef OBJCPLUS
7147 /* Did this struct have a tag? */
7148 && !TYPE_WAS_ANONYMOUS (type)
7149 #endif
7151 obstack_grow (&util_obstack,
7152 IDENTIFIER_POINTER (name),
7153 strlen (IDENTIFIER_POINTER (name)));
7154 else
7155 obstack_1grow (&util_obstack, '?');
7157 /* Encode the types (and possibly names) of the inner fields,
7158 if required. */
7159 if (inline_contents)
7161 tree fields = TYPE_FIELDS (type);
7163 obstack_1grow (&util_obstack, '=');
7164 for (; fields; fields = TREE_CHAIN (fields))
7166 #ifdef OBJCPLUS
7167 /* C++ static members, and things that are not fields at all,
7168 should not appear in the encoding. */
7169 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7170 continue;
7171 #endif
7172 if (generating_instance_variables && !pointed_to)
7174 tree fname = DECL_NAME (fields);
7176 obstack_1grow (&util_obstack, '"');
7177 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7178 obstack_grow (&util_obstack,
7179 IDENTIFIER_POINTER (fname),
7180 strlen (IDENTIFIER_POINTER (fname)));
7181 obstack_1grow (&util_obstack, '"');
7183 encode_field_decl (fields, curtype, format);
7186 /* Close parenth/bracket. */
7187 obstack_1grow (&util_obstack, right);
7190 static void
7191 encode_aggregate (tree type, int curtype, int format)
7193 enum tree_code code = TREE_CODE (type);
7195 switch (code)
7197 case RECORD_TYPE:
7199 encode_aggregate_within (type, curtype, format, '{', '}');
7200 break;
7202 case UNION_TYPE:
7204 encode_aggregate_within (type, curtype, format, '(', ')');
7205 break;
7208 case ENUMERAL_TYPE:
7209 obstack_1grow (&util_obstack, 'i');
7210 break;
7212 default:
7213 break;
7217 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7218 field type. */
7220 static void
7221 encode_next_bitfield (int width)
7223 char buffer[40];
7224 sprintf (buffer, "b%d", width);
7225 obstack_grow (&util_obstack, buffer, strlen (buffer));
7228 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7229 static void
7230 encode_type (tree type, int curtype, int format)
7232 enum tree_code code = TREE_CODE (type);
7233 char c;
7235 if (TYPE_READONLY (type))
7236 obstack_1grow (&util_obstack, 'r');
7238 if (code == INTEGER_TYPE)
7240 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7242 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7243 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7244 case 32:
7245 if (type == long_unsigned_type_node
7246 || type == long_integer_type_node)
7247 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7248 else
7249 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7250 break;
7251 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7252 default: abort ();
7254 obstack_1grow (&util_obstack, c);
7257 else if (code == REAL_TYPE)
7259 /* Floating point types. */
7260 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7262 case 32: c = 'f'; break;
7263 case 64:
7264 case 96:
7265 case 128: c = 'd'; break;
7266 default: abort ();
7268 obstack_1grow (&util_obstack, c);
7271 else if (code == VOID_TYPE)
7272 obstack_1grow (&util_obstack, 'v');
7274 else if (code == BOOLEAN_TYPE)
7275 obstack_1grow (&util_obstack, 'B');
7277 else if (code == ARRAY_TYPE)
7278 encode_array (type, curtype, format);
7280 else if (code == POINTER_TYPE)
7281 encode_pointer (type, curtype, format);
7283 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7284 encode_aggregate (type, curtype, format);
7286 else if (code == FUNCTION_TYPE) /* '?' */
7287 obstack_1grow (&util_obstack, '?');
7290 static void
7291 encode_gnu_bitfield (int position, tree type, int size)
7293 enum tree_code code = TREE_CODE (type);
7294 char buffer[40];
7295 char charType = '?';
7297 if (code == INTEGER_TYPE)
7299 if (integer_zerop (TYPE_MIN_VALUE (type)))
7301 /* Unsigned integer types. */
7303 if (TYPE_MODE (type) == QImode)
7304 charType = 'C';
7305 else if (TYPE_MODE (type) == HImode)
7306 charType = 'S';
7307 else if (TYPE_MODE (type) == SImode)
7309 if (type == long_unsigned_type_node)
7310 charType = 'L';
7311 else
7312 charType = 'I';
7314 else if (TYPE_MODE (type) == DImode)
7315 charType = 'Q';
7318 else
7319 /* Signed integer types. */
7321 if (TYPE_MODE (type) == QImode)
7322 charType = 'c';
7323 else if (TYPE_MODE (type) == HImode)
7324 charType = 's';
7325 else if (TYPE_MODE (type) == SImode)
7327 if (type == long_integer_type_node)
7328 charType = 'l';
7329 else
7330 charType = 'i';
7333 else if (TYPE_MODE (type) == DImode)
7334 charType = 'q';
7337 else if (code == ENUMERAL_TYPE)
7338 charType = 'i';
7339 else
7340 abort ();
7342 sprintf (buffer, "b%d%c%d", position, charType, size);
7343 obstack_grow (&util_obstack, buffer, strlen (buffer));
7346 static void
7347 encode_field_decl (tree field_decl, int curtype, int format)
7349 tree type;
7351 #ifdef OBJCPLUS
7352 /* C++ static members, and things that are not fields at all,
7353 should not appear in the encoding. */
7354 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7355 return;
7356 #endif
7358 type = TREE_TYPE (field_decl);
7360 /* Generate the bitfield typing information, if needed. Note the difference
7361 between GNU and NeXT runtimes. */
7362 if (DECL_BIT_FIELD_TYPE (field_decl))
7364 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7366 if (flag_next_runtime)
7367 encode_next_bitfield (size);
7368 else
7369 encode_gnu_bitfield (int_bit_position (field_decl),
7370 DECL_BIT_FIELD_TYPE (field_decl), size);
7372 else
7373 encode_type (TREE_TYPE (field_decl), curtype, format);
7376 static GTY(()) tree objc_parmlist = NULL_TREE;
7378 /* Append PARM to a list of formal parameters of a method, making a necessary
7379 array-to-pointer adjustment along the way. */
7381 static void
7382 objc_push_parm (tree parm)
7384 /* Decay arrays and functions into pointers. */
7385 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
7386 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
7387 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
7388 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
7390 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
7391 DECL_ARG_TYPE (parm)
7392 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
7394 /* Record constancy and volatility. */
7395 c_apply_type_quals_to_decl
7396 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
7397 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
7398 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
7400 objc_parmlist = chainon (objc_parmlist, parm);
7403 /* Retrieve the formal parameter list constructed via preceding calls to
7404 objc_push_parm(). */
7406 #ifdef OBJCPLUS
7407 static tree
7408 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
7409 #else
7410 static struct c_arg_info *
7411 objc_get_parm_info (int have_ellipsis)
7412 #endif
7414 #ifdef OBJCPLUS
7415 tree parm_info = objc_parmlist;
7416 objc_parmlist = NULL_TREE;
7418 return parm_info;
7419 #else
7420 tree parm_info = objc_parmlist;
7421 struct c_arg_info *arg_info;
7422 /* The C front-end requires an elaborate song and dance at
7423 this point. */
7424 push_scope ();
7425 declare_parm_level ();
7426 while (parm_info)
7428 tree next = TREE_CHAIN (parm_info);
7430 TREE_CHAIN (parm_info) = NULL_TREE;
7431 parm_info = pushdecl (parm_info);
7432 finish_decl (parm_info, NULL_TREE, NULL_TREE);
7433 parm_info = next;
7435 arg_info = get_parm_info (have_ellipsis);
7436 pop_scope ();
7437 objc_parmlist = NULL_TREE;
7438 return arg_info;
7439 #endif
7442 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
7443 method definitions. In the case of instance methods, we can be more
7444 specific as to the type of 'self'. */
7446 static void
7447 synth_self_and_ucmd_args (void)
7449 tree self_type;
7451 if (objc_method_context
7452 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7453 self_type = objc_instance_type;
7454 else
7455 /* Really a `struct objc_class *'. However, we allow people to
7456 assign to self, which changes its type midstream. */
7457 self_type = objc_object_type;
7459 /* id self; */
7460 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
7462 /* SEL _cmd; */
7463 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
7466 /* Transform an Objective-C method definition into a static C function
7467 definition, synthesizing the first two arguments, "self" and "_cmd",
7468 in the process. */
7470 static void
7471 start_method_def (tree method)
7473 tree parmlist;
7474 #ifdef OBJCPLUS
7475 tree parm_info;
7476 #else
7477 struct c_arg_info *parm_info;
7478 #endif
7479 int have_ellipsis = 0;
7481 /* Required to implement _msgSuper. */
7482 objc_method_context = method;
7483 UOBJC_SUPER_decl = NULL_TREE;
7485 /* Generate prototype declarations for arguments..."new-style". */
7486 synth_self_and_ucmd_args ();
7488 /* Generate argument declarations if a keyword_decl. */
7489 parmlist = METHOD_SEL_ARGS (method);
7490 while (parmlist)
7492 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
7494 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
7495 objc_push_parm (parm);
7496 parmlist = TREE_CHAIN (parmlist);
7499 if (METHOD_ADD_ARGS (method))
7501 tree akey;
7503 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
7504 akey; akey = TREE_CHAIN (akey))
7506 objc_push_parm (TREE_VALUE (akey));
7509 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
7510 have_ellipsis = 1;
7513 parm_info = objc_get_parm_info (have_ellipsis);
7515 really_start_method (objc_method_context, parm_info);
7518 static void
7519 warn_with_method (const char *message, int mtype, tree method)
7521 /* Add a readable method name to the warning. */
7522 warning ("%J%s %<%c%s%>", method,
7523 message, mtype, gen_method_decl (method));
7526 /* Return 1 if TYPE1 is equivalent to TYPE2
7527 for purposes of method overloading. */
7529 static int
7530 objc_types_are_equivalent (tree type1, tree type2)
7532 if (type1 == type2)
7533 return 1;
7535 /* Strip away indirections. */
7536 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
7537 && (TREE_CODE (type1) == TREE_CODE (type2)))
7538 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
7539 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7540 return 0;
7542 type1 = (TYPE_HAS_OBJC_INFO (type1)
7543 ? TYPE_OBJC_PROTOCOL_LIST (type1)
7544 : NULL_TREE);
7545 type2 = (TYPE_HAS_OBJC_INFO (type2)
7546 ? TYPE_OBJC_PROTOCOL_LIST (type2)
7547 : NULL_TREE);
7549 if (list_length (type1) == list_length (type2))
7551 for (; type2; type2 = TREE_CHAIN (type2))
7552 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7553 return 0;
7554 return 1;
7556 return 0;
7559 /* Return 1 if PROTO1 is equivalent to PROTO2
7560 for purposes of method overloading. */
7562 static int
7563 comp_proto_with_proto (tree proto1, tree proto2)
7565 tree type1, type2;
7567 /* The following test is needed in case there are hashing
7568 collisions. */
7569 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7570 return 0;
7572 /* Compare return types. */
7573 type1 = TREE_VALUE (TREE_TYPE (proto1));
7574 type2 = TREE_VALUE (TREE_TYPE (proto2));
7576 if (!objc_types_are_equivalent (type1, type2))
7577 return 0;
7579 /* Compare argument types. */
7580 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7581 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7582 type1 && type2;
7583 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7585 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7586 return 0;
7589 return (!type1 && !type2);
7592 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
7593 this occurs. ObjC method dispatches are _not_ like C++ virtual
7594 member function dispatches, and we account for the difference here. */
7595 tree
7596 #ifdef OBJCPLUS
7597 objc_fold_obj_type_ref (tree ref, tree known_type)
7598 #else
7599 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
7600 tree known_type ATTRIBUTE_UNUSED)
7601 #endif
7603 #ifdef OBJCPLUS
7604 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
7606 /* If the receiver does not have virtual member functions, there
7607 is nothing we can (or need to) do here. */
7608 if (!v)
7609 return NULL_TREE;
7611 /* Let C++ handle C++ virtual functions. */
7612 return cp_fold_obj_type_ref (ref, known_type);
7613 #else
7614 /* For plain ObjC, we currently do not need to do anything. */
7615 return NULL_TREE;
7616 #endif
7619 static void
7620 objc_start_function (tree name, tree type, tree attrs,
7621 #ifdef OBJCPLUS
7622 tree params
7623 #else
7624 struct c_arg_info *params
7625 #endif
7628 tree fndecl = build_decl (FUNCTION_DECL, name, type);
7630 #ifdef OBJCPLUS
7631 DECL_ARGUMENTS (fndecl) = params;
7632 DECL_INITIAL (fndecl) = error_mark_node;
7633 DECL_EXTERNAL (fndecl) = 0;
7634 TREE_STATIC (fndecl) = 1;
7635 retrofit_lang_decl (fndecl);
7636 cplus_decl_attributes (&fndecl, attrs, 0);
7637 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
7638 #else
7639 decl_attributes (&fndecl, attrs, 0);
7640 announce_function (fndecl);
7641 DECL_INITIAL (fndecl) = error_mark_node;
7642 DECL_EXTERNAL (fndecl) = 0;
7643 TREE_STATIC (fndecl) = 1;
7644 current_function_decl = pushdecl (fndecl);
7645 push_scope ();
7646 declare_parm_level ();
7647 DECL_RESULT (current_function_decl)
7648 = build_decl (RESULT_DECL, NULL_TREE,
7649 TREE_TYPE (TREE_TYPE (current_function_decl)));
7650 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
7651 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
7652 start_fname_decls ();
7653 store_parm_decls_from (params);
7654 #endif
7656 TREE_USED (current_function_decl) = 1;
7659 /* - Generate an identifier for the function. the format is "_n_cls",
7660 where 1 <= n <= nMethods, and cls is the name the implementation we
7661 are processing.
7662 - Install the return type from the method declaration.
7663 - If we have a prototype, check for type consistency. */
7665 static void
7666 really_start_method (tree method,
7667 #ifdef OBJCPLUS
7668 tree parmlist
7669 #else
7670 struct c_arg_info *parmlist
7671 #endif
7674 tree ret_type, meth_type;
7675 tree method_id;
7676 const char *sel_name, *class_name, *cat_name;
7677 char *buf;
7679 /* Synth the storage class & assemble the return type. */
7680 ret_type = TREE_VALUE (TREE_TYPE (method));
7682 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7683 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7684 cat_name = ((TREE_CODE (objc_implementation_context)
7685 == CLASS_IMPLEMENTATION_TYPE)
7686 ? NULL
7687 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7688 method_slot++;
7690 /* Make sure this is big enough for any plausible method label. */
7691 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7692 + (cat_name ? strlen (cat_name) : 0));
7694 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7695 class_name, cat_name, sel_name, method_slot);
7697 method_id = get_identifier (buf);
7699 #ifdef OBJCPLUS
7700 /* Objective-C methods cannot be overloaded, so we don't need
7701 the type encoding appended. It looks bad anyway... */
7702 push_lang_context (lang_name_c);
7703 #endif
7705 meth_type
7706 = build_function_type (ret_type,
7707 get_arg_type_list (method, METHOD_DEF, 0));
7708 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
7710 /* Set self_decl from the first argument. */
7711 self_decl = DECL_ARGUMENTS (current_function_decl);
7713 /* Suppress unused warnings. */
7714 TREE_USED (self_decl) = 1;
7715 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7716 #ifdef OBJCPLUS
7717 pop_lang_context ();
7718 #endif
7720 METHOD_DEFINITION (method) = current_function_decl;
7722 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7724 if (implementation_template != objc_implementation_context)
7726 tree proto
7727 = lookup_method_static (implementation_template,
7728 METHOD_SEL_NAME (method),
7729 TREE_CODE (method) == CLASS_METHOD_DECL);
7731 if (proto)
7733 if (!comp_proto_with_proto (method, proto))
7735 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7737 warn_with_method ("conflicting types for", type, method);
7738 warn_with_method ("previous declaration of", type, proto);
7741 else
7743 /* We have a method @implementation even though we did not
7744 see a corresponding @interface declaration (which is allowed
7745 by Objective-C rules). Go ahead and place the method in
7746 the @interface anyway, so that message dispatch lookups
7747 will see it. */
7748 tree interface = implementation_template;
7750 if (TREE_CODE (objc_implementation_context)
7751 == CATEGORY_IMPLEMENTATION_TYPE)
7752 interface = lookup_category
7753 (interface,
7754 CLASS_SUPER_NAME (objc_implementation_context));
7756 if (interface)
7757 objc_add_method (interface, copy_node (method),
7758 TREE_CODE (method) == CLASS_METHOD_DECL);
7763 static void *UOBJC_SUPER_scope = 0;
7765 /* _n_Method (id self, SEL sel, ...)
7767 struct objc_super _S;
7768 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7769 } */
7771 static tree
7772 get_super_receiver (void)
7774 if (objc_method_context)
7776 tree super_expr, super_expr_list;
7778 if (!UOBJC_SUPER_decl)
7780 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
7781 objc_super_template);
7782 /* This prevents `unused variable' warnings when compiling with -Wall. */
7783 TREE_USED (UOBJC_SUPER_decl) = 1;
7784 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
7785 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7786 UOBJC_SUPER_scope = objc_get_current_scope ();
7789 /* Set receiver to self. */
7790 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7791 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7792 super_expr_list = super_expr;
7794 /* Set class to begin searching. */
7795 super_expr = build_component_ref (UOBJC_SUPER_decl,
7796 get_identifier ("super_class"));
7798 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7800 /* [_cls, __cls]Super are "pre-built" in
7801 synth_forward_declarations. */
7803 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7804 ((TREE_CODE (objc_method_context)
7805 == INSTANCE_METHOD_DECL)
7806 ? ucls_super_ref
7807 : uucls_super_ref));
7810 else
7811 /* We have a category. */
7813 tree super_name = CLASS_SUPER_NAME (implementation_template);
7814 tree super_class;
7816 /* Barf if super used in a category of Object. */
7817 if (!super_name)
7819 error ("no super class declared in interface for %qs",
7820 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7821 return error_mark_node;
7824 if (flag_next_runtime && !flag_zero_link)
7826 super_class = objc_get_class_reference (super_name);
7827 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7828 /* If we are in a class method, we must retrieve the
7829 _metaclass_ for the current class, pointed at by
7830 the class's "isa" pointer. The following assumes that
7831 "isa" is the first ivar in a class (which it must be). */
7832 super_class
7833 = build_indirect_ref
7834 (build_c_cast (build_pointer_type (objc_class_type),
7835 super_class), "unary *");
7837 else
7839 add_class_reference (super_name);
7840 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7841 ? objc_get_class_decl : objc_get_meta_class_decl);
7842 assemble_external (super_class);
7843 super_class
7844 = build_function_call
7845 (super_class,
7846 build_tree_list
7847 (NULL_TREE,
7848 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7849 IDENTIFIER_POINTER (super_name))));
7852 super_expr
7853 = build_modify_expr (super_expr, NOP_EXPR,
7854 build_c_cast (TREE_TYPE (super_expr),
7855 super_class));
7858 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7860 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7861 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7863 return super_expr_list;
7865 else
7867 error ("[super ...] must appear in a method context");
7868 return error_mark_node;
7872 /* When exiting a scope, sever links to a 'super' declaration (if any)
7873 therein contained. */
7875 void
7876 objc_clear_super_receiver (void)
7878 if (objc_method_context
7879 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
7880 UOBJC_SUPER_decl = 0;
7881 UOBJC_SUPER_scope = 0;
7885 void
7886 objc_finish_method_definition (tree fndecl)
7888 /* We cannot validly inline ObjC methods, at least not without a language
7889 extension to declare that a method need not be dynamically
7890 dispatched, so suppress all thoughts of doing so. */
7891 DECL_INLINE (fndecl) = 0;
7892 DECL_UNINLINABLE (fndecl) = 1;
7894 #ifndef OBJCPLUS
7895 /* The C++ front-end will have called finish_function() for us. */
7896 finish_function ();
7897 #endif
7899 METHOD_ENCODING (objc_method_context)
7900 = encode_method_prototype (objc_method_context);
7902 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7903 since the optimizer may find "may be used before set" errors. */
7904 objc_method_context = NULL_TREE;
7907 #if 0
7909 lang_report_error_function (tree decl)
7911 if (objc_method_context)
7913 fprintf (stderr, "In method %qs\n",
7914 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7915 return 1;
7918 else
7919 return 0;
7921 #endif
7923 /* Given a tree DECL node, produce a printable description of it in the given
7924 buffer, overwriting the buffer. */
7926 static char *
7927 gen_declaration (tree decl)
7929 errbuf[0] = '\0';
7931 if (DECL_P (decl))
7933 gen_type_name_0 (TREE_TYPE (decl));
7935 if (DECL_NAME (decl))
7937 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
7938 strcat (errbuf, " ");
7940 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
7943 if (DECL_INITIAL (decl)
7944 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
7945 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
7946 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
7949 return errbuf;
7952 /* Given a tree TYPE node, produce a printable description of it in the given
7953 buffer, overwriting the buffer. */
7955 static char *
7956 gen_type_name_0 (tree type)
7958 tree orig = type, proto;
7960 if (TYPE_P (type) && TYPE_NAME (type))
7961 type = TYPE_NAME (type);
7962 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
7964 tree inner = TREE_TYPE (type);
7966 while (TREE_CODE (inner) == ARRAY_TYPE)
7967 inner = TREE_TYPE (inner);
7969 gen_type_name_0 (inner);
7971 if (!POINTER_TYPE_P (inner))
7972 strcat (errbuf, " ");
7974 if (POINTER_TYPE_P (type))
7975 strcat (errbuf, "*");
7976 else
7977 while (type != inner)
7979 strcat (errbuf, "[");
7981 if (TYPE_DOMAIN (type))
7983 char sz[20];
7985 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
7986 (TREE_INT_CST_LOW
7987 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
7988 strcat (errbuf, sz);
7991 strcat (errbuf, "]");
7992 type = TREE_TYPE (type);
7995 goto exit_function;
7998 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
7999 type = DECL_NAME (type);
8001 strcat (errbuf, IDENTIFIER_POINTER (type));
8003 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8004 if (objc_is_id (orig))
8005 orig = TREE_TYPE (orig);
8007 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8009 if (proto)
8011 strcat (errbuf, " <");
8013 while (proto) {
8014 strcat (errbuf,
8015 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8016 proto = TREE_CHAIN (proto);
8017 strcat (errbuf, proto ? ", " : ">");
8021 exit_function:
8022 return errbuf;
8025 static char *
8026 gen_type_name (tree type)
8028 errbuf[0] = '\0';
8030 return gen_type_name_0 (type);
8033 /* Given a method tree, put a printable description into the given
8034 buffer (overwriting) and return a pointer to the buffer. */
8036 static char *
8037 gen_method_decl (tree method)
8039 tree chain;
8041 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8042 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8043 strcat (errbuf, ")");
8044 chain = METHOD_SEL_ARGS (method);
8046 if (chain)
8048 /* We have a chain of keyword_decls. */
8051 if (KEYWORD_KEY_NAME (chain))
8052 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8054 strcat (errbuf, ":(");
8055 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8056 strcat (errbuf, ")");
8058 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8059 if ((chain = TREE_CHAIN (chain)))
8060 strcat (errbuf, " ");
8062 while (chain);
8064 if (METHOD_ADD_ARGS (method))
8066 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8068 /* Know we have a chain of parm_decls. */
8069 while (chain)
8071 strcat (errbuf, ", ");
8072 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8073 chain = TREE_CHAIN (chain);
8076 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
8077 strcat (errbuf, ", ...");
8081 else
8082 /* We have a unary selector. */
8083 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8085 return errbuf;
8088 /* Debug info. */
8091 /* Dump an @interface declaration of the supplied class CHAIN to the
8092 supplied file FP. Used to implement the -gen-decls option (which
8093 prints out an @interface declaration of all classes compiled in
8094 this run); potentially useful for debugging the compiler too. */
8095 static void
8096 dump_interface (FILE *fp, tree chain)
8098 /* FIXME: A heap overflow here whenever a method (or ivar)
8099 declaration is so long that it doesn't fit in the buffer. The
8100 code and all the related functions should be rewritten to avoid
8101 using fixed size buffers. */
8102 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8103 tree ivar_decls = CLASS_RAW_IVARS (chain);
8104 tree nst_methods = CLASS_NST_METHODS (chain);
8105 tree cls_methods = CLASS_CLS_METHODS (chain);
8107 fprintf (fp, "\n@interface %s", my_name);
8109 /* CLASS_SUPER_NAME is used to store the superclass name for
8110 classes, and the category name for categories. */
8111 if (CLASS_SUPER_NAME (chain))
8113 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8115 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8116 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8118 fprintf (fp, " (%s)\n", name);
8120 else
8122 fprintf (fp, " : %s\n", name);
8125 else
8126 fprintf (fp, "\n");
8128 /* FIXME - the following doesn't seem to work at the moment. */
8129 if (ivar_decls)
8131 fprintf (fp, "{\n");
8134 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
8135 ivar_decls = TREE_CHAIN (ivar_decls);
8137 while (ivar_decls);
8138 fprintf (fp, "}\n");
8141 while (nst_methods)
8143 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
8144 nst_methods = TREE_CHAIN (nst_methods);
8147 while (cls_methods)
8149 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
8150 cls_methods = TREE_CHAIN (cls_methods);
8153 fprintf (fp, "@end\n");
8156 /* Demangle function for Objective-C */
8157 static const char *
8158 objc_demangle (const char *mangled)
8160 char *demangled, *cp;
8162 if (mangled[0] == '_' &&
8163 (mangled[1] == 'i' || mangled[1] == 'c') &&
8164 mangled[2] == '_')
8166 cp = demangled = xmalloc(strlen(mangled) + 2);
8167 if (mangled[1] == 'i')
8168 *cp++ = '-'; /* for instance method */
8169 else
8170 *cp++ = '+'; /* for class method */
8171 *cp++ = '['; /* opening left brace */
8172 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8173 while (*cp && *cp == '_')
8174 cp++; /* skip any initial underbars in class name */
8175 cp = strchr(cp, '_'); /* find first non-initial underbar */
8176 if (cp == NULL)
8178 free(demangled); /* not mangled name */
8179 return mangled;
8181 if (cp[1] == '_') /* easy case: no category name */
8183 *cp++ = ' '; /* replace two '_' with one ' ' */
8184 strcpy(cp, mangled + (cp - demangled) + 2);
8186 else
8188 *cp++ = '('; /* less easy case: category name */
8189 cp = strchr(cp, '_');
8190 if (cp == 0)
8192 free(demangled); /* not mangled name */
8193 return mangled;
8195 *cp++ = ')';
8196 *cp++ = ' '; /* overwriting 1st char of method name... */
8197 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8199 while (*cp && *cp == '_')
8200 cp++; /* skip any initial underbars in method name */
8201 for (; *cp; cp++)
8202 if (*cp == '_')
8203 *cp = ':'; /* replace remaining '_' with ':' */
8204 *cp++ = ']'; /* closing right brace */
8205 *cp++ = 0; /* string terminator */
8206 return demangled;
8208 else
8209 return mangled; /* not an objc mangled name */
8212 const char *
8213 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8215 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8218 static void
8219 init_objc (void)
8221 gcc_obstack_init (&util_obstack);
8222 util_firstobj = (char *) obstack_finish (&util_obstack);
8224 errbuf = (char *) xmalloc (1024 * 10);
8225 hash_init ();
8226 synth_module_prologue ();
8229 static void
8230 finish_objc (void)
8232 struct imp_entry *impent;
8233 tree chain;
8234 /* The internally generated initializers appear to have missing braces.
8235 Don't warn about this. */
8236 int save_warn_missing_braces = warn_missing_braces;
8237 warn_missing_braces = 0;
8239 /* A missing @end may not be detected by the parser. */
8240 if (objc_implementation_context)
8242 warning ("%<@end%> missing in implementation context");
8243 finish_class (objc_implementation_context);
8244 objc_ivar_chain = NULL_TREE;
8245 objc_implementation_context = NULL_TREE;
8248 /* Process the static instances here because initialization of objc_symtab
8249 depends on them. */
8250 if (objc_static_instances)
8251 generate_static_references ();
8253 if (imp_list || class_names_chain
8254 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8255 generate_objc_symtab_decl ();
8257 for (impent = imp_list; impent; impent = impent->next)
8259 objc_implementation_context = impent->imp_context;
8260 implementation_template = impent->imp_template;
8262 UOBJC_CLASS_decl = impent->class_decl;
8263 UOBJC_METACLASS_decl = impent->meta_decl;
8265 /* Dump the @interface of each class as we compile it, if the
8266 -gen-decls option is in use. TODO: Dump the classes in the
8267 order they were found, rather than in reverse order as we
8268 are doing now. */
8269 if (flag_gen_declaration)
8271 dump_interface (gen_declaration_file, objc_implementation_context);
8274 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8276 /* all of the following reference the string pool... */
8277 generate_ivar_lists ();
8278 generate_dispatch_tables ();
8279 generate_shared_structures ();
8281 else
8283 generate_dispatch_tables ();
8284 generate_category (objc_implementation_context);
8288 /* If we are using an array of selectors, we must always
8289 finish up the array decl even if no selectors were used. */
8290 if (! flag_next_runtime || sel_ref_chain)
8291 build_selector_translation_table ();
8293 if (protocol_chain)
8294 generate_protocols ();
8296 if (flag_replace_objc_classes && imp_list)
8297 generate_objc_image_info ();
8299 /* Arrange for ObjC data structures to be initialized at run time. */
8300 if (objc_implementation_context || class_names_chain || objc_static_instances
8301 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8303 build_module_descriptor ();
8305 if (!flag_next_runtime)
8306 build_module_initializer_routine ();
8309 /* Dump the class references. This forces the appropriate classes
8310 to be linked into the executable image, preserving unix archive
8311 semantics. This can be removed when we move to a more dynamically
8312 linked environment. */
8314 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8316 handle_class_ref (chain);
8317 if (TREE_PURPOSE (chain))
8318 generate_classref_translation_entry (chain);
8321 for (impent = imp_list; impent; impent = impent->next)
8322 handle_impent (impent);
8324 /* Dump the string table last. */
8326 generate_strings ();
8328 if (warn_selector)
8330 int slot;
8331 hash hsh;
8333 /* Run through the selector hash tables and print a warning for any
8334 selector which has multiple methods. */
8336 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8338 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8339 check_duplicates (hsh, 0, 1);
8340 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8341 check_duplicates (hsh, 0, 1);
8345 warn_missing_braces = save_warn_missing_braces;
8348 /* Subroutines of finish_objc. */
8350 static void
8351 generate_classref_translation_entry (tree chain)
8353 tree expr, decl, type;
8355 decl = TREE_PURPOSE (chain);
8356 type = TREE_TYPE (decl);
8358 expr = add_objc_string (TREE_VALUE (chain), class_names);
8359 expr = convert (type, expr); /* cast! */
8361 /* The decl that is the one that we
8362 forward declared in build_class_reference. */
8363 finish_var_decl (decl, expr);
8364 return;
8367 static void
8368 handle_class_ref (tree chain)
8370 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8371 char *string = (char *) alloca (strlen (name) + 30);
8372 tree decl;
8373 tree exp;
8375 sprintf (string, "%sobjc_class_name_%s",
8376 (flag_next_runtime ? "." : "__"), name);
8378 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8379 if (flag_next_runtime)
8381 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8382 return;
8384 #endif
8386 /* Make a decl for this name, so we can use its address in a tree. */
8387 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8388 DECL_EXTERNAL (decl) = 1;
8389 TREE_PUBLIC (decl) = 1;
8391 pushdecl (decl);
8392 rest_of_decl_compilation (decl, 0, 0);
8394 /* Make a decl for the address. */
8395 sprintf (string, "%sobjc_class_ref_%s",
8396 (flag_next_runtime ? "." : "__"), name);
8397 exp = build1 (ADDR_EXPR, string_type_node, decl);
8398 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8399 DECL_INITIAL (decl) = exp;
8400 TREE_STATIC (decl) = 1;
8401 TREE_USED (decl) = 1;
8403 pushdecl (decl);
8404 rest_of_decl_compilation (decl, 0, 0);
8407 static void
8408 handle_impent (struct imp_entry *impent)
8410 char *string;
8412 objc_implementation_context = impent->imp_context;
8413 implementation_template = impent->imp_template;
8415 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8417 const char *const class_name =
8418 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8420 string = (char *) alloca (strlen (class_name) + 30);
8422 sprintf (string, "%sobjc_class_name_%s",
8423 (flag_next_runtime ? "." : "__"), class_name);
8425 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8427 const char *const class_name =
8428 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8429 const char *const class_super_name =
8430 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8432 string = (char *) alloca (strlen (class_name)
8433 + strlen (class_super_name) + 30);
8435 /* Do the same for categories. Even though no references to
8436 these symbols are generated automatically by the compiler, it
8437 gives you a handle to pull them into an archive by hand. */
8438 sprintf (string, "*%sobjc_category_name_%s_%s",
8439 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8441 else
8442 return;
8444 #ifdef ASM_DECLARE_CLASS_REFERENCE
8445 if (flag_next_runtime)
8447 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8448 return;
8450 else
8451 #endif
8453 tree decl, init;
8455 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
8456 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8457 TREE_PUBLIC (decl) = 1;
8458 TREE_READONLY (decl) = 1;
8459 TREE_USED (decl) = 1;
8460 TREE_CONSTANT (decl) = 1;
8461 DECL_CONTEXT (decl) = 0;
8462 DECL_ARTIFICIAL (decl) = 1;
8463 DECL_INITIAL (decl) = init;
8464 assemble_variable (decl, 1, 0, 0);
8468 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
8469 later requires that ObjC translation units participating in F&C be
8470 specially marked. The following routine accomplishes this. */
8472 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
8474 static void
8475 generate_objc_image_info (void)
8477 tree decl, initlist;
8479 decl = start_var_decl (build_array_type
8480 (integer_type_node,
8481 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
8482 "_OBJC_IMAGE_INFO");
8484 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
8485 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 1), initlist);
8486 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
8488 finish_var_decl (decl, initlist);
8491 /* Look up ID as an instance variable. OTHER contains the result of
8492 the C or C++ lookup, which we may want to use instead. */
8494 tree
8495 objc_lookup_ivar (tree other, tree id)
8497 tree ivar;
8499 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
8500 if (!objc_method_context)
8501 return other;
8503 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
8504 /* We have a message to super. */
8505 return get_super_receiver ();
8507 /* In a class method, look up an instance variable only as a last
8508 resort. */
8509 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
8510 && other && other != error_mark_node)
8511 return other;
8513 /* Look up the ivar, but do not use it if it is not accessible. */
8514 ivar = is_ivar (objc_ivar_chain, id);
8516 if (!ivar || is_private (ivar))
8517 return other;
8519 /* In an instance method, a local variable (or parameter) may hide the
8520 instance variable. */
8521 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8522 && other && other != error_mark_node && !DECL_FILE_SCOPE_P (other))
8524 warning ("local declaration of %qs hides instance variable",
8525 IDENTIFIER_POINTER (id));
8527 return other;
8530 /* At this point, we are either in an instance method with no obscuring
8531 local definitions, or in a class method with no alternate definitions
8532 at all. */
8533 return build_ivar_reference (id);
8536 #include "gt-objc-objc-act.h"