* config/arm/symbian.h (STARTFILE_SPEC): Remove crt*.o.
[official-gcc.git] / gcc / objc / objc-act.c
blobe09e7a3e8cde444b2166e5154adc39d11cbb5ea5
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 "flags.h"
59 #include "langhooks.h"
60 #include "objc-act.h"
61 #include "input.h"
62 #include "except.h"
63 #include "function.h"
64 #include "output.h"
65 #include "toplev.h"
66 #include "ggc.h"
67 #include "varray.h"
68 #include "debug.h"
69 #include "target.h"
70 #include "diagnostic.h"
71 #include "cgraph.h"
72 #include "tree-iterator.h"
73 #include "libfuncs.h"
74 #include "hashtab.h"
76 #define OBJC_VOID_AT_END void_list_node
78 /* When building Objective-C++, we are not linking against the C front-end
79 and so need to replicate the C tree-construction functions in some way. */
80 #ifdef OBJCPLUS
81 #define OBJCP_REMAP_FUNCTIONS
82 #include "objcp-decl.h"
83 #endif /* OBJCPLUS */
85 /* This is the default way of generating a method name. */
86 /* I am not sure it is really correct.
87 Perhaps there's a danger that it will make name conflicts
88 if method names contain underscores. -- rms. */
89 #ifndef OBJC_GEN_METHOD_LABEL
90 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
91 do { \
92 char *temp; \
93 sprintf ((BUF), "_%s_%s_%s_%s", \
94 ((IS_INST) ? "i" : "c"), \
95 (CLASS_NAME), \
96 ((CAT_NAME)? (CAT_NAME) : ""), \
97 (SEL_NAME)); \
98 for (temp = (BUF); *temp; temp++) \
99 if (*temp == ':') *temp = '_'; \
100 } while (0)
101 #endif
103 /* These need specifying. */
104 #ifndef OBJC_FORWARDING_STACK_OFFSET
105 #define OBJC_FORWARDING_STACK_OFFSET 0
106 #endif
108 #ifndef OBJC_FORWARDING_MIN_OFFSET
109 #define OBJC_FORWARDING_MIN_OFFSET 0
110 #endif
112 /* Set up for use of obstacks. */
114 #include "obstack.h"
116 /* This obstack is used to accumulate the encoding of a data type. */
117 static struct obstack util_obstack;
119 /* This points to the beginning of obstack contents, so we can free
120 the whole contents. */
121 char *util_firstobj;
123 /* The version identifies which language generation and runtime
124 the module (file) was compiled for, and is recorded in the
125 module descriptor. */
127 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
128 #define PROTOCOL_VERSION 2
130 /* (Decide if these can ever be validly changed.) */
131 #define OBJC_ENCODE_INLINE_DEFS 0
132 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
134 /*** Private Interface (procedures) ***/
136 /* Used by compile_file. */
138 static void init_objc (void);
139 static void finish_objc (void);
141 /* Code generation. */
143 static void synth_module_prologue (void);
144 static tree objc_build_constructor (tree, tree);
145 static void build_module_descriptor (void);
146 static void build_module_initializer_routine (void);
147 static tree init_module_descriptor (tree);
148 static tree build_objc_method_call (int, tree, tree, tree, tree);
149 static void generate_strings (void);
150 static tree get_proto_encoding (tree);
151 static void build_selector_translation_table (void);
152 static tree lookup_interface (tree);
153 static tree objc_add_static_instance (tree, tree);
155 static tree start_class (enum tree_code, tree, tree, tree);
156 static tree continue_class (tree);
157 static void finish_class (tree);
158 static void start_method_def (tree);
159 #ifdef OBJCPLUS
160 static void objc_start_function (tree, tree, tree, tree);
161 #else
162 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
163 #endif
164 static tree start_protocol (enum tree_code, tree, tree);
165 static tree build_method_decl (enum tree_code, tree, tree, tree);
166 static tree objc_add_method (tree, tree, int);
167 static tree add_instance_variable (tree, int, tree);
168 static tree build_ivar_reference (tree);
169 static tree is_ivar (tree, tree);
170 static int is_private (tree);
171 static tree get_super_receiver (void);
173 static void build_objc_exception_stuff (void);
174 static void build_next_objc_exception_stuff (void);
176 static tree build_ivar_template (void);
177 static tree build_method_template (void);
178 static tree build_private_template (tree);
179 static void build_class_template (void);
180 static void build_selector_template (void);
181 static void build_category_template (void);
182 static tree lookup_method_in_hash_lists (tree, int);
183 static void build_super_template (void);
184 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
185 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
186 static void synth_forward_declarations (void);
187 static int ivar_list_length (tree);
188 static tree get_class_ivars (tree);
189 static void generate_ivar_lists (void);
190 static void generate_dispatch_tables (void);
191 static void generate_shared_structures (void);
192 static tree generate_protocol_list (tree);
193 static void build_protocol_reference (tree);
195 static tree build_keyword_selector (tree);
196 static const char *synth_id_with_class_suffix (const char *, tree);
198 static void generate_static_references (void);
199 static int check_methods_accessible (tree, tree, int);
200 static void encode_aggregate_within (tree, int, int, int, int);
201 static const char *objc_demangle (const char *);
203 /* Hash tables to manage the global pool of method prototypes. */
205 hash *nst_method_hash_list = 0;
206 hash *cls_method_hash_list = 0;
208 static size_t hash_func (tree);
209 static void hash_init (void);
210 static void hash_enter (hash *, tree);
211 static hash hash_lookup (hash *, tree);
212 static void hash_add_attr (hash, tree);
213 static tree lookup_method (tree, tree);
214 static tree lookup_method_static (tree, tree, int);
215 static void add_method_to_hash_list (hash *, tree);
216 static tree add_class (tree);
217 static void add_category (tree, tree);
218 static inline tree lookup_category (tree, tree);
220 enum string_section
222 class_names, /* class, category, protocol, module names */
223 meth_var_names, /* method and variable names */
224 meth_var_types /* method and variable type descriptors */
227 static tree add_objc_string (tree, enum string_section);
228 static tree get_objc_string_decl (tree, enum string_section);
229 static tree build_objc_string_decl (enum string_section);
230 static tree build_selector_reference_decl (void);
231 static void build_selector_table_decl (void);
233 /* Protocol additions. */
235 static tree add_protocol (tree);
236 static tree lookup_protocol (tree);
237 static void check_protocol_recursively (tree, tree);
238 static tree lookup_and_install_protocols (tree);
240 /* Type encoding. */
242 static void encode_type_qualifiers (tree);
243 static void encode_pointer (tree, int, int);
244 static void encode_array (tree, int, int);
245 static void encode_aggregate (tree, int, int);
246 static void encode_next_bitfield (int);
247 static void encode_gnu_bitfield (int, tree, int);
248 static void encode_type (tree, int, int);
249 static void encode_field_decl (tree, int, int);
251 #ifdef OBJCPLUS
252 static void really_start_method (tree, tree);
253 #else
254 static void really_start_method (tree, struct c_arg_info *);
255 #endif
256 static int objc_types_are_equivalent (tree, tree);
257 static int comp_proto_with_proto (tree, tree);
258 static tree get_arg_type_list (tree, int, int);
259 static void objc_push_parm (tree);
260 #ifdef OBJCPLUS
261 static tree objc_get_parm_info (int);
262 #else
263 static struct c_arg_info *objc_get_parm_info (int);
264 #endif
265 static void synth_self_and_ucmd_args (void);
267 /* Utilities for debugging and error diagnostics. */
269 static void warn_with_method (const char *, int, tree);
270 static void error_with_ivar (const char *, tree);
271 static char *gen_type_name (tree);
272 static char *gen_type_name_0 (tree);
273 static char *gen_method_decl (tree);
274 static char *gen_declaration (tree);
275 static void dump_interface (FILE *, tree);
277 /* Everything else. */
279 static tree lookup_method_in_protocol_list (tree, tree, int);
280 static tree lookup_protocol_in_reflist (tree, tree);
281 static tree start_var_decl (tree, const char *);
282 static void finish_var_decl (tree, tree);
283 static tree create_field_decl (tree, const char *);
284 static tree setup_string_decl (void);
285 static int check_string_class_template (void);
286 static tree my_build_string (int, const char *);
287 static void build_objc_symtab_template (void);
288 static tree init_def_list (tree);
289 static tree init_objc_symtab (tree);
290 static tree build_metadata_decl (const char *, tree);
291 static void forward_declare_categories (void);
292 static void generate_objc_symtab_decl (void);
293 static tree build_selector (tree);
294 static tree build_typed_selector_reference (tree, tree);
295 static tree build_selector_reference (tree);
296 static tree build_class_reference_decl (void);
297 static void add_class_reference (tree);
298 static void build_protocol_template (void);
299 static tree build_descriptor_table_initializer (tree, tree);
300 static tree build_method_prototype_list_template (tree, int);
301 static tree build_method_prototype_template (void);
302 static tree objc_method_parm_type (tree);
303 static int objc_encoded_type_size (tree);
304 static tree encode_method_prototype (tree);
305 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
306 static void generate_method_descriptors (tree);
307 static void generate_protocol_references (tree);
308 static void generate_protocols (void);
309 static void check_ivars (tree, tree);
310 static tree build_ivar_list_template (tree, int);
311 static tree build_method_list_template (tree, int);
312 static tree build_ivar_list_initializer (tree, tree);
313 static tree generate_ivars_list (tree, const char *, int, tree);
314 static tree build_dispatch_table_initializer (tree, tree);
315 static tree generate_dispatch_table (tree, const char *, int, tree);
316 static tree build_shared_structure_initializer (tree, tree, tree, tree,
317 tree, int, tree, tree, tree);
318 static void generate_category (tree);
319 static tree adjust_type_for_id_default (tree);
320 static tree check_duplicates (hash, int, int);
321 static tree receiver_is_class_object (tree, int, int);
322 static int check_methods (tree, tree, int);
323 static int conforms_to_protocol (tree, tree);
324 static void check_protocol (tree, const char *, const char *);
325 static void check_protocols (tree, const char *, const char *);
326 static void generate_classref_translation_entry (tree);
327 static void handle_class_ref (tree);
328 static void generate_struct_by_value_array (void)
329 ATTRIBUTE_NORETURN;
330 static void mark_referenced_methods (void);
331 static void generate_objc_image_info (void);
333 /*** Private Interface (data) ***/
335 /* Reserved tag definitions. */
337 #define OBJECT_TYPEDEF_NAME "id"
338 #define CLASS_TYPEDEF_NAME "Class"
340 #define TAG_OBJECT "objc_object"
341 #define TAG_CLASS "objc_class"
342 #define TAG_SUPER "objc_super"
343 #define TAG_SELECTOR "objc_selector"
345 #define UTAG_CLASS "_objc_class"
346 #define UTAG_IVAR "_objc_ivar"
347 #define UTAG_IVAR_LIST "_objc_ivar_list"
348 #define UTAG_METHOD "_objc_method"
349 #define UTAG_METHOD_LIST "_objc_method_list"
350 #define UTAG_CATEGORY "_objc_category"
351 #define UTAG_MODULE "_objc_module"
352 #define UTAG_SYMTAB "_objc_symtab"
353 #define UTAG_SUPER "_objc_super"
354 #define UTAG_SELECTOR "_objc_selector"
356 #define UTAG_PROTOCOL "_objc_protocol"
357 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
358 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
360 /* Note that the string object global name is only needed for the
361 NeXT runtime. */
362 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
364 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
366 static const char *TAG_GETCLASS;
367 static const char *TAG_GETMETACLASS;
368 static const char *TAG_MSGSEND;
369 static const char *TAG_MSGSENDSUPER;
370 /* The NeXT Objective-C messenger may have two extra entry points, for use
371 when returning a structure. */
372 static const char *TAG_MSGSEND_STRET;
373 static const char *TAG_MSGSENDSUPER_STRET;
374 static const char *default_constant_string_class_name;
376 /* Runtime metadata flags. */
377 #define CLS_FACTORY 0x0001L
378 #define CLS_META 0x0002L
380 #define OBJC_MODIFIER_STATIC 0x00000001
381 #define OBJC_MODIFIER_FINAL 0x00000002
382 #define OBJC_MODIFIER_PUBLIC 0x00000004
383 #define OBJC_MODIFIER_PRIVATE 0x00000008
384 #define OBJC_MODIFIER_PROTECTED 0x00000010
385 #define OBJC_MODIFIER_NATIVE 0x00000020
386 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
387 #define OBJC_MODIFIER_ABSTRACT 0x00000080
388 #define OBJC_MODIFIER_VOLATILE 0x00000100
389 #define OBJC_MODIFIER_TRANSIENT 0x00000200
390 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
392 /* NeXT-specific tags. */
394 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
395 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
396 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
397 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
398 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
399 #define TAG_EXCEPTIONMATCH "objc_exception_match"
400 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
401 #define TAG_SYNCENTER "objc_sync_enter"
402 #define TAG_SYNCEXIT "objc_sync_exit"
403 #define TAG_SETJMP "_setjmp"
404 #define UTAG_EXCDATA "_objc_exception_data"
406 /* GNU-specific tags. */
408 #define TAG_EXECCLASS "__objc_exec_class"
409 #define TAG_GNUINIT "__objc_gnu_init"
411 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
412 tree objc_global_trees[OCTI_MAX];
414 static void handle_impent (struct imp_entry *);
416 struct imp_entry *imp_list = 0;
417 int imp_count = 0; /* `@implementation' */
418 int cat_count = 0; /* `@category' */
420 enum tree_code objc_inherit_code;
421 int objc_public_flag;
423 /* Use to generate method labels. */
424 static int method_slot = 0;
426 #define BUFSIZE 1024
428 static char *errbuf; /* Buffer for error diagnostics */
430 /* Data imported from tree.c. */
432 extern enum debug_info_type write_symbols;
434 /* Data imported from toplev.c. */
436 extern const char *dump_base_name;
438 static int flag_typed_selectors;
440 /* Store all constructed constant strings in a hash table so that
441 they get uniqued properly. */
443 struct string_descriptor GTY(())
445 /* The literal argument . */
446 tree literal;
448 /* The resulting constant string. */
449 tree constructor;
452 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
454 static hashval_t string_hash (const void *);
455 static int string_eq (const void *, const void *);
457 FILE *gen_declaration_file;
459 /* Tells "encode_pointer/encode_aggregate" whether we are generating
460 type descriptors for instance variables (as opposed to methods).
461 Type descriptors for instance variables contain more information
462 than methods (for static typing and embedded structures). */
464 static int generating_instance_variables = 0;
466 /* Some platforms pass small structures through registers versus
467 through an invisible pointer. Determine at what size structure is
468 the transition point between the two possibilities. */
470 static void
471 generate_struct_by_value_array (void)
473 tree type;
474 tree field_decl, field_decl_chain;
475 int i, j;
476 int aggregate_in_mem[32];
477 int found = 0;
479 /* Presumably no platform passes 32 byte structures in a register. */
480 for (i = 1; i < 32; i++)
482 char buffer[5];
484 /* Create an unnamed struct that has `i' character components */
485 type = start_struct (RECORD_TYPE, NULL_TREE);
487 strcpy (buffer, "c1");
488 field_decl = create_field_decl (char_type_node,
489 buffer);
490 field_decl_chain = field_decl;
492 for (j = 1; j < i; j++)
494 sprintf (buffer, "c%d", j + 1);
495 field_decl = create_field_decl (char_type_node,
496 buffer);
497 chainon (field_decl_chain, field_decl);
499 finish_struct (type, field_decl_chain, NULL_TREE);
501 aggregate_in_mem[i] = aggregate_value_p (type, 0);
502 if (!aggregate_in_mem[i])
503 found = 1;
506 /* We found some structures that are returned in registers instead of memory
507 so output the necessary data. */
508 if (found)
510 for (i = 31; i >= 0; i--)
511 if (!aggregate_in_mem[i])
512 break;
513 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
515 /* The first member of the structure is always 0 because we don't handle
516 structures with 0 members */
517 printf ("static int struct_forward_array[] = {\n 0");
519 for (j = 1; j <= i; j++)
520 printf (", %d", aggregate_in_mem[j]);
521 printf ("\n};\n");
524 exit (0);
527 bool
528 objc_init (void)
530 #ifdef OBJCPLUS
531 if (cxx_init () == false)
532 #else
533 if (c_objc_common_init () == false)
534 #endif
535 return false;
537 #ifndef USE_MAPPED_LOCATION
538 /* Force the line number back to 0; check_newline will have
539 raised it to 1, which will make the builtin functions appear
540 not to be built in. */
541 input_line = 0;
542 #endif
544 /* If gen_declaration desired, open the output file. */
545 if (flag_gen_declaration)
547 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
548 gen_declaration_file = fopen (dumpname, "w");
549 if (gen_declaration_file == 0)
550 fatal_error ("can't open %s: %m", dumpname);
551 free (dumpname);
554 if (flag_next_runtime)
556 TAG_GETCLASS = "objc_getClass";
557 TAG_GETMETACLASS = "objc_getMetaClass";
558 TAG_MSGSEND = "objc_msgSend";
559 TAG_MSGSENDSUPER = "objc_msgSendSuper";
560 TAG_MSGSEND_STRET = "objc_msgSend_stret";
561 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
562 default_constant_string_class_name = "NSConstantString";
564 else
566 TAG_GETCLASS = "objc_get_class";
567 TAG_GETMETACLASS = "objc_get_meta_class";
568 TAG_MSGSEND = "objc_msg_lookup";
569 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
570 /* GNU runtime does not provide special functions to support
571 structure-returning methods. */
572 default_constant_string_class_name = "NXConstantString";
573 flag_typed_selectors = 1;
576 init_objc ();
578 if (print_struct_values)
579 generate_struct_by_value_array ();
581 return true;
584 void
585 objc_finish_file (void)
587 mark_referenced_methods ();
589 #ifdef OBJCPLUS
590 /* We need to instantiate templates _before_ we emit ObjC metadata;
591 if we do not, some metadata (such as selectors) may go missing. */
592 instantiate_pending_templates (0);
593 #endif
595 /* Finalize Objective-C runtime data. No need to generate tables
596 and code if only checking syntax. */
597 if (!flag_syntax_only)
598 finish_objc ();
600 if (gen_declaration_file)
601 fclose (gen_declaration_file);
603 #ifdef OBJCPLUS
604 cp_finish_file ();
605 #endif
608 /* Return the first occurrence of a method declaration corresponding
609 to sel_name in rproto_list. Search rproto_list recursively.
610 If is_class is 0, search for instance methods, otherwise for class
611 methods. */
612 static tree
613 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
614 int is_class)
616 tree rproto, p;
617 tree fnd = 0;
619 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
621 p = TREE_VALUE (rproto);
623 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
625 if ((fnd = lookup_method (is_class
626 ? PROTOCOL_CLS_METHODS (p)
627 : PROTOCOL_NST_METHODS (p), sel_name)))
629 else if (PROTOCOL_LIST (p))
630 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
631 sel_name, is_class);
633 else
635 ; /* An identifier...if we could not find a protocol. */
638 if (fnd)
639 return fnd;
642 return 0;
645 static tree
646 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
648 tree rproto, p;
650 /* Make sure the protocol is supported by the object on the rhs. */
651 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
653 tree fnd = 0;
654 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
656 p = TREE_VALUE (rproto);
658 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
660 if (lproto == p)
661 fnd = lproto;
663 else if (PROTOCOL_LIST (p))
664 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
667 if (fnd)
668 return fnd;
671 else
673 ; /* An identifier...if we could not find a protocol. */
676 return 0;
679 void
680 objc_start_class_interface (tree class, tree super_class, tree protos)
682 objc_interface_context
683 = objc_ivar_context
684 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
685 objc_public_flag = 0;
688 void
689 objc_start_category_interface (tree class, tree categ, tree protos)
691 objc_interface_context
692 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
693 objc_ivar_chain
694 = continue_class (objc_interface_context);
697 void
698 objc_start_protocol (tree name, tree protos)
700 objc_interface_context
701 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
704 void
705 objc_continue_interface (void)
707 objc_ivar_chain
708 = continue_class (objc_interface_context);
711 void
712 objc_finish_interface (void)
714 finish_class (objc_interface_context);
715 objc_interface_context = NULL_TREE;
718 void
719 objc_start_class_implementation (tree class, tree super_class)
721 objc_implementation_context
722 = objc_ivar_context
723 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
724 objc_public_flag = 0;
727 void
728 objc_start_category_implementation (tree class, tree categ)
730 objc_implementation_context
731 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
732 objc_ivar_chain
733 = continue_class (objc_implementation_context);
736 void
737 objc_continue_implementation (void)
739 objc_ivar_chain
740 = continue_class (objc_implementation_context);
743 void
744 objc_finish_implementation (void)
746 if (objc_implementation_context)
748 finish_class (objc_implementation_context);
749 objc_ivar_chain = NULL_TREE;
750 objc_implementation_context = NULL_TREE;
752 else
753 warning ("`@end' must appear in an @implementation context");
756 void
757 objc_set_visibility (int visibility)
759 objc_public_flag = visibility;
762 void
763 objc_set_method_type (enum tree_code type)
765 objc_inherit_code = (type == PLUS_EXPR
766 ? CLASS_METHOD_DECL
767 : INSTANCE_METHOD_DECL);
770 tree
771 objc_build_method_signature (tree rettype, tree selector, tree optparms)
773 return build_method_decl (objc_inherit_code, rettype, selector, optparms);
776 void
777 objc_add_method_declaration (tree decl)
779 if (!objc_interface_context)
780 fatal_error ("method declaration not in @interface context");
782 objc_add_method (objc_interface_context,
783 decl,
784 objc_inherit_code == CLASS_METHOD_DECL);
787 void
788 objc_start_method_definition (tree decl)
790 if (!objc_implementation_context)
791 fatal_error ("method definition not in @implementation context");
793 objc_add_method (objc_implementation_context,
794 decl,
795 objc_inherit_code == CLASS_METHOD_DECL);
796 start_method_def (decl);
799 void
800 objc_add_instance_variable (tree decl)
802 (void) add_instance_variable (objc_ivar_context,
803 objc_public_flag,
804 decl);
807 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
808 an '@'. */
811 objc_is_reserved_word (tree ident)
813 unsigned char code = C_RID_CODE (ident);
815 return (OBJC_IS_AT_KEYWORD (code)
816 #ifdef OBJCPLUS
817 || code == RID_CLASS || code == RID_PUBLIC
818 || code == RID_PROTECTED || code == RID_PRIVATE
819 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
820 #endif
824 /* Return true if TYPE is 'id'. */
826 static bool
827 objc_is_object_id (tree type)
829 return OBJC_TYPE_NAME (type) == objc_object_id;
832 static bool
833 objc_is_class_id (tree type)
835 return OBJC_TYPE_NAME (type) == objc_class_id;
838 /* Return 1 if LHS and RHS are compatible types for assignment or
839 various other operations. Return 0 if they are incompatible, and
840 return -1 if we choose to not decide (because the types are really
841 just C types, not ObjC specific ones). When the operation is
842 REFLEXIVE (typically comparisons), check for compatibility in
843 either direction; when it's not (typically assignments), don't.
845 This function is called in two cases: when both lhs and rhs are
846 pointers to records (in which case we check protocols too), and
847 when both lhs and rhs are records (in which case we check class
848 inheritance only).
850 Warnings about classes/protocols not implementing a protocol are
851 emitted here (multiple of those warnings might be emitted for a
852 single line!); generic warnings about incompatible assignments and
853 lacks of casts in comparisons are/must be emitted by the caller if
854 we return 0.
858 objc_comptypes (tree lhs, tree rhs, int reflexive)
860 /* New clause for protocols. */
862 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
863 manage the ObjC ones, and leave the rest to the C code. */
864 if (TREE_CODE (lhs) == POINTER_TYPE
865 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
866 && TREE_CODE (rhs) == POINTER_TYPE
867 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
869 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
870 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
872 if (lhs_is_proto)
874 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
875 tree rproto, rproto_list;
876 tree p;
878 /* <Protocol> = <Protocol> */
879 if (rhs_is_proto)
881 rproto_list = TYPE_PROTOCOL_LIST (rhs);
883 if (!reflexive)
885 /* An assignment between objects of type 'id
886 <Protocol>'; make sure the protocol on the lhs is
887 supported by the object on the rhs. */
888 for (lproto = lproto_list; lproto;
889 lproto = TREE_CHAIN (lproto))
891 p = TREE_VALUE (lproto);
892 rproto = lookup_protocol_in_reflist (rproto_list, p);
894 if (!rproto)
895 warning
896 ("object does not conform to the `%s' protocol",
897 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
899 return 1;
901 else
903 /* Obscure case - a comparison between two objects
904 of type 'id <Protocol>'. Check that either the
905 protocol on the lhs is supported by the object on
906 the rhs, or viceversa. */
908 /* Check if the protocol on the lhs is supported by the
909 object on the rhs. */
910 for (lproto = lproto_list; lproto;
911 lproto = TREE_CHAIN (lproto))
913 p = TREE_VALUE (lproto);
914 rproto = lookup_protocol_in_reflist (rproto_list, p);
916 if (!rproto)
918 /* Check failed - check if the protocol on the rhs
919 is supported by the object on the lhs. */
920 for (rproto = rproto_list; rproto;
921 rproto = TREE_CHAIN (rproto))
923 p = TREE_VALUE (rproto);
924 lproto = lookup_protocol_in_reflist (lproto_list,
927 if (!lproto)
929 /* This check failed too: incompatible */
930 return 0;
933 return 1;
936 return 1;
939 /* <Protocol> = <class> * */
940 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
942 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
943 tree rinter;
945 /* Make sure the protocol is supported by the object on
946 the rhs. */
947 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
949 p = TREE_VALUE (lproto);
950 rproto = 0;
951 rinter = lookup_interface (rname);
953 while (rinter && !rproto)
955 tree cat;
957 rproto_list = CLASS_PROTOCOL_LIST (rinter);
958 rproto = lookup_protocol_in_reflist (rproto_list, p);
959 /* If the underlying ObjC class does not have
960 the protocol we're looking for, check for "one-off"
961 protocols (e.g., `NSObject<MyProt> *foo;') attached
962 to the rhs. */
963 if (!rproto)
965 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
966 rproto = lookup_protocol_in_reflist (rproto_list, p);
969 /* Check for protocols adopted by categories. */
970 cat = CLASS_CATEGORY_LIST (rinter);
971 while (cat && !rproto)
973 rproto_list = CLASS_PROTOCOL_LIST (cat);
974 rproto = lookup_protocol_in_reflist (rproto_list, p);
975 cat = CLASS_CATEGORY_LIST (cat);
978 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
981 if (!rproto)
982 warning ("class `%s' does not implement the `%s' protocol",
983 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
984 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
986 return 1;
988 /* <Protocol> = id */
989 else if (objc_is_object_id (TREE_TYPE (rhs)))
991 return 1;
993 /* <Protocol> = Class */
994 else if (objc_is_class_id (TREE_TYPE (rhs)))
996 return 0;
998 /* <Protocol> = ?? : let comptypes decide. */
999 return -1;
1001 else if (rhs_is_proto)
1003 /* <class> * = <Protocol> */
1004 if (TYPED_OBJECT (TREE_TYPE (lhs)))
1006 if (reflexive)
1008 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
1009 tree rinter;
1010 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
1012 /* Make sure the protocol is supported by the object on
1013 the lhs. */
1014 for (rproto = rproto_list; rproto;
1015 rproto = TREE_CHAIN (rproto))
1017 tree p = TREE_VALUE (rproto);
1018 tree lproto = 0;
1019 rinter = lookup_interface (rname);
1021 while (rinter && !lproto)
1023 tree cat;
1025 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
1026 lproto = lookup_protocol_in_reflist (lproto_list, p);
1027 /* If the underlying ObjC class does not
1028 have the protocol we're looking for,
1029 check for "one-off" protocols (e.g.,
1030 `NSObject<MyProt> *foo;') attached to the
1031 lhs. */
1032 if (!lproto)
1034 lproto_list = TYPE_PROTOCOL_LIST
1035 (TREE_TYPE (lhs));
1036 lproto = lookup_protocol_in_reflist
1037 (lproto_list, p);
1040 /* Check for protocols adopted by categories. */
1041 cat = CLASS_CATEGORY_LIST (rinter);
1042 while (cat && !lproto)
1044 lproto_list = CLASS_PROTOCOL_LIST (cat);
1045 lproto = lookup_protocol_in_reflist (lproto_list,
1047 cat = CLASS_CATEGORY_LIST (cat);
1050 rinter = lookup_interface (CLASS_SUPER_NAME
1051 (rinter));
1054 if (!lproto)
1055 warning ("class `%s' does not implement the `%s' protocol",
1056 IDENTIFIER_POINTER (OBJC_TYPE_NAME
1057 (TREE_TYPE (lhs))),
1058 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1060 return 1;
1062 else
1063 return 0;
1065 /* id = <Protocol> */
1066 else if (objc_is_object_id (TREE_TYPE (lhs)))
1068 return 1;
1070 /* Class = <Protocol> */
1071 else if (objc_is_class_id (TREE_TYPE (lhs)))
1073 return 0;
1075 /* ??? = <Protocol> : let comptypes decide */
1076 else
1078 return -1;
1081 else
1083 /* Attention: we shouldn't defer to comptypes here. One bad
1084 side effect would be that we might loose the REFLEXIVE
1085 information.
1087 lhs = TREE_TYPE (lhs);
1088 rhs = TREE_TYPE (rhs);
1092 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
1094 /* Nothing to do with ObjC - let immediately comptypes take
1095 responsibility for checking. */
1096 return -1;
1099 /* `id' = `<class> *' `<class> *' = `id': always allow it.
1100 Please note that
1101 'Object *o = [[Object alloc] init]; falls
1102 in the case <class> * = `id'.
1104 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
1105 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
1106 return 1;
1108 /* `id' = `Class', `Class' = `id' */
1110 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
1111 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
1112 return 1;
1114 /* `Class' != `<class> *' && `<class> *' != `Class'! */
1115 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
1116 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
1117 return 0;
1119 /* `<class> *' = `<class> *' */
1121 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1123 tree lname = OBJC_TYPE_NAME (lhs);
1124 tree rname = OBJC_TYPE_NAME (rhs);
1125 tree inter;
1127 if (lname == rname)
1128 return 1;
1130 /* If the left hand side is a super class of the right hand side,
1131 allow it. */
1132 for (inter = lookup_interface (rname); inter;
1133 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1134 if (lname == CLASS_SUPER_NAME (inter))
1135 return 1;
1137 /* Allow the reverse when reflexive. */
1138 if (reflexive)
1139 for (inter = lookup_interface (lname); inter;
1140 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1141 if (rname == CLASS_SUPER_NAME (inter))
1142 return 1;
1144 return 0;
1146 else
1147 /* Not an ObjC type - let comptypes do the check. */
1148 return -1;
1151 /* Called from finish_decl. */
1153 void
1154 objc_check_decl (tree decl)
1156 tree type = TREE_TYPE (decl);
1158 if (TREE_CODE (type) != RECORD_TYPE)
1159 return;
1160 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1161 error ("statically allocated instance of Objective-C class `%s'",
1162 IDENTIFIER_POINTER (type));
1165 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1166 either name an Objective-C class, or refer to the special 'id' or 'Class'
1167 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1169 tree
1170 objc_get_protocol_qualified_type (tree interface, tree protocols)
1172 tree type;
1174 if (!interface)
1175 type = objc_object_type;
1176 else if (!(type = objc_is_id (interface)))
1178 type = objc_is_class_name (interface);
1180 if (type)
1181 type = xref_tag (RECORD_TYPE, type);
1182 else
1183 return interface;
1186 if (protocols)
1188 type = build_variant_type_copy (type);
1189 /* Look up protocols and install in lang specific list. Note
1190 that the protocol list can have a different lifetime than T! */
1191 SET_TYPE_PROTOCOL_LIST (type, lookup_and_install_protocols (protocols));
1193 /* Establish the ObjC-ness of this record. */
1194 if (TREE_CODE (type) == RECORD_TYPE)
1195 TREE_STATIC_TEMPLATE (type) = 1;
1198 return type;
1201 /* Check for circular dependencies in protocols. The arguments are
1202 PROTO, the protocol to check, and LIST, a list of protocol it
1203 conforms to. */
1205 static void
1206 check_protocol_recursively (tree proto, tree list)
1208 tree p;
1210 for (p = list; p; p = TREE_CHAIN (p))
1212 tree pp = TREE_VALUE (p);
1214 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1215 pp = lookup_protocol (pp);
1217 if (pp == proto)
1218 fatal_error ("protocol `%s' has circular dependency",
1219 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1220 if (pp)
1221 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1225 /* Look up PROTOCOLS, and return a list of those that are found.
1226 If none are found, return NULL. */
1228 static tree
1229 lookup_and_install_protocols (tree protocols)
1231 tree proto;
1232 tree return_value = NULL_TREE;
1234 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1236 tree ident = TREE_VALUE (proto);
1237 tree p = lookup_protocol (ident);
1239 if (!p)
1240 error ("cannot find protocol declaration for `%s'",
1241 IDENTIFIER_POINTER (ident));
1242 else
1243 return_value = chainon (return_value,
1244 build_tree_list (NULL_TREE, p));
1247 return return_value;
1250 /* Create a declaration for field NAME of a given TYPE. */
1252 static tree
1253 create_field_decl (tree type, const char *name)
1255 return build_decl (FIELD_DECL, get_identifier (name), type);
1258 /* Create a global, static declaration for variable NAME of a given TYPE. The
1259 finish_var_decl() routine will need to be called on it afterwards. */
1261 static tree
1262 start_var_decl (tree type, const char *name)
1264 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1266 TREE_STATIC (var) = 1;
1267 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1268 DECL_IGNORED_P (var) = 1;
1269 DECL_ARTIFICIAL (var) = 1;
1270 DECL_CONTEXT (var) = NULL_TREE;
1271 #ifdef OBJCPLUS
1272 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1273 #endif
1275 return var;
1278 /* Finish off the variable declaration created by start_var_decl(). */
1280 static void
1281 finish_var_decl (tree var, tree initializer)
1283 finish_decl (var, initializer, NULL_TREE);
1284 /* Ensure that the variable actually gets output. */
1285 mark_decl_referenced (var);
1286 /* Mark the decl to avoid "defined but not used" warning. */
1287 TREE_USED (var) = 1;
1290 /* Find the decl for the constant string class refernce. This is only
1291 used for the NeXT runtime. */
1293 static tree
1294 setup_string_decl (void)
1296 char *name;
1297 size_t length;
1299 /* %s in format will provide room for terminating null */
1300 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1301 + strlen (constant_string_class_name);
1302 name = xmalloc (length);
1303 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1304 constant_string_class_name);
1305 constant_string_global_id = get_identifier (name);
1306 string_class_decl = lookup_name (constant_string_global_id);
1308 return string_class_decl;
1311 /* Purpose: "play" parser, creating/installing representations
1312 of the declarations that are required by Objective-C.
1314 Model:
1316 type_spec--------->sc_spec
1317 (tree_list) (tree_list)
1320 identifier_node identifier_node */
1322 static void
1323 synth_module_prologue (void)
1325 tree type;
1326 enum debug_info_type save_write_symbols = write_symbols;
1327 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1329 /* Suppress outputting debug symbols, because
1330 dbxout_init hasn'r been called yet. */
1331 write_symbols = NO_DEBUG;
1332 debug_hooks = &do_nothing_debug_hooks;
1334 #ifdef OBJCPLUS
1335 push_lang_context (lang_name_c); /* extern "C" */
1336 #endif
1338 /* The following are also defined in <objc/objc.h> and friends. */
1340 objc_object_id = get_identifier (TAG_OBJECT);
1341 objc_class_id = get_identifier (TAG_CLASS);
1343 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1344 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1346 objc_object_type = build_pointer_type (objc_object_reference);
1347 objc_class_type = build_pointer_type (objc_class_reference);
1349 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1350 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1352 /* Declare the 'id' and 'Class' typedefs. */
1354 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1355 objc_object_name,
1356 objc_object_type));
1357 DECL_IN_SYSTEM_HEADER (type) = 1;
1358 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1359 objc_class_name,
1360 objc_class_type));
1361 DECL_IN_SYSTEM_HEADER (type) = 1;
1363 /* Forward-declare '@interface Protocol'. */
1365 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1366 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1367 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1368 type));
1370 /* Declare type of selector-objects that represent an operation name. */
1372 if (flag_next_runtime)
1373 /* `struct objc_selector *' */
1374 objc_selector_type
1375 = build_pointer_type (xref_tag (RECORD_TYPE,
1376 get_identifier (TAG_SELECTOR)));
1377 else
1378 /* `const struct objc_selector *' */
1379 objc_selector_type
1380 = build_pointer_type
1381 (build_qualified_type (xref_tag (RECORD_TYPE,
1382 get_identifier (TAG_SELECTOR)),
1383 TYPE_QUAL_CONST));
1385 /* Declare receiver type used for dispatching messages to 'super'. */
1387 /* `struct objc_super *' */
1388 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1389 get_identifier (TAG_SUPER)));
1391 if (flag_next_runtime)
1393 /* NB: In order to call one of the ..._stret (struct-returning)
1394 functions, the function *MUST* first be cast to a signature that
1395 corresponds to the actual ObjC method being invoked. This is
1396 what is done by the build_objc_method_call() routine below. */
1398 /* id objc_msgSend (id, SEL, ...); */
1399 /* id objc_msgSendNonNil (id, SEL, ...); */
1400 /* id objc_msgSend_stret (id, SEL, ...); */
1401 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1402 type
1403 = build_function_type (objc_object_type,
1404 tree_cons (NULL_TREE, objc_object_type,
1405 tree_cons (NULL_TREE, objc_selector_type,
1406 NULL_TREE)));
1407 umsg_decl = builtin_function (TAG_MSGSEND,
1408 type, 0, NOT_BUILT_IN,
1409 NULL, NULL_TREE);
1410 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1411 type, 0, NOT_BUILT_IN,
1412 NULL, NULL_TREE);
1413 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1414 type, 0, NOT_BUILT_IN,
1415 NULL, NULL_TREE);
1416 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1417 type, 0, NOT_BUILT_IN,
1418 NULL, NULL_TREE);
1420 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1421 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1422 type
1423 = build_function_type (objc_object_type,
1424 tree_cons (NULL_TREE, objc_super_type,
1425 tree_cons (NULL_TREE, objc_selector_type,
1426 NULL_TREE)));
1427 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1428 type, 0, NOT_BUILT_IN,
1429 NULL, NULL_TREE);
1430 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1431 type, 0, NOT_BUILT_IN, 0,
1432 NULL_TREE);
1434 else
1436 /* GNU runtime messenger entry points. */
1438 /* typedef id (*IMP)(id, SEL, ...); */
1439 tree IMP_type
1440 = build_pointer_type
1441 (build_function_type (objc_object_type,
1442 tree_cons (NULL_TREE, objc_object_type,
1443 tree_cons (NULL_TREE, objc_selector_type,
1444 NULL_TREE))));
1446 /* IMP objc_msg_lookup (id, SEL); */
1447 type
1448 = build_function_type (IMP_type,
1449 tree_cons (NULL_TREE, objc_object_type,
1450 tree_cons (NULL_TREE, objc_selector_type,
1451 OBJC_VOID_AT_END)));
1452 umsg_decl = builtin_function (TAG_MSGSEND,
1453 type, 0, NOT_BUILT_IN,
1454 NULL, NULL_TREE);
1456 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1457 type
1458 = build_function_type (IMP_type,
1459 tree_cons (NULL_TREE, objc_super_type,
1460 tree_cons (NULL_TREE, objc_selector_type,
1461 OBJC_VOID_AT_END)));
1462 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1463 type, 0, NOT_BUILT_IN,
1464 NULL, NULL_TREE);
1466 /* The following GNU runtime entry point is called to initialize
1467 each module:
1469 __objc_exec_class (void *); */
1470 type
1471 = build_function_type (void_type_node,
1472 tree_cons (NULL_TREE, ptr_type_node,
1473 OBJC_VOID_AT_END));
1474 execclass_decl = builtin_function (TAG_EXECCLASS,
1475 type, 0, NOT_BUILT_IN,
1476 NULL, NULL_TREE);
1479 /* id objc_getClass (const char *); */
1481 type = build_function_type (objc_object_type,
1482 tree_cons (NULL_TREE,
1483 const_string_type_node,
1484 OBJC_VOID_AT_END));
1486 objc_get_class_decl
1487 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1488 NULL, NULL_TREE);
1490 /* id objc_getMetaClass (const char *); */
1492 objc_get_meta_class_decl
1493 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1495 build_class_template ();
1496 build_super_template ();
1497 build_protocol_template ();
1498 build_category_template ();
1499 build_objc_exception_stuff ();
1501 if (flag_next_runtime)
1502 build_next_objc_exception_stuff ();
1504 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1506 if (! flag_next_runtime)
1507 build_selector_table_decl ();
1509 /* Forward declare constant_string_id and constant_string_type. */
1510 if (!constant_string_class_name)
1511 constant_string_class_name = default_constant_string_class_name;
1513 constant_string_id = get_identifier (constant_string_class_name);
1514 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1516 /* Pre-build the following entities - for speed/convenience. */
1517 self_id = get_identifier ("self");
1518 ucmd_id = get_identifier ("_cmd");
1519 #ifndef OBJCPLUS
1520 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1521 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1522 #endif
1524 #ifdef OBJCPLUS
1525 pop_lang_context ();
1526 #endif
1528 write_symbols = save_write_symbols;
1529 debug_hooks = save_hooks;
1532 /* Ensure that the ivar list for NSConstantString/NXConstantString
1533 (or whatever was specified via `-fconstant-string-class')
1534 contains fields at least as large as the following three, so that
1535 the runtime can stomp on them with confidence:
1537 struct STRING_OBJECT_CLASS_NAME
1539 Object isa;
1540 char *cString;
1541 unsigned int length;
1542 }; */
1544 static int
1545 check_string_class_template (void)
1547 tree field_decl = TYPE_FIELDS (constant_string_type);
1549 #define AT_LEAST_AS_LARGE_AS(F, T) \
1550 (F && TREE_CODE (F) == FIELD_DECL \
1551 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1552 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1554 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1555 return 0;
1557 field_decl = TREE_CHAIN (field_decl);
1558 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1559 return 0;
1561 field_decl = TREE_CHAIN (field_decl);
1562 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1564 #undef AT_LEAST_AS_LARGE_AS
1567 /* Avoid calling `check_string_class_template ()' more than once. */
1568 static GTY(()) int string_layout_checked;
1570 /* Custom build_string which sets TREE_TYPE! */
1572 static tree
1573 my_build_string (int len, const char *str)
1575 return fix_string_type (build_string (len, str));
1579 static hashval_t
1580 string_hash (const void *ptr)
1582 tree str = ((struct string_descriptor *)ptr)->literal;
1583 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1584 int i, len = TREE_STRING_LENGTH (str);
1585 hashval_t h = len;
1587 for (i = 0; i < len; i++)
1588 h = ((h * 613) + p[i]);
1590 return h;
1593 static int
1594 string_eq (const void *ptr1, const void *ptr2)
1596 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1597 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1598 int len1 = TREE_STRING_LENGTH (str1);
1600 return (len1 == TREE_STRING_LENGTH (str2)
1601 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1602 len1));
1605 /* Given a chain of STRING_CST's, build a static instance of
1606 NXConstantString which points at the concatenation of those
1607 strings. We place the string object in the __string_objects
1608 section of the __OBJC segment. The Objective-C runtime will
1609 initialize the isa pointers of the string objects to point at the
1610 NXConstantString class object. */
1612 tree
1613 objc_build_string_object (tree string)
1615 tree initlist, constructor, constant_string_class;
1616 int length;
1617 tree fields, addr;
1618 struct string_descriptor *desc, key;
1619 void **loc;
1621 /* Prep the string argument. */
1622 string = fix_string_type (string);
1623 TREE_SET_CODE (string, STRING_CST);
1624 length = TREE_STRING_LENGTH (string) - 1;
1626 /* Check whether the string class being used actually exists and has the
1627 correct ivar layout. */
1628 if (!string_layout_checked)
1630 string_layout_checked = -1;
1631 constant_string_class = lookup_interface (constant_string_id);
1633 if (!constant_string_class
1634 || !(constant_string_type
1635 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1636 error ("cannot find interface declaration for `%s'",
1637 IDENTIFIER_POINTER (constant_string_id));
1638 /* The NSConstantString/NXConstantString ivar layout is now known. */
1639 else if (!check_string_class_template ())
1640 error ("interface `%s' does not have valid constant string layout",
1641 IDENTIFIER_POINTER (constant_string_id));
1642 /* For the NeXT runtime, we can generate a literal reference
1643 to the string class, don't need to run a constructor. */
1644 else if (flag_next_runtime && !setup_string_decl ())
1645 error ("cannot find reference tag for class `%s'",
1646 IDENTIFIER_POINTER (constant_string_id));
1647 else
1649 string_layout_checked = 1; /* Success! */
1650 add_class_reference (constant_string_id);
1654 if (string_layout_checked == -1)
1655 return error_mark_node;
1657 /* Perhaps we already constructed a constant string just like this one? */
1658 key.literal = string;
1659 loc = htab_find_slot (string_htab, &key, INSERT);
1660 desc = *loc;
1662 if (!desc)
1664 *loc = desc = ggc_alloc (sizeof (*desc));
1665 desc->literal = string;
1667 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1668 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1669 fields = TYPE_FIELDS (constant_string_type);
1670 initlist
1671 = build_tree_list (fields,
1672 flag_next_runtime
1673 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1674 : build_int_cst (NULL_TREE, 0));
1675 fields = TREE_CHAIN (fields);
1676 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1677 initlist);
1678 fields = TREE_CHAIN (fields);
1679 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1680 initlist);
1681 constructor = objc_build_constructor (constant_string_type,
1682 nreverse (initlist));
1683 TREE_INVARIANT (constructor) = true;
1685 if (!flag_next_runtime)
1686 constructor
1687 = objc_add_static_instance (constructor, constant_string_type);
1689 desc->constructor = constructor;
1692 addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
1693 TREE_CONSTANT (addr) = true;
1694 TREE_INVARIANT (addr) = true;
1695 TREE_STATIC (addr) = true;
1697 return addr;
1700 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1702 static GTY(()) int num_static_inst;
1704 static tree
1705 objc_add_static_instance (tree constructor, tree class_decl)
1707 tree *chain, decl;
1708 char buf[256];
1710 /* Find the list of static instances for the CLASS_DECL. Create one if
1711 not found. */
1712 for (chain = &objc_static_instances;
1713 *chain && TREE_VALUE (*chain) != class_decl;
1714 chain = &TREE_CHAIN (*chain));
1715 if (!*chain)
1717 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1718 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1721 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1722 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1723 DECL_COMMON (decl) = 1;
1724 TREE_STATIC (decl) = 1;
1725 DECL_ARTIFICIAL (decl) = 1;
1726 DECL_INITIAL (decl) = constructor;
1728 /* We may be writing something else just now.
1729 Postpone till end of input. */
1730 DECL_DEFER_OUTPUT (decl) = 1;
1731 pushdecl_top_level (decl);
1732 rest_of_decl_compilation (decl, 1, 0);
1734 /* Add the DECL to the head of this CLASS' list. */
1735 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1737 return decl;
1740 /* Build a static constant CONSTRUCTOR
1741 with type TYPE and elements ELTS. */
1743 static tree
1744 objc_build_constructor (tree type, tree elts)
1746 tree constructor = build_constructor (type, elts);
1748 TREE_CONSTANT (constructor) = 1;
1749 TREE_STATIC (constructor) = 1;
1750 TREE_READONLY (constructor) = 1;
1752 #ifdef OBJCPLUS
1753 /* Adjust for impedance mismatch. We should figure out how to build
1754 CONSTRUCTORs that consistently please both the C and C++ gods. */
1755 if (!TREE_PURPOSE (elts))
1756 TREE_TYPE (constructor) = NULL_TREE;
1757 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1758 #endif
1760 return constructor;
1763 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1765 /* Predefine the following data type:
1767 struct _objc_symtab
1769 long sel_ref_cnt;
1770 SEL *refs;
1771 short cls_def_cnt;
1772 short cat_def_cnt;
1773 void *defs[cls_def_cnt + cat_def_cnt];
1774 }; */
1776 static void
1777 build_objc_symtab_template (void)
1779 tree field_decl, field_decl_chain;
1781 objc_symtab_template
1782 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1784 /* long sel_ref_cnt; */
1785 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
1786 field_decl_chain = field_decl;
1788 /* SEL *refs; */
1789 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
1790 "refs");
1791 chainon (field_decl_chain, field_decl);
1793 /* short cls_def_cnt; */
1794 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
1795 chainon (field_decl_chain, field_decl);
1797 /* short cat_def_cnt; */
1798 field_decl = create_field_decl (short_integer_type_node,
1799 "cat_def_cnt");
1800 chainon (field_decl_chain, field_decl);
1802 if (imp_count || cat_count || !flag_next_runtime)
1804 /* void *defs[imp_count + cat_count (+ 1)]; */
1805 /* NB: The index is one less than the size of the array. */
1806 int index = imp_count + cat_count
1807 + (flag_next_runtime? -1: 0);
1808 field_decl = create_field_decl
1809 (build_array_type
1810 (ptr_type_node,
1811 build_index_type (build_int_cst (NULL_TREE, index))),
1812 "defs");
1813 chainon (field_decl_chain, field_decl);
1816 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1819 /* Create the initial value for the `defs' field of _objc_symtab.
1820 This is a CONSTRUCTOR. */
1822 static tree
1823 init_def_list (tree type)
1825 tree expr, initlist = NULL_TREE;
1826 struct imp_entry *impent;
1828 if (imp_count)
1829 for (impent = imp_list; impent; impent = impent->next)
1831 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1833 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1834 initlist = tree_cons (NULL_TREE, expr, initlist);
1838 if (cat_count)
1839 for (impent = imp_list; impent; impent = impent->next)
1841 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1843 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1844 initlist = tree_cons (NULL_TREE, expr, initlist);
1848 if (!flag_next_runtime)
1850 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1851 tree expr;
1853 if (static_instances_decl)
1854 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1855 else
1856 expr = build_int_cst (NULL_TREE, 0);
1858 initlist = tree_cons (NULL_TREE, expr, initlist);
1861 return objc_build_constructor (type, nreverse (initlist));
1864 /* Construct the initial value for all of _objc_symtab. */
1866 static tree
1867 init_objc_symtab (tree type)
1869 tree initlist;
1871 /* sel_ref_cnt = { ..., 5, ... } */
1873 initlist = build_tree_list (NULL_TREE,
1874 build_int_cst (long_integer_type_node, 0));
1876 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1878 if (flag_next_runtime || ! sel_ref_chain)
1879 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
1880 else
1881 initlist
1882 = tree_cons (NULL_TREE,
1883 convert (build_pointer_type (objc_selector_type),
1884 build_unary_op (ADDR_EXPR,
1885 UOBJC_SELECTOR_TABLE_decl, 1)),
1886 initlist);
1888 /* cls_def_cnt = { ..., 5, ... } */
1890 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
1892 /* cat_def_cnt = { ..., 5, ... } */
1894 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
1896 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1898 if (imp_count || cat_count || !flag_next_runtime)
1901 tree field = TYPE_FIELDS (type);
1902 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1904 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1905 initlist);
1908 return objc_build_constructor (type, nreverse (initlist));
1911 /* Generate forward declarations for metadata such as
1912 'OBJC_CLASS_...'. */
1914 static tree
1915 build_metadata_decl (const char *name, tree type)
1917 tree decl;
1919 /* struct TYPE NAME_<name>; */
1920 decl = start_var_decl (type, synth_id_with_class_suffix
1921 (name,
1922 objc_implementation_context));
1924 return decl;
1927 /* Push forward-declarations of all the categories so that
1928 init_def_list can use them in a CONSTRUCTOR. */
1930 static void
1931 forward_declare_categories (void)
1933 struct imp_entry *impent;
1934 tree sav = objc_implementation_context;
1936 for (impent = imp_list; impent; impent = impent->next)
1938 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1940 /* Set an invisible arg to synth_id_with_class_suffix. */
1941 objc_implementation_context = impent->imp_context;
1942 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1943 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1944 objc_category_template);
1947 objc_implementation_context = sav;
1950 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1951 and initialized appropriately. */
1953 static void
1954 generate_objc_symtab_decl (void)
1956 /* forward declare categories */
1957 if (cat_count)
1958 forward_declare_categories ();
1960 build_objc_symtab_template ();
1961 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
1962 finish_var_decl (UOBJC_SYMBOLS_decl,
1963 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
1966 static tree
1967 init_module_descriptor (tree type)
1969 tree initlist, expr;
1971 /* version = { 1, ... } */
1973 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
1974 initlist = build_tree_list (NULL_TREE, expr);
1976 /* size = { ..., sizeof (struct _objc_module), ... } */
1978 expr = convert (long_integer_type_node,
1979 size_in_bytes (objc_module_template));
1980 initlist = tree_cons (NULL_TREE, expr, initlist);
1982 /* name = { ..., "foo.m", ... } */
1984 expr = add_objc_string (get_identifier (input_filename), class_names);
1985 initlist = tree_cons (NULL_TREE, expr, initlist);
1987 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1989 if (UOBJC_SYMBOLS_decl)
1990 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1991 else
1992 expr = build_int_cst (NULL_TREE, 0);
1993 initlist = tree_cons (NULL_TREE, expr, initlist);
1995 return objc_build_constructor (type, nreverse (initlist));
1998 /* Write out the data structures to describe Objective C classes defined.
2000 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2002 static void
2003 build_module_descriptor (void)
2005 tree field_decl, field_decl_chain;
2007 #ifdef OBJCPLUS
2008 push_lang_context (lang_name_c); /* extern "C" */
2009 #endif
2011 objc_module_template
2012 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2014 /* long version; */
2015 field_decl = create_field_decl (long_integer_type_node, "version");
2016 field_decl_chain = field_decl;
2018 /* long size; */
2019 field_decl = create_field_decl (long_integer_type_node, "size");
2020 chainon (field_decl_chain, field_decl);
2022 /* char *name; */
2023 field_decl = create_field_decl (string_type_node, "name");
2024 chainon (field_decl_chain, field_decl);
2026 /* struct _objc_symtab *symtab; */
2027 field_decl
2028 = create_field_decl (build_pointer_type
2029 (xref_tag (RECORD_TYPE,
2030 get_identifier (UTAG_SYMTAB))),
2031 "symtab");
2032 chainon (field_decl_chain, field_decl);
2034 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2036 /* Create an instance of "_objc_module". */
2037 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2038 finish_var_decl (UOBJC_MODULES_decl,
2039 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2041 #ifdef OBJCPLUS
2042 pop_lang_context ();
2043 #endif
2046 /* The GNU runtime requires us to provide a static initializer function
2047 for each module:
2049 static void __objc_gnu_init (void) {
2050 __objc_exec_class (&L_OBJC_MODULES);
2051 } */
2053 static void
2054 build_module_initializer_routine (void)
2056 tree body;
2058 #ifdef OBJCPLUS
2059 push_lang_context (lang_name_c); /* extern "C" */
2060 #endif
2062 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2063 objc_start_function (get_identifier (TAG_GNUINIT),
2064 build_function_type (void_type_node,
2065 OBJC_VOID_AT_END),
2066 NULL_TREE, objc_get_parm_info (0));
2068 body = c_begin_compound_stmt (true);
2069 add_stmt (build_function_call
2070 (execclass_decl,
2071 build_tree_list
2072 (NULL_TREE,
2073 build_unary_op (ADDR_EXPR,
2074 UOBJC_MODULES_decl, 0))));
2075 add_stmt (c_end_compound_stmt (body, true));
2077 TREE_PUBLIC (current_function_decl) = 0;
2079 #ifndef OBJCPLUS
2080 /* For Objective-C++, we will need to call __objc_gnu_init
2081 from objc_generate_static_init_call() below. */
2082 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2083 #endif
2085 GNU_INIT_decl = current_function_decl;
2086 finish_function ();
2088 #ifdef OBJCPLUS
2089 pop_lang_context ();
2090 #endif
2093 #ifdef OBJCPLUS
2094 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2095 to be called by the module initializer routine. */
2098 objc_static_init_needed_p (void)
2100 return (GNU_INIT_decl != NULL_TREE);
2103 /* Generate a call to the __objc_gnu_init initializer function. */
2105 tree
2106 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2108 add_stmt (build_stmt (EXPR_STMT,
2109 build_function_call (GNU_INIT_decl, NULL_TREE)));
2111 return ctors;
2113 #endif /* OBJCPLUS */
2115 /* Return the DECL of the string IDENT in the SECTION. */
2117 static tree
2118 get_objc_string_decl (tree ident, enum string_section section)
2120 tree chain;
2122 if (section == class_names)
2123 chain = class_names_chain;
2124 else if (section == meth_var_names)
2125 chain = meth_var_names_chain;
2126 else if (section == meth_var_types)
2127 chain = meth_var_types_chain;
2128 else
2129 abort ();
2131 for (; chain != 0; chain = TREE_CHAIN (chain))
2132 if (TREE_VALUE (chain) == ident)
2133 return (TREE_PURPOSE (chain));
2135 abort ();
2136 return NULL_TREE;
2139 /* Output references to all statically allocated objects. Return the DECL
2140 for the array built. */
2142 static void
2143 generate_static_references (void)
2145 tree decls = NULL_TREE, expr = NULL_TREE;
2146 tree class_name, class, decl, initlist;
2147 tree cl_chain, in_chain, type
2148 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2149 int num_inst, num_class;
2150 char buf[256];
2152 if (flag_next_runtime)
2153 abort ();
2155 for (cl_chain = objc_static_instances, num_class = 0;
2156 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2158 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2159 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2161 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2162 decl = start_var_decl (type, buf);
2164 /* Output {class_name, ...}. */
2165 class = TREE_VALUE (cl_chain);
2166 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2167 initlist = build_tree_list (NULL_TREE,
2168 build_unary_op (ADDR_EXPR, class_name, 1));
2170 /* Output {..., instance, ...}. */
2171 for (in_chain = TREE_PURPOSE (cl_chain);
2172 in_chain; in_chain = TREE_CHAIN (in_chain))
2174 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2175 initlist = tree_cons (NULL_TREE, expr, initlist);
2178 /* Output {..., NULL}. */
2179 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2181 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2182 finish_var_decl (decl, expr);
2183 decls
2184 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2187 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2188 expr = objc_build_constructor (type, nreverse (decls));
2189 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2190 finish_var_decl (static_instances_decl, expr);
2193 /* Output all strings. */
2195 static void
2196 generate_strings (void)
2198 tree chain, string_expr;
2199 tree string, decl, type;
2201 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2203 string = TREE_VALUE (chain);
2204 decl = TREE_PURPOSE (chain);
2205 type = build_array_type
2206 (char_type_node,
2207 build_index_type
2208 (build_int_cst (NULL_TREE,
2209 IDENTIFIER_LENGTH (string))));
2210 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2211 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2212 IDENTIFIER_POINTER (string));
2213 finish_var_decl (decl, string_expr);
2216 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2218 string = TREE_VALUE (chain);
2219 decl = TREE_PURPOSE (chain);
2220 type = build_array_type
2221 (char_type_node,
2222 build_index_type
2223 (build_int_cst (NULL_TREE,
2224 IDENTIFIER_LENGTH (string))));
2225 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2226 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2227 IDENTIFIER_POINTER (string));
2228 finish_var_decl (decl, string_expr);
2231 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2233 string = TREE_VALUE (chain);
2234 decl = TREE_PURPOSE (chain);
2235 type = build_array_type
2236 (char_type_node,
2237 build_index_type
2238 (build_int_cst (NULL_TREE,
2239 IDENTIFIER_LENGTH (string))));
2240 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2241 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2242 IDENTIFIER_POINTER (string));
2243 finish_var_decl (decl, string_expr);
2247 static GTY(()) int selector_reference_idx;
2249 static tree
2250 build_selector_reference_decl (void)
2252 tree decl;
2253 char buf[256];
2255 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2256 decl = start_var_decl (objc_selector_type, buf);
2258 return decl;
2261 static void
2262 build_selector_table_decl (void)
2264 tree temp;
2266 if (flag_typed_selectors)
2268 build_selector_template ();
2269 temp = build_array_type (objc_selector_template, NULL_TREE);
2271 else
2272 temp = build_array_type (objc_selector_type, NULL_TREE);
2274 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2277 /* Just a handy wrapper for add_objc_string. */
2279 static tree
2280 build_selector (tree ident)
2282 return convert (objc_selector_type,
2283 add_objc_string (ident, meth_var_names));
2286 static void
2287 build_selector_translation_table (void)
2289 tree chain, initlist = NULL_TREE;
2290 int offset = 0;
2291 tree decl = NULL_TREE;
2293 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2295 tree expr;
2297 if (warn_selector && objc_implementation_context)
2299 tree method_chain;
2300 bool found = false;
2301 for (method_chain = meth_var_names_chain;
2302 method_chain;
2303 method_chain = TREE_CHAIN (method_chain))
2305 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2307 found = true;
2308 break;
2311 if (!found)
2312 warning ("%Jcreating selector for nonexistent method %qE",
2313 TREE_PURPOSE (chain), TREE_VALUE (chain));
2316 expr = build_selector (TREE_VALUE (chain));
2317 /* add one for the '\0' character */
2318 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2320 if (flag_next_runtime)
2322 decl = TREE_PURPOSE (chain);
2323 finish_var_decl (decl, expr);
2325 else
2327 if (flag_typed_selectors)
2329 tree eltlist = NULL_TREE;
2330 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2331 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2332 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2333 expr = objc_build_constructor (objc_selector_template,
2334 nreverse (eltlist));
2337 initlist = tree_cons (NULL_TREE, expr, initlist);
2341 if (! flag_next_runtime)
2343 /* Cause the selector table (previously forward-declared)
2344 to be actually output. */
2345 initlist = tree_cons (NULL_TREE,
2346 flag_typed_selectors
2347 ? objc_build_constructor
2348 (objc_selector_template,
2349 tree_cons (NULL_TREE,
2350 build_int_cst (NULL_TREE, 0),
2351 tree_cons (NULL_TREE,
2352 build_int_cst (NULL_TREE, 0),
2353 NULL_TREE)))
2354 : build_int_cst (NULL_TREE, 0), initlist);
2355 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2356 nreverse (initlist));
2357 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2361 static tree
2362 get_proto_encoding (tree proto)
2364 tree encoding;
2365 if (proto)
2367 if (! METHOD_ENCODING (proto))
2369 encoding = encode_method_prototype (proto);
2370 METHOD_ENCODING (proto) = encoding;
2372 else
2373 encoding = METHOD_ENCODING (proto);
2375 return add_objc_string (encoding, meth_var_types);
2377 else
2378 return build_int_cst (NULL_TREE, 0);
2381 /* sel_ref_chain is a list whose "value" fields will be instances of
2382 identifier_node that represent the selector. */
2384 static tree
2385 build_typed_selector_reference (tree ident, tree prototype)
2387 tree *chain = &sel_ref_chain;
2388 tree expr;
2389 int index = 0;
2391 while (*chain)
2393 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2394 goto return_at_index;
2396 index++;
2397 chain = &TREE_CHAIN (*chain);
2400 *chain = tree_cons (prototype, ident, NULL_TREE);
2402 return_at_index:
2403 expr = build_unary_op (ADDR_EXPR,
2404 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2405 build_int_cst (NULL_TREE, index)),
2407 return convert (objc_selector_type, expr);
2410 static tree
2411 build_selector_reference (tree ident)
2413 tree *chain = &sel_ref_chain;
2414 tree expr;
2415 int index = 0;
2417 while (*chain)
2419 if (TREE_VALUE (*chain) == ident)
2420 return (flag_next_runtime
2421 ? TREE_PURPOSE (*chain)
2422 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2423 build_int_cst (NULL_TREE, index)));
2425 index++;
2426 chain = &TREE_CHAIN (*chain);
2429 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2431 *chain = tree_cons (expr, ident, NULL_TREE);
2433 return (flag_next_runtime
2434 ? expr
2435 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2436 build_int_cst (NULL_TREE, index)));
2439 static GTY(()) int class_reference_idx;
2441 static tree
2442 build_class_reference_decl (void)
2444 tree decl;
2445 char buf[256];
2447 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2448 decl = start_var_decl (objc_class_type, buf);
2450 return decl;
2453 /* Create a class reference, but don't create a variable to reference
2454 it. */
2456 static void
2457 add_class_reference (tree ident)
2459 tree chain;
2461 if ((chain = cls_ref_chain))
2463 tree tail;
2466 if (ident == TREE_VALUE (chain))
2467 return;
2469 tail = chain;
2470 chain = TREE_CHAIN (chain);
2472 while (chain);
2474 /* Append to the end of the list */
2475 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2477 else
2478 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2481 /* Get a class reference, creating it if necessary. Also create the
2482 reference variable. */
2484 tree
2485 objc_get_class_reference (tree ident)
2487 tree orig_ident;
2489 #ifdef OBJCPLUS
2490 if (processing_template_decl)
2491 /* Must wait until template instantiation time. */
2492 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2493 if (TREE_CODE (ident) == TYPE_DECL)
2494 ident = DECL_NAME (ident);
2495 #endif
2496 orig_ident = ident;
2498 if (!(ident = objc_is_class_name (ident)))
2500 error ("`%s' is not an Objective-C class name or alias",
2501 IDENTIFIER_POINTER (orig_ident));
2502 return error_mark_node;
2505 if (flag_next_runtime && !flag_zero_link)
2507 tree *chain;
2508 tree decl;
2510 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2511 if (TREE_VALUE (*chain) == ident)
2513 if (! TREE_PURPOSE (*chain))
2514 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2516 return TREE_PURPOSE (*chain);
2519 decl = build_class_reference_decl ();
2520 *chain = tree_cons (decl, ident, NULL_TREE);
2521 return decl;
2523 else
2525 tree params;
2527 add_class_reference (ident);
2529 params = build_tree_list (NULL_TREE,
2530 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2531 IDENTIFIER_POINTER (ident)));
2533 assemble_external (objc_get_class_decl);
2534 return build_function_call (objc_get_class_decl, params);
2538 /* For each string section we have a chain which maps identifier nodes
2539 to decls for the strings. */
2541 static tree
2542 add_objc_string (tree ident, enum string_section section)
2544 tree *chain, decl;
2546 if (section == class_names)
2547 chain = &class_names_chain;
2548 else if (section == meth_var_names)
2549 chain = &meth_var_names_chain;
2550 else if (section == meth_var_types)
2551 chain = &meth_var_types_chain;
2552 else
2553 abort ();
2555 while (*chain)
2557 if (TREE_VALUE (*chain) == ident)
2558 return convert (string_type_node,
2559 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2561 chain = &TREE_CHAIN (*chain);
2564 decl = build_objc_string_decl (section);
2566 *chain = tree_cons (decl, ident, NULL_TREE);
2568 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2571 static GTY(()) int class_names_idx;
2572 static GTY(()) int meth_var_names_idx;
2573 static GTY(()) int meth_var_types_idx;
2575 static tree
2576 build_objc_string_decl (enum string_section section)
2578 tree decl, ident;
2579 char buf[256];
2581 if (section == class_names)
2582 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2583 else if (section == meth_var_names)
2584 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2585 else if (section == meth_var_types)
2586 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2588 ident = get_identifier (buf);
2590 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2591 DECL_EXTERNAL (decl) = 1;
2592 TREE_PUBLIC (decl) = 0;
2593 TREE_USED (decl) = 1;
2594 TREE_CONSTANT (decl) = 1;
2595 DECL_CONTEXT (decl) = 0;
2596 DECL_ARTIFICIAL (decl) = 1;
2597 #ifdef OBJCPLUS
2598 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2599 #endif
2601 make_decl_rtl (decl);
2602 pushdecl_top_level (decl);
2604 return decl;
2608 void
2609 objc_declare_alias (tree alias_ident, tree class_ident)
2611 tree underlying_class;
2613 #ifdef OBJCPLUS
2614 if (current_namespace != global_namespace) {
2615 error ("Objective-C declarations may only appear in global scope");
2617 #endif /* OBJCPLUS */
2619 if (!(underlying_class = objc_is_class_name (class_ident)))
2620 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2621 else if (objc_is_class_name (alias_ident))
2622 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2623 else
2624 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2627 void
2628 objc_declare_class (tree ident_list)
2630 tree list;
2631 #ifdef OBJCPLUS
2632 if (current_namespace != global_namespace) {
2633 error ("Objective-C declarations may only appear in global scope");
2635 #endif /* OBJCPLUS */
2637 for (list = ident_list; list; list = TREE_CHAIN (list))
2639 tree ident = TREE_VALUE (list);
2641 if (! objc_is_class_name (ident))
2643 tree record = lookup_name (ident);
2645 if (record && ! TREE_STATIC_TEMPLATE (record))
2647 error ("`%s' redeclared as different kind of symbol",
2648 IDENTIFIER_POINTER (ident));
2649 error ("%Jprevious declaration of '%D'",
2650 record, record);
2653 record = xref_tag (RECORD_TYPE, ident);
2654 TREE_STATIC_TEMPLATE (record) = 1;
2655 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2660 tree
2661 objc_is_class_name (tree ident)
2663 tree chain;
2665 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2666 && identifier_global_value (ident))
2667 ident = identifier_global_value (ident);
2668 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2669 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2671 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2672 ident = OBJC_TYPE_NAME (ident);
2673 #ifdef OBJCPLUS
2674 if (ident && TREE_CODE (ident) == TYPE_DECL)
2675 ident = DECL_NAME (ident);
2676 #endif
2677 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2678 return NULL_TREE;
2680 if (lookup_interface (ident))
2681 return ident;
2683 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2685 if (ident == TREE_VALUE (chain))
2686 return ident;
2689 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2691 if (ident == TREE_VALUE (chain))
2692 return TREE_PURPOSE (chain);
2695 return 0;
2698 /* Check whether TYPE is either 'id' or 'Class'. */
2700 tree
2701 objc_is_id (tree type)
2703 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2704 && identifier_global_value (type))
2705 type = identifier_global_value (type);
2707 if (type && TREE_CODE (type) == TYPE_DECL)
2708 type = TREE_TYPE (type);
2710 /* NB: This function may be called before the ObjC front-end has
2711 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2712 return (objc_object_type && type && (IS_ID (type) || IS_CLASS (type))
2713 ? type
2714 : NULL_TREE);
2717 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2718 class instance. This is needed by other parts of the compiler to
2719 handle ObjC types gracefully. */
2721 tree
2722 objc_is_object_ptr (tree type)
2724 tree ret;
2726 type = TYPE_MAIN_VARIANT (type);
2727 if (!POINTER_TYPE_P (type))
2728 return 0;
2730 ret = objc_is_id (type);
2731 if (!ret)
2732 ret = objc_is_class_name (TREE_TYPE (type));
2734 return ret;
2737 static tree
2738 lookup_interface (tree ident)
2740 tree chain;
2742 #ifdef OBJCPLUS
2743 if (ident && TREE_CODE (ident) == TYPE_DECL)
2744 ident = DECL_NAME (ident);
2745 #endif
2746 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2748 if (ident == CLASS_NAME (chain))
2749 return chain;
2751 return NULL_TREE;
2754 /* Implement @defs (<classname>) within struct bodies. */
2756 tree
2757 objc_get_class_ivars (tree class_name)
2759 tree interface = lookup_interface (class_name);
2761 if (interface)
2762 return get_class_ivars (interface);
2764 error ("cannot find interface declaration for `%s'",
2765 IDENTIFIER_POINTER (class_name));
2767 return error_mark_node;
2770 /* Used by: build_private_template, continue_class,
2771 and for @defs constructs. */
2773 static tree
2774 get_class_ivars (tree interface)
2776 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
2778 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
2779 by the current class (i.e., they do not include super-class ivars).
2780 However, the CLASS_IVARS list will be side-effected by a call to
2781 finish_struct(), which will fill in field offsets. */
2782 if (!CLASS_IVARS (interface))
2783 CLASS_IVARS (interface) = ivar_chain;
2785 while (CLASS_SUPER_NAME (interface))
2787 /* Prepend super-class ivars. */
2788 interface = lookup_interface (CLASS_SUPER_NAME (interface));
2789 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
2790 ivar_chain);
2793 return ivar_chain;
2796 static tree
2797 objc_create_temporary_var (tree type)
2799 tree decl;
2801 decl = build_decl (VAR_DECL, NULL_TREE, type);
2802 TREE_USED (decl) = 1;
2803 DECL_ARTIFICIAL (decl) = 1;
2804 DECL_IGNORED_P (decl) = 1;
2805 DECL_CONTEXT (decl) = current_function_decl;
2807 return decl;
2810 /* Exception handling constructs. We begin by having the parser do most
2811 of the work and passing us blocks. What we do next depends on whether
2812 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2813 We abstract all of this in a handful of appropriately named routines. */
2815 /* Stack of open try blocks. */
2817 struct objc_try_context
2819 struct objc_try_context *outer;
2821 /* Statements (or statement lists) as processed by the parser. */
2822 tree try_body;
2823 tree finally_body;
2825 /* Some file position locations. */
2826 location_t try_locus;
2827 location_t end_try_locus;
2828 location_t end_catch_locus;
2829 location_t finally_locus;
2830 location_t end_finally_locus;
2832 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2833 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2834 tree catch_list;
2836 /* The CATCH_EXPR of an open @catch clause. */
2837 tree current_catch;
2839 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2840 tree caught_decl;
2841 tree stack_decl;
2842 tree rethrow_decl;
2845 static struct objc_try_context *cur_try_context;
2847 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2848 that represents TYPE. For Objective-C, this is just the class name. */
2849 /* ??? Isn't there a class object or some such? Is it easy to get? */
2851 #ifndef OBJCPLUS
2852 static tree
2853 objc_eh_runtime_type (tree type)
2855 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
2857 #endif
2859 /* Initialize exception handling. */
2861 static void
2862 objc_init_exceptions (void)
2864 static bool done = false;
2865 if (done)
2866 return;
2867 done = true;
2869 if (flag_objc_sjlj_exceptions)
2871 /* On Darwin, ObjC exceptions require a sufficiently recent
2872 version of the runtime, so the user must ask for them explicitly. */
2873 if (!flag_objc_exceptions)
2874 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2875 "exception syntax");
2877 #ifndef OBJCPLUS
2878 else
2880 c_eh_initialized_p = true;
2881 eh_personality_libfunc
2882 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2883 ? "__gnu_objc_personality_sj0"
2884 : "__gnu_objc_personality_v0");
2885 using_eh_for_cleanups ();
2886 lang_eh_runtime_type = objc_eh_runtime_type;
2888 #endif
2891 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2892 we'll arrange for it to be initialized (and associated with a binding)
2893 later. */
2895 static tree
2896 objc_build_exc_ptr (void)
2898 if (flag_objc_sjlj_exceptions)
2900 tree var = cur_try_context->caught_decl;
2901 if (!var)
2903 var = objc_create_temporary_var (objc_object_type);
2904 cur_try_context->caught_decl = var;
2906 return var;
2908 else
2909 return build (EXC_PTR_EXPR, objc_object_type);
2912 /* Build "objc_exception_try_exit(&_stack)". */
2914 static tree
2915 next_sjlj_build_try_exit (void)
2917 tree t;
2918 t = build_fold_addr_expr (cur_try_context->stack_decl);
2919 t = tree_cons (NULL, t, NULL);
2920 t = build_function_call (objc_exception_try_exit_decl, t);
2921 return t;
2924 /* Build
2925 objc_exception_try_enter (&_stack);
2926 if (_setjmp(&_stack.buf))
2928 else
2930 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2931 empty, ready for the caller to fill them in. */
2933 static tree
2934 next_sjlj_build_enter_and_setjmp (void)
2936 tree t, enter, sj, cond;
2938 t = build_fold_addr_expr (cur_try_context->stack_decl);
2939 t = tree_cons (NULL, t, NULL);
2940 enter = build_function_call (objc_exception_try_enter_decl, t);
2942 t = build_component_ref (cur_try_context->stack_decl,
2943 get_identifier ("buf"));
2944 t = build_fold_addr_expr (t);
2945 t = convert (ptr_type_node, t);
2946 t = tree_cons (NULL, t, NULL);
2947 sj = build_function_call (objc_setjmp_decl, t);
2949 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
2950 cond = lang_hooks.truthvalue_conversion (cond);
2952 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
2955 /* Build
2956 DECL = objc_exception_extract(&_stack);
2959 static tree
2960 next_sjlj_build_exc_extract (tree decl)
2962 tree t;
2964 t = build_fold_addr_expr (cur_try_context->stack_decl);
2965 t = tree_cons (NULL, t, NULL);
2966 t = build_function_call (objc_exception_extract_decl, t);
2967 t = convert (TREE_TYPE (decl), t);
2968 t = build (MODIFY_EXPR, void_type_node, decl, t);
2970 return t;
2973 /* Build
2974 if (objc_exception_match(obj_get_class(TYPE), _caught)
2975 BODY
2976 else if (...)
2978 else
2980 _rethrow = _caught;
2981 objc_exception_try_exit(&_stack);
2983 from the sequence of CATCH_EXPRs in the current try context. */
2985 static tree
2986 next_sjlj_build_catch_list (void)
2988 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
2989 tree catch_seq, t;
2990 tree *last = &catch_seq;
2991 bool saw_id = false;
2993 for (; !tsi_end_p (i); tsi_next (&i))
2995 tree stmt = tsi_stmt (i);
2996 tree type = CATCH_TYPES (stmt);
2997 tree body = CATCH_BODY (stmt);
2999 if (type == NULL)
3001 *last = body;
3002 saw_id = true;
3003 break;
3005 else
3007 tree args, cond;
3009 if (type == error_mark_node)
3010 cond = error_mark_node;
3011 else
3013 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3014 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3015 args = tree_cons (NULL, t, args);
3016 t = build_function_call (objc_exception_match_decl, args);
3017 cond = lang_hooks.truthvalue_conversion (t);
3019 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3020 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3022 *last = t;
3023 last = &COND_EXPR_ELSE (t);
3027 if (!saw_id)
3029 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3030 cur_try_context->caught_decl);
3031 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3032 append_to_statement_list (t, last);
3034 t = next_sjlj_build_try_exit ();
3035 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3036 append_to_statement_list (t, last);
3039 return catch_seq;
3042 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3043 exception handling. We aim to build:
3046 struct _objc_exception_data _stack;
3047 id volatile _rethrow = 0;
3050 objc_exception_try_enter (&_stack);
3051 if (_setjmp(&_stack.buf))
3053 id _caught = objc_exception_extract(&_stack);
3054 objc_exception_try_enter (&_stack);
3055 if (_setjmp(&_stack.buf))
3056 _rethrow = objc_exception_extract(&_stack);
3057 else
3058 CATCH-LIST
3060 else
3061 TRY-BLOCK
3063 finally
3065 if (!_rethrow)
3066 objc_exception_try_exit(&_stack);
3067 FINALLY-BLOCK
3068 if (_rethrow)
3069 objc_exception_throw(_rethrow);
3073 If CATCH-LIST is empty, we can omit all of the block containing
3074 "_caught" except for the setting of _rethrow. Note the use of
3075 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3076 but handles goto and other exits from the block. */
3078 static tree
3079 next_sjlj_build_try_catch_finally (void)
3081 tree rethrow_decl, stack_decl, t;
3082 tree catch_seq, try_fin, bind;
3084 /* Create the declarations involved. */
3085 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3086 stack_decl = objc_create_temporary_var (t);
3087 cur_try_context->stack_decl = stack_decl;
3089 rethrow_decl = objc_create_temporary_var (objc_object_type);
3090 cur_try_context->rethrow_decl = rethrow_decl;
3091 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3092 TREE_CHAIN (rethrow_decl) = stack_decl;
3094 /* Build the outermost varible binding level. */
3095 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3096 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3097 TREE_SIDE_EFFECTS (bind) = 1;
3099 /* Initialize rethrow_decl. */
3100 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
3101 convert (objc_object_type, null_pointer_node));
3102 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3103 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3105 /* Build the outermost TRY_FINALLY_EXPR. */
3106 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3107 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3108 TREE_SIDE_EFFECTS (try_fin) = 1;
3109 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3111 /* Create the complete catch sequence. */
3112 if (cur_try_context->catch_list)
3114 tree caught_decl = objc_build_exc_ptr ();
3115 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3117 t = next_sjlj_build_exc_extract (caught_decl);
3118 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3120 t = next_sjlj_build_enter_and_setjmp ();
3121 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3122 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3123 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3125 else
3126 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3127 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3129 /* Build the main register-and-try if statement. */
3130 t = next_sjlj_build_enter_and_setjmp ();
3131 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3132 COND_EXPR_THEN (t) = catch_seq;
3133 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3134 TREE_OPERAND (try_fin, 0) = t;
3136 /* Build the complete FINALLY statement list. */
3137 t = next_sjlj_build_try_exit ();
3138 t = build_stmt (COND_EXPR,
3139 lang_hooks.truthvalue_conversion (rethrow_decl),
3140 NULL, t);
3141 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3142 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3144 append_to_statement_list (cur_try_context->finally_body,
3145 &TREE_OPERAND (try_fin, 1));
3147 t = tree_cons (NULL, rethrow_decl, NULL);
3148 t = build_function_call (objc_exception_throw_decl, t);
3149 t = build_stmt (COND_EXPR,
3150 lang_hooks.truthvalue_conversion (rethrow_decl),
3151 t, NULL);
3152 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3153 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3155 return bind;
3158 /* Called just after parsing the @try and its associated BODY. We now
3159 must prepare for the tricky bits -- handling the catches and finally. */
3161 void
3162 objc_begin_try_stmt (location_t try_locus, tree body)
3164 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3165 c->outer = cur_try_context;
3166 c->try_body = body;
3167 c->try_locus = try_locus;
3168 c->end_try_locus = input_location;
3169 cur_try_context = c;
3171 objc_init_exceptions ();
3174 /* Called just after parsing "@catch (parm)". Open a binding level,
3175 enter DECL into the binding level, and initialize it. Leave the
3176 binding level open while the body of the compound statement is parsed. */
3178 void
3179 objc_begin_catch_clause (tree decl)
3181 tree compound, type, t;
3183 /* Begin a new scope that the entire catch clause will live in. */
3184 compound = c_begin_compound_stmt (true);
3186 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3187 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3188 lang_hooks.decls.pushdecl (decl);
3190 /* Since a decl is required here by syntax, don't warn if its unused. */
3191 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3192 be what the previous objc implementation did. */
3193 TREE_USED (decl) = 1;
3195 /* Verify that the type of the catch is valid. It must be a pointer
3196 to an Objective-C class, or "id" (which is catch-all). */
3197 type = TREE_TYPE (decl);
3199 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3200 type = NULL;
3201 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3203 error ("@catch parameter is not a known Objective-C class type");
3204 type = error_mark_node;
3206 else if (cur_try_context->catch_list)
3208 /* Examine previous @catch clauses and see if we've already
3209 caught the type in question. */
3210 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3211 for (; !tsi_end_p (i); tsi_next (&i))
3213 tree stmt = tsi_stmt (i);
3214 t = CATCH_TYPES (stmt);
3215 if (t == error_mark_node)
3216 continue;
3217 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3219 warning ("exception of type %<%T%> will be caught",
3220 TREE_TYPE (type));
3221 warning ("%H by earlier handler for %<%T%>",
3222 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3223 break;
3228 /* Record the data for the catch in the try context so that we can
3229 finalize it later. */
3230 t = build_stmt (CATCH_EXPR, type, compound);
3231 cur_try_context->current_catch = t;
3233 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3234 t = objc_build_exc_ptr ();
3235 t = convert (TREE_TYPE (decl), t);
3236 t = build (MODIFY_EXPR, void_type_node, decl, t);
3237 add_stmt (t);
3240 /* Called just after parsing the closing brace of a @catch clause. Close
3241 the open binding level, and record a CATCH_EXPR for it. */
3243 void
3244 objc_finish_catch_clause (void)
3246 tree c = cur_try_context->current_catch;
3247 cur_try_context->current_catch = NULL;
3248 cur_try_context->end_catch_locus = input_location;
3250 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3251 append_to_statement_list (c, &cur_try_context->catch_list);
3254 /* Called after parsing a @finally clause and its associated BODY.
3255 Record the body for later placement. */
3257 void
3258 objc_build_finally_clause (location_t finally_locus, tree body)
3260 cur_try_context->finally_body = body;
3261 cur_try_context->finally_locus = finally_locus;
3262 cur_try_context->end_finally_locus = input_location;
3265 /* Called to finalize a @try construct. */
3267 void
3268 objc_finish_try_stmt (void)
3270 struct objc_try_context *c = cur_try_context;
3271 tree stmt;
3273 if (c->catch_list == NULL && c->finally_body == NULL)
3274 error ("`@try' without `@catch' or `@finally'");
3276 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3277 if (flag_objc_sjlj_exceptions)
3279 if (!cur_try_context->finally_body)
3281 cur_try_context->finally_locus = input_location;
3282 cur_try_context->end_finally_locus = input_location;
3284 stmt = next_sjlj_build_try_catch_finally ();
3286 else
3288 /* Otherwise, nest the CATCH inside a FINALLY. */
3289 stmt = c->try_body;
3290 if (c->catch_list)
3292 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3293 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3295 if (c->finally_body)
3297 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3298 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3301 add_stmt (stmt);
3303 cur_try_context = c->outer;
3304 free (c);
3307 tree
3308 objc_build_throw_stmt (tree throw_expr)
3310 tree args;
3312 objc_init_exceptions ();
3314 if (throw_expr == NULL)
3316 /* If we're not inside a @catch block, there is no "current
3317 exception" to be rethrown. */
3318 if (cur_try_context == NULL
3319 || cur_try_context->current_catch == NULL)
3321 error ("%<@throw%> (rethrow) used outside of a @catch block");
3322 return NULL_TREE;
3325 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3326 value that we get from the runtime. */
3327 throw_expr = objc_build_exc_ptr ();
3330 /* A throw is just a call to the runtime throw function with the
3331 object as a parameter. */
3332 args = tree_cons (NULL, throw_expr, NULL);
3333 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3336 void
3337 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3339 tree args, call;
3341 /* First lock the mutex. */
3342 mutex = save_expr (mutex);
3343 args = tree_cons (NULL, mutex, NULL);
3344 call = build_function_call (objc_sync_enter_decl, args);
3345 SET_EXPR_LOCATION (call, start_locus);
3346 add_stmt (call);
3348 /* Build the mutex unlock. */
3349 args = tree_cons (NULL, mutex, NULL);
3350 call = build_function_call (objc_sync_exit_decl, args);
3351 SET_EXPR_LOCATION (call, input_location);
3353 /* Put the that and the body in a TRY_FINALLY. */
3354 objc_begin_try_stmt (start_locus, body);
3355 objc_build_finally_clause (input_location, call);
3356 objc_finish_try_stmt ();
3360 /* Predefine the following data type:
3362 struct _objc_exception_data
3364 int buf[_JBLEN];
3365 void *pointers[4];
3366 }; */
3368 /* The following yuckiness should prevent users from having to #include
3369 <setjmp.h> in their code... */
3371 #ifdef TARGET_POWERPC
3372 /* snarfed from /usr/include/ppc/setjmp.h */
3373 #define _JBLEN (26 + 36 + 129 + 1)
3374 #else
3375 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3376 #define _JBLEN 18
3377 #endif
3379 static void
3380 build_next_objc_exception_stuff (void)
3382 tree field_decl, field_decl_chain, index, temp_type;
3384 objc_exception_data_template
3385 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3387 /* int buf[_JBLEN]; */
3389 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3390 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3391 "buf");
3392 field_decl_chain = field_decl;
3394 /* void *pointers[4]; */
3396 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3397 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3398 "pointers");
3399 chainon (field_decl_chain, field_decl);
3401 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3403 /* int _setjmp(...); */
3404 /* If the user includes <setjmp.h>, this shall be superseded by
3405 'int _setjmp(jmp_buf);' */
3406 temp_type = build_function_type (integer_type_node, NULL_TREE);
3407 objc_setjmp_decl
3408 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3410 /* id objc_exception_extract(struct _objc_exception_data *); */
3411 temp_type
3412 = build_function_type (objc_object_type,
3413 tree_cons (NULL_TREE,
3414 build_pointer_type (objc_exception_data_template),
3415 OBJC_VOID_AT_END));
3416 objc_exception_extract_decl
3417 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3418 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3419 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3420 temp_type
3421 = build_function_type (void_type_node,
3422 tree_cons (NULL_TREE,
3423 build_pointer_type (objc_exception_data_template),
3424 OBJC_VOID_AT_END));
3425 objc_exception_try_enter_decl
3426 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3427 objc_exception_try_exit_decl
3428 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3430 /* int objc_exception_match(id, id); */
3431 temp_type
3432 = build_function_type (integer_type_node,
3433 tree_cons (NULL_TREE, objc_object_type,
3434 tree_cons (NULL_TREE, objc_object_type,
3435 OBJC_VOID_AT_END)));
3436 objc_exception_match_decl
3437 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3440 static void
3441 build_objc_exception_stuff (void)
3443 tree noreturn_list, nothrow_list, temp_type;
3445 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3446 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3448 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3449 /* void objc_sync_enter(id); */
3450 /* void objc_sync_exit(id); */
3451 temp_type = build_function_type (void_type_node,
3452 tree_cons (NULL_TREE, objc_object_type,
3453 OBJC_VOID_AT_END));
3454 objc_exception_throw_decl
3455 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3456 noreturn_list);
3457 objc_sync_enter_decl
3458 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3459 NULL, nothrow_list);
3460 objc_sync_exit_decl
3461 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3462 NULL, nothrow_list);
3466 /* struct <classname> {
3467 struct _objc_class *isa;
3469 }; */
3471 static tree
3472 build_private_template (tree class)
3474 tree ivar_context;
3476 if (CLASS_STATIC_TEMPLATE (class))
3478 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3479 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3481 else
3483 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3484 ivar_context = get_class_ivars (class);
3486 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3488 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3490 /* mark this record as class template - for class type checking */
3491 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3494 objc_instance_type = build_pointer_type (uprivate_record);
3496 return ivar_context;
3499 /* Begin code generation for protocols... */
3501 /* struct _objc_protocol {
3502 struct _objc_class *isa;
3503 char *protocol_name;
3504 struct _objc_protocol **protocol_list;
3505 struct _objc__method_prototype_list *instance_methods;
3506 struct _objc__method_prototype_list *class_methods;
3507 }; */
3509 static void
3510 build_protocol_template (void)
3512 tree field_decl, field_decl_chain;
3514 objc_protocol_template = start_struct (RECORD_TYPE,
3515 get_identifier (UTAG_PROTOCOL));
3517 /* struct _objc_class *isa; */
3518 field_decl = create_field_decl (build_pointer_type
3519 (xref_tag (RECORD_TYPE,
3520 get_identifier (UTAG_CLASS))),
3521 "isa");
3522 field_decl_chain = field_decl;
3524 /* char *protocol_name; */
3525 field_decl = create_field_decl (string_type_node, "protocol_name");
3526 chainon (field_decl_chain, field_decl);
3528 /* struct _objc_protocol **protocol_list; */
3529 field_decl = create_field_decl (build_pointer_type
3530 (build_pointer_type
3531 (objc_protocol_template)),
3532 "protocol_list");
3533 chainon (field_decl_chain, field_decl);
3535 /* struct objc_method_list *instance_methods; */
3536 field_decl = create_field_decl (build_pointer_type
3537 (xref_tag (RECORD_TYPE,
3538 get_identifier
3539 (UTAG_METHOD_PROTOTYPE_LIST))),
3540 "instance_methods");
3541 chainon (field_decl_chain, field_decl);
3543 /* struct objc_method_list *class_methods; */
3544 field_decl = create_field_decl (build_pointer_type
3545 (xref_tag (RECORD_TYPE,
3546 get_identifier
3547 (UTAG_METHOD_PROTOTYPE_LIST))),
3548 "class_methods");
3549 chainon (field_decl_chain, field_decl);
3551 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
3554 static tree
3555 build_descriptor_table_initializer (tree type, tree entries)
3557 tree initlist = NULL_TREE;
3561 tree eltlist = NULL_TREE;
3563 eltlist
3564 = tree_cons (NULL_TREE,
3565 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3566 eltlist
3567 = tree_cons (NULL_TREE,
3568 add_objc_string (METHOD_ENCODING (entries),
3569 meth_var_types),
3570 eltlist);
3572 initlist
3573 = tree_cons (NULL_TREE,
3574 objc_build_constructor (type, nreverse (eltlist)),
3575 initlist);
3577 entries = TREE_CHAIN (entries);
3579 while (entries);
3581 return objc_build_constructor (build_array_type (type, 0),
3582 nreverse (initlist));
3585 /* struct objc_method_prototype_list {
3586 int count;
3587 struct objc_method_prototype {
3588 SEL name;
3589 char *types;
3590 } list[1];
3591 }; */
3593 static tree
3594 build_method_prototype_list_template (tree list_type, int size)
3596 tree objc_ivar_list_record;
3597 tree field_decl, field_decl_chain;
3599 /* Generate an unnamed struct definition. */
3601 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3603 /* int method_count; */
3604 field_decl = create_field_decl (integer_type_node, "method_count");
3605 field_decl_chain = field_decl;
3607 /* struct objc_method method_list[]; */
3608 field_decl = create_field_decl (build_array_type
3609 (list_type,
3610 build_index_type
3611 (build_int_cst (NULL_TREE, size - 1))),
3612 "method_list");
3613 chainon (field_decl_chain, field_decl);
3615 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3617 return objc_ivar_list_record;
3620 static tree
3621 build_method_prototype_template (void)
3623 tree proto_record;
3624 tree field_decl, field_decl_chain;
3626 proto_record
3627 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3629 /* SEL _cmd; */
3630 field_decl = create_field_decl (objc_selector_type, "_cmd");
3631 field_decl_chain = field_decl;
3633 /* char *method_types; */
3634 field_decl = create_field_decl (string_type_node, "method_types");
3635 chainon (field_decl_chain, field_decl);
3637 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3639 return proto_record;
3642 static tree
3643 objc_method_parm_type (tree type)
3645 type = TREE_VALUE (TREE_TYPE (type));
3646 if (TREE_CODE (type) == TYPE_DECL)
3647 type = TREE_TYPE (type);
3648 return TYPE_MAIN_VARIANT (type);
3651 static int
3652 objc_encoded_type_size (tree type)
3654 int sz = int_size_in_bytes (type);
3656 /* Make all integer and enum types at least as large
3657 as an int. */
3658 if (sz > 0 && INTEGRAL_TYPE_P (type))
3659 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3660 /* Treat arrays as pointers, since that's how they're
3661 passed in. */
3662 else if (TREE_CODE (type) == ARRAY_TYPE)
3663 sz = int_size_in_bytes (ptr_type_node);
3664 return sz;
3667 static tree
3668 encode_method_prototype (tree method_decl)
3670 tree parms;
3671 int parm_offset, i;
3672 char buf[40];
3673 tree result;
3675 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3676 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3678 /* Encode return type. */
3679 encode_type (objc_method_parm_type (method_decl),
3680 obstack_object_size (&util_obstack),
3681 OBJC_ENCODE_INLINE_DEFS);
3683 /* Stack size. */
3684 /* The first two arguments (self and _cmd) are pointers; account for
3685 their size. */
3686 i = int_size_in_bytes (ptr_type_node);
3687 parm_offset = 2 * i;
3688 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3689 parms = TREE_CHAIN (parms))
3691 tree type = objc_method_parm_type (parms);
3692 int sz = objc_encoded_type_size (type);
3694 /* If a type size is not known, bail out. */
3695 if (sz < 0)
3697 error ("%Jtype '%D' does not have a known size",
3698 type, type);
3699 /* Pretend that the encoding succeeded; the compilation will
3700 fail nevertheless. */
3701 goto finish_encoding;
3703 parm_offset += sz;
3706 sprintf (buf, "%d@0:%d", parm_offset, i);
3707 obstack_grow (&util_obstack, buf, strlen (buf));
3709 /* Argument types. */
3710 parm_offset = 2 * i;
3711 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3712 parms = TREE_CHAIN (parms))
3714 tree type = objc_method_parm_type (parms);
3716 /* Process argument qualifiers for user supplied arguments. */
3717 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3719 /* Type. */
3720 encode_type (type, obstack_object_size (&util_obstack),
3721 OBJC_ENCODE_INLINE_DEFS);
3723 /* Compute offset. */
3724 sprintf (buf, "%d", parm_offset);
3725 parm_offset += objc_encoded_type_size (type);
3727 obstack_grow (&util_obstack, buf, strlen (buf));
3730 finish_encoding:
3731 obstack_1grow (&util_obstack, '\0');
3732 result = get_identifier (obstack_finish (&util_obstack));
3733 obstack_free (&util_obstack, util_firstobj);
3734 return result;
3737 static tree
3738 generate_descriptor_table (tree type, const char *name, int size, tree list,
3739 tree proto)
3741 tree decl, initlist;
3743 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
3745 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
3746 initlist = tree_cons (NULL_TREE, list, initlist);
3748 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
3750 return decl;
3753 static void
3754 generate_method_descriptors (tree protocol)
3756 tree initlist, chain, method_list_template;
3757 tree variable_length_type
3758 = xref_tag (RECORD_TYPE,
3759 get_identifier (UTAG_METHOD_PROTOTYPE_LIST));
3760 int size;
3762 if (!objc_method_prototype_template)
3763 objc_method_prototype_template = build_method_prototype_template ();
3765 chain = PROTOCOL_CLS_METHODS (protocol);
3766 if (chain)
3768 size = list_length (chain);
3770 method_list_template
3771 = build_method_prototype_list_template (objc_method_prototype_template,
3772 size);
3774 initlist
3775 = build_descriptor_table_initializer (objc_method_prototype_template,
3776 chain);
3778 UOBJC_CLASS_METHODS_decl
3779 = generate_descriptor_table (method_list_template,
3780 "_OBJC_PROTOCOL_CLASS_METHODS",
3781 size, initlist, protocol);
3782 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3784 else
3785 UOBJC_CLASS_METHODS_decl = 0;
3787 chain = PROTOCOL_NST_METHODS (protocol);
3788 if (chain)
3790 size = list_length (chain);
3792 method_list_template
3793 = build_method_prototype_list_template (objc_method_prototype_template,
3794 size);
3795 initlist
3796 = build_descriptor_table_initializer (objc_method_prototype_template,
3797 chain);
3799 UOBJC_INSTANCE_METHODS_decl
3800 = generate_descriptor_table (method_list_template,
3801 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3802 size, initlist, protocol);
3803 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3805 else
3806 UOBJC_INSTANCE_METHODS_decl = 0;
3809 static void
3810 generate_protocol_references (tree plist)
3812 tree lproto;
3814 /* Forward declare protocols referenced. */
3815 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3817 tree proto = TREE_VALUE (lproto);
3819 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3820 && PROTOCOL_NAME (proto))
3822 if (! PROTOCOL_FORWARD_DECL (proto))
3823 build_protocol_reference (proto);
3825 if (PROTOCOL_LIST (proto))
3826 generate_protocol_references (PROTOCOL_LIST (proto));
3831 /* For each protocol which was referenced either from a @protocol()
3832 expression, or because a class/category implements it (then a
3833 pointer to the protocol is stored in the struct describing the
3834 class/category), we create a statically allocated instance of the
3835 Protocol class. The code is written in such a way as to generate
3836 as few Protocol objects as possible; we generate a unique Protocol
3837 instance for each protocol, and we don't generate a Protocol
3838 instance if the protocol is never referenced (either from a
3839 @protocol() or from a class/category implementation). These
3840 statically allocated objects can be referred to via the static
3841 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3843 The statically allocated Protocol objects that we generate here
3844 need to be fixed up at runtime in order to be used: the 'isa'
3845 pointer of the objects need to be set up to point to the 'Protocol'
3846 class, as known at runtime.
3848 The NeXT runtime fixes up all protocols at program startup time,
3849 before main() is entered. It uses a low-level trick to look up all
3850 those symbols, then loops on them and fixes them up.
3852 The GNU runtime as well fixes up all protocols before user code
3853 from the module is executed; it requires pointers to those symbols
3854 to be put in the objc_symtab (which is then passed as argument to
3855 the function __objc_exec_class() which the compiler sets up to be
3856 executed automatically when the module is loaded); setup of those
3857 Protocol objects happen in two ways in the GNU runtime: all
3858 Protocol objects referred to by a class or category implementation
3859 are fixed up when the class/category is loaded; all Protocol
3860 objects referred to by a @protocol() expression are added by the
3861 compiler to the list of statically allocated instances to fixup
3862 (the same list holding the statically allocated constant string
3863 objects). Because, as explained above, the compiler generates as
3864 few Protocol objects as possible, some Protocol object might end up
3865 being referenced multiple times when compiled with the GNU runtime,
3866 and end up being fixed up multiple times at runtime inizialization.
3867 But that doesn't hurt, it's just a little inefficient. */
3869 static void
3870 generate_protocols (void)
3872 tree p, encoding;
3873 tree decl;
3874 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3876 /* If a protocol was directly referenced, pull in indirect references. */
3877 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3878 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3879 generate_protocol_references (PROTOCOL_LIST (p));
3881 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3883 tree nst_methods = PROTOCOL_NST_METHODS (p);
3884 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3886 /* If protocol wasn't referenced, don't generate any code. */
3887 decl = PROTOCOL_FORWARD_DECL (p);
3889 if (!decl)
3890 continue;
3892 /* Make sure we link in the Protocol class. */
3893 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3895 while (nst_methods)
3897 if (! METHOD_ENCODING (nst_methods))
3899 encoding = encode_method_prototype (nst_methods);
3900 METHOD_ENCODING (nst_methods) = encoding;
3902 nst_methods = TREE_CHAIN (nst_methods);
3905 while (cls_methods)
3907 if (! METHOD_ENCODING (cls_methods))
3909 encoding = encode_method_prototype (cls_methods);
3910 METHOD_ENCODING (cls_methods) = encoding;
3913 cls_methods = TREE_CHAIN (cls_methods);
3915 generate_method_descriptors (p);
3917 if (PROTOCOL_LIST (p))
3918 refs_decl = generate_protocol_list (p);
3919 else
3920 refs_decl = 0;
3922 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3923 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3925 if (refs_decl)
3926 refs_expr = convert (build_pointer_type (build_pointer_type
3927 (objc_protocol_template)),
3928 build_unary_op (ADDR_EXPR, refs_decl, 0));
3929 else
3930 refs_expr = build_int_cst (NULL_TREE, 0);
3932 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3933 by generate_method_descriptors, which is called above. */
3934 initlist = build_protocol_initializer (TREE_TYPE (decl),
3935 protocol_name_expr, refs_expr,
3936 UOBJC_INSTANCE_METHODS_decl,
3937 UOBJC_CLASS_METHODS_decl);
3938 finish_var_decl (decl, initlist);
3942 static tree
3943 build_protocol_initializer (tree type, tree protocol_name,
3944 tree protocol_list, tree instance_methods,
3945 tree class_methods)
3947 tree initlist = NULL_TREE, expr;
3948 tree cast_type = build_pointer_type
3949 (xref_tag (RECORD_TYPE,
3950 get_identifier (UTAG_CLASS)));
3952 /* Filling the "isa" in with one allows the runtime system to
3953 detect that the version change...should remove before final release. */
3955 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
3956 initlist = tree_cons (NULL_TREE, expr, initlist);
3957 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3958 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3960 if (!instance_methods)
3961 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
3962 else
3964 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3965 initlist = tree_cons (NULL_TREE, expr, initlist);
3968 if (!class_methods)
3969 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
3970 else
3972 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3973 initlist = tree_cons (NULL_TREE, expr, initlist);
3976 return objc_build_constructor (type, nreverse (initlist));
3979 /* struct _objc_category {
3980 char *category_name;
3981 char *class_name;
3982 struct _objc_method_list *instance_methods;
3983 struct _objc_method_list *class_methods;
3984 struct _objc_protocol_list *protocols;
3985 }; */
3987 static void
3988 build_category_template (void)
3990 tree field_decl, field_decl_chain;
3992 objc_category_template = start_struct (RECORD_TYPE,
3993 get_identifier (UTAG_CATEGORY));
3995 /* char *category_name; */
3996 field_decl = create_field_decl (string_type_node, "category_name");
3997 field_decl_chain = field_decl;
3999 /* char *class_name; */
4000 field_decl = create_field_decl (string_type_node, "class_name");
4001 chainon (field_decl_chain, field_decl);
4003 /* struct _objc_method_list *instance_methods; */
4004 field_decl = create_field_decl (build_pointer_type
4005 (xref_tag (RECORD_TYPE,
4006 get_identifier
4007 (UTAG_METHOD_LIST))),
4008 "instance_methods");
4009 chainon (field_decl_chain, field_decl);
4011 /* struct _objc_method_list *class_methods; */
4012 field_decl = create_field_decl (build_pointer_type
4013 (xref_tag (RECORD_TYPE,
4014 get_identifier
4015 (UTAG_METHOD_LIST))),
4016 "class_methods");
4017 chainon (field_decl_chain, field_decl);
4019 /* struct _objc_protocol **protocol_list; */
4020 field_decl = create_field_decl (build_pointer_type
4021 (build_pointer_type
4022 (objc_protocol_template)),
4023 "protocol_list");
4024 chainon (field_decl_chain, field_decl);
4026 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4029 /* struct _objc_selector {
4030 SEL sel_id;
4031 char *sel_type;
4032 }; */
4034 static void
4035 build_selector_template (void)
4038 tree field_decl, field_decl_chain;
4040 objc_selector_template
4041 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4043 /* SEL sel_id; */
4044 field_decl = create_field_decl (objc_selector_type, "sel_id");
4045 field_decl_chain = field_decl;
4047 /* char *sel_type; */
4048 field_decl = create_field_decl (string_type_node, "sel_type");
4049 chainon (field_decl_chain, field_decl);
4051 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4054 /* struct _objc_class {
4055 struct _objc_class *isa;
4056 struct _objc_class *super_class;
4057 char *name;
4058 long version;
4059 long info;
4060 long instance_size;
4061 struct _objc_ivar_list *ivars;
4062 struct _objc_method_list *methods;
4063 #ifdef __NEXT_RUNTIME__
4064 struct objc_cache *cache;
4065 #else
4066 struct sarray *dtable;
4067 struct _objc_class *subclass_list;
4068 struct _objc_class *sibling_class;
4069 #endif
4070 struct _objc_protocol_list *protocols;
4071 #ifdef __NEXT_RUNTIME__
4072 void *sel_id;
4073 #endif
4074 void *gc_object_type;
4075 }; */
4077 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4078 the NeXT/Apple runtime; still, the compiler must generate them to
4079 maintain backward binary compatibility (and to allow for future
4080 expansion). */
4082 static void
4083 build_class_template (void)
4085 tree field_decl, field_decl_chain;
4087 objc_class_template
4088 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4090 /* struct _objc_class *isa; */
4091 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4092 "isa");
4093 field_decl_chain = field_decl;
4095 /* struct _objc_class *super_class; */
4096 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4097 "super_class");
4098 chainon (field_decl_chain, field_decl);
4100 /* char *name; */
4101 field_decl = create_field_decl (string_type_node, "name");
4102 chainon (field_decl_chain, field_decl);
4104 /* long version; */
4105 field_decl = create_field_decl (long_integer_type_node, "version");
4106 chainon (field_decl_chain, field_decl);
4108 /* long info; */
4109 field_decl = create_field_decl (long_integer_type_node, "info");
4110 chainon (field_decl_chain, field_decl);
4112 /* long instance_size; */
4113 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4114 chainon (field_decl_chain, field_decl);
4116 /* struct _objc_ivar_list *ivars; */
4117 field_decl = create_field_decl (build_pointer_type
4118 (xref_tag (RECORD_TYPE,
4119 get_identifier
4120 (UTAG_IVAR_LIST))),
4121 "ivars");
4122 chainon (field_decl_chain, field_decl);
4124 /* struct _objc_method_list *methods; */
4125 field_decl = create_field_decl (build_pointer_type
4126 (xref_tag (RECORD_TYPE,
4127 get_identifier
4128 (UTAG_METHOD_LIST))),
4129 "methods");
4130 chainon (field_decl_chain, field_decl);
4132 if (flag_next_runtime)
4134 /* struct objc_cache *cache; */
4135 field_decl = create_field_decl (build_pointer_type
4136 (xref_tag (RECORD_TYPE,
4137 get_identifier
4138 ("objc_cache"))),
4139 "cache");
4140 chainon (field_decl_chain, field_decl);
4142 else
4144 /* struct sarray *dtable; */
4145 field_decl = create_field_decl (build_pointer_type
4146 (xref_tag (RECORD_TYPE,
4147 get_identifier
4148 ("sarray"))),
4149 "dtable");
4150 chainon (field_decl_chain, field_decl);
4152 /* struct objc_class *subclass_list; */
4153 field_decl = create_field_decl (build_pointer_type
4154 (objc_class_template),
4155 "subclass_list");
4156 chainon (field_decl_chain, field_decl);
4158 /* struct objc_class *sibling_class; */
4159 field_decl = create_field_decl (build_pointer_type
4160 (objc_class_template),
4161 "sibling_class");
4162 chainon (field_decl_chain, field_decl);
4165 /* struct _objc_protocol **protocol_list; */
4166 field_decl = create_field_decl (build_pointer_type
4167 (build_pointer_type
4168 (xref_tag (RECORD_TYPE,
4169 get_identifier
4170 (UTAG_PROTOCOL)))),
4171 "protocol_list");
4172 chainon (field_decl_chain, field_decl);
4174 if (flag_next_runtime)
4176 /* void *sel_id; */
4177 field_decl = create_field_decl (build_pointer_type (void_type_node),
4178 "sel_id");
4179 chainon (field_decl_chain, field_decl);
4182 /* void *gc_object_type; */
4183 field_decl = create_field_decl (build_pointer_type (void_type_node),
4184 "gc_object_type");
4185 chainon (field_decl_chain, field_decl);
4187 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4190 /* Generate appropriate forward declarations for an implementation. */
4192 static void
4193 synth_forward_declarations (void)
4195 tree an_id;
4197 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4198 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4199 objc_class_template);
4201 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4202 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4203 objc_class_template);
4205 /* Pre-build the following entities - for speed/convenience. */
4207 an_id = get_identifier ("super_class");
4208 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4209 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4212 static void
4213 error_with_ivar (const char *message, tree decl)
4215 error ("%J%s `%s'", decl,
4216 message, gen_declaration (decl));
4220 static void
4221 check_ivars (tree inter, tree imp)
4223 tree intdecls = CLASS_RAW_IVARS (inter);
4224 tree impdecls = CLASS_RAW_IVARS (imp);
4226 while (1)
4228 tree t1, t2;
4230 #ifdef OBJCPLUS
4231 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4232 intdecls = TREE_CHAIN (intdecls);
4233 #endif
4234 if (intdecls == 0 && impdecls == 0)
4235 break;
4236 if (intdecls == 0 || impdecls == 0)
4238 error ("inconsistent instance variable specification");
4239 break;
4242 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4244 if (!comptypes (t1, t2)
4245 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4246 DECL_INITIAL (impdecls)))
4248 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4250 error_with_ivar ("conflicting instance variable type",
4251 impdecls);
4252 error_with_ivar ("previous declaration of",
4253 intdecls);
4255 else /* both the type and the name don't match */
4257 error ("inconsistent instance variable specification");
4258 break;
4262 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4264 error_with_ivar ("conflicting instance variable name",
4265 impdecls);
4266 error_with_ivar ("previous declaration of",
4267 intdecls);
4270 intdecls = TREE_CHAIN (intdecls);
4271 impdecls = TREE_CHAIN (impdecls);
4275 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4276 This needs to be done just once per compilation. */
4278 /* struct _objc_super {
4279 struct _objc_object *self;
4280 struct _objc_class *super_class;
4281 }; */
4283 static void
4284 build_super_template (void)
4286 tree field_decl, field_decl_chain;
4288 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4290 /* struct _objc_object *self; */
4291 field_decl = create_field_decl (objc_object_type, "self");
4292 field_decl_chain = field_decl;
4294 /* struct _objc_class *super_class; */
4295 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4296 "super_class");
4297 chainon (field_decl_chain, field_decl);
4299 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4302 /* struct _objc_ivar {
4303 char *ivar_name;
4304 char *ivar_type;
4305 int ivar_offset;
4306 }; */
4308 static tree
4309 build_ivar_template (void)
4311 tree objc_ivar_id, objc_ivar_record;
4312 tree field_decl, field_decl_chain;
4314 objc_ivar_id = get_identifier (UTAG_IVAR);
4315 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4317 /* char *ivar_name; */
4318 field_decl = create_field_decl (string_type_node, "ivar_name");
4319 field_decl_chain = field_decl;
4321 /* char *ivar_type; */
4322 field_decl = create_field_decl (string_type_node, "ivar_type");
4323 chainon (field_decl_chain, field_decl);
4325 /* int ivar_offset; */
4326 field_decl = create_field_decl (integer_type_node, "ivar_offset");
4327 chainon (field_decl_chain, field_decl);
4329 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4331 return objc_ivar_record;
4334 /* struct {
4335 int ivar_count;
4336 struct objc_ivar ivar_list[ivar_count];
4337 }; */
4339 static tree
4340 build_ivar_list_template (tree list_type, int size)
4342 tree objc_ivar_list_record;
4343 tree field_decl, field_decl_chain;
4345 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4347 /* int ivar_count; */
4348 field_decl = create_field_decl (integer_type_node, "ivar_count");
4349 field_decl_chain = field_decl;
4351 /* struct objc_ivar ivar_list[]; */
4352 field_decl = create_field_decl (build_array_type
4353 (list_type,
4354 build_index_type
4355 (build_int_cst (NULL_TREE, size - 1))),
4356 "ivar_list");
4357 chainon (field_decl_chain, field_decl);
4359 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4361 return objc_ivar_list_record;
4364 /* struct {
4365 struct _objc__method_prototype_list *method_next;
4366 int method_count;
4367 struct objc_method method_list[method_count];
4368 }; */
4370 static tree
4371 build_method_list_template (tree list_type, int size)
4373 tree objc_ivar_list_record;
4374 tree field_decl, field_decl_chain;
4376 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4378 /* struct _objc__method_prototype_list *method_next; */
4379 field_decl = create_field_decl (build_pointer_type
4380 (xref_tag (RECORD_TYPE,
4381 get_identifier
4382 (UTAG_METHOD_PROTOTYPE_LIST))),
4383 "method_next");
4384 field_decl_chain = field_decl;
4386 /* int method_count; */
4387 field_decl = create_field_decl (integer_type_node, "method_count");
4388 chainon (field_decl_chain, field_decl);
4390 /* struct objc_method method_list[]; */
4391 field_decl = create_field_decl (build_array_type
4392 (list_type,
4393 build_index_type
4394 (build_int_cst (NULL_TREE, size - 1))),
4395 "method_list");
4396 chainon (field_decl_chain, field_decl);
4398 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4400 return objc_ivar_list_record;
4403 static tree
4404 build_ivar_list_initializer (tree type, tree field_decl)
4406 tree initlist = NULL_TREE;
4410 tree ivar = NULL_TREE;
4412 /* Set name. */
4413 if (DECL_NAME (field_decl))
4414 ivar = tree_cons (NULL_TREE,
4415 add_objc_string (DECL_NAME (field_decl),
4416 meth_var_names),
4417 ivar);
4418 else
4419 /* Unnamed bit-field ivar (yuck). */
4420 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
4422 /* Set type. */
4423 encode_field_decl (field_decl,
4424 obstack_object_size (&util_obstack),
4425 OBJC_ENCODE_DONT_INLINE_DEFS);
4427 /* Null terminate string. */
4428 obstack_1grow (&util_obstack, 0);
4429 ivar
4430 = tree_cons
4431 (NULL_TREE,
4432 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4433 meth_var_types),
4434 ivar);
4435 obstack_free (&util_obstack, util_firstobj);
4437 /* Set offset. */
4438 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4439 initlist = tree_cons (NULL_TREE,
4440 objc_build_constructor (type, nreverse (ivar)),
4441 initlist);
4443 field_decl = TREE_CHAIN (field_decl);
4444 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4446 while (field_decl);
4448 return objc_build_constructor (build_array_type (type, 0),
4449 nreverse (initlist));
4452 static tree
4453 generate_ivars_list (tree type, const char *name, int size, tree list)
4455 tree decl, initlist;
4457 decl = start_var_decl (type, synth_id_with_class_suffix
4458 (name, objc_implementation_context));
4460 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4461 initlist = tree_cons (NULL_TREE, list, initlist);
4463 finish_var_decl (decl,
4464 objc_build_constructor (TREE_TYPE (decl),
4465 nreverse (initlist)));
4467 return decl;
4470 /* Count only the fields occurring in T. */
4471 static int
4472 ivar_list_length (tree t)
4474 int count = 0;
4476 for (; t; t = TREE_CHAIN (t))
4477 if (TREE_CODE (t) == FIELD_DECL)
4478 ++count;
4480 return count;
4483 static void
4484 generate_ivar_lists (void)
4486 tree initlist, ivar_list_template, chain;
4487 tree variable_length_type
4488 = xref_tag (RECORD_TYPE, get_identifier (UTAG_IVAR_LIST));
4489 int size;
4491 generating_instance_variables = 1;
4493 if (!objc_ivar_template)
4494 objc_ivar_template = build_ivar_template ();
4496 /* Only generate class variables for the root of the inheritance
4497 hierarchy since these will be the same for every class. */
4499 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4500 && (chain = TYPE_FIELDS (objc_class_template)))
4502 size = ivar_list_length (chain);
4504 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4505 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4507 UOBJC_CLASS_VARIABLES_decl
4508 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4509 size, initlist);
4510 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4512 else
4513 UOBJC_CLASS_VARIABLES_decl = 0;
4515 chain = CLASS_IVARS (implementation_template);
4516 if (chain)
4518 size = ivar_list_length (chain);
4519 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4520 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4522 UOBJC_INSTANCE_VARIABLES_decl
4523 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4524 size, initlist);
4525 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4527 else
4528 UOBJC_INSTANCE_VARIABLES_decl = 0;
4530 generating_instance_variables = 0;
4533 static tree
4534 build_dispatch_table_initializer (tree type, tree entries)
4536 tree initlist = NULL_TREE;
4540 tree elemlist = NULL_TREE;
4542 elemlist = tree_cons (NULL_TREE,
4543 build_selector (METHOD_SEL_NAME (entries)),
4544 NULL_TREE);
4546 /* Generate the method encoding if we don't have one already. */
4547 if (! METHOD_ENCODING (entries))
4548 METHOD_ENCODING (entries) =
4549 encode_method_prototype (entries);
4551 elemlist = tree_cons (NULL_TREE,
4552 add_objc_string (METHOD_ENCODING (entries),
4553 meth_var_types),
4554 elemlist);
4556 elemlist
4557 = tree_cons (NULL_TREE,
4558 convert (ptr_type_node,
4559 build_unary_op (ADDR_EXPR,
4560 METHOD_DEFINITION (entries), 1)),
4561 elemlist);
4563 initlist = tree_cons (NULL_TREE,
4564 objc_build_constructor (type, nreverse (elemlist)),
4565 initlist);
4567 entries = TREE_CHAIN (entries);
4569 while (entries);
4571 return objc_build_constructor (build_array_type (type, 0),
4572 nreverse (initlist));
4575 /* To accomplish method prototyping without generating all kinds of
4576 inane warnings, the definition of the dispatch table entries were
4577 changed from:
4579 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4581 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4583 static tree
4584 build_method_template (void)
4586 tree _SLT_record;
4587 tree field_decl, field_decl_chain;
4589 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4591 /* SEL _cmd; */
4592 field_decl = create_field_decl (objc_selector_type, "_cmd");
4593 field_decl_chain = field_decl;
4595 /* char *method_types; */
4596 field_decl = create_field_decl (string_type_node, "method_types");
4597 chainon (field_decl_chain, field_decl);
4599 /* void *_imp; */
4600 field_decl = create_field_decl (build_pointer_type (void_type_node),
4601 "_imp");
4602 chainon (field_decl_chain, field_decl);
4604 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4606 return _SLT_record;
4610 static tree
4611 generate_dispatch_table (tree type, const char *name, int size, tree list)
4613 tree decl, initlist;
4615 decl = start_var_decl (type, synth_id_with_class_suffix
4616 (name, objc_implementation_context));
4618 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
4619 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
4620 initlist = tree_cons (NULL_TREE, list, initlist);
4622 finish_var_decl (decl,
4623 objc_build_constructor (TREE_TYPE (decl),
4624 nreverse (initlist)));
4626 return decl;
4629 static void
4630 mark_referenced_methods (void)
4632 struct imp_entry *impent;
4633 tree chain;
4635 for (impent = imp_list; impent; impent = impent->next)
4637 chain = CLASS_CLS_METHODS (impent->imp_context);
4638 while (chain)
4640 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4641 chain = TREE_CHAIN (chain);
4644 chain = CLASS_NST_METHODS (impent->imp_context);
4645 while (chain)
4647 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4648 chain = TREE_CHAIN (chain);
4653 static void
4654 generate_dispatch_tables (void)
4656 tree initlist, chain, method_list_template;
4657 tree variable_length_type
4658 = xref_tag (RECORD_TYPE, get_identifier (UTAG_METHOD_LIST));
4659 int size;
4661 if (!objc_method_template)
4662 objc_method_template = build_method_template ();
4664 chain = CLASS_CLS_METHODS (objc_implementation_context);
4665 if (chain)
4667 size = list_length (chain);
4669 method_list_template
4670 = build_method_list_template (objc_method_template, size);
4671 initlist
4672 = build_dispatch_table_initializer (objc_method_template, chain);
4674 UOBJC_CLASS_METHODS_decl
4675 = generate_dispatch_table (method_list_template,
4676 ((TREE_CODE (objc_implementation_context)
4677 == CLASS_IMPLEMENTATION_TYPE)
4678 ? "_OBJC_CLASS_METHODS"
4679 : "_OBJC_CATEGORY_CLASS_METHODS"),
4680 size, initlist);
4681 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4683 else
4684 UOBJC_CLASS_METHODS_decl = 0;
4686 chain = CLASS_NST_METHODS (objc_implementation_context);
4687 if (chain)
4689 size = list_length (chain);
4691 method_list_template
4692 = build_method_list_template (objc_method_template, size);
4693 initlist
4694 = build_dispatch_table_initializer (objc_method_template, chain);
4696 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4697 UOBJC_INSTANCE_METHODS_decl
4698 = generate_dispatch_table (method_list_template,
4699 "_OBJC_INSTANCE_METHODS",
4700 size, initlist);
4701 else
4702 /* We have a category. */
4703 UOBJC_INSTANCE_METHODS_decl
4704 = generate_dispatch_table (method_list_template,
4705 "_OBJC_CATEGORY_INSTANCE_METHODS",
4706 size, initlist);
4707 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4709 else
4710 UOBJC_INSTANCE_METHODS_decl = 0;
4713 static tree
4714 generate_protocol_list (tree i_or_p)
4716 tree initlist;
4717 tree refs_decl, lproto, e, plist;
4718 int size = 0;
4719 const char *ref_name;
4721 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4722 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4723 plist = CLASS_PROTOCOL_LIST (i_or_p);
4724 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4725 plist = PROTOCOL_LIST (i_or_p);
4726 else
4727 abort ();
4729 /* Compute size. */
4730 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4731 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4732 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4733 size++;
4735 /* Build initializer. */
4736 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
4737 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
4738 initlist = tree_cons (NULL_TREE, e, initlist);
4740 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4742 tree pval = TREE_VALUE (lproto);
4744 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4745 && PROTOCOL_FORWARD_DECL (pval))
4747 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4748 initlist = tree_cons (NULL_TREE, e, initlist);
4752 /* static struct objc_protocol *refs[n]; */
4754 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4755 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
4756 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4757 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
4758 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4759 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
4760 else
4761 abort ();
4763 refs_decl = start_var_decl
4764 (build_array_type
4765 (build_pointer_type (objc_protocol_template),
4766 build_index_type (build_int_cst (NULL_TREE, size + 2))),
4767 ref_name);
4769 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4770 nreverse (initlist)));
4772 return refs_decl;
4775 static tree
4776 build_category_initializer (tree type, tree cat_name, tree class_name,
4777 tree instance_methods, tree class_methods,
4778 tree protocol_list)
4780 tree initlist = NULL_TREE, expr;
4782 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4783 initlist = tree_cons (NULL_TREE, class_name, initlist);
4785 if (!instance_methods)
4786 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4787 else
4789 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4790 initlist = tree_cons (NULL_TREE, expr, initlist);
4792 if (!class_methods)
4793 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4794 else
4796 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4797 initlist = tree_cons (NULL_TREE, expr, initlist);
4800 /* protocol_list = */
4801 if (!protocol_list)
4802 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4803 else
4805 expr = convert (build_pointer_type
4806 (build_pointer_type
4807 (objc_protocol_template)),
4808 build_unary_op (ADDR_EXPR, protocol_list, 0));
4809 initlist = tree_cons (NULL_TREE, expr, initlist);
4812 return objc_build_constructor (type, nreverse (initlist));
4815 /* struct _objc_class {
4816 struct objc_class *isa;
4817 struct objc_class *super_class;
4818 char *name;
4819 long version;
4820 long info;
4821 long instance_size;
4822 struct objc_ivar_list *ivars;
4823 struct objc_method_list *methods;
4824 if (flag_next_runtime)
4825 struct objc_cache *cache;
4826 else {
4827 struct sarray *dtable;
4828 struct objc_class *subclass_list;
4829 struct objc_class *sibling_class;
4831 struct objc_protocol_list *protocols;
4832 if (flag_next_runtime)
4833 void *sel_id;
4834 void *gc_object_type;
4835 }; */
4837 static tree
4838 build_shared_structure_initializer (tree type, tree isa, tree super,
4839 tree name, tree size, int status,
4840 tree dispatch_table, tree ivar_list,
4841 tree protocol_list)
4843 tree initlist = NULL_TREE, expr;
4845 /* isa = */
4846 initlist = tree_cons (NULL_TREE, isa, initlist);
4848 /* super_class = */
4849 initlist = tree_cons (NULL_TREE, super, initlist);
4851 /* name = */
4852 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4854 /* version = */
4855 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
4856 initlist);
4858 /* info = */
4859 initlist = tree_cons (NULL_TREE,
4860 build_int_cst (long_integer_type_node, status),
4861 initlist);
4863 /* instance_size = */
4864 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
4865 initlist);
4867 /* objc_ivar_list = */
4868 if (!ivar_list)
4869 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4870 else
4872 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4873 initlist = tree_cons (NULL_TREE, expr, initlist);
4876 /* objc_method_list = */
4877 if (!dispatch_table)
4878 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4879 else
4881 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4882 initlist = tree_cons (NULL_TREE, expr, initlist);
4885 if (flag_next_runtime)
4886 /* method_cache = */
4887 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4888 else
4890 /* dtable = */
4891 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4893 /* subclass_list = */
4894 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4896 /* sibling_class = */
4897 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4900 /* protocol_list = */
4901 if (! protocol_list)
4902 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4903 else
4905 expr = convert (build_pointer_type
4906 (build_pointer_type
4907 (objc_protocol_template)),
4908 build_unary_op (ADDR_EXPR, protocol_list, 0));
4909 initlist = tree_cons (NULL_TREE, expr, initlist);
4912 if (flag_next_runtime)
4913 /* sel_id = NULL */
4914 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4916 /* gc_object_type = NULL */
4917 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4919 return objc_build_constructor (type, nreverse (initlist));
4922 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
4924 static inline tree
4925 lookup_category (tree class, tree cat_name)
4927 tree category = CLASS_CATEGORY_LIST (class);
4929 while (category && CLASS_SUPER_NAME (category) != cat_name)
4930 category = CLASS_CATEGORY_LIST (category);
4931 return category;
4934 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4936 static void
4937 generate_category (tree cat)
4939 tree decl;
4940 tree initlist, cat_name_expr, class_name_expr;
4941 tree protocol_decl, category;
4943 add_class_reference (CLASS_NAME (cat));
4944 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4946 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4948 category = lookup_category (implementation_template,
4949 CLASS_SUPER_NAME (cat));
4951 if (category && CLASS_PROTOCOL_LIST (category))
4953 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4954 protocol_decl = generate_protocol_list (category);
4956 else
4957 protocol_decl = 0;
4959 decl = start_var_decl (objc_category_template,
4960 synth_id_with_class_suffix
4961 ("_OBJC_CATEGORY", objc_implementation_context));
4963 initlist = build_category_initializer (TREE_TYPE (decl),
4964 cat_name_expr, class_name_expr,
4965 UOBJC_INSTANCE_METHODS_decl,
4966 UOBJC_CLASS_METHODS_decl,
4967 protocol_decl);
4969 finish_var_decl (decl, initlist);
4972 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4973 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4975 static void
4976 generate_shared_structures (void)
4978 tree sc_spec, decl_specs, decl;
4979 tree name_expr, super_expr, root_expr;
4980 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4981 tree cast_type, initlist, protocol_decl;
4983 my_super_id = CLASS_SUPER_NAME (implementation_template);
4984 if (my_super_id)
4986 add_class_reference (my_super_id);
4988 /* Compute "my_root_id" - this is required for code generation.
4989 the "isa" for all meta class structures points to the root of
4990 the inheritance hierarchy (e.g. "__Object")... */
4991 my_root_id = my_super_id;
4994 tree my_root_int = lookup_interface (my_root_id);
4996 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4997 my_root_id = CLASS_SUPER_NAME (my_root_int);
4998 else
4999 break;
5001 while (1);
5003 else
5004 /* No super class. */
5005 my_root_id = CLASS_NAME (implementation_template);
5007 cast_type = build_pointer_type (objc_class_template);
5008 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5009 class_names);
5011 /* Install class `isa' and `super' pointers at runtime. */
5012 if (my_super_id)
5014 super_expr = add_objc_string (my_super_id, class_names);
5015 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5017 else
5018 super_expr = build_int_cst (NULL_TREE, 0);
5020 root_expr = add_objc_string (my_root_id, class_names);
5021 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5023 if (CLASS_PROTOCOL_LIST (implementation_template))
5025 generate_protocol_references
5026 (CLASS_PROTOCOL_LIST (implementation_template));
5027 protocol_decl = generate_protocol_list (implementation_template);
5029 else
5030 protocol_decl = 0;
5032 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5034 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5035 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5037 decl = start_var_decl (objc_class_template,
5038 IDENTIFIER_POINTER
5039 (DECL_NAME (UOBJC_METACLASS_decl)));
5041 initlist
5042 = build_shared_structure_initializer
5043 (TREE_TYPE (decl),
5044 root_expr, super_expr, name_expr,
5045 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5046 2 /*CLS_META*/,
5047 UOBJC_CLASS_METHODS_decl,
5048 UOBJC_CLASS_VARIABLES_decl,
5049 protocol_decl);
5051 finish_var_decl (decl, initlist);
5053 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5055 decl = start_var_decl (objc_class_template,
5056 IDENTIFIER_POINTER
5057 (DECL_NAME (UOBJC_CLASS_decl)));
5059 initlist
5060 = build_shared_structure_initializer
5061 (TREE_TYPE (decl),
5062 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5063 super_expr, name_expr,
5064 convert (integer_type_node,
5065 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5066 (implementation_template))),
5067 1 /*CLS_FACTORY*/,
5068 UOBJC_INSTANCE_METHODS_decl,
5069 UOBJC_INSTANCE_VARIABLES_decl,
5070 protocol_decl);
5072 finish_var_decl (decl, initlist);
5076 static const char *
5077 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5079 static char string[BUFSIZE];
5081 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5082 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5084 sprintf (string, "%s_%s", preamble,
5085 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5087 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5088 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5090 /* We have a category. */
5091 const char *const class_name
5092 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5093 const char *const class_super_name
5094 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5095 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5097 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5099 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5100 sprintf (string, "%s_%s", preamble, protocol_name);
5102 else
5103 abort ();
5105 return string;
5108 /* If type is empty or only type qualifiers are present, add default
5109 type of id (otherwise grokdeclarator will default to int). */
5111 static tree
5112 adjust_type_for_id_default (tree type)
5114 if (!type)
5115 type = make_node (TREE_LIST);
5117 if (!TREE_VALUE (type))
5118 TREE_VALUE (type) = objc_object_type;
5119 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5120 && TYPED_OBJECT (TREE_VALUE (type)))
5121 error ("can not use an object as parameter to a method");
5123 return type;
5126 /* Usage:
5127 keyworddecl:
5128 selector ':' '(' typename ')' identifier
5130 Purpose:
5131 Transform an Objective-C keyword argument into
5132 the C equivalent parameter declarator.
5134 In: key_name, an "identifier_node" (optional).
5135 arg_type, a "tree_list" (optional).
5136 arg_name, an "identifier_node".
5138 Note: It would be really nice to strongly type the preceding
5139 arguments in the function prototype; however, then I
5140 could not use the "accessor" macros defined in "tree.h".
5142 Out: an instance of "keyword_decl". */
5144 tree
5145 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5147 tree keyword_decl;
5149 /* If no type is specified, default to "id". */
5150 arg_type = adjust_type_for_id_default (arg_type);
5152 keyword_decl = make_node (KEYWORD_DECL);
5154 TREE_TYPE (keyword_decl) = arg_type;
5155 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5156 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5158 return keyword_decl;
5161 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5163 static tree
5164 build_keyword_selector (tree selector)
5166 int len = 0;
5167 tree key_chain, key_name;
5168 char *buf;
5170 /* Scan the selector to see how much space we'll need. */
5171 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5173 if (TREE_CODE (selector) == KEYWORD_DECL)
5174 key_name = KEYWORD_KEY_NAME (key_chain);
5175 else if (TREE_CODE (selector) == TREE_LIST)
5176 key_name = TREE_PURPOSE (key_chain);
5177 else
5178 abort ();
5180 if (key_name)
5181 len += IDENTIFIER_LENGTH (key_name) + 1;
5182 else
5183 /* Just a ':' arg. */
5184 len++;
5187 buf = (char *) alloca (len + 1);
5188 /* Start the buffer out as an empty string. */
5189 buf[0] = '\0';
5191 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5193 if (TREE_CODE (selector) == KEYWORD_DECL)
5194 key_name = KEYWORD_KEY_NAME (key_chain);
5195 else if (TREE_CODE (selector) == TREE_LIST)
5197 key_name = TREE_PURPOSE (key_chain);
5198 /* The keyword decl chain will later be used as a function argument
5199 chain. Unhook the selector itself so as to not confuse other
5200 parts of the compiler. */
5201 TREE_PURPOSE (key_chain) = NULL_TREE;
5203 else
5204 abort ();
5206 if (key_name)
5207 strcat (buf, IDENTIFIER_POINTER (key_name));
5208 strcat (buf, ":");
5211 return get_identifier (buf);
5214 /* Used for declarations and definitions. */
5216 static tree
5217 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5218 tree add_args)
5220 tree method_decl;
5222 /* If no type is specified, default to "id". */
5223 ret_type = adjust_type_for_id_default (ret_type);
5225 method_decl = make_node (code);
5226 TREE_TYPE (method_decl) = ret_type;
5228 /* If we have a keyword selector, create an identifier_node that
5229 represents the full selector name (`:' included)... */
5230 if (TREE_CODE (selector) == KEYWORD_DECL)
5232 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5233 METHOD_SEL_ARGS (method_decl) = selector;
5234 METHOD_ADD_ARGS (method_decl) = add_args;
5236 else
5238 METHOD_SEL_NAME (method_decl) = selector;
5239 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5240 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5243 return method_decl;
5246 #define METHOD_DEF 0
5247 #define METHOD_REF 1
5249 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5250 an argument list for method METH. CONTEXT is either METHOD_DEF or
5251 METHOD_REF, saying whether we are trying to define a method or call
5252 one. SUPERFLAG says this is for a send to super; this makes a
5253 difference for the NeXT calling sequence in which the lookup and
5254 the method call are done together. If METH is null, user-defined
5255 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5257 static tree
5258 get_arg_type_list (tree meth, int context, int superflag)
5260 tree arglist, akey;
5262 /* Receiver type. */
5263 if (flag_next_runtime && superflag)
5264 arglist = build_tree_list (NULL_TREE, objc_super_type);
5265 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5266 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5267 else
5268 arglist = build_tree_list (NULL_TREE, objc_object_type);
5270 /* Selector type - will eventually change to `int'. */
5271 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5273 /* No actual method prototype given -- assume that remaining arguments
5274 are `...'. */
5275 if (!meth)
5276 return arglist;
5278 /* Build a list of argument types. */
5279 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5281 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
5283 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5286 if (METHOD_ADD_ARGS (meth))
5288 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5289 akey; akey = TREE_CHAIN (akey))
5291 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
5293 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5296 if (!TREE_OVERFLOW (METHOD_ADD_ARGS (meth)))
5297 goto lack_of_ellipsis;
5299 else
5301 lack_of_ellipsis:
5302 chainon (arglist, OBJC_VOID_AT_END);
5305 return arglist;
5308 static tree
5309 check_duplicates (hash hsh, int methods, int is_class)
5311 tree meth = NULL_TREE;
5313 if (hsh)
5315 meth = hsh->key;
5317 if (hsh->list)
5319 /* We have two or more methods with the same name but
5320 different types. */
5321 attr loop;
5323 warning ("multiple %s named `%c%s' found",
5324 methods ? "methods" : "selectors",
5325 (is_class ? '+' : '-'),
5326 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5328 warn_with_method (methods ? "using" : "found",
5329 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5330 ? '-'
5331 : '+'),
5332 meth);
5333 for (loop = hsh->list; loop; loop = loop->next)
5334 warn_with_method ("also found",
5335 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5336 ? '-'
5337 : '+'),
5338 loop->value);
5341 return meth;
5344 /* If RECEIVER is a class reference, return the identifier node for
5345 the referenced class. RECEIVER is created by objc_get_class_reference,
5346 so we check the exact form created depending on which runtimes are
5347 used. */
5349 static tree
5350 receiver_is_class_object (tree receiver, int self, int super)
5352 tree chain, exp, arg;
5354 /* The receiver is 'self' or 'super' in the context of a class method. */
5355 if (objc_method_context
5356 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5357 && (self || super))
5358 return (super
5359 ? CLASS_SUPER_NAME (implementation_template)
5360 : CLASS_NAME (implementation_template));
5362 if (flag_next_runtime)
5364 /* The receiver is a variable created by
5365 build_class_reference_decl. */
5366 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
5367 /* Look up the identifier. */
5368 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5369 if (TREE_PURPOSE (chain) == receiver)
5370 return TREE_VALUE (chain);
5373 /* The receiver is a function call that returns an id. Check if
5374 it is a call to objc_getClass, if so, pick up the class name. */
5375 if (TREE_CODE (receiver) == CALL_EXPR
5376 && (exp = TREE_OPERAND (receiver, 0))
5377 && TREE_CODE (exp) == ADDR_EXPR
5378 && (exp = TREE_OPERAND (exp, 0))
5379 && TREE_CODE (exp) == FUNCTION_DECL
5380 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5381 prototypes for objc_get_class(). Thankfully, they seem to share the
5382 same function type. */
5383 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5384 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5385 /* We have a call to objc_get_class/objc_getClass! */
5386 && (arg = TREE_OPERAND (receiver, 1))
5387 && TREE_CODE (arg) == TREE_LIST
5388 && (arg = TREE_VALUE (arg)))
5390 STRIP_NOPS (arg);
5391 if (TREE_CODE (arg) == ADDR_EXPR
5392 && (arg = TREE_OPERAND (arg, 0))
5393 && TREE_CODE (arg) == STRING_CST)
5394 /* Finally, we have the class name. */
5395 return get_identifier (TREE_STRING_POINTER (arg));
5397 return 0;
5400 /* If we are currently building a message expr, this holds
5401 the identifier of the selector of the message. This is
5402 used when printing warnings about argument mismatches. */
5404 static tree current_objc_message_selector = 0;
5406 tree
5407 objc_message_selector (void)
5409 return current_objc_message_selector;
5412 /* Construct an expression for sending a message.
5413 MESS has the object to send to in TREE_PURPOSE
5414 and the argument list (including selector) in TREE_VALUE.
5416 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5417 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5419 tree
5420 objc_build_message_expr (tree mess)
5422 tree receiver = TREE_PURPOSE (mess);
5423 tree sel_name;
5424 #ifdef OBJCPLUS
5425 tree args = TREE_PURPOSE (TREE_VALUE (mess));
5426 #else
5427 tree args = TREE_VALUE (mess);
5428 #endif
5429 tree method_params = NULL_TREE;
5431 if (TREE_CODE (receiver) == ERROR_MARK)
5432 return error_mark_node;
5434 /* Obtain the full selector name. */
5435 if (TREE_CODE (args) == IDENTIFIER_NODE)
5436 /* A unary selector. */
5437 sel_name = args;
5438 else if (TREE_CODE (args) == TREE_LIST)
5439 sel_name = build_keyword_selector (args);
5440 else
5441 abort ();
5443 /* Build the parameter list to give to the method. */
5444 if (TREE_CODE (args) == TREE_LIST)
5445 #ifdef OBJCPLUS
5446 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
5447 #else
5449 tree chain = args, prev = NULL_TREE;
5451 /* We have a keyword selector--check for comma expressions. */
5452 while (chain)
5454 tree element = TREE_VALUE (chain);
5456 /* We have a comma expression, must collapse... */
5457 if (TREE_CODE (element) == TREE_LIST)
5459 if (prev)
5460 TREE_CHAIN (prev) = element;
5461 else
5462 args = element;
5464 prev = chain;
5465 chain = TREE_CHAIN (chain);
5467 method_params = args;
5469 #endif
5471 #ifdef OBJCPLUS
5472 if (processing_template_decl)
5473 /* Must wait until template instantiation time. */
5474 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5475 method_params);
5476 #endif
5478 return objc_finish_message_expr (receiver, sel_name, method_params);
5481 /* Look up method SEL_NAME that would be suitable for receiver
5482 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5483 nonzero), and report on any duplicates. */
5485 static tree
5486 lookup_method_in_hash_lists (tree sel_name, int is_class)
5488 hash method_prototype = NULL;
5490 if (!is_class)
5491 method_prototype = hash_lookup (nst_method_hash_list,
5492 sel_name);
5494 if (!method_prototype)
5496 method_prototype = hash_lookup (cls_method_hash_list,
5497 sel_name);
5498 is_class = 1;
5501 return check_duplicates (method_prototype, 1, is_class);
5504 /* The 'objc_finish_message_expr' routine is called from within
5505 'objc_build_message_expr' for non-template functions. In the case of
5506 C++ template functions, it is called from 'build_expr_from_tree'
5507 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5509 tree
5510 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
5512 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5513 tree selector, retval, class_tree;
5514 int self, super, have_cast;
5516 /* Extract the receiver of the message, as well as its type
5517 (where the latter may take the form of a cast or be inferred
5518 from the implementation context). */
5519 rtype = receiver;
5520 while (TREE_CODE (rtype) == COMPOUND_EXPR
5521 || TREE_CODE (rtype) == MODIFY_EXPR
5522 || TREE_CODE (rtype) == NOP_EXPR
5523 || TREE_CODE (rtype) == CONVERT_EXPR
5524 || TREE_CODE (rtype) == COMPONENT_REF)
5525 rtype = TREE_OPERAND (rtype, 0);
5526 self = (rtype == self_decl);
5527 super = (rtype == UOBJC_SUPER_decl);
5528 rtype = TREE_TYPE (receiver);
5529 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5530 || (TREE_CODE (receiver) == COMPOUND_EXPR
5531 && !IS_SUPER (rtype)));
5533 /* If the receiver is a class object, retrieve the corresponding
5534 @interface, if one exists. */
5535 class_tree = receiver_is_class_object (receiver, self, super);
5537 /* Now determine the receiver type (if an explicit cast has not been
5538 provided). */
5539 if (!have_cast)
5541 if (class_tree)
5542 rtype = lookup_interface (class_tree);
5543 /* Handle `self' and `super'. */
5544 else if (super)
5546 if (!CLASS_SUPER_NAME (implementation_template))
5548 error ("no super class declared in @interface for `%s'",
5549 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5550 return error_mark_node;
5552 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5554 else if (self)
5555 rtype = lookup_interface (CLASS_NAME (implementation_template));
5558 /* If receiver is of type `id' or `Class' (or if the @interface for a
5559 class is not visible), we shall be satisfied with the existence of
5560 any instance or class method. */
5561 if (!rtype || objc_is_id (rtype))
5563 if (!rtype)
5564 rtype = xref_tag (RECORD_TYPE, class_tree);
5565 else if (IS_ID (rtype))
5567 rprotos = TYPE_PROTOCOL_LIST (rtype);
5568 rtype = NULL_TREE;
5570 else
5572 class_tree = objc_class_name;
5573 OBJC_SET_TYPE_NAME (rtype, class_tree);
5576 if (rprotos)
5577 method_prototype
5578 = lookup_method_in_protocol_list (rprotos, sel_name,
5579 class_tree != NULL_TREE);
5580 if (!method_prototype && !rprotos)
5581 method_prototype
5582 = lookup_method_in_hash_lists (sel_name,
5583 class_tree != NULL_TREE);
5585 else
5587 tree orig_rtype = rtype, saved_rtype;
5589 if (TREE_CODE (rtype) == POINTER_TYPE)
5590 rtype = TREE_TYPE (rtype);
5591 /* Traverse typedef aliases */
5592 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
5593 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
5594 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
5595 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
5596 saved_rtype = rtype;
5597 if (TYPED_OBJECT (rtype))
5599 rprotos = TYPE_PROTOCOL_LIST (rtype);
5600 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5602 /* If we could not find an @interface declaration, we must have
5603 only seen a @class declaration; so, we cannot say anything
5604 more intelligent about which methods the receiver will
5605 understand. */
5606 if (!rtype)
5607 rtype = saved_rtype;
5608 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5609 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5611 /* We have a valid ObjC class name. Look up the method name
5612 in the published @interface for the class (and its
5613 superclasses). */
5614 method_prototype
5615 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
5617 /* If the method was not found in the @interface, it may still
5618 exist locally as part of the @implementation. */
5619 if (!method_prototype && objc_implementation_context
5620 && CLASS_NAME (objc_implementation_context)
5621 == OBJC_TYPE_NAME (rtype))
5622 method_prototype
5623 = lookup_method
5624 ((class_tree
5625 ? CLASS_CLS_METHODS (objc_implementation_context)
5626 : CLASS_NST_METHODS (objc_implementation_context)),
5627 sel_name);
5629 /* If we haven't found a candidate method by now, try looking for
5630 it in the protocol list. */
5631 if (!method_prototype && rprotos)
5632 method_prototype
5633 = lookup_method_in_protocol_list (rprotos, sel_name,
5634 class_tree != NULL_TREE);
5636 else
5638 warning ("invalid receiver type `%s'",
5639 gen_type_name (orig_rtype));
5640 rtype = rprotos = NULL_TREE;
5644 if (!method_prototype)
5646 static bool warn_missing_methods = false;
5648 if (rtype)
5649 warning ("`%s' may not respond to `%c%s'",
5650 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5651 (class_tree ? '+' : '-'),
5652 IDENTIFIER_POINTER (sel_name));
5653 if (rprotos)
5654 warning ("`%c%s' not implemented by protocol(s)",
5655 (class_tree ? '+' : '-'),
5656 IDENTIFIER_POINTER (sel_name));
5657 if (!warn_missing_methods)
5659 warning ("(Messages without a matching method signature");
5660 warning ("will be assumed to return `id' and accept");
5661 warning ("`...' as arguments.)");
5662 warn_missing_methods = true;
5666 /* Save the selector name for printing error messages. */
5667 current_objc_message_selector = sel_name;
5669 /* Build the parameters list for looking up the method.
5670 These are the object itself and the selector. */
5672 if (flag_typed_selectors)
5673 selector = build_typed_selector_reference (sel_name, method_prototype);
5674 else
5675 selector = build_selector_reference (sel_name);
5677 retval = build_objc_method_call (super, method_prototype,
5678 receiver,
5679 selector, method_params);
5681 current_objc_message_selector = 0;
5683 return retval;
5686 /* Build a tree expression to send OBJECT the operation SELECTOR,
5687 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5688 assuming the method has prototype METHOD_PROTOTYPE.
5689 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5690 Use METHOD_PARAMS as list of args to pass to the method.
5691 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5693 static tree
5694 build_objc_method_call (int super_flag, tree method_prototype,
5695 tree lookup_object, tree selector,
5696 tree method_params)
5698 tree sender = (super_flag ? umsg_super_decl :
5699 (!flag_next_runtime || flag_nil_receivers
5700 ? umsg_decl
5701 : umsg_nonnil_decl));
5702 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
5704 /* If a prototype for the method to be called exists, then cast
5705 the sender's return type and arguments to match that of the method.
5706 Otherwise, leave sender as is. */
5707 tree ret_type
5708 = (method_prototype
5709 ? TREE_VALUE (TREE_TYPE (method_prototype))
5710 : objc_object_type);
5711 tree sender_cast
5712 = build_pointer_type
5713 (build_function_type
5714 (ret_type,
5715 get_arg_type_list
5716 (method_prototype, METHOD_REF, super_flag)));
5717 tree method, t;
5719 lookup_object = build_c_cast (rcv_p, lookup_object);
5721 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
5722 lookup_object = save_expr (lookup_object);
5724 if (flag_next_runtime)
5726 /* If we are returning a struct in memory, and the address
5727 of that memory location is passed as a hidden first
5728 argument, then change which messenger entry point this
5729 expr will call. NB: Note that sender_cast remains
5730 unchanged (it already has a struct return type). */
5731 if (!targetm.calls.struct_value_rtx (0, 0)
5732 && (TREE_CODE (ret_type) == RECORD_TYPE
5733 || TREE_CODE (ret_type) == UNION_TYPE)
5734 && targetm.calls.return_in_memory (ret_type, 0))
5735 sender = (super_flag ? umsg_super_stret_decl :
5736 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5738 method_params = tree_cons (NULL_TREE, lookup_object,
5739 tree_cons (NULL_TREE, selector,
5740 method_params));
5741 method = build_fold_addr_expr (sender);
5743 else
5745 /* This is the portable (GNU) way. */
5746 tree object;
5748 /* First, call the lookup function to get a pointer to the method,
5749 then cast the pointer, then call it with the method arguments. */
5751 object = (super_flag ? self_decl : lookup_object);
5753 t = tree_cons (NULL_TREE, selector, NULL_TREE);
5754 t = tree_cons (NULL_TREE, lookup_object, t);
5755 method = build_function_call (sender, t);
5757 /* Pass the object to the method. */
5758 method_params = tree_cons (NULL_TREE, object,
5759 tree_cons (NULL_TREE, selector,
5760 method_params));
5763 /* ??? Selector is not at this point something we can use inside
5764 the compiler itself. Set it to garbage for the nonce. */
5765 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
5766 return build_function_call (t, method_params);
5769 static void
5770 build_protocol_reference (tree p)
5772 tree decl;
5773 const char *proto_name;
5775 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
5777 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5778 decl = start_var_decl (objc_protocol_template, proto_name);
5780 PROTOCOL_FORWARD_DECL (p) = decl;
5783 /* This function is called by the parser when (and only when) a
5784 @protocol() expression is found, in order to compile it. */
5785 tree
5786 objc_build_protocol_expr (tree protoname)
5788 tree expr;
5789 tree p = lookup_protocol (protoname);
5791 if (!p)
5793 error ("cannot find protocol declaration for `%s'",
5794 IDENTIFIER_POINTER (protoname));
5795 return error_mark_node;
5798 if (!PROTOCOL_FORWARD_DECL (p))
5799 build_protocol_reference (p);
5801 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5803 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5804 if we have it, rather than converting it here. */
5805 expr = convert (objc_protocol_type, expr);
5807 /* The @protocol() expression is being compiled into a pointer to a
5808 statically allocated instance of the Protocol class. To become
5809 usable at runtime, the 'isa' pointer of the instance need to be
5810 fixed up at runtime by the runtime library, to point to the
5811 actual 'Protocol' class. */
5813 /* For the GNU runtime, put the static Protocol instance in the list
5814 of statically allocated instances, so that we make sure that its
5815 'isa' pointer is fixed up at runtime by the GNU runtime library
5816 to point to the Protocol class (at runtime, when loading the
5817 module, the GNU runtime library loops on the statically allocated
5818 instances (as found in the defs field in objc_symtab) and fixups
5819 all the 'isa' pointers of those objects). */
5820 if (! flag_next_runtime)
5822 /* This type is a struct containing the fields of a Protocol
5823 object. (Cfr. objc_protocol_type instead is the type of a pointer
5824 to such a struct). */
5825 tree protocol_struct_type = xref_tag
5826 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5827 tree *chain;
5829 /* Look for the list of Protocol statically allocated instances
5830 to fixup at runtime. Create a new list to hold Protocol
5831 statically allocated instances, if the list is not found. At
5832 present there is only another list, holding NSConstantString
5833 static instances to be fixed up at runtime. */
5834 for (chain = &objc_static_instances;
5835 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5836 chain = &TREE_CHAIN (*chain));
5837 if (!*chain)
5839 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5840 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
5841 class_names);
5844 /* Add this statically allocated instance to the Protocol list. */
5845 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5846 PROTOCOL_FORWARD_DECL (p),
5847 TREE_PURPOSE (*chain));
5851 return expr;
5854 /* This function is called by the parser when a @selector() expression
5855 is found, in order to compile it. It is only called by the parser
5856 and only to compile a @selector(). */
5857 tree
5858 objc_build_selector_expr (tree selnamelist)
5860 tree selname;
5862 /* Obtain the full selector name. */
5863 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5864 /* A unary selector. */
5865 selname = selnamelist;
5866 else if (TREE_CODE (selnamelist) == TREE_LIST)
5867 selname = build_keyword_selector (selnamelist);
5868 else
5869 abort ();
5871 /* If we are required to check @selector() expressions as they
5872 are found, check that the selector has been declared. */
5873 if (warn_undeclared_selector)
5875 /* Look the selector up in the list of all known class and
5876 instance methods (up to this line) to check that the selector
5877 exists. */
5878 hash hsh;
5880 /* First try with instance methods. */
5881 hsh = hash_lookup (nst_method_hash_list, selname);
5883 /* If not found, try with class methods. */
5884 if (!hsh)
5886 hsh = hash_lookup (cls_method_hash_list, selname);
5889 /* If still not found, print out a warning. */
5890 if (!hsh)
5892 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5897 if (flag_typed_selectors)
5898 return build_typed_selector_reference (selname, 0);
5899 else
5900 return build_selector_reference (selname);
5903 tree
5904 objc_build_encode_expr (tree type)
5906 tree result;
5907 const char *string;
5909 encode_type (type, obstack_object_size (&util_obstack),
5910 OBJC_ENCODE_INLINE_DEFS);
5911 obstack_1grow (&util_obstack, 0); /* null terminate string */
5912 string = obstack_finish (&util_obstack);
5914 /* Synthesize a string that represents the encoded struct/union. */
5915 result = my_build_string (strlen (string) + 1, string);
5916 obstack_free (&util_obstack, util_firstobj);
5917 return result;
5920 static tree
5921 build_ivar_reference (tree id)
5923 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5925 /* Historically, a class method that produced objects (factory
5926 method) would assign `self' to the instance that it
5927 allocated. This would effectively turn the class method into
5928 an instance method. Following this assignment, the instance
5929 variables could be accessed. That practice, while safe,
5930 violates the simple rule that a class method should not refer
5931 to an instance variable. It's better to catch the cases
5932 where this is done unknowingly than to support the above
5933 paradigm. */
5934 warning ("instance variable `%s' accessed in class method",
5935 IDENTIFIER_POINTER (id));
5936 self_decl = convert (objc_instance_type, self_decl); /* cast */
5939 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5942 /* Compute a hash value for a given method SEL_NAME. */
5944 static size_t
5945 hash_func (tree sel_name)
5947 const unsigned char *s
5948 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5949 size_t h = 0;
5951 while (*s)
5952 h = h * 67 + *s++ - 113;
5953 return h;
5956 static void
5957 hash_init (void)
5959 nst_method_hash_list
5960 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
5961 cls_method_hash_list
5962 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
5964 /* Initialize the hash table used to hold the constant string objects. */
5965 string_htab = htab_create_ggc (31, string_hash,
5966 string_eq, NULL);
5969 /* WARNING!!!! hash_enter is called with a method, and will peek
5970 inside to find its selector! But hash_lookup is given a selector
5971 directly, and looks for the selector that's inside the found
5972 entry's key (method) for comparison. */
5974 static void
5975 hash_enter (hash *hashlist, tree method)
5977 hash obj;
5978 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5980 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5981 obj->list = 0;
5982 obj->next = hashlist[slot];
5983 obj->key = method;
5985 hashlist[slot] = obj; /* append to front */
5988 static hash
5989 hash_lookup (hash *hashlist, tree sel_name)
5991 hash target;
5993 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5995 while (target)
5997 if (sel_name == METHOD_SEL_NAME (target->key))
5998 return target;
6000 target = target->next;
6002 return 0;
6005 static void
6006 hash_add_attr (hash entry, tree value)
6008 attr obj;
6010 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6011 obj->next = entry->list;
6012 obj->value = value;
6014 entry->list = obj; /* append to front */
6017 static tree
6018 lookup_method (tree mchain, tree method)
6020 tree key;
6022 if (TREE_CODE (method) == IDENTIFIER_NODE)
6023 key = method;
6024 else
6025 key = METHOD_SEL_NAME (method);
6027 while (mchain)
6029 if (METHOD_SEL_NAME (mchain) == key)
6030 return mchain;
6032 mchain = TREE_CHAIN (mchain);
6034 return NULL_TREE;
6037 static tree
6038 lookup_method_static (tree interface, tree ident, int is_class)
6040 tree meth = NULL_TREE, root_inter = NULL_TREE;
6041 tree inter = interface;
6043 while (inter)
6045 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6046 tree category = inter;
6048 /* First, look up the method in the class itself. */
6049 if ((meth = lookup_method (chain, ident)))
6050 return meth;
6052 /* Failing that, look for the method in each category of the class. */
6053 while ((category = CLASS_CATEGORY_LIST (category)))
6055 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6057 /* Check directly in each category. */
6058 if ((meth = lookup_method (chain, ident)))
6059 return meth;
6061 /* Failing that, check in each category's protocols. */
6062 if (CLASS_PROTOCOL_LIST (category))
6064 if ((meth = (lookup_method_in_protocol_list
6065 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6066 return meth;
6070 /* If not found in categories, check in protocols of the main class. */
6071 if (CLASS_PROTOCOL_LIST (inter))
6073 if ((meth = (lookup_method_in_protocol_list
6074 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6075 return meth;
6078 /* Failing that, climb up the inheritance hierarchy. */
6079 root_inter = inter;
6080 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6082 while (inter);
6084 /* If no class (factory) method was found, check if an _instance_
6085 method of the same name exists in the root class. This is what
6086 the Objective-C runtime will do. If an instance method was not
6087 found, return 0. */
6088 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6091 /* Add the method to the hash list if it doesn't contain an identical
6092 method already. */
6093 static void
6094 add_method_to_hash_list (hash *hash_list, tree method)
6096 hash hsh;
6098 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6100 /* Install on a global chain. */
6101 hash_enter (hash_list, method);
6103 else
6105 /* Check types against those; if different, add to a list. */
6106 attr loop;
6107 int already_there = comp_proto_with_proto (method, hsh->key);
6108 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6109 already_there |= comp_proto_with_proto (method, loop->value);
6110 if (!already_there)
6111 hash_add_attr (hsh, method);
6115 static tree
6116 objc_add_method (tree class, tree method, int is_class)
6118 tree mth;
6120 if (!(mth = lookup_method (is_class
6121 ? CLASS_CLS_METHODS (class)
6122 : CLASS_NST_METHODS (class), method)))
6124 /* put method on list in reverse order */
6125 if (is_class)
6127 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6128 CLASS_CLS_METHODS (class) = method;
6130 else
6132 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6133 CLASS_NST_METHODS (class) = method;
6136 else
6138 /* When processing an @interface for a class or category, give hard
6139 errors on methods with identical selectors but differing argument
6140 and/or return types. We do not do this for @implementations, because
6141 C/C++ will do it for us (i.e., there will be duplicate function
6142 definition errors). */
6143 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6144 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6145 && !comp_proto_with_proto (method, mth))
6146 error ("duplicate declaration of method `%c%s'",
6147 is_class ? '+' : '-',
6148 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6151 if (is_class)
6152 add_method_to_hash_list (cls_method_hash_list, method);
6153 else
6155 add_method_to_hash_list (nst_method_hash_list, method);
6157 /* Instance methods in root classes (and categories thereof)
6158 may acts as class methods as a last resort. */
6159 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6160 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6161 class = lookup_interface (CLASS_NAME (class));
6163 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6164 && !CLASS_SUPER_NAME (class))
6165 add_method_to_hash_list (cls_method_hash_list, method);
6168 return method;
6171 static tree
6172 add_class (tree class)
6174 /* Put interfaces on list in reverse order. */
6175 TREE_CHAIN (class) = interface_chain;
6176 interface_chain = class;
6177 return interface_chain;
6180 static void
6181 add_category (tree class, tree category)
6183 /* Put categories on list in reverse order. */
6184 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6186 if (cat)
6188 warning ("duplicate interface declaration for category `%s(%s)'",
6189 IDENTIFIER_POINTER (CLASS_NAME (class)),
6190 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6192 else
6194 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6195 CLASS_CATEGORY_LIST (class) = category;
6199 /* Called after parsing each instance variable declaration. Necessary to
6200 preserve typedefs and implement public/private...
6202 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6204 static tree
6205 add_instance_variable (tree class, int public, tree field_decl)
6207 tree field_type = TREE_TYPE (field_decl);
6208 const char *ivar_name = DECL_NAME (field_decl)
6209 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6210 : "<unnamed>";
6212 #ifdef OBJCPLUS
6213 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6215 error ("illegal reference type specified for instance variable `%s'",
6216 ivar_name);
6217 /* Return class as is without adding this ivar. */
6218 return class;
6220 #endif
6222 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6223 || TYPE_SIZE (field_type) == error_mark_node)
6224 /* 'type[0]' is allowed, but 'type[]' is not! */
6226 error ("instance variable `%s' has unknown size", ivar_name);
6227 /* Return class as is without adding this ivar. */
6228 return class;
6231 #ifdef OBJCPLUS
6232 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6233 cannot be ivars; ditto for classes with vtables. */
6234 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6235 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6237 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6238 if(TYPE_POLYMORPHIC_P (field_type)) {
6239 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6240 error ("type `%s' has virtual member functions", type_name);
6241 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6242 type_name, ivar_name);
6243 /* Return class as is without adding this ivar. */
6244 return class;
6246 /* user-defined constructors and destructors are not known to Obj-C and
6247 hence will not be called. This may or may not be a problem. */
6248 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6249 warning ("type `%s' has a user-defined constructor", type_name);
6250 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6251 warning ("type `%s' has a user-defined destructor", type_name);
6252 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6254 #endif
6256 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6257 switch (public)
6259 case 0:
6260 TREE_PUBLIC (field_decl) = 0;
6261 TREE_PRIVATE (field_decl) = 0;
6262 TREE_PROTECTED (field_decl) = 1;
6263 break;
6265 case 1:
6266 TREE_PUBLIC (field_decl) = 1;
6267 TREE_PRIVATE (field_decl) = 0;
6268 TREE_PROTECTED (field_decl) = 0;
6269 break;
6271 case 2:
6272 TREE_PUBLIC (field_decl) = 0;
6273 TREE_PRIVATE (field_decl) = 1;
6274 TREE_PROTECTED (field_decl) = 0;
6275 break;
6279 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
6281 return class;
6284 static tree
6285 is_ivar (tree decl_chain, tree ident)
6287 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6288 if (DECL_NAME (decl_chain) == ident)
6289 return decl_chain;
6290 return NULL_TREE;
6293 /* True if the ivar is private and we are not in its implementation. */
6295 static int
6296 is_private (tree decl)
6298 return (TREE_PRIVATE (decl)
6299 && ! is_ivar (CLASS_IVARS (implementation_template),
6300 DECL_NAME (decl)));
6303 /* We have an instance variable reference;, check to see if it is public. */
6306 objc_is_public (tree expr, tree identifier)
6308 tree basetype = TREE_TYPE (expr);
6309 enum tree_code code = TREE_CODE (basetype);
6310 tree decl;
6312 if (code == RECORD_TYPE)
6314 if (TREE_STATIC_TEMPLATE (basetype))
6316 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6318 error ("cannot find interface declaration for `%s'",
6319 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6320 return 0;
6323 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6325 if (TREE_PUBLIC (decl))
6326 return 1;
6328 /* Important difference between the Stepstone translator:
6329 all instance variables should be public within the context
6330 of the implementation. */
6331 if (objc_implementation_context
6332 && (((TREE_CODE (objc_implementation_context)
6333 == CLASS_IMPLEMENTATION_TYPE)
6334 || (TREE_CODE (objc_implementation_context)
6335 == CATEGORY_IMPLEMENTATION_TYPE))
6336 && (CLASS_NAME (objc_implementation_context)
6337 == OBJC_TYPE_NAME (basetype))))
6339 int private = is_private (decl);
6341 if (private)
6342 error ("instance variable `%s' is declared private",
6343 IDENTIFIER_POINTER (DECL_NAME (decl)));
6344 return !private;
6347 /* The 2.95.2 compiler sometimes allowed C functions to access
6348 non-@public ivars. We will let this slide for now... */
6349 if (!objc_method_context)
6351 warning ("instance variable `%s' is %s; "
6352 "this will be a hard error in the future",
6353 IDENTIFIER_POINTER (identifier),
6354 TREE_PRIVATE (decl) ? "@private" : "@protected");
6355 return 1;
6358 error ("instance variable `%s' is declared %s",
6359 IDENTIFIER_POINTER (identifier),
6360 TREE_PRIVATE (decl) ? "private" : "protected");
6361 return 0;
6365 else if (objc_implementation_context && (basetype == objc_object_reference))
6367 expr = convert (uprivate_record, expr);
6368 warning ("static access to object of type `id'");
6372 return 1;
6375 /* Make sure all entries in CHAIN are also in LIST. */
6377 static int
6378 check_methods (tree chain, tree list, int mtype)
6380 int first = 1;
6382 while (chain)
6384 if (!lookup_method (list, chain))
6386 if (first)
6388 if (TREE_CODE (objc_implementation_context)
6389 == CLASS_IMPLEMENTATION_TYPE)
6390 warning ("incomplete implementation of class `%s'",
6391 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6392 else if (TREE_CODE (objc_implementation_context)
6393 == CATEGORY_IMPLEMENTATION_TYPE)
6394 warning ("incomplete implementation of category `%s'",
6395 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6396 first = 0;
6399 warning ("method definition for `%c%s' not found",
6400 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6403 chain = TREE_CHAIN (chain);
6406 return first;
6409 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6411 static int
6412 conforms_to_protocol (tree class, tree protocol)
6414 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6416 tree p = CLASS_PROTOCOL_LIST (class);
6417 while (p && TREE_VALUE (p) != protocol)
6418 p = TREE_CHAIN (p);
6420 if (!p)
6422 tree super = (CLASS_SUPER_NAME (class)
6423 ? lookup_interface (CLASS_SUPER_NAME (class))
6424 : NULL_TREE);
6425 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6426 if (!tmp)
6427 return 0;
6431 return 1;
6434 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6435 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6437 static int
6438 check_methods_accessible (tree chain, tree context, int mtype)
6440 int first = 1;
6441 tree list;
6442 tree base_context = context;
6444 while (chain)
6446 context = base_context;
6447 while (context)
6449 if (mtype == '+')
6450 list = CLASS_CLS_METHODS (context);
6451 else
6452 list = CLASS_NST_METHODS (context);
6454 if (lookup_method (list, chain))
6455 break;
6457 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6458 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6459 context = (CLASS_SUPER_NAME (context)
6460 ? lookup_interface (CLASS_SUPER_NAME (context))
6461 : NULL_TREE);
6463 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6464 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6465 context = (CLASS_NAME (context)
6466 ? lookup_interface (CLASS_NAME (context))
6467 : NULL_TREE);
6468 else
6469 abort ();
6472 if (context == NULL_TREE)
6474 if (first)
6476 if (TREE_CODE (objc_implementation_context)
6477 == CLASS_IMPLEMENTATION_TYPE)
6478 warning ("incomplete implementation of class `%s'",
6479 IDENTIFIER_POINTER
6480 (CLASS_NAME (objc_implementation_context)));
6481 else if (TREE_CODE (objc_implementation_context)
6482 == CATEGORY_IMPLEMENTATION_TYPE)
6483 warning ("incomplete implementation of category `%s'",
6484 IDENTIFIER_POINTER
6485 (CLASS_SUPER_NAME (objc_implementation_context)));
6486 first = 0;
6488 warning ("method definition for `%c%s' not found",
6489 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6492 chain = TREE_CHAIN (chain); /* next method... */
6494 return first;
6497 /* Check whether the current interface (accessible via
6498 'objc_implementation_context') actually implements protocol P, along
6499 with any protocols that P inherits. */
6501 static void
6502 check_protocol (tree p, const char *type, const char *name)
6504 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6506 int f1, f2;
6508 /* Ensure that all protocols have bodies! */
6509 if (warn_protocol)
6511 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6512 CLASS_CLS_METHODS (objc_implementation_context),
6513 '+');
6514 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6515 CLASS_NST_METHODS (objc_implementation_context),
6516 '-');
6518 else
6520 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6521 objc_implementation_context,
6522 '+');
6523 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6524 objc_implementation_context,
6525 '-');
6528 if (!f1 || !f2)
6529 warning ("%s `%s' does not fully implement the `%s' protocol",
6530 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6533 /* Check protocols recursively. */
6534 if (PROTOCOL_LIST (p))
6536 tree subs = PROTOCOL_LIST (p);
6537 tree super_class =
6538 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6540 while (subs)
6542 tree sub = TREE_VALUE (subs);
6544 /* If the superclass does not conform to the protocols
6545 inherited by P, then we must! */
6546 if (!super_class || !conforms_to_protocol (super_class, sub))
6547 check_protocol (sub, type, name);
6548 subs = TREE_CHAIN (subs);
6553 /* Check whether the current interface (accessible via
6554 'objc_implementation_context') actually implements the protocols listed
6555 in PROTO_LIST. */
6557 static void
6558 check_protocols (tree proto_list, const char *type, const char *name)
6560 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6562 tree p = TREE_VALUE (proto_list);
6564 check_protocol (p, type, name);
6568 /* Make sure that the class CLASS_NAME is defined
6569 CODE says which kind of thing CLASS_NAME ought to be.
6570 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6571 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6573 static tree
6574 start_class (enum tree_code code, tree class_name, tree super_name,
6575 tree protocol_list)
6577 tree class, decl;
6579 #ifdef OBJCPLUS
6580 if (current_namespace != global_namespace) {
6581 error ("Objective-C declarations may only appear in global scope");
6583 #endif /* OBJCPLUS */
6585 if (objc_implementation_context)
6587 warning ("`@end' missing in implementation context");
6588 finish_class (objc_implementation_context);
6589 objc_ivar_chain = NULL_TREE;
6590 objc_implementation_context = NULL_TREE;
6593 class = make_node (code);
6594 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
6596 /* Check for existence of the super class, if one was specified. */
6597 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
6598 && super_name && !objc_is_class_name (super_name))
6600 error ("cannot find interface declaration for `%s', superclass of `%s'",
6601 IDENTIFIER_POINTER (super_name),
6602 IDENTIFIER_POINTER (class_name));
6603 super_name = NULL_TREE;
6606 CLASS_NAME (class) = class_name;
6607 CLASS_SUPER_NAME (class) = super_name;
6608 CLASS_CLS_METHODS (class) = NULL_TREE;
6610 if (! objc_is_class_name (class_name)
6611 && (decl = lookup_name (class_name)))
6613 error ("`%s' redeclared as different kind of symbol",
6614 IDENTIFIER_POINTER (class_name));
6615 error ("%Jprevious declaration of '%D'",
6616 decl, decl);
6619 if (code == CLASS_IMPLEMENTATION_TYPE)
6622 tree chain;
6624 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6625 if (TREE_VALUE (chain) == class_name)
6627 error ("reimplementation of class `%s'",
6628 IDENTIFIER_POINTER (class_name));
6629 return error_mark_node;
6631 implemented_classes = tree_cons (NULL_TREE, class_name,
6632 implemented_classes);
6635 /* Reset for multiple classes per file. */
6636 method_slot = 0;
6638 objc_implementation_context = class;
6640 /* Lookup the interface for this implementation. */
6642 if (!(implementation_template = lookup_interface (class_name)))
6644 warning ("cannot find interface declaration for `%s'",
6645 IDENTIFIER_POINTER (class_name));
6646 add_class (implementation_template = objc_implementation_context);
6649 /* If a super class has been specified in the implementation,
6650 insure it conforms to the one specified in the interface. */
6652 if (super_name
6653 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6655 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6656 const char *const name =
6657 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6658 error ("conflicting super class name `%s'",
6659 IDENTIFIER_POINTER (super_name));
6660 error ("previous declaration of `%s'", name);
6663 else if (! super_name)
6665 CLASS_SUPER_NAME (objc_implementation_context)
6666 = CLASS_SUPER_NAME (implementation_template);
6670 else if (code == CLASS_INTERFACE_TYPE)
6672 if (lookup_interface (class_name))
6673 #ifdef OBJCPLUS
6674 error ("duplicate interface declaration for class `%s'",
6675 #else
6676 warning ("duplicate interface declaration for class `%s'",
6677 #endif
6678 IDENTIFIER_POINTER (class_name));
6679 else
6680 add_class (class);
6682 if (protocol_list)
6683 CLASS_PROTOCOL_LIST (class)
6684 = lookup_and_install_protocols (protocol_list);
6687 else if (code == CATEGORY_INTERFACE_TYPE)
6689 tree class_category_is_assoc_with;
6691 /* For a category, class_name is really the name of the class that
6692 the following set of methods will be associated with. We must
6693 find the interface so that can derive the objects template. */
6695 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6697 error ("cannot find interface declaration for `%s'",
6698 IDENTIFIER_POINTER (class_name));
6699 exit (FATAL_EXIT_CODE);
6701 else
6702 add_category (class_category_is_assoc_with, class);
6704 if (protocol_list)
6705 CLASS_PROTOCOL_LIST (class)
6706 = lookup_and_install_protocols (protocol_list);
6709 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6711 /* Reset for multiple classes per file. */
6712 method_slot = 0;
6714 objc_implementation_context = class;
6716 /* For a category, class_name is really the name of the class that
6717 the following set of methods will be associated with. We must
6718 find the interface so that can derive the objects template. */
6720 if (!(implementation_template = lookup_interface (class_name)))
6722 error ("cannot find interface declaration for `%s'",
6723 IDENTIFIER_POINTER (class_name));
6724 exit (FATAL_EXIT_CODE);
6727 return class;
6730 static tree
6731 continue_class (tree class)
6733 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6734 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6736 struct imp_entry *imp_entry;
6737 tree ivar_context;
6739 /* Check consistency of the instance variables. */
6741 if (CLASS_RAW_IVARS (class))
6742 check_ivars (implementation_template, class);
6744 /* code generation */
6746 #ifdef OBJCPLUS
6747 push_lang_context (lang_name_c);
6748 #endif
6750 ivar_context = build_private_template (implementation_template);
6752 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6754 imp_entry->next = imp_list;
6755 imp_entry->imp_context = class;
6756 imp_entry->imp_template = implementation_template;
6758 synth_forward_declarations ();
6759 imp_entry->class_decl = UOBJC_CLASS_decl;
6760 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6762 /* Append to front and increment count. */
6763 imp_list = imp_entry;
6764 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6765 imp_count++;
6766 else
6767 cat_count++;
6769 #ifdef OBJCPLUS
6770 pop_lang_context ();
6771 #endif /* OBJCPLUS */
6773 return ivar_context;
6776 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6778 #ifdef OBJCPLUS
6779 push_lang_context (lang_name_c);
6780 #endif /* OBJCPLUS */
6782 if (!CLASS_STATIC_TEMPLATE (class))
6784 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6785 finish_struct (record, get_class_ivars (class), NULL_TREE);
6786 CLASS_STATIC_TEMPLATE (class) = record;
6788 /* Mark this record as a class template for static typing. */
6789 TREE_STATIC_TEMPLATE (record) = 1;
6792 #ifdef OBJCPLUS
6793 pop_lang_context ();
6794 #endif /* OBJCPLUS */
6796 return NULL_TREE;
6799 else
6800 return error_mark_node;
6803 /* This is called once we see the "@end" in an interface/implementation. */
6805 static void
6806 finish_class (tree class)
6808 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6810 /* All code generation is done in finish_objc. */
6812 if (implementation_template != objc_implementation_context)
6814 /* Ensure that all method listed in the interface contain bodies. */
6815 check_methods (CLASS_CLS_METHODS (implementation_template),
6816 CLASS_CLS_METHODS (objc_implementation_context), '+');
6817 check_methods (CLASS_NST_METHODS (implementation_template),
6818 CLASS_NST_METHODS (objc_implementation_context), '-');
6820 if (CLASS_PROTOCOL_LIST (implementation_template))
6821 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6822 "class",
6823 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6827 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6829 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6831 if (category)
6833 /* Ensure all method listed in the interface contain bodies. */
6834 check_methods (CLASS_CLS_METHODS (category),
6835 CLASS_CLS_METHODS (objc_implementation_context), '+');
6836 check_methods (CLASS_NST_METHODS (category),
6837 CLASS_NST_METHODS (objc_implementation_context), '-');
6839 if (CLASS_PROTOCOL_LIST (category))
6840 check_protocols (CLASS_PROTOCOL_LIST (category),
6841 "category",
6842 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6846 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6848 tree decl;
6849 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6850 char *string = (char *) alloca (strlen (class_name) + 3);
6852 /* extern struct objc_object *_<my_name>; */
6854 sprintf (string, "_%s", class_name);
6856 decl = build_decl (VAR_DECL, get_identifier (string),
6857 build_pointer_type (objc_object_reference));
6858 DECL_EXTERNAL (decl) = 1;
6859 lang_hooks.decls.pushdecl (decl);
6860 finish_decl (decl, NULL_TREE, NULL_TREE);
6864 static tree
6865 add_protocol (tree protocol)
6867 /* Put protocol on list in reverse order. */
6868 TREE_CHAIN (protocol) = protocol_chain;
6869 protocol_chain = protocol;
6870 return protocol_chain;
6873 static tree
6874 lookup_protocol (tree ident)
6876 tree chain;
6878 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6879 if (ident == PROTOCOL_NAME (chain))
6880 return chain;
6882 return NULL_TREE;
6885 /* This function forward declares the protocols named by NAMES. If
6886 they are already declared or defined, the function has no effect. */
6888 void
6889 objc_declare_protocols (tree names)
6891 tree list;
6893 #ifdef OBJCPLUS
6894 if (current_namespace != global_namespace) {
6895 error ("Objective-C declarations may only appear in global scope");
6897 #endif /* OBJCPLUS */
6899 for (list = names; list; list = TREE_CHAIN (list))
6901 tree name = TREE_VALUE (list);
6903 if (lookup_protocol (name) == NULL_TREE)
6905 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6907 TYPE_LANG_SLOT_1 (protocol)
6908 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
6909 PROTOCOL_NAME (protocol) = name;
6910 PROTOCOL_LIST (protocol) = NULL_TREE;
6911 add_protocol (protocol);
6912 PROTOCOL_DEFINED (protocol) = 0;
6913 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6918 static tree
6919 start_protocol (enum tree_code code, tree name, tree list)
6921 tree protocol;
6923 #ifdef OBJCPLUS
6924 if (current_namespace != global_namespace) {
6925 error ("Objective-C declarations may only appear in global scope");
6927 #endif /* OBJCPLUS */
6929 protocol = lookup_protocol (name);
6931 if (!protocol)
6933 protocol = make_node (code);
6934 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
6936 PROTOCOL_NAME (protocol) = name;
6937 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6938 add_protocol (protocol);
6939 PROTOCOL_DEFINED (protocol) = 1;
6940 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6942 check_protocol_recursively (protocol, list);
6944 else if (! PROTOCOL_DEFINED (protocol))
6946 PROTOCOL_DEFINED (protocol) = 1;
6947 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6949 check_protocol_recursively (protocol, list);
6951 else
6953 warning ("duplicate declaration for protocol `%s'",
6954 IDENTIFIER_POINTER (name));
6956 return protocol;
6960 /* "Encode" a data type into a string, which grows in util_obstack.
6961 ??? What is the FORMAT? Someone please document this! */
6963 static void
6964 encode_type_qualifiers (tree declspecs)
6966 tree spec;
6968 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6970 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6971 obstack_1grow (&util_obstack, 'n');
6972 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6973 obstack_1grow (&util_obstack, 'N');
6974 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6975 obstack_1grow (&util_obstack, 'o');
6976 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6977 obstack_1grow (&util_obstack, 'O');
6978 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6979 obstack_1grow (&util_obstack, 'R');
6980 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6981 obstack_1grow (&util_obstack, 'V');
6985 /* Encode a pointer type. */
6987 static void
6988 encode_pointer (tree type, int curtype, int format)
6990 tree pointer_to = TREE_TYPE (type);
6992 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6994 if (OBJC_TYPE_NAME (pointer_to)
6995 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6997 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
6999 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7001 obstack_1grow (&util_obstack, '@');
7002 return;
7004 else if (TREE_STATIC_TEMPLATE (pointer_to))
7006 if (generating_instance_variables)
7008 obstack_1grow (&util_obstack, '@');
7009 obstack_1grow (&util_obstack, '"');
7010 obstack_grow (&util_obstack, name, strlen (name));
7011 obstack_1grow (&util_obstack, '"');
7012 return;
7014 else
7016 obstack_1grow (&util_obstack, '@');
7017 return;
7020 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7022 obstack_1grow (&util_obstack, '#');
7023 return;
7025 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7027 obstack_1grow (&util_obstack, ':');
7028 return;
7032 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7033 && TYPE_MODE (pointer_to) == QImode)
7035 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7036 ? OBJC_TYPE_NAME (pointer_to)
7037 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7039 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7041 /* It appears that "r*" means "const char *" rather than
7042 "char *const". */
7043 if (TYPE_READONLY (pointer_to))
7044 obstack_1grow (&util_obstack, 'r');
7046 obstack_1grow (&util_obstack, '*');
7047 return;
7051 /* We have a type that does not get special treatment. */
7053 /* NeXT extension */
7054 obstack_1grow (&util_obstack, '^');
7055 encode_type (pointer_to, curtype, format);
7058 static void
7059 encode_array (tree type, int curtype, int format)
7061 tree an_int_cst = TYPE_SIZE (type);
7062 tree array_of = TREE_TYPE (type);
7063 char buffer[40];
7065 /* An incomplete array is treated like a pointer. */
7066 if (an_int_cst == NULL)
7068 encode_pointer (type, curtype, format);
7069 return;
7072 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7073 (TREE_INT_CST_LOW (an_int_cst)
7074 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7076 obstack_grow (&util_obstack, buffer, strlen (buffer));
7077 encode_type (array_of, curtype, format);
7078 obstack_1grow (&util_obstack, ']');
7079 return;
7082 static void
7083 encode_aggregate_within (tree type, int curtype, int format, int left,
7084 int right)
7086 tree name;
7087 /* NB: aggregates that are pointed to have slightly different encoding
7088 rules in that you never encode the names of instance variables. */
7089 int pointed_to
7090 = (obstack_object_size (&util_obstack) > 0
7091 && *(obstack_next_free (&util_obstack) - 1) == '^');
7092 int inline_contents
7093 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7094 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7096 /* Traverse struct aliases; it is important to get the
7097 original struct and its tag name (if any). */
7098 type = TYPE_MAIN_VARIANT (type);
7099 name = OBJC_TYPE_NAME (type);
7100 /* Open parenth/bracket. */
7101 obstack_1grow (&util_obstack, left);
7103 /* Encode the struct/union tag name, or '?' if a tag was
7104 not provided. Typedef aliases do not qualify. */
7105 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7106 #ifdef OBJCPLUS
7107 /* Did this struct have a tag? */
7108 && !TYPE_WAS_ANONYMOUS (type)
7109 #endif
7111 obstack_grow (&util_obstack,
7112 IDENTIFIER_POINTER (name),
7113 strlen (IDENTIFIER_POINTER (name)));
7114 else
7115 obstack_1grow (&util_obstack, '?');
7117 /* Encode the types (and possibly names) of the inner fields,
7118 if required. */
7119 if (inline_contents)
7121 tree fields = TYPE_FIELDS (type);
7123 obstack_1grow (&util_obstack, '=');
7124 for (; fields; fields = TREE_CHAIN (fields))
7126 #ifdef OBJCPLUS
7127 /* C++ static members, and things that are not fields at all,
7128 should not appear in the encoding. */
7129 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7130 continue;
7131 #endif
7132 if (generating_instance_variables && !pointed_to)
7134 tree fname = DECL_NAME (fields);
7136 obstack_1grow (&util_obstack, '"');
7137 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7138 obstack_grow (&util_obstack,
7139 IDENTIFIER_POINTER (fname),
7140 strlen (IDENTIFIER_POINTER (fname)));
7141 obstack_1grow (&util_obstack, '"');
7143 encode_field_decl (fields, curtype, format);
7146 /* Close parenth/bracket. */
7147 obstack_1grow (&util_obstack, right);
7150 static void
7151 encode_aggregate (tree type, int curtype, int format)
7153 enum tree_code code = TREE_CODE (type);
7155 switch (code)
7157 case RECORD_TYPE:
7159 encode_aggregate_within (type, curtype, format, '{', '}');
7160 break;
7162 case UNION_TYPE:
7164 encode_aggregate_within (type, curtype, format, '(', ')');
7165 break;
7168 case ENUMERAL_TYPE:
7169 obstack_1grow (&util_obstack, 'i');
7170 break;
7172 default:
7173 break;
7177 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7178 field type. */
7180 static void
7181 encode_next_bitfield (int width)
7183 char buffer[40];
7184 sprintf (buffer, "b%d", width);
7185 obstack_grow (&util_obstack, buffer, strlen (buffer));
7188 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7189 static void
7190 encode_type (tree type, int curtype, int format)
7192 enum tree_code code = TREE_CODE (type);
7193 char c;
7195 if (TYPE_READONLY (type))
7196 obstack_1grow (&util_obstack, 'r');
7198 if (code == INTEGER_TYPE)
7200 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7202 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7203 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7204 case 32:
7205 if (type == long_unsigned_type_node
7206 || type == long_integer_type_node)
7207 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7208 else
7209 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7210 break;
7211 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7212 default: abort ();
7214 obstack_1grow (&util_obstack, c);
7217 else if (code == REAL_TYPE)
7219 /* Floating point types. */
7220 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7222 case 32: c = 'f'; break;
7223 case 64:
7224 case 128: c = 'd'; break;
7225 default: abort ();
7227 obstack_1grow (&util_obstack, c);
7230 else if (code == VOID_TYPE)
7231 obstack_1grow (&util_obstack, 'v');
7233 else if (code == BOOLEAN_TYPE)
7234 obstack_1grow (&util_obstack, 'B');
7236 else if (code == ARRAY_TYPE)
7237 encode_array (type, curtype, format);
7239 else if (code == POINTER_TYPE)
7240 encode_pointer (type, curtype, format);
7242 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7243 encode_aggregate (type, curtype, format);
7245 else if (code == FUNCTION_TYPE) /* '?' */
7246 obstack_1grow (&util_obstack, '?');
7249 static void
7250 encode_gnu_bitfield (int position, tree type, int size)
7252 enum tree_code code = TREE_CODE (type);
7253 char buffer[40];
7254 char charType = '?';
7256 if (code == INTEGER_TYPE)
7258 if (integer_zerop (TYPE_MIN_VALUE (type)))
7260 /* Unsigned integer types. */
7262 if (TYPE_MODE (type) == QImode)
7263 charType = 'C';
7264 else if (TYPE_MODE (type) == HImode)
7265 charType = 'S';
7266 else if (TYPE_MODE (type) == SImode)
7268 if (type == long_unsigned_type_node)
7269 charType = 'L';
7270 else
7271 charType = 'I';
7273 else if (TYPE_MODE (type) == DImode)
7274 charType = 'Q';
7277 else
7278 /* Signed integer types. */
7280 if (TYPE_MODE (type) == QImode)
7281 charType = 'c';
7282 else if (TYPE_MODE (type) == HImode)
7283 charType = 's';
7284 else if (TYPE_MODE (type) == SImode)
7286 if (type == long_integer_type_node)
7287 charType = 'l';
7288 else
7289 charType = 'i';
7292 else if (TYPE_MODE (type) == DImode)
7293 charType = 'q';
7296 else if (code == ENUMERAL_TYPE)
7297 charType = 'i';
7298 else
7299 abort ();
7301 sprintf (buffer, "b%d%c%d", position, charType, size);
7302 obstack_grow (&util_obstack, buffer, strlen (buffer));
7305 static void
7306 encode_field_decl (tree field_decl, int curtype, int format)
7308 tree type;
7310 #ifdef OBJCPLUS
7311 /* C++ static members, and things that are not fields at all,
7312 should not appear in the encoding. */
7313 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7314 return;
7315 #endif
7317 type = TREE_TYPE (field_decl);
7319 /* Generate the bitfield typing information, if needed. Note the difference
7320 between GNU and NeXT runtimes. */
7321 if (DECL_BIT_FIELD_TYPE (field_decl))
7323 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7325 if (flag_next_runtime)
7326 encode_next_bitfield (size);
7327 else
7328 encode_gnu_bitfield (int_bit_position (field_decl),
7329 DECL_BIT_FIELD_TYPE (field_decl), size);
7331 else
7332 encode_type (TREE_TYPE (field_decl), curtype, format);
7335 static GTY(()) tree objc_parmlist = NULL_TREE;
7337 /* Append PARM to a list of formal parameters of a method, making a necessary
7338 array-to-pointer adjustment along the way. */
7340 static void
7341 objc_push_parm (tree parm)
7343 /* Convert array parameters of unknown size into pointers. */
7344 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE
7345 && !TYPE_SIZE (TREE_TYPE (parm)))
7346 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
7348 objc_parmlist = chainon (objc_parmlist, parm);
7351 /* Retrieve the formal paramter list constructed via preceding calls to
7352 objc_push_parm(). */
7354 #ifdef OBJCPLUS
7355 static tree
7356 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
7357 #else
7358 static struct c_arg_info *
7359 objc_get_parm_info (int have_ellipsis)
7360 #endif
7362 #ifdef OBJCPLUS
7363 tree parm_info = objc_parmlist;
7364 objc_parmlist = NULL_TREE;
7366 return parm_info;
7367 #else
7368 tree parm_info = objc_parmlist;
7369 struct c_arg_info *arg_info;
7370 /* The C front-end requires an elaborate song and dance at
7371 this point. */
7372 push_scope ();
7373 declare_parm_level ();
7374 while (parm_info)
7376 tree next = TREE_CHAIN (parm_info);
7378 TREE_CHAIN (parm_info) = NULL_TREE;
7379 pushdecl (parm_info);
7380 parm_info = next;
7382 arg_info = get_parm_info (have_ellipsis);
7383 pop_scope ();
7384 objc_parmlist = NULL_TREE;
7385 return arg_info;
7386 #endif
7389 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
7390 method definitions. In the case of instance methods, we can be more
7391 specific as to the type of 'self'. */
7393 static void
7394 synth_self_and_ucmd_args (void)
7396 tree self_type;
7398 if (objc_method_context
7399 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7400 self_type = objc_instance_type;
7401 else
7402 /* Really a `struct objc_class *'. However, we allow people to
7403 assign to self, which changes its type midstream. */
7404 self_type = objc_object_type;
7406 /* id self; */
7407 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
7409 /* SEL _cmd; */
7410 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
7413 /* Transform an Objective-C method definition into a static C function
7414 definition, synthesizing the first two arguments, "self" and "_cmd",
7415 in the process. */
7417 static void
7418 start_method_def (tree method)
7420 tree parmlist;
7421 #ifdef OBJCPLUS
7422 tree parm_info;
7423 #else
7424 struct c_arg_info *parm_info;
7425 #endif
7426 int have_ellipsis = 0;
7428 /* Required to implement _msgSuper. */
7429 objc_method_context = method;
7430 UOBJC_SUPER_decl = NULL_TREE;
7432 /* Generate prototype declarations for arguments..."new-style". */
7433 synth_self_and_ucmd_args ();
7435 /* Generate argument declarations if a keyword_decl. */
7436 parmlist = METHOD_SEL_ARGS (method);
7437 while (parmlist)
7439 tree parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist),
7440 TREE_VALUE (TREE_TYPE (parmlist)));
7442 objc_push_parm (parm);
7443 parmlist = TREE_CHAIN (parmlist);
7446 if (METHOD_ADD_ARGS (method))
7448 tree akey;
7450 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
7451 akey; akey = TREE_CHAIN (akey))
7453 objc_push_parm (TREE_VALUE (akey));
7456 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
7457 have_ellipsis = 1;
7460 parm_info = objc_get_parm_info (have_ellipsis);
7462 really_start_method (objc_method_context, parm_info);
7465 static void
7466 warn_with_method (const char *message, int mtype, tree method)
7468 /* Add a readable method name to the warning. */
7469 warning ("%J%s `%c%s'", method,
7470 message, mtype, gen_method_decl (method));
7473 /* Return 1 if TYPE1 is equivalent to TYPE2
7474 for purposes of method overloading. */
7476 static int
7477 objc_types_are_equivalent (tree type1, tree type2)
7479 if (type1 == type2)
7480 return 1;
7482 /* Strip away indirections. */
7483 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
7484 && (TREE_CODE (type1) == TREE_CODE (type2)))
7485 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
7486 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7487 return 0;
7489 type1 = TYPE_PROTOCOL_LIST (type1);
7490 type2 = TYPE_PROTOCOL_LIST (type2);
7491 if (list_length (type1) == list_length (type2))
7493 for (; type2; type2 = TREE_CHAIN (type2))
7494 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7495 return 0;
7496 return 1;
7498 return 0;
7501 /* Return 1 if PROTO1 is equivalent to PROTO2
7502 for purposes of method overloading. */
7504 static int
7505 comp_proto_with_proto (tree proto1, tree proto2)
7507 tree type1, type2;
7509 /* The following test is needed in case there are hashing
7510 collisions. */
7511 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7512 return 0;
7514 /* Compare return types. */
7515 type1 = TREE_VALUE (TREE_TYPE (proto1));
7516 type2 = TREE_VALUE (TREE_TYPE (proto2));
7518 if (!objc_types_are_equivalent (type1, type2))
7519 return 0;
7521 /* Compare argument types. */
7522 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7523 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7524 type1 && type2;
7525 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7527 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7528 return 0;
7531 return (!type1 && !type2);
7534 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
7535 this occurs. ObjC method dispatches are _not_ like C++ virtual
7536 member function dispatches, and we account for the difference here. */
7537 tree
7538 #ifdef OBJCPLUS
7539 objc_fold_obj_type_ref (tree ref, tree known_type)
7540 #else
7541 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
7542 tree known_type ATTRIBUTE_UNUSED)
7543 #endif
7545 #ifdef OBJCPLUS
7546 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
7548 /* If the receiver does not have virtual member functions, there
7549 is nothing we can (or need to) do here. */
7550 if (!v)
7551 return NULL_TREE;
7553 /* Let C++ handle C++ virtual functions. */
7554 return cp_fold_obj_type_ref (ref, known_type);
7555 #else
7556 /* For plain ObjC, we currently do not need to do anything. */
7557 return NULL_TREE;
7558 #endif
7561 static void
7562 objc_start_function (tree name, tree type, tree attrs,
7563 #ifdef OBJCPLUS
7564 tree params
7565 #else
7566 struct c_arg_info *params
7567 #endif
7570 tree fndecl = build_decl (FUNCTION_DECL, name, type);
7572 #ifdef OBJCPLUS
7573 DECL_ARGUMENTS (fndecl) = params;
7574 #endif
7575 DECL_INITIAL (fndecl) = error_mark_node;
7576 DECL_EXTERNAL (fndecl) = 0;
7577 TREE_STATIC (fndecl) = 1;
7579 #ifdef OBJCPLUS
7580 retrofit_lang_decl (fndecl);
7581 cplus_decl_attributes (&fndecl, attrs, 0);
7582 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
7583 #else
7584 decl_attributes (&fndecl, attrs, 0);
7585 announce_function (fndecl);
7586 current_function_decl = pushdecl (fndecl);
7587 push_scope ();
7588 declare_parm_level ();
7589 DECL_RESULT (current_function_decl)
7590 = build_decl (RESULT_DECL, NULL_TREE,
7591 TREE_TYPE (TREE_TYPE (current_function_decl)));
7592 start_fname_decls ();
7593 store_parm_decls_from (params);
7594 #endif
7596 TREE_USED (current_function_decl) = 1;
7599 /* - Generate an identifier for the function. the format is "_n_cls",
7600 where 1 <= n <= nMethods, and cls is the name the implementation we
7601 are processing.
7602 - Install the return type from the method declaration.
7603 - If we have a prototype, check for type consistency. */
7605 static void
7606 really_start_method (tree method,
7607 #ifdef OBJCPLUS
7608 tree parmlist
7609 #else
7610 struct c_arg_info *parmlist
7611 #endif
7614 tree ret_type, meth_type;
7615 tree method_id;
7616 const char *sel_name, *class_name, *cat_name;
7617 char *buf;
7619 /* Synth the storage class & assemble the return type. */
7620 ret_type = TREE_VALUE (TREE_TYPE (method));
7622 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7623 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7624 cat_name = ((TREE_CODE (objc_implementation_context)
7625 == CLASS_IMPLEMENTATION_TYPE)
7626 ? NULL
7627 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7628 method_slot++;
7630 /* Make sure this is big enough for any plausible method label. */
7631 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7632 + (cat_name ? strlen (cat_name) : 0));
7634 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7635 class_name, cat_name, sel_name, method_slot);
7637 method_id = get_identifier (buf);
7639 #ifdef OBJCPLUS
7640 /* Objective-C methods cannot be overloaded, so we don't need
7641 the type encoding appended. It looks bad anyway... */
7642 push_lang_context (lang_name_c);
7643 #endif
7645 meth_type
7646 = build_function_type (ret_type,
7647 get_arg_type_list (method, METHOD_DEF, 0));
7648 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
7650 /* Set self_decl from the first argument. */
7651 self_decl = DECL_ARGUMENTS (current_function_decl);
7653 /* Suppress unused warnings. */
7654 TREE_USED (self_decl) = 1;
7655 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7656 #ifdef OBJCPLUS
7657 pop_lang_context ();
7658 #endif
7660 METHOD_DEFINITION (method) = current_function_decl;
7662 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7664 if (implementation_template != objc_implementation_context)
7666 tree proto
7667 = lookup_method_static (implementation_template,
7668 METHOD_SEL_NAME (method),
7669 TREE_CODE (method) == CLASS_METHOD_DECL);
7671 if (proto)
7673 if (!comp_proto_with_proto (method, proto))
7675 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7677 warn_with_method ("conflicting types for", type, method);
7678 warn_with_method ("previous declaration of", type, proto);
7681 else
7683 /* We have a method @implementation even though we did not
7684 see a corresponding @interface declaration (which is allowed
7685 by Objective-C rules). Go ahead and place the method in
7686 the @interface anyway, so that message dispatch lookups
7687 will see it. */
7688 tree interface = implementation_template;
7690 if (TREE_CODE (objc_implementation_context)
7691 == CATEGORY_IMPLEMENTATION_TYPE)
7692 interface = lookup_category
7693 (interface,
7694 CLASS_SUPER_NAME (objc_implementation_context));
7696 if (interface)
7697 objc_add_method (interface, copy_node (method),
7698 TREE_CODE (method) == CLASS_METHOD_DECL);
7703 static void *UOBJC_SUPER_scope = 0;
7705 /* _n_Method (id self, SEL sel, ...)
7707 struct objc_super _S;
7708 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7709 } */
7711 static tree
7712 get_super_receiver (void)
7714 if (objc_method_context)
7716 tree super_expr, super_expr_list;
7718 if (!UOBJC_SUPER_decl)
7720 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
7721 objc_super_template);
7722 /* This prevents `unused variable' warnings when compiling with -Wall. */
7723 TREE_USED (UOBJC_SUPER_decl) = 1;
7724 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
7725 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7726 UOBJC_SUPER_scope = objc_get_current_scope ();
7729 /* Set receiver to self. */
7730 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7731 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7732 super_expr_list = super_expr;
7734 /* Set class to begin searching. */
7735 super_expr = build_component_ref (UOBJC_SUPER_decl,
7736 get_identifier ("super_class"));
7738 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7740 /* [_cls, __cls]Super are "pre-built" in
7741 synth_forward_declarations. */
7743 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7744 ((TREE_CODE (objc_method_context)
7745 == INSTANCE_METHOD_DECL)
7746 ? ucls_super_ref
7747 : uucls_super_ref));
7750 else
7751 /* We have a category. */
7753 tree super_name = CLASS_SUPER_NAME (implementation_template);
7754 tree super_class;
7756 /* Barf if super used in a category of Object. */
7757 if (!super_name)
7759 error ("no super class declared in interface for `%s'",
7760 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7761 return error_mark_node;
7764 if (flag_next_runtime && !flag_zero_link)
7766 super_class = objc_get_class_reference (super_name);
7767 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7768 /* If we are in a class method, we must retrieve the
7769 _metaclass_ for the current class, pointed at by
7770 the class's "isa" pointer. The following assumes that
7771 "isa" is the first ivar in a class (which it must be). */
7772 super_class
7773 = build_indirect_ref
7774 (build_c_cast (build_pointer_type (objc_class_type),
7775 super_class), "unary *");
7777 else
7779 add_class_reference (super_name);
7780 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7781 ? objc_get_class_decl : objc_get_meta_class_decl);
7782 assemble_external (super_class);
7783 super_class
7784 = build_function_call
7785 (super_class,
7786 build_tree_list
7787 (NULL_TREE,
7788 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7789 IDENTIFIER_POINTER (super_name))));
7792 super_expr
7793 = build_modify_expr (super_expr, NOP_EXPR,
7794 build_c_cast (TREE_TYPE (super_expr),
7795 super_class));
7798 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7800 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7801 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7803 return super_expr_list;
7805 else
7807 error ("[super ...] must appear in a method context");
7808 return error_mark_node;
7812 /* When exiting a scope, sever links to a 'super' declaration (if any)
7813 therein contained. */
7815 void
7816 objc_clear_super_receiver (void)
7818 if (objc_method_context
7819 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
7820 UOBJC_SUPER_decl = 0;
7821 UOBJC_SUPER_scope = 0;
7825 void
7826 objc_finish_method_definition (tree fndecl)
7828 /* We cannot validly inline ObjC methods, at least not without a language
7829 extension to declare that a method need not be dynamically
7830 dispatched, so suppress all thoughts of doing so. */
7831 DECL_INLINE (fndecl) = 0;
7832 DECL_UNINLINABLE (fndecl) = 1;
7834 #ifndef OBJCPLUS
7835 /* The C++ front-end will have called finish_function() for us. */
7836 finish_function ();
7837 #endif
7839 METHOD_ENCODING (objc_method_context)
7840 = encode_method_prototype (objc_method_context);
7842 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7843 since the optimizer may find "may be used before set" errors. */
7844 objc_method_context = NULL_TREE;
7847 #if 0
7849 lang_report_error_function (tree decl)
7851 if (objc_method_context)
7853 fprintf (stderr, "In method `%s'\n",
7854 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7855 return 1;
7858 else
7859 return 0;
7861 #endif
7863 /* Given a tree DECL node, produce a printable description of it in the given
7864 buffer, overwriting the buffer. */
7866 static char *
7867 gen_declaration (tree decl)
7869 errbuf[0] = '\0';
7871 if (DECL_P (decl))
7873 gen_type_name_0 (TREE_TYPE (decl));
7875 if (DECL_NAME (decl))
7877 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
7878 strcat (errbuf, " ");
7880 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
7883 if (DECL_INITIAL (decl)
7884 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
7885 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
7886 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
7889 return errbuf;
7892 /* Given a tree TYPE node, produce a printable description of it in the given
7893 buffer, overwriting the buffer. */
7895 static char *
7896 gen_type_name_0 (tree type)
7898 tree orig = type, proto;
7900 if (TYPE_P (type) && TYPE_NAME (type))
7901 type = TYPE_NAME (type);
7902 else if (POINTER_TYPE_P (type))
7904 gen_type_name_0 (TREE_TYPE (type));
7906 if (!POINTER_TYPE_P (TREE_TYPE (type)))
7907 strcat (errbuf, " ");
7909 strcat (errbuf, "*");
7910 goto exit_function;
7913 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
7914 type = DECL_NAME (type);
7916 strcat (errbuf, IDENTIFIER_POINTER (type));
7917 proto = TYPE_PROTOCOL_LIST (orig);
7919 if (proto)
7921 strcat (errbuf, " <");
7923 while (proto) {
7924 strcat (errbuf,
7925 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
7926 proto = TREE_CHAIN (proto);
7927 strcat (errbuf, proto ? ", " : ">");
7931 exit_function:
7932 return errbuf;
7935 static char *
7936 gen_type_name (tree type)
7938 errbuf[0] = '\0';
7940 return gen_type_name_0 (type);
7943 /* Given a method tree, put a printable description into the given
7944 buffer (overwriting) and return a pointer to the buffer. */
7946 static char *
7947 gen_method_decl (tree method)
7949 tree chain;
7951 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
7952 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
7953 strcat (errbuf, ")");
7954 chain = METHOD_SEL_ARGS (method);
7956 if (chain)
7958 /* We have a chain of keyword_decls. */
7961 if (KEYWORD_KEY_NAME (chain))
7962 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7964 strcat (errbuf, ":(");
7965 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
7966 strcat (errbuf, ")");
7968 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7969 if ((chain = TREE_CHAIN (chain)))
7970 strcat (errbuf, " ");
7972 while (chain);
7974 if (METHOD_ADD_ARGS (method))
7976 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
7978 /* Know we have a chain of parm_decls. */
7979 while (chain)
7981 strcat (errbuf, ", ");
7982 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
7983 chain = TREE_CHAIN (chain);
7986 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
7987 strcat (errbuf, ", ...");
7991 else
7992 /* We have a unary selector. */
7993 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7995 return errbuf;
7998 /* Debug info. */
8001 /* Dump an @interface declaration of the supplied class CHAIN to the
8002 supplied file FP. Used to implement the -gen-decls option (which
8003 prints out an @interface declaration of all classes compiled in
8004 this run); potentially useful for debugging the compiler too. */
8005 static void
8006 dump_interface (FILE *fp, tree chain)
8008 /* FIXME: A heap overflow here whenever a method (or ivar)
8009 declaration is so long that it doesn't fit in the buffer. The
8010 code and all the related functions should be rewritten to avoid
8011 using fixed size buffers. */
8012 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8013 tree ivar_decls = CLASS_RAW_IVARS (chain);
8014 tree nst_methods = CLASS_NST_METHODS (chain);
8015 tree cls_methods = CLASS_CLS_METHODS (chain);
8017 fprintf (fp, "\n@interface %s", my_name);
8019 /* CLASS_SUPER_NAME is used to store the superclass name for
8020 classes, and the category name for categories. */
8021 if (CLASS_SUPER_NAME (chain))
8023 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8025 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8026 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8028 fprintf (fp, " (%s)\n", name);
8030 else
8032 fprintf (fp, " : %s\n", name);
8035 else
8036 fprintf (fp, "\n");
8038 /* FIXME - the following doesn't seem to work at the moment. */
8039 if (ivar_decls)
8041 fprintf (fp, "{\n");
8044 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
8045 ivar_decls = TREE_CHAIN (ivar_decls);
8047 while (ivar_decls);
8048 fprintf (fp, "}\n");
8051 while (nst_methods)
8053 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
8054 nst_methods = TREE_CHAIN (nst_methods);
8057 while (cls_methods)
8059 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
8060 cls_methods = TREE_CHAIN (cls_methods);
8063 fprintf (fp, "@end\n");
8066 /* Demangle function for Objective-C */
8067 static const char *
8068 objc_demangle (const char *mangled)
8070 char *demangled, *cp;
8072 if (mangled[0] == '_' &&
8073 (mangled[1] == 'i' || mangled[1] == 'c') &&
8074 mangled[2] == '_')
8076 cp = demangled = xmalloc(strlen(mangled) + 2);
8077 if (mangled[1] == 'i')
8078 *cp++ = '-'; /* for instance method */
8079 else
8080 *cp++ = '+'; /* for class method */
8081 *cp++ = '['; /* opening left brace */
8082 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8083 while (*cp && *cp == '_')
8084 cp++; /* skip any initial underbars in class name */
8085 cp = strchr(cp, '_'); /* find first non-initial underbar */
8086 if (cp == NULL)
8088 free(demangled); /* not mangled name */
8089 return mangled;
8091 if (cp[1] == '_') /* easy case: no category name */
8093 *cp++ = ' '; /* replace two '_' with one ' ' */
8094 strcpy(cp, mangled + (cp - demangled) + 2);
8096 else
8098 *cp++ = '('; /* less easy case: category name */
8099 cp = strchr(cp, '_');
8100 if (cp == 0)
8102 free(demangled); /* not mangled name */
8103 return mangled;
8105 *cp++ = ')';
8106 *cp++ = ' '; /* overwriting 1st char of method name... */
8107 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8109 while (*cp && *cp == '_')
8110 cp++; /* skip any initial underbars in method name */
8111 for (; *cp; cp++)
8112 if (*cp == '_')
8113 *cp = ':'; /* replace remaining '_' with ':' */
8114 *cp++ = ']'; /* closing right brace */
8115 *cp++ = 0; /* string terminator */
8116 return demangled;
8118 else
8119 return mangled; /* not an objc mangled name */
8122 const char *
8123 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8125 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8128 static void
8129 init_objc (void)
8131 gcc_obstack_init (&util_obstack);
8132 util_firstobj = (char *) obstack_finish (&util_obstack);
8134 errbuf = (char *) xmalloc (1024 * 10);
8135 hash_init ();
8136 synth_module_prologue ();
8139 static void
8140 finish_objc (void)
8142 struct imp_entry *impent;
8143 tree chain;
8144 /* The internally generated initializers appear to have missing braces.
8145 Don't warn about this. */
8146 int save_warn_missing_braces = warn_missing_braces;
8147 warn_missing_braces = 0;
8149 /* A missing @end may not be detected by the parser. */
8150 if (objc_implementation_context)
8152 warning ("`@end' missing in implementation context");
8153 finish_class (objc_implementation_context);
8154 objc_ivar_chain = NULL_TREE;
8155 objc_implementation_context = NULL_TREE;
8158 /* Process the static instances here because initialization of objc_symtab
8159 depends on them. */
8160 if (objc_static_instances)
8161 generate_static_references ();
8163 if (imp_list || class_names_chain
8164 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8165 generate_objc_symtab_decl ();
8167 for (impent = imp_list; impent; impent = impent->next)
8169 objc_implementation_context = impent->imp_context;
8170 implementation_template = impent->imp_template;
8172 UOBJC_CLASS_decl = impent->class_decl;
8173 UOBJC_METACLASS_decl = impent->meta_decl;
8175 /* Dump the @interface of each class as we compile it, if the
8176 -gen-decls option is in use. TODO: Dump the classes in the
8177 order they were found, rather than in reverse order as we
8178 are doing now. */
8179 if (flag_gen_declaration)
8181 dump_interface (gen_declaration_file, objc_implementation_context);
8184 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8186 /* all of the following reference the string pool... */
8187 generate_ivar_lists ();
8188 generate_dispatch_tables ();
8189 generate_shared_structures ();
8191 else
8193 generate_dispatch_tables ();
8194 generate_category (objc_implementation_context);
8198 /* If we are using an array of selectors, we must always
8199 finish up the array decl even if no selectors were used. */
8200 if (! flag_next_runtime || sel_ref_chain)
8201 build_selector_translation_table ();
8203 if (protocol_chain)
8204 generate_protocols ();
8206 if (flag_replace_objc_classes && imp_list)
8207 generate_objc_image_info ();
8209 /* Arrange for ObjC data structures to be initialized at run time. */
8210 if (objc_implementation_context || class_names_chain || objc_static_instances
8211 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8213 build_module_descriptor ();
8215 if (!flag_next_runtime)
8216 build_module_initializer_routine ();
8219 /* Dump the class references. This forces the appropriate classes
8220 to be linked into the executable image, preserving unix archive
8221 semantics. This can be removed when we move to a more dynamically
8222 linked environment. */
8224 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8226 handle_class_ref (chain);
8227 if (TREE_PURPOSE (chain))
8228 generate_classref_translation_entry (chain);
8231 for (impent = imp_list; impent; impent = impent->next)
8232 handle_impent (impent);
8234 /* Dump the string table last. */
8236 generate_strings ();
8238 if (warn_selector)
8240 int slot;
8241 hash hsh;
8243 /* Run through the selector hash tables and print a warning for any
8244 selector which has multiple methods. */
8246 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8248 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8249 check_duplicates (hsh, 0, 1);
8250 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8251 check_duplicates (hsh, 0, 1);
8255 warn_missing_braces = save_warn_missing_braces;
8258 /* Subroutines of finish_objc. */
8260 static void
8261 generate_classref_translation_entry (tree chain)
8263 tree expr, decl, type;
8265 decl = TREE_PURPOSE (chain);
8266 type = TREE_TYPE (decl);
8268 expr = add_objc_string (TREE_VALUE (chain), class_names);
8269 expr = convert (type, expr); /* cast! */
8271 /* The decl that is the one that we
8272 forward declared in build_class_reference. */
8273 finish_var_decl (decl, expr);
8274 return;
8277 static void
8278 handle_class_ref (tree chain)
8280 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8281 char *string = (char *) alloca (strlen (name) + 30);
8282 tree decl;
8283 tree exp;
8285 sprintf (string, "%sobjc_class_name_%s",
8286 (flag_next_runtime ? "." : "__"), name);
8288 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8289 if (flag_next_runtime)
8291 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8292 return;
8294 #endif
8296 /* Make a decl for this name, so we can use its address in a tree. */
8297 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8298 DECL_EXTERNAL (decl) = 1;
8299 TREE_PUBLIC (decl) = 1;
8301 pushdecl (decl);
8302 rest_of_decl_compilation (decl, 0, 0);
8304 /* Make a decl for the address. */
8305 sprintf (string, "%sobjc_class_ref_%s",
8306 (flag_next_runtime ? "." : "__"), name);
8307 exp = build1 (ADDR_EXPR, string_type_node, decl);
8308 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8309 DECL_INITIAL (decl) = exp;
8310 TREE_STATIC (decl) = 1;
8311 TREE_USED (decl) = 1;
8313 pushdecl (decl);
8314 rest_of_decl_compilation (decl, 0, 0);
8317 static void
8318 handle_impent (struct imp_entry *impent)
8320 char *string;
8322 objc_implementation_context = impent->imp_context;
8323 implementation_template = impent->imp_template;
8325 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8327 const char *const class_name =
8328 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8330 string = (char *) alloca (strlen (class_name) + 30);
8332 sprintf (string, "%sobjc_class_name_%s",
8333 (flag_next_runtime ? "." : "__"), class_name);
8335 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8337 const char *const class_name =
8338 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8339 const char *const class_super_name =
8340 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8342 string = (char *) alloca (strlen (class_name)
8343 + strlen (class_super_name) + 30);
8345 /* Do the same for categories. Even though no references to
8346 these symbols are generated automatically by the compiler, it
8347 gives you a handle to pull them into an archive by hand. */
8348 sprintf (string, "*%sobjc_category_name_%s_%s",
8349 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8351 else
8352 return;
8354 #ifdef ASM_DECLARE_CLASS_REFERENCE
8355 if (flag_next_runtime)
8357 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8358 return;
8360 else
8361 #endif
8363 tree decl, init;
8365 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
8366 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8367 TREE_PUBLIC (decl) = 1;
8368 TREE_READONLY (decl) = 1;
8369 TREE_USED (decl) = 1;
8370 TREE_CONSTANT (decl) = 1;
8371 DECL_CONTEXT (decl) = 0;
8372 DECL_ARTIFICIAL (decl) = 1;
8373 DECL_INITIAL (decl) = init;
8374 assemble_variable (decl, 1, 0, 0);
8378 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
8379 later requires that ObjC translation units participating in F&C be
8380 specially marked. The following routine accomplishes this. */
8382 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
8384 static void
8385 generate_objc_image_info (void)
8387 tree decl, initlist;
8389 decl = start_var_decl (build_array_type
8390 (integer_type_node,
8391 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
8392 "_OBJC_IMAGE_INFO");
8394 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
8395 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 1), initlist);
8396 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
8398 finish_var_decl (decl, initlist);
8401 /* Look up ID as an instance variable. */
8403 tree
8404 objc_lookup_ivar (tree id)
8406 tree decl;
8408 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8409 /* We have a message to super. */
8410 return get_super_receiver ();
8411 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8413 if (is_private (decl))
8414 return 0;
8415 else
8416 return build_ivar_reference (id);
8418 else
8419 return 0;
8422 #include "gt-objc-objc-act.h"