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)
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
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
62 #include "diagnostic.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) \
73 sprintf ((BUF), "_%s_%s_%s_%s", \
74 ((IS_INST) ? "i" : "c"), \
76 ((CAT_NAME)? (CAT_NAME) : ""), \
78 for (temp = (BUF); *temp; temp++) \
79 if (*temp == ':') *temp = '_'; \
83 /* These need specifying. */
84 #ifndef OBJC_FORWARDING_STACK_OFFSET
85 #define OBJC_FORWARDING_STACK_OFFSET 0
88 #ifndef OBJC_FORWARDING_MIN_OFFSET
89 #define OBJC_FORWARDING_MIN_OFFSET 0
93 /* Set up for use of obstacks. */
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. */
103 /* for encode_method_def */
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 (void);
122 static void finish_objc (void);
124 /* Code generation. */
126 static void synth_module_prologue (void);
127 static tree objc_build_constructor (tree, tree);
128 static rtx build_module_descriptor (void);
129 static tree init_module_descriptor (tree);
130 static tree build_objc_method_call (int, tree, tree, tree, tree, tree);
131 static void generate_strings (void);
132 static tree get_proto_encoding (tree);
133 static void build_selector_translation_table (void);
135 static tree objc_add_static_instance (tree, tree);
137 static tree build_ivar_template (void);
138 static tree build_method_template (void);
139 static tree build_private_template (tree);
140 static void build_class_template (void);
141 static void build_selector_template (void);
142 static void build_category_template (void);
143 static tree build_super_template (void);
144 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
145 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
147 static void synth_forward_declarations (void);
148 static void generate_ivar_lists (void);
149 static void generate_dispatch_tables (void);
150 static void generate_shared_structures (void);
151 static tree generate_protocol_list (tree);
152 static void generate_forward_declaration_to_string_table (void);
153 static void build_protocol_reference (tree);
155 static tree build_keyword_selector (tree);
156 static tree synth_id_with_class_suffix (const char *, tree);
158 static void generate_static_references (void);
159 static int check_methods_accessible (tree, tree, int);
160 static void encode_aggregate_within (tree, int, int, int, int);
161 static const char *objc_demangle (const char *);
162 static void objc_expand_function_end (void);
164 /* Hash tables to manage the global pool of method prototypes. */
166 hash *nst_method_hash_list = 0;
167 hash *cls_method_hash_list = 0;
169 static size_t hash_func (tree);
170 static void hash_init (void);
171 static void hash_enter (hash *, tree);
172 static hash hash_lookup (hash *, tree);
173 static void hash_add_attr (hash, tree);
174 static tree lookup_method (tree, tree);
175 static tree lookup_instance_method_static (tree, tree);
176 static tree lookup_class_method_static (tree, tree);
177 static tree add_class (tree);
178 static void add_category (tree, tree);
182 class_names, /* class, category, protocol, module names */
183 meth_var_names, /* method and variable names */
184 meth_var_types /* method and variable type descriptors */
187 static tree add_objc_string (tree, enum string_section);
188 static tree get_objc_string_decl (tree, enum string_section);
189 static tree build_objc_string_decl (enum string_section);
190 static tree build_selector_reference_decl (void);
192 /* Protocol additions. */
194 static tree add_protocol (tree);
195 static tree lookup_protocol (tree);
196 static void check_protocol_recursively (tree, tree);
197 static tree lookup_and_install_protocols (tree);
201 static void encode_type_qualifiers (tree);
202 static void encode_pointer (tree, int, int);
203 static void encode_array (tree, int, int);
204 static void encode_aggregate (tree, int, int);
205 static void encode_bitfield (int);
206 static void encode_type (tree, int, int);
207 static void encode_field_decl (tree, int, int);
209 static void really_start_method (tree, tree);
210 static int comp_method_with_proto (tree, tree);
211 static int comp_proto_with_proto (tree, tree);
212 static tree get_arg_type_list (tree, int, int);
213 static tree objc_expr_last (tree);
215 /* Utilities for debugging and error diagnostics. */
217 static void warn_with_method (const char *, int, tree);
218 static void error_with_ivar (const char *, tree, tree);
219 static char *gen_method_decl (tree, char *);
220 static char *gen_declaration (tree, char *);
221 static void gen_declaration_1 (tree, char *);
222 static char *gen_declarator (tree, char *, const char *);
223 static int is_complex_decl (tree);
224 static void adorn_decl (tree, char *);
225 static void dump_interface (FILE *, tree);
227 /* Everything else. */
229 static tree define_decl (tree, tree);
230 static tree lookup_method_in_protocol_list (tree, tree, int);
231 static tree lookup_protocol_in_reflist (tree, tree);
232 static tree create_builtin_decl (enum tree_code, tree, const char *);
233 static void setup_string_decl (void);
234 static void build_string_class_template (void);
235 static tree my_build_string (int, const char *);
236 static void build_objc_symtab_template (void);
237 static tree init_def_list (tree);
238 static tree init_objc_symtab (tree);
239 static void forward_declare_categories (void);
240 static void generate_objc_symtab_decl (void);
241 static tree build_selector (tree);
242 static tree build_typed_selector_reference (tree, tree);
243 static tree build_selector_reference (tree);
244 static tree build_class_reference_decl (void);
245 static void add_class_reference (tree);
246 static tree build_protocol_template (void);
247 static tree build_descriptor_table_initializer (tree, tree);
248 static tree build_method_prototype_list_template (tree, int);
249 static tree build_method_prototype_template (void);
250 static int forwarding_offset (tree);
251 static tree encode_method_prototype (tree, tree);
252 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
253 static void generate_method_descriptors (tree);
254 static tree build_tmp_function_decl (void);
255 static void hack_method_prototype (tree, tree);
256 static void generate_protocol_references (tree);
257 static void generate_protocols (void);
258 static void check_ivars (tree, tree);
259 static tree build_ivar_list_template (tree, int);
260 static tree build_method_list_template (tree, int);
261 static tree build_ivar_list_initializer (tree, tree);
262 static tree generate_ivars_list (tree, const char *, int, tree);
263 static tree build_dispatch_table_initializer (tree, tree);
264 static tree generate_dispatch_table (tree, const char *, int, tree);
265 static tree build_shared_structure_initializer (tree, tree, tree, tree, tree,
266 int, tree, tree, tree);
267 static void generate_category (tree);
268 static int is_objc_type_qualifier (tree);
269 static tree adjust_type_for_id_default (tree);
270 static tree check_duplicates (hash);
271 static tree receiver_is_class_object (tree);
272 static int check_methods (tree, tree, int);
273 static int conforms_to_protocol (tree, tree);
274 static void check_protocol (tree, const char *, const char *);
275 static void check_protocols (tree, const char *, const char *);
276 static tree encode_method_def (tree);
277 static void gen_declspecs (tree, char *, int);
278 static void generate_classref_translation_entry (tree);
279 static void handle_class_ref (tree);
280 static void generate_struct_by_value_array (void)
282 static void encode_complete_bitfield (int, tree, int);
283 static void mark_referenced_methods (void);
285 /*** Private Interface (data) ***/
287 /* Reserved tag definitions. */
290 #define TAG_OBJECT "objc_object"
291 #define TAG_CLASS "objc_class"
292 #define TAG_SUPER "objc_super"
293 #define TAG_SELECTOR "objc_selector"
295 #define UTAG_CLASS "_objc_class"
296 #define UTAG_IVAR "_objc_ivar"
297 #define UTAG_IVAR_LIST "_objc_ivar_list"
298 #define UTAG_METHOD "_objc_method"
299 #define UTAG_METHOD_LIST "_objc_method_list"
300 #define UTAG_CATEGORY "_objc_category"
301 #define UTAG_MODULE "_objc_module"
302 #define UTAG_SYMTAB "_objc_symtab"
303 #define UTAG_SUPER "_objc_super"
304 #define UTAG_SELECTOR "_objc_selector"
306 #define UTAG_PROTOCOL "_objc_protocol"
307 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
308 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
310 /* Note that the string object global name is only needed for the
312 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
314 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
316 static const char *TAG_GETCLASS;
317 static const char *TAG_GETMETACLASS;
318 static const char *TAG_MSGSEND;
319 static const char *TAG_MSGSENDSUPER;
320 static const char *TAG_EXECCLASS;
321 static const char *default_constant_string_class_name;
323 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
324 tree objc_global_trees[OCTI_MAX];
326 static void handle_impent (struct imp_entry *);
328 struct imp_entry *imp_list = 0;
329 int imp_count = 0; /* `@implementation' */
330 int cat_count = 0; /* `@category' */
332 static int method_slot = 0; /* Used by start_method_def, */
336 static char *errbuf; /* Buffer for error diagnostics */
338 /* Data imported from tree.c. */
340 extern enum debug_info_type write_symbols;
342 /* Data imported from toplev.c. */
344 extern const char *dump_base_name;
346 static int flag_typed_selectors;
348 FILE *gen_declaration_file;
350 /* Tells "encode_pointer/encode_aggregate" whether we are generating
351 type descriptors for instance variables (as opposed to methods).
352 Type descriptors for instance variables contain more information
353 than methods (for static typing and embedded structures). */
355 static int generating_instance_variables = 0;
357 /* Some platforms pass small structures through registers versus
358 through an invisible pointer. Determine at what size structure is
359 the transition point between the two possibilities. */
362 generate_struct_by_value_array (void)
365 tree field_decl, field_decl_chain;
367 int aggregate_in_mem[32];
370 /* Presumably no platform passes 32 byte structures in a register. */
371 for (i = 1; i < 32; i++)
375 /* Create an unnamed struct that has `i' character components */
376 type = start_struct (RECORD_TYPE, NULL_TREE);
378 strcpy (buffer, "c1");
379 field_decl = create_builtin_decl (FIELD_DECL,
382 field_decl_chain = field_decl;
384 for (j = 1; j < i; j++)
386 sprintf (buffer, "c%d", j + 1);
387 field_decl = create_builtin_decl (FIELD_DECL,
390 chainon (field_decl_chain, field_decl);
392 finish_struct (type, field_decl_chain, NULL_TREE);
394 aggregate_in_mem[i] = aggregate_value_p (type, 0);
395 if (!aggregate_in_mem[i])
399 /* We found some structures that are returned in registers instead of memory
400 so output the necessary data. */
403 for (i = 31; i >= 0; i--)
404 if (!aggregate_in_mem[i])
406 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
408 /* The first member of the structure is always 0 because we don't handle
409 structures with 0 members */
410 printf ("static int struct_forward_array[] = {\n 0");
412 for (j = 1; j <= i; j++)
413 printf (", %d", aggregate_in_mem[j]);
423 if (c_objc_common_init () == false)
426 /* Force the line number back to 0; check_newline will have
427 raised it to 1, which will make the builtin functions appear
428 not to be built in. */
431 /* If gen_declaration desired, open the output file. */
432 if (flag_gen_declaration)
434 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
435 gen_declaration_file = fopen (dumpname, "w");
436 if (gen_declaration_file == 0)
437 fatal_error ("can't open %s: %m", dumpname);
441 if (flag_next_runtime)
443 TAG_GETCLASS = "objc_getClass";
444 TAG_GETMETACLASS = "objc_getMetaClass";
445 TAG_MSGSEND = "objc_msgSend";
446 TAG_MSGSENDSUPER = "objc_msgSendSuper";
447 TAG_EXECCLASS = "__objc_execClass";
448 default_constant_string_class_name = "NSConstantString";
452 TAG_GETCLASS = "objc_get_class";
453 TAG_GETMETACLASS = "objc_get_meta_class";
454 TAG_MSGSEND = "objc_msg_lookup";
455 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
456 TAG_EXECCLASS = "__objc_exec_class";
457 default_constant_string_class_name = "NXConstantString";
458 flag_typed_selectors = 1;
461 objc_ellipsis_node = make_node (ERROR_MARK);
465 if (print_struct_values)
466 generate_struct_by_value_array ();
474 mark_referenced_methods ();
475 c_objc_common_finish_file ();
477 /* Finalize Objective-C runtime data. No need to generate tables
478 and code if only checking syntax. */
479 if (!flag_syntax_only)
482 if (gen_declaration_file)
483 fclose (gen_declaration_file);
487 define_decl (tree declarator, tree declspecs)
489 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
490 finish_decl (decl, NULL_TREE, NULL_TREE);
494 /* Return 1 if LHS and RHS are compatible types for assignment or
495 various other operations. Return 0 if they are incompatible, and
496 return -1 if we choose to not decide. When the operation is
497 REFLEXIVE, check for compatibility in either direction.
499 For statically typed objects, an assignment of the form `a' = `b'
503 `a' and `b' are the same class type, or
504 `a' and `b' are of class types A and B such that B is a descendant of A. */
507 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
513 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
515 p = TREE_VALUE (rproto);
517 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
519 if ((fnd = lookup_method (class_meth
520 ? PROTOCOL_CLS_METHODS (p)
521 : PROTOCOL_NST_METHODS (p), sel_name)))
523 else if (PROTOCOL_LIST (p))
524 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
525 sel_name, class_meth);
529 ; /* An identifier...if we could not find a protocol. */
540 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
544 /* Make sure the protocol is supported by the object on the rhs. */
545 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
548 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
550 p = TREE_VALUE (rproto);
552 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
557 else if (PROTOCOL_LIST (p))
558 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
567 ; /* An identifier...if we could not find a protocol. */
573 /* Return 1 if LHS and RHS are compatible types for assignment or
574 various other operations. Return 0 if they are incompatible, and
575 return -1 if we choose to not decide (because the types are really
576 just C types, not ObjC specific ones). When the operation is
577 REFLEXIVE (typically comparisons), check for compatibility in
578 either direction; when it's not (typically assignments), don't.
580 This function is called in two cases: when both lhs and rhs are
581 pointers to records (in which case we check protocols too), and
582 when both lhs and rhs are records (in which case we check class
585 Warnings about classes/protocols not implementing a protocol are
586 emitted here (multiple of those warnings might be emitted for a
587 single line!); generic warnings about incompatible assignments and
588 lacks of casts in comparisons are/must be emitted by the caller if
593 objc_comptypes (tree lhs, tree rhs, int reflexive)
595 /* New clause for protocols. */
597 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
598 manage the ObjC ones, and leave the rest to the C code. */
599 if (TREE_CODE (lhs) == POINTER_TYPE
600 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
601 && TREE_CODE (rhs) == POINTER_TYPE
602 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
604 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
605 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
609 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
610 tree rproto, rproto_list;
613 /* <Protocol> = <Protocol> */
616 rproto_list = TYPE_PROTOCOL_LIST (rhs);
620 /* An assignment between objects of type 'id
621 <Protocol>'; make sure the protocol on the lhs is
622 supported by the object on the rhs. */
623 for (lproto = lproto_list; lproto;
624 lproto = TREE_CHAIN (lproto))
626 p = TREE_VALUE (lproto);
627 rproto = lookup_protocol_in_reflist (rproto_list, p);
631 ("object does not conform to the `%s' protocol",
632 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
638 /* Obscure case - a comparison between two objects
639 of type 'id <Protocol>'. Check that either the
640 protocol on the lhs is supported by the object on
641 the rhs, or viceversa. */
643 /* Check if the protocol on the lhs is supported by the
644 object on the rhs. */
645 for (lproto = lproto_list; lproto;
646 lproto = TREE_CHAIN (lproto))
648 p = TREE_VALUE (lproto);
649 rproto = lookup_protocol_in_reflist (rproto_list, p);
653 /* Check failed - check if the protocol on the rhs
654 is supported by the object on the lhs. */
655 for (rproto = rproto_list; rproto;
656 rproto = TREE_CHAIN (rproto))
658 p = TREE_VALUE (rproto);
659 lproto = lookup_protocol_in_reflist (lproto_list,
664 /* This check failed too: incompatible */
674 /* <Protocol> = <class> * */
675 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
677 tree rname = TYPE_NAME (TREE_TYPE (rhs));
680 /* Make sure the protocol is supported by the object on
682 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
684 p = TREE_VALUE (lproto);
686 rinter = lookup_interface (rname);
688 while (rinter && !rproto)
692 rproto_list = CLASS_PROTOCOL_LIST (rinter);
693 rproto = lookup_protocol_in_reflist (rproto_list, p);
694 /* If the underlying ObjC class does not have
695 the protocol we're looking for, check for "one-off"
696 protocols (e.g., `NSObject<MyProt> *foo;') attached
700 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
701 rproto = lookup_protocol_in_reflist (rproto_list, p);
704 /* Check for protocols adopted by categories. */
705 cat = CLASS_CATEGORY_LIST (rinter);
706 while (cat && !rproto)
708 rproto_list = CLASS_PROTOCOL_LIST (cat);
709 rproto = lookup_protocol_in_reflist (rproto_list, p);
710 cat = CLASS_CATEGORY_LIST (cat);
713 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
717 warning ("class `%s' does not implement the `%s' protocol",
718 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
719 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
723 /* <Protocol> = id */
724 else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
728 /* <Protocol> = Class */
729 else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
733 /* <Protocol> = ?? : let comptypes decide. */
736 else if (rhs_is_proto)
738 /* <class> * = <Protocol> */
739 if (TYPED_OBJECT (TREE_TYPE (lhs)))
743 tree rname = TYPE_NAME (TREE_TYPE (lhs));
745 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
747 /* Make sure the protocol is supported by the object on
749 for (rproto = rproto_list; rproto;
750 rproto = TREE_CHAIN (rproto))
752 tree p = TREE_VALUE (rproto);
754 rinter = lookup_interface (rname);
756 while (rinter && !lproto)
760 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
761 lproto = lookup_protocol_in_reflist (lproto_list, p);
762 /* If the underlying ObjC class does not
763 have the protocol we're looking for,
764 check for "one-off" protocols (e.g.,
765 `NSObject<MyProt> *foo;') attached to the
769 lproto_list = TYPE_PROTOCOL_LIST
771 lproto = lookup_protocol_in_reflist
775 /* Check for protocols adopted by categories. */
776 cat = CLASS_CATEGORY_LIST (rinter);
777 while (cat && !lproto)
779 lproto_list = CLASS_PROTOCOL_LIST (cat);
780 lproto = lookup_protocol_in_reflist (lproto_list,
782 cat = CLASS_CATEGORY_LIST (cat);
785 rinter = lookup_interface (CLASS_SUPER_NAME
790 warning ("class `%s' does not implement the `%s' protocol",
791 IDENTIFIER_POINTER (TYPE_NAME
793 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
800 /* id = <Protocol> */
801 else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
805 /* Class = <Protocol> */
806 else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
810 /* ??? = <Protocol> : let comptypes decide */
818 /* Attention: we shouldn't defer to comptypes here. One bad
819 side effect would be that we might loose the REFLEXIVE
822 lhs = TREE_TYPE (lhs);
823 rhs = TREE_TYPE (rhs);
827 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
829 /* Nothing to do with ObjC - let immediately comptypes take
830 responsibility for checking. */
834 /* `id' = `<class> *' `<class> *' = `id': always allow it.
836 'Object *o = [[Object alloc] init]; falls
837 in the case <class> * = `id'.
839 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
840 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
843 /* `id' = `Class', `Class' = `id' */
845 else if ((TYPE_NAME (lhs) == objc_object_id
846 && TYPE_NAME (rhs) == objc_class_id)
847 || (TYPE_NAME (lhs) == objc_class_id
848 && TYPE_NAME (rhs) == objc_object_id))
851 /* `<class> *' = `<class> *' */
853 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
855 tree lname = TYPE_NAME (lhs);
856 tree rname = TYPE_NAME (rhs);
862 /* If the left hand side is a super class of the right hand side,
864 for (inter = lookup_interface (rname); inter;
865 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
866 if (lname == CLASS_SUPER_NAME (inter))
869 /* Allow the reverse when reflexive. */
871 for (inter = lookup_interface (lname); inter;
872 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
873 if (rname == CLASS_SUPER_NAME (inter))
879 /* Not an ObjC type - let comptypes do the check. */
883 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
886 objc_check_decl (tree decl)
888 tree type = TREE_TYPE (decl);
890 if (TREE_CODE (type) == RECORD_TYPE
891 && TREE_STATIC_TEMPLATE (type)
892 && type != constant_string_type)
893 error ("%H'%D' cannot be statically allocated",
894 &DECL_SOURCE_LOCATION (decl), decl);
897 /* Implement static typing. At this point, we know we have an interface. */
900 get_static_reference (tree interface, tree protocols)
902 tree type = xref_tag (RECORD_TYPE, interface);
906 tree t, m = TYPE_MAIN_VARIANT (type);
908 t = copy_node (type);
910 /* Add this type to the chain of variants of TYPE. */
911 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
912 TYPE_NEXT_VARIANT (m) = t;
914 /* Look up protocols and install in lang specific list. Note
915 that the protocol list can have a different lifetime than T! */
916 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
918 /* This forces a new pointer type to be created later
919 (in build_pointer_type)...so that the new template
920 we just created will actually be used...what a hack! */
921 if (TYPE_POINTER_TO (t))
922 TYPE_POINTER_TO (t) = NULL_TREE;
931 get_object_reference (tree protocols)
933 tree type_decl = lookup_name (objc_id_id);
936 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
938 type = TREE_TYPE (type_decl);
939 if (TYPE_MAIN_VARIANT (type) != id_type)
940 warning ("unexpected type for `id' (%s)",
941 gen_declaration (type, errbuf));
945 error ("undefined type `id', please import <objc/objc.h>");
946 return error_mark_node;
949 /* This clause creates a new pointer type that is qualified with
950 the protocol specification...this info is used later to do more
951 elaborate type checking. */
955 tree t, m = TYPE_MAIN_VARIANT (type);
957 t = copy_node (type);
959 /* Add this type to the chain of variants of TYPE. */
960 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
961 TYPE_NEXT_VARIANT (m) = t;
963 /* Look up protocols...and install in lang specific list */
964 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
966 /* This forces a new pointer type to be created later
967 (in build_pointer_type)...so that the new template
968 we just created will actually be used...what a hack! */
969 if (TYPE_POINTER_TO (t))
970 TYPE_POINTER_TO (t) = NULL_TREE;
977 /* Check for circular dependencies in protocols. The arguments are
978 PROTO, the protocol to check, and LIST, a list of protocol it
982 check_protocol_recursively (tree proto, tree list)
986 for (p = list; p; p = TREE_CHAIN (p))
988 tree pp = TREE_VALUE (p);
990 if (TREE_CODE (pp) == IDENTIFIER_NODE)
991 pp = lookup_protocol (pp);
994 fatal_error ("protocol `%s' has circular dependency",
995 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
997 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1002 lookup_and_install_protocols (tree protocols)
1006 tree return_value = protocols;
1008 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1010 tree ident = TREE_VALUE (proto);
1011 tree p = lookup_protocol (ident);
1015 error ("cannot find protocol declaration for `%s'",
1016 IDENTIFIER_POINTER (ident));
1018 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1020 return_value = TREE_CHAIN (proto);
1024 /* Replace identifier with actual protocol node. */
1025 TREE_VALUE (proto) = p;
1030 return return_value;
1033 /* Create and push a decl for a built-in external variable or field NAME.
1035 TYPE is its data type. */
1038 create_builtin_decl (enum tree_code code, tree type, const char *name)
1040 tree decl = build_decl (code, get_identifier (name), type);
1042 if (code == VAR_DECL)
1044 TREE_STATIC (decl) = 1;
1045 make_decl_rtl (decl, 0);
1049 DECL_ARTIFICIAL (decl) = 1;
1053 /* Find the decl for the constant string class. */
1056 setup_string_decl (void)
1058 if (!string_class_decl)
1060 if (!constant_string_global_id)
1061 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1062 string_class_decl = lookup_name (constant_string_global_id);
1066 /* Purpose: "play" parser, creating/installing representations
1067 of the declarations that are required by Objective-C.
1071 type_spec--------->sc_spec
1072 (tree_list) (tree_list)
1075 identifier_node identifier_node */
1078 synth_module_prologue (void)
1083 /* Defined in `objc.h' */
1084 objc_object_id = get_identifier (TAG_OBJECT);
1086 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1088 id_type = build_pointer_type (objc_object_reference);
1090 objc_id_id = get_identifier (TYPE_ID);
1091 objc_class_id = get_identifier (TAG_CLASS);
1093 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1094 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1095 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1097 /* Declare type of selector-objects that represent an operation name. */
1099 /* `struct objc_selector *' */
1101 = build_pointer_type (xref_tag (RECORD_TYPE,
1102 get_identifier (TAG_SELECTOR)));
1104 /* Forward declare type, or else the prototype for msgSendSuper will
1107 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1108 get_identifier (TAG_SUPER)));
1111 /* id objc_msgSend (id, SEL, ...); */
1114 = build_function_type (id_type,
1115 tree_cons (NULL_TREE, id_type,
1116 tree_cons (NULL_TREE, selector_type,
1119 if (! flag_next_runtime)
1121 umsg_decl = build_decl (FUNCTION_DECL,
1122 get_identifier (TAG_MSGSEND), temp_type);
1123 DECL_EXTERNAL (umsg_decl) = 1;
1124 TREE_PUBLIC (umsg_decl) = 1;
1125 DECL_INLINE (umsg_decl) = 1;
1126 DECL_ARTIFICIAL (umsg_decl) = 1;
1128 make_decl_rtl (umsg_decl, NULL);
1129 pushdecl (umsg_decl);
1132 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
1135 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1138 = build_function_type (id_type,
1139 tree_cons (NULL_TREE, super_p,
1140 tree_cons (NULL_TREE, selector_type,
1143 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1144 temp_type, 0, NOT_BUILT_IN,
1147 /* id objc_getClass (const char *); */
1149 temp_type = build_function_type (id_type,
1150 tree_cons (NULL_TREE,
1151 const_string_type_node,
1152 tree_cons (NULL_TREE, void_type_node,
1156 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1159 /* id objc_getMetaClass (const char *); */
1161 objc_get_meta_class_decl
1162 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
1165 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1167 if (! flag_next_runtime)
1169 if (flag_typed_selectors)
1171 /* Suppress outputting debug symbols, because
1172 dbxout_init hasn'r been called yet. */
1173 enum debug_info_type save_write_symbols = write_symbols;
1174 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1175 write_symbols = NO_DEBUG;
1176 debug_hooks = &do_nothing_debug_hooks;
1178 build_selector_template ();
1179 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1181 write_symbols = save_write_symbols;
1182 debug_hooks = save_hooks;
1185 temp_type = build_array_type (selector_type, NULL_TREE);
1187 layout_type (temp_type);
1188 UOBJC_SELECTOR_TABLE_decl
1189 = create_builtin_decl (VAR_DECL, temp_type,
1190 "_OBJC_SELECTOR_TABLE");
1192 /* Avoid warning when not sending messages. */
1193 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1196 generate_forward_declaration_to_string_table ();
1198 /* Forward declare constant_string_id and constant_string_type. */
1199 if (!constant_string_class_name)
1200 constant_string_class_name = default_constant_string_class_name;
1202 constant_string_id = get_identifier (constant_string_class_name);
1203 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1206 /* Predefine the following data type:
1208 struct STRING_OBJECT_CLASS_NAME
1212 unsigned int length;
1216 build_string_class_template (void)
1218 tree field_decl, field_decl_chain;
1220 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1221 field_decl_chain = field_decl;
1223 field_decl = create_builtin_decl (FIELD_DECL,
1224 build_pointer_type (char_type_node),
1226 chainon (field_decl_chain, field_decl);
1228 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1229 chainon (field_decl_chain, field_decl);
1231 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1234 /* Custom build_string which sets TREE_TYPE! */
1237 my_build_string (int len, const char *str)
1239 return fix_string_type (build_string (len, str));
1242 /* Build a static instance of NXConstantString which points at the
1243 string constant STRING.
1244 We place the string object in the __string_objects section of the
1245 __OBJC segment. The Objective-C runtime will initialize the isa
1246 pointers of the string objects to point at the NXConstantString
1250 build_objc_string_object (tree string)
1252 tree initlist, constructor;
1255 if (lookup_interface (constant_string_id) == NULL_TREE)
1257 error ("cannot find interface declaration for `%s'",
1258 IDENTIFIER_POINTER (constant_string_id));
1259 return error_mark_node;
1262 add_class_reference (constant_string_id);
1264 length = TREE_STRING_LENGTH (string) - 1;
1266 /* We could not properly create NXConstantString in synth_module_prologue,
1267 because that's called before debugging is initialized. Do it now. */
1268 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1269 build_string_class_template ();
1271 /* & ((NXConstantString) { NULL, string, length }) */
1273 if (flag_next_runtime)
1275 /* For the NeXT runtime, we can generate a literal reference
1276 to the string class, don't need to run a constructor. */
1277 setup_string_decl ();
1278 if (string_class_decl == NULL_TREE)
1280 error ("cannot find reference tag for class `%s'",
1281 IDENTIFIER_POINTER (constant_string_id));
1282 return error_mark_node;
1284 initlist = build_tree_list
1286 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1290 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1294 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1296 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1297 constructor = objc_build_constructor (constant_string_type,
1298 nreverse (initlist));
1300 if (!flag_next_runtime)
1303 = objc_add_static_instance (constructor, constant_string_type);
1306 return (build_unary_op (ADDR_EXPR, constructor, 1));
1309 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1311 static GTY(()) int num_static_inst;
1313 objc_add_static_instance (tree constructor, tree class_decl)
1318 /* Find the list of static instances for the CLASS_DECL. Create one if
1320 for (chain = &objc_static_instances;
1321 *chain && TREE_VALUE (*chain) != class_decl;
1322 chain = &TREE_CHAIN (*chain));
1325 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1326 add_objc_string (TYPE_NAME (class_decl), class_names);
1329 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1330 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1331 DECL_COMMON (decl) = 1;
1332 TREE_STATIC (decl) = 1;
1333 DECL_ARTIFICIAL (decl) = 1;
1334 DECL_INITIAL (decl) = constructor;
1336 /* We may be writing something else just now.
1337 Postpone till end of input. */
1338 DECL_DEFER_OUTPUT (decl) = 1;
1339 pushdecl_top_level (decl);
1340 rest_of_decl_compilation (decl, 0, 1, 0);
1342 /* Add the DECL to the head of this CLASS' list. */
1343 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1348 /* Build a static constant CONSTRUCTOR
1349 with type TYPE and elements ELTS. */
1352 objc_build_constructor (tree type, tree elts)
1354 tree constructor, f, e;
1356 /* ??? Most of the places that we build constructors, we don't fill in
1357 the type of integers properly. Convert them all en masse. */
1358 if (TREE_CODE (type) == ARRAY_TYPE)
1360 f = TREE_TYPE (type);
1361 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1362 for (e = elts; e ; e = TREE_CHAIN (e))
1363 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1367 f = TYPE_FIELDS (type);
1368 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1369 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1370 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1371 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1374 constructor = build_constructor (type, elts);
1375 TREE_CONSTANT (constructor) = 1;
1376 TREE_STATIC (constructor) = 1;
1377 TREE_READONLY (constructor) = 1;
1382 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1384 /* Predefine the following data type:
1392 void *defs[cls_def_cnt + cat_def_cnt];
1396 build_objc_symtab_template (void)
1398 tree field_decl, field_decl_chain, index;
1400 objc_symtab_template
1401 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1403 /* long sel_ref_cnt; */
1405 field_decl = create_builtin_decl (FIELD_DECL,
1406 long_integer_type_node,
1408 field_decl_chain = field_decl;
1412 field_decl = create_builtin_decl (FIELD_DECL,
1413 build_pointer_type (selector_type),
1415 chainon (field_decl_chain, field_decl);
1417 /* short cls_def_cnt; */
1419 field_decl = create_builtin_decl (FIELD_DECL,
1420 short_integer_type_node,
1422 chainon (field_decl_chain, field_decl);
1424 /* short cat_def_cnt; */
1426 field_decl = create_builtin_decl (FIELD_DECL,
1427 short_integer_type_node,
1429 chainon (field_decl_chain, field_decl);
1431 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1433 if (!flag_next_runtime)
1434 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1436 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1437 imp_count == 0 && cat_count == 0
1439 field_decl = create_builtin_decl (FIELD_DECL,
1440 build_array_type (ptr_type_node, index),
1442 chainon (field_decl_chain, field_decl);
1444 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1447 /* Create the initial value for the `defs' field of _objc_symtab.
1448 This is a CONSTRUCTOR. */
1451 init_def_list (tree type)
1453 tree expr, initlist = NULL_TREE;
1454 struct imp_entry *impent;
1457 for (impent = imp_list; impent; impent = impent->next)
1459 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1461 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1462 initlist = tree_cons (NULL_TREE, expr, initlist);
1467 for (impent = imp_list; impent; impent = impent->next)
1469 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1471 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1472 initlist = tree_cons (NULL_TREE, expr, initlist);
1476 if (!flag_next_runtime)
1478 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1481 if (static_instances_decl)
1482 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1484 expr = build_int_2 (0, 0);
1486 initlist = tree_cons (NULL_TREE, expr, initlist);
1489 return objc_build_constructor (type, nreverse (initlist));
1492 /* Construct the initial value for all of _objc_symtab. */
1495 init_objc_symtab (tree type)
1499 /* sel_ref_cnt = { ..., 5, ... } */
1501 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1503 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1505 if (flag_next_runtime || ! sel_ref_chain)
1506 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1508 initlist = tree_cons (NULL_TREE,
1509 build_unary_op (ADDR_EXPR,
1510 UOBJC_SELECTOR_TABLE_decl, 1),
1513 /* cls_def_cnt = { ..., 5, ... } */
1515 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1517 /* cat_def_cnt = { ..., 5, ... } */
1519 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1521 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1523 if (imp_count || cat_count || static_instances_decl)
1526 tree field = TYPE_FIELDS (type);
1527 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1529 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1533 return objc_build_constructor (type, nreverse (initlist));
1536 /* Push forward-declarations of all the categories so that
1537 init_def_list can use them in a CONSTRUCTOR. */
1540 forward_declare_categories (void)
1542 struct imp_entry *impent;
1543 tree sav = objc_implementation_context;
1545 for (impent = imp_list; impent; impent = impent->next)
1547 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1549 /* Set an invisible arg to synth_id_with_class_suffix. */
1550 objc_implementation_context = impent->imp_context;
1552 = create_builtin_decl (VAR_DECL, objc_category_template,
1553 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1554 TREE_PUBLIC (impent->class_decl) = 0;
1557 objc_implementation_context = sav;
1560 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1561 and initialized appropriately. */
1564 generate_objc_symtab_decl (void)
1568 if (!objc_category_template)
1569 build_category_template ();
1571 /* forward declare categories */
1573 forward_declare_categories ();
1575 if (!objc_symtab_template)
1576 build_objc_symtab_template ();
1578 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1580 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1581 tree_cons (NULL_TREE,
1582 objc_symtab_template, sc_spec),
1586 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1587 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1588 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1589 finish_decl (UOBJC_SYMBOLS_decl,
1590 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1595 init_module_descriptor (tree type)
1597 tree initlist, expr;
1599 /* version = { 1, ... } */
1601 expr = build_int_2 (OBJC_VERSION, 0);
1602 initlist = build_tree_list (NULL_TREE, expr);
1604 /* size = { ..., sizeof (struct objc_module), ... } */
1606 expr = size_in_bytes (objc_module_template);
1607 initlist = tree_cons (NULL_TREE, expr, initlist);
1609 /* name = { ..., "foo.m", ... } */
1611 expr = add_objc_string (get_identifier (input_filename), class_names);
1612 initlist = tree_cons (NULL_TREE, expr, initlist);
1614 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1616 if (UOBJC_SYMBOLS_decl)
1617 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1619 expr = build_int_2 (0, 0);
1620 initlist = tree_cons (NULL_TREE, expr, initlist);
1622 return objc_build_constructor (type, nreverse (initlist));
1625 /* Write out the data structures to describe Objective C classes defined.
1626 If appropriate, compile and output a setup function to initialize them.
1627 Return a symbol_ref to the function to call to initialize the Objective C
1628 data structures for this file (and perhaps for other files also).
1630 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1633 build_module_descriptor (void)
1635 tree decl_specs, field_decl, field_decl_chain;
1637 objc_module_template
1638 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1642 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1643 field_decl = get_identifier ("version");
1644 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1645 field_decl_chain = field_decl;
1649 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1650 field_decl = get_identifier ("size");
1651 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1652 chainon (field_decl_chain, field_decl);
1656 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1657 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1658 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1659 chainon (field_decl_chain, field_decl);
1661 /* struct objc_symtab *symtab; */
1663 decl_specs = get_identifier (UTAG_SYMTAB);
1664 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1665 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1666 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1667 chainon (field_decl_chain, field_decl);
1669 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1671 /* Create an instance of "objc_module". */
1673 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1674 build_tree_list (NULL_TREE,
1675 ridpointers[(int) RID_STATIC]));
1677 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1678 decl_specs, 1, NULL_TREE);
1680 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1681 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1682 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1684 finish_decl (UOBJC_MODULES_decl,
1685 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1688 /* Mark the decl to avoid "defined but not used" warning. */
1689 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1691 /* Generate a constructor call for the module descriptor.
1692 This code was generated by reading the grammar rules
1693 of c-parse.in; Therefore, it may not be the most efficient
1694 way of generating the requisite code. */
1696 if (flag_next_runtime)
1700 tree parms, execclass_decl, decelerator, void_list_node_1;
1701 tree init_function_name, init_function_decl;
1703 /* Declare void __objc_execClass (void *); */
1705 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1706 execclass_decl = build_decl (FUNCTION_DECL,
1707 get_identifier (TAG_EXECCLASS),
1708 build_function_type (void_type_node,
1709 tree_cons (NULL_TREE, ptr_type_node,
1710 void_list_node_1)));
1711 DECL_EXTERNAL (execclass_decl) = 1;
1712 DECL_ARTIFICIAL (execclass_decl) = 1;
1713 TREE_PUBLIC (execclass_decl) = 1;
1714 pushdecl (execclass_decl);
1715 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1716 assemble_external (execclass_decl);
1718 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1720 init_function_name = get_file_function_name ('I');
1721 start_function (void_list_node_1,
1722 build_nt (CALL_EXPR, init_function_name,
1723 tree_cons (NULL_TREE, NULL_TREE,
1727 store_parm_decls ();
1729 init_function_decl = current_function_decl;
1730 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1731 TREE_USED (init_function_decl) = 1;
1732 /* Don't let this one be deferred. */
1733 DECL_INLINE (init_function_decl) = 0;
1734 DECL_UNINLINABLE (init_function_decl) = 1;
1735 current_function_cannot_inline
1736 = "static constructors and destructors cannot be inlined";
1739 = build_tree_list (NULL_TREE,
1740 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1741 decelerator = build_function_call (execclass_decl, parms);
1743 c_expand_expr_stmt (decelerator);
1747 return XEXP (DECL_RTL (init_function_decl), 0);
1751 /* extern const char _OBJC_STRINGS[]; */
1754 generate_forward_declaration_to_string_table (void)
1756 tree sc_spec, decl_specs, expr_decl;
1758 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1759 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1762 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1764 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1767 /* Return the DECL of the string IDENT in the SECTION. */
1770 get_objc_string_decl (tree ident, enum string_section section)
1774 if (section == class_names)
1775 chain = class_names_chain;
1776 else if (section == meth_var_names)
1777 chain = meth_var_names_chain;
1778 else if (section == meth_var_types)
1779 chain = meth_var_types_chain;
1783 for (; chain != 0; chain = TREE_CHAIN (chain))
1784 if (TREE_VALUE (chain) == ident)
1785 return (TREE_PURPOSE (chain));
1791 /* Output references to all statically allocated objects. Return the DECL
1792 for the array built. */
1795 generate_static_references (void)
1797 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1798 tree class_name, class, decl, initlist;
1799 tree cl_chain, in_chain, type;
1800 int num_inst, num_class;
1803 if (flag_next_runtime)
1806 for (cl_chain = objc_static_instances, num_class = 0;
1807 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1809 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1810 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1812 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1813 ident = get_identifier (buf);
1815 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1816 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1817 build_tree_list (NULL_TREE,
1818 ridpointers[(int) RID_STATIC]));
1819 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1820 DECL_CONTEXT (decl) = 0;
1821 DECL_ARTIFICIAL (decl) = 1;
1823 /* Output {class_name, ...}. */
1824 class = TREE_VALUE (cl_chain);
1825 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1826 initlist = build_tree_list (NULL_TREE,
1827 build_unary_op (ADDR_EXPR, class_name, 1));
1829 /* Output {..., instance, ...}. */
1830 for (in_chain = TREE_PURPOSE (cl_chain);
1831 in_chain; in_chain = TREE_CHAIN (in_chain))
1833 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1834 initlist = tree_cons (NULL_TREE, expr, initlist);
1837 /* Output {..., NULL}. */
1838 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1840 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
1841 finish_decl (decl, expr, NULL_TREE);
1842 TREE_USED (decl) = 1;
1844 type = build_array_type (build_pointer_type (void_type_node), 0);
1845 decl = build_decl (VAR_DECL, ident, type);
1846 TREE_USED (decl) = 1;
1847 TREE_STATIC (decl) = 1;
1849 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1852 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1853 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1854 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1855 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1856 build_tree_list (NULL_TREE,
1857 ridpointers[(int) RID_STATIC]));
1858 static_instances_decl
1859 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1860 TREE_USED (static_instances_decl) = 1;
1861 DECL_CONTEXT (static_instances_decl) = 0;
1862 DECL_ARTIFICIAL (static_instances_decl) = 1;
1863 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
1865 finish_decl (static_instances_decl, expr, NULL_TREE);
1868 /* Output all strings. */
1871 generate_strings (void)
1873 tree sc_spec, decl_specs, expr_decl;
1874 tree chain, string_expr;
1877 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1879 string = TREE_VALUE (chain);
1880 decl = TREE_PURPOSE (chain);
1882 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1883 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1884 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1885 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1886 DECL_CONTEXT (decl) = NULL_TREE;
1887 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1888 IDENTIFIER_POINTER (string));
1889 finish_decl (decl, string_expr, NULL_TREE);
1892 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1894 string = TREE_VALUE (chain);
1895 decl = TREE_PURPOSE (chain);
1897 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1898 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1899 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1900 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1901 DECL_CONTEXT (decl) = NULL_TREE;
1902 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1903 IDENTIFIER_POINTER (string));
1904 finish_decl (decl, string_expr, NULL_TREE);
1907 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1909 string = TREE_VALUE (chain);
1910 decl = TREE_PURPOSE (chain);
1912 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1913 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1914 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1915 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1916 DECL_CONTEXT (decl) = NULL_TREE;
1917 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1918 IDENTIFIER_POINTER (string));
1919 finish_decl (decl, string_expr, NULL_TREE);
1923 static GTY(()) int selector_reference_idx;
1925 build_selector_reference_decl (void)
1930 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
1932 ident = get_identifier (buf);
1934 decl = build_decl (VAR_DECL, ident, selector_type);
1935 DECL_EXTERNAL (decl) = 1;
1936 TREE_PUBLIC (decl) = 0;
1937 TREE_USED (decl) = 1;
1938 TREE_READONLY (decl) = 1;
1939 DECL_ARTIFICIAL (decl) = 1;
1940 DECL_CONTEXT (decl) = 0;
1942 make_decl_rtl (decl, 0);
1943 pushdecl_top_level (decl);
1948 /* Just a handy wrapper for add_objc_string. */
1951 build_selector (tree ident)
1953 tree expr = add_objc_string (ident, meth_var_names);
1954 if (flag_typed_selectors)
1957 return build_c_cast (selector_type, expr); /* cast! */
1961 build_selector_translation_table (void)
1963 tree sc_spec, decl_specs;
1964 tree chain, initlist = NULL_TREE;
1966 tree decl = NULL_TREE, var_decl, name;
1968 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1972 if (warn_selector && objc_implementation_context)
1976 for (method_chain = meth_var_names_chain;
1978 method_chain = TREE_CHAIN (method_chain))
1980 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
1988 /* Adjust line number for warning message. */
1989 int save_lineno = input_line;
1990 if (flag_next_runtime && TREE_PURPOSE (chain))
1991 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
1992 warning ("creating selector for non existant method %s",
1993 IDENTIFIER_POINTER (TREE_VALUE (chain)));
1994 input_line = save_lineno;
1998 expr = build_selector (TREE_VALUE (chain));
2000 if (flag_next_runtime)
2002 name = DECL_NAME (TREE_PURPOSE (chain));
2004 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2006 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2007 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2011 /* The `decl' that is returned from start_decl is the one that we
2012 forward declared in `build_selector_reference' */
2013 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2016 /* add one for the '\0' character */
2017 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2019 if (flag_next_runtime)
2020 finish_decl (decl, expr, NULL_TREE);
2023 if (flag_typed_selectors)
2025 tree eltlist = NULL_TREE;
2026 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2027 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2028 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2029 expr = objc_build_constructor (objc_selector_template,
2030 nreverse (eltlist));
2032 initlist = tree_cons (NULL_TREE, expr, initlist);
2037 if (! flag_next_runtime)
2039 /* Cause the variable and its initial value to be actually output. */
2040 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2041 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2042 /* NULL terminate the list and fix the decl for output. */
2043 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2044 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2045 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2046 nreverse (initlist));
2047 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2048 current_function_decl = NULL_TREE;
2053 get_proto_encoding (tree proto)
2060 if (! METHOD_ENCODING (proto))
2062 tmp_decl = build_tmp_function_decl ();
2063 hack_method_prototype (proto, tmp_decl);
2064 encoding = encode_method_prototype (proto, tmp_decl);
2065 METHOD_ENCODING (proto) = encoding;
2068 encoding = METHOD_ENCODING (proto);
2070 return add_objc_string (encoding, meth_var_types);
2073 return build_int_2 (0, 0);
2076 /* sel_ref_chain is a list whose "value" fields will be instances of
2077 identifier_node that represent the selector. */
2080 build_typed_selector_reference (tree ident, tree prototype)
2082 tree *chain = &sel_ref_chain;
2088 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2089 goto return_at_index;
2092 chain = &TREE_CHAIN (*chain);
2095 *chain = tree_cons (prototype, ident, NULL_TREE);
2098 expr = build_unary_op (ADDR_EXPR,
2099 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2100 build_int_2 (index, 0)),
2102 return build_c_cast (selector_type, expr);
2106 build_selector_reference (tree ident)
2108 tree *chain = &sel_ref_chain;
2114 if (TREE_VALUE (*chain) == ident)
2115 return (flag_next_runtime
2116 ? TREE_PURPOSE (*chain)
2117 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2118 build_int_2 (index, 0)));
2121 chain = &TREE_CHAIN (*chain);
2124 expr = build_selector_reference_decl ();
2126 *chain = tree_cons (expr, ident, NULL_TREE);
2128 return (flag_next_runtime
2130 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2131 build_int_2 (index, 0)));
2134 static GTY(()) int class_reference_idx;
2136 build_class_reference_decl (void)
2141 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2143 ident = get_identifier (buf);
2145 decl = build_decl (VAR_DECL, ident, objc_class_type);
2146 DECL_EXTERNAL (decl) = 1;
2147 TREE_PUBLIC (decl) = 0;
2148 TREE_USED (decl) = 1;
2149 TREE_READONLY (decl) = 1;
2150 DECL_CONTEXT (decl) = 0;
2151 DECL_ARTIFICIAL (decl) = 1;
2153 make_decl_rtl (decl, 0);
2154 pushdecl_top_level (decl);
2159 /* Create a class reference, but don't create a variable to reference
2163 add_class_reference (tree ident)
2167 if ((chain = cls_ref_chain))
2172 if (ident == TREE_VALUE (chain))
2176 chain = TREE_CHAIN (chain);
2180 /* Append to the end of the list */
2181 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2184 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2187 /* Get a class reference, creating it if necessary. Also create the
2188 reference variable. */
2191 get_class_reference (tree ident)
2193 if (flag_next_runtime)
2198 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2199 if (TREE_VALUE (*chain) == ident)
2201 if (! TREE_PURPOSE (*chain))
2202 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2204 return TREE_PURPOSE (*chain);
2207 decl = build_class_reference_decl ();
2208 *chain = tree_cons (decl, ident, NULL_TREE);
2215 add_class_reference (ident);
2217 params = build_tree_list (NULL_TREE,
2218 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2219 IDENTIFIER_POINTER (ident)));
2221 assemble_external (objc_get_class_decl);
2222 return build_function_call (objc_get_class_decl, params);
2226 /* For each string section we have a chain which maps identifier nodes
2227 to decls for the strings. */
2230 add_objc_string (tree ident, enum string_section section)
2234 if (section == class_names)
2235 chain = &class_names_chain;
2236 else if (section == meth_var_names)
2237 chain = &meth_var_names_chain;
2238 else if (section == meth_var_types)
2239 chain = &meth_var_types_chain;
2245 if (TREE_VALUE (*chain) == ident)
2246 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2248 chain = &TREE_CHAIN (*chain);
2251 decl = build_objc_string_decl (section);
2253 *chain = tree_cons (decl, ident, NULL_TREE);
2255 return build_unary_op (ADDR_EXPR, decl, 1);
2258 static GTY(()) int class_names_idx;
2259 static GTY(()) int meth_var_names_idx;
2260 static GTY(()) int meth_var_types_idx;
2263 build_objc_string_decl (enum string_section section)
2268 if (section == class_names)
2269 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2270 else if (section == meth_var_names)
2271 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2272 else if (section == meth_var_types)
2273 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2275 ident = get_identifier (buf);
2277 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2278 DECL_EXTERNAL (decl) = 1;
2279 TREE_PUBLIC (decl) = 0;
2280 TREE_USED (decl) = 1;
2281 TREE_READONLY (decl) = 1;
2282 TREE_CONSTANT (decl) = 1;
2283 DECL_CONTEXT (decl) = 0;
2284 DECL_ARTIFICIAL (decl) = 1;
2286 make_decl_rtl (decl, 0);
2287 pushdecl_top_level (decl);
2294 objc_declare_alias (tree alias_ident, tree class_ident)
2296 if (is_class_name (class_ident) != class_ident)
2297 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2298 else if (is_class_name (alias_ident))
2299 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2301 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2305 objc_declare_class (tree ident_list)
2309 for (list = ident_list; list; list = TREE_CHAIN (list))
2311 tree ident = TREE_VALUE (list);
2314 if ((decl = lookup_name (ident)))
2316 error ("`%s' redeclared as different kind of symbol",
2317 IDENTIFIER_POINTER (ident));
2318 error ("%Hprevious declaration of '%D'",
2319 &DECL_SOURCE_LOCATION (decl), decl);
2322 if (! is_class_name (ident))
2324 tree record = xref_tag (RECORD_TYPE, ident);
2325 TREE_STATIC_TEMPLATE (record) = 1;
2326 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2332 is_class_name (tree ident)
2336 if (lookup_interface (ident))
2339 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2341 if (ident == TREE_VALUE (chain))
2345 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2347 if (ident == TREE_VALUE (chain))
2348 return TREE_PURPOSE (chain);
2355 objc_is_id (tree ident)
2357 /* NB: This function may be called before the ObjC front-end
2358 has been initialized, in which case ID_TYPE will be NULL. */
2359 return (id_type && ident && TYPE_P (ident) && IS_ID (ident))
2365 lookup_interface (tree ident)
2369 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2371 if (ident == CLASS_NAME (chain))
2377 /* Used by: build_private_template, continue_class,
2378 and for @defs constructs. */
2381 get_class_ivars (tree interface)
2383 tree my_name, super_name, ivar_chain;
2385 my_name = CLASS_NAME (interface);
2386 super_name = CLASS_SUPER_NAME (interface);
2387 ivar_chain = CLASS_IVARS (interface);
2389 /* Save off a pristine copy of the leaf ivars (i.e, those not
2390 inherited from a super class). */
2391 if (!CLASS_OWN_IVARS (interface))
2392 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2397 tree super_interface = lookup_interface (super_name);
2399 if (!super_interface)
2401 /* fatal did not work with 2 args...should fix */
2402 error ("cannot find interface declaration for `%s', superclass of `%s'",
2403 IDENTIFIER_POINTER (super_name),
2404 IDENTIFIER_POINTER (my_name));
2405 exit (FATAL_EXIT_CODE);
2408 if (super_interface == interface)
2409 fatal_error ("circular inheritance in interface declaration for `%s'",
2410 IDENTIFIER_POINTER (super_name));
2412 interface = super_interface;
2413 my_name = CLASS_NAME (interface);
2414 super_name = CLASS_SUPER_NAME (interface);
2416 op1 = CLASS_OWN_IVARS (interface);
2419 tree head = copy_list (op1);
2421 /* Prepend super class ivars...make a copy of the list, we
2422 do not want to alter the original. */
2423 chainon (head, ivar_chain);
2430 /* struct <classname> {
2431 struct objc_class *isa;
2436 build_private_template (tree class)
2440 if (CLASS_STATIC_TEMPLATE (class))
2442 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2443 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2447 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2449 ivar_context = get_class_ivars (class);
2451 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2453 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2455 /* mark this record as class template - for class type checking */
2456 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2460 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2462 build1 (INDIRECT_REF, NULL_TREE,
2465 return ivar_context;
2468 /* Begin code generation for protocols... */
2470 /* struct objc_protocol {
2471 char *protocol_name;
2472 struct objc_protocol **protocol_list;
2473 struct objc_method_desc *instance_methods;
2474 struct objc_method_desc *class_methods;
2478 build_protocol_template (void)
2480 tree decl_specs, field_decl, field_decl_chain;
2483 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2485 /* struct objc_class *isa; */
2487 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2488 get_identifier (UTAG_CLASS)));
2489 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2490 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2491 field_decl_chain = field_decl;
2493 /* char *protocol_name; */
2495 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2497 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2498 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2499 chainon (field_decl_chain, field_decl);
2501 /* struct objc_protocol **protocol_list; */
2503 decl_specs = build_tree_list (NULL_TREE, template);
2505 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2506 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2507 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2508 chainon (field_decl_chain, field_decl);
2510 /* struct objc_method_list *instance_methods; */
2513 = build_tree_list (NULL_TREE,
2514 xref_tag (RECORD_TYPE,
2515 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2517 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2518 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2519 chainon (field_decl_chain, field_decl);
2521 /* struct objc_method_list *class_methods; */
2524 = build_tree_list (NULL_TREE,
2525 xref_tag (RECORD_TYPE,
2526 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2528 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2529 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2530 chainon (field_decl_chain, field_decl);
2532 return finish_struct (template, field_decl_chain, NULL_TREE);
2536 build_descriptor_table_initializer (tree type, tree entries)
2538 tree initlist = NULL_TREE;
2542 tree eltlist = NULL_TREE;
2545 = tree_cons (NULL_TREE,
2546 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2548 = tree_cons (NULL_TREE,
2549 add_objc_string (METHOD_ENCODING (entries),
2554 = tree_cons (NULL_TREE,
2555 objc_build_constructor (type, nreverse (eltlist)),
2558 entries = TREE_CHAIN (entries);
2562 return objc_build_constructor (build_array_type (type, 0),
2563 nreverse (initlist));
2566 /* struct objc_method_prototype_list {
2568 struct objc_method_prototype {
2575 build_method_prototype_list_template (tree list_type, int size)
2577 tree objc_ivar_list_record;
2578 tree decl_specs, field_decl, field_decl_chain;
2580 /* Generate an unnamed struct definition. */
2582 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2584 /* int method_count; */
2586 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2587 field_decl = get_identifier ("method_count");
2588 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2589 field_decl_chain = field_decl;
2591 /* struct objc_method method_list[]; */
2593 decl_specs = build_tree_list (NULL_TREE, list_type);
2594 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2595 build_int_2 (size, 0));
2596 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2597 chainon (field_decl_chain, field_decl);
2599 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2601 return objc_ivar_list_record;
2605 build_method_prototype_template (void)
2608 tree decl_specs, field_decl, field_decl_chain;
2611 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2613 /* struct objc_selector *_cmd; */
2614 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2615 get_identifier (TAG_SELECTOR)), NULL_TREE);
2616 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2617 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2618 field_decl_chain = field_decl;
2620 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2622 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2623 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2624 chainon (field_decl_chain, field_decl);
2626 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2628 return proto_record;
2631 /* True if last call to forwarding_offset yielded a register offset. */
2632 static int offset_is_register;
2635 forwarding_offset (tree parm)
2637 int offset_in_bytes;
2639 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2641 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2643 /* ??? Here we assume that the parm address is indexed
2644 off the frame pointer or arg pointer.
2645 If that is not true, we produce meaningless results,
2646 but do not crash. */
2647 if (GET_CODE (addr) == PLUS
2648 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2649 offset_in_bytes = INTVAL (XEXP (addr, 1));
2651 offset_in_bytes = 0;
2653 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2654 offset_is_register = 0;
2656 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2658 int regno = REGNO (DECL_INCOMING_RTL (parm));
2659 offset_in_bytes = apply_args_register_offset (regno);
2660 offset_is_register = 1;
2665 /* This is the case where the parm is passed as an int or double
2666 and it is converted to a char, short or float and stored back
2667 in the parmlist. In this case, describe the parm
2668 with the variable's declared type, and adjust the address
2669 if the least significant bytes (which we are using) are not
2671 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2672 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2673 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2675 return offset_in_bytes;
2679 encode_method_prototype (tree method_decl, tree func_decl)
2684 HOST_WIDE_INT max_parm_end = 0;
2688 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2689 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2692 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2693 obstack_object_size (&util_obstack),
2694 OBJC_ENCODE_INLINE_DEFS);
2697 for (parms = DECL_ARGUMENTS (func_decl); parms;
2698 parms = TREE_CHAIN (parms))
2700 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2701 + int_size_in_bytes (TREE_TYPE (parms)));
2703 if (!offset_is_register && max_parm_end < parm_end)
2704 max_parm_end = parm_end;
2707 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2709 sprintf (buf, "%d", stack_size);
2710 obstack_grow (&util_obstack, buf, strlen (buf));
2712 user_args = METHOD_SEL_ARGS (method_decl);
2714 /* Argument types. */
2715 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2716 parms = TREE_CHAIN (parms), i++)
2718 /* Process argument qualifiers for user supplied arguments. */
2721 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2722 user_args = TREE_CHAIN (user_args);
2726 encode_type (TREE_TYPE (parms),
2727 obstack_object_size (&util_obstack),
2728 OBJC_ENCODE_INLINE_DEFS);
2730 /* Compute offset. */
2731 sprintf (buf, "%d", forwarding_offset (parms));
2733 /* Indicate register. */
2734 if (offset_is_register)
2735 obstack_1grow (&util_obstack, '+');
2737 obstack_grow (&util_obstack, buf, strlen (buf));
2740 obstack_1grow (&util_obstack, '\0');
2741 result = get_identifier (obstack_finish (&util_obstack));
2742 obstack_free (&util_obstack, util_firstobj);
2747 generate_descriptor_table (tree type, const char *name, int size, tree list,
2750 tree sc_spec, decl_specs, decl, initlist;
2752 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2753 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2755 decl = start_decl (synth_id_with_class_suffix (name, proto),
2756 decl_specs, 1, NULL_TREE);
2757 DECL_CONTEXT (decl) = NULL_TREE;
2759 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2760 initlist = tree_cons (NULL_TREE, list, initlist);
2762 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
2769 generate_method_descriptors (tree protocol)
2771 tree initlist, chain, method_list_template;
2772 tree cast, variable_length_type;
2775 if (!objc_method_prototype_template)
2776 objc_method_prototype_template = build_method_prototype_template ();
2778 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2779 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2781 variable_length_type = groktypename (cast);
2783 chain = PROTOCOL_CLS_METHODS (protocol);
2786 size = list_length (chain);
2788 method_list_template
2789 = build_method_prototype_list_template (objc_method_prototype_template,
2793 = build_descriptor_table_initializer (objc_method_prototype_template,
2796 UOBJC_CLASS_METHODS_decl
2797 = generate_descriptor_table (method_list_template,
2798 "_OBJC_PROTOCOL_CLASS_METHODS",
2799 size, initlist, protocol);
2800 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2803 UOBJC_CLASS_METHODS_decl = 0;
2805 chain = PROTOCOL_NST_METHODS (protocol);
2808 size = list_length (chain);
2810 method_list_template
2811 = build_method_prototype_list_template (objc_method_prototype_template,
2814 = build_descriptor_table_initializer (objc_method_prototype_template,
2817 UOBJC_INSTANCE_METHODS_decl
2818 = generate_descriptor_table (method_list_template,
2819 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2820 size, initlist, protocol);
2821 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2824 UOBJC_INSTANCE_METHODS_decl = 0;
2827 /* Generate a temporary FUNCTION_DECL node to be used in
2828 hack_method_prototype below. */
2830 static GTY(()) int build_tmp_function_decl_xxx;
2832 build_tmp_function_decl (void)
2834 tree decl_specs, expr_decl, parms;
2838 /* struct objc_object *objc_xxx (id, SEL, ...); */
2840 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2841 push_parm_decl (build_tree_list
2842 (build_tree_list (decl_specs,
2843 build1 (INDIRECT_REF, NULL_TREE,
2847 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2848 get_identifier (TAG_SELECTOR)));
2849 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2851 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2853 parms = get_parm_info (0);
2856 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2857 sprintf (buffer, "__objc_tmp_%x", build_tmp_function_decl_xxx++);
2858 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2859 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2861 tmp_decl = define_decl (expr_decl, decl_specs);
2862 DECL_SOURCE_LINE (tmp_decl) = 0;
2867 /* Generate the prototypes for protocol methods. This is used to
2868 generate method encodings for these.
2870 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2871 a decl node to be used. This is also where the return value is
2875 hack_method_prototype (tree nst_methods, tree tmp_decl)
2880 /* Hack to avoid problem with static typing of self arg. */
2881 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2882 start_method_def (nst_methods);
2883 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2885 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2886 parms = get_parm_info (0); /* we have a `, ...' */
2888 parms = get_parm_info (1); /* place a `void_at_end' */
2890 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2892 /* Usually called from store_parm_decls -> init_function_start. */
2894 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2896 if (current_function_decl)
2898 current_function_decl = tmp_decl;
2901 /* Code taken from start_function. */
2902 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2903 /* Promote the value to int before returning it. */
2904 if (TREE_CODE (restype) == INTEGER_TYPE
2905 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2906 restype = integer_type_node;
2907 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2910 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2911 DECL_CONTEXT (parm) = tmp_decl;
2913 init_function_start (tmp_decl);
2915 /* Typically called from expand_function_start for function definitions. */
2916 assign_parms (tmp_decl);
2918 /* install return type */
2919 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2921 current_function_decl = NULL;
2925 generate_protocol_references (tree plist)
2929 /* Forward declare protocols referenced. */
2930 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2932 tree proto = TREE_VALUE (lproto);
2934 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2935 && PROTOCOL_NAME (proto))
2937 if (! PROTOCOL_FORWARD_DECL (proto))
2938 build_protocol_reference (proto);
2940 if (PROTOCOL_LIST (proto))
2941 generate_protocol_references (PROTOCOL_LIST (proto));
2946 /* For each protocol which was referenced either from a @protocol()
2947 expression, or because a class/category implements it (then a
2948 pointer to the protocol is stored in the struct describing the
2949 class/category), we create a statically allocated instance of the
2950 Protocol class. The code is written in such a way as to generate
2951 as few Protocol objects as possible; we generate a unique Protocol
2952 instance for each protocol, and we don't generate a Protocol
2953 instance if the protocol is never referenced (either from a
2954 @protocol() or from a class/category implementation). These
2955 statically allocated objects can be referred to via the static
2956 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
2958 The statically allocated Protocol objects that we generate here
2959 need to be fixed up at runtime in order to be used: the 'isa'
2960 pointer of the objects need to be set up to point to the 'Protocol'
2961 class, as known at runtime.
2963 The NeXT runtime fixes up all protocols at program startup time,
2964 before main() is entered. It uses a low-level trick to look up all
2965 those symbols, then loops on them and fixes them up.
2967 The GNU runtime as well fixes up all protocols before user code
2968 from the module is executed; it requires pointers to those symbols
2969 to be put in the objc_symtab (which is then passed as argument to
2970 the function __objc_exec_class() which the compiler sets up to be
2971 executed automatically when the module is loaded); setup of those
2972 Protocol objects happen in two ways in the GNU runtime: all
2973 Protocol objects referred to by a class or category implementation
2974 are fixed up when the class/category is loaded; all Protocol
2975 objects referred to by a @protocol() expression are added by the
2976 compiler to the list of statically allocated instances to fixup
2977 (the same list holding the statically allocated constant string
2978 objects). Because, as explained above, the compiler generates as
2979 few Protocol objects as possible, some Protocol object might end up
2980 being referenced multiple times when compiled with the GNU runtime,
2981 and end up being fixed up multiple times at runtime inizialization.
2982 But that doesn't hurt, it's just a little inefficient. */
2984 generate_protocols (void)
2986 tree p, tmp_decl, encoding;
2987 tree sc_spec, decl_specs, decl;
2988 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2991 tmp_decl = build_tmp_function_decl ();
2993 if (! objc_protocol_template)
2994 objc_protocol_template = build_protocol_template ();
2996 /* If a protocol was directly referenced, pull in indirect references. */
2997 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2998 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2999 generate_protocol_references (PROTOCOL_LIST (p));
3001 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3003 tree nst_methods = PROTOCOL_NST_METHODS (p);
3004 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3006 /* If protocol wasn't referenced, don't generate any code. */
3007 if (! PROTOCOL_FORWARD_DECL (p))
3010 /* Make sure we link in the Protocol class. */
3011 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3015 if (! METHOD_ENCODING (nst_methods))
3017 hack_method_prototype (nst_methods, tmp_decl);
3018 encoding = encode_method_prototype (nst_methods, tmp_decl);
3019 METHOD_ENCODING (nst_methods) = encoding;
3021 nst_methods = TREE_CHAIN (nst_methods);
3026 if (! METHOD_ENCODING (cls_methods))
3028 hack_method_prototype (cls_methods, tmp_decl);
3029 encoding = encode_method_prototype (cls_methods, tmp_decl);
3030 METHOD_ENCODING (cls_methods) = encoding;
3033 cls_methods = TREE_CHAIN (cls_methods);
3035 generate_method_descriptors (p);
3037 if (PROTOCOL_LIST (p))
3038 refs_decl = generate_protocol_list (p);
3042 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3044 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3046 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3048 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3049 decl_specs, 1, NULL_TREE);
3051 DECL_CONTEXT (decl) = NULL_TREE;
3053 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3059 (build_tree_list (build_tree_list (NULL_TREE,
3060 objc_protocol_template),
3061 build1 (INDIRECT_REF, NULL_TREE,
3062 build1 (INDIRECT_REF, NULL_TREE,
3065 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3066 TREE_TYPE (refs_expr) = cast_type2;
3069 refs_expr = build_int_2 (0, 0);
3071 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3072 by generate_method_descriptors, which is called above. */
3073 initlist = build_protocol_initializer (TREE_TYPE (decl),
3074 protocol_name_expr, refs_expr,
3075 UOBJC_INSTANCE_METHODS_decl,
3076 UOBJC_CLASS_METHODS_decl);
3077 finish_decl (decl, initlist, NULL_TREE);
3079 /* Mark the decl as used to avoid "defined but not used" warning. */
3080 TREE_USED (decl) = 1;
3085 build_protocol_initializer (tree type, tree protocol_name,
3086 tree protocol_list, tree instance_methods,
3089 tree initlist = NULL_TREE, expr;
3092 cast_type = groktypename
3094 (build_tree_list (NULL_TREE,
3095 xref_tag (RECORD_TYPE,
3096 get_identifier (UTAG_CLASS))),
3097 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3099 /* Filling the "isa" in with one allows the runtime system to
3100 detect that the version change...should remove before final release. */
3102 expr = build_int_2 (PROTOCOL_VERSION, 0);
3103 TREE_TYPE (expr) = cast_type;
3104 initlist = tree_cons (NULL_TREE, expr, initlist);
3105 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3106 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3108 if (!instance_methods)
3109 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3112 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3113 initlist = tree_cons (NULL_TREE, expr, initlist);
3117 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3120 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3121 initlist = tree_cons (NULL_TREE, expr, initlist);
3124 return objc_build_constructor (type, nreverse (initlist));
3127 /* struct objc_category {
3128 char *category_name;
3130 struct objc_method_list *instance_methods;
3131 struct objc_method_list *class_methods;
3132 struct objc_protocol_list *protocols;
3136 build_category_template (void)
3138 tree decl_specs, field_decl, field_decl_chain;
3140 objc_category_template = start_struct (RECORD_TYPE,
3141 get_identifier (UTAG_CATEGORY));
3142 /* char *category_name; */
3144 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3146 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3147 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3148 field_decl_chain = field_decl;
3150 /* char *class_name; */
3152 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3153 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3154 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3155 chainon (field_decl_chain, field_decl);
3157 /* struct objc_method_list *instance_methods; */
3159 decl_specs = build_tree_list (NULL_TREE,
3160 xref_tag (RECORD_TYPE,
3161 get_identifier (UTAG_METHOD_LIST)));
3163 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3164 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3165 chainon (field_decl_chain, field_decl);
3167 /* struct objc_method_list *class_methods; */
3169 decl_specs = build_tree_list (NULL_TREE,
3170 xref_tag (RECORD_TYPE,
3171 get_identifier (UTAG_METHOD_LIST)));
3173 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3174 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3175 chainon (field_decl_chain, field_decl);
3177 /* struct objc_protocol **protocol_list; */
3179 decl_specs = build_tree_list (NULL_TREE,
3180 xref_tag (RECORD_TYPE,
3181 get_identifier (UTAG_PROTOCOL)));
3183 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3184 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3185 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3186 chainon (field_decl_chain, field_decl);
3188 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3191 /* struct objc_selector {
3197 build_selector_template (void)
3200 tree decl_specs, field_decl, field_decl_chain;
3202 objc_selector_template
3203 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3207 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3208 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3209 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3210 field_decl_chain = field_decl;
3212 /* char *sel_type; */
3214 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3215 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3216 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3217 chainon (field_decl_chain, field_decl);
3219 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3222 /* struct objc_class {
3223 struct objc_class *isa;
3224 struct objc_class *super_class;
3229 struct objc_ivar_list *ivars;
3230 struct objc_method_list *methods;
3231 if (flag_next_runtime)
3232 struct objc_cache *cache;
3234 struct sarray *dtable;
3235 struct objc_class *subclass_list;
3236 struct objc_class *sibling_class;
3238 struct objc_protocol_list *protocols;
3239 void *gc_object_type;
3243 build_class_template (void)
3245 tree decl_specs, field_decl, field_decl_chain;
3248 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3250 /* struct objc_class *isa; */
3252 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3253 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3254 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3255 field_decl_chain = field_decl;
3257 /* struct objc_class *super_class; */
3259 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3261 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3262 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3263 chainon (field_decl_chain, field_decl);
3267 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3268 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3269 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3270 chainon (field_decl_chain, field_decl);
3274 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3275 field_decl = get_identifier ("version");
3276 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3277 chainon (field_decl_chain, field_decl);
3281 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3282 field_decl = get_identifier ("info");
3283 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3284 chainon (field_decl_chain, field_decl);
3286 /* long instance_size; */
3288 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3289 field_decl = get_identifier ("instance_size");
3290 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3291 chainon (field_decl_chain, field_decl);
3293 /* struct objc_ivar_list *ivars; */
3295 decl_specs = build_tree_list (NULL_TREE,
3296 xref_tag (RECORD_TYPE,
3297 get_identifier (UTAG_IVAR_LIST)));
3298 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3299 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3300 chainon (field_decl_chain, field_decl);
3302 /* struct objc_method_list *methods; */
3304 decl_specs = build_tree_list (NULL_TREE,
3305 xref_tag (RECORD_TYPE,
3306 get_identifier (UTAG_METHOD_LIST)));
3307 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3308 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3309 chainon (field_decl_chain, field_decl);
3311 if (flag_next_runtime)
3313 /* struct objc_cache *cache; */
3315 decl_specs = build_tree_list (NULL_TREE,
3316 xref_tag (RECORD_TYPE,
3317 get_identifier ("objc_cache")));
3318 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3319 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3320 chainon (field_decl_chain, field_decl);
3324 /* struct sarray *dtable; */
3326 decl_specs = build_tree_list (NULL_TREE,
3327 xref_tag (RECORD_TYPE,
3328 get_identifier ("sarray")));
3329 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3330 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3331 chainon (field_decl_chain, field_decl);
3333 /* struct objc_class *subclass_list; */
3335 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3337 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3338 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3339 chainon (field_decl_chain, field_decl);
3341 /* struct objc_class *sibling_class; */
3343 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3345 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3346 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3347 chainon (field_decl_chain, field_decl);
3350 /* struct objc_protocol **protocol_list; */
3352 decl_specs = build_tree_list (NULL_TREE,
3353 xref_tag (RECORD_TYPE,
3354 get_identifier (UTAG_PROTOCOL)));
3356 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3358 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3359 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3360 chainon (field_decl_chain, field_decl);
3364 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3365 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3366 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3367 chainon (field_decl_chain, field_decl);
3369 /* void *gc_object_type; */
3371 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3372 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3373 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3374 chainon (field_decl_chain, field_decl);
3376 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3379 /* Generate appropriate forward declarations for an implementation. */
3382 synth_forward_declarations (void)
3384 tree sc_spec, decl_specs, an_id;
3386 /* static struct objc_class _OBJC_CLASS_<my_name>; */
3388 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3390 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3391 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3392 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3393 TREE_USED (UOBJC_CLASS_decl) = 1;
3394 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3395 TREE_PUBLIC (UOBJC_CLASS_decl) = 0;
3397 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
3399 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3400 objc_implementation_context);
3402 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3403 TREE_USED (UOBJC_METACLASS_decl) = 1;
3404 DECL_ARTIFICIAL (UOBJC_METACLASS_decl) = 1;
3405 TREE_PUBLIC (UOBJC_METACLASS_decl) = 0;
3407 /* Pre-build the following entities - for speed/convenience. */
3409 an_id = get_identifier ("super_class");
3410 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3411 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3415 error_with_ivar (const char *message, tree decl, tree rawdecl)
3417 error ("%H%s `%s'", &DECL_SOURCE_LOCATION (decl),
3418 message, gen_declaration (rawdecl, errbuf));
3423 check_ivars (tree inter, tree imp)
3425 tree intdecls = CLASS_IVARS (inter);
3426 tree impdecls = CLASS_IVARS (imp);
3427 tree rawintdecls = CLASS_RAW_IVARS (inter);
3428 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3434 if (intdecls == 0 && impdecls == 0)
3436 if (intdecls == 0 || impdecls == 0)
3438 error ("inconsistent instance variable specification");
3442 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3444 if (!comptypes (t1, t2, false))
3446 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3448 error_with_ivar ("conflicting instance variable type",
3449 impdecls, rawimpdecls);
3450 error_with_ivar ("previous declaration of",
3451 intdecls, rawintdecls);
3453 else /* both the type and the name don't match */
3455 error ("inconsistent instance variable specification");
3460 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3462 error_with_ivar ("conflicting instance variable name",
3463 impdecls, rawimpdecls);
3464 error_with_ivar ("previous declaration of",
3465 intdecls, rawintdecls);
3468 intdecls = TREE_CHAIN (intdecls);
3469 impdecls = TREE_CHAIN (impdecls);
3470 rawintdecls = TREE_CHAIN (rawintdecls);
3471 rawimpdecls = TREE_CHAIN (rawimpdecls);
3475 /* Set super_type to the data type node for struct objc_super *,
3476 first defining struct objc_super itself.
3477 This needs to be done just once per compilation. */
3480 build_super_template (void)
3482 tree record, decl_specs, field_decl, field_decl_chain;
3484 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3486 /* struct objc_object *self; */
3488 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3489 field_decl = get_identifier ("self");
3490 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3491 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3492 field_decl_chain = field_decl;
3494 /* struct objc_class *class; */
3496 decl_specs = get_identifier (UTAG_CLASS);
3497 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3498 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3500 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3501 chainon (field_decl_chain, field_decl);
3503 finish_struct (record, field_decl_chain, NULL_TREE);
3505 /* `struct objc_super *' */
3506 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3508 build1 (INDIRECT_REF,
3509 NULL_TREE, NULL_TREE)));
3513 /* struct objc_ivar {
3520 build_ivar_template (void)
3522 tree objc_ivar_id, objc_ivar_record;
3523 tree decl_specs, field_decl, field_decl_chain;
3525 objc_ivar_id = get_identifier (UTAG_IVAR);
3526 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3528 /* char *ivar_name; */
3530 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3531 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3533 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3534 field_decl_chain = field_decl;
3536 /* char *ivar_type; */
3538 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3539 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3541 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3542 chainon (field_decl_chain, field_decl);
3544 /* int ivar_offset; */
3546 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3547 field_decl = get_identifier ("ivar_offset");
3549 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3550 chainon (field_decl_chain, field_decl);
3552 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3554 return objc_ivar_record;
3559 struct objc_ivar ivar_list[ivar_count];
3563 build_ivar_list_template (tree list_type, int size)
3565 tree objc_ivar_list_record;
3566 tree decl_specs, field_decl, field_decl_chain;
3568 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3570 /* int ivar_count; */
3572 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3573 field_decl = get_identifier ("ivar_count");
3575 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3576 field_decl_chain = field_decl;
3578 /* struct objc_ivar ivar_list[]; */
3580 decl_specs = build_tree_list (NULL_TREE, list_type);
3581 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3582 build_int_2 (size, 0));
3584 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3585 chainon (field_decl_chain, field_decl);
3587 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3589 return objc_ivar_list_record;
3595 struct objc_method method_list[method_count];
3599 build_method_list_template (tree list_type, int size)
3601 tree objc_ivar_list_record;
3602 tree decl_specs, field_decl, field_decl_chain;
3604 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3606 /* int method_next; */
3611 xref_tag (RECORD_TYPE,
3612 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3614 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3615 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3616 field_decl_chain = field_decl;
3618 /* int method_count; */
3620 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3621 field_decl = get_identifier ("method_count");
3623 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3624 chainon (field_decl_chain, field_decl);
3626 /* struct objc_method method_list[]; */
3628 decl_specs = build_tree_list (NULL_TREE, list_type);
3629 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3630 build_int_2 (size, 0));
3632 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3633 chainon (field_decl_chain, field_decl);
3635 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3637 return objc_ivar_list_record;
3641 build_ivar_list_initializer (tree type, tree field_decl)
3643 tree initlist = NULL_TREE;
3647 tree ivar = NULL_TREE;
3650 if (DECL_NAME (field_decl))
3651 ivar = tree_cons (NULL_TREE,
3652 add_objc_string (DECL_NAME (field_decl),
3656 /* Unnamed bit-field ivar (yuck). */
3657 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3660 encode_field_decl (field_decl,
3661 obstack_object_size (&util_obstack),
3662 OBJC_ENCODE_DONT_INLINE_DEFS);
3664 /* Null terminate string. */
3665 obstack_1grow (&util_obstack, 0);
3669 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3672 obstack_free (&util_obstack, util_firstobj);
3675 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3676 initlist = tree_cons (NULL_TREE,
3677 objc_build_constructor (type, nreverse (ivar)),
3680 field_decl = TREE_CHAIN (field_decl);
3684 return objc_build_constructor (build_array_type (type, 0),
3685 nreverse (initlist));
3689 generate_ivars_list (tree type, const char *name, int size, tree list)
3691 tree sc_spec, decl_specs, decl, initlist;
3693 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3694 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3696 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3697 decl_specs, 1, NULL_TREE);
3699 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3700 initlist = tree_cons (NULL_TREE, list, initlist);
3703 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3710 generate_ivar_lists (void)
3712 tree initlist, ivar_list_template, chain;
3713 tree cast, variable_length_type;
3716 generating_instance_variables = 1;
3718 if (!objc_ivar_template)
3719 objc_ivar_template = build_ivar_template ();
3723 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3724 get_identifier (UTAG_IVAR_LIST))),
3726 variable_length_type = groktypename (cast);
3728 /* Only generate class variables for the root of the inheritance
3729 hierarchy since these will be the same for every class. */
3731 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3732 && (chain = TYPE_FIELDS (objc_class_template)))
3734 size = list_length (chain);
3736 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3737 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3739 UOBJC_CLASS_VARIABLES_decl
3740 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3742 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3745 UOBJC_CLASS_VARIABLES_decl = 0;
3747 chain = CLASS_IVARS (implementation_template);
3750 size = list_length (chain);
3751 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3752 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3754 UOBJC_INSTANCE_VARIABLES_decl
3755 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3757 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3760 UOBJC_INSTANCE_VARIABLES_decl = 0;
3762 generating_instance_variables = 0;
3766 build_dispatch_table_initializer (tree type, tree entries)
3768 tree initlist = NULL_TREE;
3772 tree elemlist = NULL_TREE;
3774 elemlist = tree_cons (NULL_TREE,
3775 build_selector (METHOD_SEL_NAME (entries)),
3778 /* Generate the method encoding if we don't have one already. */
3779 if (! METHOD_ENCODING (entries))
3780 METHOD_ENCODING (entries) =
3781 encode_method_def (METHOD_DEFINITION (entries));
3783 elemlist = tree_cons (NULL_TREE,
3784 add_objc_string (METHOD_ENCODING (entries),
3788 elemlist = tree_cons (NULL_TREE,
3789 build_unary_op (ADDR_EXPR,
3790 METHOD_DEFINITION (entries), 1),
3793 initlist = tree_cons (NULL_TREE,
3794 objc_build_constructor (type, nreverse (elemlist)),
3797 entries = TREE_CHAIN (entries);
3801 return objc_build_constructor (build_array_type (type, 0),
3802 nreverse (initlist));
3805 /* To accomplish method prototyping without generating all kinds of
3806 inane warnings, the definition of the dispatch table entries were
3809 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3811 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3814 build_method_template (void)
3817 tree decl_specs, field_decl, field_decl_chain;
3819 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3821 /* struct objc_selector *_cmd; */
3822 decl_specs = tree_cons (NULL_TREE,
3823 xref_tag (RECORD_TYPE,
3824 get_identifier (TAG_SELECTOR)),
3826 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3828 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3829 field_decl_chain = field_decl;
3831 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3832 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3833 get_identifier ("method_types"));
3834 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3835 chainon (field_decl_chain, field_decl);
3839 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3840 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3841 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3842 chainon (field_decl_chain, field_decl);
3844 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3851 generate_dispatch_table (tree type, const char *name, int size, tree list)
3853 tree sc_spec, decl_specs, decl, initlist;
3855 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3856 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3858 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3859 decl_specs, 1, NULL_TREE);
3861 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3862 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3863 initlist = tree_cons (NULL_TREE, list, initlist);
3866 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3873 mark_referenced_methods (void)
3875 struct imp_entry *impent;
3878 for (impent = imp_list; impent; impent = impent->next)
3880 chain = CLASS_CLS_METHODS (impent->imp_context);
3883 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
3884 chain = TREE_CHAIN (chain);
3887 chain = CLASS_NST_METHODS (impent->imp_context);
3890 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
3891 chain = TREE_CHAIN (chain);
3897 generate_dispatch_tables (void)
3899 tree initlist, chain, method_list_template;
3900 tree cast, variable_length_type;
3903 if (!objc_method_template)
3904 objc_method_template = build_method_template ();
3908 (build_tree_list (NULL_TREE,
3909 xref_tag (RECORD_TYPE,
3910 get_identifier (UTAG_METHOD_LIST))),
3913 variable_length_type = groktypename (cast);
3915 chain = CLASS_CLS_METHODS (objc_implementation_context);
3918 size = list_length (chain);
3920 method_list_template
3921 = build_method_list_template (objc_method_template, size);
3923 = build_dispatch_table_initializer (objc_method_template, chain);
3925 UOBJC_CLASS_METHODS_decl
3926 = generate_dispatch_table (method_list_template,
3927 ((TREE_CODE (objc_implementation_context)
3928 == CLASS_IMPLEMENTATION_TYPE)
3929 ? "_OBJC_CLASS_METHODS"
3930 : "_OBJC_CATEGORY_CLASS_METHODS"),
3932 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3935 UOBJC_CLASS_METHODS_decl = 0;
3937 chain = CLASS_NST_METHODS (objc_implementation_context);
3940 size = list_length (chain);
3942 method_list_template
3943 = build_method_list_template (objc_method_template, size);
3945 = build_dispatch_table_initializer (objc_method_template, chain);
3947 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3948 UOBJC_INSTANCE_METHODS_decl
3949 = generate_dispatch_table (method_list_template,
3950 "_OBJC_INSTANCE_METHODS",
3953 /* We have a category. */
3954 UOBJC_INSTANCE_METHODS_decl
3955 = generate_dispatch_table (method_list_template,
3956 "_OBJC_CATEGORY_INSTANCE_METHODS",
3958 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3961 UOBJC_INSTANCE_METHODS_decl = 0;
3965 generate_protocol_list (tree i_or_p)
3967 tree initlist, decl_specs, sc_spec;
3968 tree refs_decl, expr_decl, lproto, e, plist;
3972 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3973 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3974 plist = CLASS_PROTOCOL_LIST (i_or_p);
3975 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3976 plist = PROTOCOL_LIST (i_or_p);
3980 cast_type = groktypename
3982 (build_tree_list (NULL_TREE,
3983 xref_tag (RECORD_TYPE,
3984 get_identifier (UTAG_PROTOCOL))),
3985 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3988 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3989 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
3990 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
3993 /* Build initializer. */
3994 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
3996 e = build_int_2 (size, 0);
3997 TREE_TYPE (e) = cast_type;
3998 initlist = tree_cons (NULL_TREE, e, initlist);
4000 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4002 tree pval = TREE_VALUE (lproto);
4004 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4005 && PROTOCOL_FORWARD_DECL (pval))
4007 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4008 initlist = tree_cons (NULL_TREE, e, initlist);
4012 /* static struct objc_protocol *refs[n]; */
4014 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4015 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4016 get_identifier (UTAG_PROTOCOL)),
4019 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4020 expr_decl = build_nt (ARRAY_REF,
4021 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4023 build_int_2 (size + 2, 0));
4024 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4025 expr_decl = build_nt (ARRAY_REF,
4026 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4028 build_int_2 (size + 2, 0));
4029 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4031 = build_nt (ARRAY_REF,
4032 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4034 build_int_2 (size + 2, 0));
4038 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4040 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4041 DECL_CONTEXT (refs_decl) = NULL_TREE;
4043 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4044 nreverse (initlist)),
4051 build_category_initializer (tree type, tree cat_name, tree class_name,
4052 tree instance_methods, tree class_methods,
4055 tree initlist = NULL_TREE, expr;
4057 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4058 initlist = tree_cons (NULL_TREE, class_name, initlist);
4060 if (!instance_methods)
4061 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4064 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4065 initlist = tree_cons (NULL_TREE, expr, initlist);
4068 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4071 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4072 initlist = tree_cons (NULL_TREE, expr, initlist);
4075 /* protocol_list = */
4077 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4080 tree cast_type2 = groktypename
4082 (build_tree_list (NULL_TREE,
4083 xref_tag (RECORD_TYPE,
4084 get_identifier (UTAG_PROTOCOL))),
4085 build1 (INDIRECT_REF, NULL_TREE,
4086 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4088 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4089 TREE_TYPE (expr) = cast_type2;
4090 initlist = tree_cons (NULL_TREE, expr, initlist);
4093 return objc_build_constructor (type, nreverse (initlist));
4096 /* struct objc_class {
4097 struct objc_class *isa;
4098 struct objc_class *super_class;
4103 struct objc_ivar_list *ivars;
4104 struct objc_method_list *methods;
4105 if (flag_next_runtime)
4106 struct objc_cache *cache;
4108 struct sarray *dtable;
4109 struct objc_class *subclass_list;
4110 struct objc_class *sibling_class;
4112 struct objc_protocol_list *protocols;
4113 void *gc_object_type;
4117 build_shared_structure_initializer (tree type, tree isa, tree super,
4118 tree name, tree size, int status,
4119 tree dispatch_table, tree ivar_list,
4122 tree initlist = NULL_TREE, expr;
4125 initlist = tree_cons (NULL_TREE, isa, initlist);
4128 initlist = tree_cons (NULL_TREE, super, initlist);
4131 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4134 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4137 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4139 /* instance_size = */
4140 initlist = tree_cons (NULL_TREE, size, initlist);
4142 /* objc_ivar_list = */
4144 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4147 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4148 initlist = tree_cons (NULL_TREE, expr, initlist);
4151 /* objc_method_list = */
4152 if (!dispatch_table)
4153 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4156 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4157 initlist = tree_cons (NULL_TREE, expr, initlist);
4160 if (flag_next_runtime)
4161 /* method_cache = */
4162 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4166 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4168 /* subclass_list = */
4169 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4171 /* sibling_class = */
4172 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4175 /* protocol_list = */
4176 if (! protocol_list)
4177 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
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 /* gc_object_type = NULL */
4195 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4197 return objc_build_constructor (type, nreverse (initlist));
4200 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4203 generate_category (tree cat)
4205 tree sc_spec, decl_specs, decl;
4206 tree initlist, cat_name_expr, class_name_expr;
4207 tree protocol_decl, category;
4209 add_class_reference (CLASS_NAME (cat));
4210 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4212 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4214 category = CLASS_CATEGORY_LIST (implementation_template);
4216 /* find the category interface from the class it is associated with */
4219 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4221 category = CLASS_CATEGORY_LIST (category);
4224 if (category && CLASS_PROTOCOL_LIST (category))
4226 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4227 protocol_decl = generate_protocol_list (category);
4232 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4233 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4235 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4236 objc_implementation_context),
4237 decl_specs, 1, NULL_TREE);
4239 initlist = build_category_initializer (TREE_TYPE (decl),
4240 cat_name_expr, class_name_expr,
4241 UOBJC_INSTANCE_METHODS_decl,
4242 UOBJC_CLASS_METHODS_decl,
4245 TREE_USED (decl) = 1;
4246 finish_decl (decl, initlist, NULL_TREE);
4249 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4250 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4253 generate_shared_structures (void)
4255 tree sc_spec, decl_specs, decl;
4256 tree name_expr, super_expr, root_expr;
4257 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4258 tree cast_type, initlist, protocol_decl;
4260 my_super_id = CLASS_SUPER_NAME (implementation_template);
4263 add_class_reference (my_super_id);
4265 /* Compute "my_root_id" - this is required for code generation.
4266 the "isa" for all meta class structures points to the root of
4267 the inheritance hierarchy (e.g. "__Object")... */
4268 my_root_id = my_super_id;
4271 tree my_root_int = lookup_interface (my_root_id);
4273 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4274 my_root_id = CLASS_SUPER_NAME (my_root_int);
4281 /* No super class. */
4282 my_root_id = CLASS_NAME (implementation_template);
4285 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4286 objc_class_template),
4287 build1 (INDIRECT_REF,
4288 NULL_TREE, NULL_TREE)));
4290 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4293 /* Install class `isa' and `super' pointers at runtime. */
4296 super_expr = add_objc_string (my_super_id, class_names);
4297 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4300 super_expr = build_int_2 (0, 0);
4302 root_expr = add_objc_string (my_root_id, class_names);
4303 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4305 if (CLASS_PROTOCOL_LIST (implementation_template))
4307 generate_protocol_references
4308 (CLASS_PROTOCOL_LIST (implementation_template));
4309 protocol_decl = generate_protocol_list (implementation_template);
4314 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4316 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4317 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4319 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4323 = build_shared_structure_initializer
4325 root_expr, super_expr, name_expr,
4326 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4328 UOBJC_CLASS_METHODS_decl,
4329 UOBJC_CLASS_VARIABLES_decl,
4332 finish_decl (decl, initlist, NULL_TREE);
4334 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4336 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4340 = build_shared_structure_initializer
4342 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4343 super_expr, name_expr,
4344 convert (integer_type_node,
4345 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4346 (implementation_template))),
4348 UOBJC_INSTANCE_METHODS_decl,
4349 UOBJC_INSTANCE_VARIABLES_decl,
4352 finish_decl (decl, initlist, NULL_TREE);
4356 synth_id_with_class_suffix (const char *preamble, tree ctxt)
4359 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4360 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4362 const char *const class_name
4363 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4364 string = alloca (strlen (preamble) + strlen (class_name) + 3);
4365 sprintf (string, "%s_%s", preamble,
4366 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4368 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4369 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4371 /* We have a category. */
4372 const char *const class_name
4373 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4374 const char *const class_super_name
4375 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4376 string = alloca (strlen (preamble) + strlen (class_name)
4377 + strlen (class_super_name) + 3);
4378 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4380 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4382 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4383 string = alloca (strlen (preamble) + strlen (protocol_name) + 3);
4384 sprintf (string, "%s_%s", preamble, protocol_name);
4389 return get_identifier (string);
4393 is_objc_type_qualifier (tree node)
4395 return (TREE_CODE (node) == IDENTIFIER_NODE
4396 && (node == ridpointers [(int) RID_CONST]
4397 || node == ridpointers [(int) RID_VOLATILE]
4398 || node == ridpointers [(int) RID_IN]
4399 || node == ridpointers [(int) RID_OUT]
4400 || node == ridpointers [(int) RID_INOUT]
4401 || node == ridpointers [(int) RID_BYCOPY]
4402 || node == ridpointers [(int) RID_BYREF]
4403 || node == ridpointers [(int) RID_ONEWAY]));
4406 /* If type is empty or only type qualifiers are present, add default
4407 type of id (otherwise grokdeclarator will default to int). */
4410 adjust_type_for_id_default (tree type)
4412 tree declspecs, chain;
4415 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4416 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4418 declspecs = TREE_PURPOSE (type);
4420 /* Determine if a typespec is present. */
4421 for (chain = declspecs;
4423 chain = TREE_CHAIN (chain))
4425 if (TYPED_OBJECT (TREE_VALUE (chain))
4426 && !(TREE_VALUE (type)
4427 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4428 error ("can not use an object as parameter to a method\n");
4429 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4433 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4435 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4440 selector ':' '(' typename ')' identifier
4443 Transform an Objective-C keyword argument into
4444 the C equivalent parameter declarator.
4446 In: key_name, an "identifier_node" (optional).
4447 arg_type, a "tree_list" (optional).
4448 arg_name, an "identifier_node".
4450 Note: It would be really nice to strongly type the preceding
4451 arguments in the function prototype; however, then I
4452 could not use the "accessor" macros defined in "tree.h".
4454 Out: an instance of "keyword_decl". */
4457 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
4461 /* If no type is specified, default to "id". */
4462 arg_type = adjust_type_for_id_default (arg_type);
4464 keyword_decl = make_node (KEYWORD_DECL);
4466 TREE_TYPE (keyword_decl) = arg_type;
4467 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4468 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4470 return keyword_decl;
4473 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4476 build_keyword_selector (tree selector)
4479 tree key_chain, key_name;
4482 /* Scan the selector to see how much space we'll need. */
4483 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4485 if (TREE_CODE (selector) == KEYWORD_DECL)
4486 key_name = KEYWORD_KEY_NAME (key_chain);
4487 else if (TREE_CODE (selector) == TREE_LIST)
4488 key_name = TREE_PURPOSE (key_chain);
4493 len += IDENTIFIER_LENGTH (key_name) + 1;
4495 /* Just a ':' arg. */
4499 buf = alloca (len + 1);
4500 /* Start the buffer out as an empty string. */
4503 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4505 if (TREE_CODE (selector) == KEYWORD_DECL)
4506 key_name = KEYWORD_KEY_NAME (key_chain);
4507 else if (TREE_CODE (selector) == TREE_LIST)
4508 key_name = TREE_PURPOSE (key_chain);
4513 strcat (buf, IDENTIFIER_POINTER (key_name));
4517 return get_identifier (buf);
4520 /* Used for declarations and definitions. */
4523 build_method_decl (enum tree_code code, tree ret_type, tree selector,
4528 /* If no type is specified, default to "id". */
4529 ret_type = adjust_type_for_id_default (ret_type);
4531 method_decl = make_node (code);
4532 TREE_TYPE (method_decl) = ret_type;
4534 /* If we have a keyword selector, create an identifier_node that
4535 represents the full selector name (`:' included)... */
4536 if (TREE_CODE (selector) == KEYWORD_DECL)
4538 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4539 METHOD_SEL_ARGS (method_decl) = selector;
4540 METHOD_ADD_ARGS (method_decl) = add_args;
4544 METHOD_SEL_NAME (method_decl) = selector;
4545 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4546 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4552 #define METHOD_DEF 0
4553 #define METHOD_REF 1
4555 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4556 an argument list for method METH. CONTEXT is either METHOD_DEF or
4557 METHOD_REF, saying whether we are trying to define a method or call
4558 one. SUPERFLAG says this is for a send to super; this makes a
4559 difference for the NeXT calling sequence in which the lookup and
4560 the method call are done together. */
4563 get_arg_type_list (tree meth, int context, int superflag)
4567 /* Receiver type. */
4568 if (flag_next_runtime && superflag)
4569 arglist = build_tree_list (NULL_TREE, super_type);
4570 else if (context == METHOD_DEF)
4571 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4573 arglist = build_tree_list (NULL_TREE, id_type);
4575 /* Selector type - will eventually change to `int'. */
4576 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4578 /* Build a list of argument types. */
4579 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4581 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4582 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4585 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4586 /* We have a `, ...' immediately following the selector,
4587 finalize the arglist...simulate get_parm_info (0). */
4589 else if (METHOD_ADD_ARGS (meth))
4591 /* we have a variable length selector */
4592 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4593 chainon (arglist, add_arg_list);
4596 /* finalize the arglist...simulate get_parm_info (1) */
4597 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4603 check_duplicates (hash hsh)
4605 tree meth = NULL_TREE;
4613 /* We have two methods with the same name and different types. */
4615 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4617 warning ("multiple declarations for method `%s'",
4618 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4620 warn_with_method ("using", type, meth);
4621 for (loop = hsh->list; loop; loop = loop->next)
4622 warn_with_method ("also found", type, loop->value);
4628 /* If RECEIVER is a class reference, return the identifier node for
4629 the referenced class. RECEIVER is created by get_class_reference,
4630 so we check the exact form created depending on which runtimes are
4634 receiver_is_class_object (tree receiver)
4636 tree chain, exp, arg;
4638 /* The receiver is 'self' in the context of a class method. */
4639 if (objc_method_context
4640 && receiver == self_decl
4641 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4643 return CLASS_NAME (objc_implementation_context);
4646 if (flag_next_runtime)
4648 /* The receiver is a variable created by
4649 build_class_reference_decl. */
4650 if (TREE_CODE (receiver) == VAR_DECL
4651 && TREE_TYPE (receiver) == objc_class_type)
4652 /* Look up the identifier. */
4653 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4654 if (TREE_PURPOSE (chain) == receiver)
4655 return TREE_VALUE (chain);
4659 /* The receiver is a function call that returns an id. Check if
4660 it is a call to objc_getClass, if so, pick up the class name. */
4661 if (TREE_CODE (receiver) == CALL_EXPR
4662 && (exp = TREE_OPERAND (receiver, 0))
4663 && TREE_CODE (exp) == ADDR_EXPR
4664 && (exp = TREE_OPERAND (exp, 0))
4665 && TREE_CODE (exp) == FUNCTION_DECL
4666 && exp == objc_get_class_decl
4667 /* We have a call to objc_getClass! */
4668 && (arg = TREE_OPERAND (receiver, 1))
4669 && TREE_CODE (arg) == TREE_LIST
4670 && (arg = TREE_VALUE (arg)))
4673 if (TREE_CODE (arg) == ADDR_EXPR
4674 && (arg = TREE_OPERAND (arg, 0))
4675 && TREE_CODE (arg) == STRING_CST)
4676 /* Finally, we have the class name. */
4677 return get_identifier (TREE_STRING_POINTER (arg));
4683 /* If we are currently building a message expr, this holds
4684 the identifier of the selector of the message. This is
4685 used when printing warnings about argument mismatches. */
4687 static tree current_objc_message_selector = 0;
4690 objc_message_selector (void)
4692 return current_objc_message_selector;
4695 /* Construct an expression for sending a message.
4696 MESS has the object to send to in TREE_PURPOSE
4697 and the argument list (including selector) in TREE_VALUE.
4699 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4700 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4703 build_message_expr (tree mess)
4705 tree receiver = TREE_PURPOSE (mess);
4707 tree args = TREE_VALUE (mess);
4708 tree method_params = NULL_TREE;
4710 if (TREE_CODE (receiver) == ERROR_MARK)
4711 return error_mark_node;
4713 /* Obtain the full selector name. */
4714 if (TREE_CODE (args) == IDENTIFIER_NODE)
4715 /* A unary selector. */
4717 else if (TREE_CODE (args) == TREE_LIST)
4718 sel_name = build_keyword_selector (args);
4722 /* Build the parameter list to give to the method. */
4723 if (TREE_CODE (args) == TREE_LIST)
4725 tree chain = args, prev = NULL_TREE;
4727 /* We have a keyword selector--check for comma expressions. */
4730 tree element = TREE_VALUE (chain);
4732 /* We have a comma expression, must collapse... */
4733 if (TREE_CODE (element) == TREE_LIST)
4736 TREE_CHAIN (prev) = element;
4741 chain = TREE_CHAIN (chain);
4743 method_params = args;
4746 return finish_message_expr (receiver, sel_name, method_params);
4749 /* The 'finish_message_expr' routine is called from within
4750 'build_message_expr' for non-template functions. In the case of
4751 C++ template functions, it is called from 'build_expr_from_tree'
4752 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4755 finish_message_expr (tree receiver, tree sel_name, tree method_params)
4757 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4758 tree selector, self_object, retval;
4759 int statically_typed = 0, statically_allocated = 0;
4761 /* Determine receiver type. */
4762 tree rtype = TREE_TYPE (receiver);
4763 int super = IS_SUPER (rtype);
4767 if (TREE_STATIC_TEMPLATE (rtype))
4768 statically_allocated = 1;
4769 else if (TREE_CODE (rtype) == POINTER_TYPE
4770 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4771 statically_typed = 1;
4772 else if ((flag_next_runtime
4774 && (class_ident = receiver_is_class_object (receiver)))
4776 else if (! IS_ID (rtype)
4777 /* Allow any type that matches objc_class_type. */
4778 && ! comptypes (rtype, objc_class_type, false))
4780 warning ("invalid receiver type `%s'",
4781 gen_declaration (rtype, errbuf));
4783 if (statically_allocated)
4784 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4786 /* Don't evaluate the receiver twice. */
4787 receiver = save_expr (receiver);
4788 self_object = receiver;
4791 /* If sending to `super', use current self as the object. */
4792 self_object = self_decl;
4794 /* Determine operation return type. */
4800 if (CLASS_SUPER_NAME (implementation_template))
4803 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4805 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4806 method_prototype = lookup_instance_method_static (iface, sel_name);
4808 method_prototype = lookup_class_method_static (iface, sel_name);
4810 if (iface && !method_prototype)
4811 warning ("`%s' does not respond to `%s'",
4812 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4813 IDENTIFIER_POINTER (sel_name));
4817 error ("no super class declared in interface for `%s'",
4818 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4819 return error_mark_node;
4823 else if (statically_allocated)
4825 tree ctype = TREE_TYPE (rtype);
4826 tree iface = lookup_interface (TYPE_NAME (rtype));
4829 method_prototype = lookup_instance_method_static (iface, sel_name);
4831 if (! method_prototype && ctype && TYPE_PROTOCOL_LIST (ctype))
4833 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4836 if (!method_prototype)
4837 warning ("`%s' does not respond to `%s'",
4838 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4839 IDENTIFIER_POINTER (sel_name));
4841 else if (statically_typed)
4843 tree ctype = TREE_TYPE (rtype);
4845 /* `self' is now statically_typed. All methods should be visible
4846 within the context of the implementation. */
4847 if (objc_implementation_context
4848 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4851 = lookup_instance_method_static (implementation_template,
4854 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4856 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4859 if (! method_prototype
4860 && implementation_template != objc_implementation_context)
4861 /* The method is not published in the interface. Check
4864 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4871 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4872 method_prototype = lookup_instance_method_static (iface, sel_name);
4874 if (! method_prototype)
4876 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4879 = lookup_method_in_protocol_list (protocol_list,
4884 if (!method_prototype)
4885 warning ("`%s' does not respond to `%s'",
4886 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4887 IDENTIFIER_POINTER (sel_name));
4889 else if (class_ident)
4891 if (objc_implementation_context
4892 && CLASS_NAME (objc_implementation_context) == class_ident)
4895 = lookup_class_method_static (implementation_template, sel_name);
4897 if (!method_prototype
4898 && implementation_template != objc_implementation_context)
4899 /* The method is not published in the interface. Check
4902 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
4909 if ((iface = lookup_interface (class_ident)))
4910 method_prototype = lookup_class_method_static (iface, sel_name);
4913 if (!method_prototype)
4915 warning ("cannot find class (factory) method");
4916 warning ("return type for `%s' defaults to id",
4917 IDENTIFIER_POINTER (sel_name));
4920 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4922 /* An anonymous object that has been qualified with a protocol. */
4924 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4926 method_prototype = lookup_method_in_protocol_list (protocol_list,
4929 if (!method_prototype)
4933 warning ("method `%s' not implemented by protocol",
4934 IDENTIFIER_POINTER (sel_name));
4936 /* Try and find the method signature in the global pools. */
4938 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4939 hsh = hash_lookup (cls_method_hash_list, sel_name);
4941 if (!(method_prototype = check_duplicates (hsh)))
4942 warning ("return type defaults to id");
4949 /* We think we have an instance...loophole: extern id Object; */
4950 hsh = hash_lookup (nst_method_hash_list, sel_name);
4953 /* For various loopholes */
4954 hsh = hash_lookup (cls_method_hash_list, sel_name);
4956 method_prototype = check_duplicates (hsh);
4957 if (!method_prototype)
4959 warning ("cannot find method");
4960 warning ("return type for `%s' defaults to id",
4961 IDENTIFIER_POINTER (sel_name));
4965 /* Save the selector name for printing error messages. */
4966 current_objc_message_selector = sel_name;
4968 /* Build the parameters list for looking up the method.
4969 These are the object itself and the selector. */
4971 if (flag_typed_selectors)
4972 selector = build_typed_selector_reference (sel_name, method_prototype);
4974 selector = build_selector_reference (sel_name);
4976 retval = build_objc_method_call (super, method_prototype,
4977 receiver, self_object,
4978 selector, method_params);
4980 current_objc_message_selector = 0;
4985 /* Build a tree expression to send OBJECT the operation SELECTOR,
4986 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
4987 assuming the method has prototype METHOD_PROTOTYPE.
4988 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
4989 Use METHOD_PARAMS as list of args to pass to the method.
4990 If SUPER_FLAG is nonzero, we look up the superclass's method. */
4993 build_objc_method_call (int super_flag, tree method_prototype,
4994 tree lookup_object, tree object, tree selector,
4997 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
4998 tree rcv_p = (super_flag
4999 ? build_pointer_type (xref_tag (RECORD_TYPE,
5000 get_identifier (TAG_SUPER)))
5003 if (flag_next_runtime)
5005 if (! method_prototype)
5007 method_params = tree_cons (NULL_TREE, lookup_object,
5008 tree_cons (NULL_TREE, selector,
5010 assemble_external (sender);
5011 return build_function_call (sender, method_params);
5015 /* This is a real kludge, but it is used only for the Next.
5016 Clobber the data type of SENDER temporarily to accept
5017 all the arguments for this operation, and to return
5018 whatever this operation returns. */
5019 tree arglist = NULL_TREE, retval, savarg, savret;
5020 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5022 /* Save the proper contents of SENDER's data type. */
5023 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5024 savret = TREE_TYPE (TREE_TYPE (sender));
5026 /* Install this method's argument types. */
5027 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5029 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5031 /* Install this method's return type. */
5032 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5034 /* Call SENDER with all the parameters. This will do type
5035 checking using the arg types for this method. */
5036 method_params = tree_cons (NULL_TREE, lookup_object,
5037 tree_cons (NULL_TREE, selector,
5039 assemble_external (sender);
5040 retval = build_function_call (sender, method_params);
5042 /* Restore SENDER's return/argument types. */
5043 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5044 TREE_TYPE (TREE_TYPE (sender)) = savret;
5050 /* This is the portable way.
5051 First call the lookup function to get a pointer to the method,
5052 then cast the pointer, then call it with the method arguments. */
5055 /* Avoid trouble since we may evaluate each of these twice. */
5056 object = save_expr (object);
5057 selector = save_expr (selector);
5059 lookup_object = build_c_cast (rcv_p, lookup_object);
5061 assemble_external (sender);
5063 = build_function_call (sender,
5064 tree_cons (NULL_TREE, lookup_object,
5065 tree_cons (NULL_TREE, selector,
5068 /* If we have a method prototype, construct the data type this
5069 method needs, and cast what we got from SENDER into a pointer
5071 if (method_prototype)
5073 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5075 tree valtype = groktypename (TREE_TYPE (method_prototype));
5076 tree fake_function_type = build_function_type (valtype, arglist);
5077 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5081 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5083 /* Pass the object to the method. */
5084 assemble_external (method);
5085 return build_function_call (method,
5086 tree_cons (NULL_TREE, object,
5087 tree_cons (NULL_TREE, selector,
5093 build_protocol_reference (tree p)
5095 tree decl, ident, ptype;
5097 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5099 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5101 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5102 objc_protocol_template),
5105 if (identifier_global_value (ident))
5106 decl = identifier_global_value (ident); /* Set by pushdecl. */
5109 decl = build_decl (VAR_DECL, ident, ptype);
5110 DECL_EXTERNAL (decl) = 1;
5111 TREE_PUBLIC (decl) = 0;
5112 TREE_USED (decl) = 1;
5113 DECL_ARTIFICIAL (decl) = 1;
5115 make_decl_rtl (decl, 0);
5116 pushdecl_top_level (decl);
5119 PROTOCOL_FORWARD_DECL (p) = decl;
5122 /* This function is called by the parser when (and only when) a
5123 @protocol() expression is found, in order to compile it. */
5125 build_protocol_expr (tree protoname)
5128 tree p = lookup_protocol (protoname);
5132 error ("cannot find protocol declaration for `%s'",
5133 IDENTIFIER_POINTER (protoname));
5134 return error_mark_node;
5137 if (!PROTOCOL_FORWARD_DECL (p))
5138 build_protocol_reference (p);
5140 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5142 TREE_TYPE (expr) = protocol_type;
5144 /* The @protocol() expression is being compiled into a pointer to a
5145 statically allocated instance of the Protocol class. To become
5146 usable at runtime, the 'isa' pointer of the instance need to be
5147 fixed up at runtime by the runtime library, to point to the
5148 actual 'Protocol' class. */
5150 /* For the GNU runtime, put the static Protocol instance in the list
5151 of statically allocated instances, so that we make sure that its
5152 'isa' pointer is fixed up at runtime by the GNU runtime library
5153 to point to the Protocol class (at runtime, when loading the
5154 module, the GNU runtime library loops on the statically allocated
5155 instances (as found in the defs field in objc_symtab) and fixups
5156 all the 'isa' pointers of those objects). */
5157 if (! flag_next_runtime)
5159 /* This type is a struct containing the fields of a Protocol
5160 object. (Cfr. protocol_type instead is the type of a pointer
5161 to such a struct). */
5162 tree protocol_struct_type = xref_tag
5163 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5166 /* Look for the list of Protocol statically allocated instances
5167 to fixup at runtime. Create a new list to hold Protocol
5168 statically allocated instances, if the list is not found. At
5169 present there is only another list, holding NSConstantString
5170 static instances to be fixed up at runtime. */
5171 for (chain = &objc_static_instances;
5172 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5173 chain = &TREE_CHAIN (*chain));
5176 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5177 add_objc_string (TYPE_NAME (protocol_struct_type),
5181 /* Add this statically allocated instance to the Protocol list. */
5182 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5183 PROTOCOL_FORWARD_DECL (p),
5184 TREE_PURPOSE (*chain));
5191 /* This function is called by the parser when a @selector() expression
5192 is found, in order to compile it. It is only called by the parser
5193 and only to compile a @selector(). */
5195 build_selector_expr (tree selnamelist)
5199 /* Obtain the full selector name. */
5200 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5201 /* A unary selector. */
5202 selname = selnamelist;
5203 else if (TREE_CODE (selnamelist) == TREE_LIST)
5204 selname = build_keyword_selector (selnamelist);
5208 /* If we are required to check @selector() expressions as they
5209 are found, check that the selector has been declared. */
5210 if (warn_undeclared_selector)
5212 /* Look the selector up in the list of all known class and
5213 instance methods (up to this line) to check that the selector
5217 /* First try with instance methods. */
5218 hsh = hash_lookup (nst_method_hash_list, selname);
5220 /* If not found, try with class methods. */
5223 hsh = hash_lookup (cls_method_hash_list, selname);
5226 /* If still not found, print out a warning. */
5229 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5234 if (flag_typed_selectors)
5235 return build_typed_selector_reference (selname, 0);
5237 return build_selector_reference (selname);
5241 build_encode_expr (tree type)
5246 encode_type (type, obstack_object_size (&util_obstack),
5247 OBJC_ENCODE_INLINE_DEFS);
5248 obstack_1grow (&util_obstack, 0); /* null terminate string */
5249 string = obstack_finish (&util_obstack);
5251 /* Synthesize a string that represents the encoded struct/union. */
5252 result = my_build_string (strlen (string) + 1, string);
5253 obstack_free (&util_obstack, util_firstobj);
5258 build_ivar_reference (tree id)
5260 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5262 /* Historically, a class method that produced objects (factory
5263 method) would assign `self' to the instance that it
5264 allocated. This would effectively turn the class method into
5265 an instance method. Following this assignment, the instance
5266 variables could be accessed. That practice, while safe,
5267 violates the simple rule that a class method should not refer
5268 to an instance variable. It's better to catch the cases
5269 where this is done unknowingly than to support the above
5271 warning ("instance variable `%s' accessed in class method",
5272 IDENTIFIER_POINTER (id));
5273 TREE_TYPE (self_decl) = instance_type; /* cast */
5276 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5279 /* Compute a hash value for a given method SEL_NAME. */
5282 hash_func (tree sel_name)
5284 const unsigned char *s
5285 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5289 h = h * 67 + *s++ - 113;
5296 nst_method_hash_list = ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5297 cls_method_hash_list = ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5300 /* WARNING!!!! hash_enter is called with a method, and will peek
5301 inside to find its selector! But hash_lookup is given a selector
5302 directly, and looks for the selector that's inside the found
5303 entry's key (method) for comparison. */
5306 hash_enter (hash *hashlist, tree method)
5309 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5311 obj = ggc_alloc (sizeof (struct hashed_entry));
5313 obj->next = hashlist[slot];
5316 hashlist[slot] = obj; /* append to front */
5320 hash_lookup (hash *hashlist, tree sel_name)
5324 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5328 if (sel_name == METHOD_SEL_NAME (target->key))
5331 target = target->next;
5337 hash_add_attr (hash entry, tree value)
5341 obj = ggc_alloc (sizeof (struct hashed_attribute));
5342 obj->next = entry->list;
5345 entry->list = obj; /* append to front */
5349 lookup_method (tree mchain, tree method)
5353 if (TREE_CODE (method) == IDENTIFIER_NODE)
5356 key = METHOD_SEL_NAME (method);
5360 if (METHOD_SEL_NAME (mchain) == key)
5363 mchain = TREE_CHAIN (mchain);
5369 lookup_instance_method_static (tree interface, tree ident)
5371 tree inter = interface;
5372 tree chain = CLASS_NST_METHODS (inter);
5373 tree meth = NULL_TREE;
5377 if ((meth = lookup_method (chain, ident)))
5380 if (CLASS_CATEGORY_LIST (inter))
5382 tree category = CLASS_CATEGORY_LIST (inter);
5383 chain = CLASS_NST_METHODS (category);
5387 if ((meth = lookup_method (chain, ident)))
5390 /* Check for instance methods in protocols in categories. */
5391 if (CLASS_PROTOCOL_LIST (category))
5393 if ((meth = (lookup_method_in_protocol_list
5394 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5398 if ((category = CLASS_CATEGORY_LIST (category)))
5399 chain = CLASS_NST_METHODS (category);
5404 if (CLASS_PROTOCOL_LIST (inter))
5406 if ((meth = (lookup_method_in_protocol_list
5407 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5411 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5412 chain = CLASS_NST_METHODS (inter);
5420 lookup_class_method_static (tree interface, tree ident)
5422 tree inter = interface;
5423 tree chain = CLASS_CLS_METHODS (inter);
5424 tree meth = NULL_TREE;
5425 tree root_inter = NULL_TREE;
5429 if ((meth = lookup_method (chain, ident)))
5432 if (CLASS_CATEGORY_LIST (inter))
5434 tree category = CLASS_CATEGORY_LIST (inter);
5435 chain = CLASS_CLS_METHODS (category);
5439 if ((meth = lookup_method (chain, ident)))
5442 /* Check for class methods in protocols in categories. */
5443 if (CLASS_PROTOCOL_LIST (category))
5445 if ((meth = (lookup_method_in_protocol_list
5446 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5450 if ((category = CLASS_CATEGORY_LIST (category)))
5451 chain = CLASS_CLS_METHODS (category);
5456 /* Check for class methods in protocols. */
5457 if (CLASS_PROTOCOL_LIST (inter))
5459 if ((meth = (lookup_method_in_protocol_list
5460 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5465 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5466 chain = CLASS_CLS_METHODS (inter);
5470 /* If no class (factory) method was found, check if an _instance_
5471 method of the same name exists in the root class. This is what
5472 the Objective-C runtime will do. */
5473 return lookup_instance_method_static (root_inter, ident);
5477 add_class_method (tree class, tree method)
5482 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5484 /* put method on list in reverse order */
5485 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5486 CLASS_CLS_METHODS (class) = method;
5490 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5491 error ("duplicate definition of class method `%s'",
5492 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5495 /* Check types; if different, complain. */
5496 if (!comp_proto_with_proto (method, mth))
5497 error ("duplicate declaration of class method `%s'",
5498 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5502 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5504 /* Install on a global chain. */
5505 hash_enter (cls_method_hash_list, method);
5509 /* Check types; if different, add to a list. */
5510 if (!comp_proto_with_proto (method, hsh->key))
5511 hash_add_attr (hsh, method);
5517 add_instance_method (tree class, tree method)
5522 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5524 /* Put method on list in reverse order. */
5525 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5526 CLASS_NST_METHODS (class) = method;
5530 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5531 error ("duplicate definition of instance method `%s'",
5532 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5535 /* Check types; if different, complain. */
5536 if (!comp_proto_with_proto (method, mth))
5537 error ("duplicate declaration of instance method `%s'",
5538 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5542 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5544 /* Install on a global chain. */
5545 hash_enter (nst_method_hash_list, method);
5549 /* Check types; if different, add to a list. */
5550 if (!comp_proto_with_proto (method, hsh->key))
5551 hash_add_attr (hsh, method);
5557 add_class (tree class)
5559 /* Put interfaces on list in reverse order. */
5560 TREE_CHAIN (class) = interface_chain;
5561 interface_chain = class;
5562 return interface_chain;
5566 add_category (tree class, tree category)
5568 /* Put categories on list in reverse order. */
5569 tree cat = CLASS_CATEGORY_LIST (class);
5573 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5574 warning ("duplicate interface declaration for category `%s(%s)'",
5575 IDENTIFIER_POINTER (CLASS_NAME (class)),
5576 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5577 cat = CLASS_CATEGORY_LIST (cat);
5580 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5581 CLASS_CATEGORY_LIST (class) = category;
5584 /* Called after parsing each instance variable declaration. Necessary to
5585 preserve typedefs and implement public/private...
5587 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5590 add_instance_variable (tree class, int public, tree declarator,
5591 tree declspecs, tree width)
5593 tree field_decl, raw_decl;
5595 raw_decl = build_tree_list (declspecs, declarator);
5597 if (CLASS_RAW_IVARS (class))
5598 chainon (CLASS_RAW_IVARS (class), raw_decl);
5600 CLASS_RAW_IVARS (class) = raw_decl;
5602 field_decl = grokfield (declarator, declspecs, width);
5604 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5608 TREE_PUBLIC (field_decl) = 0;
5609 TREE_PRIVATE (field_decl) = 0;
5610 TREE_PROTECTED (field_decl) = 1;
5614 TREE_PUBLIC (field_decl) = 1;
5615 TREE_PRIVATE (field_decl) = 0;
5616 TREE_PROTECTED (field_decl) = 0;
5620 TREE_PUBLIC (field_decl) = 0;
5621 TREE_PRIVATE (field_decl) = 1;
5622 TREE_PROTECTED (field_decl) = 0;
5627 if (CLASS_IVARS (class))
5628 chainon (CLASS_IVARS (class), field_decl);
5630 CLASS_IVARS (class) = field_decl;
5636 is_ivar (tree decl_chain, tree ident)
5638 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5639 if (DECL_NAME (decl_chain) == ident)
5644 /* True if the ivar is private and we are not in its implementation. */
5647 is_private (tree decl)
5649 if (TREE_PRIVATE (decl)
5650 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5652 error ("instance variable `%s' is declared private",
5653 IDENTIFIER_POINTER (DECL_NAME (decl)));
5660 /* We have an instance variable reference;, check to see if it is public. */
5663 is_public (tree expr, tree identifier)
5665 tree basetype = TREE_TYPE (expr);
5666 enum tree_code code = TREE_CODE (basetype);
5669 if (code == RECORD_TYPE)
5671 if (TREE_STATIC_TEMPLATE (basetype))
5673 if (!lookup_interface (TYPE_NAME (basetype)))
5675 error ("cannot find interface declaration for `%s'",
5676 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5680 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5682 if (TREE_PUBLIC (decl))
5685 /* Important difference between the Stepstone translator:
5686 all instance variables should be public within the context
5687 of the implementation. */
5688 if (objc_implementation_context
5689 && (((TREE_CODE (objc_implementation_context)
5690 == CLASS_IMPLEMENTATION_TYPE)
5691 || (TREE_CODE (objc_implementation_context)
5692 == CATEGORY_IMPLEMENTATION_TYPE))
5693 && (CLASS_NAME (objc_implementation_context)
5694 == TYPE_NAME (basetype))))
5695 return ! is_private (decl);
5697 error ("instance variable `%s' is declared %s",
5698 IDENTIFIER_POINTER (identifier),
5699 TREE_PRIVATE (decl) ? "private" : "protected");
5704 else if (objc_implementation_context && (basetype == objc_object_reference))
5706 TREE_TYPE (expr) = uprivate_record;
5707 warning ("static access to object of type `id'");
5714 /* Make sure all entries in CHAIN are also in LIST. */
5717 check_methods (tree chain, tree list, int mtype)
5723 if (!lookup_method (list, chain))
5727 if (TREE_CODE (objc_implementation_context)
5728 == CLASS_IMPLEMENTATION_TYPE)
5729 warning ("incomplete implementation of class `%s'",
5730 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5731 else if (TREE_CODE (objc_implementation_context)
5732 == CATEGORY_IMPLEMENTATION_TYPE)
5733 warning ("incomplete implementation of category `%s'",
5734 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5738 warning ("method definition for `%c%s' not found",
5739 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5742 chain = TREE_CHAIN (chain);
5748 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5751 conforms_to_protocol (tree class, tree protocol)
5753 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5755 tree p = CLASS_PROTOCOL_LIST (class);
5756 while (p && TREE_VALUE (p) != protocol)
5761 tree super = (CLASS_SUPER_NAME (class)
5762 ? lookup_interface (CLASS_SUPER_NAME (class))
5764 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5773 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5774 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5777 check_methods_accessible (tree chain, tree context, int mtype)
5781 tree base_context = context;
5785 context = base_context;
5789 list = CLASS_CLS_METHODS (context);
5791 list = CLASS_NST_METHODS (context);
5793 if (lookup_method (list, chain))
5796 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5797 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5798 context = (CLASS_SUPER_NAME (context)
5799 ? lookup_interface (CLASS_SUPER_NAME (context))
5802 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5803 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5804 context = (CLASS_NAME (context)
5805 ? lookup_interface (CLASS_NAME (context))
5811 if (context == NULL_TREE)
5815 if (TREE_CODE (objc_implementation_context)
5816 == CLASS_IMPLEMENTATION_TYPE)
5817 warning ("incomplete implementation of class `%s'",
5819 (CLASS_NAME (objc_implementation_context)));
5820 else if (TREE_CODE (objc_implementation_context)
5821 == CATEGORY_IMPLEMENTATION_TYPE)
5822 warning ("incomplete implementation of category `%s'",
5824 (CLASS_SUPER_NAME (objc_implementation_context)));
5827 warning ("method definition for `%c%s' not found",
5828 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5831 chain = TREE_CHAIN (chain); /* next method... */
5836 /* Check whether the current interface (accessible via
5837 'objc_implementation_context') actually implements protocol P, along
5838 with any protocols that P inherits. */
5841 check_protocol (tree p, const char *type, const char *name)
5843 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5847 /* Ensure that all protocols have bodies! */
5850 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5851 CLASS_CLS_METHODS (objc_implementation_context),
5853 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5854 CLASS_NST_METHODS (objc_implementation_context),
5859 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5860 objc_implementation_context,
5862 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5863 objc_implementation_context,
5868 warning ("%s `%s' does not fully implement the `%s' protocol",
5869 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5872 /* Check protocols recursively. */
5873 if (PROTOCOL_LIST (p))
5875 tree subs = PROTOCOL_LIST (p);
5877 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5881 tree sub = TREE_VALUE (subs);
5883 /* If the superclass does not conform to the protocols
5884 inherited by P, then we must! */
5885 if (!super_class || !conforms_to_protocol (super_class, sub))
5886 check_protocol (sub, type, name);
5887 subs = TREE_CHAIN (subs);
5892 /* Check whether the current interface (accessible via
5893 'objc_implementation_context') actually implements the protocols listed
5897 check_protocols (tree proto_list, const char *type, const char *name)
5899 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5901 tree p = TREE_VALUE (proto_list);
5903 check_protocol (p, type, name);
5907 /* Make sure that the class CLASS_NAME is defined
5908 CODE says which kind of thing CLASS_NAME ought to be.
5909 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5910 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5913 start_class (enum tree_code code, tree class_name, tree super_name,
5918 if (objc_implementation_context)
5920 warning ("`@end' missing in implementation context");
5921 finish_class (objc_implementation_context);
5922 objc_ivar_chain = NULL_TREE;
5923 objc_implementation_context = NULL_TREE;
5926 class = make_node (code);
5927 TYPE_BINFO (class) = make_tree_vec (BINFO_ELTS);
5929 CLASS_NAME (class) = class_name;
5930 CLASS_SUPER_NAME (class) = super_name;
5931 CLASS_CLS_METHODS (class) = NULL_TREE;
5933 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5935 error ("`%s' redeclared as different kind of symbol",
5936 IDENTIFIER_POINTER (class_name));
5937 error ("%Hprevious declaration of '%D'",
5938 &DECL_SOURCE_LOCATION (decl), decl);
5941 if (code == CLASS_IMPLEMENTATION_TYPE)
5946 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5947 if (TREE_VALUE (chain) == class_name)
5949 error ("reimplementation of class `%s'",
5950 IDENTIFIER_POINTER (class_name));
5951 return error_mark_node;
5953 implemented_classes = tree_cons (NULL_TREE, class_name,
5954 implemented_classes);
5957 /* Pre-build the following entities - for speed/convenience. */
5959 self_id = get_identifier ("self");
5961 ucmd_id = get_identifier ("_cmd");
5964 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
5965 if (!objc_super_template)
5966 objc_super_template = build_super_template ();
5968 /* Reset for multiple classes per file. */
5971 objc_implementation_context = class;
5973 /* Lookup the interface for this implementation. */
5975 if (!(implementation_template = lookup_interface (class_name)))
5977 warning ("cannot find interface declaration for `%s'",
5978 IDENTIFIER_POINTER (class_name));
5979 add_class (implementation_template = objc_implementation_context);
5982 /* If a super class has been specified in the implementation,
5983 insure it conforms to the one specified in the interface. */
5986 && (super_name != CLASS_SUPER_NAME (implementation_template)))
5988 tree previous_name = CLASS_SUPER_NAME (implementation_template);
5989 const char *const name =
5990 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
5991 error ("conflicting super class name `%s'",
5992 IDENTIFIER_POINTER (super_name));
5993 error ("previous declaration of `%s'", name);
5996 else if (! super_name)
5998 CLASS_SUPER_NAME (objc_implementation_context)
5999 = CLASS_SUPER_NAME (implementation_template);
6003 else if (code == CLASS_INTERFACE_TYPE)
6005 if (lookup_interface (class_name))
6006 warning ("duplicate interface declaration for class `%s'",
6007 IDENTIFIER_POINTER (class_name));
6012 CLASS_PROTOCOL_LIST (class)
6013 = lookup_and_install_protocols (protocol_list);
6016 else if (code == CATEGORY_INTERFACE_TYPE)
6018 tree class_category_is_assoc_with;
6020 /* For a category, class_name is really the name of the class that
6021 the following set of methods will be associated with. We must
6022 find the interface so that can derive the objects template. */
6024 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6026 error ("cannot find interface declaration for `%s'",
6027 IDENTIFIER_POINTER (class_name));
6028 exit (FATAL_EXIT_CODE);
6031 add_category (class_category_is_assoc_with, class);
6034 CLASS_PROTOCOL_LIST (class)
6035 = lookup_and_install_protocols (protocol_list);
6038 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6040 /* Pre-build the following entities for speed/convenience. */
6042 self_id = get_identifier ("self");
6044 ucmd_id = get_identifier ("_cmd");
6047 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6048 if (!objc_super_template)
6049 objc_super_template = build_super_template ();
6051 /* Reset for multiple classes per file. */
6054 objc_implementation_context = class;
6056 /* For a category, class_name is really the name of the class that
6057 the following set of methods will be associated with. We must
6058 find the interface so that can derive the objects template. */
6060 if (!(implementation_template = lookup_interface (class_name)))
6062 error ("cannot find interface declaration for `%s'",
6063 IDENTIFIER_POINTER (class_name));
6064 exit (FATAL_EXIT_CODE);
6071 continue_class (tree class)
6073 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6074 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6076 struct imp_entry *imp_entry;
6079 /* Check consistency of the instance variables. */
6081 if (CLASS_IVARS (class))
6082 check_ivars (implementation_template, class);
6084 /* code generation */
6086 ivar_context = build_private_template (implementation_template);
6088 if (!objc_class_template)
6089 build_class_template ();
6091 imp_entry = ggc_alloc (sizeof (struct imp_entry));
6093 imp_entry->next = imp_list;
6094 imp_entry->imp_context = class;
6095 imp_entry->imp_template = implementation_template;
6097 synth_forward_declarations ();
6098 imp_entry->class_decl = UOBJC_CLASS_decl;
6099 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6101 /* Append to front and increment count. */
6102 imp_list = imp_entry;
6103 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6108 return ivar_context;
6111 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6113 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6115 if (!TYPE_FIELDS (record))
6117 finish_struct (record, get_class_ivars (class), NULL_TREE);
6118 CLASS_STATIC_TEMPLATE (class) = record;
6120 /* Mark this record as a class template for static typing. */
6121 TREE_STATIC_TEMPLATE (record) = 1;
6128 return error_mark_node;
6131 /* This is called once we see the "@end" in an interface/implementation. */
6134 finish_class (tree class)
6136 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6138 /* All code generation is done in finish_objc. */
6140 if (implementation_template != objc_implementation_context)
6142 /* Ensure that all method listed in the interface contain bodies. */
6143 check_methods (CLASS_CLS_METHODS (implementation_template),
6144 CLASS_CLS_METHODS (objc_implementation_context), '+');
6145 check_methods (CLASS_NST_METHODS (implementation_template),
6146 CLASS_NST_METHODS (objc_implementation_context), '-');
6148 if (CLASS_PROTOCOL_LIST (implementation_template))
6149 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6151 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6155 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6157 tree category = CLASS_CATEGORY_LIST (implementation_template);
6159 /* Find the category interface from the class it is associated with. */
6162 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6164 category = CLASS_CATEGORY_LIST (category);
6169 /* Ensure all method listed in the interface contain bodies. */
6170 check_methods (CLASS_CLS_METHODS (category),
6171 CLASS_CLS_METHODS (objc_implementation_context), '+');
6172 check_methods (CLASS_NST_METHODS (category),
6173 CLASS_NST_METHODS (objc_implementation_context), '-');
6175 if (CLASS_PROTOCOL_LIST (category))
6176 check_protocols (CLASS_PROTOCOL_LIST (category),
6178 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6182 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6185 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6186 char *string = alloca (strlen (class_name) + 3);
6188 /* extern struct objc_object *_<my_name>; */
6190 sprintf (string, "_%s", class_name);
6192 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6193 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6194 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6200 add_protocol (tree protocol)
6202 /* Put protocol on list in reverse order. */
6203 TREE_CHAIN (protocol) = protocol_chain;
6204 protocol_chain = protocol;
6205 return protocol_chain;
6209 lookup_protocol (tree ident)
6213 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6214 if (ident == PROTOCOL_NAME (chain))
6220 /* This function forward declares the protocols named by NAMES. If
6221 they are already declared or defined, the function has no effect. */
6224 objc_declare_protocols (tree names)
6228 for (list = names; list; list = TREE_CHAIN (list))
6230 tree name = TREE_VALUE (list);
6232 if (lookup_protocol (name) == NULL_TREE)
6234 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6236 TYPE_BINFO (protocol) = make_tree_vec (2);
6237 PROTOCOL_NAME (protocol) = name;
6238 PROTOCOL_LIST (protocol) = NULL_TREE;
6239 add_protocol (protocol);
6240 PROTOCOL_DEFINED (protocol) = 0;
6241 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6247 start_protocol (enum tree_code code, tree name, tree list)
6251 /* This is as good a place as any. Need to invoke
6252 push_tag_toplevel. */
6253 if (!objc_protocol_template)
6254 objc_protocol_template = build_protocol_template ();
6256 protocol = lookup_protocol (name);
6260 protocol = make_node (code);
6261 TYPE_BINFO (protocol) = make_tree_vec (2);
6263 PROTOCOL_NAME (protocol) = name;
6264 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6265 add_protocol (protocol);
6266 PROTOCOL_DEFINED (protocol) = 1;
6267 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6269 check_protocol_recursively (protocol, list);
6271 else if (! PROTOCOL_DEFINED (protocol))
6273 PROTOCOL_DEFINED (protocol) = 1;
6274 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6276 check_protocol_recursively (protocol, list);
6280 warning ("duplicate declaration for protocol `%s'",
6281 IDENTIFIER_POINTER (name));
6287 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
6292 /* "Encode" a data type into a string, which grows in util_obstack.
6293 ??? What is the FORMAT? Someone please document this! */
6296 encode_type_qualifiers (tree declspecs)
6300 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6302 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6303 obstack_1grow (&util_obstack, 'r');
6304 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6305 obstack_1grow (&util_obstack, 'n');
6306 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6307 obstack_1grow (&util_obstack, 'N');
6308 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6309 obstack_1grow (&util_obstack, 'o');
6310 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6311 obstack_1grow (&util_obstack, 'O');
6312 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6313 obstack_1grow (&util_obstack, 'R');
6314 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6315 obstack_1grow (&util_obstack, 'V');
6319 /* Encode a pointer type. */
6322 encode_pointer (tree type, int curtype, int format)
6324 tree pointer_to = TREE_TYPE (type);
6326 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6328 if (TYPE_NAME (pointer_to)
6329 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6331 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6333 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6335 obstack_1grow (&util_obstack, '@');
6338 else if (TREE_STATIC_TEMPLATE (pointer_to))
6340 if (generating_instance_variables)
6342 obstack_1grow (&util_obstack, '@');
6343 obstack_1grow (&util_obstack, '"');
6344 obstack_grow (&util_obstack, name, strlen (name));
6345 obstack_1grow (&util_obstack, '"');
6350 obstack_1grow (&util_obstack, '@');
6354 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6356 obstack_1grow (&util_obstack, '#');
6359 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6361 obstack_1grow (&util_obstack, ':');
6366 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6367 && TYPE_MODE (pointer_to) == QImode)
6369 obstack_1grow (&util_obstack, '*');
6373 /* We have a type that does not get special treatment. */
6375 /* NeXT extension */
6376 obstack_1grow (&util_obstack, '^');
6377 encode_type (pointer_to, curtype, format);
6381 encode_array (tree type, int curtype, int format)
6383 tree an_int_cst = TYPE_SIZE (type);
6384 tree array_of = TREE_TYPE (type);
6387 /* An incomplete array is treated like a pointer. */
6388 if (an_int_cst == NULL)
6390 encode_pointer (type, curtype, format);
6394 sprintf (buffer, "[%ld",
6395 (long) (TREE_INT_CST_LOW (an_int_cst)
6396 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6398 obstack_grow (&util_obstack, buffer, strlen (buffer));
6399 encode_type (array_of, curtype, format);
6400 obstack_1grow (&util_obstack, ']');
6405 encode_aggregate_within (tree type, int curtype, int format, int left,
6408 /* The RECORD_TYPE may in fact be a typedef! For purposes
6409 of encoding, we need the real underlying enchilada. */
6410 if (TYPE_MAIN_VARIANT (type))
6411 type = TYPE_MAIN_VARIANT (type);
6413 if (obstack_object_size (&util_obstack) > 0
6414 && *(obstack_next_free (&util_obstack) - 1) == '^')
6416 tree name = TYPE_NAME (type);
6418 /* we have a reference; this is a NeXT extension. */
6420 if (obstack_object_size (&util_obstack) - curtype == 1
6421 && format == OBJC_ENCODE_INLINE_DEFS)
6423 /* Output format of struct for first level only. */
6424 tree fields = TYPE_FIELDS (type);
6426 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6428 obstack_1grow (&util_obstack, left);
6429 obstack_grow (&util_obstack,
6430 IDENTIFIER_POINTER (name),
6431 strlen (IDENTIFIER_POINTER (name)));
6432 obstack_1grow (&util_obstack, '=');
6436 obstack_1grow (&util_obstack, left);
6437 obstack_grow (&util_obstack, "?=", 2);
6440 for ( ; fields; fields = TREE_CHAIN (fields))
6441 encode_field_decl (fields, curtype, format);
6443 obstack_1grow (&util_obstack, right);
6446 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6448 obstack_1grow (&util_obstack, left);
6449 obstack_grow (&util_obstack,
6450 IDENTIFIER_POINTER (name),
6451 strlen (IDENTIFIER_POINTER (name)));
6452 obstack_1grow (&util_obstack, right);
6457 /* We have an untagged structure or a typedef. */
6458 obstack_1grow (&util_obstack, left);
6459 obstack_1grow (&util_obstack, '?');
6460 obstack_1grow (&util_obstack, right);
6466 tree name = TYPE_NAME (type);
6467 tree fields = TYPE_FIELDS (type);
6469 if (format == OBJC_ENCODE_INLINE_DEFS
6470 || generating_instance_variables)
6472 obstack_1grow (&util_obstack, left);
6473 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6474 obstack_grow (&util_obstack,
6475 IDENTIFIER_POINTER (name),
6476 strlen (IDENTIFIER_POINTER (name)));
6478 obstack_1grow (&util_obstack, '?');
6480 obstack_1grow (&util_obstack, '=');
6482 for (; fields; fields = TREE_CHAIN (fields))
6484 if (generating_instance_variables)
6486 tree fname = DECL_NAME (fields);
6488 obstack_1grow (&util_obstack, '"');
6489 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6491 obstack_grow (&util_obstack,
6492 IDENTIFIER_POINTER (fname),
6493 strlen (IDENTIFIER_POINTER (fname)));
6496 obstack_1grow (&util_obstack, '"');
6499 encode_field_decl (fields, curtype, format);
6502 obstack_1grow (&util_obstack, right);
6507 obstack_1grow (&util_obstack, left);
6508 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6509 obstack_grow (&util_obstack,
6510 IDENTIFIER_POINTER (name),
6511 strlen (IDENTIFIER_POINTER (name)));
6513 /* We have an untagged structure or a typedef. */
6514 obstack_1grow (&util_obstack, '?');
6516 obstack_1grow (&util_obstack, right);
6522 encode_aggregate (tree type, int curtype, int format)
6524 enum tree_code code = TREE_CODE (type);
6530 encode_aggregate_within(type, curtype, format, '{', '}');
6535 encode_aggregate_within(type, curtype, format, '(', ')');
6540 obstack_1grow (&util_obstack, 'i');
6548 /* Support bitfields. The current version of Objective-C does not support
6549 them. The string will consist of one or more "b:n"'s where n is an
6550 integer describing the width of the bitfield. Currently, classes in
6551 the kit implement a method "-(char *)describeBitfieldStruct:" that
6552 simulates this. If they do not implement this method, the archiver
6553 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6554 according to the GNU compiler. After looking at the "kit", it appears
6555 that all classes currently rely on this default behavior, rather than
6556 hand generating this string (which is tedious). */
6559 encode_bitfield (int width)
6562 sprintf (buffer, "b%d", width);
6563 obstack_grow (&util_obstack, buffer, strlen (buffer));
6566 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6569 encode_type (tree type, int curtype, int format)
6571 enum tree_code code = TREE_CODE (type);
6573 if (code == INTEGER_TYPE)
6575 if (integer_zerop (TYPE_MIN_VALUE (type)))
6577 /* Unsigned integer types. */
6579 if (TYPE_MODE (type) == QImode)
6580 obstack_1grow (&util_obstack, 'C');
6581 else if (TYPE_MODE (type) == HImode)
6582 obstack_1grow (&util_obstack, 'S');
6583 else if (TYPE_MODE (type) == SImode)
6585 if (type == long_unsigned_type_node)
6586 obstack_1grow (&util_obstack, 'L');
6588 obstack_1grow (&util_obstack, 'I');
6590 else if (TYPE_MODE (type) == DImode)
6591 obstack_1grow (&util_obstack, 'Q');
6595 /* Signed integer types. */
6597 if (TYPE_MODE (type) == QImode)
6598 obstack_1grow (&util_obstack, 'c');
6599 else if (TYPE_MODE (type) == HImode)
6600 obstack_1grow (&util_obstack, 's');
6601 else if (TYPE_MODE (type) == SImode)
6603 if (type == long_integer_type_node)
6604 obstack_1grow (&util_obstack, 'l');
6606 obstack_1grow (&util_obstack, 'i');
6609 else if (TYPE_MODE (type) == DImode)
6610 obstack_1grow (&util_obstack, 'q');
6614 else if (code == REAL_TYPE)
6616 /* Floating point types. */
6618 if (TYPE_MODE (type) == SFmode)
6619 obstack_1grow (&util_obstack, 'f');
6620 else if (TYPE_MODE (type) == DFmode
6621 || TYPE_MODE (type) == TFmode)
6622 obstack_1grow (&util_obstack, 'd');
6625 else if (code == VOID_TYPE)
6626 obstack_1grow (&util_obstack, 'v');
6628 else if (code == ARRAY_TYPE)
6629 encode_array (type, curtype, format);
6631 else if (code == POINTER_TYPE)
6632 encode_pointer (type, curtype, format);
6634 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6635 encode_aggregate (type, curtype, format);
6637 else if (code == FUNCTION_TYPE) /* '?' */
6638 obstack_1grow (&util_obstack, '?');
6642 encode_complete_bitfield (int position, tree type, int size)
6644 enum tree_code code = TREE_CODE (type);
6646 char charType = '?';
6648 if (code == INTEGER_TYPE)
6650 if (integer_zerop (TYPE_MIN_VALUE (type)))
6652 /* Unsigned integer types. */
6654 if (TYPE_MODE (type) == QImode)
6656 else if (TYPE_MODE (type) == HImode)
6658 else if (TYPE_MODE (type) == SImode)
6660 if (type == long_unsigned_type_node)
6665 else if (TYPE_MODE (type) == DImode)
6670 /* Signed integer types. */
6672 if (TYPE_MODE (type) == QImode)
6674 else if (TYPE_MODE (type) == HImode)
6676 else if (TYPE_MODE (type) == SImode)
6678 if (type == long_integer_type_node)
6684 else if (TYPE_MODE (type) == DImode)
6688 else if (code == ENUMERAL_TYPE)
6693 sprintf (buffer, "b%d%c%d", position, charType, size);
6694 obstack_grow (&util_obstack, buffer, strlen (buffer));
6698 encode_field_decl (tree field_decl, int curtype, int format)
6702 type = TREE_TYPE (field_decl);
6704 /* If this field is obviously a bitfield, or is a bitfield that has been
6705 clobbered to look like a ordinary integer mode, go ahead and generate
6706 the bitfield typing information. */
6707 if (flag_next_runtime)
6709 if (DECL_BIT_FIELD_TYPE (field_decl))
6710 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6712 encode_type (TREE_TYPE (field_decl), curtype, format);
6716 if (DECL_BIT_FIELD_TYPE (field_decl))
6717 encode_complete_bitfield (int_bit_position (field_decl),
6718 DECL_BIT_FIELD_TYPE (field_decl),
6719 tree_low_cst (DECL_SIZE (field_decl), 1));
6721 encode_type (TREE_TYPE (field_decl), curtype, format);
6726 objc_expr_last (tree complex_expr)
6731 while ((next = TREE_OPERAND (complex_expr, 0)))
6732 complex_expr = next;
6734 return complex_expr;
6737 /* Transform a method definition into a function definition as follows:
6738 - synthesize the first two arguments, "self" and "_cmd". */
6741 start_method_def (tree method)
6745 /* Required to implement _msgSuper. */
6746 objc_method_context = method;
6747 UOBJC_SUPER_decl = NULL_TREE;
6749 /* Must be called BEFORE start_function. */
6752 /* Generate prototype declarations for arguments..."new-style". */
6754 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6755 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6757 /* Really a `struct objc_class *'. However, we allow people to
6758 assign to self, which changes its type midstream. */
6759 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6761 push_parm_decl (build_tree_list
6762 (build_tree_list (decl_specs,
6763 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6766 decl_specs = build_tree_list (NULL_TREE,
6767 xref_tag (RECORD_TYPE,
6768 get_identifier (TAG_SELECTOR)));
6769 push_parm_decl (build_tree_list
6770 (build_tree_list (decl_specs,
6771 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6774 /* Generate argument declarations if a keyword_decl. */
6775 if (METHOD_SEL_ARGS (method))
6777 tree arglist = METHOD_SEL_ARGS (method);
6780 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6781 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6785 tree last_expr = objc_expr_last (arg_decl);
6787 /* Unite the abstract decl with its name. */
6788 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6789 push_parm_decl (build_tree_list
6790 (build_tree_list (arg_spec, arg_decl),
6793 /* Unhook: restore the abstract declarator. */
6794 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6798 push_parm_decl (build_tree_list
6799 (build_tree_list (arg_spec,
6800 KEYWORD_ARG_NAME (arglist)),
6803 arglist = TREE_CHAIN (arglist);
6808 if (METHOD_ADD_ARGS (method) != NULL_TREE
6809 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6811 /* We have a variable length selector - in "prototype" format. */
6812 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6815 /* This must be done prior to calling pushdecl. pushdecl is
6816 going to change our chain on us. */
6817 tree nextkey = TREE_CHAIN (akey);
6825 warn_with_method (const char *message, int mtype, tree method)
6827 /* Add a readable method name to the warning. */
6828 warning ("%H%s `%c%s'", &DECL_SOURCE_LOCATION (method),
6829 message, mtype, gen_method_decl (method, errbuf));
6832 /* Return 1 if METHOD is consistent with PROTO. */
6835 comp_method_with_proto (tree method, tree proto)
6837 /* Create a function template node at most once. */
6838 if (!function1_template)
6839 function1_template = make_node (FUNCTION_TYPE);
6841 /* Install argument types - normally set by build_function_type. */
6842 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6844 /* install return type */
6845 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6847 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template,
6851 /* Return 1 if PROTO1 is consistent with PROTO2. */
6854 comp_proto_with_proto (tree proto0, tree proto1)
6856 /* Create a couple of function_template nodes at most once. */
6857 if (!function1_template)
6858 function1_template = make_node (FUNCTION_TYPE);
6859 if (!function2_template)
6860 function2_template = make_node (FUNCTION_TYPE);
6862 /* Install argument types; normally set by build_function_type. */
6863 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6864 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6866 /* Install return type. */
6867 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6868 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6870 return comptypes (function1_template, function2_template, false);
6873 /* - Generate an identifier for the function. the format is "_n_cls",
6874 where 1 <= n <= nMethods, and cls is the name the implementation we
6876 - Install the return type from the method declaration.
6877 - If we have a prototype, check for type consistency. */
6880 really_start_method (tree method, tree parmlist)
6882 tree sc_spec, ret_spec, ret_decl, decl_specs;
6883 tree method_decl, method_id;
6884 const char *sel_name, *class_name, *cat_name;
6887 /* Synth the storage class & assemble the return type. */
6888 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6889 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6890 decl_specs = chainon (sc_spec, ret_spec);
6892 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6893 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6894 cat_name = ((TREE_CODE (objc_implementation_context)
6895 == CLASS_IMPLEMENTATION_TYPE)
6897 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6900 /* Make sure this is big enough for any plausible method label. */
6901 buf = alloca (50 + strlen (sel_name) + strlen (class_name)
6902 + (cat_name ? strlen (cat_name) : 0));
6904 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6905 class_name, cat_name, sel_name, method_slot);
6907 method_id = get_identifier (buf);
6909 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
6911 /* Check the declarator portion of the return type for the method. */
6912 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6914 /* Unite the complex decl (specified in the abstract decl) with the
6915 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6916 tree save_expr = objc_expr_last (ret_decl);
6918 TREE_OPERAND (save_expr, 0) = method_decl;
6919 method_decl = ret_decl;
6921 /* Fool the parser into thinking it is starting a function. */
6922 start_function (decl_specs, method_decl, NULL_TREE);
6924 /* Unhook: this has the effect of restoring the abstract declarator. */
6925 TREE_OPERAND (save_expr, 0) = NULL_TREE;
6930 TREE_VALUE (TREE_TYPE (method)) = method_decl;
6932 /* Fool the parser into thinking it is starting a function. */
6933 start_function (decl_specs, method_decl, NULL_TREE);
6935 /* Unhook: this has the effect of restoring the abstract declarator. */
6936 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
6939 METHOD_DEFINITION (method) = current_function_decl;
6941 /* Check consistency...start_function, pushdecl, duplicate_decls. */
6943 if (implementation_template != objc_implementation_context)
6947 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
6948 proto = lookup_instance_method_static (implementation_template,
6949 METHOD_SEL_NAME (method));
6951 proto = lookup_class_method_static (implementation_template,
6952 METHOD_SEL_NAME (method));
6954 if (proto && ! comp_method_with_proto (method, proto))
6956 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
6958 warn_with_method ("conflicting types for", type, method);
6959 warn_with_method ("previous declaration of", type, proto);
6964 /* The following routine is always called...this "architecture" is to
6965 accommodate "old-style" variable length selectors.
6967 - a:a b:b // prototype ; id c; id d; // old-style. */
6970 continue_method_def (void)
6974 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
6975 /* We have a `, ...' immediately following the selector. */
6976 parmlist = get_parm_info (0);
6978 parmlist = get_parm_info (1); /* place a `void_at_end' */
6980 /* Set self_decl from the first argument...this global is used by
6981 build_ivar_reference calling build_indirect_ref. */
6982 self_decl = TREE_PURPOSE (parmlist);
6985 really_start_method (objc_method_context, parmlist);
6986 store_parm_decls ();
6989 /* Called by the parser, from the `pushlevel' production. */
6992 add_objc_decls (void)
6994 if (!UOBJC_SUPER_decl)
6996 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
6997 build_tree_list (NULL_TREE,
6998 objc_super_template),
7001 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7003 /* This prevents `unused variable' warnings when compiling with -Wall. */
7004 TREE_USED (UOBJC_SUPER_decl) = 1;
7005 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7009 /* _n_Method (id self, SEL sel, ...)
7011 struct objc_super _S;
7012 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7016 get_super_receiver (void)
7018 if (objc_method_context)
7020 tree super_expr, super_expr_list;
7022 /* Set receiver to self. */
7023 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7024 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7025 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7027 /* Set class to begin searching. */
7028 super_expr = build_component_ref (UOBJC_SUPER_decl,
7029 get_identifier ("class"));
7031 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7033 /* [_cls, __cls]Super are "pre-built" in
7034 synth_forward_declarations. */
7036 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7037 ((TREE_CODE (objc_method_context)
7038 == INSTANCE_METHOD_DECL)
7040 : uucls_super_ref));
7044 /* We have a category. */
7046 tree super_name = CLASS_SUPER_NAME (implementation_template);
7049 /* Barf if super used in a category of Object. */
7052 error ("no super class declared in interface for `%s'",
7053 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7054 return error_mark_node;
7057 if (flag_next_runtime)
7059 super_class = get_class_reference (super_name);
7060 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7061 /* Cast the super class to 'id', since the user may not have
7062 included <objc/objc-class.h>, leaving 'struct objc_class'
7063 an incomplete type. */
7065 = build_component_ref (build_indirect_ref
7066 (build_c_cast (id_type, super_class), "->"),
7067 get_identifier ("isa"));
7071 add_class_reference (super_name);
7072 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7073 ? objc_get_class_decl : objc_get_meta_class_decl);
7074 assemble_external (super_class);
7076 = build_function_call
7080 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7081 IDENTIFIER_POINTER (super_name))));
7084 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7085 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7088 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7090 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7091 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7093 return build_compound_expr (super_expr_list);
7097 error ("[super ...] must appear in a method context");
7098 return error_mark_node;
7103 encode_method_def (tree func_decl)
7107 HOST_WIDE_INT max_parm_end = 0;
7112 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7113 obstack_object_size (&util_obstack),
7114 OBJC_ENCODE_INLINE_DEFS);
7117 for (parms = DECL_ARGUMENTS (func_decl); parms;
7118 parms = TREE_CHAIN (parms))
7120 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7121 + int_size_in_bytes (TREE_TYPE (parms)));
7123 if (! offset_is_register && parm_end > max_parm_end)
7124 max_parm_end = parm_end;
7127 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7129 sprintf (buffer, "%d", stack_size);
7130 obstack_grow (&util_obstack, buffer, strlen (buffer));
7132 /* Argument types. */
7133 for (parms = DECL_ARGUMENTS (func_decl); parms;
7134 parms = TREE_CHAIN (parms))
7137 encode_type (TREE_TYPE (parms),
7138 obstack_object_size (&util_obstack),
7139 OBJC_ENCODE_INLINE_DEFS);
7141 /* Compute offset. */
7142 sprintf (buffer, "%d", forwarding_offset (parms));
7144 /* Indicate register. */
7145 if (offset_is_register)
7146 obstack_1grow (&util_obstack, '+');
7148 obstack_grow (&util_obstack, buffer, strlen (buffer));
7151 /* Null terminate string. */
7152 obstack_1grow (&util_obstack, 0);
7153 result = get_identifier (obstack_finish (&util_obstack));
7154 obstack_free (&util_obstack, util_firstobj);
7159 objc_expand_function_end (void)
7161 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7165 finish_method_def (void)
7167 lang_expand_function_end = objc_expand_function_end;
7169 lang_expand_function_end = NULL;
7171 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7172 since the optimizer may find "may be used before set" errors. */
7173 objc_method_context = NULL_TREE;
7178 lang_report_error_function (tree decl)
7180 if (objc_method_context)
7182 fprintf (stderr, "In method `%s'\n",
7183 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7193 is_complex_decl (tree type)
7195 return (TREE_CODE (type) == ARRAY_TYPE
7196 || TREE_CODE (type) == FUNCTION_TYPE
7197 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7201 /* Code to convert a decl node into text for a declaration in C. */
7203 static char tmpbuf[256];
7206 adorn_decl (tree decl, char *str)
7208 enum tree_code code = TREE_CODE (decl);
7210 if (code == ARRAY_REF)
7212 tree an_int_cst = TREE_OPERAND (decl, 1);
7214 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7215 sprintf (str + strlen (str), "[%ld]",
7216 (long) TREE_INT_CST_LOW (an_int_cst));
7221 else if (code == ARRAY_TYPE)
7223 tree an_int_cst = TYPE_SIZE (decl);
7224 tree array_of = TREE_TYPE (decl);
7226 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7227 sprintf (str + strlen (str), "[%ld]",
7228 (long) (TREE_INT_CST_LOW (an_int_cst)
7229 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7234 else if (code == CALL_EXPR)
7236 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7241 gen_declaration_1 (chain, str);
7242 chain = TREE_CHAIN (chain);
7249 else if (code == FUNCTION_TYPE)
7251 tree chain = TYPE_ARG_TYPES (decl);
7254 while (chain && TREE_VALUE (chain) != void_type_node)
7256 gen_declaration_1 (TREE_VALUE (chain), str);
7257 chain = TREE_CHAIN (chain);
7258 if (chain && TREE_VALUE (chain) != void_type_node)
7264 else if (code == INDIRECT_REF)
7266 strcpy (tmpbuf, "*");
7267 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7271 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7273 chain = TREE_CHAIN (chain))
7275 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7277 strcat (tmpbuf, " ");
7278 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7282 strcat (tmpbuf, " ");
7284 strcat (tmpbuf, str);
7285 strcpy (str, tmpbuf);
7288 else if (code == POINTER_TYPE)
7290 strcpy (tmpbuf, "*");
7291 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7293 if (TREE_READONLY (decl))
7294 strcat (tmpbuf, " const");
7295 if (TYPE_VOLATILE (decl))
7296 strcat (tmpbuf, " volatile");
7298 strcat (tmpbuf, " ");
7300 strcat (tmpbuf, str);
7301 strcpy (str, tmpbuf);
7306 gen_declarator (tree decl, char *buf, const char *name)
7310 enum tree_code code = TREE_CODE (decl);
7320 op = TREE_OPERAND (decl, 0);
7322 /* We have a pointer to a function or array...(*)(), (*)[] */
7323 if ((code == ARRAY_REF || code == CALL_EXPR)
7324 && op && TREE_CODE (op) == INDIRECT_REF)
7327 str = gen_declarator (op, buf, name);
7331 strcpy (tmpbuf, "(");
7332 strcat (tmpbuf, str);
7333 strcat (tmpbuf, ")");
7334 strcpy (str, tmpbuf);
7337 adorn_decl (decl, str);
7346 /* This clause is done iteratively rather than recursively. */
7349 op = (is_complex_decl (TREE_TYPE (decl))
7350 ? TREE_TYPE (decl) : NULL_TREE);
7352 adorn_decl (decl, str);
7354 /* We have a pointer to a function or array...(*)(), (*)[] */
7355 if (code == POINTER_TYPE
7356 && op && (TREE_CODE (op) == FUNCTION_TYPE
7357 || TREE_CODE (op) == ARRAY_TYPE))
7359 strcpy (tmpbuf, "(");
7360 strcat (tmpbuf, str);
7361 strcat (tmpbuf, ")");
7362 strcpy (str, tmpbuf);
7365 decl = (is_complex_decl (TREE_TYPE (decl))
7366 ? TREE_TYPE (decl) : NULL_TREE);
7369 while (decl && (code = TREE_CODE (decl)))
7374 case IDENTIFIER_NODE:
7375 /* Will only happen if we are processing a "raw" expr-decl. */
7376 strcpy (buf, IDENTIFIER_POINTER (decl));
7387 /* We have an abstract declarator or a _DECL node. */
7395 gen_declspecs (tree declspecs, char *buf, int raw)
7401 for (chain = nreverse (copy_list (declspecs));
7402 chain; chain = TREE_CHAIN (chain))
7404 tree aspec = TREE_VALUE (chain);
7406 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7407 strcat (buf, IDENTIFIER_POINTER (aspec));
7408 else if (TREE_CODE (aspec) == RECORD_TYPE)
7410 if (TYPE_NAME (aspec))
7412 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7414 if (! TREE_STATIC_TEMPLATE (aspec))
7415 strcat (buf, "struct ");
7416 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7421 tree chain = protocol_list;
7428 (PROTOCOL_NAME (TREE_VALUE (chain))));
7429 chain = TREE_CHAIN (chain);
7438 strcat (buf, "untagged struct");
7441 else if (TREE_CODE (aspec) == UNION_TYPE)
7443 if (TYPE_NAME (aspec))
7445 if (! TREE_STATIC_TEMPLATE (aspec))
7446 strcat (buf, "union ");
7447 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7450 strcat (buf, "untagged union");
7453 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7455 if (TYPE_NAME (aspec))
7457 if (! TREE_STATIC_TEMPLATE (aspec))
7458 strcat (buf, "enum ");
7459 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7462 strcat (buf, "untagged enum");
7465 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7466 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7468 else if (IS_ID (aspec))
7470 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7475 tree chain = protocol_list;
7482 (PROTOCOL_NAME (TREE_VALUE (chain))));
7483 chain = TREE_CHAIN (chain);
7490 if (TREE_CHAIN (chain))
7496 /* Type qualifiers. */
7497 if (TREE_READONLY (declspecs))
7498 strcat (buf, "const ");
7499 if (TYPE_VOLATILE (declspecs))
7500 strcat (buf, "volatile ");
7502 switch (TREE_CODE (declspecs))
7504 /* Type specifiers. */
7507 declspecs = TYPE_MAIN_VARIANT (declspecs);
7509 /* Signed integer types. */
7511 if (declspecs == short_integer_type_node)
7512 strcat (buf, "short int ");
7513 else if (declspecs == integer_type_node)
7514 strcat (buf, "int ");
7515 else if (declspecs == long_integer_type_node)
7516 strcat (buf, "long int ");
7517 else if (declspecs == long_long_integer_type_node)
7518 strcat (buf, "long long int ");
7519 else if (declspecs == signed_char_type_node
7520 || declspecs == char_type_node)
7521 strcat (buf, "char ");
7523 /* Unsigned integer types. */
7525 else if (declspecs == short_unsigned_type_node)
7526 strcat (buf, "unsigned short ");
7527 else if (declspecs == unsigned_type_node)
7528 strcat (buf, "unsigned int ");
7529 else if (declspecs == long_unsigned_type_node)
7530 strcat (buf, "unsigned long ");
7531 else if (declspecs == long_long_unsigned_type_node)
7532 strcat (buf, "unsigned long long ");
7533 else if (declspecs == unsigned_char_type_node)
7534 strcat (buf, "unsigned char ");
7538 declspecs = TYPE_MAIN_VARIANT (declspecs);
7540 if (declspecs == float_type_node)
7541 strcat (buf, "float ");
7542 else if (declspecs == double_type_node)
7543 strcat (buf, "double ");
7544 else if (declspecs == long_double_type_node)
7545 strcat (buf, "long double ");
7549 if (TYPE_NAME (declspecs)
7550 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7552 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7554 if (! TREE_STATIC_TEMPLATE (declspecs))
7555 strcat (buf, "struct ");
7556 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7560 tree chain = protocol_list;
7567 (PROTOCOL_NAME (TREE_VALUE (chain))));
7568 chain = TREE_CHAIN (chain);
7577 strcat (buf, "untagged struct");
7583 if (TYPE_NAME (declspecs)
7584 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7586 strcat (buf, "union ");
7587 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7592 strcat (buf, "untagged union ");
7596 if (TYPE_NAME (declspecs)
7597 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7599 strcat (buf, "enum ");
7600 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7605 strcat (buf, "untagged enum ");
7609 strcat (buf, "void ");
7614 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7619 tree chain = protocol_list;
7626 (PROTOCOL_NAME (TREE_VALUE (chain))));
7627 chain = TREE_CHAIN (chain);
7643 /* Given a tree node, produce a printable description of it in the given
7644 buffer, overwriting the buffer. */
7647 gen_declaration (tree atype_or_adecl, char *buf)
7650 gen_declaration_1 (atype_or_adecl, buf);
7654 /* Given a tree node, append a printable description to the end of the
7658 gen_declaration_1 (tree atype_or_adecl, char *buf)
7662 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7664 tree declspecs; /* "identifier_node", "record_type" */
7665 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7667 /* We have a "raw", abstract declarator (typename). */
7668 declarator = TREE_VALUE (atype_or_adecl);
7669 declspecs = TREE_PURPOSE (atype_or_adecl);
7671 gen_declspecs (declspecs, buf, 1);
7675 strcat (buf, gen_declarator (declarator, declbuf, ""));
7682 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7683 tree declarator; /* "array_type", "function_type", "pointer_type". */
7685 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7686 || TREE_CODE (atype_or_adecl) == PARM_DECL
7687 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7688 atype = TREE_TYPE (atype_or_adecl);
7690 /* Assume we have a *_type node. */
7691 atype = atype_or_adecl;
7693 if (is_complex_decl (atype))
7697 /* Get the declaration specifier; it is at the end of the list. */
7698 declarator = chain = atype;
7700 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7701 while (is_complex_decl (chain));
7708 declarator = NULL_TREE;
7711 gen_declspecs (declspecs, buf, 0);
7713 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7714 || TREE_CODE (atype_or_adecl) == PARM_DECL
7715 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7717 const char *const decl_name =
7718 (DECL_NAME (atype_or_adecl)
7719 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7724 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7727 else if (decl_name[0])
7730 strcat (buf, decl_name);
7733 else if (declarator)
7736 strcat (buf, gen_declarator (declarator, declbuf, ""));
7741 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7743 /* Given a method tree, put a printable description into the given
7744 buffer (overwriting) and return a pointer to the buffer. */
7747 gen_method_decl (tree method, char *buf)
7752 if (RAW_TYPESPEC (method) != objc_object_reference)
7755 gen_declaration_1 (TREE_TYPE (method), buf);
7759 chain = METHOD_SEL_ARGS (method);
7762 /* We have a chain of keyword_decls. */
7765 if (KEYWORD_KEY_NAME (chain))
7766 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7769 if (RAW_TYPESPEC (chain) != objc_object_reference)
7772 gen_declaration_1 (TREE_TYPE (chain), buf);
7776 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7777 if ((chain = TREE_CHAIN (chain)))
7782 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7783 strcat (buf, ", ...");
7784 else if (METHOD_ADD_ARGS (method))
7786 /* We have a tree list node as generate by get_parm_info. */
7787 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7789 /* Know we have a chain of parm_decls. */
7793 gen_declaration_1 (chain, buf);
7794 chain = TREE_CHAIN (chain);
7800 /* We have a unary selector. */
7801 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7809 /* Dump an @interface declaration of the supplied class CHAIN to the
7810 supplied file FP. Used to implement the -gen-decls option (which
7811 prints out an @interface declaration of all classes compiled in
7812 this run); potentially useful for debugging the compiler too. */
7814 dump_interface (FILE *fp, tree chain)
7816 /* FIXME: A heap overflow here whenever a method (or ivar)
7817 declaration is so long that it doesn't fit in the buffer. The
7818 code and all the related functions should be rewritten to avoid
7819 using fixed size buffers. */
7820 char *buf = xmalloc (1024 * 10);
7821 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7822 tree ivar_decls = CLASS_RAW_IVARS (chain);
7823 tree nst_methods = CLASS_NST_METHODS (chain);
7824 tree cls_methods = CLASS_CLS_METHODS (chain);
7826 fprintf (fp, "\n@interface %s", my_name);
7828 /* CLASS_SUPER_NAME is used to store the superclass name for
7829 classes, and the category name for categories. */
7830 if (CLASS_SUPER_NAME (chain))
7832 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7834 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
7835 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
7837 fprintf (fp, " (%s)\n", name);
7841 fprintf (fp, " : %s\n", name);
7847 /* FIXME - the following doesn't seem to work at the moment. */
7850 fprintf (fp, "{\n");
7853 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7854 ivar_decls = TREE_CHAIN (ivar_decls);
7857 fprintf (fp, "}\n");
7862 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7863 nst_methods = TREE_CHAIN (nst_methods);
7868 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7869 cls_methods = TREE_CHAIN (cls_methods);
7872 fprintf (fp, "@end\n");
7875 /* Demangle function for Objective-C */
7877 objc_demangle (const char *mangled)
7879 char *demangled, *cp;
7881 if (mangled[0] == '_' &&
7882 (mangled[1] == 'i' || mangled[1] == 'c') &&
7885 cp = demangled = xmalloc(strlen(mangled) + 2);
7886 if (mangled[1] == 'i')
7887 *cp++ = '-'; /* for instance method */
7889 *cp++ = '+'; /* for class method */
7890 *cp++ = '['; /* opening left brace */
7891 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
7892 while (*cp && *cp == '_')
7893 cp++; /* skip any initial underbars in class name */
7894 cp = strchr(cp, '_'); /* find first non-initial underbar */
7897 free(demangled); /* not mangled name */
7900 if (cp[1] == '_') /* easy case: no category name */
7902 *cp++ = ' '; /* replace two '_' with one ' ' */
7903 strcpy(cp, mangled + (cp - demangled) + 2);
7907 *cp++ = '('; /* less easy case: category name */
7908 cp = strchr(cp, '_');
7911 free(demangled); /* not mangled name */
7915 *cp++ = ' '; /* overwriting 1st char of method name... */
7916 strcpy(cp, mangled + (cp - demangled)); /* get it back */
7918 while (*cp && *cp == '_')
7919 cp++; /* skip any initial underbars in method name */
7922 *cp = ':'; /* replace remaining '_' with ':' */
7923 *cp++ = ']'; /* closing right brace */
7924 *cp++ = 0; /* string terminator */
7928 return mangled; /* not an objc mangled name */
7932 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
7934 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
7940 gcc_obstack_init (&util_obstack);
7941 util_firstobj = (char *) obstack_finish (&util_obstack);
7943 errbuf = xmalloc (BUFSIZE);
7945 synth_module_prologue ();
7951 struct imp_entry *impent;
7953 /* The internally generated initializers appear to have missing braces.
7954 Don't warn about this. */
7955 int save_warn_missing_braces = warn_missing_braces;
7956 warn_missing_braces = 0;
7958 /* A missing @end may not be detected by the parser. */
7959 if (objc_implementation_context)
7961 warning ("`@end' missing in implementation context");
7962 finish_class (objc_implementation_context);
7963 objc_ivar_chain = NULL_TREE;
7964 objc_implementation_context = NULL_TREE;
7967 generate_forward_declaration_to_string_table ();
7969 /* Process the static instances here because initialization of objc_symtab
7971 if (objc_static_instances)
7972 generate_static_references ();
7974 if (imp_list || class_names_chain
7975 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7976 generate_objc_symtab_decl ();
7978 for (impent = imp_list; impent; impent = impent->next)
7980 objc_implementation_context = impent->imp_context;
7981 implementation_template = impent->imp_template;
7983 UOBJC_CLASS_decl = impent->class_decl;
7984 UOBJC_METACLASS_decl = impent->meta_decl;
7986 /* Dump the @interface of each class as we compile it, if the
7987 -gen-decls option is in use. TODO: Dump the classes in the
7988 order they were found, rather than in reverse order as we
7990 if (flag_gen_declaration)
7992 dump_interface (gen_declaration_file, objc_implementation_context);
7995 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7997 /* all of the following reference the string pool... */
7998 generate_ivar_lists ();
7999 generate_dispatch_tables ();
8000 generate_shared_structures ();
8004 generate_dispatch_tables ();
8005 generate_category (objc_implementation_context);
8009 /* If we are using an array of selectors, we must always
8010 finish up the array decl even if no selectors were used. */
8011 if (! flag_next_runtime || sel_ref_chain)
8012 build_selector_translation_table ();
8015 generate_protocols ();
8017 if (objc_implementation_context || class_names_chain || objc_static_instances
8018 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8020 /* Arrange for ObjC data structures to be initialized at run time. */
8021 rtx init_sym = build_module_descriptor ();
8022 if (init_sym && targetm.have_ctors_dtors)
8023 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8026 /* Dump the class references. This forces the appropriate classes
8027 to be linked into the executable image, preserving unix archive
8028 semantics. This can be removed when we move to a more dynamically
8029 linked environment. */
8031 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8033 handle_class_ref (chain);
8034 if (TREE_PURPOSE (chain))
8035 generate_classref_translation_entry (chain);
8038 for (impent = imp_list; impent; impent = impent->next)
8039 handle_impent (impent);
8041 /* Dump the string table last. */
8043 generate_strings ();
8050 /* Run through the selector hash tables and print a warning for any
8051 selector which has multiple methods. */
8053 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8054 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8057 tree meth = hsh->key;
8058 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8062 warning ("potential selector conflict for method `%s'",
8063 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8064 warn_with_method ("found", type, meth);
8065 for (loop = hsh->list; loop; loop = loop->next)
8066 warn_with_method ("found", type, loop->value);
8069 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8070 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8073 tree meth = hsh->key;
8074 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8078 warning ("potential selector conflict for method `%s'",
8079 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8080 warn_with_method ("found", type, meth);
8081 for (loop = hsh->list; loop; loop = loop->next)
8082 warn_with_method ("found", type, loop->value);
8086 warn_missing_braces = save_warn_missing_braces;
8089 /* Subroutines of finish_objc. */
8092 generate_classref_translation_entry (tree chain)
8094 tree expr, name, decl_specs, decl, sc_spec;
8097 type = TREE_TYPE (TREE_PURPOSE (chain));
8099 expr = add_objc_string (TREE_VALUE (chain), class_names);
8100 expr = build_c_cast (type, expr); /* cast! */
8102 name = DECL_NAME (TREE_PURPOSE (chain));
8104 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8106 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8107 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8109 /* The decl that is returned from start_decl is the one that we
8110 forward declared in build_class_reference. */
8111 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8112 DECL_CONTEXT (decl) = NULL_TREE;
8113 finish_decl (decl, expr, NULL_TREE);
8118 handle_class_ref (tree chain)
8120 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8121 char *string = alloca (strlen (name) + 30);
8125 sprintf (string, "%sobjc_class_name_%s",
8126 (flag_next_runtime ? "." : "__"), name);
8128 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8129 if (flag_next_runtime)
8131 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8136 /* Make a decl for this name, so we can use its address in a tree. */
8137 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8138 DECL_EXTERNAL (decl) = 1;
8139 TREE_PUBLIC (decl) = 1;
8142 rest_of_decl_compilation (decl, 0, 0, 0);
8144 /* Make a decl for the address. */
8145 sprintf (string, "%sobjc_class_ref_%s",
8146 (flag_next_runtime ? "." : "__"), name);
8147 exp = build1 (ADDR_EXPR, string_type_node, decl);
8148 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8149 DECL_INITIAL (decl) = exp;
8150 TREE_STATIC (decl) = 1;
8151 TREE_USED (decl) = 1;
8154 rest_of_decl_compilation (decl, 0, 0, 0);
8158 handle_impent (struct imp_entry *impent)
8162 objc_implementation_context = impent->imp_context;
8163 implementation_template = impent->imp_template;
8165 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8167 const char *const class_name =
8168 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8170 string = alloca (strlen (class_name) + 30);
8172 sprintf (string, "%sobjc_class_name_%s",
8173 (flag_next_runtime ? "." : "__"), class_name);
8175 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8177 const char *const class_name =
8178 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8179 const char *const class_super_name =
8180 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8182 string = alloca (strlen (class_name)
8183 + strlen (class_super_name) + 30);
8185 /* Do the same for categories. Even though no references to
8186 these symbols are generated automatically by the compiler, it
8187 gives you a handle to pull them into an archive by hand. */
8188 sprintf (string, "*%sobjc_category_name_%s_%s",
8189 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8194 #ifdef ASM_DECLARE_CLASS_REFERENCE
8195 if (flag_next_runtime)
8197 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8205 init = build_int_2 (0, 0);
8206 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8207 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8208 TREE_PUBLIC (decl) = 1;
8209 TREE_READONLY (decl) = 1;
8210 TREE_USED (decl) = 1;
8211 TREE_CONSTANT (decl) = 1;
8212 DECL_CONTEXT (decl) = 0;
8213 DECL_ARTIFICIAL (decl) = 1;
8214 DECL_INITIAL (decl) = init;
8215 assemble_variable (decl, 1, 0, 0);
8219 /* Look up ID as an instance variable. */
8221 lookup_objc_ivar (tree id)
8225 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8226 /* We have a message to super. */
8227 return get_super_receiver ();
8228 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8230 if (is_private (decl))
8231 return error_mark_node;
8233 return build_ivar_reference (id);
8239 #include "gt-objc-objc-act.h"
8240 #include "gtype-objc.h"