* cpplib.h (CPP_AT_NAME, CPP_OBJC_STRING): New token types.
[official-gcc.git] / gcc / objc / objc-act.c
blob3d78b099941b42069c07021fbe1bc77ea4a41462
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 objc_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 objc_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 bool
436 objc_init ()
438 if (c_objc_common_init () == false)
439 return false;
441 /* Force the line number back to 0; check_newline will have
442 raised it to 1, which will make the builtin functions appear
443 not to be built in. */
444 input_line = 0;
446 /* If gen_declaration desired, open the output file. */
447 if (flag_gen_declaration)
449 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
450 gen_declaration_file = fopen (dumpname, "w");
451 if (gen_declaration_file == 0)
452 fatal_error ("can't open %s: %m", dumpname);
453 free (dumpname);
456 if (flag_next_runtime)
458 TAG_GETCLASS = "objc_getClass";
459 TAG_GETMETACLASS = "objc_getMetaClass";
460 TAG_MSGSEND = "objc_msgSend";
461 TAG_MSGSENDSUPER = "objc_msgSendSuper";
462 TAG_EXECCLASS = "__objc_execClass";
463 default_constant_string_class_name = "NSConstantString";
465 else
467 TAG_GETCLASS = "objc_get_class";
468 TAG_GETMETACLASS = "objc_get_meta_class";
469 TAG_MSGSEND = "objc_msg_lookup";
470 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
471 TAG_EXECCLASS = "__objc_exec_class";
472 default_constant_string_class_name = "NXConstantString";
473 flag_typed_selectors = 1;
476 objc_ellipsis_node = make_node (ERROR_MARK);
478 init_objc ();
480 if (print_struct_values)
481 generate_struct_by_value_array ();
483 return true;
486 void
487 finish_file ()
489 mark_referenced_methods ();
490 c_objc_common_finish_file ();
492 /* Finalize Objective-C runtime data. No need to generate tables
493 and code if only checking syntax. */
494 if (!flag_syntax_only)
495 finish_objc ();
497 if (gen_declaration_file)
498 fclose (gen_declaration_file);
501 static tree
502 define_decl (declarator, declspecs)
503 tree declarator;
504 tree declspecs;
506 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
507 finish_decl (decl, NULL_TREE, NULL_TREE);
508 return decl;
511 /* Return 1 if LHS and RHS are compatible types for assignment or
512 various other operations. Return 0 if they are incompatible, and
513 return -1 if we choose to not decide. When the operation is
514 REFLEXIVE, check for compatibility in either direction.
516 For statically typed objects, an assignment of the form `a' = `b'
517 is permitted if:
519 `a' is of type "id",
520 `a' and `b' are the same class type, or
521 `a' and `b' are of class types A and B such that B is a descendant of A. */
523 static tree
524 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
525 tree rproto_list;
526 tree sel_name;
527 int class_meth;
529 tree rproto, p;
530 tree fnd = 0;
532 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
534 p = TREE_VALUE (rproto);
536 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
538 if ((fnd = lookup_method (class_meth
539 ? PROTOCOL_CLS_METHODS (p)
540 : PROTOCOL_NST_METHODS (p), sel_name)))
542 else if (PROTOCOL_LIST (p))
543 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
544 sel_name, class_meth);
546 else
548 ; /* An identifier...if we could not find a protocol. */
551 if (fnd)
552 return fnd;
555 return 0;
558 static tree
559 lookup_protocol_in_reflist (rproto_list, lproto)
560 tree rproto_list;
561 tree lproto;
563 tree rproto, p;
565 /* Make sure the protocol is supported by the object on the rhs. */
566 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
568 tree fnd = 0;
569 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
571 p = TREE_VALUE (rproto);
573 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
575 if (lproto == p)
576 fnd = lproto;
578 else if (PROTOCOL_LIST (p))
579 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
582 if (fnd)
583 return fnd;
586 else
588 ; /* An identifier...if we could not find a protocol. */
591 return 0;
594 /* Return 1 if LHS and RHS are compatible types for assignment or
595 various other operations. Return 0 if they are incompatible, and
596 return -1 if we choose to not decide (because the types are really
597 just C types, not ObjC specific ones). When the operation is
598 REFLEXIVE (typically comparisons), check for compatibility in
599 either direction; when it's not (typically assignments), don't.
601 This function is called in two cases: when both lhs and rhs are
602 pointers to records (in which case we check protocols too), and
603 when both lhs and rhs are records (in which case we check class
604 inheritance only).
606 Warnings about classes/protocols not implementing a protocol are
607 emitted here (multiple of those warnings might be emitted for a
608 single line!); generic warnings about incompatible assignments and
609 lacks of casts in comparisons are/must be emitted by the caller if
610 we return 0.
614 objc_comptypes (lhs, rhs, reflexive)
615 tree lhs;
616 tree rhs;
617 int reflexive;
619 /* New clause for protocols. */
621 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
622 manage the ObjC ones, and leave the rest to the C code. */
623 if (TREE_CODE (lhs) == POINTER_TYPE
624 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
625 && TREE_CODE (rhs) == POINTER_TYPE
626 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
628 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
629 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
631 if (lhs_is_proto)
633 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
634 tree rproto, rproto_list;
635 tree p;
637 /* <Protocol> = <Protocol> */
638 if (rhs_is_proto)
640 rproto_list = TYPE_PROTOCOL_LIST (rhs);
642 if (!reflexive)
644 /* An assignment between objects of type 'id
645 <Protocol>'; make sure the protocol on the lhs is
646 supported by the object on the rhs. */
647 for (lproto = lproto_list; lproto;
648 lproto = TREE_CHAIN (lproto))
650 p = TREE_VALUE (lproto);
651 rproto = lookup_protocol_in_reflist (rproto_list, p);
653 if (!rproto)
654 warning
655 ("object does not conform to the `%s' protocol",
656 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
658 return 1;
660 else
662 /* Obscure case - a comparison between two objects
663 of type 'id <Protocol>'. Check that either the
664 protocol on the lhs is supported by the object on
665 the rhs, or viceversa. */
667 /* Check if the protocol on the lhs is supported by the
668 object on the rhs. */
669 for (lproto = lproto_list; lproto;
670 lproto = TREE_CHAIN (lproto))
672 p = TREE_VALUE (lproto);
673 rproto = lookup_protocol_in_reflist (rproto_list, p);
675 if (!rproto)
677 /* Check failed - check if the protocol on the rhs
678 is supported by the object on the lhs. */
679 for (rproto = rproto_list; rproto;
680 rproto = TREE_CHAIN (rproto))
682 p = TREE_VALUE (rproto);
683 lproto = lookup_protocol_in_reflist (lproto_list,
686 if (!lproto)
688 /* This check failed too: incompatible */
689 return 0;
692 return 1;
695 return 1;
698 /* <Protocol> = <class> * */
699 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
701 tree rname = TYPE_NAME (TREE_TYPE (rhs));
702 tree rinter;
704 /* Make sure the protocol is supported by the object on
705 the rhs. */
706 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
708 p = TREE_VALUE (lproto);
709 rproto = 0;
710 rinter = lookup_interface (rname);
712 while (rinter && !rproto)
714 tree cat;
716 rproto_list = CLASS_PROTOCOL_LIST (rinter);
717 rproto = lookup_protocol_in_reflist (rproto_list, p);
718 /* If the underlying ObjC class does not have
719 the protocol we're looking for, check for "one-off"
720 protocols (e.g., `NSObject<MyProt> *foo;') attached
721 to the rhs. */
722 if (!rproto)
724 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
725 rproto = lookup_protocol_in_reflist (rproto_list, p);
728 /* Check for protocols adopted by categories. */
729 cat = CLASS_CATEGORY_LIST (rinter);
730 while (cat && !rproto)
732 rproto_list = CLASS_PROTOCOL_LIST (cat);
733 rproto = lookup_protocol_in_reflist (rproto_list, p);
734 cat = CLASS_CATEGORY_LIST (cat);
737 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
740 if (!rproto)
741 warning ("class `%s' does not implement the `%s' protocol",
742 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
743 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
745 return 1;
747 /* <Protocol> = id */
748 else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
750 return 1;
752 /* <Protocol> = Class */
753 else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
755 return 0;
757 /* <Protocol> = ?? : let comptypes decide. */
758 return -1;
760 else if (rhs_is_proto)
762 /* <class> * = <Protocol> */
763 if (TYPED_OBJECT (TREE_TYPE (lhs)))
765 if (reflexive)
767 tree rname = TYPE_NAME (TREE_TYPE (lhs));
768 tree rinter;
769 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
771 /* Make sure the protocol is supported by the object on
772 the lhs. */
773 for (rproto = rproto_list; rproto;
774 rproto = TREE_CHAIN (rproto))
776 tree p = TREE_VALUE (rproto);
777 tree lproto = 0;
778 rinter = lookup_interface (rname);
780 while (rinter && !lproto)
782 tree cat;
784 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
785 lproto = lookup_protocol_in_reflist (lproto_list, p);
786 /* If the underlying ObjC class does not
787 have the protocol we're looking for,
788 check for "one-off" protocols (e.g.,
789 `NSObject<MyProt> *foo;') attached to the
790 lhs. */
791 if (!lproto)
793 lproto_list = TYPE_PROTOCOL_LIST
794 (TREE_TYPE (lhs));
795 lproto = lookup_protocol_in_reflist
796 (lproto_list, p);
799 /* Check for protocols adopted by categories. */
800 cat = CLASS_CATEGORY_LIST (rinter);
801 while (cat && !lproto)
803 lproto_list = CLASS_PROTOCOL_LIST (cat);
804 lproto = lookup_protocol_in_reflist (lproto_list,
806 cat = CLASS_CATEGORY_LIST (cat);
809 rinter = lookup_interface (CLASS_SUPER_NAME
810 (rinter));
813 if (!lproto)
814 warning ("class `%s' does not implement the `%s' protocol",
815 IDENTIFIER_POINTER (TYPE_NAME
816 (TREE_TYPE (lhs))),
817 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
819 return 1;
821 else
822 return 0;
824 /* id = <Protocol> */
825 else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
827 return 1;
829 /* Class = <Protocol> */
830 else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
832 return 0;
834 /* ??? = <Protocol> : let comptypes decide */
835 else
837 return -1;
840 else
842 /* Attention: we shouldn't defer to comptypes here. One bad
843 side effect would be that we might loose the REFLEXIVE
844 information.
846 lhs = TREE_TYPE (lhs);
847 rhs = TREE_TYPE (rhs);
851 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
853 /* Nothing to do with ObjC - let immediately comptypes take
854 responsibility for checking. */
855 return -1;
858 /* `id' = `<class> *' `<class> *' = `id': always allow it.
859 Please note that
860 'Object *o = [[Object alloc] init]; falls
861 in the case <class> * = `id'.
863 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
864 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
865 return 1;
867 /* `id' = `Class', `Class' = `id' */
869 else if ((TYPE_NAME (lhs) == objc_object_id
870 && TYPE_NAME (rhs) == objc_class_id)
871 || (TYPE_NAME (lhs) == objc_class_id
872 && TYPE_NAME (rhs) == objc_object_id))
873 return 1;
875 /* `<class> *' = `<class> *' */
877 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
879 tree lname = TYPE_NAME (lhs);
880 tree rname = TYPE_NAME (rhs);
881 tree inter;
883 if (lname == rname)
884 return 1;
886 /* If the left hand side is a super class of the right hand side,
887 allow it. */
888 for (inter = lookup_interface (rname); inter;
889 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
890 if (lname == CLASS_SUPER_NAME (inter))
891 return 1;
893 /* Allow the reverse when reflexive. */
894 if (reflexive)
895 for (inter = lookup_interface (lname); inter;
896 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
897 if (rname == CLASS_SUPER_NAME (inter))
898 return 1;
900 return 0;
902 else
903 /* Not an ObjC type - let comptypes do the check. */
904 return -1;
907 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
909 void
910 objc_check_decl (decl)
911 tree decl;
913 tree type = TREE_TYPE (decl);
915 if (TREE_CODE (type) == RECORD_TYPE
916 && TREE_STATIC_TEMPLATE (type)
917 && type != constant_string_type)
918 error_with_decl (decl, "`%s' cannot be statically allocated");
921 /* Implement static typing. At this point, we know we have an interface. */
923 tree
924 get_static_reference (interface, protocols)
925 tree interface;
926 tree protocols;
928 tree type = xref_tag (RECORD_TYPE, interface);
930 if (protocols)
932 tree t, m = TYPE_MAIN_VARIANT (type);
934 t = copy_node (type);
936 /* Add this type to the chain of variants of TYPE. */
937 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
938 TYPE_NEXT_VARIANT (m) = t;
940 /* Look up protocols and install in lang specific list. Note
941 that the protocol list can have a different lifetime than T! */
942 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
944 /* This forces a new pointer type to be created later
945 (in build_pointer_type)...so that the new template
946 we just created will actually be used...what a hack! */
947 if (TYPE_POINTER_TO (t))
948 TYPE_POINTER_TO (t) = NULL_TREE;
950 type = t;
953 return type;
956 tree
957 get_object_reference (protocols)
958 tree protocols;
960 tree type_decl = lookup_name (objc_id_id);
961 tree type;
963 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
965 type = TREE_TYPE (type_decl);
966 if (TYPE_MAIN_VARIANT (type) != id_type)
967 warning ("unexpected type for `id' (%s)",
968 gen_declaration (type, errbuf));
970 else
972 error ("undefined type `id', please import <objc/objc.h>");
973 return error_mark_node;
976 /* This clause creates a new pointer type that is qualified with
977 the protocol specification...this info is used later to do more
978 elaborate type checking. */
980 if (protocols)
982 tree t, m = TYPE_MAIN_VARIANT (type);
984 t = copy_node (type);
986 /* Add this type to the chain of variants of TYPE. */
987 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
988 TYPE_NEXT_VARIANT (m) = t;
990 /* Look up protocols...and install in lang specific list */
991 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
993 /* This forces a new pointer type to be created later
994 (in build_pointer_type)...so that the new template
995 we just created will actually be used...what a hack! */
996 if (TYPE_POINTER_TO (t))
997 TYPE_POINTER_TO (t) = NULL_TREE;
999 type = t;
1001 return type;
1004 /* Check for circular dependencies in protocols. The arguments are
1005 PROTO, the protocol to check, and LIST, a list of protocol it
1006 conforms to. */
1008 static void
1009 check_protocol_recursively (proto, list)
1010 tree proto;
1011 tree list;
1013 tree p;
1015 for (p = list; p; p = TREE_CHAIN (p))
1017 tree pp = TREE_VALUE (p);
1019 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1020 pp = lookup_protocol (pp);
1022 if (pp == proto)
1023 fatal_error ("protocol `%s' has circular dependency",
1024 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1025 if (pp)
1026 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1030 static tree
1031 lookup_and_install_protocols (protocols)
1032 tree protocols;
1034 tree proto;
1035 tree prev = NULL;
1036 tree return_value = protocols;
1038 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1040 tree ident = TREE_VALUE (proto);
1041 tree p = lookup_protocol (ident);
1043 if (!p)
1045 error ("cannot find protocol declaration for `%s'",
1046 IDENTIFIER_POINTER (ident));
1047 if (prev)
1048 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1049 else
1050 return_value = TREE_CHAIN (proto);
1052 else
1054 /* Replace identifier with actual protocol node. */
1055 TREE_VALUE (proto) = p;
1056 prev = proto;
1060 return return_value;
1063 /* Create and push a decl for a built-in external variable or field NAME.
1064 CODE says which.
1065 TYPE is its data type. */
1067 static tree
1068 create_builtin_decl (code, type, name)
1069 enum tree_code code;
1070 tree type;
1071 const char *name;
1073 tree decl = build_decl (code, get_identifier (name), type);
1075 if (code == VAR_DECL)
1077 TREE_STATIC (decl) = 1;
1078 make_decl_rtl (decl, 0);
1079 pushdecl (decl);
1082 DECL_ARTIFICIAL (decl) = 1;
1083 return decl;
1086 /* Find the decl for the constant string class. */
1088 static void
1089 setup_string_decl ()
1091 if (!string_class_decl)
1093 if (!constant_string_global_id)
1094 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1095 string_class_decl = lookup_name (constant_string_global_id);
1099 /* Purpose: "play" parser, creating/installing representations
1100 of the declarations that are required by Objective-C.
1102 Model:
1104 type_spec--------->sc_spec
1105 (tree_list) (tree_list)
1108 identifier_node identifier_node */
1110 static void
1111 synth_module_prologue ()
1113 tree temp_type;
1114 tree super_p;
1116 /* Defined in `objc.h' */
1117 objc_object_id = get_identifier (TAG_OBJECT);
1119 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1121 id_type = build_pointer_type (objc_object_reference);
1123 objc_id_id = get_identifier (TYPE_ID);
1124 objc_class_id = get_identifier (TAG_CLASS);
1126 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1127 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1128 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1130 /* Declare type of selector-objects that represent an operation name. */
1132 /* `struct objc_selector *' */
1133 selector_type
1134 = build_pointer_type (xref_tag (RECORD_TYPE,
1135 get_identifier (TAG_SELECTOR)));
1137 /* Forward declare type, or else the prototype for msgSendSuper will
1138 complain. */
1140 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1141 get_identifier (TAG_SUPER)));
1144 /* id objc_msgSend (id, SEL, ...); */
1146 temp_type
1147 = build_function_type (id_type,
1148 tree_cons (NULL_TREE, id_type,
1149 tree_cons (NULL_TREE, selector_type,
1150 NULL_TREE)));
1152 if (! flag_next_runtime)
1154 umsg_decl = build_decl (FUNCTION_DECL,
1155 get_identifier (TAG_MSGSEND), temp_type);
1156 DECL_EXTERNAL (umsg_decl) = 1;
1157 TREE_PUBLIC (umsg_decl) = 1;
1158 DECL_INLINE (umsg_decl) = 1;
1159 DECL_ARTIFICIAL (umsg_decl) = 1;
1161 make_decl_rtl (umsg_decl, NULL);
1162 pushdecl (umsg_decl);
1164 else
1165 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
1166 NULL, NULL_TREE);
1168 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1170 temp_type
1171 = build_function_type (id_type,
1172 tree_cons (NULL_TREE, super_p,
1173 tree_cons (NULL_TREE, selector_type,
1174 NULL_TREE)));
1176 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1177 temp_type, 0, NOT_BUILT_IN,
1178 NULL, NULL_TREE);
1180 /* id objc_getClass (const char *); */
1182 temp_type = build_function_type (id_type,
1183 tree_cons (NULL_TREE,
1184 const_string_type_node,
1185 tree_cons (NULL_TREE, void_type_node,
1186 NULL_TREE)));
1188 objc_get_class_decl
1189 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1190 NULL, NULL_TREE);
1192 /* id objc_getMetaClass (const char *); */
1194 objc_get_meta_class_decl
1195 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
1196 NULL, NULL_TREE);
1198 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1200 if (! flag_next_runtime)
1202 if (flag_typed_selectors)
1204 /* Suppress outputting debug symbols, because
1205 dbxout_init hasn'r been called yet. */
1206 enum debug_info_type save_write_symbols = write_symbols;
1207 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1208 write_symbols = NO_DEBUG;
1209 debug_hooks = &do_nothing_debug_hooks;
1211 build_selector_template ();
1212 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1214 write_symbols = save_write_symbols;
1215 debug_hooks = save_hooks;
1217 else
1218 temp_type = build_array_type (selector_type, NULL_TREE);
1220 layout_type (temp_type);
1221 UOBJC_SELECTOR_TABLE_decl
1222 = create_builtin_decl (VAR_DECL, temp_type,
1223 "_OBJC_SELECTOR_TABLE");
1225 /* Avoid warning when not sending messages. */
1226 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1229 generate_forward_declaration_to_string_table ();
1231 /* Forward declare constant_string_id and constant_string_type. */
1232 if (!constant_string_class_name)
1233 constant_string_class_name = default_constant_string_class_name;
1235 constant_string_id = get_identifier (constant_string_class_name);
1236 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1239 /* Predefine the following data type:
1241 struct STRING_OBJECT_CLASS_NAME
1243 Object isa;
1244 char *cString;
1245 unsigned int length;
1246 }; */
1248 static void
1249 build_string_class_template ()
1251 tree field_decl, field_decl_chain;
1253 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1254 field_decl_chain = field_decl;
1256 field_decl = create_builtin_decl (FIELD_DECL,
1257 build_pointer_type (char_type_node),
1258 "cString");
1259 chainon (field_decl_chain, field_decl);
1261 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1262 chainon (field_decl_chain, field_decl);
1264 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1267 /* Custom build_string which sets TREE_TYPE! */
1269 static tree
1270 my_build_string (len, str)
1271 int len;
1272 const char *str;
1274 return fix_string_type (build_string (len, str));
1277 /* Build a static instance of NXConstantString which points at the
1278 string constant STRING.
1279 We place the string object in the __string_objects section of the
1280 __OBJC segment. The Objective-C runtime will initialize the isa
1281 pointers of the string objects to point at the NXConstantString
1282 class object. */
1284 tree
1285 build_objc_string_object (string)
1286 tree string;
1288 tree initlist, constructor;
1289 int length;
1291 if (lookup_interface (constant_string_id) == NULL_TREE)
1293 error ("cannot find interface declaration for `%s'",
1294 IDENTIFIER_POINTER (constant_string_id));
1295 return error_mark_node;
1298 add_class_reference (constant_string_id);
1300 length = TREE_STRING_LENGTH (string) - 1;
1302 /* We could not properly create NXConstantString in synth_module_prologue,
1303 because that's called before debugging is initialized. Do it now. */
1304 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1305 build_string_class_template ();
1307 /* & ((NXConstantString) { NULL, string, length }) */
1309 if (flag_next_runtime)
1311 /* For the NeXT runtime, we can generate a literal reference
1312 to the string class, don't need to run a constructor. */
1313 setup_string_decl ();
1314 if (string_class_decl == NULL_TREE)
1316 error ("cannot find reference tag for class `%s'",
1317 IDENTIFIER_POINTER (constant_string_id));
1318 return error_mark_node;
1320 initlist = build_tree_list
1321 (NULL_TREE,
1322 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1324 else
1326 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1329 initlist
1330 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1331 initlist);
1332 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1333 constructor = objc_build_constructor (constant_string_type,
1334 nreverse (initlist));
1336 if (!flag_next_runtime)
1338 constructor
1339 = objc_add_static_instance (constructor, constant_string_type);
1342 return (build_unary_op (ADDR_EXPR, constructor, 1));
1345 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1347 static GTY(()) int num_static_inst;
1348 static tree
1349 objc_add_static_instance (constructor, class_decl)
1350 tree constructor, class_decl;
1352 tree *chain, decl;
1353 char buf[256];
1355 /* Find the list of static instances for the CLASS_DECL. Create one if
1356 not found. */
1357 for (chain = &objc_static_instances;
1358 *chain && TREE_VALUE (*chain) != class_decl;
1359 chain = &TREE_CHAIN (*chain));
1360 if (!*chain)
1362 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1363 add_objc_string (TYPE_NAME (class_decl), class_names);
1366 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1367 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1368 DECL_COMMON (decl) = 1;
1369 TREE_STATIC (decl) = 1;
1370 DECL_ARTIFICIAL (decl) = 1;
1371 DECL_INITIAL (decl) = constructor;
1373 /* We may be writing something else just now.
1374 Postpone till end of input. */
1375 DECL_DEFER_OUTPUT (decl) = 1;
1376 pushdecl_top_level (decl);
1377 rest_of_decl_compilation (decl, 0, 1, 0);
1379 /* Add the DECL to the head of this CLASS' list. */
1380 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1382 return decl;
1385 /* Build a static constant CONSTRUCTOR
1386 with type TYPE and elements ELTS. */
1388 static tree
1389 objc_build_constructor (type, elts)
1390 tree type, elts;
1392 tree constructor, f, e;
1394 /* ??? Most of the places that we build constructors, we don't fill in
1395 the type of integers properly. Convert them all en masse. */
1396 if (TREE_CODE (type) == ARRAY_TYPE)
1398 f = TREE_TYPE (type);
1399 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1400 for (e = elts; e ; e = TREE_CHAIN (e))
1401 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1403 else
1405 f = TYPE_FIELDS (type);
1406 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1407 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1408 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1409 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1412 constructor = build_constructor (type, elts);
1413 TREE_CONSTANT (constructor) = 1;
1414 TREE_STATIC (constructor) = 1;
1415 TREE_READONLY (constructor) = 1;
1417 return constructor;
1420 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1422 /* Predefine the following data type:
1424 struct _objc_symtab
1426 long sel_ref_cnt;
1427 SEL *refs;
1428 short cls_def_cnt;
1429 short cat_def_cnt;
1430 void *defs[cls_def_cnt + cat_def_cnt];
1431 }; */
1433 static void
1434 build_objc_symtab_template ()
1436 tree field_decl, field_decl_chain, index;
1438 objc_symtab_template
1439 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1441 /* long sel_ref_cnt; */
1443 field_decl = create_builtin_decl (FIELD_DECL,
1444 long_integer_type_node,
1445 "sel_ref_cnt");
1446 field_decl_chain = field_decl;
1448 /* SEL *refs; */
1450 field_decl = create_builtin_decl (FIELD_DECL,
1451 build_pointer_type (selector_type),
1452 "refs");
1453 chainon (field_decl_chain, field_decl);
1455 /* short cls_def_cnt; */
1457 field_decl = create_builtin_decl (FIELD_DECL,
1458 short_integer_type_node,
1459 "cls_def_cnt");
1460 chainon (field_decl_chain, field_decl);
1462 /* short cat_def_cnt; */
1464 field_decl = create_builtin_decl (FIELD_DECL,
1465 short_integer_type_node,
1466 "cat_def_cnt");
1467 chainon (field_decl_chain, field_decl);
1469 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1471 if (!flag_next_runtime)
1472 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1473 else
1474 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1475 imp_count == 0 && cat_count == 0
1476 ? -1 : 0));
1477 field_decl = create_builtin_decl (FIELD_DECL,
1478 build_array_type (ptr_type_node, index),
1479 "defs");
1480 chainon (field_decl_chain, field_decl);
1482 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1485 /* Create the initial value for the `defs' field of _objc_symtab.
1486 This is a CONSTRUCTOR. */
1488 static tree
1489 init_def_list (type)
1490 tree type;
1492 tree expr, initlist = NULL_TREE;
1493 struct imp_entry *impent;
1495 if (imp_count)
1496 for (impent = imp_list; impent; impent = impent->next)
1498 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1500 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1501 initlist = tree_cons (NULL_TREE, expr, initlist);
1505 if (cat_count)
1506 for (impent = imp_list; impent; impent = impent->next)
1508 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1510 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1511 initlist = tree_cons (NULL_TREE, expr, initlist);
1515 if (!flag_next_runtime)
1517 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1518 tree expr;
1520 if (static_instances_decl)
1521 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1522 else
1523 expr = build_int_2 (0, 0);
1525 initlist = tree_cons (NULL_TREE, expr, initlist);
1528 return objc_build_constructor (type, nreverse (initlist));
1531 /* Construct the initial value for all of _objc_symtab. */
1533 static tree
1534 init_objc_symtab (type)
1535 tree type;
1537 tree initlist;
1539 /* sel_ref_cnt = { ..., 5, ... } */
1541 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1543 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1545 if (flag_next_runtime || ! sel_ref_chain)
1546 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1547 else
1548 initlist = tree_cons (NULL_TREE,
1549 build_unary_op (ADDR_EXPR,
1550 UOBJC_SELECTOR_TABLE_decl, 1),
1551 initlist);
1553 /* cls_def_cnt = { ..., 5, ... } */
1555 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1557 /* cat_def_cnt = { ..., 5, ... } */
1559 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1561 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1563 if (imp_count || cat_count || static_instances_decl)
1566 tree field = TYPE_FIELDS (type);
1567 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1569 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1570 initlist);
1573 return objc_build_constructor (type, nreverse (initlist));
1576 /* Push forward-declarations of all the categories so that
1577 init_def_list can use them in a CONSTRUCTOR. */
1579 static void
1580 forward_declare_categories ()
1582 struct imp_entry *impent;
1583 tree sav = objc_implementation_context;
1585 for (impent = imp_list; impent; impent = impent->next)
1587 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1589 /* Set an invisible arg to synth_id_with_class_suffix. */
1590 objc_implementation_context = impent->imp_context;
1591 impent->class_decl
1592 = create_builtin_decl (VAR_DECL, objc_category_template,
1593 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1596 objc_implementation_context = sav;
1599 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1600 and initialized appropriately. */
1602 static void
1603 generate_objc_symtab_decl ()
1605 tree sc_spec;
1607 if (!objc_category_template)
1608 build_category_template ();
1610 /* forward declare categories */
1611 if (cat_count)
1612 forward_declare_categories ();
1614 if (!objc_symtab_template)
1615 build_objc_symtab_template ();
1617 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1619 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1620 tree_cons (NULL_TREE,
1621 objc_symtab_template, sc_spec),
1623 NULL_TREE);
1625 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1626 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1627 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1628 finish_decl (UOBJC_SYMBOLS_decl,
1629 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1630 NULL_TREE);
1633 static tree
1634 init_module_descriptor (type)
1635 tree type;
1637 tree initlist, expr;
1639 /* version = { 1, ... } */
1641 expr = build_int_2 (OBJC_VERSION, 0);
1642 initlist = build_tree_list (NULL_TREE, expr);
1644 /* size = { ..., sizeof (struct objc_module), ... } */
1646 expr = size_in_bytes (objc_module_template);
1647 initlist = tree_cons (NULL_TREE, expr, initlist);
1649 /* name = { ..., "foo.m", ... } */
1651 expr = add_objc_string (get_identifier (input_filename), class_names);
1652 initlist = tree_cons (NULL_TREE, expr, initlist);
1654 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1656 if (UOBJC_SYMBOLS_decl)
1657 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1658 else
1659 expr = build_int_2 (0, 0);
1660 initlist = tree_cons (NULL_TREE, expr, initlist);
1662 return objc_build_constructor (type, nreverse (initlist));
1665 /* Write out the data structures to describe Objective C classes defined.
1666 If appropriate, compile and output a setup function to initialize them.
1667 Return a symbol_ref to the function to call to initialize the Objective C
1668 data structures for this file (and perhaps for other files also).
1670 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1672 static rtx
1673 build_module_descriptor ()
1675 tree decl_specs, field_decl, field_decl_chain;
1677 objc_module_template
1678 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1680 /* Long version; */
1682 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1683 field_decl = get_identifier ("version");
1684 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1685 field_decl_chain = field_decl;
1687 /* long size; */
1689 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1690 field_decl = get_identifier ("size");
1691 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1692 chainon (field_decl_chain, field_decl);
1694 /* char *name; */
1696 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1697 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1698 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1699 chainon (field_decl_chain, field_decl);
1701 /* struct objc_symtab *symtab; */
1703 decl_specs = get_identifier (UTAG_SYMTAB);
1704 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1705 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1706 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1707 chainon (field_decl_chain, field_decl);
1709 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1711 /* Create an instance of "objc_module". */
1713 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1714 build_tree_list (NULL_TREE,
1715 ridpointers[(int) RID_STATIC]));
1717 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1718 decl_specs, 1, NULL_TREE);
1720 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1721 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1722 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1724 finish_decl (UOBJC_MODULES_decl,
1725 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1726 NULL_TREE);
1728 /* Mark the decl to avoid "defined but not used" warning. */
1729 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1731 /* Generate a constructor call for the module descriptor.
1732 This code was generated by reading the grammar rules
1733 of c-parse.in; Therefore, it may not be the most efficient
1734 way of generating the requisite code. */
1736 if (flag_next_runtime)
1737 return NULL_RTX;
1740 tree parms, execclass_decl, decelerator, void_list_node_1;
1741 tree init_function_name, init_function_decl;
1743 /* Declare void __objc_execClass (void *); */
1745 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1746 execclass_decl = build_decl (FUNCTION_DECL,
1747 get_identifier (TAG_EXECCLASS),
1748 build_function_type (void_type_node,
1749 tree_cons (NULL_TREE, ptr_type_node,
1750 void_list_node_1)));
1751 DECL_EXTERNAL (execclass_decl) = 1;
1752 DECL_ARTIFICIAL (execclass_decl) = 1;
1753 TREE_PUBLIC (execclass_decl) = 1;
1754 pushdecl (execclass_decl);
1755 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1756 assemble_external (execclass_decl);
1758 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1760 init_function_name = get_file_function_name ('I');
1761 start_function (void_list_node_1,
1762 build_nt (CALL_EXPR, init_function_name,
1763 tree_cons (NULL_TREE, NULL_TREE,
1764 void_list_node_1),
1765 NULL_TREE),
1766 NULL_TREE);
1767 store_parm_decls ();
1769 init_function_decl = current_function_decl;
1770 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1771 TREE_USED (init_function_decl) = 1;
1772 /* Don't let this one be deferred. */
1773 DECL_INLINE (init_function_decl) = 0;
1774 DECL_UNINLINABLE (init_function_decl) = 1;
1775 current_function_cannot_inline
1776 = "static constructors and destructors cannot be inlined";
1778 parms
1779 = build_tree_list (NULL_TREE,
1780 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1781 decelerator = build_function_call (execclass_decl, parms);
1783 c_expand_expr_stmt (decelerator);
1785 finish_function (0, 0);
1787 return XEXP (DECL_RTL (init_function_decl), 0);
1791 /* extern const char _OBJC_STRINGS[]; */
1793 static void
1794 generate_forward_declaration_to_string_table ()
1796 tree sc_spec, decl_specs, expr_decl;
1798 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1799 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1801 expr_decl
1802 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1804 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1807 /* Return the DECL of the string IDENT in the SECTION. */
1809 static tree
1810 get_objc_string_decl (ident, section)
1811 tree ident;
1812 enum string_section section;
1814 tree chain;
1816 if (section == class_names)
1817 chain = class_names_chain;
1818 else if (section == meth_var_names)
1819 chain = meth_var_names_chain;
1820 else if (section == meth_var_types)
1821 chain = meth_var_types_chain;
1822 else
1823 abort ();
1825 for (; chain != 0; chain = TREE_CHAIN (chain))
1826 if (TREE_VALUE (chain) == ident)
1827 return (TREE_PURPOSE (chain));
1829 abort ();
1830 return NULL_TREE;
1833 /* Output references to all statically allocated objects. Return the DECL
1834 for the array built. */
1836 static void
1837 generate_static_references ()
1839 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1840 tree class_name, class, decl, initlist;
1841 tree cl_chain, in_chain, type;
1842 int num_inst, num_class;
1843 char buf[256];
1845 if (flag_next_runtime)
1846 abort ();
1848 for (cl_chain = objc_static_instances, num_class = 0;
1849 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1851 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1852 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1854 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1855 ident = get_identifier (buf);
1857 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1858 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1859 build_tree_list (NULL_TREE,
1860 ridpointers[(int) RID_STATIC]));
1861 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1862 DECL_CONTEXT (decl) = 0;
1863 DECL_ARTIFICIAL (decl) = 1;
1865 /* Output {class_name, ...}. */
1866 class = TREE_VALUE (cl_chain);
1867 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1868 initlist = build_tree_list (NULL_TREE,
1869 build_unary_op (ADDR_EXPR, class_name, 1));
1871 /* Output {..., instance, ...}. */
1872 for (in_chain = TREE_PURPOSE (cl_chain);
1873 in_chain; in_chain = TREE_CHAIN (in_chain))
1875 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1876 initlist = tree_cons (NULL_TREE, expr, initlist);
1879 /* Output {..., NULL}. */
1880 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1882 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
1883 finish_decl (decl, expr, NULL_TREE);
1884 TREE_USED (decl) = 1;
1886 type = build_array_type (build_pointer_type (void_type_node), 0);
1887 decl = build_decl (VAR_DECL, ident, type);
1888 TREE_USED (decl) = 1;
1889 TREE_STATIC (decl) = 1;
1890 decls
1891 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1894 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1895 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1896 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1897 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1898 build_tree_list (NULL_TREE,
1899 ridpointers[(int) RID_STATIC]));
1900 static_instances_decl
1901 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1902 TREE_USED (static_instances_decl) = 1;
1903 DECL_CONTEXT (static_instances_decl) = 0;
1904 DECL_ARTIFICIAL (static_instances_decl) = 1;
1905 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
1906 nreverse (decls));
1907 finish_decl (static_instances_decl, expr, NULL_TREE);
1910 /* Output all strings. */
1912 static void
1913 generate_strings ()
1915 tree sc_spec, decl_specs, expr_decl;
1916 tree chain, string_expr;
1917 tree string, decl;
1919 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1921 string = TREE_VALUE (chain);
1922 decl = TREE_PURPOSE (chain);
1923 sc_spec
1924 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1925 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1926 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1927 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1928 DECL_CONTEXT (decl) = NULL_TREE;
1929 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1930 IDENTIFIER_POINTER (string));
1931 finish_decl (decl, string_expr, NULL_TREE);
1934 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1936 string = TREE_VALUE (chain);
1937 decl = TREE_PURPOSE (chain);
1938 sc_spec
1939 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1940 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1941 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1942 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1943 DECL_CONTEXT (decl) = NULL_TREE;
1944 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1945 IDENTIFIER_POINTER (string));
1946 finish_decl (decl, string_expr, NULL_TREE);
1949 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1951 string = TREE_VALUE (chain);
1952 decl = TREE_PURPOSE (chain);
1953 sc_spec
1954 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1955 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1956 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1957 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1958 DECL_CONTEXT (decl) = NULL_TREE;
1959 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1960 IDENTIFIER_POINTER (string));
1961 finish_decl (decl, string_expr, NULL_TREE);
1965 static GTY(()) int selector_reference_idx;
1966 static tree
1967 build_selector_reference_decl ()
1969 tree decl, ident;
1970 char buf[256];
1972 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
1974 ident = get_identifier (buf);
1976 decl = build_decl (VAR_DECL, ident, selector_type);
1977 DECL_EXTERNAL (decl) = 1;
1978 TREE_PUBLIC (decl) = 1;
1979 TREE_USED (decl) = 1;
1980 TREE_READONLY (decl) = 1;
1981 DECL_ARTIFICIAL (decl) = 1;
1982 DECL_CONTEXT (decl) = 0;
1984 make_decl_rtl (decl, 0);
1985 pushdecl_top_level (decl);
1987 return decl;
1990 /* Just a handy wrapper for add_objc_string. */
1992 static tree
1993 build_selector (ident)
1994 tree ident;
1996 tree expr = add_objc_string (ident, meth_var_names);
1997 if (flag_typed_selectors)
1998 return expr;
1999 else
2000 return build_c_cast (selector_type, expr); /* cast! */
2003 static void
2004 build_selector_translation_table ()
2006 tree sc_spec, decl_specs;
2007 tree chain, initlist = NULL_TREE;
2008 int offset = 0;
2009 tree decl = NULL_TREE, var_decl, name;
2011 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2013 tree expr;
2015 if (warn_selector && objc_implementation_context)
2017 tree method_chain;
2018 bool found = false;
2019 for (method_chain = meth_var_names_chain;
2020 method_chain;
2021 method_chain = TREE_CHAIN (method_chain))
2023 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2025 found = true;
2026 break;
2029 if (!found)
2031 /* Adjust line number for warning message. */
2032 int save_lineno = input_line;
2033 if (flag_next_runtime && TREE_PURPOSE (chain))
2034 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2035 warning ("creating selector for non existant method %s",
2036 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2037 input_line = save_lineno;
2041 expr = build_selector (TREE_VALUE (chain));
2043 if (flag_next_runtime)
2045 name = DECL_NAME (TREE_PURPOSE (chain));
2047 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2049 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2050 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2052 var_decl = name;
2054 /* The `decl' that is returned from start_decl is the one that we
2055 forward declared in `build_selector_reference' */
2056 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2059 /* add one for the '\0' character */
2060 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2062 if (flag_next_runtime)
2063 finish_decl (decl, expr, NULL_TREE);
2064 else
2066 if (flag_typed_selectors)
2068 tree eltlist = NULL_TREE;
2069 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2070 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2071 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2072 expr = objc_build_constructor (objc_selector_template,
2073 nreverse (eltlist));
2075 initlist = tree_cons (NULL_TREE, expr, initlist);
2080 if (! flag_next_runtime)
2082 /* Cause the variable and its initial value to be actually output. */
2083 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2084 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2085 /* NULL terminate the list and fix the decl for output. */
2086 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2087 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2088 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2089 nreverse (initlist));
2090 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2091 current_function_decl = NULL_TREE;
2095 static tree
2096 get_proto_encoding (proto)
2097 tree proto;
2099 tree encoding;
2100 if (proto)
2102 tree tmp_decl;
2104 if (! METHOD_ENCODING (proto))
2106 tmp_decl = build_tmp_function_decl ();
2107 hack_method_prototype (proto, tmp_decl);
2108 encoding = encode_method_prototype (proto, tmp_decl);
2109 METHOD_ENCODING (proto) = encoding;
2111 else
2112 encoding = METHOD_ENCODING (proto);
2114 return add_objc_string (encoding, meth_var_types);
2116 else
2117 return build_int_2 (0, 0);
2120 /* sel_ref_chain is a list whose "value" fields will be instances of
2121 identifier_node that represent the selector. */
2123 static tree
2124 build_typed_selector_reference (ident, prototype)
2125 tree ident, prototype;
2127 tree *chain = &sel_ref_chain;
2128 tree expr;
2129 int index = 0;
2131 while (*chain)
2133 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2134 goto return_at_index;
2136 index++;
2137 chain = &TREE_CHAIN (*chain);
2140 *chain = tree_cons (prototype, ident, NULL_TREE);
2142 return_at_index:
2143 expr = build_unary_op (ADDR_EXPR,
2144 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2145 build_int_2 (index, 0)),
2147 return build_c_cast (selector_type, expr);
2150 static tree
2151 build_selector_reference (ident)
2152 tree ident;
2154 tree *chain = &sel_ref_chain;
2155 tree expr;
2156 int index = 0;
2158 while (*chain)
2160 if (TREE_VALUE (*chain) == ident)
2161 return (flag_next_runtime
2162 ? TREE_PURPOSE (*chain)
2163 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2164 build_int_2 (index, 0)));
2166 index++;
2167 chain = &TREE_CHAIN (*chain);
2170 expr = build_selector_reference_decl ();
2172 *chain = tree_cons (expr, ident, NULL_TREE);
2174 return (flag_next_runtime
2175 ? expr
2176 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2177 build_int_2 (index, 0)));
2180 static GTY(()) int class_reference_idx;
2181 static tree
2182 build_class_reference_decl ()
2184 tree decl, ident;
2185 char buf[256];
2187 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2189 ident = get_identifier (buf);
2191 decl = build_decl (VAR_DECL, ident, objc_class_type);
2192 DECL_EXTERNAL (decl) = 1;
2193 TREE_PUBLIC (decl) = 1;
2194 TREE_USED (decl) = 1;
2195 TREE_READONLY (decl) = 1;
2196 DECL_CONTEXT (decl) = 0;
2197 DECL_ARTIFICIAL (decl) = 1;
2199 make_decl_rtl (decl, 0);
2200 pushdecl_top_level (decl);
2202 return decl;
2205 /* Create a class reference, but don't create a variable to reference
2206 it. */
2208 static void
2209 add_class_reference (ident)
2210 tree ident;
2212 tree chain;
2214 if ((chain = cls_ref_chain))
2216 tree tail;
2219 if (ident == TREE_VALUE (chain))
2220 return;
2222 tail = chain;
2223 chain = TREE_CHAIN (chain);
2225 while (chain);
2227 /* Append to the end of the list */
2228 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2230 else
2231 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2234 /* Get a class reference, creating it if necessary. Also create the
2235 reference variable. */
2237 tree
2238 get_class_reference (ident)
2239 tree ident;
2241 if (flag_next_runtime)
2243 tree *chain;
2244 tree decl;
2246 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2247 if (TREE_VALUE (*chain) == ident)
2249 if (! TREE_PURPOSE (*chain))
2250 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2252 return TREE_PURPOSE (*chain);
2255 decl = build_class_reference_decl ();
2256 *chain = tree_cons (decl, ident, NULL_TREE);
2257 return decl;
2259 else
2261 tree params;
2263 add_class_reference (ident);
2265 params = build_tree_list (NULL_TREE,
2266 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2267 IDENTIFIER_POINTER (ident)));
2269 assemble_external (objc_get_class_decl);
2270 return build_function_call (objc_get_class_decl, params);
2274 /* For each string section we have a chain which maps identifier nodes
2275 to decls for the strings. */
2277 static tree
2278 add_objc_string (ident, section)
2279 tree ident;
2280 enum string_section section;
2282 tree *chain, decl;
2284 if (section == class_names)
2285 chain = &class_names_chain;
2286 else if (section == meth_var_names)
2287 chain = &meth_var_names_chain;
2288 else if (section == meth_var_types)
2289 chain = &meth_var_types_chain;
2290 else
2291 abort ();
2293 while (*chain)
2295 if (TREE_VALUE (*chain) == ident)
2296 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2298 chain = &TREE_CHAIN (*chain);
2301 decl = build_objc_string_decl (section);
2303 *chain = tree_cons (decl, ident, NULL_TREE);
2305 return build_unary_op (ADDR_EXPR, decl, 1);
2308 static GTY(()) int class_names_idx;
2309 static GTY(()) int meth_var_names_idx;
2310 static GTY(()) int meth_var_types_idx;
2312 static tree
2313 build_objc_string_decl (section)
2314 enum string_section section;
2316 tree decl, ident;
2317 char buf[256];
2319 if (section == class_names)
2320 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2321 else if (section == meth_var_names)
2322 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2323 else if (section == meth_var_types)
2324 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2326 ident = get_identifier (buf);
2328 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2329 DECL_EXTERNAL (decl) = 1;
2330 TREE_PUBLIC (decl) = 1;
2331 TREE_USED (decl) = 1;
2332 TREE_READONLY (decl) = 1;
2333 TREE_CONSTANT (decl) = 1;
2334 DECL_CONTEXT (decl) = 0;
2335 DECL_ARTIFICIAL (decl) = 1;
2337 make_decl_rtl (decl, 0);
2338 pushdecl_top_level (decl);
2340 return decl;
2344 void
2345 objc_declare_alias (alias_ident, class_ident)
2346 tree alias_ident;
2347 tree class_ident;
2349 if (is_class_name (class_ident) != class_ident)
2350 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2351 else if (is_class_name (alias_ident))
2352 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2353 else
2354 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2357 void
2358 objc_declare_class (ident_list)
2359 tree ident_list;
2361 tree list;
2363 for (list = ident_list; list; list = TREE_CHAIN (list))
2365 tree ident = TREE_VALUE (list);
2366 tree decl;
2368 if ((decl = lookup_name (ident)))
2370 error ("`%s' redeclared as different kind of symbol",
2371 IDENTIFIER_POINTER (ident));
2372 error_with_decl (decl, "previous declaration of `%s'");
2375 if (! is_class_name (ident))
2377 tree record = xref_tag (RECORD_TYPE, ident);
2378 TREE_STATIC_TEMPLATE (record) = 1;
2379 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2384 tree
2385 is_class_name (ident)
2386 tree ident;
2388 tree chain;
2390 if (lookup_interface (ident))
2391 return ident;
2393 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2395 if (ident == TREE_VALUE (chain))
2396 return ident;
2399 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2401 if (ident == TREE_VALUE (chain))
2402 return TREE_PURPOSE (chain);
2405 return 0;
2408 tree
2409 objc_is_id (ident)
2410 tree ident;
2412 /* NB: This function may be called before the ObjC front-end
2413 has been initialized, in which case ID_TYPE will be NULL. */
2414 return (id_type && ident && TYPE_P (ident) && IS_ID (ident))
2415 ? id_type
2416 : NULL_TREE;
2419 tree
2420 lookup_interface (ident)
2421 tree ident;
2423 tree chain;
2425 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2427 if (ident == CLASS_NAME (chain))
2428 return chain;
2430 return NULL_TREE;
2433 /* Used by: build_private_template, continue_class,
2434 and for @defs constructs. */
2436 tree
2437 get_class_ivars (interface)
2438 tree interface;
2440 tree my_name, super_name, ivar_chain;
2442 my_name = CLASS_NAME (interface);
2443 super_name = CLASS_SUPER_NAME (interface);
2444 ivar_chain = CLASS_IVARS (interface);
2446 /* Save off a pristine copy of the leaf ivars (i.e, those not
2447 inherited from a super class). */
2448 if (!CLASS_OWN_IVARS (interface))
2449 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2451 while (super_name)
2453 tree op1;
2454 tree super_interface = lookup_interface (super_name);
2456 if (!super_interface)
2458 /* fatal did not work with 2 args...should fix */
2459 error ("cannot find interface declaration for `%s', superclass of `%s'",
2460 IDENTIFIER_POINTER (super_name),
2461 IDENTIFIER_POINTER (my_name));
2462 exit (FATAL_EXIT_CODE);
2465 if (super_interface == interface)
2466 fatal_error ("circular inheritance in interface declaration for `%s'",
2467 IDENTIFIER_POINTER (super_name));
2469 interface = super_interface;
2470 my_name = CLASS_NAME (interface);
2471 super_name = CLASS_SUPER_NAME (interface);
2473 op1 = CLASS_OWN_IVARS (interface);
2474 if (op1)
2476 tree head = copy_list (op1);
2478 /* Prepend super class ivars...make a copy of the list, we
2479 do not want to alter the original. */
2480 chainon (head, ivar_chain);
2481 ivar_chain = head;
2484 return ivar_chain;
2487 /* struct <classname> {
2488 struct objc_class *isa;
2490 }; */
2492 static tree
2493 build_private_template (class)
2494 tree class;
2496 tree ivar_context;
2498 if (CLASS_STATIC_TEMPLATE (class))
2500 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2501 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2503 else
2505 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2507 ivar_context = get_class_ivars (class);
2509 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2511 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2513 /* mark this record as class template - for class type checking */
2514 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2517 instance_type
2518 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2519 uprivate_record),
2520 build1 (INDIRECT_REF, NULL_TREE,
2521 NULL_TREE)));
2523 return ivar_context;
2526 /* Begin code generation for protocols... */
2528 /* struct objc_protocol {
2529 char *protocol_name;
2530 struct objc_protocol **protocol_list;
2531 struct objc_method_desc *instance_methods;
2532 struct objc_method_desc *class_methods;
2533 }; */
2535 static tree
2536 build_protocol_template ()
2538 tree decl_specs, field_decl, field_decl_chain;
2539 tree template;
2541 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2543 /* struct objc_class *isa; */
2545 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2546 get_identifier (UTAG_CLASS)));
2547 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2548 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2549 field_decl_chain = field_decl;
2551 /* char *protocol_name; */
2553 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2554 field_decl
2555 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2556 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2557 chainon (field_decl_chain, field_decl);
2559 /* struct objc_protocol **protocol_list; */
2561 decl_specs = build_tree_list (NULL_TREE, template);
2562 field_decl
2563 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2564 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2565 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2566 chainon (field_decl_chain, field_decl);
2568 /* struct objc_method_list *instance_methods; */
2570 decl_specs
2571 = build_tree_list (NULL_TREE,
2572 xref_tag (RECORD_TYPE,
2573 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2574 field_decl
2575 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2576 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2577 chainon (field_decl_chain, field_decl);
2579 /* struct objc_method_list *class_methods; */
2581 decl_specs
2582 = build_tree_list (NULL_TREE,
2583 xref_tag (RECORD_TYPE,
2584 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2585 field_decl
2586 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2587 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2588 chainon (field_decl_chain, field_decl);
2590 return finish_struct (template, field_decl_chain, NULL_TREE);
2593 static tree
2594 build_descriptor_table_initializer (type, entries)
2595 tree type;
2596 tree entries;
2598 tree initlist = NULL_TREE;
2602 tree eltlist = NULL_TREE;
2604 eltlist
2605 = tree_cons (NULL_TREE,
2606 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2607 eltlist
2608 = tree_cons (NULL_TREE,
2609 add_objc_string (METHOD_ENCODING (entries),
2610 meth_var_types),
2611 eltlist);
2613 initlist
2614 = tree_cons (NULL_TREE,
2615 objc_build_constructor (type, nreverse (eltlist)),
2616 initlist);
2618 entries = TREE_CHAIN (entries);
2620 while (entries);
2622 return objc_build_constructor (build_array_type (type, 0),
2623 nreverse (initlist));
2626 /* struct objc_method_prototype_list {
2627 int count;
2628 struct objc_method_prototype {
2629 SEL name;
2630 char *types;
2631 } list[1];
2632 }; */
2634 static tree
2635 build_method_prototype_list_template (list_type, size)
2636 tree list_type;
2637 int size;
2639 tree objc_ivar_list_record;
2640 tree decl_specs, field_decl, field_decl_chain;
2642 /* Generate an unnamed struct definition. */
2644 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2646 /* int method_count; */
2648 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2649 field_decl = get_identifier ("method_count");
2650 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2651 field_decl_chain = field_decl;
2653 /* struct objc_method method_list[]; */
2655 decl_specs = build_tree_list (NULL_TREE, list_type);
2656 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2657 build_int_2 (size, 0));
2658 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2659 chainon (field_decl_chain, field_decl);
2661 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2663 return objc_ivar_list_record;
2666 static tree
2667 build_method_prototype_template ()
2669 tree proto_record;
2670 tree decl_specs, field_decl, field_decl_chain;
2672 proto_record
2673 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2675 /* struct objc_selector *_cmd; */
2676 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2677 get_identifier (TAG_SELECTOR)), NULL_TREE);
2678 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2679 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2680 field_decl_chain = field_decl;
2682 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2683 field_decl
2684 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2685 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2686 chainon (field_decl_chain, field_decl);
2688 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2690 return proto_record;
2693 /* True if last call to forwarding_offset yielded a register offset. */
2694 static int offset_is_register;
2696 static int
2697 forwarding_offset (parm)
2698 tree parm;
2700 int offset_in_bytes;
2702 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2704 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2706 /* ??? Here we assume that the parm address is indexed
2707 off the frame pointer or arg pointer.
2708 If that is not true, we produce meaningless results,
2709 but do not crash. */
2710 if (GET_CODE (addr) == PLUS
2711 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2712 offset_in_bytes = INTVAL (XEXP (addr, 1));
2713 else
2714 offset_in_bytes = 0;
2716 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2717 offset_is_register = 0;
2719 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2721 int regno = REGNO (DECL_INCOMING_RTL (parm));
2722 offset_in_bytes = apply_args_register_offset (regno);
2723 offset_is_register = 1;
2725 else
2726 return 0;
2728 /* This is the case where the parm is passed as an int or double
2729 and it is converted to a char, short or float and stored back
2730 in the parmlist. In this case, describe the parm
2731 with the variable's declared type, and adjust the address
2732 if the least significant bytes (which we are using) are not
2733 the first ones. */
2734 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2735 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2736 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2738 return offset_in_bytes;
2741 static tree
2742 encode_method_prototype (method_decl, func_decl)
2743 tree method_decl;
2744 tree func_decl;
2746 tree parms;
2747 int stack_size, i;
2748 tree user_args;
2749 HOST_WIDE_INT max_parm_end = 0;
2750 char buf[40];
2751 tree result;
2753 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2754 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2756 /* C type. */
2757 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2758 obstack_object_size (&util_obstack),
2759 OBJC_ENCODE_INLINE_DEFS);
2761 /* Stack size. */
2762 for (parms = DECL_ARGUMENTS (func_decl); parms;
2763 parms = TREE_CHAIN (parms))
2765 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2766 + int_size_in_bytes (TREE_TYPE (parms)));
2768 if (!offset_is_register && max_parm_end < parm_end)
2769 max_parm_end = parm_end;
2772 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2774 sprintf (buf, "%d", stack_size);
2775 obstack_grow (&util_obstack, buf, strlen (buf));
2777 user_args = METHOD_SEL_ARGS (method_decl);
2779 /* Argument types. */
2780 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2781 parms = TREE_CHAIN (parms), i++)
2783 /* Process argument qualifiers for user supplied arguments. */
2784 if (i > 1)
2786 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2787 user_args = TREE_CHAIN (user_args);
2790 /* Type. */
2791 encode_type (TREE_TYPE (parms),
2792 obstack_object_size (&util_obstack),
2793 OBJC_ENCODE_INLINE_DEFS);
2795 /* Compute offset. */
2796 sprintf (buf, "%d", forwarding_offset (parms));
2798 /* Indicate register. */
2799 if (offset_is_register)
2800 obstack_1grow (&util_obstack, '+');
2802 obstack_grow (&util_obstack, buf, strlen (buf));
2805 obstack_1grow (&util_obstack, '\0');
2806 result = get_identifier (obstack_finish (&util_obstack));
2807 obstack_free (&util_obstack, util_firstobj);
2808 return result;
2811 static tree
2812 generate_descriptor_table (type, name, size, list, proto)
2813 tree type;
2814 const char *name;
2815 int size;
2816 tree list;
2817 tree proto;
2819 tree sc_spec, decl_specs, decl, initlist;
2821 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2822 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2824 decl = start_decl (synth_id_with_class_suffix (name, proto),
2825 decl_specs, 1, NULL_TREE);
2826 DECL_CONTEXT (decl) = NULL_TREE;
2828 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2829 initlist = tree_cons (NULL_TREE, list, initlist);
2831 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
2832 NULL_TREE);
2834 return decl;
2837 static void
2838 generate_method_descriptors (protocol)
2839 tree protocol;
2841 tree initlist, chain, method_list_template;
2842 tree cast, variable_length_type;
2843 int size;
2845 if (!objc_method_prototype_template)
2846 objc_method_prototype_template = build_method_prototype_template ();
2848 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2849 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2850 NULL_TREE);
2851 variable_length_type = groktypename (cast);
2853 chain = PROTOCOL_CLS_METHODS (protocol);
2854 if (chain)
2856 size = list_length (chain);
2858 method_list_template
2859 = build_method_prototype_list_template (objc_method_prototype_template,
2860 size);
2862 initlist
2863 = build_descriptor_table_initializer (objc_method_prototype_template,
2864 chain);
2866 UOBJC_CLASS_METHODS_decl
2867 = generate_descriptor_table (method_list_template,
2868 "_OBJC_PROTOCOL_CLASS_METHODS",
2869 size, initlist, protocol);
2870 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2872 else
2873 UOBJC_CLASS_METHODS_decl = 0;
2875 chain = PROTOCOL_NST_METHODS (protocol);
2876 if (chain)
2878 size = list_length (chain);
2880 method_list_template
2881 = build_method_prototype_list_template (objc_method_prototype_template,
2882 size);
2883 initlist
2884 = build_descriptor_table_initializer (objc_method_prototype_template,
2885 chain);
2887 UOBJC_INSTANCE_METHODS_decl
2888 = generate_descriptor_table (method_list_template,
2889 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2890 size, initlist, protocol);
2891 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2893 else
2894 UOBJC_INSTANCE_METHODS_decl = 0;
2897 /* Generate a temporary FUNCTION_DECL node to be used in
2898 hack_method_prototype below. */
2900 static GTY(()) int build_tmp_function_decl_xxx;
2901 static tree
2902 build_tmp_function_decl ()
2904 tree decl_specs, expr_decl, parms;
2905 char buffer[80];
2906 tree tmp_decl;
2908 /* struct objc_object *objc_xxx (id, SEL, ...); */
2909 pushlevel (0);
2910 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2911 push_parm_decl (build_tree_list
2912 (build_tree_list (decl_specs,
2913 build1 (INDIRECT_REF, NULL_TREE,
2914 NULL_TREE)),
2915 NULL_TREE));
2917 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2918 get_identifier (TAG_SELECTOR)));
2919 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2921 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2922 NULL_TREE));
2923 parms = get_parm_info (0);
2924 poplevel (0, 0, 0);
2926 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2927 sprintf (buffer, "__objc_tmp_%x", build_tmp_function_decl_xxx++);
2928 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2929 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2931 tmp_decl = define_decl (expr_decl, decl_specs);
2932 DECL_SOURCE_LINE (tmp_decl) = 0;
2934 return tmp_decl;
2937 /* Generate the prototypes for protocol methods. This is used to
2938 generate method encodings for these.
2940 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2941 a decl node to be used. This is also where the return value is
2942 given. */
2944 static void
2945 hack_method_prototype (nst_methods, tmp_decl)
2946 tree nst_methods;
2947 tree tmp_decl;
2949 tree parms;
2950 tree parm;
2952 /* Hack to avoid problem with static typing of self arg. */
2953 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2954 start_method_def (nst_methods);
2955 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2957 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2958 parms = get_parm_info (0); /* we have a `, ...' */
2959 else
2960 parms = get_parm_info (1); /* place a `void_at_end' */
2962 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2964 /* Usually called from store_parm_decls -> init_function_start. */
2966 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2968 if (current_function_decl)
2969 abort ();
2970 current_function_decl = tmp_decl;
2973 /* Code taken from start_function. */
2974 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2975 /* Promote the value to int before returning it. */
2976 if (TREE_CODE (restype) == INTEGER_TYPE
2977 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2978 restype = integer_type_node;
2979 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2982 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2983 DECL_CONTEXT (parm) = tmp_decl;
2985 init_function_start (tmp_decl);
2987 /* Typically called from expand_function_start for function definitions. */
2988 assign_parms (tmp_decl);
2990 /* install return type */
2991 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2993 current_function_decl = NULL;
2996 static void
2997 generate_protocol_references (plist)
2998 tree plist;
3000 tree lproto;
3002 /* Forward declare protocols referenced. */
3003 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3005 tree proto = TREE_VALUE (lproto);
3007 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3008 && PROTOCOL_NAME (proto))
3010 if (! PROTOCOL_FORWARD_DECL (proto))
3011 build_protocol_reference (proto);
3013 if (PROTOCOL_LIST (proto))
3014 generate_protocol_references (PROTOCOL_LIST (proto));
3019 /* For each protocol which was referenced either from a @protocol()
3020 expression, or because a class/category implements it (then a
3021 pointer to the protocol is stored in the struct describing the
3022 class/category), we create a statically allocated instance of the
3023 Protocol class. The code is written in such a way as to generate
3024 as few Protocol objects as possible; we generate a unique Protocol
3025 instance for each protocol, and we don't generate a Protocol
3026 instance if the protocol is never referenced (either from a
3027 @protocol() or from a class/category implementation). These
3028 statically allocated objects can be referred to via the static
3029 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3031 The statically allocated Protocol objects that we generate here
3032 need to be fixed up at runtime in order to be used: the 'isa'
3033 pointer of the objects need to be set up to point to the 'Protocol'
3034 class, as known at runtime.
3036 The NeXT runtime fixes up all protocols at program startup time,
3037 before main() is entered. It uses a low-level trick to look up all
3038 those symbols, then loops on them and fixes them up.
3040 The GNU runtime as well fixes up all protocols before user code
3041 from the module is executed; it requires pointers to those symbols
3042 to be put in the objc_symtab (which is then passed as argument to
3043 the function __objc_exec_class() which the compiler sets up to be
3044 executed automatically when the module is loaded); setup of those
3045 Protocol objects happen in two ways in the GNU runtime: all
3046 Protocol objects referred to by a class or category implementation
3047 are fixed up when the class/category is loaded; all Protocol
3048 objects referred to by a @protocol() expression are added by the
3049 compiler to the list of statically allocated instances to fixup
3050 (the same list holding the statically allocated constant string
3051 objects). Because, as explained above, the compiler generates as
3052 few Protocol objects as possible, some Protocol object might end up
3053 being referenced multiple times when compiled with the GNU runtime,
3054 and end up being fixed up multiple times at runtime inizialization.
3055 But that doesn't hurt, it's just a little inefficient. */
3056 static void
3057 generate_protocols ()
3059 tree p, tmp_decl, encoding;
3060 tree sc_spec, decl_specs, decl;
3061 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3062 tree cast_type2;
3064 tmp_decl = build_tmp_function_decl ();
3066 if (! objc_protocol_template)
3067 objc_protocol_template = build_protocol_template ();
3069 /* If a protocol was directly referenced, pull in indirect references. */
3070 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3071 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3072 generate_protocol_references (PROTOCOL_LIST (p));
3074 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3076 tree nst_methods = PROTOCOL_NST_METHODS (p);
3077 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3079 /* If protocol wasn't referenced, don't generate any code. */
3080 if (! PROTOCOL_FORWARD_DECL (p))
3081 continue;
3083 /* Make sure we link in the Protocol class. */
3084 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3086 while (nst_methods)
3088 if (! METHOD_ENCODING (nst_methods))
3090 hack_method_prototype (nst_methods, tmp_decl);
3091 encoding = encode_method_prototype (nst_methods, tmp_decl);
3092 METHOD_ENCODING (nst_methods) = encoding;
3094 nst_methods = TREE_CHAIN (nst_methods);
3097 while (cls_methods)
3099 if (! METHOD_ENCODING (cls_methods))
3101 hack_method_prototype (cls_methods, tmp_decl);
3102 encoding = encode_method_prototype (cls_methods, tmp_decl);
3103 METHOD_ENCODING (cls_methods) = encoding;
3106 cls_methods = TREE_CHAIN (cls_methods);
3108 generate_method_descriptors (p);
3110 if (PROTOCOL_LIST (p))
3111 refs_decl = generate_protocol_list (p);
3112 else
3113 refs_decl = 0;
3115 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3117 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3118 NULL_TREE);
3119 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3121 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3122 decl_specs, 1, NULL_TREE);
3124 DECL_CONTEXT (decl) = NULL_TREE;
3126 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3128 if (refs_decl)
3130 cast_type2
3131 = groktypename
3132 (build_tree_list (build_tree_list (NULL_TREE,
3133 objc_protocol_template),
3134 build1 (INDIRECT_REF, NULL_TREE,
3135 build1 (INDIRECT_REF, NULL_TREE,
3136 NULL_TREE))));
3138 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3139 TREE_TYPE (refs_expr) = cast_type2;
3141 else
3142 refs_expr = build_int_2 (0, 0);
3144 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3145 by generate_method_descriptors, which is called above. */
3146 initlist = build_protocol_initializer (TREE_TYPE (decl),
3147 protocol_name_expr, refs_expr,
3148 UOBJC_INSTANCE_METHODS_decl,
3149 UOBJC_CLASS_METHODS_decl);
3150 finish_decl (decl, initlist, NULL_TREE);
3152 /* Mark the decl as used to avoid "defined but not used" warning. */
3153 TREE_USED (decl) = 1;
3157 static tree
3158 build_protocol_initializer (type, protocol_name, protocol_list,
3159 instance_methods, class_methods)
3160 tree type;
3161 tree protocol_name;
3162 tree protocol_list;
3163 tree instance_methods;
3164 tree class_methods;
3166 tree initlist = NULL_TREE, expr;
3167 tree cast_type;
3169 cast_type = groktypename
3170 (build_tree_list
3171 (build_tree_list (NULL_TREE,
3172 xref_tag (RECORD_TYPE,
3173 get_identifier (UTAG_CLASS))),
3174 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3176 /* Filling the "isa" in with one allows the runtime system to
3177 detect that the version change...should remove before final release. */
3179 expr = build_int_2 (PROTOCOL_VERSION, 0);
3180 TREE_TYPE (expr) = cast_type;
3181 initlist = tree_cons (NULL_TREE, expr, initlist);
3182 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3183 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3185 if (!instance_methods)
3186 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3187 else
3189 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3190 initlist = tree_cons (NULL_TREE, expr, initlist);
3193 if (!class_methods)
3194 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3195 else
3197 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3198 initlist = tree_cons (NULL_TREE, expr, initlist);
3201 return objc_build_constructor (type, nreverse (initlist));
3204 /* struct objc_category {
3205 char *category_name;
3206 char *class_name;
3207 struct objc_method_list *instance_methods;
3208 struct objc_method_list *class_methods;
3209 struct objc_protocol_list *protocols;
3210 }; */
3212 static void
3213 build_category_template ()
3215 tree decl_specs, field_decl, field_decl_chain;
3217 objc_category_template = start_struct (RECORD_TYPE,
3218 get_identifier (UTAG_CATEGORY));
3219 /* char *category_name; */
3221 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3222 field_decl
3223 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3224 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3225 field_decl_chain = field_decl;
3227 /* char *class_name; */
3229 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3230 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3231 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3232 chainon (field_decl_chain, field_decl);
3234 /* struct objc_method_list *instance_methods; */
3236 decl_specs = build_tree_list (NULL_TREE,
3237 xref_tag (RECORD_TYPE,
3238 get_identifier (UTAG_METHOD_LIST)));
3239 field_decl
3240 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3241 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3242 chainon (field_decl_chain, field_decl);
3244 /* struct objc_method_list *class_methods; */
3246 decl_specs = build_tree_list (NULL_TREE,
3247 xref_tag (RECORD_TYPE,
3248 get_identifier (UTAG_METHOD_LIST)));
3249 field_decl
3250 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3251 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3252 chainon (field_decl_chain, field_decl);
3254 /* struct objc_protocol **protocol_list; */
3256 decl_specs = build_tree_list (NULL_TREE,
3257 xref_tag (RECORD_TYPE,
3258 get_identifier (UTAG_PROTOCOL)));
3259 field_decl
3260 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3261 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3262 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3263 chainon (field_decl_chain, field_decl);
3265 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3268 /* struct objc_selector {
3269 void *sel_id;
3270 char *sel_type;
3271 }; */
3273 static void
3274 build_selector_template ()
3277 tree decl_specs, field_decl, field_decl_chain;
3279 objc_selector_template
3280 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3282 /* void *sel_id; */
3284 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3285 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3286 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3287 field_decl_chain = field_decl;
3289 /* char *sel_type; */
3291 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3292 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3293 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3294 chainon (field_decl_chain, field_decl);
3296 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3299 /* struct objc_class {
3300 struct objc_class *isa;
3301 struct objc_class *super_class;
3302 char *name;
3303 long version;
3304 long info;
3305 long instance_size;
3306 struct objc_ivar_list *ivars;
3307 struct objc_method_list *methods;
3308 if (flag_next_runtime)
3309 struct objc_cache *cache;
3310 else {
3311 struct sarray *dtable;
3312 struct objc_class *subclass_list;
3313 struct objc_class *sibling_class;
3315 struct objc_protocol_list *protocols;
3316 void *gc_object_type;
3317 }; */
3319 static void
3320 build_class_template ()
3322 tree decl_specs, field_decl, field_decl_chain;
3324 objc_class_template
3325 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3327 /* struct objc_class *isa; */
3329 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3330 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3331 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3332 field_decl_chain = field_decl;
3334 /* struct objc_class *super_class; */
3336 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3337 field_decl
3338 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3339 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3340 chainon (field_decl_chain, field_decl);
3342 /* char *name; */
3344 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3345 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3346 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3347 chainon (field_decl_chain, field_decl);
3349 /* long version; */
3351 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3352 field_decl = get_identifier ("version");
3353 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3354 chainon (field_decl_chain, field_decl);
3356 /* long info; */
3358 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3359 field_decl = get_identifier ("info");
3360 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3361 chainon (field_decl_chain, field_decl);
3363 /* long instance_size; */
3365 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3366 field_decl = get_identifier ("instance_size");
3367 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3368 chainon (field_decl_chain, field_decl);
3370 /* struct objc_ivar_list *ivars; */
3372 decl_specs = build_tree_list (NULL_TREE,
3373 xref_tag (RECORD_TYPE,
3374 get_identifier (UTAG_IVAR_LIST)));
3375 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3376 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3377 chainon (field_decl_chain, field_decl);
3379 /* struct objc_method_list *methods; */
3381 decl_specs = build_tree_list (NULL_TREE,
3382 xref_tag (RECORD_TYPE,
3383 get_identifier (UTAG_METHOD_LIST)));
3384 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3385 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3386 chainon (field_decl_chain, field_decl);
3388 if (flag_next_runtime)
3390 /* struct objc_cache *cache; */
3392 decl_specs = build_tree_list (NULL_TREE,
3393 xref_tag (RECORD_TYPE,
3394 get_identifier ("objc_cache")));
3395 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3396 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3397 chainon (field_decl_chain, field_decl);
3399 else
3401 /* struct sarray *dtable; */
3403 decl_specs = build_tree_list (NULL_TREE,
3404 xref_tag (RECORD_TYPE,
3405 get_identifier ("sarray")));
3406 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3407 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3408 chainon (field_decl_chain, field_decl);
3410 /* struct objc_class *subclass_list; */
3412 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3413 field_decl
3414 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3415 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3416 chainon (field_decl_chain, field_decl);
3418 /* struct objc_class *sibling_class; */
3420 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3421 field_decl
3422 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3423 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3424 chainon (field_decl_chain, field_decl);
3427 /* struct objc_protocol **protocol_list; */
3429 decl_specs = build_tree_list (NULL_TREE,
3430 xref_tag (RECORD_TYPE,
3431 get_identifier (UTAG_PROTOCOL)));
3432 field_decl
3433 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3434 field_decl
3435 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3436 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3437 chainon (field_decl_chain, field_decl);
3439 /* void *sel_id; */
3441 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3442 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3443 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3444 chainon (field_decl_chain, field_decl);
3446 /* void *gc_object_type; */
3448 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3449 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3450 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3451 chainon (field_decl_chain, field_decl);
3453 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3456 /* Generate appropriate forward declarations for an implementation. */
3458 static void
3459 synth_forward_declarations ()
3461 tree sc_spec, decl_specs, an_id;
3463 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3465 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3467 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3468 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3469 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3470 TREE_USED (UOBJC_CLASS_decl) = 1;
3471 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3473 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3475 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3476 objc_implementation_context);
3478 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3479 TREE_USED (UOBJC_METACLASS_decl) = 1;
3480 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3482 /* Pre-build the following entities - for speed/convenience. */
3484 an_id = get_identifier ("super_class");
3485 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3486 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3489 static void
3490 error_with_ivar (message, decl, rawdecl)
3491 const char *message;
3492 tree decl;
3493 tree rawdecl;
3495 error ("%H%s `%s'", &DECL_SOURCE_LOCATION (decl),
3496 message, gen_declaration (rawdecl, errbuf));
3500 static void
3501 check_ivars (inter, imp)
3502 tree inter;
3503 tree imp;
3505 tree intdecls = CLASS_IVARS (inter);
3506 tree impdecls = CLASS_IVARS (imp);
3507 tree rawintdecls = CLASS_RAW_IVARS (inter);
3508 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3510 while (1)
3512 tree t1, t2;
3514 if (intdecls == 0 && impdecls == 0)
3515 break;
3516 if (intdecls == 0 || impdecls == 0)
3518 error ("inconsistent instance variable specification");
3519 break;
3522 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3524 if (!comptypes (t1, t2))
3526 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3528 error_with_ivar ("conflicting instance variable type",
3529 impdecls, rawimpdecls);
3530 error_with_ivar ("previous declaration of",
3531 intdecls, rawintdecls);
3533 else /* both the type and the name don't match */
3535 error ("inconsistent instance variable specification");
3536 break;
3540 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3542 error_with_ivar ("conflicting instance variable name",
3543 impdecls, rawimpdecls);
3544 error_with_ivar ("previous declaration of",
3545 intdecls, rawintdecls);
3548 intdecls = TREE_CHAIN (intdecls);
3549 impdecls = TREE_CHAIN (impdecls);
3550 rawintdecls = TREE_CHAIN (rawintdecls);
3551 rawimpdecls = TREE_CHAIN (rawimpdecls);
3555 /* Set super_type to the data type node for struct objc_super *,
3556 first defining struct objc_super itself.
3557 This needs to be done just once per compilation. */
3559 static tree
3560 build_super_template ()
3562 tree record, decl_specs, field_decl, field_decl_chain;
3564 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3566 /* struct objc_object *self; */
3568 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3569 field_decl = get_identifier ("self");
3570 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3571 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3572 field_decl_chain = field_decl;
3574 /* struct objc_class *class; */
3576 decl_specs = get_identifier (UTAG_CLASS);
3577 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3578 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3580 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3581 chainon (field_decl_chain, field_decl);
3583 finish_struct (record, field_decl_chain, NULL_TREE);
3585 /* `struct objc_super *' */
3586 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3587 record),
3588 build1 (INDIRECT_REF,
3589 NULL_TREE, NULL_TREE)));
3590 return record;
3593 /* struct objc_ivar {
3594 char *ivar_name;
3595 char *ivar_type;
3596 int ivar_offset;
3597 }; */
3599 static tree
3600 build_ivar_template ()
3602 tree objc_ivar_id, objc_ivar_record;
3603 tree decl_specs, field_decl, field_decl_chain;
3605 objc_ivar_id = get_identifier (UTAG_IVAR);
3606 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3608 /* char *ivar_name; */
3610 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3611 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3613 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3614 field_decl_chain = field_decl;
3616 /* char *ivar_type; */
3618 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3619 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3621 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3622 chainon (field_decl_chain, field_decl);
3624 /* int ivar_offset; */
3626 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3627 field_decl = get_identifier ("ivar_offset");
3629 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3630 chainon (field_decl_chain, field_decl);
3632 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3634 return objc_ivar_record;
3637 /* struct {
3638 int ivar_count;
3639 struct objc_ivar ivar_list[ivar_count];
3640 }; */
3642 static tree
3643 build_ivar_list_template (list_type, size)
3644 tree list_type;
3645 int size;
3647 tree objc_ivar_list_record;
3648 tree decl_specs, field_decl, field_decl_chain;
3650 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3652 /* int ivar_count; */
3654 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3655 field_decl = get_identifier ("ivar_count");
3657 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3658 field_decl_chain = field_decl;
3660 /* struct objc_ivar ivar_list[]; */
3662 decl_specs = build_tree_list (NULL_TREE, list_type);
3663 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3664 build_int_2 (size, 0));
3666 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3667 chainon (field_decl_chain, field_decl);
3669 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3671 return objc_ivar_list_record;
3674 /* struct {
3675 int method_next;
3676 int method_count;
3677 struct objc_method method_list[method_count];
3678 }; */
3680 static tree
3681 build_method_list_template (list_type, size)
3682 tree list_type;
3683 int size;
3685 tree objc_ivar_list_record;
3686 tree decl_specs, field_decl, field_decl_chain;
3688 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3690 /* int method_next; */
3692 decl_specs
3693 = build_tree_list
3694 (NULL_TREE,
3695 xref_tag (RECORD_TYPE,
3696 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3697 field_decl
3698 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3699 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3700 field_decl_chain = field_decl;
3702 /* int method_count; */
3704 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3705 field_decl = get_identifier ("method_count");
3707 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3708 chainon (field_decl_chain, field_decl);
3710 /* struct objc_method method_list[]; */
3712 decl_specs = build_tree_list (NULL_TREE, list_type);
3713 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3714 build_int_2 (size, 0));
3716 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3717 chainon (field_decl_chain, field_decl);
3719 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3721 return objc_ivar_list_record;
3724 static tree
3725 build_ivar_list_initializer (type, field_decl)
3726 tree type;
3727 tree field_decl;
3729 tree initlist = NULL_TREE;
3733 tree ivar = NULL_TREE;
3735 /* Set name. */
3736 if (DECL_NAME (field_decl))
3737 ivar = tree_cons (NULL_TREE,
3738 add_objc_string (DECL_NAME (field_decl),
3739 meth_var_names),
3740 ivar);
3741 else
3742 /* Unnamed bit-field ivar (yuck). */
3743 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3745 /* Set type. */
3746 encode_field_decl (field_decl,
3747 obstack_object_size (&util_obstack),
3748 OBJC_ENCODE_DONT_INLINE_DEFS);
3750 /* Null terminate string. */
3751 obstack_1grow (&util_obstack, 0);
3752 ivar
3753 = tree_cons
3754 (NULL_TREE,
3755 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3756 meth_var_types),
3757 ivar);
3758 obstack_free (&util_obstack, util_firstobj);
3760 /* Set offset. */
3761 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3762 initlist = tree_cons (NULL_TREE,
3763 objc_build_constructor (type, nreverse (ivar)),
3764 initlist);
3766 field_decl = TREE_CHAIN (field_decl);
3768 while (field_decl);
3770 return objc_build_constructor (build_array_type (type, 0),
3771 nreverse (initlist));
3774 static tree
3775 generate_ivars_list (type, name, size, list)
3776 tree type;
3777 const char *name;
3778 int size;
3779 tree list;
3781 tree sc_spec, decl_specs, decl, initlist;
3783 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3784 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3786 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3787 decl_specs, 1, NULL_TREE);
3789 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3790 initlist = tree_cons (NULL_TREE, list, initlist);
3792 finish_decl (decl,
3793 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3794 NULL_TREE);
3796 return decl;
3799 static void
3800 generate_ivar_lists ()
3802 tree initlist, ivar_list_template, chain;
3803 tree cast, variable_length_type;
3804 int size;
3806 generating_instance_variables = 1;
3808 if (!objc_ivar_template)
3809 objc_ivar_template = build_ivar_template ();
3811 cast
3812 = build_tree_list
3813 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3814 get_identifier (UTAG_IVAR_LIST))),
3815 NULL_TREE);
3816 variable_length_type = groktypename (cast);
3818 /* Only generate class variables for the root of the inheritance
3819 hierarchy since these will be the same for every class. */
3821 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3822 && (chain = TYPE_FIELDS (objc_class_template)))
3824 size = list_length (chain);
3826 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3827 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3829 UOBJC_CLASS_VARIABLES_decl
3830 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3831 size, initlist);
3832 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3834 else
3835 UOBJC_CLASS_VARIABLES_decl = 0;
3837 chain = CLASS_IVARS (implementation_template);
3838 if (chain)
3840 size = list_length (chain);
3841 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3842 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3844 UOBJC_INSTANCE_VARIABLES_decl
3845 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3846 size, initlist);
3847 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3849 else
3850 UOBJC_INSTANCE_VARIABLES_decl = 0;
3852 generating_instance_variables = 0;
3855 static tree
3856 build_dispatch_table_initializer (type, entries)
3857 tree type;
3858 tree entries;
3860 tree initlist = NULL_TREE;
3864 tree elemlist = NULL_TREE;
3866 elemlist = tree_cons (NULL_TREE,
3867 build_selector (METHOD_SEL_NAME (entries)),
3868 NULL_TREE);
3870 /* Generate the method encoding if we don't have one already. */
3871 if (! METHOD_ENCODING (entries))
3872 METHOD_ENCODING (entries) =
3873 encode_method_def (METHOD_DEFINITION (entries));
3875 elemlist = tree_cons (NULL_TREE,
3876 add_objc_string (METHOD_ENCODING (entries),
3877 meth_var_types),
3878 elemlist);
3880 elemlist = tree_cons (NULL_TREE,
3881 build_unary_op (ADDR_EXPR,
3882 METHOD_DEFINITION (entries), 1),
3883 elemlist);
3885 initlist = tree_cons (NULL_TREE,
3886 objc_build_constructor (type, nreverse (elemlist)),
3887 initlist);
3889 entries = TREE_CHAIN (entries);
3891 while (entries);
3893 return objc_build_constructor (build_array_type (type, 0),
3894 nreverse (initlist));
3897 /* To accomplish method prototyping without generating all kinds of
3898 inane warnings, the definition of the dispatch table entries were
3899 changed from:
3901 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3903 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3905 static tree
3906 build_method_template ()
3908 tree _SLT_record;
3909 tree decl_specs, field_decl, field_decl_chain;
3911 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3913 /* struct objc_selector *_cmd; */
3914 decl_specs = tree_cons (NULL_TREE,
3915 xref_tag (RECORD_TYPE,
3916 get_identifier (TAG_SELECTOR)),
3917 NULL_TREE);
3918 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3920 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3921 field_decl_chain = field_decl;
3923 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3924 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3925 get_identifier ("method_types"));
3926 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3927 chainon (field_decl_chain, field_decl);
3929 /* void *_imp; */
3931 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3932 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3933 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3934 chainon (field_decl_chain, field_decl);
3936 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3938 return _SLT_record;
3942 static tree
3943 generate_dispatch_table (type, name, size, list)
3944 tree type;
3945 const char *name;
3946 int size;
3947 tree list;
3949 tree sc_spec, decl_specs, decl, initlist;
3951 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3952 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3954 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3955 decl_specs, 1, NULL_TREE);
3957 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3958 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3959 initlist = tree_cons (NULL_TREE, list, initlist);
3961 finish_decl (decl,
3962 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3963 NULL_TREE);
3965 return decl;
3968 static void
3969 mark_referenced_methods ()
3971 struct imp_entry *impent;
3972 tree chain;
3974 for (impent = imp_list; impent; impent = impent->next)
3976 chain = CLASS_CLS_METHODS (impent->imp_context);
3977 while (chain)
3979 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)), 1);
3980 chain = TREE_CHAIN (chain);
3982 chain = CLASS_NST_METHODS (impent->imp_context);
3983 while (chain)
3985 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)), 1);
3986 chain = TREE_CHAIN (chain);
3991 static void
3992 generate_dispatch_tables ()
3994 tree initlist, chain, method_list_template;
3995 tree cast, variable_length_type;
3996 int size;
3998 if (!objc_method_template)
3999 objc_method_template = build_method_template ();
4001 cast
4002 = build_tree_list
4003 (build_tree_list (NULL_TREE,
4004 xref_tag (RECORD_TYPE,
4005 get_identifier (UTAG_METHOD_LIST))),
4006 NULL_TREE);
4008 variable_length_type = groktypename (cast);
4010 chain = CLASS_CLS_METHODS (objc_implementation_context);
4011 if (chain)
4013 size = list_length (chain);
4015 method_list_template
4016 = build_method_list_template (objc_method_template, size);
4017 initlist
4018 = build_dispatch_table_initializer (objc_method_template, chain);
4020 UOBJC_CLASS_METHODS_decl
4021 = generate_dispatch_table (method_list_template,
4022 ((TREE_CODE (objc_implementation_context)
4023 == CLASS_IMPLEMENTATION_TYPE)
4024 ? "_OBJC_CLASS_METHODS"
4025 : "_OBJC_CATEGORY_CLASS_METHODS"),
4026 size, initlist);
4027 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4029 else
4030 UOBJC_CLASS_METHODS_decl = 0;
4032 chain = CLASS_NST_METHODS (objc_implementation_context);
4033 if (chain)
4035 size = list_length (chain);
4037 method_list_template
4038 = build_method_list_template (objc_method_template, size);
4039 initlist
4040 = build_dispatch_table_initializer (objc_method_template, chain);
4042 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4043 UOBJC_INSTANCE_METHODS_decl
4044 = generate_dispatch_table (method_list_template,
4045 "_OBJC_INSTANCE_METHODS",
4046 size, initlist);
4047 else
4048 /* We have a category. */
4049 UOBJC_INSTANCE_METHODS_decl
4050 = generate_dispatch_table (method_list_template,
4051 "_OBJC_CATEGORY_INSTANCE_METHODS",
4052 size, initlist);
4053 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4055 else
4056 UOBJC_INSTANCE_METHODS_decl = 0;
4059 static tree
4060 generate_protocol_list (i_or_p)
4061 tree i_or_p;
4063 tree initlist, decl_specs, sc_spec;
4064 tree refs_decl, expr_decl, lproto, e, plist;
4065 tree cast_type;
4066 int size = 0;
4068 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4069 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4070 plist = CLASS_PROTOCOL_LIST (i_or_p);
4071 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4072 plist = PROTOCOL_LIST (i_or_p);
4073 else
4074 abort ();
4076 cast_type = groktypename
4077 (build_tree_list
4078 (build_tree_list (NULL_TREE,
4079 xref_tag (RECORD_TYPE,
4080 get_identifier (UTAG_PROTOCOL))),
4081 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4083 /* Compute size. */
4084 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4085 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4086 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4087 size++;
4089 /* Build initializer. */
4090 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4092 e = build_int_2 (size, 0);
4093 TREE_TYPE (e) = cast_type;
4094 initlist = tree_cons (NULL_TREE, e, initlist);
4096 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4098 tree pval = TREE_VALUE (lproto);
4100 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4101 && PROTOCOL_FORWARD_DECL (pval))
4103 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4104 initlist = tree_cons (NULL_TREE, e, initlist);
4108 /* static struct objc_protocol *refs[n]; */
4110 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4111 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4112 get_identifier (UTAG_PROTOCOL)),
4113 sc_spec);
4115 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4116 expr_decl = build_nt (ARRAY_REF,
4117 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4118 i_or_p),
4119 build_int_2 (size + 2, 0));
4120 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4121 expr_decl = build_nt (ARRAY_REF,
4122 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4123 i_or_p),
4124 build_int_2 (size + 2, 0));
4125 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4126 expr_decl
4127 = build_nt (ARRAY_REF,
4128 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4129 i_or_p),
4130 build_int_2 (size + 2, 0));
4131 else
4132 abort ();
4134 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4136 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4137 DECL_CONTEXT (refs_decl) = NULL_TREE;
4139 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4140 nreverse (initlist)),
4141 NULL_TREE);
4143 return refs_decl;
4146 static tree
4147 build_category_initializer (type, cat_name, class_name,
4148 instance_methods, class_methods, protocol_list)
4149 tree type;
4150 tree cat_name;
4151 tree class_name;
4152 tree instance_methods;
4153 tree class_methods;
4154 tree protocol_list;
4156 tree initlist = NULL_TREE, expr;
4158 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4159 initlist = tree_cons (NULL_TREE, class_name, initlist);
4161 if (!instance_methods)
4162 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4163 else
4165 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4166 initlist = tree_cons (NULL_TREE, expr, initlist);
4168 if (!class_methods)
4169 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4170 else
4172 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4173 initlist = tree_cons (NULL_TREE, expr, initlist);
4176 /* protocol_list = */
4177 if (!protocol_list)
4178 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4179 else
4181 tree cast_type2 = groktypename
4182 (build_tree_list
4183 (build_tree_list (NULL_TREE,
4184 xref_tag (RECORD_TYPE,
4185 get_identifier (UTAG_PROTOCOL))),
4186 build1 (INDIRECT_REF, NULL_TREE,
4187 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4189 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4190 TREE_TYPE (expr) = cast_type2;
4191 initlist = tree_cons (NULL_TREE, expr, initlist);
4194 return objc_build_constructor (type, nreverse (initlist));
4197 /* struct objc_class {
4198 struct objc_class *isa;
4199 struct objc_class *super_class;
4200 char *name;
4201 long version;
4202 long info;
4203 long instance_size;
4204 struct objc_ivar_list *ivars;
4205 struct objc_method_list *methods;
4206 if (flag_next_runtime)
4207 struct objc_cache *cache;
4208 else {
4209 struct sarray *dtable;
4210 struct objc_class *subclass_list;
4211 struct objc_class *sibling_class;
4213 struct objc_protocol_list *protocols;
4214 void *gc_object_type;
4215 }; */
4217 static tree
4218 build_shared_structure_initializer (type, isa, super, name, size, status,
4219 dispatch_table, ivar_list, protocol_list)
4220 tree type;
4221 tree isa;
4222 tree super;
4223 tree name;
4224 tree size;
4225 int status;
4226 tree dispatch_table;
4227 tree ivar_list;
4228 tree protocol_list;
4230 tree initlist = NULL_TREE, expr;
4232 /* isa = */
4233 initlist = tree_cons (NULL_TREE, isa, initlist);
4235 /* super_class = */
4236 initlist = tree_cons (NULL_TREE, super, initlist);
4238 /* name = */
4239 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4241 /* version = */
4242 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4244 /* info = */
4245 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4247 /* instance_size = */
4248 initlist = tree_cons (NULL_TREE, size, initlist);
4250 /* objc_ivar_list = */
4251 if (!ivar_list)
4252 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4253 else
4255 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4256 initlist = tree_cons (NULL_TREE, expr, initlist);
4259 /* objc_method_list = */
4260 if (!dispatch_table)
4261 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4262 else
4264 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4265 initlist = tree_cons (NULL_TREE, expr, initlist);
4268 if (flag_next_runtime)
4269 /* method_cache = */
4270 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4271 else
4273 /* dtable = */
4274 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4276 /* subclass_list = */
4277 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4279 /* sibling_class = */
4280 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4283 /* protocol_list = */
4284 if (! protocol_list)
4285 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4286 else
4288 tree cast_type2
4289 = groktypename
4290 (build_tree_list
4291 (build_tree_list (NULL_TREE,
4292 xref_tag (RECORD_TYPE,
4293 get_identifier (UTAG_PROTOCOL))),
4294 build1 (INDIRECT_REF, NULL_TREE,
4295 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4297 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4298 TREE_TYPE (expr) = cast_type2;
4299 initlist = tree_cons (NULL_TREE, expr, initlist);
4302 /* gc_object_type = NULL */
4303 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4305 return objc_build_constructor (type, nreverse (initlist));
4308 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4310 static void
4311 generate_category (cat)
4312 tree cat;
4314 tree sc_spec, decl_specs, decl;
4315 tree initlist, cat_name_expr, class_name_expr;
4316 tree protocol_decl, category;
4318 add_class_reference (CLASS_NAME (cat));
4319 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4321 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4323 category = CLASS_CATEGORY_LIST (implementation_template);
4325 /* find the category interface from the class it is associated with */
4326 while (category)
4328 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4329 break;
4330 category = CLASS_CATEGORY_LIST (category);
4333 if (category && CLASS_PROTOCOL_LIST (category))
4335 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4336 protocol_decl = generate_protocol_list (category);
4338 else
4339 protocol_decl = 0;
4341 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4342 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4344 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4345 objc_implementation_context),
4346 decl_specs, 1, NULL_TREE);
4348 initlist = build_category_initializer (TREE_TYPE (decl),
4349 cat_name_expr, class_name_expr,
4350 UOBJC_INSTANCE_METHODS_decl,
4351 UOBJC_CLASS_METHODS_decl,
4352 protocol_decl);
4354 TREE_USED (decl) = 1;
4355 finish_decl (decl, initlist, NULL_TREE);
4358 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4359 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4361 static void
4362 generate_shared_structures ()
4364 tree sc_spec, decl_specs, decl;
4365 tree name_expr, super_expr, root_expr;
4366 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4367 tree cast_type, initlist, protocol_decl;
4369 my_super_id = CLASS_SUPER_NAME (implementation_template);
4370 if (my_super_id)
4372 add_class_reference (my_super_id);
4374 /* Compute "my_root_id" - this is required for code generation.
4375 the "isa" for all meta class structures points to the root of
4376 the inheritance hierarchy (e.g. "__Object")... */
4377 my_root_id = my_super_id;
4380 tree my_root_int = lookup_interface (my_root_id);
4382 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4383 my_root_id = CLASS_SUPER_NAME (my_root_int);
4384 else
4385 break;
4387 while (1);
4389 else
4390 /* No super class. */
4391 my_root_id = CLASS_NAME (implementation_template);
4393 cast_type
4394 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4395 objc_class_template),
4396 build1 (INDIRECT_REF,
4397 NULL_TREE, NULL_TREE)));
4399 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4400 class_names);
4402 /* Install class `isa' and `super' pointers at runtime. */
4403 if (my_super_id)
4405 super_expr = add_objc_string (my_super_id, class_names);
4406 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4408 else
4409 super_expr = build_int_2 (0, 0);
4411 root_expr = add_objc_string (my_root_id, class_names);
4412 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4414 if (CLASS_PROTOCOL_LIST (implementation_template))
4416 generate_protocol_references
4417 (CLASS_PROTOCOL_LIST (implementation_template));
4418 protocol_decl = generate_protocol_list (implementation_template);
4420 else
4421 protocol_decl = 0;
4423 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4425 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4426 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4428 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4429 NULL_TREE);
4431 initlist
4432 = build_shared_structure_initializer
4433 (TREE_TYPE (decl),
4434 root_expr, super_expr, name_expr,
4435 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4436 2 /*CLS_META*/,
4437 UOBJC_CLASS_METHODS_decl,
4438 UOBJC_CLASS_VARIABLES_decl,
4439 protocol_decl);
4441 finish_decl (decl, initlist, NULL_TREE);
4443 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4445 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4446 NULL_TREE);
4448 initlist
4449 = build_shared_structure_initializer
4450 (TREE_TYPE (decl),
4451 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4452 super_expr, name_expr,
4453 convert (integer_type_node,
4454 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4455 (implementation_template))),
4456 1 /*CLS_FACTORY*/,
4457 UOBJC_INSTANCE_METHODS_decl,
4458 UOBJC_INSTANCE_VARIABLES_decl,
4459 protocol_decl);
4461 finish_decl (decl, initlist, NULL_TREE);
4464 static tree
4465 synth_id_with_class_suffix (preamble, ctxt)
4466 const char *preamble;
4467 tree ctxt;
4469 char *string;
4470 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4471 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4473 const char *const class_name
4474 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4475 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4476 sprintf (string, "%s_%s", preamble,
4477 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4479 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4480 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4482 /* We have a category. */
4483 const char *const class_name
4484 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4485 const char *const class_super_name
4486 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4487 string = (char *) alloca (strlen (preamble)
4488 + strlen (class_name)
4489 + strlen (class_super_name)
4490 + 3);
4491 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4493 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4495 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4496 string
4497 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4498 sprintf (string, "%s_%s", preamble, protocol_name);
4500 else
4501 abort ();
4503 return get_identifier (string);
4506 static int
4507 is_objc_type_qualifier (node)
4508 tree node;
4510 return (TREE_CODE (node) == IDENTIFIER_NODE
4511 && (node == ridpointers [(int) RID_CONST]
4512 || node == ridpointers [(int) RID_VOLATILE]
4513 || node == ridpointers [(int) RID_IN]
4514 || node == ridpointers [(int) RID_OUT]
4515 || node == ridpointers [(int) RID_INOUT]
4516 || node == ridpointers [(int) RID_BYCOPY]
4517 || node == ridpointers [(int) RID_BYREF]
4518 || node == ridpointers [(int) RID_ONEWAY]));
4521 /* If type is empty or only type qualifiers are present, add default
4522 type of id (otherwise grokdeclarator will default to int). */
4524 static tree
4525 adjust_type_for_id_default (type)
4526 tree type;
4528 tree declspecs, chain;
4530 if (!type)
4531 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4532 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4534 declspecs = TREE_PURPOSE (type);
4536 /* Determine if a typespec is present. */
4537 for (chain = declspecs;
4538 chain;
4539 chain = TREE_CHAIN (chain))
4541 if (TYPED_OBJECT (TREE_VALUE (chain))
4542 && !(TREE_VALUE (type)
4543 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4544 error ("can not use an object as parameter to a method\n");
4545 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4546 return type;
4549 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4550 declspecs),
4551 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4554 /* Usage:
4555 keyworddecl:
4556 selector ':' '(' typename ')' identifier
4558 Purpose:
4559 Transform an Objective-C keyword argument into
4560 the C equivalent parameter declarator.
4562 In: key_name, an "identifier_node" (optional).
4563 arg_type, a "tree_list" (optional).
4564 arg_name, an "identifier_node".
4566 Note: It would be really nice to strongly type the preceding
4567 arguments in the function prototype; however, then I
4568 could not use the "accessor" macros defined in "tree.h".
4570 Out: an instance of "keyword_decl". */
4572 tree
4573 build_keyword_decl (key_name, arg_type, arg_name)
4574 tree key_name;
4575 tree arg_type;
4576 tree arg_name;
4578 tree keyword_decl;
4580 /* If no type is specified, default to "id". */
4581 arg_type = adjust_type_for_id_default (arg_type);
4583 keyword_decl = make_node (KEYWORD_DECL);
4585 TREE_TYPE (keyword_decl) = arg_type;
4586 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4587 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4589 return keyword_decl;
4592 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4594 static tree
4595 build_keyword_selector (selector)
4596 tree selector;
4598 int len = 0;
4599 tree key_chain, key_name;
4600 char *buf;
4602 /* Scan the selector to see how much space we'll need. */
4603 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4605 if (TREE_CODE (selector) == KEYWORD_DECL)
4606 key_name = KEYWORD_KEY_NAME (key_chain);
4607 else if (TREE_CODE (selector) == TREE_LIST)
4608 key_name = TREE_PURPOSE (key_chain);
4609 else
4610 abort ();
4612 if (key_name)
4613 len += IDENTIFIER_LENGTH (key_name) + 1;
4614 else
4615 /* Just a ':' arg. */
4616 len++;
4619 buf = (char *) alloca (len + 1);
4620 /* Start the buffer out as an empty string. */
4621 buf[0] = '\0';
4623 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4625 if (TREE_CODE (selector) == KEYWORD_DECL)
4626 key_name = KEYWORD_KEY_NAME (key_chain);
4627 else if (TREE_CODE (selector) == TREE_LIST)
4628 key_name = TREE_PURPOSE (key_chain);
4629 else
4630 abort ();
4632 if (key_name)
4633 strcat (buf, IDENTIFIER_POINTER (key_name));
4634 strcat (buf, ":");
4637 return get_identifier (buf);
4640 /* Used for declarations and definitions. */
4642 tree
4643 build_method_decl (code, ret_type, selector, add_args)
4644 enum tree_code code;
4645 tree ret_type;
4646 tree selector;
4647 tree add_args;
4649 tree method_decl;
4651 /* If no type is specified, default to "id". */
4652 ret_type = adjust_type_for_id_default (ret_type);
4654 method_decl = make_node (code);
4655 TREE_TYPE (method_decl) = ret_type;
4657 /* If we have a keyword selector, create an identifier_node that
4658 represents the full selector name (`:' included)... */
4659 if (TREE_CODE (selector) == KEYWORD_DECL)
4661 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4662 METHOD_SEL_ARGS (method_decl) = selector;
4663 METHOD_ADD_ARGS (method_decl) = add_args;
4665 else
4667 METHOD_SEL_NAME (method_decl) = selector;
4668 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4669 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4672 return method_decl;
4675 #define METHOD_DEF 0
4676 #define METHOD_REF 1
4678 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4679 an argument list for method METH. CONTEXT is either METHOD_DEF or
4680 METHOD_REF, saying whether we are trying to define a method or call
4681 one. SUPERFLAG says this is for a send to super; this makes a
4682 difference for the NeXT calling sequence in which the lookup and
4683 the method call are done together. */
4685 static tree
4686 get_arg_type_list (meth, context, superflag)
4687 tree meth;
4688 int context;
4689 int superflag;
4691 tree arglist, akey;
4693 /* Receiver type. */
4694 if (flag_next_runtime && superflag)
4695 arglist = build_tree_list (NULL_TREE, super_type);
4696 else if (context == METHOD_DEF)
4697 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4698 else
4699 arglist = build_tree_list (NULL_TREE, id_type);
4701 /* Selector type - will eventually change to `int'. */
4702 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4704 /* Build a list of argument types. */
4705 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4707 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4708 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4711 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4712 /* We have a `, ...' immediately following the selector,
4713 finalize the arglist...simulate get_parm_info (0). */
4715 else if (METHOD_ADD_ARGS (meth))
4717 /* we have a variable length selector */
4718 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4719 chainon (arglist, add_arg_list);
4721 else
4722 /* finalize the arglist...simulate get_parm_info (1) */
4723 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4725 return arglist;
4728 static tree
4729 check_duplicates (hsh)
4730 hash hsh;
4732 tree meth = NULL_TREE;
4734 if (hsh)
4736 meth = hsh->key;
4738 if (hsh->list)
4740 /* We have two methods with the same name and different types. */
4741 attr loop;
4742 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4744 warning ("multiple declarations for method `%s'",
4745 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4747 warn_with_method ("using", type, meth);
4748 for (loop = hsh->list; loop; loop = loop->next)
4749 warn_with_method ("also found", type, loop->value);
4752 return meth;
4755 /* If RECEIVER is a class reference, return the identifier node for
4756 the referenced class. RECEIVER is created by get_class_reference,
4757 so we check the exact form created depending on which runtimes are
4758 used. */
4760 static tree
4761 receiver_is_class_object (receiver)
4762 tree receiver;
4764 tree chain, exp, arg;
4766 /* The receiver is 'self' in the context of a class method. */
4767 if (objc_method_context
4768 && receiver == self_decl
4769 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4771 return CLASS_NAME (objc_implementation_context);
4774 if (flag_next_runtime)
4776 /* The receiver is a variable created by
4777 build_class_reference_decl. */
4778 if (TREE_CODE (receiver) == VAR_DECL
4779 && TREE_TYPE (receiver) == objc_class_type)
4780 /* Look up the identifier. */
4781 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4782 if (TREE_PURPOSE (chain) == receiver)
4783 return TREE_VALUE (chain);
4785 else
4787 /* The receiver is a function call that returns an id. Check if
4788 it is a call to objc_getClass, if so, pick up the class name. */
4789 if (TREE_CODE (receiver) == CALL_EXPR
4790 && (exp = TREE_OPERAND (receiver, 0))
4791 && TREE_CODE (exp) == ADDR_EXPR
4792 && (exp = TREE_OPERAND (exp, 0))
4793 && TREE_CODE (exp) == FUNCTION_DECL
4794 && exp == objc_get_class_decl
4795 /* We have a call to objc_getClass! */
4796 && (arg = TREE_OPERAND (receiver, 1))
4797 && TREE_CODE (arg) == TREE_LIST
4798 && (arg = TREE_VALUE (arg)))
4800 STRIP_NOPS (arg);
4801 if (TREE_CODE (arg) == ADDR_EXPR
4802 && (arg = TREE_OPERAND (arg, 0))
4803 && TREE_CODE (arg) == STRING_CST)
4804 /* Finally, we have the class name. */
4805 return get_identifier (TREE_STRING_POINTER (arg));
4808 return 0;
4811 /* If we are currently building a message expr, this holds
4812 the identifier of the selector of the message. This is
4813 used when printing warnings about argument mismatches. */
4815 static tree current_objc_message_selector = 0;
4817 tree
4818 objc_message_selector ()
4820 return current_objc_message_selector;
4823 /* Construct an expression for sending a message.
4824 MESS has the object to send to in TREE_PURPOSE
4825 and the argument list (including selector) in TREE_VALUE.
4827 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4828 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4830 tree
4831 build_message_expr (mess)
4832 tree mess;
4834 tree receiver = TREE_PURPOSE (mess);
4835 tree sel_name;
4836 tree args = TREE_VALUE (mess);
4837 tree method_params = NULL_TREE;
4839 if (TREE_CODE (receiver) == ERROR_MARK)
4840 return error_mark_node;
4842 /* Obtain the full selector name. */
4843 if (TREE_CODE (args) == IDENTIFIER_NODE)
4844 /* A unary selector. */
4845 sel_name = args;
4846 else if (TREE_CODE (args) == TREE_LIST)
4847 sel_name = build_keyword_selector (args);
4848 else
4849 abort ();
4851 /* Build the parameter list to give to the method. */
4852 if (TREE_CODE (args) == TREE_LIST)
4854 tree chain = args, prev = NULL_TREE;
4856 /* We have a keyword selector--check for comma expressions. */
4857 while (chain)
4859 tree element = TREE_VALUE (chain);
4861 /* We have a comma expression, must collapse... */
4862 if (TREE_CODE (element) == TREE_LIST)
4864 if (prev)
4865 TREE_CHAIN (prev) = element;
4866 else
4867 args = element;
4869 prev = chain;
4870 chain = TREE_CHAIN (chain);
4872 method_params = args;
4875 return finish_message_expr (receiver, sel_name, method_params);
4878 /* The 'finish_message_expr' routine is called from within
4879 'build_message_expr' for non-template functions. In the case of
4880 C++ template functions, it is called from 'build_expr_from_tree'
4881 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4883 tree
4884 finish_message_expr (receiver, sel_name, method_params)
4885 tree receiver, sel_name, method_params;
4887 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4888 tree selector, self_object, retval;
4889 int statically_typed = 0, statically_allocated = 0;
4891 /* Determine receiver type. */
4892 tree rtype = TREE_TYPE (receiver);
4893 int super = IS_SUPER (rtype);
4895 if (! super)
4897 if (TREE_STATIC_TEMPLATE (rtype))
4898 statically_allocated = 1;
4899 else if (TREE_CODE (rtype) == POINTER_TYPE
4900 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4901 statically_typed = 1;
4902 else if ((flag_next_runtime
4903 || (IS_ID (rtype)))
4904 && (class_ident = receiver_is_class_object (receiver)))
4906 else if (! IS_ID (rtype)
4907 /* Allow any type that matches objc_class_type. */
4908 && ! comptypes (rtype, objc_class_type))
4910 warning ("invalid receiver type `%s'",
4911 gen_declaration (rtype, errbuf));
4913 if (statically_allocated)
4914 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4916 /* Don't evaluate the receiver twice. */
4917 receiver = save_expr (receiver);
4918 self_object = receiver;
4920 else
4921 /* If sending to `super', use current self as the object. */
4922 self_object = self_decl;
4924 /* Determine operation return type. */
4926 if (super)
4928 tree iface;
4930 if (CLASS_SUPER_NAME (implementation_template))
4932 iface
4933 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4935 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4936 method_prototype = lookup_instance_method_static (iface, sel_name);
4937 else
4938 method_prototype = lookup_class_method_static (iface, sel_name);
4940 if (iface && !method_prototype)
4941 warning ("`%s' does not respond to `%s'",
4942 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4943 IDENTIFIER_POINTER (sel_name));
4945 else
4947 error ("no super class declared in interface for `%s'",
4948 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4949 return error_mark_node;
4953 else if (statically_allocated)
4955 tree ctype = TREE_TYPE (rtype);
4956 tree iface = lookup_interface (TYPE_NAME (rtype));
4958 if (iface)
4959 method_prototype = lookup_instance_method_static (iface, sel_name);
4961 if (! method_prototype && ctype && TYPE_PROTOCOL_LIST (ctype))
4962 method_prototype
4963 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4964 sel_name, 0);
4966 if (!method_prototype)
4967 warning ("`%s' does not respond to `%s'",
4968 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4969 IDENTIFIER_POINTER (sel_name));
4971 else if (statically_typed)
4973 tree ctype = TREE_TYPE (rtype);
4975 /* `self' is now statically_typed. All methods should be visible
4976 within the context of the implementation. */
4977 if (objc_implementation_context
4978 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4980 method_prototype
4981 = lookup_instance_method_static (implementation_template,
4982 sel_name);
4984 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4985 method_prototype
4986 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4987 sel_name, 0);
4989 if (! method_prototype
4990 && implementation_template != objc_implementation_context)
4991 /* The method is not published in the interface. Check
4992 locally. */
4993 method_prototype
4994 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4995 sel_name);
4997 else
4999 tree iface;
5001 if ((iface = lookup_interface (TYPE_NAME (ctype))))
5002 method_prototype = lookup_instance_method_static (iface, sel_name);
5004 if (! method_prototype)
5006 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
5007 if (protocol_list)
5008 method_prototype
5009 = lookup_method_in_protocol_list (protocol_list,
5010 sel_name, 0);
5014 if (!method_prototype)
5015 warning ("`%s' does not respond to `%s'",
5016 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
5017 IDENTIFIER_POINTER (sel_name));
5019 else if (class_ident)
5021 if (objc_implementation_context
5022 && CLASS_NAME (objc_implementation_context) == class_ident)
5024 method_prototype
5025 = lookup_class_method_static (implementation_template, sel_name);
5027 if (!method_prototype
5028 && implementation_template != objc_implementation_context)
5029 /* The method is not published in the interface. Check
5030 locally. */
5031 method_prototype
5032 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
5033 sel_name);
5035 else
5037 tree iface;
5039 if ((iface = lookup_interface (class_ident)))
5040 method_prototype = lookup_class_method_static (iface, sel_name);
5043 if (!method_prototype)
5045 warning ("cannot find class (factory) method");
5046 warning ("return type for `%s' defaults to id",
5047 IDENTIFIER_POINTER (sel_name));
5050 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5052 /* An anonymous object that has been qualified with a protocol. */
5054 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5056 method_prototype = lookup_method_in_protocol_list (protocol_list,
5057 sel_name, 0);
5059 if (!method_prototype)
5061 hash hsh;
5063 warning ("method `%s' not implemented by protocol",
5064 IDENTIFIER_POINTER (sel_name));
5066 /* Try and find the method signature in the global pools. */
5068 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5069 hsh = hash_lookup (cls_method_hash_list, sel_name);
5071 if (!(method_prototype = check_duplicates (hsh)))
5072 warning ("return type defaults to id");
5075 else
5077 hash hsh;
5079 /* We think we have an instance...loophole: extern id Object; */
5080 hsh = hash_lookup (nst_method_hash_list, sel_name);
5082 if (!hsh)
5083 /* For various loopholes */
5084 hsh = hash_lookup (cls_method_hash_list, sel_name);
5086 method_prototype = check_duplicates (hsh);
5087 if (!method_prototype)
5089 warning ("cannot find method");
5090 warning ("return type for `%s' defaults to id",
5091 IDENTIFIER_POINTER (sel_name));
5095 /* Save the selector name for printing error messages. */
5096 current_objc_message_selector = sel_name;
5098 /* Build the parameters list for looking up the method.
5099 These are the object itself and the selector. */
5101 if (flag_typed_selectors)
5102 selector = build_typed_selector_reference (sel_name, method_prototype);
5103 else
5104 selector = build_selector_reference (sel_name);
5106 retval = build_objc_method_call (super, method_prototype,
5107 receiver, self_object,
5108 selector, method_params);
5110 current_objc_message_selector = 0;
5112 return retval;
5115 /* Build a tree expression to send OBJECT the operation SELECTOR,
5116 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5117 assuming the method has prototype METHOD_PROTOTYPE.
5118 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5119 Use METHOD_PARAMS as list of args to pass to the method.
5120 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5122 static tree
5123 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5124 selector, method_params)
5125 int super_flag;
5126 tree method_prototype, lookup_object, object, selector, method_params;
5128 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5129 tree rcv_p = (super_flag
5130 ? build_pointer_type (xref_tag (RECORD_TYPE,
5131 get_identifier (TAG_SUPER)))
5132 : id_type);
5134 if (flag_next_runtime)
5136 if (! method_prototype)
5138 method_params = tree_cons (NULL_TREE, lookup_object,
5139 tree_cons (NULL_TREE, selector,
5140 method_params));
5141 assemble_external (sender);
5142 return build_function_call (sender, method_params);
5144 else
5146 /* This is a real kludge, but it is used only for the Next.
5147 Clobber the data type of SENDER temporarily to accept
5148 all the arguments for this operation, and to return
5149 whatever this operation returns. */
5150 tree arglist = NULL_TREE, retval, savarg, savret;
5151 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5153 /* Save the proper contents of SENDER's data type. */
5154 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5155 savret = TREE_TYPE (TREE_TYPE (sender));
5157 /* Install this method's argument types. */
5158 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5159 super_flag);
5160 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5162 /* Install this method's return type. */
5163 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5165 /* Call SENDER with all the parameters. This will do type
5166 checking using the arg types for this method. */
5167 method_params = tree_cons (NULL_TREE, lookup_object,
5168 tree_cons (NULL_TREE, selector,
5169 method_params));
5170 assemble_external (sender);
5171 retval = build_function_call (sender, method_params);
5173 /* Restore SENDER's return/argument types. */
5174 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5175 TREE_TYPE (TREE_TYPE (sender)) = savret;
5176 return retval;
5179 else
5181 /* This is the portable way.
5182 First call the lookup function to get a pointer to the method,
5183 then cast the pointer, then call it with the method arguments. */
5184 tree method;
5186 /* Avoid trouble since we may evaluate each of these twice. */
5187 object = save_expr (object);
5188 selector = save_expr (selector);
5190 lookup_object = build_c_cast (rcv_p, lookup_object);
5192 assemble_external (sender);
5193 method
5194 = build_function_call (sender,
5195 tree_cons (NULL_TREE, lookup_object,
5196 tree_cons (NULL_TREE, selector,
5197 NULL_TREE)));
5199 /* If we have a method prototype, construct the data type this
5200 method needs, and cast what we got from SENDER into a pointer
5201 to that type. */
5202 if (method_prototype)
5204 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5205 super_flag);
5206 tree valtype = groktypename (TREE_TYPE (method_prototype));
5207 tree fake_function_type = build_function_type (valtype, arglist);
5208 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5210 else
5211 TREE_TYPE (method)
5212 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5214 /* Pass the object to the method. */
5215 assemble_external (method);
5216 return build_function_call (method,
5217 tree_cons (NULL_TREE, object,
5218 tree_cons (NULL_TREE, selector,
5219 method_params)));
5223 static void
5224 build_protocol_reference (p)
5225 tree p;
5227 tree decl, ident, ptype;
5229 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5231 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5232 ptype
5233 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5234 objc_protocol_template),
5235 NULL_TREE));
5237 if (identifier_global_value (ident))
5238 decl = identifier_global_value (ident); /* Set by pushdecl. */
5239 else
5241 decl = build_decl (VAR_DECL, ident, ptype);
5242 DECL_EXTERNAL (decl) = 1;
5243 TREE_PUBLIC (decl) = 1;
5244 TREE_USED (decl) = 1;
5245 DECL_ARTIFICIAL (decl) = 1;
5247 make_decl_rtl (decl, 0);
5248 pushdecl_top_level (decl);
5251 PROTOCOL_FORWARD_DECL (p) = decl;
5254 /* This function is called by the parser when (and only when) a
5255 @protocol() expression is found, in order to compile it. */
5256 tree
5257 build_protocol_expr (protoname)
5258 tree protoname;
5260 tree expr;
5261 tree p = lookup_protocol (protoname);
5263 if (!p)
5265 error ("cannot find protocol declaration for `%s'",
5266 IDENTIFIER_POINTER (protoname));
5267 return error_mark_node;
5270 if (!PROTOCOL_FORWARD_DECL (p))
5271 build_protocol_reference (p);
5273 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5275 TREE_TYPE (expr) = protocol_type;
5277 /* The @protocol() expression is being compiled into a pointer to a
5278 statically allocated instance of the Protocol class. To become
5279 usable at runtime, the 'isa' pointer of the instance need to be
5280 fixed up at runtime by the runtime library, to point to the
5281 actual 'Protocol' class. */
5283 /* For the GNU runtime, put the static Protocol instance in the list
5284 of statically allocated instances, so that we make sure that its
5285 'isa' pointer is fixed up at runtime by the GNU runtime library
5286 to point to the Protocol class (at runtime, when loading the
5287 module, the GNU runtime library loops on the statically allocated
5288 instances (as found in the defs field in objc_symtab) and fixups
5289 all the 'isa' pointers of those objects). */
5290 if (! flag_next_runtime)
5292 /* This type is a struct containing the fields of a Protocol
5293 object. (Cfr. protocol_type instead is the type of a pointer
5294 to such a struct). */
5295 tree protocol_struct_type = xref_tag
5296 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5297 tree *chain;
5299 /* Look for the list of Protocol statically allocated instances
5300 to fixup at runtime. Create a new list to hold Protocol
5301 statically allocated instances, if the list is not found. At
5302 present there is only another list, holding NSConstantString
5303 static instances to be fixed up at runtime. */
5304 for (chain = &objc_static_instances;
5305 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5306 chain = &TREE_CHAIN (*chain));
5307 if (!*chain)
5309 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5310 add_objc_string (TYPE_NAME (protocol_struct_type),
5311 class_names);
5314 /* Add this statically allocated instance to the Protocol list. */
5315 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5316 PROTOCOL_FORWARD_DECL (p),
5317 TREE_PURPOSE (*chain));
5321 return expr;
5324 /* This function is called by the parser when a @selector() expression
5325 is found, in order to compile it. It is only called by the parser
5326 and only to compile a @selector(). */
5327 tree
5328 build_selector_expr (selnamelist)
5329 tree selnamelist;
5331 tree selname;
5333 /* Obtain the full selector name. */
5334 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5335 /* A unary selector. */
5336 selname = selnamelist;
5337 else if (TREE_CODE (selnamelist) == TREE_LIST)
5338 selname = build_keyword_selector (selnamelist);
5339 else
5340 abort ();
5342 /* If we are required to check @selector() expressions as they
5343 are found, check that the selector has been declared. */
5344 if (warn_undeclared_selector)
5346 /* Look the selector up in the list of all known class and
5347 instance methods (up to this line) to check that the selector
5348 exists. */
5349 hash hsh;
5351 /* First try with instance methods. */
5352 hsh = hash_lookup (nst_method_hash_list, selname);
5354 /* If not found, try with class methods. */
5355 if (!hsh)
5357 hsh = hash_lookup (cls_method_hash_list, selname);
5360 /* If still not found, print out a warning. */
5361 if (!hsh)
5363 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5368 if (flag_typed_selectors)
5369 return build_typed_selector_reference (selname, 0);
5370 else
5371 return build_selector_reference (selname);
5374 tree
5375 build_encode_expr (type)
5376 tree type;
5378 tree result;
5379 const char *string;
5381 encode_type (type, obstack_object_size (&util_obstack),
5382 OBJC_ENCODE_INLINE_DEFS);
5383 obstack_1grow (&util_obstack, 0); /* null terminate string */
5384 string = obstack_finish (&util_obstack);
5386 /* Synthesize a string that represents the encoded struct/union. */
5387 result = my_build_string (strlen (string) + 1, string);
5388 obstack_free (&util_obstack, util_firstobj);
5389 return result;
5392 tree
5393 build_ivar_reference (id)
5394 tree id;
5396 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5398 /* Historically, a class method that produced objects (factory
5399 method) would assign `self' to the instance that it
5400 allocated. This would effectively turn the class method into
5401 an instance method. Following this assignment, the instance
5402 variables could be accessed. That practice, while safe,
5403 violates the simple rule that a class method should not refer
5404 to an instance variable. It's better to catch the cases
5405 where this is done unknowingly than to support the above
5406 paradigm. */
5407 warning ("instance variable `%s' accessed in class method",
5408 IDENTIFIER_POINTER (id));
5409 TREE_TYPE (self_decl) = instance_type; /* cast */
5412 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5415 /* Compute a hash value for a given method SEL_NAME. */
5417 static size_t
5418 hash_func (sel_name)
5419 tree sel_name;
5421 const unsigned char *s
5422 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5423 size_t h = 0;
5425 while (*s)
5426 h = h * 67 + *s++ - 113;
5427 return h;
5430 static void
5431 hash_init ()
5433 nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5434 cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5437 /* WARNING!!!! hash_enter is called with a method, and will peek
5438 inside to find its selector! But hash_lookup is given a selector
5439 directly, and looks for the selector that's inside the found
5440 entry's key (method) for comparison. */
5442 static void
5443 hash_enter (hashlist, method)
5444 hash *hashlist;
5445 tree method;
5447 hash obj;
5448 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5450 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5451 obj->list = 0;
5452 obj->next = hashlist[slot];
5453 obj->key = method;
5455 hashlist[slot] = obj; /* append to front */
5458 static hash
5459 hash_lookup (hashlist, sel_name)
5460 hash *hashlist;
5461 tree sel_name;
5463 hash target;
5465 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5467 while (target)
5469 if (sel_name == METHOD_SEL_NAME (target->key))
5470 return target;
5472 target = target->next;
5474 return 0;
5477 static void
5478 hash_add_attr (entry, value)
5479 hash entry;
5480 tree value;
5482 attr obj;
5484 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5485 obj->next = entry->list;
5486 obj->value = value;
5488 entry->list = obj; /* append to front */
5491 static tree
5492 lookup_method (mchain, method)
5493 tree mchain;
5494 tree method;
5496 tree key;
5498 if (TREE_CODE (method) == IDENTIFIER_NODE)
5499 key = method;
5500 else
5501 key = METHOD_SEL_NAME (method);
5503 while (mchain)
5505 if (METHOD_SEL_NAME (mchain) == key)
5506 return mchain;
5508 mchain = TREE_CHAIN (mchain);
5510 return NULL_TREE;
5513 static tree
5514 lookup_instance_method_static (interface, ident)
5515 tree interface;
5516 tree ident;
5518 tree inter = interface;
5519 tree chain = CLASS_NST_METHODS (inter);
5520 tree meth = NULL_TREE;
5524 if ((meth = lookup_method (chain, ident)))
5525 return meth;
5527 if (CLASS_CATEGORY_LIST (inter))
5529 tree category = CLASS_CATEGORY_LIST (inter);
5530 chain = CLASS_NST_METHODS (category);
5534 if ((meth = lookup_method (chain, ident)))
5535 return meth;
5537 /* Check for instance methods in protocols in categories. */
5538 if (CLASS_PROTOCOL_LIST (category))
5540 if ((meth = (lookup_method_in_protocol_list
5541 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5542 return meth;
5545 if ((category = CLASS_CATEGORY_LIST (category)))
5546 chain = CLASS_NST_METHODS (category);
5548 while (category);
5551 if (CLASS_PROTOCOL_LIST (inter))
5553 if ((meth = (lookup_method_in_protocol_list
5554 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5555 return meth;
5558 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5559 chain = CLASS_NST_METHODS (inter);
5561 while (inter);
5563 return meth;
5566 static tree
5567 lookup_class_method_static (interface, ident)
5568 tree interface;
5569 tree ident;
5571 tree inter = interface;
5572 tree chain = CLASS_CLS_METHODS (inter);
5573 tree meth = NULL_TREE;
5574 tree root_inter = NULL_TREE;
5578 if ((meth = lookup_method (chain, ident)))
5579 return meth;
5581 if (CLASS_CATEGORY_LIST (inter))
5583 tree category = CLASS_CATEGORY_LIST (inter);
5584 chain = CLASS_CLS_METHODS (category);
5588 if ((meth = lookup_method (chain, ident)))
5589 return meth;
5591 /* Check for class methods in protocols in categories. */
5592 if (CLASS_PROTOCOL_LIST (category))
5594 if ((meth = (lookup_method_in_protocol_list
5595 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5596 return meth;
5599 if ((category = CLASS_CATEGORY_LIST (category)))
5600 chain = CLASS_CLS_METHODS (category);
5602 while (category);
5605 /* Check for class methods in protocols. */
5606 if (CLASS_PROTOCOL_LIST (inter))
5608 if ((meth = (lookup_method_in_protocol_list
5609 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5610 return meth;
5613 root_inter = inter;
5614 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5615 chain = CLASS_CLS_METHODS (inter);
5617 while (inter);
5619 /* If no class (factory) method was found, check if an _instance_
5620 method of the same name exists in the root class. This is what
5621 the Objective-C runtime will do. */
5622 return lookup_instance_method_static (root_inter, ident);
5625 tree
5626 add_class_method (class, method)
5627 tree class;
5628 tree method;
5630 tree mth;
5631 hash hsh;
5633 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5635 /* put method on list in reverse order */
5636 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5637 CLASS_CLS_METHODS (class) = method;
5639 else
5641 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5642 error ("duplicate definition of class method `%s'",
5643 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5644 else
5646 /* Check types; if different, complain. */
5647 if (!comp_proto_with_proto (method, mth))
5648 error ("duplicate declaration of class method `%s'",
5649 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5653 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5655 /* Install on a global chain. */
5656 hash_enter (cls_method_hash_list, method);
5658 else
5660 /* Check types; if different, add to a list. */
5661 if (!comp_proto_with_proto (method, hsh->key))
5662 hash_add_attr (hsh, method);
5664 return method;
5667 tree
5668 add_instance_method (class, method)
5669 tree class;
5670 tree method;
5672 tree mth;
5673 hash hsh;
5675 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5677 /* Put method on list in reverse order. */
5678 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5679 CLASS_NST_METHODS (class) = method;
5681 else
5683 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5684 error ("duplicate definition of instance method `%s'",
5685 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5686 else
5688 /* Check types; if different, complain. */
5689 if (!comp_proto_with_proto (method, mth))
5690 error ("duplicate declaration of instance method `%s'",
5691 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5695 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5697 /* Install on a global chain. */
5698 hash_enter (nst_method_hash_list, method);
5700 else
5702 /* Check types; if different, add to a list. */
5703 if (!comp_proto_with_proto (method, hsh->key))
5704 hash_add_attr (hsh, method);
5706 return method;
5709 static tree
5710 add_class (class)
5711 tree class;
5713 /* Put interfaces on list in reverse order. */
5714 TREE_CHAIN (class) = interface_chain;
5715 interface_chain = class;
5716 return interface_chain;
5719 static void
5720 add_category (class, category)
5721 tree class;
5722 tree category;
5724 /* Put categories on list in reverse order. */
5725 tree cat = CLASS_CATEGORY_LIST (class);
5727 while (cat)
5729 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5730 warning ("duplicate interface declaration for category `%s(%s)'",
5731 IDENTIFIER_POINTER (CLASS_NAME (class)),
5732 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5733 cat = CLASS_CATEGORY_LIST (cat);
5736 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5737 CLASS_CATEGORY_LIST (class) = category;
5740 /* Called after parsing each instance variable declaration. Necessary to
5741 preserve typedefs and implement public/private...
5743 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5745 tree
5746 add_instance_variable (class, public, declarator, declspecs, width)
5747 tree class;
5748 int public;
5749 tree declarator;
5750 tree declspecs;
5751 tree width;
5753 tree field_decl, raw_decl;
5755 raw_decl = build_tree_list (declspecs, declarator);
5757 if (CLASS_RAW_IVARS (class))
5758 chainon (CLASS_RAW_IVARS (class), raw_decl);
5759 else
5760 CLASS_RAW_IVARS (class) = raw_decl;
5762 field_decl = grokfield (declarator, declspecs, width);
5764 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5765 switch (public)
5767 case 0:
5768 TREE_PUBLIC (field_decl) = 0;
5769 TREE_PRIVATE (field_decl) = 0;
5770 TREE_PROTECTED (field_decl) = 1;
5771 break;
5773 case 1:
5774 TREE_PUBLIC (field_decl) = 1;
5775 TREE_PRIVATE (field_decl) = 0;
5776 TREE_PROTECTED (field_decl) = 0;
5777 break;
5779 case 2:
5780 TREE_PUBLIC (field_decl) = 0;
5781 TREE_PRIVATE (field_decl) = 1;
5782 TREE_PROTECTED (field_decl) = 0;
5783 break;
5787 if (CLASS_IVARS (class))
5788 chainon (CLASS_IVARS (class), field_decl);
5789 else
5790 CLASS_IVARS (class) = field_decl;
5792 return class;
5795 tree
5796 is_ivar (decl_chain, ident)
5797 tree decl_chain;
5798 tree ident;
5800 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5801 if (DECL_NAME (decl_chain) == ident)
5802 return decl_chain;
5803 return NULL_TREE;
5806 /* True if the ivar is private and we are not in its implementation. */
5809 is_private (decl)
5810 tree decl;
5812 if (TREE_PRIVATE (decl)
5813 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5815 error ("instance variable `%s' is declared private",
5816 IDENTIFIER_POINTER (DECL_NAME (decl)));
5817 return 1;
5819 else
5820 return 0;
5823 /* We have an instance variable reference;, check to see if it is public. */
5826 is_public (expr, identifier)
5827 tree expr;
5828 tree identifier;
5830 tree basetype = TREE_TYPE (expr);
5831 enum tree_code code = TREE_CODE (basetype);
5832 tree decl;
5834 if (code == RECORD_TYPE)
5836 if (TREE_STATIC_TEMPLATE (basetype))
5838 if (!lookup_interface (TYPE_NAME (basetype)))
5840 error ("cannot find interface declaration for `%s'",
5841 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5842 return 0;
5845 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5847 if (TREE_PUBLIC (decl))
5848 return 1;
5850 /* Important difference between the Stepstone translator:
5851 all instance variables should be public within the context
5852 of the implementation. */
5853 if (objc_implementation_context
5854 && (((TREE_CODE (objc_implementation_context)
5855 == CLASS_IMPLEMENTATION_TYPE)
5856 || (TREE_CODE (objc_implementation_context)
5857 == CATEGORY_IMPLEMENTATION_TYPE))
5858 && (CLASS_NAME (objc_implementation_context)
5859 == TYPE_NAME (basetype))))
5860 return ! is_private (decl);
5862 error ("instance variable `%s' is declared %s",
5863 IDENTIFIER_POINTER (identifier),
5864 TREE_PRIVATE (decl) ? "private" : "protected");
5865 return 0;
5869 else if (objc_implementation_context && (basetype == objc_object_reference))
5871 TREE_TYPE (expr) = uprivate_record;
5872 warning ("static access to object of type `id'");
5876 return 1;
5879 /* Make sure all entries in CHAIN are also in LIST. */
5881 static int
5882 check_methods (chain, list, mtype)
5883 tree chain;
5884 tree list;
5885 int mtype;
5887 int first = 1;
5889 while (chain)
5891 if (!lookup_method (list, chain))
5893 if (first)
5895 if (TREE_CODE (objc_implementation_context)
5896 == CLASS_IMPLEMENTATION_TYPE)
5897 warning ("incomplete implementation of class `%s'",
5898 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5899 else if (TREE_CODE (objc_implementation_context)
5900 == CATEGORY_IMPLEMENTATION_TYPE)
5901 warning ("incomplete implementation of category `%s'",
5902 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5903 first = 0;
5906 warning ("method definition for `%c%s' not found",
5907 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5910 chain = TREE_CHAIN (chain);
5913 return first;
5916 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5918 static int
5919 conforms_to_protocol (class, protocol)
5920 tree class;
5921 tree protocol;
5923 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5925 tree p = CLASS_PROTOCOL_LIST (class);
5926 while (p && TREE_VALUE (p) != protocol)
5927 p = TREE_CHAIN (p);
5929 if (!p)
5931 tree super = (CLASS_SUPER_NAME (class)
5932 ? lookup_interface (CLASS_SUPER_NAME (class))
5933 : NULL_TREE);
5934 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5935 if (!tmp)
5936 return 0;
5940 return 1;
5943 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5944 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5946 static int
5947 check_methods_accessible (chain, context, mtype)
5948 tree chain;
5949 tree context;
5950 int mtype;
5952 int first = 1;
5953 tree list;
5954 tree base_context = context;
5956 while (chain)
5958 context = base_context;
5959 while (context)
5961 if (mtype == '+')
5962 list = CLASS_CLS_METHODS (context);
5963 else
5964 list = CLASS_NST_METHODS (context);
5966 if (lookup_method (list, chain))
5967 break;
5969 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5970 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5971 context = (CLASS_SUPER_NAME (context)
5972 ? lookup_interface (CLASS_SUPER_NAME (context))
5973 : NULL_TREE);
5975 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5976 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5977 context = (CLASS_NAME (context)
5978 ? lookup_interface (CLASS_NAME (context))
5979 : NULL_TREE);
5980 else
5981 abort ();
5984 if (context == NULL_TREE)
5986 if (first)
5988 if (TREE_CODE (objc_implementation_context)
5989 == CLASS_IMPLEMENTATION_TYPE)
5990 warning ("incomplete implementation of class `%s'",
5991 IDENTIFIER_POINTER
5992 (CLASS_NAME (objc_implementation_context)));
5993 else if (TREE_CODE (objc_implementation_context)
5994 == CATEGORY_IMPLEMENTATION_TYPE)
5995 warning ("incomplete implementation of category `%s'",
5996 IDENTIFIER_POINTER
5997 (CLASS_SUPER_NAME (objc_implementation_context)));
5998 first = 0;
6000 warning ("method definition for `%c%s' not found",
6001 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6004 chain = TREE_CHAIN (chain); /* next method... */
6006 return first;
6009 /* Check whether the current interface (accessible via
6010 'objc_implementation_context') actually implements protocol P, along
6011 with any protocols that P inherits. */
6013 static void
6014 check_protocol (p, type, name)
6015 tree p;
6016 const char *type;
6017 const char *name;
6019 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6021 int f1, f2;
6023 /* Ensure that all protocols have bodies! */
6024 if (warn_protocol)
6026 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6027 CLASS_CLS_METHODS (objc_implementation_context),
6028 '+');
6029 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6030 CLASS_NST_METHODS (objc_implementation_context),
6031 '-');
6033 else
6035 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6036 objc_implementation_context,
6037 '+');
6038 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6039 objc_implementation_context,
6040 '-');
6043 if (!f1 || !f2)
6044 warning ("%s `%s' does not fully implement the `%s' protocol",
6045 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6048 /* Check protocols recursively. */
6049 if (PROTOCOL_LIST (p))
6051 tree subs = PROTOCOL_LIST (p);
6052 tree super_class =
6053 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6055 while (subs)
6057 tree sub = TREE_VALUE (subs);
6059 /* If the superclass does not conform to the protocols
6060 inherited by P, then we must! */
6061 if (!super_class || !conforms_to_protocol (super_class, sub))
6062 check_protocol (sub, type, name);
6063 subs = TREE_CHAIN (subs);
6068 /* Check whether the current interface (accessible via
6069 'objc_implementation_context') actually implements the protocols listed
6070 in PROTO_LIST. */
6072 static void
6073 check_protocols (proto_list, type, name)
6074 tree proto_list;
6075 const char *type;
6076 const char *name;
6078 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6080 tree p = TREE_VALUE (proto_list);
6082 check_protocol (p, type, name);
6086 /* Make sure that the class CLASS_NAME is defined
6087 CODE says which kind of thing CLASS_NAME ought to be.
6088 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6089 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6091 tree
6092 start_class (code, class_name, super_name, protocol_list)
6093 enum tree_code code;
6094 tree class_name;
6095 tree super_name;
6096 tree protocol_list;
6098 tree class, decl;
6100 if (objc_implementation_context)
6102 warning ("`@end' missing in implementation context");
6103 finish_class (objc_implementation_context);
6104 objc_ivar_chain = NULL_TREE;
6105 objc_implementation_context = NULL_TREE;
6108 class = make_node (code);
6109 TYPE_BINFO (class) = make_tree_vec (BINFO_ELTS);
6111 CLASS_NAME (class) = class_name;
6112 CLASS_SUPER_NAME (class) = super_name;
6113 CLASS_CLS_METHODS (class) = NULL_TREE;
6115 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6117 error ("`%s' redeclared as different kind of symbol",
6118 IDENTIFIER_POINTER (class_name));
6119 error_with_decl (decl, "previous declaration of `%s'");
6122 if (code == CLASS_IMPLEMENTATION_TYPE)
6125 tree chain;
6127 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6128 if (TREE_VALUE (chain) == class_name)
6130 error ("reimplementation of class `%s'",
6131 IDENTIFIER_POINTER (class_name));
6132 return error_mark_node;
6134 implemented_classes = tree_cons (NULL_TREE, class_name,
6135 implemented_classes);
6138 /* Pre-build the following entities - for speed/convenience. */
6139 if (!self_id)
6140 self_id = get_identifier ("self");
6141 if (!ucmd_id)
6142 ucmd_id = get_identifier ("_cmd");
6143 if (!unused_list)
6144 unused_list
6145 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6146 if (!objc_super_template)
6147 objc_super_template = build_super_template ();
6149 /* Reset for multiple classes per file. */
6150 method_slot = 0;
6152 objc_implementation_context = class;
6154 /* Lookup the interface for this implementation. */
6156 if (!(implementation_template = lookup_interface (class_name)))
6158 warning ("cannot find interface declaration for `%s'",
6159 IDENTIFIER_POINTER (class_name));
6160 add_class (implementation_template = objc_implementation_context);
6163 /* If a super class has been specified in the implementation,
6164 insure it conforms to the one specified in the interface. */
6166 if (super_name
6167 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6169 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6170 const char *const name =
6171 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6172 error ("conflicting super class name `%s'",
6173 IDENTIFIER_POINTER (super_name));
6174 error ("previous declaration of `%s'", name);
6177 else if (! super_name)
6179 CLASS_SUPER_NAME (objc_implementation_context)
6180 = CLASS_SUPER_NAME (implementation_template);
6184 else if (code == CLASS_INTERFACE_TYPE)
6186 if (lookup_interface (class_name))
6187 warning ("duplicate interface declaration for class `%s'",
6188 IDENTIFIER_POINTER (class_name));
6189 else
6190 add_class (class);
6192 if (protocol_list)
6193 CLASS_PROTOCOL_LIST (class)
6194 = lookup_and_install_protocols (protocol_list);
6197 else if (code == CATEGORY_INTERFACE_TYPE)
6199 tree class_category_is_assoc_with;
6201 /* For a category, class_name is really the name of the class that
6202 the following set of methods will be associated with. We must
6203 find the interface so that can derive the objects template. */
6205 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6207 error ("cannot find interface declaration for `%s'",
6208 IDENTIFIER_POINTER (class_name));
6209 exit (FATAL_EXIT_CODE);
6211 else
6212 add_category (class_category_is_assoc_with, class);
6214 if (protocol_list)
6215 CLASS_PROTOCOL_LIST (class)
6216 = lookup_and_install_protocols (protocol_list);
6219 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6221 /* Pre-build the following entities for speed/convenience. */
6222 if (!self_id)
6223 self_id = get_identifier ("self");
6224 if (!ucmd_id)
6225 ucmd_id = get_identifier ("_cmd");
6226 if (!unused_list)
6227 unused_list
6228 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6229 if (!objc_super_template)
6230 objc_super_template = build_super_template ();
6232 /* Reset for multiple classes per file. */
6233 method_slot = 0;
6235 objc_implementation_context = class;
6237 /* For a category, class_name is really the name of the class that
6238 the following set of methods will be associated with. We must
6239 find the interface so that can derive the objects template. */
6241 if (!(implementation_template = lookup_interface (class_name)))
6243 error ("cannot find interface declaration for `%s'",
6244 IDENTIFIER_POINTER (class_name));
6245 exit (FATAL_EXIT_CODE);
6248 return class;
6251 tree
6252 continue_class (class)
6253 tree class;
6255 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6256 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6258 struct imp_entry *imp_entry;
6259 tree ivar_context;
6261 /* Check consistency of the instance variables. */
6263 if (CLASS_IVARS (class))
6264 check_ivars (implementation_template, class);
6266 /* code generation */
6268 ivar_context = build_private_template (implementation_template);
6270 if (!objc_class_template)
6271 build_class_template ();
6273 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6275 imp_entry->next = imp_list;
6276 imp_entry->imp_context = class;
6277 imp_entry->imp_template = implementation_template;
6279 synth_forward_declarations ();
6280 imp_entry->class_decl = UOBJC_CLASS_decl;
6281 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6283 /* Append to front and increment count. */
6284 imp_list = imp_entry;
6285 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6286 imp_count++;
6287 else
6288 cat_count++;
6290 return ivar_context;
6293 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6295 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6297 if (!TYPE_FIELDS (record))
6299 finish_struct (record, get_class_ivars (class), NULL_TREE);
6300 CLASS_STATIC_TEMPLATE (class) = record;
6302 /* Mark this record as a class template for static typing. */
6303 TREE_STATIC_TEMPLATE (record) = 1;
6306 return NULL_TREE;
6309 else
6310 return error_mark_node;
6313 /* This is called once we see the "@end" in an interface/implementation. */
6315 void
6316 finish_class (class)
6317 tree class;
6319 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6321 /* All code generation is done in finish_objc. */
6323 if (implementation_template != objc_implementation_context)
6325 /* Ensure that all method listed in the interface contain bodies. */
6326 check_methods (CLASS_CLS_METHODS (implementation_template),
6327 CLASS_CLS_METHODS (objc_implementation_context), '+');
6328 check_methods (CLASS_NST_METHODS (implementation_template),
6329 CLASS_NST_METHODS (objc_implementation_context), '-');
6331 if (CLASS_PROTOCOL_LIST (implementation_template))
6332 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6333 "class",
6334 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6338 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6340 tree category = CLASS_CATEGORY_LIST (implementation_template);
6342 /* Find the category interface from the class it is associated with. */
6343 while (category)
6345 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6346 break;
6347 category = CLASS_CATEGORY_LIST (category);
6350 if (category)
6352 /* Ensure all method listed in the interface contain bodies. */
6353 check_methods (CLASS_CLS_METHODS (category),
6354 CLASS_CLS_METHODS (objc_implementation_context), '+');
6355 check_methods (CLASS_NST_METHODS (category),
6356 CLASS_NST_METHODS (objc_implementation_context), '-');
6358 if (CLASS_PROTOCOL_LIST (category))
6359 check_protocols (CLASS_PROTOCOL_LIST (category),
6360 "category",
6361 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6365 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6367 tree decl_specs;
6368 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6369 char *string = (char *) alloca (strlen (class_name) + 3);
6371 /* extern struct objc_object *_<my_name>; */
6373 sprintf (string, "_%s", class_name);
6375 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6376 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6377 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6378 decl_specs);
6382 static tree
6383 add_protocol (protocol)
6384 tree protocol;
6386 /* Put protocol on list in reverse order. */
6387 TREE_CHAIN (protocol) = protocol_chain;
6388 protocol_chain = protocol;
6389 return protocol_chain;
6392 static tree
6393 lookup_protocol (ident)
6394 tree ident;
6396 tree chain;
6398 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6399 if (ident == PROTOCOL_NAME (chain))
6400 return chain;
6402 return NULL_TREE;
6405 /* This function forward declares the protocols named by NAMES. If
6406 they are already declared or defined, the function has no effect. */
6408 void
6409 objc_declare_protocols (names)
6410 tree names;
6412 tree list;
6414 for (list = names; list; list = TREE_CHAIN (list))
6416 tree name = TREE_VALUE (list);
6418 if (lookup_protocol (name) == NULL_TREE)
6420 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6422 TYPE_BINFO (protocol) = make_tree_vec (2);
6423 PROTOCOL_NAME (protocol) = name;
6424 PROTOCOL_LIST (protocol) = NULL_TREE;
6425 add_protocol (protocol);
6426 PROTOCOL_DEFINED (protocol) = 0;
6427 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6432 tree
6433 start_protocol (code, name, list)
6434 enum tree_code code;
6435 tree name;
6436 tree list;
6438 tree protocol;
6440 /* This is as good a place as any. Need to invoke
6441 push_tag_toplevel. */
6442 if (!objc_protocol_template)
6443 objc_protocol_template = build_protocol_template ();
6445 protocol = lookup_protocol (name);
6447 if (!protocol)
6449 protocol = make_node (code);
6450 TYPE_BINFO (protocol) = make_tree_vec (2);
6452 PROTOCOL_NAME (protocol) = name;
6453 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6454 add_protocol (protocol);
6455 PROTOCOL_DEFINED (protocol) = 1;
6456 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6458 check_protocol_recursively (protocol, list);
6460 else if (! PROTOCOL_DEFINED (protocol))
6462 PROTOCOL_DEFINED (protocol) = 1;
6463 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6465 check_protocol_recursively (protocol, list);
6467 else
6469 warning ("duplicate declaration for protocol `%s'",
6470 IDENTIFIER_POINTER (name));
6472 return protocol;
6475 void
6476 finish_protocol (protocol)
6477 tree protocol ATTRIBUTE_UNUSED;
6482 /* "Encode" a data type into a string, which grows in util_obstack.
6483 ??? What is the FORMAT? Someone please document this! */
6485 static void
6486 encode_type_qualifiers (declspecs)
6487 tree declspecs;
6489 tree spec;
6491 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6493 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6494 obstack_1grow (&util_obstack, 'r');
6495 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6496 obstack_1grow (&util_obstack, 'n');
6497 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6498 obstack_1grow (&util_obstack, 'N');
6499 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6500 obstack_1grow (&util_obstack, 'o');
6501 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6502 obstack_1grow (&util_obstack, 'O');
6503 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6504 obstack_1grow (&util_obstack, 'R');
6505 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6506 obstack_1grow (&util_obstack, 'V');
6510 /* Encode a pointer type. */
6512 static void
6513 encode_pointer (type, curtype, format)
6514 tree type;
6515 int curtype;
6516 int format;
6518 tree pointer_to = TREE_TYPE (type);
6520 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6522 if (TYPE_NAME (pointer_to)
6523 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6525 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6527 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6529 obstack_1grow (&util_obstack, '@');
6530 return;
6532 else if (TREE_STATIC_TEMPLATE (pointer_to))
6534 if (generating_instance_variables)
6536 obstack_1grow (&util_obstack, '@');
6537 obstack_1grow (&util_obstack, '"');
6538 obstack_grow (&util_obstack, name, strlen (name));
6539 obstack_1grow (&util_obstack, '"');
6540 return;
6542 else
6544 obstack_1grow (&util_obstack, '@');
6545 return;
6548 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6550 obstack_1grow (&util_obstack, '#');
6551 return;
6553 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6555 obstack_1grow (&util_obstack, ':');
6556 return;
6560 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6561 && TYPE_MODE (pointer_to) == QImode)
6563 obstack_1grow (&util_obstack, '*');
6564 return;
6567 /* We have a type that does not get special treatment. */
6569 /* NeXT extension */
6570 obstack_1grow (&util_obstack, '^');
6571 encode_type (pointer_to, curtype, format);
6574 static void
6575 encode_array (type, curtype, format)
6576 tree type;
6577 int curtype;
6578 int format;
6580 tree an_int_cst = TYPE_SIZE (type);
6581 tree array_of = TREE_TYPE (type);
6582 char buffer[40];
6584 /* An incomplete array is treated like a pointer. */
6585 if (an_int_cst == NULL)
6587 encode_pointer (type, curtype, format);
6588 return;
6591 sprintf (buffer, "[%ld",
6592 (long) (TREE_INT_CST_LOW (an_int_cst)
6593 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6595 obstack_grow (&util_obstack, buffer, strlen (buffer));
6596 encode_type (array_of, curtype, format);
6597 obstack_1grow (&util_obstack, ']');
6598 return;
6601 static void
6602 encode_aggregate_within (type, curtype, format, left, right)
6603 tree type;
6604 int curtype;
6605 int format;
6606 int left;
6607 int right;
6609 /* The RECORD_TYPE may in fact be a typedef! For purposes
6610 of encoding, we need the real underlying enchilada. */
6611 if (TYPE_MAIN_VARIANT (type))
6612 type = TYPE_MAIN_VARIANT (type);
6614 if (obstack_object_size (&util_obstack) > 0
6615 && *(obstack_next_free (&util_obstack) - 1) == '^')
6617 tree name = TYPE_NAME (type);
6619 /* we have a reference; this is a NeXT extension. */
6621 if (obstack_object_size (&util_obstack) - curtype == 1
6622 && format == OBJC_ENCODE_INLINE_DEFS)
6624 /* Output format of struct for first level only. */
6625 tree fields = TYPE_FIELDS (type);
6627 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6629 obstack_1grow (&util_obstack, left);
6630 obstack_grow (&util_obstack,
6631 IDENTIFIER_POINTER (name),
6632 strlen (IDENTIFIER_POINTER (name)));
6633 obstack_1grow (&util_obstack, '=');
6635 else
6637 obstack_1grow (&util_obstack, left);
6638 obstack_grow (&util_obstack, "?=", 2);
6641 for ( ; fields; fields = TREE_CHAIN (fields))
6642 encode_field_decl (fields, curtype, format);
6644 obstack_1grow (&util_obstack, right);
6647 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6649 obstack_1grow (&util_obstack, left);
6650 obstack_grow (&util_obstack,
6651 IDENTIFIER_POINTER (name),
6652 strlen (IDENTIFIER_POINTER (name)));
6653 obstack_1grow (&util_obstack, right);
6656 else
6658 /* We have an untagged structure or a typedef. */
6659 obstack_1grow (&util_obstack, left);
6660 obstack_1grow (&util_obstack, '?');
6661 obstack_1grow (&util_obstack, right);
6665 else
6667 tree name = TYPE_NAME (type);
6668 tree fields = TYPE_FIELDS (type);
6670 if (format == OBJC_ENCODE_INLINE_DEFS
6671 || generating_instance_variables)
6673 obstack_1grow (&util_obstack, left);
6674 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6675 obstack_grow (&util_obstack,
6676 IDENTIFIER_POINTER (name),
6677 strlen (IDENTIFIER_POINTER (name)));
6678 else
6679 obstack_1grow (&util_obstack, '?');
6681 obstack_1grow (&util_obstack, '=');
6683 for (; fields; fields = TREE_CHAIN (fields))
6685 if (generating_instance_variables)
6687 tree fname = DECL_NAME (fields);
6689 obstack_1grow (&util_obstack, '"');
6690 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6692 obstack_grow (&util_obstack,
6693 IDENTIFIER_POINTER (fname),
6694 strlen (IDENTIFIER_POINTER (fname)));
6697 obstack_1grow (&util_obstack, '"');
6700 encode_field_decl (fields, curtype, format);
6703 obstack_1grow (&util_obstack, right);
6706 else
6708 obstack_1grow (&util_obstack, left);
6709 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6710 obstack_grow (&util_obstack,
6711 IDENTIFIER_POINTER (name),
6712 strlen (IDENTIFIER_POINTER (name)));
6713 else
6714 /* We have an untagged structure or a typedef. */
6715 obstack_1grow (&util_obstack, '?');
6717 obstack_1grow (&util_obstack, right);
6722 static void
6723 encode_aggregate (type, curtype, format)
6724 tree type;
6725 int curtype;
6726 int format;
6728 enum tree_code code = TREE_CODE (type);
6730 switch (code)
6732 case RECORD_TYPE:
6734 encode_aggregate_within(type, curtype, format, '{', '}');
6735 break;
6737 case UNION_TYPE:
6739 encode_aggregate_within(type, curtype, format, '(', ')');
6740 break;
6743 case ENUMERAL_TYPE:
6744 obstack_1grow (&util_obstack, 'i');
6745 break;
6747 default:
6748 break;
6752 /* Support bitfields. The current version of Objective-C does not support
6753 them. The string will consist of one or more "b:n"'s where n is an
6754 integer describing the width of the bitfield. Currently, classes in
6755 the kit implement a method "-(char *)describeBitfieldStruct:" that
6756 simulates this. If they do not implement this method, the archiver
6757 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6758 according to the GNU compiler. After looking at the "kit", it appears
6759 that all classes currently rely on this default behavior, rather than
6760 hand generating this string (which is tedious). */
6762 static void
6763 encode_bitfield (width)
6764 int width;
6766 char buffer[40];
6767 sprintf (buffer, "b%d", width);
6768 obstack_grow (&util_obstack, buffer, strlen (buffer));
6771 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6773 static void
6774 encode_type (type, curtype, format)
6775 tree type;
6776 int curtype;
6777 int format;
6779 enum tree_code code = TREE_CODE (type);
6781 if (code == INTEGER_TYPE)
6783 if (integer_zerop (TYPE_MIN_VALUE (type)))
6785 /* Unsigned integer types. */
6787 if (TYPE_MODE (type) == QImode)
6788 obstack_1grow (&util_obstack, 'C');
6789 else if (TYPE_MODE (type) == HImode)
6790 obstack_1grow (&util_obstack, 'S');
6791 else if (TYPE_MODE (type) == SImode)
6793 if (type == long_unsigned_type_node)
6794 obstack_1grow (&util_obstack, 'L');
6795 else
6796 obstack_1grow (&util_obstack, 'I');
6798 else if (TYPE_MODE (type) == DImode)
6799 obstack_1grow (&util_obstack, 'Q');
6802 else
6803 /* Signed integer types. */
6805 if (TYPE_MODE (type) == QImode)
6806 obstack_1grow (&util_obstack, 'c');
6807 else if (TYPE_MODE (type) == HImode)
6808 obstack_1grow (&util_obstack, 's');
6809 else if (TYPE_MODE (type) == SImode)
6811 if (type == long_integer_type_node)
6812 obstack_1grow (&util_obstack, 'l');
6813 else
6814 obstack_1grow (&util_obstack, 'i');
6817 else if (TYPE_MODE (type) == DImode)
6818 obstack_1grow (&util_obstack, 'q');
6822 else if (code == REAL_TYPE)
6824 /* Floating point types. */
6826 if (TYPE_MODE (type) == SFmode)
6827 obstack_1grow (&util_obstack, 'f');
6828 else if (TYPE_MODE (type) == DFmode
6829 || TYPE_MODE (type) == TFmode)
6830 obstack_1grow (&util_obstack, 'd');
6833 else if (code == VOID_TYPE)
6834 obstack_1grow (&util_obstack, 'v');
6836 else if (code == ARRAY_TYPE)
6837 encode_array (type, curtype, format);
6839 else if (code == POINTER_TYPE)
6840 encode_pointer (type, curtype, format);
6842 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6843 encode_aggregate (type, curtype, format);
6845 else if (code == FUNCTION_TYPE) /* '?' */
6846 obstack_1grow (&util_obstack, '?');
6849 static void
6850 encode_complete_bitfield (position, type, size)
6851 int position;
6852 tree type;
6853 int size;
6855 enum tree_code code = TREE_CODE (type);
6856 char buffer[40];
6857 char charType = '?';
6859 if (code == INTEGER_TYPE)
6861 if (integer_zerop (TYPE_MIN_VALUE (type)))
6863 /* Unsigned integer types. */
6865 if (TYPE_MODE (type) == QImode)
6866 charType = 'C';
6867 else if (TYPE_MODE (type) == HImode)
6868 charType = 'S';
6869 else if (TYPE_MODE (type) == SImode)
6871 if (type == long_unsigned_type_node)
6872 charType = 'L';
6873 else
6874 charType = 'I';
6876 else if (TYPE_MODE (type) == DImode)
6877 charType = 'Q';
6880 else
6881 /* Signed integer types. */
6883 if (TYPE_MODE (type) == QImode)
6884 charType = 'c';
6885 else if (TYPE_MODE (type) == HImode)
6886 charType = 's';
6887 else if (TYPE_MODE (type) == SImode)
6889 if (type == long_integer_type_node)
6890 charType = 'l';
6891 else
6892 charType = 'i';
6895 else if (TYPE_MODE (type) == DImode)
6896 charType = 'q';
6899 else if (code == ENUMERAL_TYPE)
6900 charType = 'i';
6901 else
6902 abort ();
6904 sprintf (buffer, "b%d%c%d", position, charType, size);
6905 obstack_grow (&util_obstack, buffer, strlen (buffer));
6908 static void
6909 encode_field_decl (field_decl, curtype, format)
6910 tree field_decl;
6911 int curtype;
6912 int format;
6914 tree type;
6916 type = TREE_TYPE (field_decl);
6918 /* If this field is obviously a bitfield, or is a bitfield that has been
6919 clobbered to look like a ordinary integer mode, go ahead and generate
6920 the bitfield typing information. */
6921 if (flag_next_runtime)
6923 if (DECL_BIT_FIELD_TYPE (field_decl))
6924 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6925 else
6926 encode_type (TREE_TYPE (field_decl), curtype, format);
6928 else
6930 if (DECL_BIT_FIELD_TYPE (field_decl))
6931 encode_complete_bitfield (int_bit_position (field_decl),
6932 DECL_BIT_FIELD_TYPE (field_decl),
6933 tree_low_cst (DECL_SIZE (field_decl), 1));
6934 else
6935 encode_type (TREE_TYPE (field_decl), curtype, format);
6939 static tree
6940 objc_expr_last (complex_expr)
6941 tree complex_expr;
6943 tree next;
6945 if (complex_expr)
6946 while ((next = TREE_OPERAND (complex_expr, 0)))
6947 complex_expr = next;
6949 return complex_expr;
6952 /* Transform a method definition into a function definition as follows:
6953 - synthesize the first two arguments, "self" and "_cmd". */
6955 void
6956 start_method_def (method)
6957 tree method;
6959 tree decl_specs;
6961 /* Required to implement _msgSuper. */
6962 objc_method_context = method;
6963 UOBJC_SUPER_decl = NULL_TREE;
6965 /* Must be called BEFORE start_function. */
6966 pushlevel (0);
6968 /* Generate prototype declarations for arguments..."new-style". */
6970 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6971 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6972 else
6973 /* Really a `struct objc_class *'. However, we allow people to
6974 assign to self, which changes its type midstream. */
6975 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6977 push_parm_decl (build_tree_list
6978 (build_tree_list (decl_specs,
6979 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6980 unused_list));
6982 decl_specs = build_tree_list (NULL_TREE,
6983 xref_tag (RECORD_TYPE,
6984 get_identifier (TAG_SELECTOR)));
6985 push_parm_decl (build_tree_list
6986 (build_tree_list (decl_specs,
6987 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6988 unused_list));
6990 /* Generate argument declarations if a keyword_decl. */
6991 if (METHOD_SEL_ARGS (method))
6993 tree arglist = METHOD_SEL_ARGS (method);
6996 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6997 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6999 if (arg_decl)
7001 tree last_expr = objc_expr_last (arg_decl);
7003 /* Unite the abstract decl with its name. */
7004 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7005 push_parm_decl (build_tree_list
7006 (build_tree_list (arg_spec, arg_decl),
7007 NULL_TREE));
7009 /* Unhook: restore the abstract declarator. */
7010 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7013 else
7014 push_parm_decl (build_tree_list
7015 (build_tree_list (arg_spec,
7016 KEYWORD_ARG_NAME (arglist)),
7017 NULL_TREE));
7019 arglist = TREE_CHAIN (arglist);
7021 while (arglist);
7024 if (METHOD_ADD_ARGS (method) != NULL_TREE
7025 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7027 /* We have a variable length selector - in "prototype" format. */
7028 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7029 while (akey)
7031 /* This must be done prior to calling pushdecl. pushdecl is
7032 going to change our chain on us. */
7033 tree nextkey = TREE_CHAIN (akey);
7034 pushdecl (akey);
7035 akey = nextkey;
7040 static void
7041 warn_with_method (message, mtype, method)
7042 const char *message;
7043 int mtype;
7044 tree method;
7046 /* Add a readable method name to the warning. */
7047 warning ("%H%s `%c%s'", &DECL_SOURCE_LOCATION (method),
7048 message, mtype, gen_method_decl (method, errbuf));
7051 /* Return 1 if METHOD is consistent with PROTO. */
7053 static int
7054 comp_method_with_proto (method, proto)
7055 tree method, proto;
7057 /* Create a function template node at most once. */
7058 if (!function1_template)
7059 function1_template = make_node (FUNCTION_TYPE);
7061 /* Install argument types - normally set by build_function_type. */
7062 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7064 /* install return type */
7065 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7067 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7070 /* Return 1 if PROTO1 is consistent with PROTO2. */
7072 static int
7073 comp_proto_with_proto (proto0, proto1)
7074 tree proto0, proto1;
7076 /* Create a couple of function_template nodes at most once. */
7077 if (!function1_template)
7078 function1_template = make_node (FUNCTION_TYPE);
7079 if (!function2_template)
7080 function2_template = make_node (FUNCTION_TYPE);
7082 /* Install argument types; normally set by build_function_type. */
7083 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
7084 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
7086 /* Install return type. */
7087 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
7088 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
7090 return comptypes (function1_template, function2_template);
7093 /* - Generate an identifier for the function. the format is "_n_cls",
7094 where 1 <= n <= nMethods, and cls is the name the implementation we
7095 are processing.
7096 - Install the return type from the method declaration.
7097 - If we have a prototype, check for type consistency. */
7099 static void
7100 really_start_method (method, parmlist)
7101 tree method, parmlist;
7103 tree sc_spec, ret_spec, ret_decl, decl_specs;
7104 tree method_decl, method_id;
7105 const char *sel_name, *class_name, *cat_name;
7106 char *buf;
7108 /* Synth the storage class & assemble the return type. */
7109 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7110 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7111 decl_specs = chainon (sc_spec, ret_spec);
7113 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7114 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7115 cat_name = ((TREE_CODE (objc_implementation_context)
7116 == CLASS_IMPLEMENTATION_TYPE)
7117 ? NULL
7118 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7119 method_slot++;
7121 /* Make sure this is big enough for any plausible method label. */
7122 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7123 + (cat_name ? strlen (cat_name) : 0));
7125 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7126 class_name, cat_name, sel_name, method_slot);
7128 method_id = get_identifier (buf);
7130 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7132 /* Check the declarator portion of the return type for the method. */
7133 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7135 /* Unite the complex decl (specified in the abstract decl) with the
7136 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7137 tree save_expr = objc_expr_last (ret_decl);
7139 TREE_OPERAND (save_expr, 0) = method_decl;
7140 method_decl = ret_decl;
7142 /* Fool the parser into thinking it is starting a function. */
7143 start_function (decl_specs, method_decl, NULL_TREE);
7145 /* Unhook: this has the effect of restoring the abstract declarator. */
7146 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7149 else
7151 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7153 /* Fool the parser into thinking it is starting a function. */
7154 start_function (decl_specs, method_decl, NULL_TREE);
7156 /* Unhook: this has the effect of restoring the abstract declarator. */
7157 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7160 METHOD_DEFINITION (method) = current_function_decl;
7162 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7164 if (implementation_template != objc_implementation_context)
7166 tree proto;
7168 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7169 proto = lookup_instance_method_static (implementation_template,
7170 METHOD_SEL_NAME (method));
7171 else
7172 proto = lookup_class_method_static (implementation_template,
7173 METHOD_SEL_NAME (method));
7175 if (proto && ! comp_method_with_proto (method, proto))
7177 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7179 warn_with_method ("conflicting types for", type, method);
7180 warn_with_method ("previous declaration of", type, proto);
7185 /* The following routine is always called...this "architecture" is to
7186 accommodate "old-style" variable length selectors.
7188 - a:a b:b // prototype ; id c; id d; // old-style. */
7190 void
7191 continue_method_def ()
7193 tree parmlist;
7195 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7196 /* We have a `, ...' immediately following the selector. */
7197 parmlist = get_parm_info (0);
7198 else
7199 parmlist = get_parm_info (1); /* place a `void_at_end' */
7201 /* Set self_decl from the first argument...this global is used by
7202 build_ivar_reference calling build_indirect_ref. */
7203 self_decl = TREE_PURPOSE (parmlist);
7205 poplevel (0, 0, 0);
7206 really_start_method (objc_method_context, parmlist);
7207 store_parm_decls ();
7210 /* Called by the parser, from the `pushlevel' production. */
7212 void
7213 add_objc_decls ()
7215 if (!UOBJC_SUPER_decl)
7217 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7218 build_tree_list (NULL_TREE,
7219 objc_super_template),
7220 0, NULL_TREE);
7222 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7224 /* This prevents `unused variable' warnings when compiling with -Wall. */
7225 TREE_USED (UOBJC_SUPER_decl) = 1;
7226 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7230 /* _n_Method (id self, SEL sel, ...)
7232 struct objc_super _S;
7233 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7234 } */
7236 tree
7237 get_super_receiver ()
7239 if (objc_method_context)
7241 tree super_expr, super_expr_list;
7243 /* Set receiver to self. */
7244 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7245 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7246 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7248 /* Set class to begin searching. */
7249 super_expr = build_component_ref (UOBJC_SUPER_decl,
7250 get_identifier ("class"));
7252 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7254 /* [_cls, __cls]Super are "pre-built" in
7255 synth_forward_declarations. */
7257 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7258 ((TREE_CODE (objc_method_context)
7259 == INSTANCE_METHOD_DECL)
7260 ? ucls_super_ref
7261 : uucls_super_ref));
7264 else
7265 /* We have a category. */
7267 tree super_name = CLASS_SUPER_NAME (implementation_template);
7268 tree super_class;
7270 /* Barf if super used in a category of Object. */
7271 if (!super_name)
7273 error ("no super class declared in interface for `%s'",
7274 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7275 return error_mark_node;
7278 if (flag_next_runtime)
7280 super_class = get_class_reference (super_name);
7281 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7282 /* Cast the super class to 'id', since the user may not have
7283 included <objc/objc-class.h>, leaving 'struct objc_class'
7284 an incomplete type. */
7285 super_class
7286 = build_component_ref (build_indirect_ref
7287 (build_c_cast (id_type, super_class), "->"),
7288 get_identifier ("isa"));
7290 else
7292 add_class_reference (super_name);
7293 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7294 ? objc_get_class_decl : objc_get_meta_class_decl);
7295 assemble_external (super_class);
7296 super_class
7297 = build_function_call
7298 (super_class,
7299 build_tree_list
7300 (NULL_TREE,
7301 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7302 IDENTIFIER_POINTER (super_name))));
7305 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7306 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7309 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7311 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7312 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7314 return build_compound_expr (super_expr_list);
7316 else
7318 error ("[super ...] must appear in a method context");
7319 return error_mark_node;
7323 static tree
7324 encode_method_def (func_decl)
7325 tree func_decl;
7327 tree parms;
7328 int stack_size;
7329 HOST_WIDE_INT max_parm_end = 0;
7330 char buffer[40];
7331 tree result;
7333 /* Return type. */
7334 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7335 obstack_object_size (&util_obstack),
7336 OBJC_ENCODE_INLINE_DEFS);
7338 /* Stack size. */
7339 for (parms = DECL_ARGUMENTS (func_decl); parms;
7340 parms = TREE_CHAIN (parms))
7342 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7343 + int_size_in_bytes (TREE_TYPE (parms)));
7345 if (! offset_is_register && parm_end > max_parm_end)
7346 max_parm_end = parm_end;
7349 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7351 sprintf (buffer, "%d", stack_size);
7352 obstack_grow (&util_obstack, buffer, strlen (buffer));
7354 /* Argument types. */
7355 for (parms = DECL_ARGUMENTS (func_decl); parms;
7356 parms = TREE_CHAIN (parms))
7358 /* Type. */
7359 encode_type (TREE_TYPE (parms),
7360 obstack_object_size (&util_obstack),
7361 OBJC_ENCODE_INLINE_DEFS);
7363 /* Compute offset. */
7364 sprintf (buffer, "%d", forwarding_offset (parms));
7366 /* Indicate register. */
7367 if (offset_is_register)
7368 obstack_1grow (&util_obstack, '+');
7370 obstack_grow (&util_obstack, buffer, strlen (buffer));
7373 /* Null terminate string. */
7374 obstack_1grow (&util_obstack, 0);
7375 result = get_identifier (obstack_finish (&util_obstack));
7376 obstack_free (&util_obstack, util_firstobj);
7377 return result;
7380 static void
7381 objc_expand_function_end ()
7383 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7386 void
7387 finish_method_def ()
7389 lang_expand_function_end = objc_expand_function_end;
7390 finish_function (0, 1);
7391 lang_expand_function_end = NULL;
7393 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7394 since the optimizer may find "may be used before set" errors. */
7395 objc_method_context = NULL_TREE;
7398 #if 0
7400 lang_report_error_function (decl)
7401 tree decl;
7403 if (objc_method_context)
7405 fprintf (stderr, "In method `%s'\n",
7406 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7407 return 1;
7410 else
7411 return 0;
7413 #endif
7415 static int
7416 is_complex_decl (type)
7417 tree type;
7419 return (TREE_CODE (type) == ARRAY_TYPE
7420 || TREE_CODE (type) == FUNCTION_TYPE
7421 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7425 /* Code to convert a decl node into text for a declaration in C. */
7427 static char tmpbuf[256];
7429 static void
7430 adorn_decl (decl, str)
7431 tree decl;
7432 char *str;
7434 enum tree_code code = TREE_CODE (decl);
7436 if (code == ARRAY_REF)
7438 tree an_int_cst = TREE_OPERAND (decl, 1);
7440 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7441 sprintf (str + strlen (str), "[%ld]",
7442 (long) TREE_INT_CST_LOW (an_int_cst));
7443 else
7444 strcat (str, "[]");
7447 else if (code == ARRAY_TYPE)
7449 tree an_int_cst = TYPE_SIZE (decl);
7450 tree array_of = TREE_TYPE (decl);
7452 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7453 sprintf (str + strlen (str), "[%ld]",
7454 (long) (TREE_INT_CST_LOW (an_int_cst)
7455 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7456 else
7457 strcat (str, "[]");
7460 else if (code == CALL_EXPR)
7462 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7464 strcat (str, "(");
7465 while (chain)
7467 gen_declaration_1 (chain, str);
7468 chain = TREE_CHAIN (chain);
7469 if (chain)
7470 strcat (str, ", ");
7472 strcat (str, ")");
7475 else if (code == FUNCTION_TYPE)
7477 tree chain = TYPE_ARG_TYPES (decl);
7479 strcat (str, "(");
7480 while (chain && TREE_VALUE (chain) != void_type_node)
7482 gen_declaration_1 (TREE_VALUE (chain), str);
7483 chain = TREE_CHAIN (chain);
7484 if (chain && TREE_VALUE (chain) != void_type_node)
7485 strcat (str, ", ");
7487 strcat (str, ")");
7490 else if (code == INDIRECT_REF)
7492 strcpy (tmpbuf, "*");
7493 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7495 tree chain;
7497 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7498 chain;
7499 chain = TREE_CHAIN (chain))
7501 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7503 strcat (tmpbuf, " ");
7504 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7507 if (str[0])
7508 strcat (tmpbuf, " ");
7510 strcat (tmpbuf, str);
7511 strcpy (str, tmpbuf);
7514 else if (code == POINTER_TYPE)
7516 strcpy (tmpbuf, "*");
7517 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7519 if (TREE_READONLY (decl))
7520 strcat (tmpbuf, " const");
7521 if (TYPE_VOLATILE (decl))
7522 strcat (tmpbuf, " volatile");
7523 if (str[0])
7524 strcat (tmpbuf, " ");
7526 strcat (tmpbuf, str);
7527 strcpy (str, tmpbuf);
7531 static char *
7532 gen_declarator (decl, buf, name)
7533 tree decl;
7534 char *buf;
7535 const char *name;
7537 if (decl)
7539 enum tree_code code = TREE_CODE (decl);
7540 char *str;
7541 tree op;
7542 int wrap = 0;
7544 switch (code)
7546 case ARRAY_REF:
7547 case INDIRECT_REF:
7548 case CALL_EXPR:
7549 op = TREE_OPERAND (decl, 0);
7551 /* We have a pointer to a function or array...(*)(), (*)[] */
7552 if ((code == ARRAY_REF || code == CALL_EXPR)
7553 && op && TREE_CODE (op) == INDIRECT_REF)
7554 wrap = 1;
7556 str = gen_declarator (op, buf, name);
7558 if (wrap)
7560 strcpy (tmpbuf, "(");
7561 strcat (tmpbuf, str);
7562 strcat (tmpbuf, ")");
7563 strcpy (str, tmpbuf);
7566 adorn_decl (decl, str);
7567 break;
7569 case ARRAY_TYPE:
7570 case FUNCTION_TYPE:
7571 case POINTER_TYPE:
7572 strcpy (buf, name);
7573 str = buf;
7575 /* This clause is done iteratively rather than recursively. */
7578 op = (is_complex_decl (TREE_TYPE (decl))
7579 ? TREE_TYPE (decl) : NULL_TREE);
7581 adorn_decl (decl, str);
7583 /* We have a pointer to a function or array...(*)(), (*)[] */
7584 if (code == POINTER_TYPE
7585 && op && (TREE_CODE (op) == FUNCTION_TYPE
7586 || TREE_CODE (op) == ARRAY_TYPE))
7588 strcpy (tmpbuf, "(");
7589 strcat (tmpbuf, str);
7590 strcat (tmpbuf, ")");
7591 strcpy (str, tmpbuf);
7594 decl = (is_complex_decl (TREE_TYPE (decl))
7595 ? TREE_TYPE (decl) : NULL_TREE);
7598 while (decl && (code = TREE_CODE (decl)))
7601 break;
7603 case IDENTIFIER_NODE:
7604 /* Will only happen if we are processing a "raw" expr-decl. */
7605 strcpy (buf, IDENTIFIER_POINTER (decl));
7606 return buf;
7608 default:
7609 abort ();
7612 return str;
7615 else
7616 /* We have an abstract declarator or a _DECL node. */
7618 strcpy (buf, name);
7619 return buf;
7623 static void
7624 gen_declspecs (declspecs, buf, raw)
7625 tree declspecs;
7626 char *buf;
7627 int raw;
7629 if (raw)
7631 tree chain;
7633 for (chain = nreverse (copy_list (declspecs));
7634 chain; chain = TREE_CHAIN (chain))
7636 tree aspec = TREE_VALUE (chain);
7638 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7639 strcat (buf, IDENTIFIER_POINTER (aspec));
7640 else if (TREE_CODE (aspec) == RECORD_TYPE)
7642 if (TYPE_NAME (aspec))
7644 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7646 if (! TREE_STATIC_TEMPLATE (aspec))
7647 strcat (buf, "struct ");
7648 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7650 /* NEW!!! */
7651 if (protocol_list)
7653 tree chain = protocol_list;
7655 strcat (buf, " <");
7656 while (chain)
7658 strcat (buf,
7659 IDENTIFIER_POINTER
7660 (PROTOCOL_NAME (TREE_VALUE (chain))));
7661 chain = TREE_CHAIN (chain);
7662 if (chain)
7663 strcat (buf, ", ");
7665 strcat (buf, ">");
7669 else
7670 strcat (buf, "untagged struct");
7673 else if (TREE_CODE (aspec) == UNION_TYPE)
7675 if (TYPE_NAME (aspec))
7677 if (! TREE_STATIC_TEMPLATE (aspec))
7678 strcat (buf, "union ");
7679 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7681 else
7682 strcat (buf, "untagged union");
7685 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7687 if (TYPE_NAME (aspec))
7689 if (! TREE_STATIC_TEMPLATE (aspec))
7690 strcat (buf, "enum ");
7691 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7693 else
7694 strcat (buf, "untagged enum");
7697 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7698 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7700 else if (IS_ID (aspec))
7702 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7704 strcat (buf, "id");
7705 if (protocol_list)
7707 tree chain = protocol_list;
7709 strcat (buf, " <");
7710 while (chain)
7712 strcat (buf,
7713 IDENTIFIER_POINTER
7714 (PROTOCOL_NAME (TREE_VALUE (chain))));
7715 chain = TREE_CHAIN (chain);
7716 if (chain)
7717 strcat (buf, ", ");
7719 strcat (buf, ">");
7722 if (TREE_CHAIN (chain))
7723 strcat (buf, " ");
7726 else
7728 /* Type qualifiers. */
7729 if (TREE_READONLY (declspecs))
7730 strcat (buf, "const ");
7731 if (TYPE_VOLATILE (declspecs))
7732 strcat (buf, "volatile ");
7734 switch (TREE_CODE (declspecs))
7736 /* Type specifiers. */
7738 case INTEGER_TYPE:
7739 declspecs = TYPE_MAIN_VARIANT (declspecs);
7741 /* Signed integer types. */
7743 if (declspecs == short_integer_type_node)
7744 strcat (buf, "short int ");
7745 else if (declspecs == integer_type_node)
7746 strcat (buf, "int ");
7747 else if (declspecs == long_integer_type_node)
7748 strcat (buf, "long int ");
7749 else if (declspecs == long_long_integer_type_node)
7750 strcat (buf, "long long int ");
7751 else if (declspecs == signed_char_type_node
7752 || declspecs == char_type_node)
7753 strcat (buf, "char ");
7755 /* Unsigned integer types. */
7757 else if (declspecs == short_unsigned_type_node)
7758 strcat (buf, "unsigned short ");
7759 else if (declspecs == unsigned_type_node)
7760 strcat (buf, "unsigned int ");
7761 else if (declspecs == long_unsigned_type_node)
7762 strcat (buf, "unsigned long ");
7763 else if (declspecs == long_long_unsigned_type_node)
7764 strcat (buf, "unsigned long long ");
7765 else if (declspecs == unsigned_char_type_node)
7766 strcat (buf, "unsigned char ");
7767 break;
7769 case REAL_TYPE:
7770 declspecs = TYPE_MAIN_VARIANT (declspecs);
7772 if (declspecs == float_type_node)
7773 strcat (buf, "float ");
7774 else if (declspecs == double_type_node)
7775 strcat (buf, "double ");
7776 else if (declspecs == long_double_type_node)
7777 strcat (buf, "long double ");
7778 break;
7780 case RECORD_TYPE:
7781 if (TYPE_NAME (declspecs)
7782 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7784 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7786 if (! TREE_STATIC_TEMPLATE (declspecs))
7787 strcat (buf, "struct ");
7788 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7790 if (protocol_list)
7792 tree chain = protocol_list;
7794 strcat (buf, " <");
7795 while (chain)
7797 strcat (buf,
7798 IDENTIFIER_POINTER
7799 (PROTOCOL_NAME (TREE_VALUE (chain))));
7800 chain = TREE_CHAIN (chain);
7801 if (chain)
7802 strcat (buf, ", ");
7804 strcat (buf, ">");
7808 else
7809 strcat (buf, "untagged struct");
7811 strcat (buf, " ");
7812 break;
7814 case UNION_TYPE:
7815 if (TYPE_NAME (declspecs)
7816 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7818 strcat (buf, "union ");
7819 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7820 strcat (buf, " ");
7823 else
7824 strcat (buf, "untagged union ");
7825 break;
7827 case ENUMERAL_TYPE:
7828 if (TYPE_NAME (declspecs)
7829 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7831 strcat (buf, "enum ");
7832 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7833 strcat (buf, " ");
7836 else
7837 strcat (buf, "untagged enum ");
7838 break;
7840 case VOID_TYPE:
7841 strcat (buf, "void ");
7842 break;
7844 case POINTER_TYPE:
7846 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7848 strcat (buf, "id");
7849 if (protocol_list)
7851 tree chain = protocol_list;
7853 strcat (buf, " <");
7854 while (chain)
7856 strcat (buf,
7857 IDENTIFIER_POINTER
7858 (PROTOCOL_NAME (TREE_VALUE (chain))));
7859 chain = TREE_CHAIN (chain);
7860 if (chain)
7861 strcat (buf, ", ");
7864 strcat (buf, ">");
7867 break;
7869 default:
7870 break;
7875 /* Given a tree node, produce a printable description of it in the given
7876 buffer, overwriting the buffer. */
7878 static char *
7879 gen_declaration (atype_or_adecl, buf)
7880 tree atype_or_adecl;
7881 char *buf;
7883 buf[0] = '\0';
7884 gen_declaration_1 (atype_or_adecl, buf);
7885 return buf;
7888 /* Given a tree node, append a printable description to the end of the
7889 given buffer. */
7891 static void
7892 gen_declaration_1 (atype_or_adecl, buf)
7893 tree atype_or_adecl;
7894 char *buf;
7896 char declbuf[256];
7898 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7900 tree declspecs; /* "identifier_node", "record_type" */
7901 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7903 /* We have a "raw", abstract declarator (typename). */
7904 declarator = TREE_VALUE (atype_or_adecl);
7905 declspecs = TREE_PURPOSE (atype_or_adecl);
7907 gen_declspecs (declspecs, buf, 1);
7908 if (declarator)
7910 strcat (buf, " ");
7911 strcat (buf, gen_declarator (declarator, declbuf, ""));
7915 else
7917 tree atype;
7918 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7919 tree declarator; /* "array_type", "function_type", "pointer_type". */
7921 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7922 || TREE_CODE (atype_or_adecl) == PARM_DECL
7923 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7924 atype = TREE_TYPE (atype_or_adecl);
7925 else
7926 /* Assume we have a *_type node. */
7927 atype = atype_or_adecl;
7929 if (is_complex_decl (atype))
7931 tree chain;
7933 /* Get the declaration specifier; it is at the end of the list. */
7934 declarator = chain = atype;
7936 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7937 while (is_complex_decl (chain));
7938 declspecs = chain;
7941 else
7943 declspecs = atype;
7944 declarator = NULL_TREE;
7947 gen_declspecs (declspecs, buf, 0);
7949 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7950 || TREE_CODE (atype_or_adecl) == PARM_DECL
7951 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7953 const char *const decl_name =
7954 (DECL_NAME (atype_or_adecl)
7955 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7957 if (declarator)
7959 strcat (buf, " ");
7960 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7963 else if (decl_name[0])
7965 strcat (buf, " ");
7966 strcat (buf, decl_name);
7969 else if (declarator)
7971 strcat (buf, " ");
7972 strcat (buf, gen_declarator (declarator, declbuf, ""));
7977 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7979 /* Given a method tree, put a printable description into the given
7980 buffer (overwriting) and return a pointer to the buffer. */
7982 static char *
7983 gen_method_decl (method, buf)
7984 tree method;
7985 char *buf;
7987 tree chain;
7989 buf[0] = '\0';
7990 if (RAW_TYPESPEC (method) != objc_object_reference)
7992 strcat (buf, "(");
7993 gen_declaration_1 (TREE_TYPE (method), buf);
7994 strcat (buf, ")");
7997 chain = METHOD_SEL_ARGS (method);
7998 if (chain)
8000 /* We have a chain of keyword_decls. */
8003 if (KEYWORD_KEY_NAME (chain))
8004 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8006 strcat (buf, ":");
8007 if (RAW_TYPESPEC (chain) != objc_object_reference)
8009 strcat (buf, "(");
8010 gen_declaration_1 (TREE_TYPE (chain), buf);
8011 strcat (buf, ")");
8014 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8015 if ((chain = TREE_CHAIN (chain)))
8016 strcat (buf, " ");
8018 while (chain);
8020 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8021 strcat (buf, ", ...");
8022 else if (METHOD_ADD_ARGS (method))
8024 /* We have a tree list node as generate by get_parm_info. */
8025 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8027 /* Know we have a chain of parm_decls. */
8028 while (chain)
8030 strcat (buf, ", ");
8031 gen_declaration_1 (chain, buf);
8032 chain = TREE_CHAIN (chain);
8037 else
8038 /* We have a unary selector. */
8039 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8041 return buf;
8044 /* Debug info. */
8047 /* Dump an @interface declaration of the supplied class CHAIN to the
8048 supplied file FP. Used to implement the -gen-decls option (which
8049 prints out an @interface declaration of all classes compiled in
8050 this run); potentially useful for debugging the compiler too. */
8051 static void
8052 dump_interface (fp, chain)
8053 FILE *fp;
8054 tree chain;
8056 /* FIXME: A heap overflow here whenever a method (or ivar)
8057 declaration is so long that it doesn't fit in the buffer. The
8058 code and all the related functions should be rewritten to avoid
8059 using fixed size buffers. */
8060 char *buf = (char *) xmalloc (1024 * 10);
8061 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8062 tree ivar_decls = CLASS_RAW_IVARS (chain);
8063 tree nst_methods = CLASS_NST_METHODS (chain);
8064 tree cls_methods = CLASS_CLS_METHODS (chain);
8066 fprintf (fp, "\n@interface %s", my_name);
8068 /* CLASS_SUPER_NAME is used to store the superclass name for
8069 classes, and the category name for categories. */
8070 if (CLASS_SUPER_NAME (chain))
8072 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8074 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8075 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8077 fprintf (fp, " (%s)\n", name);
8079 else
8081 fprintf (fp, " : %s\n", name);
8084 else
8085 fprintf (fp, "\n");
8087 /* FIXME - the following doesn't seem to work at the moment. */
8088 if (ivar_decls)
8090 fprintf (fp, "{\n");
8093 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8094 ivar_decls = TREE_CHAIN (ivar_decls);
8096 while (ivar_decls);
8097 fprintf (fp, "}\n");
8100 while (nst_methods)
8102 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8103 nst_methods = TREE_CHAIN (nst_methods);
8106 while (cls_methods)
8108 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8109 cls_methods = TREE_CHAIN (cls_methods);
8112 fprintf (fp, "@end\n");
8115 /* Demangle function for Objective-C */
8116 static const char *
8117 objc_demangle (mangled)
8118 const char *mangled;
8120 char *demangled, *cp;
8122 if (mangled[0] == '_' &&
8123 (mangled[1] == 'i' || mangled[1] == 'c') &&
8124 mangled[2] == '_')
8126 cp = demangled = xmalloc(strlen(mangled) + 2);
8127 if (mangled[1] == 'i')
8128 *cp++ = '-'; /* for instance method */
8129 else
8130 *cp++ = '+'; /* for class method */
8131 *cp++ = '['; /* opening left brace */
8132 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8133 while (*cp && *cp == '_')
8134 cp++; /* skip any initial underbars in class name */
8135 cp = strchr(cp, '_'); /* find first non-initial underbar */
8136 if (cp == NULL)
8138 free(demangled); /* not mangled name */
8139 return mangled;
8141 if (cp[1] == '_') /* easy case: no category name */
8143 *cp++ = ' '; /* replace two '_' with one ' ' */
8144 strcpy(cp, mangled + (cp - demangled) + 2);
8146 else
8148 *cp++ = '('; /* less easy case: category name */
8149 cp = strchr(cp, '_');
8150 if (cp == 0)
8152 free(demangled); /* not mangled name */
8153 return mangled;
8155 *cp++ = ')';
8156 *cp++ = ' '; /* overwriting 1st char of method name... */
8157 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8159 while (*cp && *cp == '_')
8160 cp++; /* skip any initial underbars in method name */
8161 for (; *cp; cp++)
8162 if (*cp == '_')
8163 *cp = ':'; /* replace remaining '_' with ':' */
8164 *cp++ = ']'; /* closing right brace */
8165 *cp++ = 0; /* string terminator */
8166 return demangled;
8168 else
8169 return mangled; /* not an objc mangled name */
8172 const char *
8173 objc_printable_name (decl, kind)
8174 tree decl;
8175 int kind ATTRIBUTE_UNUSED;
8177 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8180 static void
8181 init_objc ()
8183 gcc_obstack_init (&util_obstack);
8184 util_firstobj = (char *) obstack_finish (&util_obstack);
8186 errbuf = (char *) xmalloc (BUFSIZE);
8187 hash_init ();
8188 synth_module_prologue ();
8191 static void
8192 finish_objc ()
8194 struct imp_entry *impent;
8195 tree chain;
8196 /* The internally generated initializers appear to have missing braces.
8197 Don't warn about this. */
8198 int save_warn_missing_braces = warn_missing_braces;
8199 warn_missing_braces = 0;
8201 /* A missing @end may not be detected by the parser. */
8202 if (objc_implementation_context)
8204 warning ("`@end' missing in implementation context");
8205 finish_class (objc_implementation_context);
8206 objc_ivar_chain = NULL_TREE;
8207 objc_implementation_context = NULL_TREE;
8210 generate_forward_declaration_to_string_table ();
8212 /* Process the static instances here because initialization of objc_symtab
8213 depends on them. */
8214 if (objc_static_instances)
8215 generate_static_references ();
8217 if (imp_list || class_names_chain
8218 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8219 generate_objc_symtab_decl ();
8221 for (impent = imp_list; impent; impent = impent->next)
8223 objc_implementation_context = impent->imp_context;
8224 implementation_template = impent->imp_template;
8226 UOBJC_CLASS_decl = impent->class_decl;
8227 UOBJC_METACLASS_decl = impent->meta_decl;
8229 /* Dump the @interface of each class as we compile it, if the
8230 -gen-decls option is in use. TODO: Dump the classes in the
8231 order they were found, rather than in reverse order as we
8232 are doing now. */
8233 if (flag_gen_declaration)
8235 dump_interface (gen_declaration_file, objc_implementation_context);
8238 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8240 /* all of the following reference the string pool... */
8241 generate_ivar_lists ();
8242 generate_dispatch_tables ();
8243 generate_shared_structures ();
8245 else
8247 generate_dispatch_tables ();
8248 generate_category (objc_implementation_context);
8252 /* If we are using an array of selectors, we must always
8253 finish up the array decl even if no selectors were used. */
8254 if (! flag_next_runtime || sel_ref_chain)
8255 build_selector_translation_table ();
8257 if (protocol_chain)
8258 generate_protocols ();
8260 if (objc_implementation_context || class_names_chain || objc_static_instances
8261 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8263 /* Arrange for ObjC data structures to be initialized at run time. */
8264 rtx init_sym = build_module_descriptor ();
8265 if (init_sym && targetm.have_ctors_dtors)
8266 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8269 /* Dump the class references. This forces the appropriate classes
8270 to be linked into the executable image, preserving unix archive
8271 semantics. This can be removed when we move to a more dynamically
8272 linked environment. */
8274 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8276 handle_class_ref (chain);
8277 if (TREE_PURPOSE (chain))
8278 generate_classref_translation_entry (chain);
8281 for (impent = imp_list; impent; impent = impent->next)
8282 handle_impent (impent);
8284 /* Dump the string table last. */
8286 generate_strings ();
8288 if (warn_selector)
8290 int slot;
8291 hash hsh;
8293 /* Run through the selector hash tables and print a warning for any
8294 selector which has multiple methods. */
8296 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8297 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8298 if (hsh->list)
8300 tree meth = hsh->key;
8301 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8302 ? '-' : '+');
8303 attr loop;
8305 warning ("potential selector conflict for method `%s'",
8306 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8307 warn_with_method ("found", type, meth);
8308 for (loop = hsh->list; loop; loop = loop->next)
8309 warn_with_method ("found", type, loop->value);
8312 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8313 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8314 if (hsh->list)
8316 tree meth = hsh->key;
8317 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8318 ? '-' : '+');
8319 attr loop;
8321 warning ("potential selector conflict for method `%s'",
8322 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8323 warn_with_method ("found", type, meth);
8324 for (loop = hsh->list; loop; loop = loop->next)
8325 warn_with_method ("found", type, loop->value);
8329 warn_missing_braces = save_warn_missing_braces;
8332 /* Subroutines of finish_objc. */
8334 static void
8335 generate_classref_translation_entry (chain)
8336 tree chain;
8338 tree expr, name, decl_specs, decl, sc_spec;
8339 tree type;
8341 type = TREE_TYPE (TREE_PURPOSE (chain));
8343 expr = add_objc_string (TREE_VALUE (chain), class_names);
8344 expr = build_c_cast (type, expr); /* cast! */
8346 name = DECL_NAME (TREE_PURPOSE (chain));
8348 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8350 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8351 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8353 /* The decl that is returned from start_decl is the one that we
8354 forward declared in build_class_reference. */
8355 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8356 DECL_CONTEXT (decl) = NULL_TREE;
8357 finish_decl (decl, expr, NULL_TREE);
8358 return;
8361 static void
8362 handle_class_ref (chain)
8363 tree chain;
8365 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8366 char *string = (char *) alloca (strlen (name) + 30);
8367 tree decl;
8368 tree exp;
8370 sprintf (string, "%sobjc_class_name_%s",
8371 (flag_next_runtime ? "." : "__"), name);
8373 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8374 if (flag_next_runtime)
8376 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8377 return;
8379 #endif
8381 /* Make a decl for this name, so we can use its address in a tree. */
8382 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8383 DECL_EXTERNAL (decl) = 1;
8384 TREE_PUBLIC (decl) = 1;
8386 pushdecl (decl);
8387 rest_of_decl_compilation (decl, 0, 0, 0);
8389 /* Make a decl for the address. */
8390 sprintf (string, "%sobjc_class_ref_%s",
8391 (flag_next_runtime ? "." : "__"), name);
8392 exp = build1 (ADDR_EXPR, string_type_node, decl);
8393 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8394 DECL_INITIAL (decl) = exp;
8395 TREE_STATIC (decl) = 1;
8396 TREE_USED (decl) = 1;
8398 pushdecl (decl);
8399 rest_of_decl_compilation (decl, 0, 0, 0);
8402 static void
8403 handle_impent (impent)
8404 struct imp_entry *impent;
8406 char *string;
8408 objc_implementation_context = impent->imp_context;
8409 implementation_template = impent->imp_template;
8411 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8413 const char *const class_name =
8414 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8416 string = (char *) alloca (strlen (class_name) + 30);
8418 sprintf (string, "%sobjc_class_name_%s",
8419 (flag_next_runtime ? "." : "__"), class_name);
8421 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8423 const char *const class_name =
8424 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8425 const char *const class_super_name =
8426 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8428 string = (char *) alloca (strlen (class_name)
8429 + strlen (class_super_name) + 30);
8431 /* Do the same for categories. Even though no references to
8432 these symbols are generated automatically by the compiler, it
8433 gives you a handle to pull them into an archive by hand. */
8434 sprintf (string, "*%sobjc_category_name_%s_%s",
8435 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8437 else
8438 return;
8440 #ifdef ASM_DECLARE_CLASS_REFERENCE
8441 if (flag_next_runtime)
8443 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8444 return;
8446 else
8447 #endif
8449 tree decl, init;
8451 init = build_int_2 (0, 0);
8452 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8453 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8454 TREE_PUBLIC (decl) = 1;
8455 TREE_READONLY (decl) = 1;
8456 TREE_USED (decl) = 1;
8457 TREE_CONSTANT (decl) = 1;
8458 DECL_CONTEXT (decl) = 0;
8459 DECL_ARTIFICIAL (decl) = 1;
8460 DECL_INITIAL (decl) = init;
8461 assemble_variable (decl, 1, 0, 0);
8465 /* Look up ID as an instance variable. */
8466 tree
8467 lookup_objc_ivar (id)
8468 tree id;
8470 tree decl;
8472 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8473 /* We have a message to super. */
8474 return get_super_receiver ();
8475 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8477 if (is_private (decl))
8478 return error_mark_node;
8479 else
8480 return build_ivar_reference (id);
8482 else
8483 return 0;
8486 #include "gt-objc-objc-act.h"
8487 #include "gtype-objc.h"