Update copyright.
[official-gcc.git] / gcc / objc / objc-act.c
blobd3a22a30f2ee50a65b64095f0ba4a0ec5ba736d6
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003 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 "expr.h"
49 #include "c-tree.h"
50 #include "c-common.h"
51 #include "flags.h"
52 #include "objc-act.h"
53 #include "input.h"
54 #include "except.h"
55 #include "function.h"
56 #include "output.h"
57 #include "toplev.h"
58 #include "ggc.h"
59 #include "varray.h"
60 #include "debug.h"
61 #include "target.h"
62 #include "diagnostic.h"
63 #include "cgraph.h"
65 /* This is the default way of generating a method name. */
66 /* I am not sure it is really correct.
67 Perhaps there's a danger that it will make name conflicts
68 if method names contain underscores. -- rms. */
69 #ifndef OBJC_GEN_METHOD_LABEL
70 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
71 do { \
72 char *temp; \
73 sprintf ((BUF), "_%s_%s_%s_%s", \
74 ((IS_INST) ? "i" : "c"), \
75 (CLASS_NAME), \
76 ((CAT_NAME)? (CAT_NAME) : ""), \
77 (SEL_NAME)); \
78 for (temp = (BUF); *temp; temp++) \
79 if (*temp == ':') *temp = '_'; \
80 } while (0)
81 #endif
83 /* These need specifying. */
84 #ifndef OBJC_FORWARDING_STACK_OFFSET
85 #define OBJC_FORWARDING_STACK_OFFSET 0
86 #endif
88 #ifndef OBJC_FORWARDING_MIN_OFFSET
89 #define OBJC_FORWARDING_MIN_OFFSET 0
90 #endif
93 /* Set up for use of obstacks. */
95 #include "obstack.h"
97 /* This obstack is used to accumulate the encoding of a data type. */
98 static struct obstack util_obstack;
99 /* This points to the beginning of obstack contents,
100 so we can free the whole contents. */
101 char *util_firstobj;
103 /* for encode_method_def */
104 #include "rtl.h"
106 /* The version identifies which language generation and runtime
107 the module (file) was compiled for, and is recorded in the
108 module descriptor. */
110 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
111 #define PROTOCOL_VERSION 2
113 /* (Decide if these can ever be validly changed.) */
114 #define OBJC_ENCODE_INLINE_DEFS 0
115 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
117 /*** Private Interface (procedures) ***/
119 /* Used by compile_file. */
121 static void init_objc PARAMS ((void));
122 static void finish_objc PARAMS ((void));
124 /* Code generation. */
126 static void synth_module_prologue PARAMS ((void));
127 static tree build_constructor PARAMS ((tree, tree));
128 static rtx build_module_descriptor PARAMS ((void));
129 static tree init_module_descriptor PARAMS ((tree));
130 static tree build_objc_method_call PARAMS ((int, tree, tree,
131 tree, tree, tree));
132 static void generate_strings PARAMS ((void));
133 static tree get_proto_encoding PARAMS ((tree));
134 static void build_selector_translation_table PARAMS ((void));
136 static tree objc_add_static_instance PARAMS ((tree, tree));
138 static tree build_ivar_template PARAMS ((void));
139 static tree build_method_template PARAMS ((void));
140 static tree build_private_template PARAMS ((tree));
141 static void build_class_template PARAMS ((void));
142 static void build_selector_template PARAMS ((void));
143 static void build_category_template PARAMS ((void));
144 static tree build_super_template PARAMS ((void));
145 static tree build_category_initializer PARAMS ((tree, tree, tree,
146 tree, tree, tree));
147 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
148 tree, tree));
150 static void synth_forward_declarations PARAMS ((void));
151 static void generate_ivar_lists PARAMS ((void));
152 static void generate_dispatch_tables PARAMS ((void));
153 static void generate_shared_structures PARAMS ((void));
154 static tree generate_protocol_list PARAMS ((tree));
155 static void generate_forward_declaration_to_string_table PARAMS ((void));
156 static void build_protocol_reference PARAMS ((tree));
158 static tree build_keyword_selector PARAMS ((tree));
159 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
161 static void generate_static_references PARAMS ((void));
162 static int check_methods_accessible PARAMS ((tree, tree,
163 int));
164 static void encode_aggregate_within PARAMS ((tree, int, int,
165 int, int));
166 static const char *objc_demangle PARAMS ((const char *));
167 static void objc_expand_function_end PARAMS ((void));
169 /* Hash tables to manage the global pool of method prototypes. */
171 hash *nst_method_hash_list = 0;
172 hash *cls_method_hash_list = 0;
174 static size_t hash_func PARAMS ((tree));
175 static void hash_init PARAMS ((void));
176 static void hash_enter PARAMS ((hash *, tree));
177 static hash hash_lookup PARAMS ((hash *, tree));
178 static void hash_add_attr PARAMS ((hash, tree));
179 static tree lookup_method PARAMS ((tree, tree));
180 static tree lookup_instance_method_static PARAMS ((tree, tree));
181 static tree lookup_class_method_static PARAMS ((tree, tree));
182 static tree add_class PARAMS ((tree));
183 static void add_category PARAMS ((tree, tree));
185 enum string_section
187 class_names, /* class, category, protocol, module names */
188 meth_var_names, /* method and variable names */
189 meth_var_types /* method and variable type descriptors */
192 static tree add_objc_string PARAMS ((tree,
193 enum string_section));
194 static tree get_objc_string_decl PARAMS ((tree,
195 enum string_section));
196 static tree build_objc_string_decl PARAMS ((enum string_section));
197 static tree build_selector_reference_decl PARAMS ((void));
199 /* Protocol additions. */
201 static tree add_protocol PARAMS ((tree));
202 static tree lookup_protocol PARAMS ((tree));
203 static void check_protocol_recursively PARAMS ((tree, tree));
204 static tree lookup_and_install_protocols PARAMS ((tree));
206 /* Type encoding. */
208 static void encode_type_qualifiers PARAMS ((tree));
209 static void encode_pointer PARAMS ((tree, int, int));
210 static void encode_array PARAMS ((tree, int, int));
211 static void encode_aggregate PARAMS ((tree, int, int));
212 static void encode_bitfield PARAMS ((int));
213 static void encode_type PARAMS ((tree, int, int));
214 static void encode_field_decl PARAMS ((tree, int, int));
216 static void really_start_method PARAMS ((tree, tree));
217 static int comp_method_with_proto PARAMS ((tree, tree));
218 static int comp_proto_with_proto PARAMS ((tree, tree));
219 static tree get_arg_type_list PARAMS ((tree, int, int));
220 static tree expr_last PARAMS ((tree));
222 /* Utilities for debugging and error diagnostics. */
224 static void warn_with_method PARAMS ((const char *, int, tree));
225 static void error_with_ivar PARAMS ((const char *, tree, tree));
226 static char *gen_method_decl PARAMS ((tree, char *));
227 static char *gen_declaration PARAMS ((tree, char *));
228 static void gen_declaration_1 PARAMS ((tree, char *));
229 static char *gen_declarator PARAMS ((tree, char *,
230 const char *));
231 static int is_complex_decl PARAMS ((tree));
232 static void adorn_decl PARAMS ((tree, char *));
233 static void dump_interface PARAMS ((FILE *, tree));
235 /* Everything else. */
237 static tree define_decl PARAMS ((tree, tree));
238 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
239 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
240 static tree create_builtin_decl PARAMS ((enum tree_code,
241 tree, const char *));
242 static void setup_string_decl PARAMS ((void));
243 static void build_string_class_template PARAMS ((void));
244 static tree my_build_string PARAMS ((int, const char *));
245 static void build_objc_symtab_template PARAMS ((void));
246 static tree init_def_list PARAMS ((tree));
247 static tree init_objc_symtab PARAMS ((tree));
248 static void forward_declare_categories PARAMS ((void));
249 static void generate_objc_symtab_decl PARAMS ((void));
250 static tree build_selector PARAMS ((tree));
251 static tree build_typed_selector_reference PARAMS ((tree, tree));
252 static tree build_selector_reference PARAMS ((tree));
253 static tree build_class_reference_decl PARAMS ((void));
254 static void add_class_reference PARAMS ((tree));
255 static tree build_protocol_template PARAMS ((void));
256 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
257 static tree build_method_prototype_list_template PARAMS ((tree, int));
258 static tree build_method_prototype_template PARAMS ((void));
259 static int forwarding_offset PARAMS ((tree));
260 static tree encode_method_prototype PARAMS ((tree, tree));
261 static tree generate_descriptor_table PARAMS ((tree, const char *,
262 int, tree, tree));
263 static void generate_method_descriptors PARAMS ((tree));
264 static tree build_tmp_function_decl PARAMS ((void));
265 static void hack_method_prototype PARAMS ((tree, tree));
266 static void generate_protocol_references PARAMS ((tree));
267 static void generate_protocols PARAMS ((void));
268 static void check_ivars PARAMS ((tree, tree));
269 static tree build_ivar_list_template PARAMS ((tree, int));
270 static tree build_method_list_template PARAMS ((tree, int));
271 static tree build_ivar_list_initializer PARAMS ((tree, tree));
272 static tree generate_ivars_list PARAMS ((tree, const char *,
273 int, tree));
274 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
275 static tree generate_dispatch_table PARAMS ((tree, const char *,
276 int, tree));
277 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
278 tree, int, tree, tree,
279 tree));
280 static void generate_category PARAMS ((tree));
281 static int is_objc_type_qualifier PARAMS ((tree));
282 static tree adjust_type_for_id_default PARAMS ((tree));
283 static tree check_duplicates PARAMS ((hash));
284 static tree receiver_is_class_object PARAMS ((tree));
285 static int check_methods PARAMS ((tree, tree, int));
286 static int conforms_to_protocol PARAMS ((tree, tree));
287 static void check_protocol PARAMS ((tree, const char *,
288 const char *));
289 static void check_protocols PARAMS ((tree, const char *,
290 const char *));
291 static tree encode_method_def PARAMS ((tree));
292 static void gen_declspecs PARAMS ((tree, char *, int));
293 static void generate_classref_translation_entry PARAMS ((tree));
294 static void handle_class_ref PARAMS ((tree));
295 static void generate_struct_by_value_array PARAMS ((void))
296 ATTRIBUTE_NORETURN;
297 static void encode_complete_bitfield PARAMS ((int, tree, int));
298 static void mark_referenced_methods PARAMS ((void));
300 /*** Private Interface (data) ***/
302 /* Reserved tag definitions. */
304 #define TYPE_ID "id"
305 #define TAG_OBJECT "objc_object"
306 #define TAG_CLASS "objc_class"
307 #define TAG_SUPER "objc_super"
308 #define TAG_SELECTOR "objc_selector"
310 #define UTAG_CLASS "_objc_class"
311 #define UTAG_IVAR "_objc_ivar"
312 #define UTAG_IVAR_LIST "_objc_ivar_list"
313 #define UTAG_METHOD "_objc_method"
314 #define UTAG_METHOD_LIST "_objc_method_list"
315 #define UTAG_CATEGORY "_objc_category"
316 #define UTAG_MODULE "_objc_module"
317 #define UTAG_SYMTAB "_objc_symtab"
318 #define UTAG_SUPER "_objc_super"
319 #define UTAG_SELECTOR "_objc_selector"
321 #define UTAG_PROTOCOL "_objc_protocol"
322 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
323 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
325 /* Note that the string object global name is only needed for the
326 NeXT runtime. */
327 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
329 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
331 static const char *TAG_GETCLASS;
332 static const char *TAG_GETMETACLASS;
333 static const char *TAG_MSGSEND;
334 static const char *TAG_MSGSENDSUPER;
335 static const char *TAG_EXECCLASS;
336 static const char *default_constant_string_class_name;
338 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
339 tree objc_global_trees[OCTI_MAX];
341 static void handle_impent PARAMS ((struct imp_entry *));
343 struct imp_entry *imp_list = 0;
344 int imp_count = 0; /* `@implementation' */
345 int cat_count = 0; /* `@category' */
347 static int method_slot = 0; /* Used by start_method_def, */
349 #define BUFSIZE 1024
351 static char *errbuf; /* Buffer for error diagnostics */
353 /* Data imported from tree.c. */
355 extern enum debug_info_type write_symbols;
357 /* Data imported from toplev.c. */
359 extern const char *dump_base_name;
361 static int flag_typed_selectors;
363 FILE *gen_declaration_file;
365 /* Tells "encode_pointer/encode_aggregate" whether we are generating
366 type descriptors for instance variables (as opposed to methods).
367 Type descriptors for instance variables contain more information
368 than methods (for static typing and embedded structures). */
370 static int generating_instance_variables = 0;
372 /* Some platforms pass small structures through registers versus
373 through an invisible pointer. Determine at what size structure is
374 the transition point between the two possibilities. */
376 static void
377 generate_struct_by_value_array ()
379 tree type;
380 tree field_decl, field_decl_chain;
381 int i, j;
382 int aggregate_in_mem[32];
383 int found = 0;
385 /* Presumably no platform passes 32 byte structures in a register. */
386 for (i = 1; i < 32; i++)
388 char buffer[5];
390 /* Create an unnamed struct that has `i' character components */
391 type = start_struct (RECORD_TYPE, NULL_TREE);
393 strcpy (buffer, "c1");
394 field_decl = create_builtin_decl (FIELD_DECL,
395 char_type_node,
396 buffer);
397 field_decl_chain = field_decl;
399 for (j = 1; j < i; j++)
401 sprintf (buffer, "c%d", j + 1);
402 field_decl = create_builtin_decl (FIELD_DECL,
403 char_type_node,
404 buffer);
405 chainon (field_decl_chain, field_decl);
407 finish_struct (type, field_decl_chain, NULL_TREE);
409 aggregate_in_mem[i] = aggregate_value_p (type);
410 if (!aggregate_in_mem[i])
411 found = 1;
414 /* We found some structures that are returned in registers instead of memory
415 so output the necessary data. */
416 if (found)
418 for (i = 31; i >= 0; i--)
419 if (!aggregate_in_mem[i])
420 break;
421 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
423 /* The first member of the structure is always 0 because we don't handle
424 structures with 0 members */
425 printf ("static int struct_forward_array[] = {\n 0");
427 for (j = 1; j <= i; j++)
428 printf (", %d", aggregate_in_mem[j]);
429 printf ("\n};\n");
432 exit (0);
435 const char *
436 objc_init (filename)
437 const char *filename;
439 filename = c_objc_common_init (filename);
440 if (filename == NULL)
441 return filename;
443 /* Force the line number back to 0; check_newline will have
444 raised it to 1, which will make the builtin functions appear
445 not to be built in. */
446 lineno = 0;
448 /* If gen_declaration desired, open the output file. */
449 if (flag_gen_declaration)
451 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
452 gen_declaration_file = fopen (dumpname, "w");
453 if (gen_declaration_file == 0)
454 fatal_io_error ("can't open %s", dumpname);
455 free (dumpname);
458 if (flag_next_runtime)
460 TAG_GETCLASS = "objc_getClass";
461 TAG_GETMETACLASS = "objc_getMetaClass";
462 TAG_MSGSEND = "objc_msgSend";
463 TAG_MSGSENDSUPER = "objc_msgSendSuper";
464 TAG_EXECCLASS = "__objc_execClass";
465 default_constant_string_class_name = "NSConstantString";
467 else
469 TAG_GETCLASS = "objc_get_class";
470 TAG_GETMETACLASS = "objc_get_meta_class";
471 TAG_MSGSEND = "objc_msg_lookup";
472 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
473 TAG_EXECCLASS = "__objc_exec_class";
474 default_constant_string_class_name = "NXConstantString";
475 flag_typed_selectors = 1;
478 objc_ellipsis_node = make_node (ERROR_MARK);
480 init_objc ();
482 if (print_struct_values)
483 generate_struct_by_value_array ();
485 return filename;
488 void
489 finish_file ()
491 mark_referenced_methods ();
492 c_objc_common_finish_file ();
494 /* Finalize Objective-C runtime data. No need to generate tables
495 and code if only checking syntax. */
496 if (!flag_syntax_only)
497 finish_objc ();
499 if (gen_declaration_file)
500 fclose (gen_declaration_file);
503 static tree
504 define_decl (declarator, declspecs)
505 tree declarator;
506 tree declspecs;
508 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
509 finish_decl (decl, NULL_TREE, NULL_TREE);
510 return decl;
513 /* Return 1 if LHS and RHS are compatible types for assignment or
514 various other operations. Return 0 if they are incompatible, and
515 return -1 if we choose to not decide. When the operation is
516 REFLEXIVE, check for compatibility in either direction.
518 For statically typed objects, an assignment of the form `a' = `b'
519 is permitted if:
521 `a' is of type "id",
522 `a' and `b' are the same class type, or
523 `a' and `b' are of class types A and B such that B is a descendant of A. */
525 static tree
526 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
527 tree rproto_list;
528 tree sel_name;
529 int class_meth;
531 tree rproto, p;
532 tree fnd = 0;
534 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
536 p = TREE_VALUE (rproto);
538 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
540 if ((fnd = lookup_method (class_meth
541 ? PROTOCOL_CLS_METHODS (p)
542 : PROTOCOL_NST_METHODS (p), sel_name)))
544 else if (PROTOCOL_LIST (p))
545 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
546 sel_name, class_meth);
548 else
550 ; /* An identifier...if we could not find a protocol. */
553 if (fnd)
554 return fnd;
557 return 0;
560 static tree
561 lookup_protocol_in_reflist (rproto_list, lproto)
562 tree rproto_list;
563 tree lproto;
565 tree rproto, p;
567 /* Make sure the protocol is supported by the object on the rhs. */
568 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
570 tree fnd = 0;
571 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
573 p = TREE_VALUE (rproto);
575 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
577 if (lproto == p)
578 fnd = lproto;
580 else if (PROTOCOL_LIST (p))
581 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
584 if (fnd)
585 return fnd;
588 else
590 ; /* An identifier...if we could not find a protocol. */
593 return 0;
596 /* Return 1 if LHS and RHS are compatible types for assignment or
597 various other operations. Return 0 if they are incompatible, and
598 return -1 if we choose to not decide (because the types are really
599 just C types, not ObjC specific ones). When the operation is
600 REFLEXIVE (typically comparisons), check for compatibility in
601 either direction; when it's not (typically assignments), don't.
603 This function is called in two cases: when both lhs and rhs are
604 pointers to records (in which case we check protocols too), and
605 when both lhs and rhs are records (in which case we check class
606 inheritance only).
608 Warnings about classes/protocols not implementing a protocol are
609 emitted here (multiple of those warnings might be emitted for a
610 single line!); generic warnings about incompatible assignments and
611 lacks of casts in comparisons are/must be emitted by the caller if
612 we return 0.
616 objc_comptypes (lhs, rhs, reflexive)
617 tree lhs;
618 tree rhs;
619 int reflexive;
621 /* New clause for protocols. */
623 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
624 manage the ObjC ones, and leave the rest to the C code. */
625 if (TREE_CODE (lhs) == POINTER_TYPE
626 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
627 && TREE_CODE (rhs) == POINTER_TYPE
628 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
630 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
631 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
633 if (lhs_is_proto)
635 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
636 tree rproto, rproto_list;
637 tree p;
639 /* <Protocol> = <Protocol> */
640 if (rhs_is_proto)
642 rproto_list = TYPE_PROTOCOL_LIST (rhs);
644 if (!reflexive)
646 /* An assignment between objects of type 'id
647 <Protocol>'; make sure the protocol on the lhs is
648 supported by the object on the rhs. */
649 for (lproto = lproto_list; lproto;
650 lproto = TREE_CHAIN (lproto))
652 p = TREE_VALUE (lproto);
653 rproto = lookup_protocol_in_reflist (rproto_list, p);
655 if (!rproto)
656 warning
657 ("object does not conform to the `%s' protocol",
658 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
660 return 1;
662 else
664 /* Obscure case - a comparison between two objects
665 of type 'id <Protocol>'. Check that either the
666 protocol on the lhs is supported by the object on
667 the rhs, or viceversa. */
669 /* Check if the protocol on the lhs is supported by the
670 object on the rhs. */
671 for (lproto = lproto_list; lproto;
672 lproto = TREE_CHAIN (lproto))
674 p = TREE_VALUE (lproto);
675 rproto = lookup_protocol_in_reflist (rproto_list, p);
677 if (!rproto)
679 /* Check failed - check if the protocol on the rhs
680 is supported by the object on the lhs. */
681 for (rproto = rproto_list; rproto;
682 rproto = TREE_CHAIN (rproto))
684 p = TREE_VALUE (rproto);
685 lproto = lookup_protocol_in_reflist (lproto_list,
688 if (!lproto)
690 /* This check failed too: incompatible */
691 return 0;
694 return 1;
697 return 1;
700 /* <Protocol> = <class> * */
701 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
703 tree rname = TYPE_NAME (TREE_TYPE (rhs));
704 tree rinter;
706 /* Make sure the protocol is supported by the object on
707 the rhs. */
708 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
710 p = TREE_VALUE (lproto);
711 rproto = 0;
712 rinter = lookup_interface (rname);
714 while (rinter && !rproto)
716 tree cat;
718 rproto_list = CLASS_PROTOCOL_LIST (rinter);
719 rproto = lookup_protocol_in_reflist (rproto_list, p);
720 /* If the underlying ObjC class does not have
721 the protocol we're looking for, check for "one-off"
722 protocols (e.g., `NSObject<MyProt> *foo;') attached
723 to the rhs. */
724 if (!rproto)
726 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
727 rproto = lookup_protocol_in_reflist (rproto_list, p);
730 /* Check for protocols adopted by categories. */
731 cat = CLASS_CATEGORY_LIST (rinter);
732 while (cat && !rproto)
734 rproto_list = CLASS_PROTOCOL_LIST (cat);
735 rproto = lookup_protocol_in_reflist (rproto_list, p);
736 cat = CLASS_CATEGORY_LIST (cat);
739 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
742 if (!rproto)
743 warning ("class `%s' does not implement the `%s' protocol",
744 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
745 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
747 return 1;
749 /* <Protocol> = id */
750 else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
752 return 1;
754 /* <Protocol> = Class */
755 else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
757 return 0;
759 /* <Protocol> = ?? : let comptypes decide. */
760 return -1;
762 else if (rhs_is_proto)
764 /* <class> * = <Protocol> */
765 if (TYPED_OBJECT (TREE_TYPE (lhs)))
767 if (reflexive)
769 tree rname = TYPE_NAME (TREE_TYPE (lhs));
770 tree rinter;
771 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
773 /* Make sure the protocol is supported by the object on
774 the lhs. */
775 for (rproto = rproto_list; rproto;
776 rproto = TREE_CHAIN (rproto))
778 tree p = TREE_VALUE (rproto);
779 tree lproto = 0;
780 rinter = lookup_interface (rname);
782 while (rinter && !lproto)
784 tree cat;
786 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
787 lproto = lookup_protocol_in_reflist (lproto_list, p);
788 /* If the underlying ObjC class does not
789 have the protocol we're looking for,
790 check for "one-off" protocols (e.g.,
791 `NSObject<MyProt> *foo;') attached to the
792 lhs. */
793 if (!lproto)
795 lproto_list = TYPE_PROTOCOL_LIST
796 (TREE_TYPE (lhs));
797 lproto = lookup_protocol_in_reflist
798 (lproto_list, p);
801 /* Check for protocols adopted by categories. */
802 cat = CLASS_CATEGORY_LIST (rinter);
803 while (cat && !lproto)
805 lproto_list = CLASS_PROTOCOL_LIST (cat);
806 lproto = lookup_protocol_in_reflist (lproto_list,
808 cat = CLASS_CATEGORY_LIST (cat);
811 rinter = lookup_interface (CLASS_SUPER_NAME
812 (rinter));
815 if (!lproto)
816 warning ("class `%s' does not implement the `%s' protocol",
817 IDENTIFIER_POINTER (TYPE_NAME
818 (TREE_TYPE (lhs))),
819 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
821 return 1;
823 else
824 return 0;
826 /* id = <Protocol> */
827 else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
829 return 1;
831 /* Class = <Protocol> */
832 else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
834 return 0;
836 /* ??? = <Protocol> : let comptypes decide */
837 else
839 return -1;
842 else
844 /* Attention: we shouldn't defer to comptypes here. One bad
845 side effect would be that we might loose the REFLEXIVE
846 information.
848 lhs = TREE_TYPE (lhs);
849 rhs = TREE_TYPE (rhs);
853 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
855 /* Nothing to do with ObjC - let immediately comptypes take
856 responsibility for checking. */
857 return -1;
860 /* `id' = `<class> *' `<class> *' = `id': always allow it.
861 Please note that
862 'Object *o = [[Object alloc] init]; falls
863 in the case <class> * = `id'.
865 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
866 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
867 return 1;
869 /* `id' = `Class', `Class' = `id' */
871 else if ((TYPE_NAME (lhs) == objc_object_id
872 && TYPE_NAME (rhs) == objc_class_id)
873 || (TYPE_NAME (lhs) == objc_class_id
874 && TYPE_NAME (rhs) == objc_object_id))
875 return 1;
877 /* `<class> *' = `<class> *' */
879 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
881 tree lname = TYPE_NAME (lhs);
882 tree rname = TYPE_NAME (rhs);
883 tree inter;
885 if (lname == rname)
886 return 1;
888 /* If the left hand side is a super class of the right hand side,
889 allow it. */
890 for (inter = lookup_interface (rname); inter;
891 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
892 if (lname == CLASS_SUPER_NAME (inter))
893 return 1;
895 /* Allow the reverse when reflexive. */
896 if (reflexive)
897 for (inter = lookup_interface (lname); inter;
898 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
899 if (rname == CLASS_SUPER_NAME (inter))
900 return 1;
902 return 0;
904 else
905 /* Not an ObjC type - let comptypes do the check. */
906 return -1;
909 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
911 void
912 objc_check_decl (decl)
913 tree decl;
915 tree type = TREE_TYPE (decl);
917 if (TREE_CODE (type) == RECORD_TYPE
918 && TREE_STATIC_TEMPLATE (type)
919 && type != constant_string_type)
920 error_with_decl (decl, "`%s' cannot be statically allocated");
923 /* Implement static typing. At this point, we know we have an interface. */
925 tree
926 get_static_reference (interface, protocols)
927 tree interface;
928 tree protocols;
930 tree type = xref_tag (RECORD_TYPE, interface);
932 if (protocols)
934 tree t, m = TYPE_MAIN_VARIANT (type);
936 t = copy_node (type);
938 /* Add this type to the chain of variants of TYPE. */
939 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
940 TYPE_NEXT_VARIANT (m) = t;
942 /* Look up protocols and install in lang specific list. Note
943 that the protocol list can have a different lifetime than T! */
944 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
946 /* This forces a new pointer type to be created later
947 (in build_pointer_type)...so that the new template
948 we just created will actually be used...what a hack! */
949 if (TYPE_POINTER_TO (t))
950 TYPE_POINTER_TO (t) = NULL_TREE;
952 type = t;
955 return type;
958 tree
959 get_object_reference (protocols)
960 tree protocols;
962 tree type_decl = lookup_name (objc_id_id);
963 tree type;
965 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
967 type = TREE_TYPE (type_decl);
968 if (TYPE_MAIN_VARIANT (type) != id_type)
969 warning ("unexpected type for `id' (%s)",
970 gen_declaration (type, errbuf));
972 else
974 error ("undefined type `id', please import <objc/objc.h>");
975 return error_mark_node;
978 /* This clause creates a new pointer type that is qualified with
979 the protocol specification...this info is used later to do more
980 elaborate type checking. */
982 if (protocols)
984 tree t, m = TYPE_MAIN_VARIANT (type);
986 t = copy_node (type);
988 /* Add this type to the chain of variants of TYPE. */
989 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
990 TYPE_NEXT_VARIANT (m) = t;
992 /* Look up protocols...and install in lang specific list */
993 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
995 /* This forces a new pointer type to be created later
996 (in build_pointer_type)...so that the new template
997 we just created will actually be used...what a hack! */
998 if (TYPE_POINTER_TO (t))
999 TYPE_POINTER_TO (t) = NULL_TREE;
1001 type = t;
1003 return type;
1006 /* Check for circular dependencies in protocols. The arguments are
1007 PROTO, the protocol to check, and LIST, a list of protocol it
1008 conforms to. */
1010 static void
1011 check_protocol_recursively (proto, list)
1012 tree proto;
1013 tree list;
1015 tree p;
1017 for (p = list; p; p = TREE_CHAIN (p))
1019 tree pp = TREE_VALUE (p);
1021 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1022 pp = lookup_protocol (pp);
1024 if (pp == proto)
1025 fatal_error ("protocol `%s' has circular dependency",
1026 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1027 if (pp)
1028 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1032 static tree
1033 lookup_and_install_protocols (protocols)
1034 tree protocols;
1036 tree proto;
1037 tree prev = NULL;
1038 tree return_value = protocols;
1040 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1042 tree ident = TREE_VALUE (proto);
1043 tree p = lookup_protocol (ident);
1045 if (!p)
1047 error ("cannot find protocol declaration for `%s'",
1048 IDENTIFIER_POINTER (ident));
1049 if (prev)
1050 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1051 else
1052 return_value = TREE_CHAIN (proto);
1054 else
1056 /* Replace identifier with actual protocol node. */
1057 TREE_VALUE (proto) = p;
1058 prev = proto;
1062 return return_value;
1065 /* Create and push a decl for a built-in external variable or field NAME.
1066 CODE says which.
1067 TYPE is its data type. */
1069 static tree
1070 create_builtin_decl (code, type, name)
1071 enum tree_code code;
1072 tree type;
1073 const char *name;
1075 tree decl = build_decl (code, get_identifier (name), type);
1077 if (code == VAR_DECL)
1079 TREE_STATIC (decl) = 1;
1080 make_decl_rtl (decl, 0);
1081 pushdecl (decl);
1084 DECL_ARTIFICIAL (decl) = 1;
1085 return decl;
1088 /* Find the decl for the constant string class. */
1090 static void
1091 setup_string_decl ()
1093 if (!string_class_decl)
1095 if (!constant_string_global_id)
1096 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1097 string_class_decl = lookup_name (constant_string_global_id);
1101 /* Purpose: "play" parser, creating/installing representations
1102 of the declarations that are required by Objective-C.
1104 Model:
1106 type_spec--------->sc_spec
1107 (tree_list) (tree_list)
1110 identifier_node identifier_node */
1112 static void
1113 synth_module_prologue ()
1115 tree temp_type;
1116 tree super_p;
1118 /* Defined in `objc.h' */
1119 objc_object_id = get_identifier (TAG_OBJECT);
1121 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1123 id_type = build_pointer_type (objc_object_reference);
1125 objc_id_id = get_identifier (TYPE_ID);
1126 objc_class_id = get_identifier (TAG_CLASS);
1128 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1129 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1130 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1132 /* Declare type of selector-objects that represent an operation name. */
1134 /* `struct objc_selector *' */
1135 selector_type
1136 = build_pointer_type (xref_tag (RECORD_TYPE,
1137 get_identifier (TAG_SELECTOR)));
1139 /* Forward declare type, or else the prototype for msgSendSuper will
1140 complain. */
1142 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1143 get_identifier (TAG_SUPER)));
1146 /* id objc_msgSend (id, SEL, ...); */
1148 temp_type
1149 = build_function_type (id_type,
1150 tree_cons (NULL_TREE, id_type,
1151 tree_cons (NULL_TREE, selector_type,
1152 NULL_TREE)));
1154 if (! flag_next_runtime)
1156 umsg_decl = build_decl (FUNCTION_DECL,
1157 get_identifier (TAG_MSGSEND), temp_type);
1158 DECL_EXTERNAL (umsg_decl) = 1;
1159 TREE_PUBLIC (umsg_decl) = 1;
1160 DECL_INLINE (umsg_decl) = 1;
1161 DECL_ARTIFICIAL (umsg_decl) = 1;
1163 make_decl_rtl (umsg_decl, NULL);
1164 pushdecl (umsg_decl);
1166 else
1167 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
1168 NULL, NULL_TREE);
1170 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1172 temp_type
1173 = build_function_type (id_type,
1174 tree_cons (NULL_TREE, super_p,
1175 tree_cons (NULL_TREE, selector_type,
1176 NULL_TREE)));
1178 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1179 temp_type, 0, NOT_BUILT_IN,
1180 NULL, NULL_TREE);
1182 /* id objc_getClass (const char *); */
1184 temp_type = build_function_type (id_type,
1185 tree_cons (NULL_TREE,
1186 const_string_type_node,
1187 tree_cons (NULL_TREE, void_type_node,
1188 NULL_TREE)));
1190 objc_get_class_decl
1191 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1192 NULL, NULL_TREE);
1194 /* id objc_getMetaClass (const char *); */
1196 objc_get_meta_class_decl
1197 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
1198 NULL, NULL_TREE);
1200 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1202 if (! flag_next_runtime)
1204 if (flag_typed_selectors)
1206 /* Suppress outputting debug symbols, because
1207 dbxout_init hasn'r been called yet. */
1208 enum debug_info_type save_write_symbols = write_symbols;
1209 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1210 write_symbols = NO_DEBUG;
1211 debug_hooks = &do_nothing_debug_hooks;
1213 build_selector_template ();
1214 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1216 write_symbols = save_write_symbols;
1217 debug_hooks = save_hooks;
1219 else
1220 temp_type = build_array_type (selector_type, NULL_TREE);
1222 layout_type (temp_type);
1223 UOBJC_SELECTOR_TABLE_decl
1224 = create_builtin_decl (VAR_DECL, temp_type,
1225 "_OBJC_SELECTOR_TABLE");
1227 /* Avoid warning when not sending messages. */
1228 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1231 generate_forward_declaration_to_string_table ();
1233 /* Forward declare constant_string_id and constant_string_type. */
1234 if (!constant_string_class_name)
1235 constant_string_class_name = default_constant_string_class_name;
1237 constant_string_id = get_identifier (constant_string_class_name);
1238 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1241 /* Predefine the following data type:
1243 struct STRING_OBJECT_CLASS_NAME
1245 Object isa;
1246 char *cString;
1247 unsigned int length;
1248 }; */
1250 static void
1251 build_string_class_template ()
1253 tree field_decl, field_decl_chain;
1255 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1256 field_decl_chain = field_decl;
1258 field_decl = create_builtin_decl (FIELD_DECL,
1259 build_pointer_type (char_type_node),
1260 "cString");
1261 chainon (field_decl_chain, field_decl);
1263 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1264 chainon (field_decl_chain, field_decl);
1266 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1269 /* Custom build_string which sets TREE_TYPE! */
1271 static tree
1272 my_build_string (len, str)
1273 int len;
1274 const char *str;
1276 return fix_string_type (build_string (len, str));
1279 /* Given a chain of STRING_CST's, build a static instance of
1280 NXConstantString which points at the concatenation of those strings.
1281 We place the string object in the __string_objects section of the
1282 __OBJC segment. The Objective-C runtime will initialize the isa
1283 pointers of the string objects to point at the NXConstantString
1284 class object. */
1286 tree
1287 build_objc_string_object (strings)
1288 tree strings;
1290 tree string, initlist, constructor;
1291 int length;
1293 if (lookup_interface (constant_string_id) == NULL_TREE)
1295 error ("cannot find interface declaration for `%s'",
1296 IDENTIFIER_POINTER (constant_string_id));
1297 return error_mark_node;
1300 add_class_reference (constant_string_id);
1302 if (TREE_CHAIN (strings))
1304 varray_type vstrings;
1305 VARRAY_TREE_INIT (vstrings, 32, "strings");
1307 for (; strings ; strings = TREE_CHAIN (strings))
1308 VARRAY_PUSH_TREE (vstrings, strings);
1310 string = combine_strings (vstrings);
1312 else
1313 string = strings;
1315 string = fix_string_type (string);
1317 TREE_SET_CODE (string, STRING_CST);
1318 length = TREE_STRING_LENGTH (string) - 1;
1320 /* We could not properly create NXConstantString in synth_module_prologue,
1321 because that's called before debugging is initialized. Do it now. */
1322 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1323 build_string_class_template ();
1325 /* & ((NXConstantString) { NULL, string, length }) */
1327 if (flag_next_runtime)
1329 /* For the NeXT runtime, we can generate a literal reference
1330 to the string class, don't need to run a constructor. */
1331 setup_string_decl ();
1332 if (string_class_decl == NULL_TREE)
1334 error ("cannot find reference tag for class `%s'",
1335 IDENTIFIER_POINTER (constant_string_id));
1336 return error_mark_node;
1338 initlist = build_tree_list
1339 (NULL_TREE,
1340 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1342 else
1344 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1347 initlist
1348 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1349 initlist);
1350 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1351 constructor = build_constructor (constant_string_type, nreverse (initlist));
1353 if (!flag_next_runtime)
1355 constructor
1356 = objc_add_static_instance (constructor, constant_string_type);
1359 return (build_unary_op (ADDR_EXPR, constructor, 1));
1362 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1364 static tree
1365 objc_add_static_instance (constructor, class_decl)
1366 tree constructor, class_decl;
1368 static int num_static_inst;
1369 tree *chain, decl;
1370 char buf[256];
1372 /* Find the list of static instances for the CLASS_DECL. Create one if
1373 not found. */
1374 for (chain = &objc_static_instances;
1375 *chain && TREE_VALUE (*chain) != class_decl;
1376 chain = &TREE_CHAIN (*chain));
1377 if (!*chain)
1379 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1380 add_objc_string (TYPE_NAME (class_decl), class_names);
1383 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1384 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1385 DECL_COMMON (decl) = 1;
1386 TREE_STATIC (decl) = 1;
1387 DECL_ARTIFICIAL (decl) = 1;
1388 DECL_INITIAL (decl) = constructor;
1390 /* We may be writing something else just now.
1391 Postpone till end of input. */
1392 DECL_DEFER_OUTPUT (decl) = 1;
1393 pushdecl_top_level (decl);
1394 rest_of_decl_compilation (decl, 0, 1, 0);
1396 /* Add the DECL to the head of this CLASS' list. */
1397 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1399 return decl;
1402 /* Build a static constant CONSTRUCTOR
1403 with type TYPE and elements ELTS. */
1405 static tree
1406 build_constructor (type, elts)
1407 tree type, elts;
1409 tree constructor, f, e;
1411 /* ??? Most of the places that we build constructors, we don't fill in
1412 the type of integers properly. Convert them all en masse. */
1413 if (TREE_CODE (type) == ARRAY_TYPE)
1415 f = TREE_TYPE (type);
1416 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1417 for (e = elts; e ; e = TREE_CHAIN (e))
1418 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1420 else
1422 f = TYPE_FIELDS (type);
1423 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1424 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1425 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1426 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1429 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1430 TREE_CONSTANT (constructor) = 1;
1431 TREE_STATIC (constructor) = 1;
1432 TREE_READONLY (constructor) = 1;
1434 return constructor;
1437 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1439 /* Predefine the following data type:
1441 struct _objc_symtab
1443 long sel_ref_cnt;
1444 SEL *refs;
1445 short cls_def_cnt;
1446 short cat_def_cnt;
1447 void *defs[cls_def_cnt + cat_def_cnt];
1448 }; */
1450 static void
1451 build_objc_symtab_template ()
1453 tree field_decl, field_decl_chain, index;
1455 objc_symtab_template
1456 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1458 /* long sel_ref_cnt; */
1460 field_decl = create_builtin_decl (FIELD_DECL,
1461 long_integer_type_node,
1462 "sel_ref_cnt");
1463 field_decl_chain = field_decl;
1465 /* SEL *refs; */
1467 field_decl = create_builtin_decl (FIELD_DECL,
1468 build_pointer_type (selector_type),
1469 "refs");
1470 chainon (field_decl_chain, field_decl);
1472 /* short cls_def_cnt; */
1474 field_decl = create_builtin_decl (FIELD_DECL,
1475 short_integer_type_node,
1476 "cls_def_cnt");
1477 chainon (field_decl_chain, field_decl);
1479 /* short cat_def_cnt; */
1481 field_decl = create_builtin_decl (FIELD_DECL,
1482 short_integer_type_node,
1483 "cat_def_cnt");
1484 chainon (field_decl_chain, field_decl);
1486 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1488 if (!flag_next_runtime)
1489 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1490 else
1491 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1492 imp_count == 0 && cat_count == 0
1493 ? -1 : 0));
1494 field_decl = create_builtin_decl (FIELD_DECL,
1495 build_array_type (ptr_type_node, index),
1496 "defs");
1497 chainon (field_decl_chain, field_decl);
1499 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1502 /* Create the initial value for the `defs' field of _objc_symtab.
1503 This is a CONSTRUCTOR. */
1505 static tree
1506 init_def_list (type)
1507 tree type;
1509 tree expr, initlist = NULL_TREE;
1510 struct imp_entry *impent;
1512 if (imp_count)
1513 for (impent = imp_list; impent; impent = impent->next)
1515 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1517 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1518 initlist = tree_cons (NULL_TREE, expr, initlist);
1522 if (cat_count)
1523 for (impent = imp_list; impent; impent = impent->next)
1525 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1527 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1528 initlist = tree_cons (NULL_TREE, expr, initlist);
1532 if (!flag_next_runtime)
1534 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1535 tree expr;
1537 if (static_instances_decl)
1538 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1539 else
1540 expr = build_int_2 (0, 0);
1542 initlist = tree_cons (NULL_TREE, expr, initlist);
1545 return build_constructor (type, nreverse (initlist));
1548 /* Construct the initial value for all of _objc_symtab. */
1550 static tree
1551 init_objc_symtab (type)
1552 tree type;
1554 tree initlist;
1556 /* sel_ref_cnt = { ..., 5, ... } */
1558 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1560 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1562 if (flag_next_runtime || ! sel_ref_chain)
1563 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1564 else
1565 initlist = tree_cons (NULL_TREE,
1566 build_unary_op (ADDR_EXPR,
1567 UOBJC_SELECTOR_TABLE_decl, 1),
1568 initlist);
1570 /* cls_def_cnt = { ..., 5, ... } */
1572 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1574 /* cat_def_cnt = { ..., 5, ... } */
1576 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1578 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1580 if (imp_count || cat_count || static_instances_decl)
1583 tree field = TYPE_FIELDS (type);
1584 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1586 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1587 initlist);
1590 return build_constructor (type, nreverse (initlist));
1593 /* Push forward-declarations of all the categories so that
1594 init_def_list can use them in a CONSTRUCTOR. */
1596 static void
1597 forward_declare_categories ()
1599 struct imp_entry *impent;
1600 tree sav = objc_implementation_context;
1602 for (impent = imp_list; impent; impent = impent->next)
1604 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1606 /* Set an invisible arg to synth_id_with_class_suffix. */
1607 objc_implementation_context = impent->imp_context;
1608 impent->class_decl
1609 = create_builtin_decl (VAR_DECL, objc_category_template,
1610 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1613 objc_implementation_context = sav;
1616 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1617 and initialized appropriately. */
1619 static void
1620 generate_objc_symtab_decl ()
1622 tree sc_spec;
1624 if (!objc_category_template)
1625 build_category_template ();
1627 /* forward declare categories */
1628 if (cat_count)
1629 forward_declare_categories ();
1631 if (!objc_symtab_template)
1632 build_objc_symtab_template ();
1634 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1636 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1637 tree_cons (NULL_TREE,
1638 objc_symtab_template, sc_spec),
1640 NULL_TREE);
1642 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1643 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1644 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1645 finish_decl (UOBJC_SYMBOLS_decl,
1646 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1647 NULL_TREE);
1650 static tree
1651 init_module_descriptor (type)
1652 tree type;
1654 tree initlist, expr;
1656 /* version = { 1, ... } */
1658 expr = build_int_2 (OBJC_VERSION, 0);
1659 initlist = build_tree_list (NULL_TREE, expr);
1661 /* size = { ..., sizeof (struct objc_module), ... } */
1663 expr = size_in_bytes (objc_module_template);
1664 initlist = tree_cons (NULL_TREE, expr, initlist);
1666 /* name = { ..., "foo.m", ... } */
1668 expr = add_objc_string (get_identifier (input_filename), class_names);
1669 initlist = tree_cons (NULL_TREE, expr, initlist);
1671 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1673 if (UOBJC_SYMBOLS_decl)
1674 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1675 else
1676 expr = build_int_2 (0, 0);
1677 initlist = tree_cons (NULL_TREE, expr, initlist);
1679 return build_constructor (type, nreverse (initlist));
1682 /* Write out the data structures to describe Objective C classes defined.
1683 If appropriate, compile and output a setup function to initialize them.
1684 Return a symbol_ref to the function to call to initialize the Objective C
1685 data structures for this file (and perhaps for other files also).
1687 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1689 static rtx
1690 build_module_descriptor ()
1692 tree decl_specs, field_decl, field_decl_chain;
1694 objc_module_template
1695 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1697 /* Long version; */
1699 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1700 field_decl = get_identifier ("version");
1701 field_decl
1702 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1703 field_decl_chain = field_decl;
1705 /* long size; */
1707 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1708 field_decl = get_identifier ("size");
1709 field_decl
1710 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1711 chainon (field_decl_chain, field_decl);
1713 /* char *name; */
1715 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1716 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1717 field_decl
1718 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1719 chainon (field_decl_chain, field_decl);
1721 /* struct objc_symtab *symtab; */
1723 decl_specs = get_identifier (UTAG_SYMTAB);
1724 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1725 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1726 field_decl
1727 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1728 chainon (field_decl_chain, field_decl);
1730 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1732 /* Create an instance of "objc_module". */
1734 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1735 build_tree_list (NULL_TREE,
1736 ridpointers[(int) RID_STATIC]));
1738 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1739 decl_specs, 1, NULL_TREE);
1741 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1742 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1743 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1745 finish_decl (UOBJC_MODULES_decl,
1746 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1747 NULL_TREE);
1749 /* Mark the decl to avoid "defined but not used" warning. */
1750 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1752 /* Generate a constructor call for the module descriptor.
1753 This code was generated by reading the grammar rules
1754 of c-parse.in; Therefore, it may not be the most efficient
1755 way of generating the requisite code. */
1757 if (flag_next_runtime)
1758 return NULL_RTX;
1761 tree parms, execclass_decl, decelerator, void_list_node_1;
1762 tree init_function_name, init_function_decl;
1764 /* Declare void __objc_execClass (void *); */
1766 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1767 execclass_decl = build_decl (FUNCTION_DECL,
1768 get_identifier (TAG_EXECCLASS),
1769 build_function_type (void_type_node,
1770 tree_cons (NULL_TREE, ptr_type_node,
1771 void_list_node_1)));
1772 DECL_EXTERNAL (execclass_decl) = 1;
1773 DECL_ARTIFICIAL (execclass_decl) = 1;
1774 TREE_PUBLIC (execclass_decl) = 1;
1775 pushdecl (execclass_decl);
1776 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1777 assemble_external (execclass_decl);
1779 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1781 init_function_name = get_file_function_name ('I');
1782 start_function (void_list_node_1,
1783 build_nt (CALL_EXPR, init_function_name,
1784 tree_cons (NULL_TREE, NULL_TREE,
1785 void_list_node_1),
1786 NULL_TREE),
1787 NULL_TREE);
1788 store_parm_decls ();
1790 init_function_decl = current_function_decl;
1791 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1792 TREE_USED (init_function_decl) = 1;
1793 /* Don't let this one be deferred. */
1794 DECL_INLINE (init_function_decl) = 0;
1795 DECL_UNINLINABLE (init_function_decl) = 1;
1796 current_function_cannot_inline
1797 = "static constructors and destructors cannot be inlined";
1799 parms
1800 = build_tree_list (NULL_TREE,
1801 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1802 decelerator = build_function_call (execclass_decl, parms);
1804 c_expand_expr_stmt (decelerator);
1806 finish_function (0, 0);
1808 return XEXP (DECL_RTL (init_function_decl), 0);
1812 /* extern const char _OBJC_STRINGS[]; */
1814 static void
1815 generate_forward_declaration_to_string_table ()
1817 tree sc_spec, decl_specs, expr_decl;
1819 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1820 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1822 expr_decl
1823 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1825 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1828 /* Return the DECL of the string IDENT in the SECTION. */
1830 static tree
1831 get_objc_string_decl (ident, section)
1832 tree ident;
1833 enum string_section section;
1835 tree chain;
1837 if (section == class_names)
1838 chain = class_names_chain;
1839 else if (section == meth_var_names)
1840 chain = meth_var_names_chain;
1841 else if (section == meth_var_types)
1842 chain = meth_var_types_chain;
1843 else
1844 abort ();
1846 for (; chain != 0; chain = TREE_CHAIN (chain))
1847 if (TREE_VALUE (chain) == ident)
1848 return (TREE_PURPOSE (chain));
1850 abort ();
1851 return NULL_TREE;
1854 /* Output references to all statically allocated objects. Return the DECL
1855 for the array built. */
1857 static void
1858 generate_static_references ()
1860 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1861 tree class_name, class, decl, initlist;
1862 tree cl_chain, in_chain, type;
1863 int num_inst, num_class;
1864 char buf[256];
1866 if (flag_next_runtime)
1867 abort ();
1869 for (cl_chain = objc_static_instances, num_class = 0;
1870 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1872 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1873 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1875 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1876 ident = get_identifier (buf);
1878 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1879 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1880 build_tree_list (NULL_TREE,
1881 ridpointers[(int) RID_STATIC]));
1882 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1883 DECL_CONTEXT (decl) = 0;
1884 DECL_ARTIFICIAL (decl) = 1;
1886 /* Output {class_name, ...}. */
1887 class = TREE_VALUE (cl_chain);
1888 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1889 initlist = build_tree_list (NULL_TREE,
1890 build_unary_op (ADDR_EXPR, class_name, 1));
1892 /* Output {..., instance, ...}. */
1893 for (in_chain = TREE_PURPOSE (cl_chain);
1894 in_chain; in_chain = TREE_CHAIN (in_chain))
1896 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1897 initlist = tree_cons (NULL_TREE, expr, initlist);
1900 /* Output {..., NULL}. */
1901 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1903 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1904 finish_decl (decl, expr, NULL_TREE);
1905 TREE_USED (decl) = 1;
1907 type = build_array_type (build_pointer_type (void_type_node), 0);
1908 decl = build_decl (VAR_DECL, ident, type);
1909 TREE_USED (decl) = 1;
1910 TREE_STATIC (decl) = 1;
1911 decls
1912 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1915 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1916 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1917 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1918 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1919 build_tree_list (NULL_TREE,
1920 ridpointers[(int) RID_STATIC]));
1921 static_instances_decl
1922 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1923 TREE_USED (static_instances_decl) = 1;
1924 DECL_CONTEXT (static_instances_decl) = 0;
1925 DECL_ARTIFICIAL (static_instances_decl) = 1;
1926 expr = build_constructor (TREE_TYPE (static_instances_decl),
1927 nreverse (decls));
1928 finish_decl (static_instances_decl, expr, NULL_TREE);
1931 /* Output all strings. */
1933 static void
1934 generate_strings ()
1936 tree sc_spec, decl_specs, expr_decl;
1937 tree chain, string_expr;
1938 tree string, decl;
1940 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1942 string = TREE_VALUE (chain);
1943 decl = TREE_PURPOSE (chain);
1944 sc_spec
1945 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1946 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1947 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1948 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1949 DECL_CONTEXT (decl) = NULL_TREE;
1950 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1951 IDENTIFIER_POINTER (string));
1952 finish_decl (decl, string_expr, NULL_TREE);
1955 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1957 string = TREE_VALUE (chain);
1958 decl = TREE_PURPOSE (chain);
1959 sc_spec
1960 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1961 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1962 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1963 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1964 DECL_CONTEXT (decl) = NULL_TREE;
1965 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1966 IDENTIFIER_POINTER (string));
1967 finish_decl (decl, string_expr, NULL_TREE);
1970 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1972 string = TREE_VALUE (chain);
1973 decl = TREE_PURPOSE (chain);
1974 sc_spec
1975 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1976 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1977 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1978 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1979 DECL_CONTEXT (decl) = NULL_TREE;
1980 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1981 IDENTIFIER_POINTER (string));
1982 finish_decl (decl, string_expr, NULL_TREE);
1986 static tree
1987 build_selector_reference_decl ()
1989 tree decl, ident;
1990 char buf[256];
1991 static int idx = 0;
1993 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1995 ident = get_identifier (buf);
1997 decl = build_decl (VAR_DECL, ident, selector_type);
1998 DECL_EXTERNAL (decl) = 1;
1999 TREE_PUBLIC (decl) = 1;
2000 TREE_USED (decl) = 1;
2001 TREE_READONLY (decl) = 1;
2002 DECL_ARTIFICIAL (decl) = 1;
2003 DECL_CONTEXT (decl) = 0;
2005 make_decl_rtl (decl, 0);
2006 pushdecl_top_level (decl);
2008 return decl;
2011 /* Just a handy wrapper for add_objc_string. */
2013 static tree
2014 build_selector (ident)
2015 tree ident;
2017 tree expr = add_objc_string (ident, meth_var_names);
2018 if (flag_typed_selectors)
2019 return expr;
2020 else
2021 return build_c_cast (selector_type, expr); /* cast! */
2024 static void
2025 build_selector_translation_table ()
2027 tree sc_spec, decl_specs;
2028 tree chain, initlist = NULL_TREE;
2029 int offset = 0;
2030 tree decl = NULL_TREE, var_decl, name;
2032 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2034 tree expr;
2036 if (warn_selector && objc_implementation_context)
2038 tree method_chain;
2039 bool found = false;
2040 for (method_chain = meth_var_names_chain;
2041 method_chain;
2042 method_chain = TREE_CHAIN (method_chain))
2044 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2046 found = true;
2047 break;
2050 if (!found)
2052 /* Adjust line number for warning message. */
2053 int save_lineno = lineno;
2054 if (flag_next_runtime && TREE_PURPOSE (chain))
2055 lineno = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2056 warning ("creating selector for non existant method %s",
2057 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2058 lineno = save_lineno;
2062 expr = build_selector (TREE_VALUE (chain));
2064 if (flag_next_runtime)
2066 name = DECL_NAME (TREE_PURPOSE (chain));
2068 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2070 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2071 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2073 var_decl = name;
2075 /* The `decl' that is returned from start_decl is the one that we
2076 forward declared in `build_selector_reference' */
2077 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2080 /* add one for the '\0' character */
2081 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2083 if (flag_next_runtime)
2084 finish_decl (decl, expr, NULL_TREE);
2085 else
2087 if (flag_typed_selectors)
2089 tree eltlist = NULL_TREE;
2090 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2091 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2092 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2093 expr = build_constructor (objc_selector_template,
2094 nreverse (eltlist));
2096 initlist = tree_cons (NULL_TREE, expr, initlist);
2101 if (! flag_next_runtime)
2103 /* Cause the variable and its initial value to be actually output. */
2104 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2105 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2106 /* NULL terminate the list and fix the decl for output. */
2107 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2108 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2109 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2110 nreverse (initlist));
2111 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2112 current_function_decl = NULL_TREE;
2116 static tree
2117 get_proto_encoding (proto)
2118 tree proto;
2120 tree encoding;
2121 if (proto)
2123 tree tmp_decl;
2125 if (! METHOD_ENCODING (proto))
2127 tmp_decl = build_tmp_function_decl ();
2128 hack_method_prototype (proto, tmp_decl);
2129 encoding = encode_method_prototype (proto, tmp_decl);
2130 METHOD_ENCODING (proto) = encoding;
2132 else
2133 encoding = METHOD_ENCODING (proto);
2135 return add_objc_string (encoding, meth_var_types);
2137 else
2138 return build_int_2 (0, 0);
2141 /* sel_ref_chain is a list whose "value" fields will be instances of
2142 identifier_node that represent the selector. */
2144 static tree
2145 build_typed_selector_reference (ident, prototype)
2146 tree ident, prototype;
2148 tree *chain = &sel_ref_chain;
2149 tree expr;
2150 int index = 0;
2152 while (*chain)
2154 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2155 goto return_at_index;
2157 index++;
2158 chain = &TREE_CHAIN (*chain);
2161 *chain = tree_cons (prototype, ident, NULL_TREE);
2163 return_at_index:
2164 expr = build_unary_op (ADDR_EXPR,
2165 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2166 build_int_2 (index, 0)),
2168 return build_c_cast (selector_type, expr);
2171 static tree
2172 build_selector_reference (ident)
2173 tree ident;
2175 tree *chain = &sel_ref_chain;
2176 tree expr;
2177 int index = 0;
2179 while (*chain)
2181 if (TREE_VALUE (*chain) == ident)
2182 return (flag_next_runtime
2183 ? TREE_PURPOSE (*chain)
2184 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2185 build_int_2 (index, 0)));
2187 index++;
2188 chain = &TREE_CHAIN (*chain);
2191 expr = build_selector_reference_decl ();
2193 *chain = tree_cons (expr, ident, NULL_TREE);
2195 return (flag_next_runtime
2196 ? expr
2197 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2198 build_int_2 (index, 0)));
2201 static tree
2202 build_class_reference_decl ()
2204 tree decl, ident;
2205 char buf[256];
2206 static int idx = 0;
2208 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2210 ident = get_identifier (buf);
2212 decl = build_decl (VAR_DECL, ident, objc_class_type);
2213 DECL_EXTERNAL (decl) = 1;
2214 TREE_PUBLIC (decl) = 1;
2215 TREE_USED (decl) = 1;
2216 TREE_READONLY (decl) = 1;
2217 DECL_CONTEXT (decl) = 0;
2218 DECL_ARTIFICIAL (decl) = 1;
2220 make_decl_rtl (decl, 0);
2221 pushdecl_top_level (decl);
2223 return decl;
2226 /* Create a class reference, but don't create a variable to reference
2227 it. */
2229 static void
2230 add_class_reference (ident)
2231 tree ident;
2233 tree chain;
2235 if ((chain = cls_ref_chain))
2237 tree tail;
2240 if (ident == TREE_VALUE (chain))
2241 return;
2243 tail = chain;
2244 chain = TREE_CHAIN (chain);
2246 while (chain);
2248 /* Append to the end of the list */
2249 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2251 else
2252 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2255 /* Get a class reference, creating it if necessary. Also create the
2256 reference variable. */
2258 tree
2259 get_class_reference (ident)
2260 tree ident;
2262 if (flag_next_runtime)
2264 tree *chain;
2265 tree decl;
2267 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2268 if (TREE_VALUE (*chain) == ident)
2270 if (! TREE_PURPOSE (*chain))
2271 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2273 return TREE_PURPOSE (*chain);
2276 decl = build_class_reference_decl ();
2277 *chain = tree_cons (decl, ident, NULL_TREE);
2278 return decl;
2280 else
2282 tree params;
2284 add_class_reference (ident);
2286 params = build_tree_list (NULL_TREE,
2287 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2288 IDENTIFIER_POINTER (ident)));
2290 assemble_external (objc_get_class_decl);
2291 return build_function_call (objc_get_class_decl, params);
2295 /* For each string section we have a chain which maps identifier nodes
2296 to decls for the strings. */
2298 static tree
2299 add_objc_string (ident, section)
2300 tree ident;
2301 enum string_section section;
2303 tree *chain, decl;
2305 if (section == class_names)
2306 chain = &class_names_chain;
2307 else if (section == meth_var_names)
2308 chain = &meth_var_names_chain;
2309 else if (section == meth_var_types)
2310 chain = &meth_var_types_chain;
2311 else
2312 abort ();
2314 while (*chain)
2316 if (TREE_VALUE (*chain) == ident)
2317 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2319 chain = &TREE_CHAIN (*chain);
2322 decl = build_objc_string_decl (section);
2324 *chain = tree_cons (decl, ident, NULL_TREE);
2326 return build_unary_op (ADDR_EXPR, decl, 1);
2329 static tree
2330 build_objc_string_decl (section)
2331 enum string_section section;
2333 tree decl, ident;
2334 char buf[256];
2335 static int class_names_idx = 0;
2336 static int meth_var_names_idx = 0;
2337 static int meth_var_types_idx = 0;
2339 if (section == class_names)
2340 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2341 else if (section == meth_var_names)
2342 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2343 else if (section == meth_var_types)
2344 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2346 ident = get_identifier (buf);
2348 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2349 DECL_EXTERNAL (decl) = 1;
2350 TREE_PUBLIC (decl) = 1;
2351 TREE_USED (decl) = 1;
2352 TREE_READONLY (decl) = 1;
2353 TREE_CONSTANT (decl) = 1;
2354 DECL_CONTEXT (decl) = 0;
2355 DECL_ARTIFICIAL (decl) = 1;
2357 make_decl_rtl (decl, 0);
2358 pushdecl_top_level (decl);
2360 return decl;
2364 void
2365 objc_declare_alias (alias_ident, class_ident)
2366 tree alias_ident;
2367 tree class_ident;
2369 if (is_class_name (class_ident) != class_ident)
2370 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2371 else if (is_class_name (alias_ident))
2372 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2373 else
2374 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2377 void
2378 objc_declare_class (ident_list)
2379 tree ident_list;
2381 tree list;
2383 for (list = ident_list; list; list = TREE_CHAIN (list))
2385 tree ident = TREE_VALUE (list);
2386 tree decl;
2388 if ((decl = lookup_name (ident)))
2390 error ("`%s' redeclared as different kind of symbol",
2391 IDENTIFIER_POINTER (ident));
2392 error_with_decl (decl, "previous declaration of `%s'");
2395 if (! is_class_name (ident))
2397 tree record = xref_tag (RECORD_TYPE, ident);
2398 TREE_STATIC_TEMPLATE (record) = 1;
2399 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2404 tree
2405 is_class_name (ident)
2406 tree ident;
2408 tree chain;
2410 if (lookup_interface (ident))
2411 return ident;
2413 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2415 if (ident == TREE_VALUE (chain))
2416 return ident;
2419 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2421 if (ident == TREE_VALUE (chain))
2422 return TREE_PURPOSE (chain);
2425 return 0;
2428 tree
2429 objc_is_id (ident)
2430 tree ident;
2432 /* NB: This function may be called before the ObjC front-end
2433 has been initialized, in which case ID_TYPE will be NULL. */
2434 return (id_type && ident && TYPE_P (ident) && IS_ID (ident))
2435 ? id_type
2436 : NULL_TREE;
2439 tree
2440 lookup_interface (ident)
2441 tree ident;
2443 tree chain;
2445 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2447 if (ident == CLASS_NAME (chain))
2448 return chain;
2450 return NULL_TREE;
2453 /* Used by: build_private_template, continue_class,
2454 and for @defs constructs. */
2456 tree
2457 get_class_ivars (interface)
2458 tree interface;
2460 tree my_name, super_name, ivar_chain;
2462 my_name = CLASS_NAME (interface);
2463 super_name = CLASS_SUPER_NAME (interface);
2464 ivar_chain = CLASS_IVARS (interface);
2466 /* Save off a pristine copy of the leaf ivars (i.e, those not
2467 inherited from a super class). */
2468 if (!CLASS_OWN_IVARS (interface))
2469 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2471 while (super_name)
2473 tree op1;
2474 tree super_interface = lookup_interface (super_name);
2476 if (!super_interface)
2478 /* fatal did not work with 2 args...should fix */
2479 error ("cannot find interface declaration for `%s', superclass of `%s'",
2480 IDENTIFIER_POINTER (super_name),
2481 IDENTIFIER_POINTER (my_name));
2482 exit (FATAL_EXIT_CODE);
2485 if (super_interface == interface)
2486 fatal_error ("circular inheritance in interface declaration for `%s'",
2487 IDENTIFIER_POINTER (super_name));
2489 interface = super_interface;
2490 my_name = CLASS_NAME (interface);
2491 super_name = CLASS_SUPER_NAME (interface);
2493 op1 = CLASS_OWN_IVARS (interface);
2494 if (op1)
2496 tree head = copy_list (op1);
2498 /* Prepend super class ivars...make a copy of the list, we
2499 do not want to alter the original. */
2500 chainon (head, ivar_chain);
2501 ivar_chain = head;
2504 return ivar_chain;
2507 /* struct <classname> {
2508 struct objc_class *isa;
2510 }; */
2512 static tree
2513 build_private_template (class)
2514 tree class;
2516 tree ivar_context;
2518 if (CLASS_STATIC_TEMPLATE (class))
2520 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2521 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2523 else
2525 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2527 ivar_context = get_class_ivars (class);
2529 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2531 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2533 /* mark this record as class template - for class type checking */
2534 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2537 instance_type
2538 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2539 uprivate_record),
2540 build1 (INDIRECT_REF, NULL_TREE,
2541 NULL_TREE)));
2543 return ivar_context;
2546 /* Begin code generation for protocols... */
2548 /* struct objc_protocol {
2549 char *protocol_name;
2550 struct objc_protocol **protocol_list;
2551 struct objc_method_desc *instance_methods;
2552 struct objc_method_desc *class_methods;
2553 }; */
2555 static tree
2556 build_protocol_template ()
2558 tree decl_specs, field_decl, field_decl_chain;
2559 tree template;
2561 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2563 /* struct objc_class *isa; */
2565 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2566 get_identifier (UTAG_CLASS)));
2567 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2568 field_decl
2569 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2570 field_decl_chain = field_decl;
2572 /* char *protocol_name; */
2574 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2575 field_decl
2576 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2577 field_decl
2578 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2579 chainon (field_decl_chain, field_decl);
2581 /* struct objc_protocol **protocol_list; */
2583 decl_specs = build_tree_list (NULL_TREE, template);
2584 field_decl
2585 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2586 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2587 field_decl
2588 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2589 chainon (field_decl_chain, field_decl);
2591 /* struct objc_method_list *instance_methods; */
2593 decl_specs
2594 = build_tree_list (NULL_TREE,
2595 xref_tag (RECORD_TYPE,
2596 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2597 field_decl
2598 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2599 field_decl
2600 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2601 chainon (field_decl_chain, field_decl);
2603 /* struct objc_method_list *class_methods; */
2605 decl_specs
2606 = build_tree_list (NULL_TREE,
2607 xref_tag (RECORD_TYPE,
2608 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2609 field_decl
2610 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2611 field_decl
2612 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2613 chainon (field_decl_chain, field_decl);
2615 return finish_struct (template, field_decl_chain, NULL_TREE);
2618 static tree
2619 build_descriptor_table_initializer (type, entries)
2620 tree type;
2621 tree entries;
2623 tree initlist = NULL_TREE;
2627 tree eltlist = NULL_TREE;
2629 eltlist
2630 = tree_cons (NULL_TREE,
2631 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2632 eltlist
2633 = tree_cons (NULL_TREE,
2634 add_objc_string (METHOD_ENCODING (entries),
2635 meth_var_types),
2636 eltlist);
2638 initlist
2639 = tree_cons (NULL_TREE,
2640 build_constructor (type, nreverse (eltlist)), initlist);
2642 entries = TREE_CHAIN (entries);
2644 while (entries);
2646 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2649 /* struct objc_method_prototype_list {
2650 int count;
2651 struct objc_method_prototype {
2652 SEL name;
2653 char *types;
2654 } list[1];
2655 }; */
2657 static tree
2658 build_method_prototype_list_template (list_type, size)
2659 tree list_type;
2660 int size;
2662 tree objc_ivar_list_record;
2663 tree decl_specs, field_decl, field_decl_chain;
2665 /* Generate an unnamed struct definition. */
2667 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2669 /* int method_count; */
2671 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2672 field_decl = get_identifier ("method_count");
2674 field_decl
2675 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2676 field_decl_chain = field_decl;
2678 /* struct objc_method method_list[]; */
2680 decl_specs = build_tree_list (NULL_TREE, list_type);
2681 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2682 build_int_2 (size, 0));
2684 field_decl
2685 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2686 chainon (field_decl_chain, field_decl);
2688 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2690 return objc_ivar_list_record;
2693 static tree
2694 build_method_prototype_template ()
2696 tree proto_record;
2697 tree decl_specs, field_decl, field_decl_chain;
2699 proto_record
2700 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2702 /* struct objc_selector *_cmd; */
2703 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2704 get_identifier (TAG_SELECTOR)), NULL_TREE);
2705 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2707 field_decl
2708 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2709 field_decl_chain = field_decl;
2711 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2712 field_decl
2713 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2714 field_decl
2715 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2716 chainon (field_decl_chain, field_decl);
2718 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2720 return proto_record;
2723 /* True if last call to forwarding_offset yielded a register offset. */
2724 static int offset_is_register;
2726 static int
2727 forwarding_offset (parm)
2728 tree parm;
2730 int offset_in_bytes;
2732 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2734 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2736 /* ??? Here we assume that the parm address is indexed
2737 off the frame pointer or arg pointer.
2738 If that is not true, we produce meaningless results,
2739 but do not crash. */
2740 if (GET_CODE (addr) == PLUS
2741 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2742 offset_in_bytes = INTVAL (XEXP (addr, 1));
2743 else
2744 offset_in_bytes = 0;
2746 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2747 offset_is_register = 0;
2749 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2751 int regno = REGNO (DECL_INCOMING_RTL (parm));
2752 offset_in_bytes = apply_args_register_offset (regno);
2753 offset_is_register = 1;
2755 else
2756 return 0;
2758 /* This is the case where the parm is passed as an int or double
2759 and it is converted to a char, short or float and stored back
2760 in the parmlist. In this case, describe the parm
2761 with the variable's declared type, and adjust the address
2762 if the least significant bytes (which we are using) are not
2763 the first ones. */
2764 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2765 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2766 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2768 return offset_in_bytes;
2771 static tree
2772 encode_method_prototype (method_decl, func_decl)
2773 tree method_decl;
2774 tree func_decl;
2776 tree parms;
2777 int stack_size, i;
2778 tree user_args;
2779 HOST_WIDE_INT max_parm_end = 0;
2780 char buf[40];
2781 tree result;
2783 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2784 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2786 /* C type. */
2787 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2788 obstack_object_size (&util_obstack),
2789 OBJC_ENCODE_INLINE_DEFS);
2791 /* Stack size. */
2792 for (parms = DECL_ARGUMENTS (func_decl); parms;
2793 parms = TREE_CHAIN (parms))
2795 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2796 + int_size_in_bytes (TREE_TYPE (parms)));
2798 if (!offset_is_register && max_parm_end < parm_end)
2799 max_parm_end = parm_end;
2802 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2804 sprintf (buf, "%d", stack_size);
2805 obstack_grow (&util_obstack, buf, strlen (buf));
2807 user_args = METHOD_SEL_ARGS (method_decl);
2809 /* Argument types. */
2810 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2811 parms = TREE_CHAIN (parms), i++)
2813 /* Process argument qualifiers for user supplied arguments. */
2814 if (i > 1)
2816 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2817 user_args = TREE_CHAIN (user_args);
2820 /* Type. */
2821 encode_type (TREE_TYPE (parms),
2822 obstack_object_size (&util_obstack),
2823 OBJC_ENCODE_INLINE_DEFS);
2825 /* Compute offset. */
2826 sprintf (buf, "%d", forwarding_offset (parms));
2828 /* Indicate register. */
2829 if (offset_is_register)
2830 obstack_1grow (&util_obstack, '+');
2832 obstack_grow (&util_obstack, buf, strlen (buf));
2835 obstack_1grow (&util_obstack, '\0');
2836 result = get_identifier (obstack_finish (&util_obstack));
2837 obstack_free (&util_obstack, util_firstobj);
2838 return result;
2841 static tree
2842 generate_descriptor_table (type, name, size, list, proto)
2843 tree type;
2844 const char *name;
2845 int size;
2846 tree list;
2847 tree proto;
2849 tree sc_spec, decl_specs, decl, initlist;
2851 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2852 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2854 decl = start_decl (synth_id_with_class_suffix (name, proto),
2855 decl_specs, 1, NULL_TREE);
2856 DECL_CONTEXT (decl) = NULL_TREE;
2858 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2859 initlist = tree_cons (NULL_TREE, list, initlist);
2861 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2862 NULL_TREE);
2864 return decl;
2867 static void
2868 generate_method_descriptors (protocol)
2869 tree protocol;
2871 tree initlist, chain, method_list_template;
2872 tree cast, variable_length_type;
2873 int size;
2875 if (!objc_method_prototype_template)
2876 objc_method_prototype_template = build_method_prototype_template ();
2878 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2879 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2880 NULL_TREE);
2881 variable_length_type = groktypename (cast);
2883 chain = PROTOCOL_CLS_METHODS (protocol);
2884 if (chain)
2886 size = list_length (chain);
2888 method_list_template
2889 = build_method_prototype_list_template (objc_method_prototype_template,
2890 size);
2892 initlist
2893 = build_descriptor_table_initializer (objc_method_prototype_template,
2894 chain);
2896 UOBJC_CLASS_METHODS_decl
2897 = generate_descriptor_table (method_list_template,
2898 "_OBJC_PROTOCOL_CLASS_METHODS",
2899 size, initlist, protocol);
2900 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2902 else
2903 UOBJC_CLASS_METHODS_decl = 0;
2905 chain = PROTOCOL_NST_METHODS (protocol);
2906 if (chain)
2908 size = list_length (chain);
2910 method_list_template
2911 = build_method_prototype_list_template (objc_method_prototype_template,
2912 size);
2913 initlist
2914 = build_descriptor_table_initializer (objc_method_prototype_template,
2915 chain);
2917 UOBJC_INSTANCE_METHODS_decl
2918 = generate_descriptor_table (method_list_template,
2919 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2920 size, initlist, protocol);
2921 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2923 else
2924 UOBJC_INSTANCE_METHODS_decl = 0;
2927 /* Generate a temporary FUNCTION_DECL node to be used in
2928 hack_method_prototype below. */
2930 static tree
2931 build_tmp_function_decl ()
2933 tree decl_specs, expr_decl, parms;
2934 static int xxx = 0;
2935 char buffer[80];
2937 /* struct objc_object *objc_xxx (id, SEL, ...); */
2938 pushlevel (0);
2939 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2940 push_parm_decl (build_tree_list
2941 (build_tree_list (decl_specs,
2942 build1 (INDIRECT_REF, NULL_TREE,
2943 NULL_TREE)),
2944 NULL_TREE));
2946 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2947 get_identifier (TAG_SELECTOR)));
2948 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2950 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2951 NULL_TREE));
2952 parms = get_parm_info (0);
2953 poplevel (0, 0, 0);
2955 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2956 sprintf (buffer, "__objc_tmp_%x", xxx++);
2957 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2958 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2960 return define_decl (expr_decl, decl_specs);
2963 /* Generate the prototypes for protocol methods. This is used to
2964 generate method encodings for these.
2966 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2967 a decl node to be used. This is also where the return value is
2968 given. */
2970 static void
2971 hack_method_prototype (nst_methods, tmp_decl)
2972 tree nst_methods;
2973 tree tmp_decl;
2975 tree parms;
2976 tree parm;
2978 /* Hack to avoid problem with static typing of self arg. */
2979 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2980 start_method_def (nst_methods);
2981 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2983 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2984 parms = get_parm_info (0); /* we have a `, ...' */
2985 else
2986 parms = get_parm_info (1); /* place a `void_at_end' */
2988 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2990 /* Usually called from store_parm_decls -> init_function_start. */
2992 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2994 if (current_function_decl)
2995 abort ();
2996 current_function_decl = tmp_decl;
2999 /* Code taken from start_function. */
3000 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
3001 /* Promote the value to int before returning it. */
3002 if (TREE_CODE (restype) == INTEGER_TYPE
3003 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
3004 restype = integer_type_node;
3005 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
3008 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
3009 DECL_CONTEXT (parm) = tmp_decl;
3011 init_function_start (tmp_decl, "objc-act", 0);
3013 /* Typically called from expand_function_start for function definitions. */
3014 assign_parms (tmp_decl);
3016 /* install return type */
3017 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
3019 current_function_decl = NULL;
3022 static void
3023 generate_protocol_references (plist)
3024 tree plist;
3026 tree lproto;
3028 /* Forward declare protocols referenced. */
3029 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3031 tree proto = TREE_VALUE (lproto);
3033 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3034 && PROTOCOL_NAME (proto))
3036 if (! PROTOCOL_FORWARD_DECL (proto))
3037 build_protocol_reference (proto);
3039 if (PROTOCOL_LIST (proto))
3040 generate_protocol_references (PROTOCOL_LIST (proto));
3045 /* For each protocol which was referenced either from a @protocol()
3046 expression, or because a class/category implements it (then a
3047 pointer to the protocol is stored in the struct describing the
3048 class/category), we create a statically allocated instance of the
3049 Protocol class. The code is written in such a way as to generate
3050 as few Protocol objects as possible; we generate a unique Protocol
3051 instance for each protocol, and we don't generate a Protocol
3052 instance if the protocol is never referenced (either from a
3053 @protocol() or from a class/category implementation). These
3054 statically allocated objects can be referred to via the static
3055 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3057 The statically allocated Protocol objects that we generate here
3058 need to be fixed up at runtime in order to be used: the 'isa'
3059 pointer of the objects need to be set up to point to the 'Protocol'
3060 class, as known at runtime.
3062 The NeXT runtime fixes up all protocols at program startup time,
3063 before main() is entered. It uses a low-level trick to look up all
3064 those symbols, then loops on them and fixes them up.
3066 The GNU runtime as well fixes up all protocols before user code
3067 from the module is executed; it requires pointers to those symbols
3068 to be put in the objc_symtab (which is then passed as argument to
3069 the function __objc_exec_class() which the compiler sets up to be
3070 executed automatically when the module is loaded); setup of those
3071 Protocol objects happen in two ways in the GNU runtime: all
3072 Protocol objects referred to by a class or category implementation
3073 are fixed up when the class/category is loaded; all Protocol
3074 objects referred to by a @protocol() expression are added by the
3075 compiler to the list of statically allocated instances to fixup
3076 (the same list holding the statically allocated constant string
3077 objects). Because, as explained above, the compiler generates as
3078 few Protocol objects as possible, some Protocol object might end up
3079 being referenced multiple times when compiled with the GNU runtime,
3080 and end up being fixed up multiple times at runtime inizialization.
3081 But that doesn't hurt, it's just a little inefficient. */
3082 static void
3083 generate_protocols ()
3085 tree p, tmp_decl, encoding;
3086 tree sc_spec, decl_specs, decl;
3087 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3088 tree cast_type2;
3090 tmp_decl = build_tmp_function_decl ();
3092 if (! objc_protocol_template)
3093 objc_protocol_template = build_protocol_template ();
3095 /* If a protocol was directly referenced, pull in indirect references. */
3096 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3097 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3098 generate_protocol_references (PROTOCOL_LIST (p));
3100 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3102 tree nst_methods = PROTOCOL_NST_METHODS (p);
3103 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3105 /* If protocol wasn't referenced, don't generate any code. */
3106 if (! PROTOCOL_FORWARD_DECL (p))
3107 continue;
3109 /* Make sure we link in the Protocol class. */
3110 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3112 while (nst_methods)
3114 if (! METHOD_ENCODING (nst_methods))
3116 hack_method_prototype (nst_methods, tmp_decl);
3117 encoding = encode_method_prototype (nst_methods, tmp_decl);
3118 METHOD_ENCODING (nst_methods) = encoding;
3120 nst_methods = TREE_CHAIN (nst_methods);
3123 while (cls_methods)
3125 if (! METHOD_ENCODING (cls_methods))
3127 hack_method_prototype (cls_methods, tmp_decl);
3128 encoding = encode_method_prototype (cls_methods, tmp_decl);
3129 METHOD_ENCODING (cls_methods) = encoding;
3132 cls_methods = TREE_CHAIN (cls_methods);
3134 generate_method_descriptors (p);
3136 if (PROTOCOL_LIST (p))
3137 refs_decl = generate_protocol_list (p);
3138 else
3139 refs_decl = 0;
3141 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3143 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3144 NULL_TREE);
3145 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3147 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3148 decl_specs, 1, NULL_TREE);
3150 DECL_CONTEXT (decl) = NULL_TREE;
3152 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3154 if (refs_decl)
3156 cast_type2
3157 = groktypename
3158 (build_tree_list (build_tree_list (NULL_TREE,
3159 objc_protocol_template),
3160 build1 (INDIRECT_REF, NULL_TREE,
3161 build1 (INDIRECT_REF, NULL_TREE,
3162 NULL_TREE))));
3164 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3165 TREE_TYPE (refs_expr) = cast_type2;
3167 else
3168 refs_expr = build_int_2 (0, 0);
3170 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3171 by generate_method_descriptors, which is called above. */
3172 initlist = build_protocol_initializer (TREE_TYPE (decl),
3173 protocol_name_expr, refs_expr,
3174 UOBJC_INSTANCE_METHODS_decl,
3175 UOBJC_CLASS_METHODS_decl);
3176 finish_decl (decl, initlist, NULL_TREE);
3178 /* Mark the decl as used to avoid "defined but not used" warning. */
3179 TREE_USED (decl) = 1;
3183 static tree
3184 build_protocol_initializer (type, protocol_name, protocol_list,
3185 instance_methods, class_methods)
3186 tree type;
3187 tree protocol_name;
3188 tree protocol_list;
3189 tree instance_methods;
3190 tree class_methods;
3192 tree initlist = NULL_TREE, expr;
3193 tree cast_type;
3195 cast_type = groktypename
3196 (build_tree_list
3197 (build_tree_list (NULL_TREE,
3198 xref_tag (RECORD_TYPE,
3199 get_identifier (UTAG_CLASS))),
3200 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3202 /* Filling the "isa" in with one allows the runtime system to
3203 detect that the version change...should remove before final release. */
3205 expr = build_int_2 (PROTOCOL_VERSION, 0);
3206 TREE_TYPE (expr) = cast_type;
3207 initlist = tree_cons (NULL_TREE, expr, initlist);
3208 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3209 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3211 if (!instance_methods)
3212 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3213 else
3215 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3216 initlist = tree_cons (NULL_TREE, expr, initlist);
3219 if (!class_methods)
3220 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3221 else
3223 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3224 initlist = tree_cons (NULL_TREE, expr, initlist);
3227 return build_constructor (type, nreverse (initlist));
3230 /* struct objc_category {
3231 char *category_name;
3232 char *class_name;
3233 struct objc_method_list *instance_methods;
3234 struct objc_method_list *class_methods;
3235 struct objc_protocol_list *protocols;
3236 }; */
3238 static void
3239 build_category_template ()
3241 tree decl_specs, field_decl, field_decl_chain;
3243 objc_category_template = start_struct (RECORD_TYPE,
3244 get_identifier (UTAG_CATEGORY));
3245 /* char *category_name; */
3247 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3248 field_decl
3249 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3250 field_decl
3251 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3252 field_decl_chain = field_decl;
3254 /* char *class_name; */
3256 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3257 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3258 field_decl
3259 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3260 chainon (field_decl_chain, field_decl);
3262 /* struct objc_method_list *instance_methods; */
3264 decl_specs = build_tree_list (NULL_TREE,
3265 xref_tag (RECORD_TYPE,
3266 get_identifier (UTAG_METHOD_LIST)));
3267 field_decl
3268 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3269 field_decl
3270 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3271 chainon (field_decl_chain, field_decl);
3273 /* struct objc_method_list *class_methods; */
3275 decl_specs = build_tree_list (NULL_TREE,
3276 xref_tag (RECORD_TYPE,
3277 get_identifier (UTAG_METHOD_LIST)));
3278 field_decl
3279 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3280 field_decl
3281 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3282 chainon (field_decl_chain, field_decl);
3284 /* struct objc_protocol **protocol_list; */
3286 decl_specs = build_tree_list (NULL_TREE,
3287 xref_tag (RECORD_TYPE,
3288 get_identifier (UTAG_PROTOCOL)));
3289 field_decl
3290 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3291 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3292 field_decl
3293 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3294 chainon (field_decl_chain, field_decl);
3296 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3299 /* struct objc_selector {
3300 void *sel_id;
3301 char *sel_type;
3302 }; */
3304 static void
3305 build_selector_template ()
3308 tree decl_specs, field_decl, field_decl_chain;
3310 objc_selector_template
3311 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3313 /* void *sel_id; */
3315 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3316 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3317 field_decl
3318 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3319 field_decl_chain = field_decl;
3321 /* char *sel_type; */
3323 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3324 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3325 field_decl
3326 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3327 chainon (field_decl_chain, field_decl);
3329 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3332 /* struct objc_class {
3333 struct objc_class *isa;
3334 struct objc_class *super_class;
3335 char *name;
3336 long version;
3337 long info;
3338 long instance_size;
3339 struct objc_ivar_list *ivars;
3340 struct objc_method_list *methods;
3341 if (flag_next_runtime)
3342 struct objc_cache *cache;
3343 else {
3344 struct sarray *dtable;
3345 struct objc_class *subclass_list;
3346 struct objc_class *sibling_class;
3348 struct objc_protocol_list *protocols;
3349 void *gc_object_type;
3350 }; */
3352 static void
3353 build_class_template ()
3355 tree decl_specs, field_decl, field_decl_chain;
3357 objc_class_template
3358 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3360 /* struct objc_class *isa; */
3362 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3363 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3364 field_decl
3365 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3366 field_decl_chain = field_decl;
3368 /* struct objc_class *super_class; */
3370 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3371 field_decl
3372 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3373 field_decl
3374 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3375 chainon (field_decl_chain, field_decl);
3377 /* char *name; */
3379 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3380 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3381 field_decl
3382 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3383 chainon (field_decl_chain, field_decl);
3385 /* long version; */
3387 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3388 field_decl = get_identifier ("version");
3389 field_decl
3390 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3391 chainon (field_decl_chain, field_decl);
3393 /* long info; */
3395 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3396 field_decl = get_identifier ("info");
3397 field_decl
3398 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3399 chainon (field_decl_chain, field_decl);
3401 /* long instance_size; */
3403 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3404 field_decl = get_identifier ("instance_size");
3405 field_decl
3406 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3407 chainon (field_decl_chain, field_decl);
3409 /* struct objc_ivar_list *ivars; */
3411 decl_specs = build_tree_list (NULL_TREE,
3412 xref_tag (RECORD_TYPE,
3413 get_identifier (UTAG_IVAR_LIST)));
3414 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3415 field_decl
3416 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3417 chainon (field_decl_chain, field_decl);
3419 /* struct objc_method_list *methods; */
3421 decl_specs = build_tree_list (NULL_TREE,
3422 xref_tag (RECORD_TYPE,
3423 get_identifier (UTAG_METHOD_LIST)));
3424 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3425 field_decl
3426 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3427 chainon (field_decl_chain, field_decl);
3429 if (flag_next_runtime)
3431 /* struct objc_cache *cache; */
3433 decl_specs = build_tree_list (NULL_TREE,
3434 xref_tag (RECORD_TYPE,
3435 get_identifier ("objc_cache")));
3436 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3437 field_decl = grokfield (input_filename, lineno, field_decl,
3438 decl_specs, NULL_TREE);
3439 chainon (field_decl_chain, field_decl);
3441 else
3443 /* struct sarray *dtable; */
3445 decl_specs = build_tree_list (NULL_TREE,
3446 xref_tag (RECORD_TYPE,
3447 get_identifier ("sarray")));
3448 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3449 field_decl = grokfield (input_filename, lineno, field_decl,
3450 decl_specs, NULL_TREE);
3451 chainon (field_decl_chain, field_decl);
3453 /* struct objc_class *subclass_list; */
3455 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3456 field_decl
3457 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3458 field_decl = grokfield (input_filename, lineno, field_decl,
3459 decl_specs, NULL_TREE);
3460 chainon (field_decl_chain, field_decl);
3462 /* struct objc_class *sibling_class; */
3464 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3465 field_decl
3466 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3467 field_decl = grokfield (input_filename, lineno, field_decl,
3468 decl_specs, NULL_TREE);
3469 chainon (field_decl_chain, field_decl);
3472 /* struct objc_protocol **protocol_list; */
3474 decl_specs = build_tree_list (NULL_TREE,
3475 xref_tag (RECORD_TYPE,
3476 get_identifier (UTAG_PROTOCOL)));
3477 field_decl
3478 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3479 field_decl
3480 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3481 field_decl = grokfield (input_filename, lineno, field_decl,
3482 decl_specs, NULL_TREE);
3483 chainon (field_decl_chain, field_decl);
3485 /* void *sel_id; */
3487 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3488 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3489 field_decl
3490 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3491 chainon (field_decl_chain, field_decl);
3493 /* void *gc_object_type; */
3495 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3496 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3497 field_decl
3498 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3499 chainon (field_decl_chain, field_decl);
3501 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3504 /* Generate appropriate forward declarations for an implementation. */
3506 static void
3507 synth_forward_declarations ()
3509 tree sc_spec, decl_specs, an_id;
3511 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3513 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3515 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3516 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3517 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3518 TREE_USED (UOBJC_CLASS_decl) = 1;
3519 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3521 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3523 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3524 objc_implementation_context);
3526 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3527 TREE_USED (UOBJC_METACLASS_decl) = 1;
3528 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3530 /* Pre-build the following entities - for speed/convenience. */
3532 an_id = get_identifier ("super_class");
3533 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3534 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3537 static void
3538 error_with_ivar (message, decl, rawdecl)
3539 const char *message;
3540 tree decl;
3541 tree rawdecl;
3543 diagnostic_count_diagnostic (global_dc, DK_ERROR);
3545 diagnostic_report_current_function (global_dc);
3547 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3548 DECL_SOURCE_LINE (decl),
3549 "%s `%s'",
3550 message, gen_declaration (rawdecl, errbuf));
3554 static void
3555 check_ivars (inter, imp)
3556 tree inter;
3557 tree imp;
3559 tree intdecls = CLASS_IVARS (inter);
3560 tree impdecls = CLASS_IVARS (imp);
3561 tree rawintdecls = CLASS_RAW_IVARS (inter);
3562 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3564 while (1)
3566 tree t1, t2;
3568 if (intdecls == 0 && impdecls == 0)
3569 break;
3570 if (intdecls == 0 || impdecls == 0)
3572 error ("inconsistent instance variable specification");
3573 break;
3576 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3578 if (!comptypes (t1, t2))
3580 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3582 error_with_ivar ("conflicting instance variable type",
3583 impdecls, rawimpdecls);
3584 error_with_ivar ("previous declaration of",
3585 intdecls, rawintdecls);
3587 else /* both the type and the name don't match */
3589 error ("inconsistent instance variable specification");
3590 break;
3594 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3596 error_with_ivar ("conflicting instance variable name",
3597 impdecls, rawimpdecls);
3598 error_with_ivar ("previous declaration of",
3599 intdecls, rawintdecls);
3602 intdecls = TREE_CHAIN (intdecls);
3603 impdecls = TREE_CHAIN (impdecls);
3604 rawintdecls = TREE_CHAIN (rawintdecls);
3605 rawimpdecls = TREE_CHAIN (rawimpdecls);
3609 /* Set super_type to the data type node for struct objc_super *,
3610 first defining struct objc_super itself.
3611 This needs to be done just once per compilation. */
3613 static tree
3614 build_super_template ()
3616 tree record, decl_specs, field_decl, field_decl_chain;
3618 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3620 /* struct objc_object *self; */
3622 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3623 field_decl = get_identifier ("self");
3624 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3625 field_decl = grokfield (input_filename, lineno,
3626 field_decl, decl_specs, NULL_TREE);
3627 field_decl_chain = field_decl;
3629 /* struct objc_class *class; */
3631 decl_specs = get_identifier (UTAG_CLASS);
3632 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3633 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3635 field_decl = grokfield (input_filename, lineno,
3636 field_decl, decl_specs, NULL_TREE);
3637 chainon (field_decl_chain, field_decl);
3639 finish_struct (record, field_decl_chain, NULL_TREE);
3641 /* `struct objc_super *' */
3642 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3643 record),
3644 build1 (INDIRECT_REF,
3645 NULL_TREE, NULL_TREE)));
3646 return record;
3649 /* struct objc_ivar {
3650 char *ivar_name;
3651 char *ivar_type;
3652 int ivar_offset;
3653 }; */
3655 static tree
3656 build_ivar_template ()
3658 tree objc_ivar_id, objc_ivar_record;
3659 tree decl_specs, field_decl, field_decl_chain;
3661 objc_ivar_id = get_identifier (UTAG_IVAR);
3662 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3664 /* char *ivar_name; */
3666 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3667 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3669 field_decl = grokfield (input_filename, lineno, field_decl,
3670 decl_specs, NULL_TREE);
3671 field_decl_chain = field_decl;
3673 /* char *ivar_type; */
3675 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3676 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3678 field_decl = grokfield (input_filename, lineno, field_decl,
3679 decl_specs, NULL_TREE);
3680 chainon (field_decl_chain, field_decl);
3682 /* int ivar_offset; */
3684 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3685 field_decl = get_identifier ("ivar_offset");
3687 field_decl = grokfield (input_filename, lineno, field_decl,
3688 decl_specs, NULL_TREE);
3689 chainon (field_decl_chain, field_decl);
3691 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3693 return objc_ivar_record;
3696 /* struct {
3697 int ivar_count;
3698 struct objc_ivar ivar_list[ivar_count];
3699 }; */
3701 static tree
3702 build_ivar_list_template (list_type, size)
3703 tree list_type;
3704 int size;
3706 tree objc_ivar_list_record;
3707 tree decl_specs, field_decl, field_decl_chain;
3709 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3711 /* int ivar_count; */
3713 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3714 field_decl = get_identifier ("ivar_count");
3716 field_decl = grokfield (input_filename, lineno, field_decl,
3717 decl_specs, NULL_TREE);
3718 field_decl_chain = field_decl;
3720 /* struct objc_ivar ivar_list[]; */
3722 decl_specs = build_tree_list (NULL_TREE, list_type);
3723 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3724 build_int_2 (size, 0));
3726 field_decl = grokfield (input_filename, lineno,
3727 field_decl, decl_specs, NULL_TREE);
3728 chainon (field_decl_chain, field_decl);
3730 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3732 return objc_ivar_list_record;
3735 /* struct {
3736 int method_next;
3737 int method_count;
3738 struct objc_method method_list[method_count];
3739 }; */
3741 static tree
3742 build_method_list_template (list_type, size)
3743 tree list_type;
3744 int size;
3746 tree objc_ivar_list_record;
3747 tree decl_specs, field_decl, field_decl_chain;
3749 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3751 /* int method_next; */
3753 decl_specs
3754 = build_tree_list
3755 (NULL_TREE,
3756 xref_tag (RECORD_TYPE,
3757 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3758 field_decl
3759 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3760 field_decl = grokfield (input_filename, lineno, field_decl,
3761 decl_specs, NULL_TREE);
3762 field_decl_chain = field_decl;
3764 /* int method_count; */
3766 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3767 field_decl = get_identifier ("method_count");
3769 field_decl = grokfield (input_filename, lineno,
3770 field_decl, decl_specs, NULL_TREE);
3771 chainon (field_decl_chain, field_decl);
3773 /* struct objc_method method_list[]; */
3775 decl_specs = build_tree_list (NULL_TREE, list_type);
3776 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3777 build_int_2 (size, 0));
3779 field_decl = grokfield (input_filename, lineno,
3780 field_decl, decl_specs, NULL_TREE);
3781 chainon (field_decl_chain, field_decl);
3783 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3785 return objc_ivar_list_record;
3788 static tree
3789 build_ivar_list_initializer (type, field_decl)
3790 tree type;
3791 tree field_decl;
3793 tree initlist = NULL_TREE;
3797 tree ivar = NULL_TREE;
3799 /* Set name. */
3800 if (DECL_NAME (field_decl))
3801 ivar = tree_cons (NULL_TREE,
3802 add_objc_string (DECL_NAME (field_decl),
3803 meth_var_names),
3804 ivar);
3805 else
3806 /* Unnamed bit-field ivar (yuck). */
3807 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3809 /* Set type. */
3810 encode_field_decl (field_decl,
3811 obstack_object_size (&util_obstack),
3812 OBJC_ENCODE_DONT_INLINE_DEFS);
3814 /* Null terminate string. */
3815 obstack_1grow (&util_obstack, 0);
3816 ivar
3817 = tree_cons
3818 (NULL_TREE,
3819 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3820 meth_var_types),
3821 ivar);
3822 obstack_free (&util_obstack, util_firstobj);
3824 /* Set offset. */
3825 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3826 initlist = tree_cons (NULL_TREE,
3827 build_constructor (type, nreverse (ivar)),
3828 initlist);
3830 field_decl = TREE_CHAIN (field_decl);
3832 while (field_decl);
3834 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3837 static tree
3838 generate_ivars_list (type, name, size, list)
3839 tree type;
3840 const char *name;
3841 int size;
3842 tree list;
3844 tree sc_spec, decl_specs, decl, initlist;
3846 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3847 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3849 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3850 decl_specs, 1, NULL_TREE);
3852 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3853 initlist = tree_cons (NULL_TREE, list, initlist);
3855 finish_decl (decl,
3856 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3857 NULL_TREE);
3859 return decl;
3862 static void
3863 generate_ivar_lists ()
3865 tree initlist, ivar_list_template, chain;
3866 tree cast, variable_length_type;
3867 int size;
3869 generating_instance_variables = 1;
3871 if (!objc_ivar_template)
3872 objc_ivar_template = build_ivar_template ();
3874 cast
3875 = build_tree_list
3876 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3877 get_identifier (UTAG_IVAR_LIST))),
3878 NULL_TREE);
3879 variable_length_type = groktypename (cast);
3881 /* Only generate class variables for the root of the inheritance
3882 hierarchy since these will be the same for every class. */
3884 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3885 && (chain = TYPE_FIELDS (objc_class_template)))
3887 size = list_length (chain);
3889 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3890 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3892 UOBJC_CLASS_VARIABLES_decl
3893 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3894 size, initlist);
3895 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3897 else
3898 UOBJC_CLASS_VARIABLES_decl = 0;
3900 chain = CLASS_IVARS (implementation_template);
3901 if (chain)
3903 size = list_length (chain);
3904 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3905 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3907 UOBJC_INSTANCE_VARIABLES_decl
3908 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3909 size, initlist);
3910 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3912 else
3913 UOBJC_INSTANCE_VARIABLES_decl = 0;
3915 generating_instance_variables = 0;
3918 static tree
3919 build_dispatch_table_initializer (type, entries)
3920 tree type;
3921 tree entries;
3923 tree initlist = NULL_TREE;
3927 tree elemlist = NULL_TREE;
3929 elemlist = tree_cons (NULL_TREE,
3930 build_selector (METHOD_SEL_NAME (entries)),
3931 NULL_TREE);
3933 /* Generate the method encoding if we don't have one already. */
3934 if (! METHOD_ENCODING (entries))
3935 METHOD_ENCODING (entries) =
3936 encode_method_def (METHOD_DEFINITION (entries));
3938 elemlist = tree_cons (NULL_TREE,
3939 add_objc_string (METHOD_ENCODING (entries),
3940 meth_var_types),
3941 elemlist);
3943 elemlist = tree_cons (NULL_TREE,
3944 build_unary_op (ADDR_EXPR,
3945 METHOD_DEFINITION (entries), 1),
3946 elemlist);
3948 initlist = tree_cons (NULL_TREE,
3949 build_constructor (type, nreverse (elemlist)),
3950 initlist);
3952 entries = TREE_CHAIN (entries);
3954 while (entries);
3956 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3959 /* To accomplish method prototyping without generating all kinds of
3960 inane warnings, the definition of the dispatch table entries were
3961 changed from:
3963 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3965 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3967 static tree
3968 build_method_template ()
3970 tree _SLT_record;
3971 tree decl_specs, field_decl, field_decl_chain;
3973 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3975 /* struct objc_selector *_cmd; */
3976 decl_specs = tree_cons (NULL_TREE,
3977 xref_tag (RECORD_TYPE,
3978 get_identifier (TAG_SELECTOR)),
3979 NULL_TREE);
3980 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3982 field_decl = grokfield (input_filename, lineno, field_decl,
3983 decl_specs, NULL_TREE);
3984 field_decl_chain = field_decl;
3986 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3987 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3988 get_identifier ("method_types"));
3989 field_decl = grokfield (input_filename, lineno, field_decl,
3990 decl_specs, NULL_TREE);
3991 chainon (field_decl_chain, field_decl);
3993 /* void *_imp; */
3995 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3996 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3997 field_decl = grokfield (input_filename, lineno, field_decl,
3998 decl_specs, NULL_TREE);
3999 chainon (field_decl_chain, field_decl);
4001 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4003 return _SLT_record;
4007 static tree
4008 generate_dispatch_table (type, name, size, list)
4009 tree type;
4010 const char *name;
4011 int size;
4012 tree list;
4014 tree sc_spec, decl_specs, decl, initlist;
4016 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4017 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4019 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4020 decl_specs, 1, NULL_TREE);
4022 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4023 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4024 initlist = tree_cons (NULL_TREE, list, initlist);
4026 finish_decl (decl,
4027 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4028 NULL_TREE);
4030 return decl;
4033 static void
4034 mark_referenced_methods ()
4036 struct imp_entry *impent;
4037 tree chain;
4039 for (impent = imp_list; impent; impent = impent->next)
4041 chain = CLASS_CLS_METHODS (impent->imp_context);
4042 while (chain)
4044 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)), 1);
4045 chain = TREE_CHAIN (chain);
4047 chain = CLASS_NST_METHODS (impent->imp_context);
4048 while (chain)
4050 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)), 1);
4051 chain = TREE_CHAIN (chain);
4056 static void
4057 generate_dispatch_tables ()
4059 tree initlist, chain, method_list_template;
4060 tree cast, variable_length_type;
4061 int size;
4063 if (!objc_method_template)
4064 objc_method_template = build_method_template ();
4066 cast
4067 = build_tree_list
4068 (build_tree_list (NULL_TREE,
4069 xref_tag (RECORD_TYPE,
4070 get_identifier (UTAG_METHOD_LIST))),
4071 NULL_TREE);
4073 variable_length_type = groktypename (cast);
4075 chain = CLASS_CLS_METHODS (objc_implementation_context);
4076 if (chain)
4078 size = list_length (chain);
4080 method_list_template
4081 = build_method_list_template (objc_method_template, size);
4082 initlist
4083 = build_dispatch_table_initializer (objc_method_template, chain);
4085 UOBJC_CLASS_METHODS_decl
4086 = generate_dispatch_table (method_list_template,
4087 ((TREE_CODE (objc_implementation_context)
4088 == CLASS_IMPLEMENTATION_TYPE)
4089 ? "_OBJC_CLASS_METHODS"
4090 : "_OBJC_CATEGORY_CLASS_METHODS"),
4091 size, initlist);
4092 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4094 else
4095 UOBJC_CLASS_METHODS_decl = 0;
4097 chain = CLASS_NST_METHODS (objc_implementation_context);
4098 if (chain)
4100 size = list_length (chain);
4102 method_list_template
4103 = build_method_list_template (objc_method_template, size);
4104 initlist
4105 = build_dispatch_table_initializer (objc_method_template, chain);
4107 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4108 UOBJC_INSTANCE_METHODS_decl
4109 = generate_dispatch_table (method_list_template,
4110 "_OBJC_INSTANCE_METHODS",
4111 size, initlist);
4112 else
4113 /* We have a category. */
4114 UOBJC_INSTANCE_METHODS_decl
4115 = generate_dispatch_table (method_list_template,
4116 "_OBJC_CATEGORY_INSTANCE_METHODS",
4117 size, initlist);
4118 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4120 else
4121 UOBJC_INSTANCE_METHODS_decl = 0;
4124 static tree
4125 generate_protocol_list (i_or_p)
4126 tree i_or_p;
4128 tree initlist, decl_specs, sc_spec;
4129 tree refs_decl, expr_decl, lproto, e, plist;
4130 tree cast_type;
4131 int size = 0;
4133 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4134 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4135 plist = CLASS_PROTOCOL_LIST (i_or_p);
4136 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4137 plist = PROTOCOL_LIST (i_or_p);
4138 else
4139 abort ();
4141 cast_type = groktypename
4142 (build_tree_list
4143 (build_tree_list (NULL_TREE,
4144 xref_tag (RECORD_TYPE,
4145 get_identifier (UTAG_PROTOCOL))),
4146 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4148 /* Compute size. */
4149 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4150 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4151 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4152 size++;
4154 /* Build initializer. */
4155 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4157 e = build_int_2 (size, 0);
4158 TREE_TYPE (e) = cast_type;
4159 initlist = tree_cons (NULL_TREE, e, initlist);
4161 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4163 tree pval = TREE_VALUE (lproto);
4165 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4166 && PROTOCOL_FORWARD_DECL (pval))
4168 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4169 initlist = tree_cons (NULL_TREE, e, initlist);
4173 /* static struct objc_protocol *refs[n]; */
4175 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4176 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4177 get_identifier (UTAG_PROTOCOL)),
4178 sc_spec);
4180 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4181 expr_decl = build_nt (ARRAY_REF,
4182 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4183 i_or_p),
4184 build_int_2 (size + 2, 0));
4185 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4186 expr_decl = build_nt (ARRAY_REF,
4187 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4188 i_or_p),
4189 build_int_2 (size + 2, 0));
4190 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4191 expr_decl
4192 = build_nt (ARRAY_REF,
4193 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4194 i_or_p),
4195 build_int_2 (size + 2, 0));
4196 else
4197 abort ();
4199 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4201 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4202 DECL_CONTEXT (refs_decl) = NULL_TREE;
4204 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4205 nreverse (initlist)),
4206 NULL_TREE);
4208 return refs_decl;
4211 static tree
4212 build_category_initializer (type, cat_name, class_name,
4213 instance_methods, class_methods, protocol_list)
4214 tree type;
4215 tree cat_name;
4216 tree class_name;
4217 tree instance_methods;
4218 tree class_methods;
4219 tree protocol_list;
4221 tree initlist = NULL_TREE, expr;
4223 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4224 initlist = tree_cons (NULL_TREE, class_name, initlist);
4226 if (!instance_methods)
4227 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4228 else
4230 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4231 initlist = tree_cons (NULL_TREE, expr, initlist);
4233 if (!class_methods)
4234 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4235 else
4237 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4238 initlist = tree_cons (NULL_TREE, expr, initlist);
4241 /* protocol_list = */
4242 if (!protocol_list)
4243 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4244 else
4246 tree cast_type2 = groktypename
4247 (build_tree_list
4248 (build_tree_list (NULL_TREE,
4249 xref_tag (RECORD_TYPE,
4250 get_identifier (UTAG_PROTOCOL))),
4251 build1 (INDIRECT_REF, NULL_TREE,
4252 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4254 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4255 TREE_TYPE (expr) = cast_type2;
4256 initlist = tree_cons (NULL_TREE, expr, initlist);
4259 return build_constructor (type, nreverse (initlist));
4262 /* struct objc_class {
4263 struct objc_class *isa;
4264 struct objc_class *super_class;
4265 char *name;
4266 long version;
4267 long info;
4268 long instance_size;
4269 struct objc_ivar_list *ivars;
4270 struct objc_method_list *methods;
4271 if (flag_next_runtime)
4272 struct objc_cache *cache;
4273 else {
4274 struct sarray *dtable;
4275 struct objc_class *subclass_list;
4276 struct objc_class *sibling_class;
4278 struct objc_protocol_list *protocols;
4279 void *gc_object_type;
4280 }; */
4282 static tree
4283 build_shared_structure_initializer (type, isa, super, name, size, status,
4284 dispatch_table, ivar_list, protocol_list)
4285 tree type;
4286 tree isa;
4287 tree super;
4288 tree name;
4289 tree size;
4290 int status;
4291 tree dispatch_table;
4292 tree ivar_list;
4293 tree protocol_list;
4295 tree initlist = NULL_TREE, expr;
4297 /* isa = */
4298 initlist = tree_cons (NULL_TREE, isa, initlist);
4300 /* super_class = */
4301 initlist = tree_cons (NULL_TREE, super, initlist);
4303 /* name = */
4304 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4306 /* version = */
4307 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4309 /* info = */
4310 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4312 /* instance_size = */
4313 initlist = tree_cons (NULL_TREE, size, initlist);
4315 /* objc_ivar_list = */
4316 if (!ivar_list)
4317 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4318 else
4320 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4321 initlist = tree_cons (NULL_TREE, expr, initlist);
4324 /* objc_method_list = */
4325 if (!dispatch_table)
4326 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4327 else
4329 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4330 initlist = tree_cons (NULL_TREE, expr, initlist);
4333 if (flag_next_runtime)
4334 /* method_cache = */
4335 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4336 else
4338 /* dtable = */
4339 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4341 /* subclass_list = */
4342 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4344 /* sibling_class = */
4345 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4348 /* protocol_list = */
4349 if (! protocol_list)
4350 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4351 else
4353 tree cast_type2
4354 = groktypename
4355 (build_tree_list
4356 (build_tree_list (NULL_TREE,
4357 xref_tag (RECORD_TYPE,
4358 get_identifier (UTAG_PROTOCOL))),
4359 build1 (INDIRECT_REF, NULL_TREE,
4360 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4362 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4363 TREE_TYPE (expr) = cast_type2;
4364 initlist = tree_cons (NULL_TREE, expr, initlist);
4367 /* gc_object_type = NULL */
4368 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4370 return build_constructor (type, nreverse (initlist));
4373 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4375 static void
4376 generate_category (cat)
4377 tree cat;
4379 tree sc_spec, decl_specs, decl;
4380 tree initlist, cat_name_expr, class_name_expr;
4381 tree protocol_decl, category;
4383 add_class_reference (CLASS_NAME (cat));
4384 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4386 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4388 category = CLASS_CATEGORY_LIST (implementation_template);
4390 /* find the category interface from the class it is associated with */
4391 while (category)
4393 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4394 break;
4395 category = CLASS_CATEGORY_LIST (category);
4398 if (category && CLASS_PROTOCOL_LIST (category))
4400 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4401 protocol_decl = generate_protocol_list (category);
4403 else
4404 protocol_decl = 0;
4406 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4407 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4409 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4410 objc_implementation_context),
4411 decl_specs, 1, NULL_TREE);
4413 initlist = build_category_initializer (TREE_TYPE (decl),
4414 cat_name_expr, class_name_expr,
4415 UOBJC_INSTANCE_METHODS_decl,
4416 UOBJC_CLASS_METHODS_decl,
4417 protocol_decl);
4419 TREE_USED (decl) = 1;
4420 finish_decl (decl, initlist, NULL_TREE);
4423 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4424 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4426 static void
4427 generate_shared_structures ()
4429 tree sc_spec, decl_specs, decl;
4430 tree name_expr, super_expr, root_expr;
4431 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4432 tree cast_type, initlist, protocol_decl;
4434 my_super_id = CLASS_SUPER_NAME (implementation_template);
4435 if (my_super_id)
4437 add_class_reference (my_super_id);
4439 /* Compute "my_root_id" - this is required for code generation.
4440 the "isa" for all meta class structures points to the root of
4441 the inheritance hierarchy (e.g. "__Object")... */
4442 my_root_id = my_super_id;
4445 tree my_root_int = lookup_interface (my_root_id);
4447 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4448 my_root_id = CLASS_SUPER_NAME (my_root_int);
4449 else
4450 break;
4452 while (1);
4454 else
4455 /* No super class. */
4456 my_root_id = CLASS_NAME (implementation_template);
4458 cast_type
4459 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4460 objc_class_template),
4461 build1 (INDIRECT_REF,
4462 NULL_TREE, NULL_TREE)));
4464 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4465 class_names);
4467 /* Install class `isa' and `super' pointers at runtime. */
4468 if (my_super_id)
4470 super_expr = add_objc_string (my_super_id, class_names);
4471 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4473 else
4474 super_expr = build_int_2 (0, 0);
4476 root_expr = add_objc_string (my_root_id, class_names);
4477 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4479 if (CLASS_PROTOCOL_LIST (implementation_template))
4481 generate_protocol_references
4482 (CLASS_PROTOCOL_LIST (implementation_template));
4483 protocol_decl = generate_protocol_list (implementation_template);
4485 else
4486 protocol_decl = 0;
4488 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4490 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4491 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4493 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4494 NULL_TREE);
4496 initlist
4497 = build_shared_structure_initializer
4498 (TREE_TYPE (decl),
4499 root_expr, super_expr, name_expr,
4500 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4501 2 /*CLS_META*/,
4502 UOBJC_CLASS_METHODS_decl,
4503 UOBJC_CLASS_VARIABLES_decl,
4504 protocol_decl);
4506 finish_decl (decl, initlist, NULL_TREE);
4508 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4510 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4511 NULL_TREE);
4513 initlist
4514 = build_shared_structure_initializer
4515 (TREE_TYPE (decl),
4516 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4517 super_expr, name_expr,
4518 convert (integer_type_node,
4519 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4520 (implementation_template))),
4521 1 /*CLS_FACTORY*/,
4522 UOBJC_INSTANCE_METHODS_decl,
4523 UOBJC_INSTANCE_VARIABLES_decl,
4524 protocol_decl);
4526 finish_decl (decl, initlist, NULL_TREE);
4529 static tree
4530 synth_id_with_class_suffix (preamble, ctxt)
4531 const char *preamble;
4532 tree ctxt;
4534 char *string;
4535 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4536 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4538 const char *const class_name
4539 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4540 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4541 sprintf (string, "%s_%s", preamble,
4542 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4544 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4545 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4547 /* We have a category. */
4548 const char *const class_name
4549 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4550 const char *const class_super_name
4551 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4552 string = (char *) alloca (strlen (preamble)
4553 + strlen (class_name)
4554 + strlen (class_super_name)
4555 + 3);
4556 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4558 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4560 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4561 string
4562 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4563 sprintf (string, "%s_%s", preamble, protocol_name);
4565 else
4566 abort ();
4568 return get_identifier (string);
4571 static int
4572 is_objc_type_qualifier (node)
4573 tree node;
4575 return (TREE_CODE (node) == IDENTIFIER_NODE
4576 && (node == ridpointers [(int) RID_CONST]
4577 || node == ridpointers [(int) RID_VOLATILE]
4578 || node == ridpointers [(int) RID_IN]
4579 || node == ridpointers [(int) RID_OUT]
4580 || node == ridpointers [(int) RID_INOUT]
4581 || node == ridpointers [(int) RID_BYCOPY]
4582 || node == ridpointers [(int) RID_BYREF]
4583 || node == ridpointers [(int) RID_ONEWAY]));
4586 /* If type is empty or only type qualifiers are present, add default
4587 type of id (otherwise grokdeclarator will default to int). */
4589 static tree
4590 adjust_type_for_id_default (type)
4591 tree type;
4593 tree declspecs, chain;
4595 if (!type)
4596 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4597 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4599 declspecs = TREE_PURPOSE (type);
4601 /* Determine if a typespec is present. */
4602 for (chain = declspecs;
4603 chain;
4604 chain = TREE_CHAIN (chain))
4606 if (TYPED_OBJECT (TREE_VALUE (chain))
4607 && !(TREE_VALUE (type)
4608 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4609 error ("can not use an object as parameter to a method\n");
4610 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4611 return type;
4614 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4615 declspecs),
4616 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4619 /* Usage:
4620 keyworddecl:
4621 selector ':' '(' typename ')' identifier
4623 Purpose:
4624 Transform an Objective-C keyword argument into
4625 the C equivalent parameter declarator.
4627 In: key_name, an "identifier_node" (optional).
4628 arg_type, a "tree_list" (optional).
4629 arg_name, an "identifier_node".
4631 Note: It would be really nice to strongly type the preceding
4632 arguments in the function prototype; however, then I
4633 could not use the "accessor" macros defined in "tree.h".
4635 Out: an instance of "keyword_decl". */
4637 tree
4638 build_keyword_decl (key_name, arg_type, arg_name)
4639 tree key_name;
4640 tree arg_type;
4641 tree arg_name;
4643 tree keyword_decl;
4645 /* If no type is specified, default to "id". */
4646 arg_type = adjust_type_for_id_default (arg_type);
4648 keyword_decl = make_node (KEYWORD_DECL);
4650 TREE_TYPE (keyword_decl) = arg_type;
4651 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4652 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4654 return keyword_decl;
4657 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4659 static tree
4660 build_keyword_selector (selector)
4661 tree selector;
4663 int len = 0;
4664 tree key_chain, key_name;
4665 char *buf;
4667 /* Scan the selector to see how much space we'll need. */
4668 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4670 if (TREE_CODE (selector) == KEYWORD_DECL)
4671 key_name = KEYWORD_KEY_NAME (key_chain);
4672 else if (TREE_CODE (selector) == TREE_LIST)
4673 key_name = TREE_PURPOSE (key_chain);
4674 else
4675 abort ();
4677 if (key_name)
4678 len += IDENTIFIER_LENGTH (key_name) + 1;
4679 else
4680 /* Just a ':' arg. */
4681 len++;
4684 buf = (char *) alloca (len + 1);
4685 /* Start the buffer out as an empty string. */
4686 buf[0] = '\0';
4688 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4690 if (TREE_CODE (selector) == KEYWORD_DECL)
4691 key_name = KEYWORD_KEY_NAME (key_chain);
4692 else if (TREE_CODE (selector) == TREE_LIST)
4693 key_name = TREE_PURPOSE (key_chain);
4694 else
4695 abort ();
4697 if (key_name)
4698 strcat (buf, IDENTIFIER_POINTER (key_name));
4699 strcat (buf, ":");
4702 return get_identifier (buf);
4705 /* Used for declarations and definitions. */
4707 tree
4708 build_method_decl (code, ret_type, selector, add_args)
4709 enum tree_code code;
4710 tree ret_type;
4711 tree selector;
4712 tree add_args;
4714 tree method_decl;
4716 /* If no type is specified, default to "id". */
4717 ret_type = adjust_type_for_id_default (ret_type);
4719 method_decl = make_node (code);
4720 TREE_TYPE (method_decl) = ret_type;
4722 /* If we have a keyword selector, create an identifier_node that
4723 represents the full selector name (`:' included)... */
4724 if (TREE_CODE (selector) == KEYWORD_DECL)
4726 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4727 METHOD_SEL_ARGS (method_decl) = selector;
4728 METHOD_ADD_ARGS (method_decl) = add_args;
4730 else
4732 METHOD_SEL_NAME (method_decl) = selector;
4733 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4734 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4737 return method_decl;
4740 #define METHOD_DEF 0
4741 #define METHOD_REF 1
4743 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4744 an argument list for method METH. CONTEXT is either METHOD_DEF or
4745 METHOD_REF, saying whether we are trying to define a method or call
4746 one. SUPERFLAG says this is for a send to super; this makes a
4747 difference for the NeXT calling sequence in which the lookup and
4748 the method call are done together. */
4750 static tree
4751 get_arg_type_list (meth, context, superflag)
4752 tree meth;
4753 int context;
4754 int superflag;
4756 tree arglist, akey;
4758 /* Receiver type. */
4759 if (flag_next_runtime && superflag)
4760 arglist = build_tree_list (NULL_TREE, super_type);
4761 else if (context == METHOD_DEF)
4762 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4763 else
4764 arglist = build_tree_list (NULL_TREE, id_type);
4766 /* Selector type - will eventually change to `int'. */
4767 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4769 /* Build a list of argument types. */
4770 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4772 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4773 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4776 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4777 /* We have a `, ...' immediately following the selector,
4778 finalize the arglist...simulate get_parm_info (0). */
4780 else if (METHOD_ADD_ARGS (meth))
4782 /* we have a variable length selector */
4783 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4784 chainon (arglist, add_arg_list);
4786 else
4787 /* finalize the arglist...simulate get_parm_info (1) */
4788 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4790 return arglist;
4793 static tree
4794 check_duplicates (hsh)
4795 hash hsh;
4797 tree meth = NULL_TREE;
4799 if (hsh)
4801 meth = hsh->key;
4803 if (hsh->list)
4805 /* We have two methods with the same name and different types. */
4806 attr loop;
4807 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4809 warning ("multiple declarations for method `%s'",
4810 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4812 warn_with_method ("using", type, meth);
4813 for (loop = hsh->list; loop; loop = loop->next)
4814 warn_with_method ("also found", type, loop->value);
4817 return meth;
4820 /* If RECEIVER is a class reference, return the identifier node for
4821 the referenced class. RECEIVER is created by get_class_reference,
4822 so we check the exact form created depending on which runtimes are
4823 used. */
4825 static tree
4826 receiver_is_class_object (receiver)
4827 tree receiver;
4829 tree chain, exp, arg;
4831 /* The receiver is 'self' in the context of a class method. */
4832 if (objc_method_context
4833 && receiver == self_decl
4834 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4836 return CLASS_NAME (objc_implementation_context);
4839 if (flag_next_runtime)
4841 /* The receiver is a variable created by
4842 build_class_reference_decl. */
4843 if (TREE_CODE (receiver) == VAR_DECL
4844 && TREE_TYPE (receiver) == objc_class_type)
4845 /* Look up the identifier. */
4846 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4847 if (TREE_PURPOSE (chain) == receiver)
4848 return TREE_VALUE (chain);
4850 else
4852 /* The receiver is a function call that returns an id. Check if
4853 it is a call to objc_getClass, if so, pick up the class name. */
4854 if (TREE_CODE (receiver) == CALL_EXPR
4855 && (exp = TREE_OPERAND (receiver, 0))
4856 && TREE_CODE (exp) == ADDR_EXPR
4857 && (exp = TREE_OPERAND (exp, 0))
4858 && TREE_CODE (exp) == FUNCTION_DECL
4859 && exp == objc_get_class_decl
4860 /* We have a call to objc_getClass! */
4861 && (arg = TREE_OPERAND (receiver, 1))
4862 && TREE_CODE (arg) == TREE_LIST
4863 && (arg = TREE_VALUE (arg)))
4865 STRIP_NOPS (arg);
4866 if (TREE_CODE (arg) == ADDR_EXPR
4867 && (arg = TREE_OPERAND (arg, 0))
4868 && TREE_CODE (arg) == STRING_CST)
4869 /* Finally, we have the class name. */
4870 return get_identifier (TREE_STRING_POINTER (arg));
4873 return 0;
4876 /* If we are currently building a message expr, this holds
4877 the identifier of the selector of the message. This is
4878 used when printing warnings about argument mismatches. */
4880 static tree current_objc_message_selector = 0;
4882 tree
4883 objc_message_selector ()
4885 return current_objc_message_selector;
4888 /* Construct an expression for sending a message.
4889 MESS has the object to send to in TREE_PURPOSE
4890 and the argument list (including selector) in TREE_VALUE.
4892 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4893 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4895 tree
4896 build_message_expr (mess)
4897 tree mess;
4899 tree receiver = TREE_PURPOSE (mess);
4900 tree sel_name;
4901 tree args = TREE_VALUE (mess);
4902 tree method_params = NULL_TREE;
4904 if (TREE_CODE (receiver) == ERROR_MARK)
4905 return error_mark_node;
4907 /* Obtain the full selector name. */
4908 if (TREE_CODE (args) == IDENTIFIER_NODE)
4909 /* A unary selector. */
4910 sel_name = args;
4911 else if (TREE_CODE (args) == TREE_LIST)
4912 sel_name = build_keyword_selector (args);
4913 else
4914 abort ();
4916 /* Build the parameter list to give to the method. */
4917 if (TREE_CODE (args) == TREE_LIST)
4919 tree chain = args, prev = NULL_TREE;
4921 /* We have a keyword selector--check for comma expressions. */
4922 while (chain)
4924 tree element = TREE_VALUE (chain);
4926 /* We have a comma expression, must collapse... */
4927 if (TREE_CODE (element) == TREE_LIST)
4929 if (prev)
4930 TREE_CHAIN (prev) = element;
4931 else
4932 args = element;
4934 prev = chain;
4935 chain = TREE_CHAIN (chain);
4937 method_params = args;
4940 return finish_message_expr (receiver, sel_name, method_params);
4943 /* The 'finish_message_expr' routine is called from within
4944 'build_message_expr' for non-template functions. In the case of
4945 C++ template functions, it is called from 'build_expr_from_tree'
4946 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4948 tree
4949 finish_message_expr (receiver, sel_name, method_params)
4950 tree receiver, sel_name, method_params;
4952 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4953 tree selector, self_object, retval;
4954 int statically_typed = 0, statically_allocated = 0;
4956 /* Determine receiver type. */
4957 tree rtype = TREE_TYPE (receiver);
4958 int super = IS_SUPER (rtype);
4960 if (! super)
4962 if (TREE_STATIC_TEMPLATE (rtype))
4963 statically_allocated = 1;
4964 else if (TREE_CODE (rtype) == POINTER_TYPE
4965 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4966 statically_typed = 1;
4967 else if ((flag_next_runtime
4968 || (IS_ID (rtype)))
4969 && (class_ident = receiver_is_class_object (receiver)))
4971 else if (! IS_ID (rtype)
4972 /* Allow any type that matches objc_class_type. */
4973 && ! comptypes (rtype, objc_class_type))
4975 warning ("invalid receiver type `%s'",
4976 gen_declaration (rtype, errbuf));
4978 if (statically_allocated)
4979 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4981 /* Don't evaluate the receiver twice. */
4982 receiver = save_expr (receiver);
4983 self_object = receiver;
4985 else
4986 /* If sending to `super', use current self as the object. */
4987 self_object = self_decl;
4989 /* Determine operation return type. */
4991 if (super)
4993 tree iface;
4995 if (CLASS_SUPER_NAME (implementation_template))
4997 iface
4998 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5000 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
5001 method_prototype = lookup_instance_method_static (iface, sel_name);
5002 else
5003 method_prototype = lookup_class_method_static (iface, sel_name);
5005 if (iface && !method_prototype)
5006 warning ("`%s' does not respond to `%s'",
5007 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
5008 IDENTIFIER_POINTER (sel_name));
5010 else
5012 error ("no super class declared in interface for `%s'",
5013 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5014 return error_mark_node;
5018 else if (statically_allocated)
5020 tree ctype = TREE_TYPE (rtype);
5021 tree iface = lookup_interface (TYPE_NAME (rtype));
5023 if (iface)
5024 method_prototype = lookup_instance_method_static (iface, sel_name);
5026 if (! method_prototype && ctype && TYPE_PROTOCOL_LIST (ctype))
5027 method_prototype
5028 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5029 sel_name, 0);
5031 if (!method_prototype)
5032 warning ("`%s' does not respond to `%s'",
5033 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
5034 IDENTIFIER_POINTER (sel_name));
5036 else if (statically_typed)
5038 tree ctype = TREE_TYPE (rtype);
5040 /* `self' is now statically_typed. All methods should be visible
5041 within the context of the implementation. */
5042 if (objc_implementation_context
5043 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
5045 method_prototype
5046 = lookup_instance_method_static (implementation_template,
5047 sel_name);
5049 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5050 method_prototype
5051 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5052 sel_name, 0);
5054 if (! method_prototype
5055 && implementation_template != objc_implementation_context)
5056 /* The method is not published in the interface. Check
5057 locally. */
5058 method_prototype
5059 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
5060 sel_name);
5062 else
5064 tree iface;
5066 if ((iface = lookup_interface (TYPE_NAME (ctype))))
5067 method_prototype = lookup_instance_method_static (iface, sel_name);
5069 if (! method_prototype)
5071 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
5072 if (protocol_list)
5073 method_prototype
5074 = lookup_method_in_protocol_list (protocol_list,
5075 sel_name, 0);
5079 if (!method_prototype)
5080 warning ("`%s' does not respond to `%s'",
5081 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
5082 IDENTIFIER_POINTER (sel_name));
5084 else if (class_ident)
5086 if (objc_implementation_context
5087 && CLASS_NAME (objc_implementation_context) == class_ident)
5089 method_prototype
5090 = lookup_class_method_static (implementation_template, sel_name);
5092 if (!method_prototype
5093 && implementation_template != objc_implementation_context)
5094 /* The method is not published in the interface. Check
5095 locally. */
5096 method_prototype
5097 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
5098 sel_name);
5100 else
5102 tree iface;
5104 if ((iface = lookup_interface (class_ident)))
5105 method_prototype = lookup_class_method_static (iface, sel_name);
5108 if (!method_prototype)
5110 warning ("cannot find class (factory) method");
5111 warning ("return type for `%s' defaults to id",
5112 IDENTIFIER_POINTER (sel_name));
5115 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5117 /* An anonymous object that has been qualified with a protocol. */
5119 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5121 method_prototype = lookup_method_in_protocol_list (protocol_list,
5122 sel_name, 0);
5124 if (!method_prototype)
5126 hash hsh;
5128 warning ("method `%s' not implemented by protocol",
5129 IDENTIFIER_POINTER (sel_name));
5131 /* Try and find the method signature in the global pools. */
5133 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5134 hsh = hash_lookup (cls_method_hash_list, sel_name);
5136 if (!(method_prototype = check_duplicates (hsh)))
5137 warning ("return type defaults to id");
5140 else
5142 hash hsh;
5144 /* We think we have an instance...loophole: extern id Object; */
5145 hsh = hash_lookup (nst_method_hash_list, sel_name);
5147 if (!hsh)
5148 /* For various loopholes */
5149 hsh = hash_lookup (cls_method_hash_list, sel_name);
5151 method_prototype = check_duplicates (hsh);
5152 if (!method_prototype)
5154 warning ("cannot find method");
5155 warning ("return type for `%s' defaults to id",
5156 IDENTIFIER_POINTER (sel_name));
5160 /* Save the selector name for printing error messages. */
5161 current_objc_message_selector = sel_name;
5163 /* Build the parameters list for looking up the method.
5164 These are the object itself and the selector. */
5166 if (flag_typed_selectors)
5167 selector = build_typed_selector_reference (sel_name, method_prototype);
5168 else
5169 selector = build_selector_reference (sel_name);
5171 retval = build_objc_method_call (super, method_prototype,
5172 receiver, self_object,
5173 selector, method_params);
5175 current_objc_message_selector = 0;
5177 return retval;
5180 /* Build a tree expression to send OBJECT the operation SELECTOR,
5181 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5182 assuming the method has prototype METHOD_PROTOTYPE.
5183 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5184 Use METHOD_PARAMS as list of args to pass to the method.
5185 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5187 static tree
5188 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5189 selector, method_params)
5190 int super_flag;
5191 tree method_prototype, lookup_object, object, selector, method_params;
5193 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5194 tree rcv_p = (super_flag
5195 ? build_pointer_type (xref_tag (RECORD_TYPE,
5196 get_identifier (TAG_SUPER)))
5197 : id_type);
5199 if (flag_next_runtime)
5201 if (! method_prototype)
5203 method_params = tree_cons (NULL_TREE, lookup_object,
5204 tree_cons (NULL_TREE, selector,
5205 method_params));
5206 assemble_external (sender);
5207 return build_function_call (sender, method_params);
5209 else
5211 /* This is a real kludge, but it is used only for the Next.
5212 Clobber the data type of SENDER temporarily to accept
5213 all the arguments for this operation, and to return
5214 whatever this operation returns. */
5215 tree arglist = NULL_TREE, retval, savarg, savret;
5216 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5218 /* Save the proper contents of SENDER's data type. */
5219 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5220 savret = TREE_TYPE (TREE_TYPE (sender));
5222 /* Install this method's argument types. */
5223 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5224 super_flag);
5225 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5227 /* Install this method's return type. */
5228 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5230 /* Call SENDER with all the parameters. This will do type
5231 checking using the arg types for this method. */
5232 method_params = tree_cons (NULL_TREE, lookup_object,
5233 tree_cons (NULL_TREE, selector,
5234 method_params));
5235 assemble_external (sender);
5236 retval = build_function_call (sender, method_params);
5238 /* Restore SENDER's return/argument types. */
5239 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5240 TREE_TYPE (TREE_TYPE (sender)) = savret;
5241 return retval;
5244 else
5246 /* This is the portable way.
5247 First call the lookup function to get a pointer to the method,
5248 then cast the pointer, then call it with the method arguments. */
5249 tree method;
5251 /* Avoid trouble since we may evaluate each of these twice. */
5252 object = save_expr (object);
5253 selector = save_expr (selector);
5255 lookup_object = build_c_cast (rcv_p, lookup_object);
5257 assemble_external (sender);
5258 method
5259 = build_function_call (sender,
5260 tree_cons (NULL_TREE, lookup_object,
5261 tree_cons (NULL_TREE, selector,
5262 NULL_TREE)));
5264 /* If we have a method prototype, construct the data type this
5265 method needs, and cast what we got from SENDER into a pointer
5266 to that type. */
5267 if (method_prototype)
5269 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5270 super_flag);
5271 tree valtype = groktypename (TREE_TYPE (method_prototype));
5272 tree fake_function_type = build_function_type (valtype, arglist);
5273 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5275 else
5276 TREE_TYPE (method)
5277 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5279 /* Pass the object to the method. */
5280 assemble_external (method);
5281 return build_function_call (method,
5282 tree_cons (NULL_TREE, object,
5283 tree_cons (NULL_TREE, selector,
5284 method_params)));
5288 static void
5289 build_protocol_reference (p)
5290 tree p;
5292 tree decl, ident, ptype;
5294 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5296 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5297 ptype
5298 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5299 objc_protocol_template),
5300 NULL_TREE));
5302 if (IDENTIFIER_GLOBAL_VALUE (ident))
5303 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5304 else
5306 decl = build_decl (VAR_DECL, ident, ptype);
5307 DECL_EXTERNAL (decl) = 1;
5308 TREE_PUBLIC (decl) = 1;
5309 TREE_USED (decl) = 1;
5310 DECL_ARTIFICIAL (decl) = 1;
5312 make_decl_rtl (decl, 0);
5313 pushdecl_top_level (decl);
5316 PROTOCOL_FORWARD_DECL (p) = decl;
5319 /* This function is called by the parser when (and only when) a
5320 @protocol() expression is found, in order to compile it. */
5321 tree
5322 build_protocol_expr (protoname)
5323 tree protoname;
5325 tree expr;
5326 tree p = lookup_protocol (protoname);
5328 if (!p)
5330 error ("cannot find protocol declaration for `%s'",
5331 IDENTIFIER_POINTER (protoname));
5332 return error_mark_node;
5335 if (!PROTOCOL_FORWARD_DECL (p))
5336 build_protocol_reference (p);
5338 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5340 TREE_TYPE (expr) = protocol_type;
5342 /* The @protocol() expression is being compiled into a pointer to a
5343 statically allocated instance of the Protocol class. To become
5344 usable at runtime, the 'isa' pointer of the instance need to be
5345 fixed up at runtime by the runtime library, to point to the
5346 actual 'Protocol' class. */
5348 /* For the GNU runtime, put the static Protocol instance in the list
5349 of statically allocated instances, so that we make sure that its
5350 'isa' pointer is fixed up at runtime by the GNU runtime library
5351 to point to the Protocol class (at runtime, when loading the
5352 module, the GNU runtime library loops on the statically allocated
5353 instances (as found in the defs field in objc_symtab) and fixups
5354 all the 'isa' pointers of those objects). */
5355 if (! flag_next_runtime)
5357 /* This type is a struct containing the fields of a Protocol
5358 object. (Cfr. protocol_type instead is the type of a pointer
5359 to such a struct). */
5360 tree protocol_struct_type = xref_tag
5361 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5362 tree *chain;
5364 /* Look for the list of Protocol statically allocated instances
5365 to fixup at runtime. Create a new list to hold Protocol
5366 statically allocated instances, if the list is not found. At
5367 present there is only another list, holding NSConstantString
5368 static instances to be fixed up at runtime. */
5369 for (chain = &objc_static_instances;
5370 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5371 chain = &TREE_CHAIN (*chain));
5372 if (!*chain)
5374 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5375 add_objc_string (TYPE_NAME (protocol_struct_type),
5376 class_names);
5379 /* Add this statically allocated instance to the Protocol list. */
5380 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5381 PROTOCOL_FORWARD_DECL (p),
5382 TREE_PURPOSE (*chain));
5386 return expr;
5389 /* This function is called by the parser when a @selector() expression
5390 is found, in order to compile it. It is only called by the parser
5391 and only to compile a @selector(). */
5392 tree
5393 build_selector_expr (selnamelist)
5394 tree selnamelist;
5396 tree selname;
5398 /* Obtain the full selector name. */
5399 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5400 /* A unary selector. */
5401 selname = selnamelist;
5402 else if (TREE_CODE (selnamelist) == TREE_LIST)
5403 selname = build_keyword_selector (selnamelist);
5404 else
5405 abort ();
5407 /* If we are required to check @selector() expressions as they
5408 are found, check that the selector has been declared. */
5409 if (warn_undeclared_selector)
5411 /* Look the selector up in the list of all known class and
5412 instance methods (up to this line) to check that the selector
5413 exists. */
5414 hash hsh;
5416 /* First try with instance methods. */
5417 hsh = hash_lookup (nst_method_hash_list, selname);
5419 /* If not found, try with class methods. */
5420 if (!hsh)
5422 hsh = hash_lookup (cls_method_hash_list, selname);
5425 /* If still not found, print out a warning. */
5426 if (!hsh)
5428 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5433 if (flag_typed_selectors)
5434 return build_typed_selector_reference (selname, 0);
5435 else
5436 return build_selector_reference (selname);
5439 tree
5440 build_encode_expr (type)
5441 tree type;
5443 tree result;
5444 const char *string;
5446 encode_type (type, obstack_object_size (&util_obstack),
5447 OBJC_ENCODE_INLINE_DEFS);
5448 obstack_1grow (&util_obstack, 0); /* null terminate string */
5449 string = obstack_finish (&util_obstack);
5451 /* Synthesize a string that represents the encoded struct/union. */
5452 result = my_build_string (strlen (string) + 1, string);
5453 obstack_free (&util_obstack, util_firstobj);
5454 return result;
5457 tree
5458 build_ivar_reference (id)
5459 tree id;
5461 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5463 /* Historically, a class method that produced objects (factory
5464 method) would assign `self' to the instance that it
5465 allocated. This would effectively turn the class method into
5466 an instance method. Following this assignment, the instance
5467 variables could be accessed. That practice, while safe,
5468 violates the simple rule that a class method should not refer
5469 to an instance variable. It's better to catch the cases
5470 where this is done unknowingly than to support the above
5471 paradigm. */
5472 warning ("instance variable `%s' accessed in class method",
5473 IDENTIFIER_POINTER (id));
5474 TREE_TYPE (self_decl) = instance_type; /* cast */
5477 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5480 /* Compute a hash value for a given method SEL_NAME. */
5482 static size_t
5483 hash_func (sel_name)
5484 tree sel_name;
5486 const unsigned char *s
5487 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5488 size_t h = 0;
5490 while (*s)
5491 h = h * 67 + *s++ - 113;
5492 return h;
5495 static void
5496 hash_init ()
5498 nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5499 cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5502 /* WARNING!!!! hash_enter is called with a method, and will peek
5503 inside to find its selector! But hash_lookup is given a selector
5504 directly, and looks for the selector that's inside the found
5505 entry's key (method) for comparison. */
5507 static void
5508 hash_enter (hashlist, method)
5509 hash *hashlist;
5510 tree method;
5512 hash obj;
5513 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5515 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5516 obj->list = 0;
5517 obj->next = hashlist[slot];
5518 obj->key = method;
5520 hashlist[slot] = obj; /* append to front */
5523 static hash
5524 hash_lookup (hashlist, sel_name)
5525 hash *hashlist;
5526 tree sel_name;
5528 hash target;
5530 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5532 while (target)
5534 if (sel_name == METHOD_SEL_NAME (target->key))
5535 return target;
5537 target = target->next;
5539 return 0;
5542 static void
5543 hash_add_attr (entry, value)
5544 hash entry;
5545 tree value;
5547 attr obj;
5549 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5550 obj->next = entry->list;
5551 obj->value = value;
5553 entry->list = obj; /* append to front */
5556 static tree
5557 lookup_method (mchain, method)
5558 tree mchain;
5559 tree method;
5561 tree key;
5563 if (TREE_CODE (method) == IDENTIFIER_NODE)
5564 key = method;
5565 else
5566 key = METHOD_SEL_NAME (method);
5568 while (mchain)
5570 if (METHOD_SEL_NAME (mchain) == key)
5571 return mchain;
5573 mchain = TREE_CHAIN (mchain);
5575 return NULL_TREE;
5578 static tree
5579 lookup_instance_method_static (interface, ident)
5580 tree interface;
5581 tree ident;
5583 tree inter = interface;
5584 tree chain = CLASS_NST_METHODS (inter);
5585 tree meth = NULL_TREE;
5589 if ((meth = lookup_method (chain, ident)))
5590 return meth;
5592 if (CLASS_CATEGORY_LIST (inter))
5594 tree category = CLASS_CATEGORY_LIST (inter);
5595 chain = CLASS_NST_METHODS (category);
5599 if ((meth = lookup_method (chain, ident)))
5600 return meth;
5602 /* Check for instance methods in protocols in categories. */
5603 if (CLASS_PROTOCOL_LIST (category))
5605 if ((meth = (lookup_method_in_protocol_list
5606 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5607 return meth;
5610 if ((category = CLASS_CATEGORY_LIST (category)))
5611 chain = CLASS_NST_METHODS (category);
5613 while (category);
5616 if (CLASS_PROTOCOL_LIST (inter))
5618 if ((meth = (lookup_method_in_protocol_list
5619 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5620 return meth;
5623 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5624 chain = CLASS_NST_METHODS (inter);
5626 while (inter);
5628 return meth;
5631 static tree
5632 lookup_class_method_static (interface, ident)
5633 tree interface;
5634 tree ident;
5636 tree inter = interface;
5637 tree chain = CLASS_CLS_METHODS (inter);
5638 tree meth = NULL_TREE;
5639 tree root_inter = NULL_TREE;
5643 if ((meth = lookup_method (chain, ident)))
5644 return meth;
5646 if (CLASS_CATEGORY_LIST (inter))
5648 tree category = CLASS_CATEGORY_LIST (inter);
5649 chain = CLASS_CLS_METHODS (category);
5653 if ((meth = lookup_method (chain, ident)))
5654 return meth;
5656 /* Check for class methods in protocols in categories. */
5657 if (CLASS_PROTOCOL_LIST (category))
5659 if ((meth = (lookup_method_in_protocol_list
5660 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5661 return meth;
5664 if ((category = CLASS_CATEGORY_LIST (category)))
5665 chain = CLASS_CLS_METHODS (category);
5667 while (category);
5670 /* Check for class methods in protocols. */
5671 if (CLASS_PROTOCOL_LIST (inter))
5673 if ((meth = (lookup_method_in_protocol_list
5674 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5675 return meth;
5678 root_inter = inter;
5679 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5680 chain = CLASS_CLS_METHODS (inter);
5682 while (inter);
5684 /* If no class (factory) method was found, check if an _instance_
5685 method of the same name exists in the root class. This is what
5686 the Objective-C runtime will do. */
5687 return lookup_instance_method_static (root_inter, ident);
5690 tree
5691 add_class_method (class, method)
5692 tree class;
5693 tree method;
5695 tree mth;
5696 hash hsh;
5698 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5700 /* put method on list in reverse order */
5701 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5702 CLASS_CLS_METHODS (class) = method;
5704 else
5706 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5707 error ("duplicate definition of class method `%s'",
5708 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5709 else
5711 /* Check types; if different, complain. */
5712 if (!comp_proto_with_proto (method, mth))
5713 error ("duplicate declaration of class method `%s'",
5714 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5718 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5720 /* Install on a global chain. */
5721 hash_enter (cls_method_hash_list, method);
5723 else
5725 /* Check types; if different, add to a list. */
5726 if (!comp_proto_with_proto (method, hsh->key))
5727 hash_add_attr (hsh, method);
5729 return method;
5732 tree
5733 add_instance_method (class, method)
5734 tree class;
5735 tree method;
5737 tree mth;
5738 hash hsh;
5740 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5742 /* Put method on list in reverse order. */
5743 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5744 CLASS_NST_METHODS (class) = method;
5746 else
5748 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5749 error ("duplicate definition of instance method `%s'",
5750 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5751 else
5753 /* Check types; if different, complain. */
5754 if (!comp_proto_with_proto (method, mth))
5755 error ("duplicate declaration of instance method `%s'",
5756 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5760 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5762 /* Install on a global chain. */
5763 hash_enter (nst_method_hash_list, method);
5765 else
5767 /* Check types; if different, add to a list. */
5768 if (!comp_proto_with_proto (method, hsh->key))
5769 hash_add_attr (hsh, method);
5771 return method;
5774 static tree
5775 add_class (class)
5776 tree class;
5778 /* Put interfaces on list in reverse order. */
5779 TREE_CHAIN (class) = interface_chain;
5780 interface_chain = class;
5781 return interface_chain;
5784 static void
5785 add_category (class, category)
5786 tree class;
5787 tree category;
5789 /* Put categories on list in reverse order. */
5790 tree cat = CLASS_CATEGORY_LIST (class);
5792 while (cat)
5794 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5795 warning ("duplicate interface declaration for category `%s(%s)'",
5796 IDENTIFIER_POINTER (CLASS_NAME (class)),
5797 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5798 cat = CLASS_CATEGORY_LIST (cat);
5801 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5802 CLASS_CATEGORY_LIST (class) = category;
5805 /* Called after parsing each instance variable declaration. Necessary to
5806 preserve typedefs and implement public/private...
5808 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5810 tree
5811 add_instance_variable (class, public, declarator, declspecs, width)
5812 tree class;
5813 int public;
5814 tree declarator;
5815 tree declspecs;
5816 tree width;
5818 tree field_decl, raw_decl;
5820 raw_decl = build_tree_list (declspecs, declarator);
5822 if (CLASS_RAW_IVARS (class))
5823 chainon (CLASS_RAW_IVARS (class), raw_decl);
5824 else
5825 CLASS_RAW_IVARS (class) = raw_decl;
5827 field_decl = grokfield (input_filename, lineno,
5828 declarator, declspecs, width);
5830 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5831 switch (public)
5833 case 0:
5834 TREE_PUBLIC (field_decl) = 0;
5835 TREE_PRIVATE (field_decl) = 0;
5836 TREE_PROTECTED (field_decl) = 1;
5837 break;
5839 case 1:
5840 TREE_PUBLIC (field_decl) = 1;
5841 TREE_PRIVATE (field_decl) = 0;
5842 TREE_PROTECTED (field_decl) = 0;
5843 break;
5845 case 2:
5846 TREE_PUBLIC (field_decl) = 0;
5847 TREE_PRIVATE (field_decl) = 1;
5848 TREE_PROTECTED (field_decl) = 0;
5849 break;
5853 if (CLASS_IVARS (class))
5854 chainon (CLASS_IVARS (class), field_decl);
5855 else
5856 CLASS_IVARS (class) = field_decl;
5858 return class;
5861 tree
5862 is_ivar (decl_chain, ident)
5863 tree decl_chain;
5864 tree ident;
5866 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5867 if (DECL_NAME (decl_chain) == ident)
5868 return decl_chain;
5869 return NULL_TREE;
5872 /* True if the ivar is private and we are not in its implementation. */
5875 is_private (decl)
5876 tree decl;
5878 if (TREE_PRIVATE (decl)
5879 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5881 error ("instance variable `%s' is declared private",
5882 IDENTIFIER_POINTER (DECL_NAME (decl)));
5883 return 1;
5885 else
5886 return 0;
5889 /* We have an instance variable reference;, check to see if it is public. */
5892 is_public (expr, identifier)
5893 tree expr;
5894 tree identifier;
5896 tree basetype = TREE_TYPE (expr);
5897 enum tree_code code = TREE_CODE (basetype);
5898 tree decl;
5900 if (code == RECORD_TYPE)
5902 if (TREE_STATIC_TEMPLATE (basetype))
5904 if (!lookup_interface (TYPE_NAME (basetype)))
5906 error ("cannot find interface declaration for `%s'",
5907 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5908 return 0;
5911 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5913 if (TREE_PUBLIC (decl))
5914 return 1;
5916 /* Important difference between the Stepstone translator:
5917 all instance variables should be public within the context
5918 of the implementation. */
5919 if (objc_implementation_context
5920 && (((TREE_CODE (objc_implementation_context)
5921 == CLASS_IMPLEMENTATION_TYPE)
5922 || (TREE_CODE (objc_implementation_context)
5923 == CATEGORY_IMPLEMENTATION_TYPE))
5924 && (CLASS_NAME (objc_implementation_context)
5925 == TYPE_NAME (basetype))))
5926 return ! is_private (decl);
5928 error ("instance variable `%s' is declared %s",
5929 IDENTIFIER_POINTER (identifier),
5930 TREE_PRIVATE (decl) ? "private" : "protected");
5931 return 0;
5935 else if (objc_implementation_context && (basetype == objc_object_reference))
5937 TREE_TYPE (expr) = uprivate_record;
5938 warning ("static access to object of type `id'");
5942 return 1;
5945 /* Make sure all entries in CHAIN are also in LIST. */
5947 static int
5948 check_methods (chain, list, mtype)
5949 tree chain;
5950 tree list;
5951 int mtype;
5953 int first = 1;
5955 while (chain)
5957 if (!lookup_method (list, chain))
5959 if (first)
5961 if (TREE_CODE (objc_implementation_context)
5962 == CLASS_IMPLEMENTATION_TYPE)
5963 warning ("incomplete implementation of class `%s'",
5964 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5965 else if (TREE_CODE (objc_implementation_context)
5966 == CATEGORY_IMPLEMENTATION_TYPE)
5967 warning ("incomplete implementation of category `%s'",
5968 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5969 first = 0;
5972 warning ("method definition for `%c%s' not found",
5973 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5976 chain = TREE_CHAIN (chain);
5979 return first;
5982 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5984 static int
5985 conforms_to_protocol (class, protocol)
5986 tree class;
5987 tree protocol;
5989 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5991 tree p = CLASS_PROTOCOL_LIST (class);
5992 while (p && TREE_VALUE (p) != protocol)
5993 p = TREE_CHAIN (p);
5995 if (!p)
5997 tree super = (CLASS_SUPER_NAME (class)
5998 ? lookup_interface (CLASS_SUPER_NAME (class))
5999 : NULL_TREE);
6000 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6001 if (!tmp)
6002 return 0;
6006 return 1;
6009 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6010 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6012 static int
6013 check_methods_accessible (chain, context, mtype)
6014 tree chain;
6015 tree context;
6016 int mtype;
6018 int first = 1;
6019 tree list;
6020 tree base_context = context;
6022 while (chain)
6024 context = base_context;
6025 while (context)
6027 if (mtype == '+')
6028 list = CLASS_CLS_METHODS (context);
6029 else
6030 list = CLASS_NST_METHODS (context);
6032 if (lookup_method (list, chain))
6033 break;
6035 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6036 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6037 context = (CLASS_SUPER_NAME (context)
6038 ? lookup_interface (CLASS_SUPER_NAME (context))
6039 : NULL_TREE);
6041 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6042 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6043 context = (CLASS_NAME (context)
6044 ? lookup_interface (CLASS_NAME (context))
6045 : NULL_TREE);
6046 else
6047 abort ();
6050 if (context == NULL_TREE)
6052 if (first)
6054 if (TREE_CODE (objc_implementation_context)
6055 == CLASS_IMPLEMENTATION_TYPE)
6056 warning ("incomplete implementation of class `%s'",
6057 IDENTIFIER_POINTER
6058 (CLASS_NAME (objc_implementation_context)));
6059 else if (TREE_CODE (objc_implementation_context)
6060 == CATEGORY_IMPLEMENTATION_TYPE)
6061 warning ("incomplete implementation of category `%s'",
6062 IDENTIFIER_POINTER
6063 (CLASS_SUPER_NAME (objc_implementation_context)));
6064 first = 0;
6066 warning ("method definition for `%c%s' not found",
6067 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6070 chain = TREE_CHAIN (chain); /* next method... */
6072 return first;
6075 /* Check whether the current interface (accessible via
6076 'objc_implementation_context') actually implements protocol P, along
6077 with any protocols that P inherits. */
6079 static void
6080 check_protocol (p, type, name)
6081 tree p;
6082 const char *type;
6083 const char *name;
6085 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6087 int f1, f2;
6089 /* Ensure that all protocols have bodies! */
6090 if (warn_protocol)
6092 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6093 CLASS_CLS_METHODS (objc_implementation_context),
6094 '+');
6095 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6096 CLASS_NST_METHODS (objc_implementation_context),
6097 '-');
6099 else
6101 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6102 objc_implementation_context,
6103 '+');
6104 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6105 objc_implementation_context,
6106 '-');
6109 if (!f1 || !f2)
6110 warning ("%s `%s' does not fully implement the `%s' protocol",
6111 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6114 /* Check protocols recursively. */
6115 if (PROTOCOL_LIST (p))
6117 tree subs = PROTOCOL_LIST (p);
6118 tree super_class =
6119 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6121 while (subs)
6123 tree sub = TREE_VALUE (subs);
6125 /* If the superclass does not conform to the protocols
6126 inherited by P, then we must! */
6127 if (!super_class || !conforms_to_protocol (super_class, sub))
6128 check_protocol (sub, type, name);
6129 subs = TREE_CHAIN (subs);
6134 /* Check whether the current interface (accessible via
6135 'objc_implementation_context') actually implements the protocols listed
6136 in PROTO_LIST. */
6138 static void
6139 check_protocols (proto_list, type, name)
6140 tree proto_list;
6141 const char *type;
6142 const char *name;
6144 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6146 tree p = TREE_VALUE (proto_list);
6148 check_protocol (p, type, name);
6152 /* Make sure that the class CLASS_NAME is defined
6153 CODE says which kind of thing CLASS_NAME ought to be.
6154 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6155 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6157 tree
6158 start_class (code, class_name, super_name, protocol_list)
6159 enum tree_code code;
6160 tree class_name;
6161 tree super_name;
6162 tree protocol_list;
6164 tree class, decl;
6166 if (objc_implementation_context)
6168 warning ("`@end' missing in implementation context");
6169 finish_class (objc_implementation_context);
6170 objc_ivar_chain = NULL_TREE;
6171 objc_implementation_context = NULL_TREE;
6174 class = make_node (code);
6175 TYPE_BINFO (class) = make_tree_vec (BINFO_ELTS);
6177 CLASS_NAME (class) = class_name;
6178 CLASS_SUPER_NAME (class) = super_name;
6179 CLASS_CLS_METHODS (class) = NULL_TREE;
6181 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6183 error ("`%s' redeclared as different kind of symbol",
6184 IDENTIFIER_POINTER (class_name));
6185 error_with_decl (decl, "previous declaration of `%s'");
6188 if (code == CLASS_IMPLEMENTATION_TYPE)
6191 tree chain;
6193 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6194 if (TREE_VALUE (chain) == class_name)
6196 error ("reimplementation of class `%s'",
6197 IDENTIFIER_POINTER (class_name));
6198 return error_mark_node;
6200 implemented_classes = tree_cons (NULL_TREE, class_name,
6201 implemented_classes);
6204 /* Pre-build the following entities - for speed/convenience. */
6205 if (!self_id)
6206 self_id = get_identifier ("self");
6207 if (!ucmd_id)
6208 ucmd_id = get_identifier ("_cmd");
6209 if (!unused_list)
6210 unused_list
6211 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6212 if (!objc_super_template)
6213 objc_super_template = build_super_template ();
6215 /* Reset for multiple classes per file. */
6216 method_slot = 0;
6218 objc_implementation_context = class;
6220 /* Lookup the interface for this implementation. */
6222 if (!(implementation_template = lookup_interface (class_name)))
6224 warning ("cannot find interface declaration for `%s'",
6225 IDENTIFIER_POINTER (class_name));
6226 add_class (implementation_template = objc_implementation_context);
6229 /* If a super class has been specified in the implementation,
6230 insure it conforms to the one specified in the interface. */
6232 if (super_name
6233 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6235 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6236 const char *const name =
6237 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6238 error ("conflicting super class name `%s'",
6239 IDENTIFIER_POINTER (super_name));
6240 error ("previous declaration of `%s'", name);
6243 else if (! super_name)
6245 CLASS_SUPER_NAME (objc_implementation_context)
6246 = CLASS_SUPER_NAME (implementation_template);
6250 else if (code == CLASS_INTERFACE_TYPE)
6252 if (lookup_interface (class_name))
6253 warning ("duplicate interface declaration for class `%s'",
6254 IDENTIFIER_POINTER (class_name));
6255 else
6256 add_class (class);
6258 if (protocol_list)
6259 CLASS_PROTOCOL_LIST (class)
6260 = lookup_and_install_protocols (protocol_list);
6263 else if (code == CATEGORY_INTERFACE_TYPE)
6265 tree class_category_is_assoc_with;
6267 /* For a category, class_name is really the name of the class that
6268 the following set of methods will be associated with. We must
6269 find the interface so that can derive the objects template. */
6271 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6273 error ("cannot find interface declaration for `%s'",
6274 IDENTIFIER_POINTER (class_name));
6275 exit (FATAL_EXIT_CODE);
6277 else
6278 add_category (class_category_is_assoc_with, class);
6280 if (protocol_list)
6281 CLASS_PROTOCOL_LIST (class)
6282 = lookup_and_install_protocols (protocol_list);
6285 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6287 /* Pre-build the following entities for speed/convenience. */
6288 if (!self_id)
6289 self_id = get_identifier ("self");
6290 if (!ucmd_id)
6291 ucmd_id = get_identifier ("_cmd");
6292 if (!unused_list)
6293 unused_list
6294 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6295 if (!objc_super_template)
6296 objc_super_template = build_super_template ();
6298 /* Reset for multiple classes per file. */
6299 method_slot = 0;
6301 objc_implementation_context = class;
6303 /* For a category, class_name is really the name of the class that
6304 the following set of methods will be associated with. We must
6305 find the interface so that can derive the objects template. */
6307 if (!(implementation_template = lookup_interface (class_name)))
6309 error ("cannot find interface declaration for `%s'",
6310 IDENTIFIER_POINTER (class_name));
6311 exit (FATAL_EXIT_CODE);
6314 return class;
6317 tree
6318 continue_class (class)
6319 tree class;
6321 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6322 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6324 struct imp_entry *imp_entry;
6325 tree ivar_context;
6327 /* Check consistency of the instance variables. */
6329 if (CLASS_IVARS (class))
6330 check_ivars (implementation_template, class);
6332 /* code generation */
6334 ivar_context = build_private_template (implementation_template);
6336 if (!objc_class_template)
6337 build_class_template ();
6339 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6341 imp_entry->next = imp_list;
6342 imp_entry->imp_context = class;
6343 imp_entry->imp_template = implementation_template;
6345 synth_forward_declarations ();
6346 imp_entry->class_decl = UOBJC_CLASS_decl;
6347 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6349 /* Append to front and increment count. */
6350 imp_list = imp_entry;
6351 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6352 imp_count++;
6353 else
6354 cat_count++;
6356 return ivar_context;
6359 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6361 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6363 if (!TYPE_FIELDS (record))
6365 finish_struct (record, get_class_ivars (class), NULL_TREE);
6366 CLASS_STATIC_TEMPLATE (class) = record;
6368 /* Mark this record as a class template for static typing. */
6369 TREE_STATIC_TEMPLATE (record) = 1;
6372 return NULL_TREE;
6375 else
6376 return error_mark_node;
6379 /* This is called once we see the "@end" in an interface/implementation. */
6381 void
6382 finish_class (class)
6383 tree class;
6385 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6387 /* All code generation is done in finish_objc. */
6389 if (implementation_template != objc_implementation_context)
6391 /* Ensure that all method listed in the interface contain bodies. */
6392 check_methods (CLASS_CLS_METHODS (implementation_template),
6393 CLASS_CLS_METHODS (objc_implementation_context), '+');
6394 check_methods (CLASS_NST_METHODS (implementation_template),
6395 CLASS_NST_METHODS (objc_implementation_context), '-');
6397 if (CLASS_PROTOCOL_LIST (implementation_template))
6398 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6399 "class",
6400 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6404 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6406 tree category = CLASS_CATEGORY_LIST (implementation_template);
6408 /* Find the category interface from the class it is associated with. */
6409 while (category)
6411 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6412 break;
6413 category = CLASS_CATEGORY_LIST (category);
6416 if (category)
6418 /* Ensure all method listed in the interface contain bodies. */
6419 check_methods (CLASS_CLS_METHODS (category),
6420 CLASS_CLS_METHODS (objc_implementation_context), '+');
6421 check_methods (CLASS_NST_METHODS (category),
6422 CLASS_NST_METHODS (objc_implementation_context), '-');
6424 if (CLASS_PROTOCOL_LIST (category))
6425 check_protocols (CLASS_PROTOCOL_LIST (category),
6426 "category",
6427 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6431 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6433 tree decl_specs;
6434 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6435 char *string = (char *) alloca (strlen (class_name) + 3);
6437 /* extern struct objc_object *_<my_name>; */
6439 sprintf (string, "_%s", class_name);
6441 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6442 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6443 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6444 decl_specs);
6448 static tree
6449 add_protocol (protocol)
6450 tree protocol;
6452 /* Put protocol on list in reverse order. */
6453 TREE_CHAIN (protocol) = protocol_chain;
6454 protocol_chain = protocol;
6455 return protocol_chain;
6458 static tree
6459 lookup_protocol (ident)
6460 tree ident;
6462 tree chain;
6464 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6465 if (ident == PROTOCOL_NAME (chain))
6466 return chain;
6468 return NULL_TREE;
6471 /* This function forward declares the protocols named by NAMES. If
6472 they are already declared or defined, the function has no effect. */
6474 void
6475 objc_declare_protocols (names)
6476 tree names;
6478 tree list;
6480 for (list = names; list; list = TREE_CHAIN (list))
6482 tree name = TREE_VALUE (list);
6484 if (lookup_protocol (name) == NULL_TREE)
6486 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6488 TYPE_BINFO (protocol) = make_tree_vec (2);
6489 PROTOCOL_NAME (protocol) = name;
6490 PROTOCOL_LIST (protocol) = NULL_TREE;
6491 add_protocol (protocol);
6492 PROTOCOL_DEFINED (protocol) = 0;
6493 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6498 tree
6499 start_protocol (code, name, list)
6500 enum tree_code code;
6501 tree name;
6502 tree list;
6504 tree protocol;
6506 /* This is as good a place as any. Need to invoke
6507 push_tag_toplevel. */
6508 if (!objc_protocol_template)
6509 objc_protocol_template = build_protocol_template ();
6511 protocol = lookup_protocol (name);
6513 if (!protocol)
6515 protocol = make_node (code);
6516 TYPE_BINFO (protocol) = make_tree_vec (2);
6518 PROTOCOL_NAME (protocol) = name;
6519 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6520 add_protocol (protocol);
6521 PROTOCOL_DEFINED (protocol) = 1;
6522 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6524 check_protocol_recursively (protocol, list);
6526 else if (! PROTOCOL_DEFINED (protocol))
6528 PROTOCOL_DEFINED (protocol) = 1;
6529 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6531 check_protocol_recursively (protocol, list);
6533 else
6535 warning ("duplicate declaration for protocol `%s'",
6536 IDENTIFIER_POINTER (name));
6538 return protocol;
6541 void
6542 finish_protocol (protocol)
6543 tree protocol ATTRIBUTE_UNUSED;
6548 /* "Encode" a data type into a string, which grows in util_obstack.
6549 ??? What is the FORMAT? Someone please document this! */
6551 static void
6552 encode_type_qualifiers (declspecs)
6553 tree declspecs;
6555 tree spec;
6557 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6559 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6560 obstack_1grow (&util_obstack, 'r');
6561 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6562 obstack_1grow (&util_obstack, 'n');
6563 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6564 obstack_1grow (&util_obstack, 'N');
6565 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6566 obstack_1grow (&util_obstack, 'o');
6567 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6568 obstack_1grow (&util_obstack, 'O');
6569 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6570 obstack_1grow (&util_obstack, 'R');
6571 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6572 obstack_1grow (&util_obstack, 'V');
6576 /* Encode a pointer type. */
6578 static void
6579 encode_pointer (type, curtype, format)
6580 tree type;
6581 int curtype;
6582 int format;
6584 tree pointer_to = TREE_TYPE (type);
6586 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6588 if (TYPE_NAME (pointer_to)
6589 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6591 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6593 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6595 obstack_1grow (&util_obstack, '@');
6596 return;
6598 else if (TREE_STATIC_TEMPLATE (pointer_to))
6600 if (generating_instance_variables)
6602 obstack_1grow (&util_obstack, '@');
6603 obstack_1grow (&util_obstack, '"');
6604 obstack_grow (&util_obstack, name, strlen (name));
6605 obstack_1grow (&util_obstack, '"');
6606 return;
6608 else
6610 obstack_1grow (&util_obstack, '@');
6611 return;
6614 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6616 obstack_1grow (&util_obstack, '#');
6617 return;
6619 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6621 obstack_1grow (&util_obstack, ':');
6622 return;
6626 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6627 && TYPE_MODE (pointer_to) == QImode)
6629 obstack_1grow (&util_obstack, '*');
6630 return;
6633 /* We have a type that does not get special treatment. */
6635 /* NeXT extension */
6636 obstack_1grow (&util_obstack, '^');
6637 encode_type (pointer_to, curtype, format);
6640 static void
6641 encode_array (type, curtype, format)
6642 tree type;
6643 int curtype;
6644 int format;
6646 tree an_int_cst = TYPE_SIZE (type);
6647 tree array_of = TREE_TYPE (type);
6648 char buffer[40];
6650 /* An incomplete array is treated like a pointer. */
6651 if (an_int_cst == NULL)
6653 encode_pointer (type, curtype, format);
6654 return;
6657 sprintf (buffer, "[%ld",
6658 (long) (TREE_INT_CST_LOW (an_int_cst)
6659 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6661 obstack_grow (&util_obstack, buffer, strlen (buffer));
6662 encode_type (array_of, curtype, format);
6663 obstack_1grow (&util_obstack, ']');
6664 return;
6667 static void
6668 encode_aggregate_within (type, curtype, format, left, right)
6669 tree type;
6670 int curtype;
6671 int format;
6672 int left;
6673 int right;
6675 /* The RECORD_TYPE may in fact be a typedef! For purposes
6676 of encoding, we need the real underlying enchilada. */
6677 if (TYPE_MAIN_VARIANT (type))
6678 type = TYPE_MAIN_VARIANT (type);
6680 if (obstack_object_size (&util_obstack) > 0
6681 && *(obstack_next_free (&util_obstack) - 1) == '^')
6683 tree name = TYPE_NAME (type);
6685 /* we have a reference; this is a NeXT extension. */
6687 if (obstack_object_size (&util_obstack) - curtype == 1
6688 && format == OBJC_ENCODE_INLINE_DEFS)
6690 /* Output format of struct for first level only. */
6691 tree fields = TYPE_FIELDS (type);
6693 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6695 obstack_1grow (&util_obstack, left);
6696 obstack_grow (&util_obstack,
6697 IDENTIFIER_POINTER (name),
6698 strlen (IDENTIFIER_POINTER (name)));
6699 obstack_1grow (&util_obstack, '=');
6701 else
6703 obstack_1grow (&util_obstack, left);
6704 obstack_grow (&util_obstack, "?=", 2);
6707 for ( ; fields; fields = TREE_CHAIN (fields))
6708 encode_field_decl (fields, curtype, format);
6710 obstack_1grow (&util_obstack, right);
6713 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6715 obstack_1grow (&util_obstack, left);
6716 obstack_grow (&util_obstack,
6717 IDENTIFIER_POINTER (name),
6718 strlen (IDENTIFIER_POINTER (name)));
6719 obstack_1grow (&util_obstack, right);
6722 else
6724 /* We have an untagged structure or a typedef. */
6725 obstack_1grow (&util_obstack, left);
6726 obstack_1grow (&util_obstack, '?');
6727 obstack_1grow (&util_obstack, right);
6731 else
6733 tree name = TYPE_NAME (type);
6734 tree fields = TYPE_FIELDS (type);
6736 if (format == OBJC_ENCODE_INLINE_DEFS
6737 || generating_instance_variables)
6739 obstack_1grow (&util_obstack, left);
6740 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6741 obstack_grow (&util_obstack,
6742 IDENTIFIER_POINTER (name),
6743 strlen (IDENTIFIER_POINTER (name)));
6744 else
6745 obstack_1grow (&util_obstack, '?');
6747 obstack_1grow (&util_obstack, '=');
6749 for (; fields; fields = TREE_CHAIN (fields))
6751 if (generating_instance_variables)
6753 tree fname = DECL_NAME (fields);
6755 obstack_1grow (&util_obstack, '"');
6756 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6758 obstack_grow (&util_obstack,
6759 IDENTIFIER_POINTER (fname),
6760 strlen (IDENTIFIER_POINTER (fname)));
6763 obstack_1grow (&util_obstack, '"');
6766 encode_field_decl (fields, curtype, format);
6769 obstack_1grow (&util_obstack, right);
6772 else
6774 obstack_1grow (&util_obstack, left);
6775 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6776 obstack_grow (&util_obstack,
6777 IDENTIFIER_POINTER (name),
6778 strlen (IDENTIFIER_POINTER (name)));
6779 else
6780 /* We have an untagged structure or a typedef. */
6781 obstack_1grow (&util_obstack, '?');
6783 obstack_1grow (&util_obstack, right);
6788 static void
6789 encode_aggregate (type, curtype, format)
6790 tree type;
6791 int curtype;
6792 int format;
6794 enum tree_code code = TREE_CODE (type);
6796 switch (code)
6798 case RECORD_TYPE:
6800 encode_aggregate_within(type, curtype, format, '{', '}');
6801 break;
6803 case UNION_TYPE:
6805 encode_aggregate_within(type, curtype, format, '(', ')');
6806 break;
6809 case ENUMERAL_TYPE:
6810 obstack_1grow (&util_obstack, 'i');
6811 break;
6813 default:
6814 break;
6818 /* Support bitfields. The current version of Objective-C does not support
6819 them. The string will consist of one or more "b:n"'s where n is an
6820 integer describing the width of the bitfield. Currently, classes in
6821 the kit implement a method "-(char *)describeBitfieldStruct:" that
6822 simulates this. If they do not implement this method, the archiver
6823 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6824 according to the GNU compiler. After looking at the "kit", it appears
6825 that all classes currently rely on this default behavior, rather than
6826 hand generating this string (which is tedious). */
6828 static void
6829 encode_bitfield (width)
6830 int width;
6832 char buffer[40];
6833 sprintf (buffer, "b%d", width);
6834 obstack_grow (&util_obstack, buffer, strlen (buffer));
6837 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6839 static void
6840 encode_type (type, curtype, format)
6841 tree type;
6842 int curtype;
6843 int format;
6845 enum tree_code code = TREE_CODE (type);
6847 if (code == INTEGER_TYPE)
6849 if (integer_zerop (TYPE_MIN_VALUE (type)))
6851 /* Unsigned integer types. */
6853 if (TYPE_MODE (type) == QImode)
6854 obstack_1grow (&util_obstack, 'C');
6855 else if (TYPE_MODE (type) == HImode)
6856 obstack_1grow (&util_obstack, 'S');
6857 else if (TYPE_MODE (type) == SImode)
6859 if (type == long_unsigned_type_node)
6860 obstack_1grow (&util_obstack, 'L');
6861 else
6862 obstack_1grow (&util_obstack, 'I');
6864 else if (TYPE_MODE (type) == DImode)
6865 obstack_1grow (&util_obstack, 'Q');
6868 else
6869 /* Signed integer types. */
6871 if (TYPE_MODE (type) == QImode)
6872 obstack_1grow (&util_obstack, 'c');
6873 else if (TYPE_MODE (type) == HImode)
6874 obstack_1grow (&util_obstack, 's');
6875 else if (TYPE_MODE (type) == SImode)
6877 if (type == long_integer_type_node)
6878 obstack_1grow (&util_obstack, 'l');
6879 else
6880 obstack_1grow (&util_obstack, 'i');
6883 else if (TYPE_MODE (type) == DImode)
6884 obstack_1grow (&util_obstack, 'q');
6888 else if (code == REAL_TYPE)
6890 /* Floating point types. */
6892 if (TYPE_MODE (type) == SFmode)
6893 obstack_1grow (&util_obstack, 'f');
6894 else if (TYPE_MODE (type) == DFmode
6895 || TYPE_MODE (type) == TFmode)
6896 obstack_1grow (&util_obstack, 'd');
6899 else if (code == VOID_TYPE)
6900 obstack_1grow (&util_obstack, 'v');
6902 else if (code == ARRAY_TYPE)
6903 encode_array (type, curtype, format);
6905 else if (code == POINTER_TYPE)
6906 encode_pointer (type, curtype, format);
6908 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6909 encode_aggregate (type, curtype, format);
6911 else if (code == FUNCTION_TYPE) /* '?' */
6912 obstack_1grow (&util_obstack, '?');
6915 static void
6916 encode_complete_bitfield (position, type, size)
6917 int position;
6918 tree type;
6919 int size;
6921 enum tree_code code = TREE_CODE (type);
6922 char buffer[40];
6923 char charType = '?';
6925 if (code == INTEGER_TYPE)
6927 if (integer_zerop (TYPE_MIN_VALUE (type)))
6929 /* Unsigned integer types. */
6931 if (TYPE_MODE (type) == QImode)
6932 charType = 'C';
6933 else if (TYPE_MODE (type) == HImode)
6934 charType = 'S';
6935 else if (TYPE_MODE (type) == SImode)
6937 if (type == long_unsigned_type_node)
6938 charType = 'L';
6939 else
6940 charType = 'I';
6942 else if (TYPE_MODE (type) == DImode)
6943 charType = 'Q';
6946 else
6947 /* Signed integer types. */
6949 if (TYPE_MODE (type) == QImode)
6950 charType = 'c';
6951 else if (TYPE_MODE (type) == HImode)
6952 charType = 's';
6953 else if (TYPE_MODE (type) == SImode)
6955 if (type == long_integer_type_node)
6956 charType = 'l';
6957 else
6958 charType = 'i';
6961 else if (TYPE_MODE (type) == DImode)
6962 charType = 'q';
6965 else if (code == ENUMERAL_TYPE)
6966 charType = 'i';
6967 else
6968 abort ();
6970 sprintf (buffer, "b%d%c%d", position, charType, size);
6971 obstack_grow (&util_obstack, buffer, strlen (buffer));
6974 static void
6975 encode_field_decl (field_decl, curtype, format)
6976 tree field_decl;
6977 int curtype;
6978 int format;
6980 tree type;
6982 type = TREE_TYPE (field_decl);
6984 /* If this field is obviously a bitfield, or is a bitfield that has been
6985 clobbered to look like a ordinary integer mode, go ahead and generate
6986 the bitfield typing information. */
6987 if (flag_next_runtime)
6989 if (DECL_BIT_FIELD_TYPE (field_decl))
6990 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6991 else
6992 encode_type (TREE_TYPE (field_decl), curtype, format);
6994 else
6996 if (DECL_BIT_FIELD_TYPE (field_decl))
6997 encode_complete_bitfield (int_bit_position (field_decl),
6998 DECL_BIT_FIELD_TYPE (field_decl),
6999 tree_low_cst (DECL_SIZE (field_decl), 1));
7000 else
7001 encode_type (TREE_TYPE (field_decl), curtype, format);
7005 static tree
7006 expr_last (complex_expr)
7007 tree complex_expr;
7009 tree next;
7011 if (complex_expr)
7012 while ((next = TREE_OPERAND (complex_expr, 0)))
7013 complex_expr = next;
7015 return complex_expr;
7018 /* Transform a method definition into a function definition as follows:
7019 - synthesize the first two arguments, "self" and "_cmd". */
7021 void
7022 start_method_def (method)
7023 tree method;
7025 tree decl_specs;
7027 /* Required to implement _msgSuper. */
7028 objc_method_context = method;
7029 UOBJC_SUPER_decl = NULL_TREE;
7031 /* Must be called BEFORE start_function. */
7032 pushlevel (0);
7034 /* Generate prototype declarations for arguments..."new-style". */
7036 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7037 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7038 else
7039 /* Really a `struct objc_class *'. However, we allow people to
7040 assign to self, which changes its type midstream. */
7041 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7043 push_parm_decl (build_tree_list
7044 (build_tree_list (decl_specs,
7045 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7046 unused_list));
7048 decl_specs = build_tree_list (NULL_TREE,
7049 xref_tag (RECORD_TYPE,
7050 get_identifier (TAG_SELECTOR)));
7051 push_parm_decl (build_tree_list
7052 (build_tree_list (decl_specs,
7053 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7054 unused_list));
7056 /* Generate argument declarations if a keyword_decl. */
7057 if (METHOD_SEL_ARGS (method))
7059 tree arglist = METHOD_SEL_ARGS (method);
7062 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7063 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7065 if (arg_decl)
7067 tree last_expr = expr_last (arg_decl);
7069 /* Unite the abstract decl with its name. */
7070 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7071 push_parm_decl (build_tree_list
7072 (build_tree_list (arg_spec, arg_decl),
7073 NULL_TREE));
7075 /* Unhook: restore the abstract declarator. */
7076 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7079 else
7080 push_parm_decl (build_tree_list
7081 (build_tree_list (arg_spec,
7082 KEYWORD_ARG_NAME (arglist)),
7083 NULL_TREE));
7085 arglist = TREE_CHAIN (arglist);
7087 while (arglist);
7090 if (METHOD_ADD_ARGS (method) != NULL_TREE
7091 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7093 /* We have a variable length selector - in "prototype" format. */
7094 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7095 while (akey)
7097 /* This must be done prior to calling pushdecl. pushdecl is
7098 going to change our chain on us. */
7099 tree nextkey = TREE_CHAIN (akey);
7100 pushdecl (akey);
7101 akey = nextkey;
7106 static void
7107 warn_with_method (message, mtype, method)
7108 const char *message;
7109 int mtype;
7110 tree method;
7112 if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
7113 return;
7115 diagnostic_report_current_function (global_dc);
7117 /* Add a readable method name to the warning. */
7118 warning_with_file_and_line (DECL_SOURCE_FILE (method),
7119 DECL_SOURCE_LINE (method),
7120 "%s `%c%s'",
7121 message, mtype,
7122 gen_method_decl (method, errbuf));
7125 /* Return 1 if METHOD is consistent with PROTO. */
7127 static int
7128 comp_method_with_proto (method, proto)
7129 tree method, proto;
7131 /* Create a function template node at most once. */
7132 if (!function1_template)
7133 function1_template = make_node (FUNCTION_TYPE);
7135 /* Install argument types - normally set by build_function_type. */
7136 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7138 /* install return type */
7139 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7141 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7144 /* Return 1 if PROTO1 is consistent with PROTO2. */
7146 static int
7147 comp_proto_with_proto (proto0, proto1)
7148 tree proto0, proto1;
7150 /* Create a couple of function_template nodes at most once. */
7151 if (!function1_template)
7152 function1_template = make_node (FUNCTION_TYPE);
7153 if (!function2_template)
7154 function2_template = make_node (FUNCTION_TYPE);
7156 /* Install argument types; normally set by build_function_type. */
7157 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
7158 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
7160 /* Install return type. */
7161 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
7162 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
7164 return comptypes (function1_template, function2_template);
7167 /* - Generate an identifier for the function. the format is "_n_cls",
7168 where 1 <= n <= nMethods, and cls is the name the implementation we
7169 are processing.
7170 - Install the return type from the method declaration.
7171 - If we have a prototype, check for type consistency. */
7173 static void
7174 really_start_method (method, parmlist)
7175 tree method, parmlist;
7177 tree sc_spec, ret_spec, ret_decl, decl_specs;
7178 tree method_decl, method_id;
7179 const char *sel_name, *class_name, *cat_name;
7180 char *buf;
7182 /* Synth the storage class & assemble the return type. */
7183 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7184 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7185 decl_specs = chainon (sc_spec, ret_spec);
7187 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7188 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7189 cat_name = ((TREE_CODE (objc_implementation_context)
7190 == CLASS_IMPLEMENTATION_TYPE)
7191 ? NULL
7192 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7193 method_slot++;
7195 /* Make sure this is big enough for any plausible method label. */
7196 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7197 + (cat_name ? strlen (cat_name) : 0));
7199 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7200 class_name, cat_name, sel_name, method_slot);
7202 method_id = get_identifier (buf);
7204 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7206 /* Check the declarator portion of the return type for the method. */
7207 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7209 /* Unite the complex decl (specified in the abstract decl) with the
7210 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7211 tree save_expr = expr_last (ret_decl);
7213 TREE_OPERAND (save_expr, 0) = method_decl;
7214 method_decl = ret_decl;
7216 /* Fool the parser into thinking it is starting a function. */
7217 start_function (decl_specs, method_decl, NULL_TREE);
7219 /* Unhook: this has the effect of restoring the abstract declarator. */
7220 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7223 else
7225 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7227 /* Fool the parser into thinking it is starting a function. */
7228 start_function (decl_specs, method_decl, NULL_TREE);
7230 /* Unhook: this has the effect of restoring the abstract declarator. */
7231 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7234 METHOD_DEFINITION (method) = current_function_decl;
7236 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7238 if (implementation_template != objc_implementation_context)
7240 tree proto;
7242 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7243 proto = lookup_instance_method_static (implementation_template,
7244 METHOD_SEL_NAME (method));
7245 else
7246 proto = lookup_class_method_static (implementation_template,
7247 METHOD_SEL_NAME (method));
7249 if (proto && ! comp_method_with_proto (method, proto))
7251 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7253 warn_with_method ("conflicting types for", type, method);
7254 warn_with_method ("previous declaration of", type, proto);
7259 /* The following routine is always called...this "architecture" is to
7260 accommodate "old-style" variable length selectors.
7262 - a:a b:b // prototype ; id c; id d; // old-style. */
7264 void
7265 continue_method_def ()
7267 tree parmlist;
7269 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7270 /* We have a `, ...' immediately following the selector. */
7271 parmlist = get_parm_info (0);
7272 else
7273 parmlist = get_parm_info (1); /* place a `void_at_end' */
7275 /* Set self_decl from the first argument...this global is used by
7276 build_ivar_reference calling build_indirect_ref. */
7277 self_decl = TREE_PURPOSE (parmlist);
7279 poplevel (0, 0, 0);
7280 really_start_method (objc_method_context, parmlist);
7281 store_parm_decls ();
7284 /* Called by the parser, from the `pushlevel' production. */
7286 void
7287 add_objc_decls ()
7289 if (!UOBJC_SUPER_decl)
7291 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7292 build_tree_list (NULL_TREE,
7293 objc_super_template),
7294 0, NULL_TREE);
7296 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7298 /* This prevents `unused variable' warnings when compiling with -Wall. */
7299 TREE_USED (UOBJC_SUPER_decl) = 1;
7300 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7304 /* _n_Method (id self, SEL sel, ...)
7306 struct objc_super _S;
7307 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7308 } */
7310 tree
7311 get_super_receiver ()
7313 if (objc_method_context)
7315 tree super_expr, super_expr_list;
7317 /* Set receiver to self. */
7318 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7319 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7320 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7322 /* Set class to begin searching. */
7323 super_expr = build_component_ref (UOBJC_SUPER_decl,
7324 get_identifier ("class"));
7326 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7328 /* [_cls, __cls]Super are "pre-built" in
7329 synth_forward_declarations. */
7331 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7332 ((TREE_CODE (objc_method_context)
7333 == INSTANCE_METHOD_DECL)
7334 ? ucls_super_ref
7335 : uucls_super_ref));
7338 else
7339 /* We have a category. */
7341 tree super_name = CLASS_SUPER_NAME (implementation_template);
7342 tree super_class;
7344 /* Barf if super used in a category of Object. */
7345 if (!super_name)
7347 error ("no super class declared in interface for `%s'",
7348 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7349 return error_mark_node;
7352 if (flag_next_runtime)
7354 super_class = get_class_reference (super_name);
7355 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7356 /* Cast the super class to 'id', since the user may not have
7357 included <objc/objc-class.h>, leaving 'struct objc_class'
7358 an incomplete type. */
7359 super_class
7360 = build_component_ref (build_indirect_ref
7361 (build_c_cast (id_type, super_class), "->"),
7362 get_identifier ("isa"));
7364 else
7366 add_class_reference (super_name);
7367 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7368 ? objc_get_class_decl : objc_get_meta_class_decl);
7369 assemble_external (super_class);
7370 super_class
7371 = build_function_call
7372 (super_class,
7373 build_tree_list
7374 (NULL_TREE,
7375 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7376 IDENTIFIER_POINTER (super_name))));
7379 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7380 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7383 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7385 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7386 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7388 return build_compound_expr (super_expr_list);
7390 else
7392 error ("[super ...] must appear in a method context");
7393 return error_mark_node;
7397 static tree
7398 encode_method_def (func_decl)
7399 tree func_decl;
7401 tree parms;
7402 int stack_size;
7403 HOST_WIDE_INT max_parm_end = 0;
7404 char buffer[40];
7405 tree result;
7407 /* Return type. */
7408 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7409 obstack_object_size (&util_obstack),
7410 OBJC_ENCODE_INLINE_DEFS);
7412 /* Stack size. */
7413 for (parms = DECL_ARGUMENTS (func_decl); parms;
7414 parms = TREE_CHAIN (parms))
7416 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7417 + int_size_in_bytes (TREE_TYPE (parms)));
7419 if (! offset_is_register && parm_end > max_parm_end)
7420 max_parm_end = parm_end;
7423 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7425 sprintf (buffer, "%d", stack_size);
7426 obstack_grow (&util_obstack, buffer, strlen (buffer));
7428 /* Argument types. */
7429 for (parms = DECL_ARGUMENTS (func_decl); parms;
7430 parms = TREE_CHAIN (parms))
7432 /* Type. */
7433 encode_type (TREE_TYPE (parms),
7434 obstack_object_size (&util_obstack),
7435 OBJC_ENCODE_INLINE_DEFS);
7437 /* Compute offset. */
7438 sprintf (buffer, "%d", forwarding_offset (parms));
7440 /* Indicate register. */
7441 if (offset_is_register)
7442 obstack_1grow (&util_obstack, '+');
7444 obstack_grow (&util_obstack, buffer, strlen (buffer));
7447 /* Null terminate string. */
7448 obstack_1grow (&util_obstack, 0);
7449 result = get_identifier (obstack_finish (&util_obstack));
7450 obstack_free (&util_obstack, util_firstobj);
7451 return result;
7454 static void
7455 objc_expand_function_end ()
7457 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7460 void
7461 finish_method_def ()
7463 lang_expand_function_end = objc_expand_function_end;
7464 finish_function (0, 1);
7465 lang_expand_function_end = NULL;
7467 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7468 since the optimizer may find "may be used before set" errors. */
7469 objc_method_context = NULL_TREE;
7472 #if 0
7474 lang_report_error_function (decl)
7475 tree decl;
7477 if (objc_method_context)
7479 fprintf (stderr, "In method `%s'\n",
7480 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7481 return 1;
7484 else
7485 return 0;
7487 #endif
7489 static int
7490 is_complex_decl (type)
7491 tree type;
7493 return (TREE_CODE (type) == ARRAY_TYPE
7494 || TREE_CODE (type) == FUNCTION_TYPE
7495 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7499 /* Code to convert a decl node into text for a declaration in C. */
7501 static char tmpbuf[256];
7503 static void
7504 adorn_decl (decl, str)
7505 tree decl;
7506 char *str;
7508 enum tree_code code = TREE_CODE (decl);
7510 if (code == ARRAY_REF)
7512 tree an_int_cst = TREE_OPERAND (decl, 1);
7514 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7515 sprintf (str + strlen (str), "[%ld]",
7516 (long) TREE_INT_CST_LOW (an_int_cst));
7517 else
7518 strcat (str, "[]");
7521 else if (code == ARRAY_TYPE)
7523 tree an_int_cst = TYPE_SIZE (decl);
7524 tree array_of = TREE_TYPE (decl);
7526 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7527 sprintf (str + strlen (str), "[%ld]",
7528 (long) (TREE_INT_CST_LOW (an_int_cst)
7529 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7530 else
7531 strcat (str, "[]");
7534 else if (code == CALL_EXPR)
7536 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7538 strcat (str, "(");
7539 while (chain)
7541 gen_declaration_1 (chain, str);
7542 chain = TREE_CHAIN (chain);
7543 if (chain)
7544 strcat (str, ", ");
7546 strcat (str, ")");
7549 else if (code == FUNCTION_TYPE)
7551 tree chain = TYPE_ARG_TYPES (decl);
7553 strcat (str, "(");
7554 while (chain && TREE_VALUE (chain) != void_type_node)
7556 gen_declaration_1 (TREE_VALUE (chain), str);
7557 chain = TREE_CHAIN (chain);
7558 if (chain && TREE_VALUE (chain) != void_type_node)
7559 strcat (str, ", ");
7561 strcat (str, ")");
7564 else if (code == INDIRECT_REF)
7566 strcpy (tmpbuf, "*");
7567 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7569 tree chain;
7571 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7572 chain;
7573 chain = TREE_CHAIN (chain))
7575 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7577 strcat (tmpbuf, " ");
7578 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7581 if (str[0])
7582 strcat (tmpbuf, " ");
7584 strcat (tmpbuf, str);
7585 strcpy (str, tmpbuf);
7588 else if (code == POINTER_TYPE)
7590 strcpy (tmpbuf, "*");
7591 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7593 if (TREE_READONLY (decl))
7594 strcat (tmpbuf, " const");
7595 if (TYPE_VOLATILE (decl))
7596 strcat (tmpbuf, " volatile");
7597 if (str[0])
7598 strcat (tmpbuf, " ");
7600 strcat (tmpbuf, str);
7601 strcpy (str, tmpbuf);
7605 static char *
7606 gen_declarator (decl, buf, name)
7607 tree decl;
7608 char *buf;
7609 const char *name;
7611 if (decl)
7613 enum tree_code code = TREE_CODE (decl);
7614 char *str;
7615 tree op;
7616 int wrap = 0;
7618 switch (code)
7620 case ARRAY_REF:
7621 case INDIRECT_REF:
7622 case CALL_EXPR:
7623 op = TREE_OPERAND (decl, 0);
7625 /* We have a pointer to a function or array...(*)(), (*)[] */
7626 if ((code == ARRAY_REF || code == CALL_EXPR)
7627 && op && TREE_CODE (op) == INDIRECT_REF)
7628 wrap = 1;
7630 str = gen_declarator (op, buf, name);
7632 if (wrap)
7634 strcpy (tmpbuf, "(");
7635 strcat (tmpbuf, str);
7636 strcat (tmpbuf, ")");
7637 strcpy (str, tmpbuf);
7640 adorn_decl (decl, str);
7641 break;
7643 case ARRAY_TYPE:
7644 case FUNCTION_TYPE:
7645 case POINTER_TYPE:
7646 strcpy (buf, name);
7647 str = buf;
7649 /* This clause is done iteratively rather than recursively. */
7652 op = (is_complex_decl (TREE_TYPE (decl))
7653 ? TREE_TYPE (decl) : NULL_TREE);
7655 adorn_decl (decl, str);
7657 /* We have a pointer to a function or array...(*)(), (*)[] */
7658 if (code == POINTER_TYPE
7659 && op && (TREE_CODE (op) == FUNCTION_TYPE
7660 || TREE_CODE (op) == ARRAY_TYPE))
7662 strcpy (tmpbuf, "(");
7663 strcat (tmpbuf, str);
7664 strcat (tmpbuf, ")");
7665 strcpy (str, tmpbuf);
7668 decl = (is_complex_decl (TREE_TYPE (decl))
7669 ? TREE_TYPE (decl) : NULL_TREE);
7672 while (decl && (code = TREE_CODE (decl)))
7675 break;
7677 case IDENTIFIER_NODE:
7678 /* Will only happen if we are processing a "raw" expr-decl. */
7679 strcpy (buf, IDENTIFIER_POINTER (decl));
7680 return buf;
7682 default:
7683 abort ();
7686 return str;
7689 else
7690 /* We have an abstract declarator or a _DECL node. */
7692 strcpy (buf, name);
7693 return buf;
7697 static void
7698 gen_declspecs (declspecs, buf, raw)
7699 tree declspecs;
7700 char *buf;
7701 int raw;
7703 if (raw)
7705 tree chain;
7707 for (chain = nreverse (copy_list (declspecs));
7708 chain; chain = TREE_CHAIN (chain))
7710 tree aspec = TREE_VALUE (chain);
7712 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7713 strcat (buf, IDENTIFIER_POINTER (aspec));
7714 else if (TREE_CODE (aspec) == RECORD_TYPE)
7716 if (TYPE_NAME (aspec))
7718 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7720 if (! TREE_STATIC_TEMPLATE (aspec))
7721 strcat (buf, "struct ");
7722 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7724 /* NEW!!! */
7725 if (protocol_list)
7727 tree chain = protocol_list;
7729 strcat (buf, " <");
7730 while (chain)
7732 strcat (buf,
7733 IDENTIFIER_POINTER
7734 (PROTOCOL_NAME (TREE_VALUE (chain))));
7735 chain = TREE_CHAIN (chain);
7736 if (chain)
7737 strcat (buf, ", ");
7739 strcat (buf, ">");
7743 else
7744 strcat (buf, "untagged struct");
7747 else if (TREE_CODE (aspec) == UNION_TYPE)
7749 if (TYPE_NAME (aspec))
7751 if (! TREE_STATIC_TEMPLATE (aspec))
7752 strcat (buf, "union ");
7753 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7755 else
7756 strcat (buf, "untagged union");
7759 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7761 if (TYPE_NAME (aspec))
7763 if (! TREE_STATIC_TEMPLATE (aspec))
7764 strcat (buf, "enum ");
7765 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7767 else
7768 strcat (buf, "untagged enum");
7771 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7772 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7774 else if (IS_ID (aspec))
7776 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7778 strcat (buf, "id");
7779 if (protocol_list)
7781 tree chain = protocol_list;
7783 strcat (buf, " <");
7784 while (chain)
7786 strcat (buf,
7787 IDENTIFIER_POINTER
7788 (PROTOCOL_NAME (TREE_VALUE (chain))));
7789 chain = TREE_CHAIN (chain);
7790 if (chain)
7791 strcat (buf, ", ");
7793 strcat (buf, ">");
7796 if (TREE_CHAIN (chain))
7797 strcat (buf, " ");
7800 else
7802 /* Type qualifiers. */
7803 if (TREE_READONLY (declspecs))
7804 strcat (buf, "const ");
7805 if (TYPE_VOLATILE (declspecs))
7806 strcat (buf, "volatile ");
7808 switch (TREE_CODE (declspecs))
7810 /* Type specifiers. */
7812 case INTEGER_TYPE:
7813 declspecs = TYPE_MAIN_VARIANT (declspecs);
7815 /* Signed integer types. */
7817 if (declspecs == short_integer_type_node)
7818 strcat (buf, "short int ");
7819 else if (declspecs == integer_type_node)
7820 strcat (buf, "int ");
7821 else if (declspecs == long_integer_type_node)
7822 strcat (buf, "long int ");
7823 else if (declspecs == long_long_integer_type_node)
7824 strcat (buf, "long long int ");
7825 else if (declspecs == signed_char_type_node
7826 || declspecs == char_type_node)
7827 strcat (buf, "char ");
7829 /* Unsigned integer types. */
7831 else if (declspecs == short_unsigned_type_node)
7832 strcat (buf, "unsigned short ");
7833 else if (declspecs == unsigned_type_node)
7834 strcat (buf, "unsigned int ");
7835 else if (declspecs == long_unsigned_type_node)
7836 strcat (buf, "unsigned long ");
7837 else if (declspecs == long_long_unsigned_type_node)
7838 strcat (buf, "unsigned long long ");
7839 else if (declspecs == unsigned_char_type_node)
7840 strcat (buf, "unsigned char ");
7841 break;
7843 case REAL_TYPE:
7844 declspecs = TYPE_MAIN_VARIANT (declspecs);
7846 if (declspecs == float_type_node)
7847 strcat (buf, "float ");
7848 else if (declspecs == double_type_node)
7849 strcat (buf, "double ");
7850 else if (declspecs == long_double_type_node)
7851 strcat (buf, "long double ");
7852 break;
7854 case RECORD_TYPE:
7855 if (TYPE_NAME (declspecs)
7856 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7858 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7860 if (! TREE_STATIC_TEMPLATE (declspecs))
7861 strcat (buf, "struct ");
7862 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7864 if (protocol_list)
7866 tree chain = protocol_list;
7868 strcat (buf, " <");
7869 while (chain)
7871 strcat (buf,
7872 IDENTIFIER_POINTER
7873 (PROTOCOL_NAME (TREE_VALUE (chain))));
7874 chain = TREE_CHAIN (chain);
7875 if (chain)
7876 strcat (buf, ", ");
7878 strcat (buf, ">");
7882 else
7883 strcat (buf, "untagged struct");
7885 strcat (buf, " ");
7886 break;
7888 case UNION_TYPE:
7889 if (TYPE_NAME (declspecs)
7890 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7892 strcat (buf, "union ");
7893 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7894 strcat (buf, " ");
7897 else
7898 strcat (buf, "untagged union ");
7899 break;
7901 case ENUMERAL_TYPE:
7902 if (TYPE_NAME (declspecs)
7903 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7905 strcat (buf, "enum ");
7906 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7907 strcat (buf, " ");
7910 else
7911 strcat (buf, "untagged enum ");
7912 break;
7914 case VOID_TYPE:
7915 strcat (buf, "void ");
7916 break;
7918 case POINTER_TYPE:
7920 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7922 strcat (buf, "id");
7923 if (protocol_list)
7925 tree chain = protocol_list;
7927 strcat (buf, " <");
7928 while (chain)
7930 strcat (buf,
7931 IDENTIFIER_POINTER
7932 (PROTOCOL_NAME (TREE_VALUE (chain))));
7933 chain = TREE_CHAIN (chain);
7934 if (chain)
7935 strcat (buf, ", ");
7938 strcat (buf, ">");
7941 break;
7943 default:
7944 break;
7949 /* Given a tree node, produce a printable description of it in the given
7950 buffer, overwriting the buffer. */
7952 static char *
7953 gen_declaration (atype_or_adecl, buf)
7954 tree atype_or_adecl;
7955 char *buf;
7957 buf[0] = '\0';
7958 gen_declaration_1 (atype_or_adecl, buf);
7959 return buf;
7962 /* Given a tree node, append a printable description to the end of the
7963 given buffer. */
7965 static void
7966 gen_declaration_1 (atype_or_adecl, buf)
7967 tree atype_or_adecl;
7968 char *buf;
7970 char declbuf[256];
7972 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7974 tree declspecs; /* "identifier_node", "record_type" */
7975 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7977 /* We have a "raw", abstract declarator (typename). */
7978 declarator = TREE_VALUE (atype_or_adecl);
7979 declspecs = TREE_PURPOSE (atype_or_adecl);
7981 gen_declspecs (declspecs, buf, 1);
7982 if (declarator)
7984 strcat (buf, " ");
7985 strcat (buf, gen_declarator (declarator, declbuf, ""));
7989 else
7991 tree atype;
7992 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7993 tree declarator; /* "array_type", "function_type", "pointer_type". */
7995 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7996 || TREE_CODE (atype_or_adecl) == PARM_DECL
7997 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7998 atype = TREE_TYPE (atype_or_adecl);
7999 else
8000 /* Assume we have a *_type node. */
8001 atype = atype_or_adecl;
8003 if (is_complex_decl (atype))
8005 tree chain;
8007 /* Get the declaration specifier; it is at the end of the list. */
8008 declarator = chain = atype;
8010 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8011 while (is_complex_decl (chain));
8012 declspecs = chain;
8015 else
8017 declspecs = atype;
8018 declarator = NULL_TREE;
8021 gen_declspecs (declspecs, buf, 0);
8023 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8024 || TREE_CODE (atype_or_adecl) == PARM_DECL
8025 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8027 const char *const decl_name =
8028 (DECL_NAME (atype_or_adecl)
8029 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8031 if (declarator)
8033 strcat (buf, " ");
8034 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8037 else if (decl_name[0])
8039 strcat (buf, " ");
8040 strcat (buf, decl_name);
8043 else if (declarator)
8045 strcat (buf, " ");
8046 strcat (buf, gen_declarator (declarator, declbuf, ""));
8051 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8053 /* Given a method tree, put a printable description into the given
8054 buffer (overwriting) and return a pointer to the buffer. */
8056 static char *
8057 gen_method_decl (method, buf)
8058 tree method;
8059 char *buf;
8061 tree chain;
8063 buf[0] = '\0';
8064 if (RAW_TYPESPEC (method) != objc_object_reference)
8066 strcat (buf, "(");
8067 gen_declaration_1 (TREE_TYPE (method), buf);
8068 strcat (buf, ")");
8071 chain = METHOD_SEL_ARGS (method);
8072 if (chain)
8074 /* We have a chain of keyword_decls. */
8077 if (KEYWORD_KEY_NAME (chain))
8078 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8080 strcat (buf, ":");
8081 if (RAW_TYPESPEC (chain) != objc_object_reference)
8083 strcat (buf, "(");
8084 gen_declaration_1 (TREE_TYPE (chain), buf);
8085 strcat (buf, ")");
8088 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8089 if ((chain = TREE_CHAIN (chain)))
8090 strcat (buf, " ");
8092 while (chain);
8094 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8095 strcat (buf, ", ...");
8096 else if (METHOD_ADD_ARGS (method))
8098 /* We have a tree list node as generate by get_parm_info. */
8099 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8101 /* Know we have a chain of parm_decls. */
8102 while (chain)
8104 strcat (buf, ", ");
8105 gen_declaration_1 (chain, buf);
8106 chain = TREE_CHAIN (chain);
8111 else
8112 /* We have a unary selector. */
8113 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8115 return buf;
8118 /* Debug info. */
8121 /* Dump an @interface declaration of the supplied class CHAIN to the
8122 supplied file FP. Used to implement the -gen-decls option (which
8123 prints out an @interface declaration of all classes compiled in
8124 this run); potentially useful for debugging the compiler too. */
8125 static void
8126 dump_interface (fp, chain)
8127 FILE *fp;
8128 tree chain;
8130 /* FIXME: A heap overflow here whenever a method (or ivar)
8131 declaration is so long that it doesn't fit in the buffer. The
8132 code and all the related functions should be rewritten to avoid
8133 using fixed size buffers. */
8134 char *buf = (char *) xmalloc (1024 * 10);
8135 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8136 tree ivar_decls = CLASS_RAW_IVARS (chain);
8137 tree nst_methods = CLASS_NST_METHODS (chain);
8138 tree cls_methods = CLASS_CLS_METHODS (chain);
8140 fprintf (fp, "\n@interface %s", my_name);
8142 /* CLASS_SUPER_NAME is used to store the superclass name for
8143 classes, and the category name for categories. */
8144 if (CLASS_SUPER_NAME (chain))
8146 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8148 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8149 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8151 fprintf (fp, " (%s)\n", name);
8153 else
8155 fprintf (fp, " : %s\n", name);
8158 else
8159 fprintf (fp, "\n");
8161 /* FIXME - the following doesn't seem to work at the moment. */
8162 if (ivar_decls)
8164 fprintf (fp, "{\n");
8167 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8168 ivar_decls = TREE_CHAIN (ivar_decls);
8170 while (ivar_decls);
8171 fprintf (fp, "}\n");
8174 while (nst_methods)
8176 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8177 nst_methods = TREE_CHAIN (nst_methods);
8180 while (cls_methods)
8182 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8183 cls_methods = TREE_CHAIN (cls_methods);
8186 fprintf (fp, "@end\n");
8189 /* Demangle function for Objective-C */
8190 static const char *
8191 objc_demangle (mangled)
8192 const char *mangled;
8194 char *demangled, *cp;
8196 if (mangled[0] == '_' &&
8197 (mangled[1] == 'i' || mangled[1] == 'c') &&
8198 mangled[2] == '_')
8200 cp = demangled = xmalloc(strlen(mangled) + 2);
8201 if (mangled[1] == 'i')
8202 *cp++ = '-'; /* for instance method */
8203 else
8204 *cp++ = '+'; /* for class method */
8205 *cp++ = '['; /* opening left brace */
8206 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8207 while (*cp && *cp == '_')
8208 cp++; /* skip any initial underbars in class name */
8209 cp = strchr(cp, '_'); /* find first non-initial underbar */
8210 if (cp == NULL)
8212 free(demangled); /* not mangled name */
8213 return mangled;
8215 if (cp[1] == '_') /* easy case: no category name */
8217 *cp++ = ' '; /* replace two '_' with one ' ' */
8218 strcpy(cp, mangled + (cp - demangled) + 2);
8220 else
8222 *cp++ = '('; /* less easy case: category name */
8223 cp = strchr(cp, '_');
8224 if (cp == 0)
8226 free(demangled); /* not mangled name */
8227 return mangled;
8229 *cp++ = ')';
8230 *cp++ = ' '; /* overwriting 1st char of method name... */
8231 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8233 while (*cp && *cp == '_')
8234 cp++; /* skip any initial underbars in method name */
8235 for (; *cp; cp++)
8236 if (*cp == '_')
8237 *cp = ':'; /* replace remaining '_' with ':' */
8238 *cp++ = ']'; /* closing right brace */
8239 *cp++ = 0; /* string terminator */
8240 return demangled;
8242 else
8243 return mangled; /* not an objc mangled name */
8246 const char *
8247 objc_printable_name (decl, kind)
8248 tree decl;
8249 int kind ATTRIBUTE_UNUSED;
8251 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8254 static void
8255 init_objc ()
8257 gcc_obstack_init (&util_obstack);
8258 util_firstobj = (char *) obstack_finish (&util_obstack);
8260 errbuf = (char *) xmalloc (BUFSIZE);
8261 hash_init ();
8262 synth_module_prologue ();
8265 static void
8266 finish_objc ()
8268 struct imp_entry *impent;
8269 tree chain;
8270 /* The internally generated initializers appear to have missing braces.
8271 Don't warn about this. */
8272 int save_warn_missing_braces = warn_missing_braces;
8273 warn_missing_braces = 0;
8275 /* A missing @end may not be detected by the parser. */
8276 if (objc_implementation_context)
8278 warning ("`@end' missing in implementation context");
8279 finish_class (objc_implementation_context);
8280 objc_ivar_chain = NULL_TREE;
8281 objc_implementation_context = NULL_TREE;
8284 generate_forward_declaration_to_string_table ();
8286 #ifdef OBJC_PROLOGUE
8287 OBJC_PROLOGUE;
8288 #endif
8290 /* Process the static instances here because initialization of objc_symtab
8291 depends on them. */
8292 if (objc_static_instances)
8293 generate_static_references ();
8295 if (imp_list || class_names_chain
8296 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8297 generate_objc_symtab_decl ();
8299 for (impent = imp_list; impent; impent = impent->next)
8301 objc_implementation_context = impent->imp_context;
8302 implementation_template = impent->imp_template;
8304 UOBJC_CLASS_decl = impent->class_decl;
8305 UOBJC_METACLASS_decl = impent->meta_decl;
8307 /* Dump the @interface of each class as we compile it, if the
8308 -gen-decls option is in use. TODO: Dump the classes in the
8309 order they were found, rather than in reverse order as we
8310 are doing now. */
8311 if (flag_gen_declaration)
8313 dump_interface (gen_declaration_file, objc_implementation_context);
8316 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8318 /* all of the following reference the string pool... */
8319 generate_ivar_lists ();
8320 generate_dispatch_tables ();
8321 generate_shared_structures ();
8323 else
8325 generate_dispatch_tables ();
8326 generate_category (objc_implementation_context);
8330 /* If we are using an array of selectors, we must always
8331 finish up the array decl even if no selectors were used. */
8332 if (! flag_next_runtime || sel_ref_chain)
8333 build_selector_translation_table ();
8335 if (protocol_chain)
8336 generate_protocols ();
8338 if (objc_implementation_context || class_names_chain || objc_static_instances
8339 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8341 /* Arrange for ObjC data structures to be initialized at run time. */
8342 rtx init_sym = build_module_descriptor ();
8343 if (init_sym && targetm.have_ctors_dtors)
8344 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8347 /* Dump the class references. This forces the appropriate classes
8348 to be linked into the executable image, preserving unix archive
8349 semantics. This can be removed when we move to a more dynamically
8350 linked environment. */
8352 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8354 handle_class_ref (chain);
8355 if (TREE_PURPOSE (chain))
8356 generate_classref_translation_entry (chain);
8359 for (impent = imp_list; impent; impent = impent->next)
8360 handle_impent (impent);
8362 /* Dump the string table last. */
8364 generate_strings ();
8366 if (warn_selector)
8368 int slot;
8369 hash hsh;
8371 /* Run through the selector hash tables and print a warning for any
8372 selector which has multiple methods. */
8374 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8375 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8376 if (hsh->list)
8378 tree meth = hsh->key;
8379 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8380 ? '-' : '+');
8381 attr loop;
8383 warning ("potential selector conflict for method `%s'",
8384 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8385 warn_with_method ("found", type, meth);
8386 for (loop = hsh->list; loop; loop = loop->next)
8387 warn_with_method ("found", type, loop->value);
8390 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8391 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8392 if (hsh->list)
8394 tree meth = hsh->key;
8395 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8396 ? '-' : '+');
8397 attr loop;
8399 warning ("potential selector conflict for method `%s'",
8400 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8401 warn_with_method ("found", type, meth);
8402 for (loop = hsh->list; loop; loop = loop->next)
8403 warn_with_method ("found", type, loop->value);
8407 warn_missing_braces = save_warn_missing_braces;
8410 /* Subroutines of finish_objc. */
8412 static void
8413 generate_classref_translation_entry (chain)
8414 tree chain;
8416 tree expr, name, decl_specs, decl, sc_spec;
8417 tree type;
8419 type = TREE_TYPE (TREE_PURPOSE (chain));
8421 expr = add_objc_string (TREE_VALUE (chain), class_names);
8422 expr = build_c_cast (type, expr); /* cast! */
8424 name = DECL_NAME (TREE_PURPOSE (chain));
8426 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8428 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8429 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8431 /* The decl that is returned from start_decl is the one that we
8432 forward declared in build_class_reference. */
8433 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8434 DECL_CONTEXT (decl) = NULL_TREE;
8435 finish_decl (decl, expr, NULL_TREE);
8436 return;
8439 static void
8440 handle_class_ref (chain)
8441 tree chain;
8443 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8444 char *string = (char *) alloca (strlen (name) + 30);
8445 tree decl;
8446 tree exp;
8448 sprintf (string, "%sobjc_class_name_%s",
8449 (flag_next_runtime ? "." : "__"), name);
8451 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8452 if (flag_next_runtime)
8454 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8455 return;
8457 #endif
8459 /* Make a decl for this name, so we can use its address in a tree. */
8460 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8461 DECL_EXTERNAL (decl) = 1;
8462 TREE_PUBLIC (decl) = 1;
8464 pushdecl (decl);
8465 rest_of_decl_compilation (decl, 0, 0, 0);
8467 /* Make a decl for the address. */
8468 sprintf (string, "%sobjc_class_ref_%s",
8469 (flag_next_runtime ? "." : "__"), name);
8470 exp = build1 (ADDR_EXPR, string_type_node, decl);
8471 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8472 DECL_INITIAL (decl) = exp;
8473 TREE_STATIC (decl) = 1;
8474 TREE_USED (decl) = 1;
8476 pushdecl (decl);
8477 rest_of_decl_compilation (decl, 0, 0, 0);
8480 static void
8481 handle_impent (impent)
8482 struct imp_entry *impent;
8484 char *string;
8486 objc_implementation_context = impent->imp_context;
8487 implementation_template = impent->imp_template;
8489 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8491 const char *const class_name =
8492 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8494 string = (char *) alloca (strlen (class_name) + 30);
8496 sprintf (string, "%sobjc_class_name_%s",
8497 (flag_next_runtime ? "." : "__"), class_name);
8499 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8501 const char *const class_name =
8502 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8503 const char *const class_super_name =
8504 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8506 string = (char *) alloca (strlen (class_name)
8507 + strlen (class_super_name) + 30);
8509 /* Do the same for categories. Even though no references to
8510 these symbols are generated automatically by the compiler, it
8511 gives you a handle to pull them into an archive by hand. */
8512 sprintf (string, "*%sobjc_category_name_%s_%s",
8513 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8515 else
8516 return;
8518 #ifdef ASM_DECLARE_CLASS_REFERENCE
8519 if (flag_next_runtime)
8521 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8522 return;
8524 else
8525 #endif
8527 tree decl, init;
8529 init = build_int_2 (0, 0);
8530 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8531 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8532 TREE_PUBLIC (decl) = 1;
8533 TREE_READONLY (decl) = 1;
8534 TREE_USED (decl) = 1;
8535 TREE_CONSTANT (decl) = 1;
8536 DECL_CONTEXT (decl) = 0;
8537 DECL_ARTIFICIAL (decl) = 1;
8538 DECL_INITIAL (decl) = init;
8539 assemble_variable (decl, 1, 0, 0);
8543 /* Look up ID as an instance variable. */
8544 tree
8545 lookup_objc_ivar (id)
8546 tree id;
8548 tree decl;
8550 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8551 /* We have a message to super. */
8552 return get_super_receiver ();
8553 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8555 if (is_private (decl))
8556 return error_mark_node;
8557 else
8558 return build_ivar_reference (id);
8560 else
8561 return 0;
8564 #include "gtype-objc.h"