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 ("%J'%D' cannot be statically allocated", decl, decl);
896 /* Implement static typing. At this point, we know we have an interface. */
899 get_static_reference (tree interface, tree protocols)
901 tree type = xref_tag (RECORD_TYPE, interface);
905 tree t, m = TYPE_MAIN_VARIANT (type);
907 t = copy_node (type);
909 /* Add this type to the chain of variants of TYPE. */
910 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
911 TYPE_NEXT_VARIANT (m) = t;
913 /* Look up protocols and install in lang specific list. Note
914 that the protocol list can have a different lifetime than T! */
915 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
917 /* This forces a new pointer type to be created later
918 (in build_pointer_type)...so that the new template
919 we just created will actually be used...what a hack! */
920 if (TYPE_POINTER_TO (t))
921 TYPE_POINTER_TO (t) = NULL_TREE;
930 get_object_reference (tree protocols)
932 tree type_decl = lookup_name (objc_id_id);
935 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
937 type = TREE_TYPE (type_decl);
938 if (TYPE_MAIN_VARIANT (type) != id_type)
939 warning ("unexpected type for `id' (%s)",
940 gen_declaration (type, errbuf));
944 error ("undefined type `id', please import <objc/objc.h>");
945 return error_mark_node;
948 /* This clause creates a new pointer type that is qualified with
949 the protocol specification...this info is used later to do more
950 elaborate type checking. */
954 tree t, m = TYPE_MAIN_VARIANT (type);
956 t = copy_node (type);
958 /* Add this type to the chain of variants of TYPE. */
959 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
960 TYPE_NEXT_VARIANT (m) = t;
962 /* Look up protocols...and install in lang specific list */
963 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
965 /* This forces a new pointer type to be created later
966 (in build_pointer_type)...so that the new template
967 we just created will actually be used...what a hack! */
968 if (TYPE_POINTER_TO (t))
969 TYPE_POINTER_TO (t) = NULL_TREE;
976 /* Check for circular dependencies in protocols. The arguments are
977 PROTO, the protocol to check, and LIST, a list of protocol it
981 check_protocol_recursively (tree proto, tree list)
985 for (p = list; p; p = TREE_CHAIN (p))
987 tree pp = TREE_VALUE (p);
989 if (TREE_CODE (pp) == IDENTIFIER_NODE)
990 pp = lookup_protocol (pp);
993 fatal_error ("protocol `%s' has circular dependency",
994 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
996 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1001 lookup_and_install_protocols (tree protocols)
1005 tree return_value = protocols;
1007 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1009 tree ident = TREE_VALUE (proto);
1010 tree p = lookup_protocol (ident);
1014 error ("cannot find protocol declaration for `%s'",
1015 IDENTIFIER_POINTER (ident));
1017 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1019 return_value = TREE_CHAIN (proto);
1023 /* Replace identifier with actual protocol node. */
1024 TREE_VALUE (proto) = p;
1029 return return_value;
1032 /* Create and push a decl for a built-in external variable or field NAME.
1034 TYPE is its data type. */
1037 create_builtin_decl (enum tree_code code, tree type, const char *name)
1039 tree decl = build_decl (code, get_identifier (name), type);
1041 if (code == VAR_DECL)
1043 TREE_STATIC (decl) = 1;
1044 make_decl_rtl (decl, 0);
1048 DECL_ARTIFICIAL (decl) = 1;
1052 /* Find the decl for the constant string class. */
1055 setup_string_decl (void)
1057 if (!string_class_decl)
1059 if (!constant_string_global_id)
1060 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1061 string_class_decl = lookup_name (constant_string_global_id);
1065 /* Purpose: "play" parser, creating/installing representations
1066 of the declarations that are required by Objective-C.
1070 type_spec--------->sc_spec
1071 (tree_list) (tree_list)
1074 identifier_node identifier_node */
1077 synth_module_prologue (void)
1082 /* Defined in `objc.h' */
1083 objc_object_id = get_identifier (TAG_OBJECT);
1085 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1087 id_type = build_pointer_type (objc_object_reference);
1089 objc_id_id = get_identifier (TYPE_ID);
1090 objc_class_id = get_identifier (TAG_CLASS);
1092 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1093 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1094 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1096 /* Declare type of selector-objects that represent an operation name. */
1098 /* `struct objc_selector *' */
1100 = build_pointer_type (xref_tag (RECORD_TYPE,
1101 get_identifier (TAG_SELECTOR)));
1103 /* Forward declare type, or else the prototype for msgSendSuper will
1106 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1107 get_identifier (TAG_SUPER)));
1110 /* id objc_msgSend (id, SEL, ...); */
1113 = build_function_type (id_type,
1114 tree_cons (NULL_TREE, id_type,
1115 tree_cons (NULL_TREE, selector_type,
1118 if (! flag_next_runtime)
1120 umsg_decl = build_decl (FUNCTION_DECL,
1121 get_identifier (TAG_MSGSEND), temp_type);
1122 DECL_EXTERNAL (umsg_decl) = 1;
1123 TREE_PUBLIC (umsg_decl) = 1;
1124 DECL_INLINE (umsg_decl) = 1;
1125 DECL_ARTIFICIAL (umsg_decl) = 1;
1127 make_decl_rtl (umsg_decl, NULL);
1128 pushdecl (umsg_decl);
1131 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
1134 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1137 = build_function_type (id_type,
1138 tree_cons (NULL_TREE, super_p,
1139 tree_cons (NULL_TREE, selector_type,
1142 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1143 temp_type, 0, NOT_BUILT_IN,
1146 /* id objc_getClass (const char *); */
1148 temp_type = build_function_type (id_type,
1149 tree_cons (NULL_TREE,
1150 const_string_type_node,
1151 tree_cons (NULL_TREE, void_type_node,
1155 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1158 /* id objc_getMetaClass (const char *); */
1160 objc_get_meta_class_decl
1161 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
1164 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1166 if (! flag_next_runtime)
1168 if (flag_typed_selectors)
1170 /* Suppress outputting debug symbols, because
1171 dbxout_init hasn'r been called yet. */
1172 enum debug_info_type save_write_symbols = write_symbols;
1173 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1174 write_symbols = NO_DEBUG;
1175 debug_hooks = &do_nothing_debug_hooks;
1177 build_selector_template ();
1178 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1180 write_symbols = save_write_symbols;
1181 debug_hooks = save_hooks;
1184 temp_type = build_array_type (selector_type, NULL_TREE);
1186 layout_type (temp_type);
1187 UOBJC_SELECTOR_TABLE_decl
1188 = create_builtin_decl (VAR_DECL, temp_type,
1189 "_OBJC_SELECTOR_TABLE");
1191 /* Avoid warning when not sending messages. */
1192 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1195 generate_forward_declaration_to_string_table ();
1197 /* Forward declare constant_string_id and constant_string_type. */
1198 if (!constant_string_class_name)
1199 constant_string_class_name = default_constant_string_class_name;
1201 constant_string_id = get_identifier (constant_string_class_name);
1202 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1205 /* Predefine the following data type:
1207 struct STRING_OBJECT_CLASS_NAME
1211 unsigned int length;
1215 build_string_class_template (void)
1217 tree field_decl, field_decl_chain;
1219 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1220 field_decl_chain = field_decl;
1222 field_decl = create_builtin_decl (FIELD_DECL,
1223 build_pointer_type (char_type_node),
1225 chainon (field_decl_chain, field_decl);
1227 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1228 chainon (field_decl_chain, field_decl);
1230 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1233 /* Custom build_string which sets TREE_TYPE! */
1236 my_build_string (int len, const char *str)
1238 return fix_string_type (build_string (len, str));
1241 /* Build a static instance of NXConstantString which points at the
1242 string constant STRING.
1243 We place the string object in the __string_objects section of the
1244 __OBJC segment. The Objective-C runtime will initialize the isa
1245 pointers of the string objects to point at the NXConstantString
1249 build_objc_string_object (tree string)
1251 tree initlist, constructor;
1254 if (lookup_interface (constant_string_id) == NULL_TREE)
1256 error ("cannot find interface declaration for `%s'",
1257 IDENTIFIER_POINTER (constant_string_id));
1258 return error_mark_node;
1261 add_class_reference (constant_string_id);
1263 length = TREE_STRING_LENGTH (string) - 1;
1265 /* We could not properly create NXConstantString in synth_module_prologue,
1266 because that's called before debugging is initialized. Do it now. */
1267 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1268 build_string_class_template ();
1270 /* & ((NXConstantString) { NULL, string, length }) */
1272 if (flag_next_runtime)
1274 /* For the NeXT runtime, we can generate a literal reference
1275 to the string class, don't need to run a constructor. */
1276 setup_string_decl ();
1277 if (string_class_decl == NULL_TREE)
1279 error ("cannot find reference tag for class `%s'",
1280 IDENTIFIER_POINTER (constant_string_id));
1281 return error_mark_node;
1283 initlist = build_tree_list
1285 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1289 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1293 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1295 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1296 constructor = objc_build_constructor (constant_string_type,
1297 nreverse (initlist));
1299 if (!flag_next_runtime)
1302 = objc_add_static_instance (constructor, constant_string_type);
1305 return (build_unary_op (ADDR_EXPR, constructor, 1));
1308 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1310 static GTY(()) int num_static_inst;
1312 objc_add_static_instance (tree constructor, tree class_decl)
1317 /* Find the list of static instances for the CLASS_DECL. Create one if
1319 for (chain = &objc_static_instances;
1320 *chain && TREE_VALUE (*chain) != class_decl;
1321 chain = &TREE_CHAIN (*chain));
1324 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1325 add_objc_string (TYPE_NAME (class_decl), class_names);
1328 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1329 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1330 DECL_COMMON (decl) = 1;
1331 TREE_STATIC (decl) = 1;
1332 DECL_ARTIFICIAL (decl) = 1;
1333 DECL_INITIAL (decl) = constructor;
1335 /* We may be writing something else just now.
1336 Postpone till end of input. */
1337 DECL_DEFER_OUTPUT (decl) = 1;
1338 pushdecl_top_level (decl);
1339 rest_of_decl_compilation (decl, 0, 1, 0);
1341 /* Add the DECL to the head of this CLASS' list. */
1342 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1347 /* Build a static constant CONSTRUCTOR
1348 with type TYPE and elements ELTS. */
1351 objc_build_constructor (tree type, tree elts)
1353 tree constructor, f, e;
1355 /* ??? Most of the places that we build constructors, we don't fill in
1356 the type of integers properly. Convert them all en masse. */
1357 if (TREE_CODE (type) == ARRAY_TYPE)
1359 f = TREE_TYPE (type);
1360 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1361 for (e = elts; e ; e = TREE_CHAIN (e))
1362 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1366 f = TYPE_FIELDS (type);
1367 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1368 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1369 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1370 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1373 constructor = build_constructor (type, elts);
1374 TREE_CONSTANT (constructor) = 1;
1375 TREE_STATIC (constructor) = 1;
1376 TREE_READONLY (constructor) = 1;
1381 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1383 /* Predefine the following data type:
1391 void *defs[cls_def_cnt + cat_def_cnt];
1395 build_objc_symtab_template (void)
1397 tree field_decl, field_decl_chain, index;
1399 objc_symtab_template
1400 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1402 /* long sel_ref_cnt; */
1404 field_decl = create_builtin_decl (FIELD_DECL,
1405 long_integer_type_node,
1407 field_decl_chain = field_decl;
1411 field_decl = create_builtin_decl (FIELD_DECL,
1412 build_pointer_type (selector_type),
1414 chainon (field_decl_chain, field_decl);
1416 /* short cls_def_cnt; */
1418 field_decl = create_builtin_decl (FIELD_DECL,
1419 short_integer_type_node,
1421 chainon (field_decl_chain, field_decl);
1423 /* short cat_def_cnt; */
1425 field_decl = create_builtin_decl (FIELD_DECL,
1426 short_integer_type_node,
1428 chainon (field_decl_chain, field_decl);
1430 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1432 if (!flag_next_runtime)
1433 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1435 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1436 imp_count == 0 && cat_count == 0
1438 field_decl = create_builtin_decl (FIELD_DECL,
1439 build_array_type (ptr_type_node, index),
1441 chainon (field_decl_chain, field_decl);
1443 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1446 /* Create the initial value for the `defs' field of _objc_symtab.
1447 This is a CONSTRUCTOR. */
1450 init_def_list (tree type)
1452 tree expr, initlist = NULL_TREE;
1453 struct imp_entry *impent;
1456 for (impent = imp_list; impent; impent = impent->next)
1458 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1460 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1461 initlist = tree_cons (NULL_TREE, expr, initlist);
1466 for (impent = imp_list; impent; impent = impent->next)
1468 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1470 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1471 initlist = tree_cons (NULL_TREE, expr, initlist);
1475 if (!flag_next_runtime)
1477 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1480 if (static_instances_decl)
1481 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1483 expr = build_int_2 (0, 0);
1485 initlist = tree_cons (NULL_TREE, expr, initlist);
1488 return objc_build_constructor (type, nreverse (initlist));
1491 /* Construct the initial value for all of _objc_symtab. */
1494 init_objc_symtab (tree type)
1498 /* sel_ref_cnt = { ..., 5, ... } */
1500 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1502 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1504 if (flag_next_runtime || ! sel_ref_chain)
1505 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1507 initlist = tree_cons (NULL_TREE,
1508 build_unary_op (ADDR_EXPR,
1509 UOBJC_SELECTOR_TABLE_decl, 1),
1512 /* cls_def_cnt = { ..., 5, ... } */
1514 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1516 /* cat_def_cnt = { ..., 5, ... } */
1518 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1520 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1522 if (imp_count || cat_count || static_instances_decl)
1525 tree field = TYPE_FIELDS (type);
1526 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1528 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1532 return objc_build_constructor (type, nreverse (initlist));
1535 /* Push forward-declarations of all the categories so that
1536 init_def_list can use them in a CONSTRUCTOR. */
1539 forward_declare_categories (void)
1541 struct imp_entry *impent;
1542 tree sav = objc_implementation_context;
1544 for (impent = imp_list; impent; impent = impent->next)
1546 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1548 /* Set an invisible arg to synth_id_with_class_suffix. */
1549 objc_implementation_context = impent->imp_context;
1551 = create_builtin_decl (VAR_DECL, objc_category_template,
1552 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1553 TREE_PUBLIC (impent->class_decl) = 0;
1556 objc_implementation_context = sav;
1559 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1560 and initialized appropriately. */
1563 generate_objc_symtab_decl (void)
1567 if (!objc_category_template)
1568 build_category_template ();
1570 /* forward declare categories */
1572 forward_declare_categories ();
1574 if (!objc_symtab_template)
1575 build_objc_symtab_template ();
1577 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1579 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1580 tree_cons (NULL_TREE,
1581 objc_symtab_template, sc_spec),
1585 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1586 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1587 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1588 finish_decl (UOBJC_SYMBOLS_decl,
1589 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1594 init_module_descriptor (tree type)
1596 tree initlist, expr;
1598 /* version = { 1, ... } */
1600 expr = build_int_2 (OBJC_VERSION, 0);
1601 initlist = build_tree_list (NULL_TREE, expr);
1603 /* size = { ..., sizeof (struct objc_module), ... } */
1605 expr = size_in_bytes (objc_module_template);
1606 initlist = tree_cons (NULL_TREE, expr, initlist);
1608 /* name = { ..., "foo.m", ... } */
1610 expr = add_objc_string (get_identifier (input_filename), class_names);
1611 initlist = tree_cons (NULL_TREE, expr, initlist);
1613 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1615 if (UOBJC_SYMBOLS_decl)
1616 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1618 expr = build_int_2 (0, 0);
1619 initlist = tree_cons (NULL_TREE, expr, initlist);
1621 return objc_build_constructor (type, nreverse (initlist));
1624 /* Write out the data structures to describe Objective C classes defined.
1625 If appropriate, compile and output a setup function to initialize them.
1626 Return a symbol_ref to the function to call to initialize the Objective C
1627 data structures for this file (and perhaps for other files also).
1629 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1632 build_module_descriptor (void)
1634 tree decl_specs, field_decl, field_decl_chain;
1636 objc_module_template
1637 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1641 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1642 field_decl = get_identifier ("version");
1643 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1644 field_decl_chain = field_decl;
1648 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1649 field_decl = get_identifier ("size");
1650 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1651 chainon (field_decl_chain, field_decl);
1655 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1656 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1657 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1658 chainon (field_decl_chain, field_decl);
1660 /* struct objc_symtab *symtab; */
1662 decl_specs = get_identifier (UTAG_SYMTAB);
1663 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1664 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1665 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1666 chainon (field_decl_chain, field_decl);
1668 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1670 /* Create an instance of "objc_module". */
1672 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1673 build_tree_list (NULL_TREE,
1674 ridpointers[(int) RID_STATIC]));
1676 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1677 decl_specs, 1, NULL_TREE);
1679 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1680 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1681 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1683 finish_decl (UOBJC_MODULES_decl,
1684 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1687 /* Mark the decl to avoid "defined but not used" warning. */
1688 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1690 /* Generate a constructor call for the module descriptor.
1691 This code was generated by reading the grammar rules
1692 of c-parse.in; Therefore, it may not be the most efficient
1693 way of generating the requisite code. */
1695 if (flag_next_runtime)
1699 tree parms, execclass_decl, decelerator, void_list_node_1;
1700 tree init_function_name, init_function_decl;
1702 /* Declare void __objc_execClass (void *); */
1704 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1705 execclass_decl = build_decl (FUNCTION_DECL,
1706 get_identifier (TAG_EXECCLASS),
1707 build_function_type (void_type_node,
1708 tree_cons (NULL_TREE, ptr_type_node,
1709 void_list_node_1)));
1710 DECL_EXTERNAL (execclass_decl) = 1;
1711 DECL_ARTIFICIAL (execclass_decl) = 1;
1712 TREE_PUBLIC (execclass_decl) = 1;
1713 pushdecl (execclass_decl);
1714 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1715 assemble_external (execclass_decl);
1717 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1719 init_function_name = get_file_function_name ('I');
1720 start_function (void_list_node_1,
1721 build_nt (CALL_EXPR, init_function_name,
1722 tree_cons (NULL_TREE, NULL_TREE,
1726 store_parm_decls ();
1728 init_function_decl = current_function_decl;
1729 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1730 TREE_USED (init_function_decl) = 1;
1731 /* Don't let this one be deferred. */
1732 DECL_INLINE (init_function_decl) = 0;
1733 DECL_UNINLINABLE (init_function_decl) = 1;
1734 current_function_cannot_inline
1735 = "static constructors and destructors cannot be inlined";
1738 = build_tree_list (NULL_TREE,
1739 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1740 decelerator = build_function_call (execclass_decl, parms);
1742 c_expand_expr_stmt (decelerator);
1746 return XEXP (DECL_RTL (init_function_decl), 0);
1750 /* extern const char _OBJC_STRINGS[]; */
1753 generate_forward_declaration_to_string_table (void)
1755 tree sc_spec, decl_specs, expr_decl;
1757 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1758 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1761 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1763 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1766 /* Return the DECL of the string IDENT in the SECTION. */
1769 get_objc_string_decl (tree ident, enum string_section section)
1773 if (section == class_names)
1774 chain = class_names_chain;
1775 else if (section == meth_var_names)
1776 chain = meth_var_names_chain;
1777 else if (section == meth_var_types)
1778 chain = meth_var_types_chain;
1782 for (; chain != 0; chain = TREE_CHAIN (chain))
1783 if (TREE_VALUE (chain) == ident)
1784 return (TREE_PURPOSE (chain));
1790 /* Output references to all statically allocated objects. Return the DECL
1791 for the array built. */
1794 generate_static_references (void)
1796 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1797 tree class_name, class, decl, initlist;
1798 tree cl_chain, in_chain, type;
1799 int num_inst, num_class;
1802 if (flag_next_runtime)
1805 for (cl_chain = objc_static_instances, num_class = 0;
1806 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1808 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1809 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1811 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1812 ident = get_identifier (buf);
1814 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1815 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1816 build_tree_list (NULL_TREE,
1817 ridpointers[(int) RID_STATIC]));
1818 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1819 DECL_CONTEXT (decl) = 0;
1820 DECL_ARTIFICIAL (decl) = 1;
1822 /* Output {class_name, ...}. */
1823 class = TREE_VALUE (cl_chain);
1824 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1825 initlist = build_tree_list (NULL_TREE,
1826 build_unary_op (ADDR_EXPR, class_name, 1));
1828 /* Output {..., instance, ...}. */
1829 for (in_chain = TREE_PURPOSE (cl_chain);
1830 in_chain; in_chain = TREE_CHAIN (in_chain))
1832 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1833 initlist = tree_cons (NULL_TREE, expr, initlist);
1836 /* Output {..., NULL}. */
1837 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1839 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
1840 finish_decl (decl, expr, NULL_TREE);
1841 TREE_USED (decl) = 1;
1843 type = build_array_type (build_pointer_type (void_type_node), 0);
1844 decl = build_decl (VAR_DECL, ident, type);
1845 TREE_USED (decl) = 1;
1846 TREE_STATIC (decl) = 1;
1848 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1851 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1852 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1853 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1854 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1855 build_tree_list (NULL_TREE,
1856 ridpointers[(int) RID_STATIC]));
1857 static_instances_decl
1858 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1859 TREE_USED (static_instances_decl) = 1;
1860 DECL_CONTEXT (static_instances_decl) = 0;
1861 DECL_ARTIFICIAL (static_instances_decl) = 1;
1862 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
1864 finish_decl (static_instances_decl, expr, NULL_TREE);
1867 /* Output all strings. */
1870 generate_strings (void)
1872 tree sc_spec, decl_specs, expr_decl;
1873 tree chain, string_expr;
1876 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1878 string = TREE_VALUE (chain);
1879 decl = TREE_PURPOSE (chain);
1881 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1882 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1883 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1884 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1885 DECL_CONTEXT (decl) = NULL_TREE;
1886 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1887 IDENTIFIER_POINTER (string));
1888 finish_decl (decl, string_expr, NULL_TREE);
1891 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1893 string = TREE_VALUE (chain);
1894 decl = TREE_PURPOSE (chain);
1896 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1897 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1898 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1899 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1900 DECL_CONTEXT (decl) = NULL_TREE;
1901 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1902 IDENTIFIER_POINTER (string));
1903 finish_decl (decl, string_expr, NULL_TREE);
1906 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1908 string = TREE_VALUE (chain);
1909 decl = TREE_PURPOSE (chain);
1911 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1912 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1913 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1914 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1915 DECL_CONTEXT (decl) = NULL_TREE;
1916 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1917 IDENTIFIER_POINTER (string));
1918 finish_decl (decl, string_expr, NULL_TREE);
1922 static GTY(()) int selector_reference_idx;
1924 build_selector_reference_decl (void)
1929 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
1931 ident = get_identifier (buf);
1933 decl = build_decl (VAR_DECL, ident, selector_type);
1934 DECL_EXTERNAL (decl) = 1;
1935 TREE_PUBLIC (decl) = 0;
1936 TREE_USED (decl) = 1;
1937 TREE_READONLY (decl) = 1;
1938 DECL_ARTIFICIAL (decl) = 1;
1939 DECL_CONTEXT (decl) = 0;
1941 make_decl_rtl (decl, 0);
1942 pushdecl_top_level (decl);
1947 /* Just a handy wrapper for add_objc_string. */
1950 build_selector (tree ident)
1952 tree expr = add_objc_string (ident, meth_var_names);
1953 if (flag_typed_selectors)
1956 return build_c_cast (selector_type, expr); /* cast! */
1960 build_selector_translation_table (void)
1962 tree sc_spec, decl_specs;
1963 tree chain, initlist = NULL_TREE;
1965 tree decl = NULL_TREE, var_decl, name;
1967 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1971 if (warn_selector && objc_implementation_context)
1975 for (method_chain = meth_var_names_chain;
1977 method_chain = TREE_CHAIN (method_chain))
1979 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
1987 location_t loc = input_location;
1988 if (flag_next_runtime && TREE_PURPOSE (chain))
1989 loc = TREE_LOCUS (TREE_PURPOSE (chain));
1991 warning ("%Hcreating selector for non existant method %s",
1992 &loc, IDENTIFIER_POINTER (TREE_VALUE (chain)));
1996 expr = build_selector (TREE_VALUE (chain));
1998 if (flag_next_runtime)
2000 name = DECL_NAME (TREE_PURPOSE (chain));
2002 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2004 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2005 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2009 /* The `decl' that is returned from start_decl is the one that we
2010 forward declared in `build_selector_reference' */
2011 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2014 /* add one for the '\0' character */
2015 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2017 if (flag_next_runtime)
2018 finish_decl (decl, expr, NULL_TREE);
2021 if (flag_typed_selectors)
2023 tree eltlist = NULL_TREE;
2024 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2025 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2026 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2027 expr = objc_build_constructor (objc_selector_template,
2028 nreverse (eltlist));
2030 initlist = tree_cons (NULL_TREE, expr, initlist);
2035 if (! flag_next_runtime)
2037 /* Cause the variable and its initial value to be actually output. */
2038 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2039 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2040 /* NULL terminate the list and fix the decl for output. */
2041 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2042 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2043 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2044 nreverse (initlist));
2045 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2046 current_function_decl = NULL_TREE;
2051 get_proto_encoding (tree proto)
2058 if (! METHOD_ENCODING (proto))
2060 tmp_decl = build_tmp_function_decl ();
2061 hack_method_prototype (proto, tmp_decl);
2062 encoding = encode_method_prototype (proto, tmp_decl);
2063 METHOD_ENCODING (proto) = encoding;
2066 encoding = METHOD_ENCODING (proto);
2068 return add_objc_string (encoding, meth_var_types);
2071 return build_int_2 (0, 0);
2074 /* sel_ref_chain is a list whose "value" fields will be instances of
2075 identifier_node that represent the selector. */
2078 build_typed_selector_reference (tree ident, tree prototype)
2080 tree *chain = &sel_ref_chain;
2086 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2087 goto return_at_index;
2090 chain = &TREE_CHAIN (*chain);
2093 *chain = tree_cons (prototype, ident, NULL_TREE);
2096 expr = build_unary_op (ADDR_EXPR,
2097 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2098 build_int_2 (index, 0)),
2100 return build_c_cast (selector_type, expr);
2104 build_selector_reference (tree ident)
2106 tree *chain = &sel_ref_chain;
2112 if (TREE_VALUE (*chain) == ident)
2113 return (flag_next_runtime
2114 ? TREE_PURPOSE (*chain)
2115 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2116 build_int_2 (index, 0)));
2119 chain = &TREE_CHAIN (*chain);
2122 expr = build_selector_reference_decl ();
2124 *chain = tree_cons (expr, ident, NULL_TREE);
2126 return (flag_next_runtime
2128 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2129 build_int_2 (index, 0)));
2132 static GTY(()) int class_reference_idx;
2134 build_class_reference_decl (void)
2139 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2141 ident = get_identifier (buf);
2143 decl = build_decl (VAR_DECL, ident, objc_class_type);
2144 DECL_EXTERNAL (decl) = 1;
2145 TREE_PUBLIC (decl) = 0;
2146 TREE_USED (decl) = 1;
2147 TREE_READONLY (decl) = 1;
2148 DECL_CONTEXT (decl) = 0;
2149 DECL_ARTIFICIAL (decl) = 1;
2151 make_decl_rtl (decl, 0);
2152 pushdecl_top_level (decl);
2157 /* Create a class reference, but don't create a variable to reference
2161 add_class_reference (tree ident)
2165 if ((chain = cls_ref_chain))
2170 if (ident == TREE_VALUE (chain))
2174 chain = TREE_CHAIN (chain);
2178 /* Append to the end of the list */
2179 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2182 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2185 /* Get a class reference, creating it if necessary. Also create the
2186 reference variable. */
2189 get_class_reference (tree ident)
2191 if (flag_next_runtime)
2196 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2197 if (TREE_VALUE (*chain) == ident)
2199 if (! TREE_PURPOSE (*chain))
2200 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2202 return TREE_PURPOSE (*chain);
2205 decl = build_class_reference_decl ();
2206 *chain = tree_cons (decl, ident, NULL_TREE);
2213 add_class_reference (ident);
2215 params = build_tree_list (NULL_TREE,
2216 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2217 IDENTIFIER_POINTER (ident)));
2219 assemble_external (objc_get_class_decl);
2220 return build_function_call (objc_get_class_decl, params);
2224 /* For each string section we have a chain which maps identifier nodes
2225 to decls for the strings. */
2228 add_objc_string (tree ident, enum string_section section)
2232 if (section == class_names)
2233 chain = &class_names_chain;
2234 else if (section == meth_var_names)
2235 chain = &meth_var_names_chain;
2236 else if (section == meth_var_types)
2237 chain = &meth_var_types_chain;
2243 if (TREE_VALUE (*chain) == ident)
2244 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2246 chain = &TREE_CHAIN (*chain);
2249 decl = build_objc_string_decl (section);
2251 *chain = tree_cons (decl, ident, NULL_TREE);
2253 return build_unary_op (ADDR_EXPR, decl, 1);
2256 static GTY(()) int class_names_idx;
2257 static GTY(()) int meth_var_names_idx;
2258 static GTY(()) int meth_var_types_idx;
2261 build_objc_string_decl (enum string_section section)
2266 if (section == class_names)
2267 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2268 else if (section == meth_var_names)
2269 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2270 else if (section == meth_var_types)
2271 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2273 ident = get_identifier (buf);
2275 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2276 DECL_EXTERNAL (decl) = 1;
2277 TREE_PUBLIC (decl) = 0;
2278 TREE_USED (decl) = 1;
2279 TREE_READONLY (decl) = 1;
2280 TREE_CONSTANT (decl) = 1;
2281 DECL_CONTEXT (decl) = 0;
2282 DECL_ARTIFICIAL (decl) = 1;
2284 make_decl_rtl (decl, 0);
2285 pushdecl_top_level (decl);
2292 objc_declare_alias (tree alias_ident, tree class_ident)
2294 if (is_class_name (class_ident) != class_ident)
2295 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2296 else if (is_class_name (alias_ident))
2297 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2299 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2303 objc_declare_class (tree ident_list)
2307 for (list = ident_list; list; list = TREE_CHAIN (list))
2309 tree ident = TREE_VALUE (list);
2312 if ((decl = lookup_name (ident)))
2314 error ("`%s' redeclared as different kind of symbol",
2315 IDENTIFIER_POINTER (ident));
2316 error ("%Jprevious declaration of '%D'", decl, decl);
2319 if (! is_class_name (ident))
2321 tree record = xref_tag (RECORD_TYPE, ident);
2322 TREE_STATIC_TEMPLATE (record) = 1;
2323 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2329 is_class_name (tree ident)
2333 if (lookup_interface (ident))
2336 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2338 if (ident == TREE_VALUE (chain))
2342 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2344 if (ident == TREE_VALUE (chain))
2345 return TREE_PURPOSE (chain);
2352 objc_is_id (tree ident)
2354 /* NB: This function may be called before the ObjC front-end
2355 has been initialized, in which case ID_TYPE will be NULL. */
2356 return (id_type && ident && TYPE_P (ident) && IS_ID (ident))
2362 lookup_interface (tree ident)
2366 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2368 if (ident == CLASS_NAME (chain))
2374 /* Used by: build_private_template, continue_class,
2375 and for @defs constructs. */
2378 get_class_ivars (tree interface)
2380 tree my_name, super_name, ivar_chain;
2382 my_name = CLASS_NAME (interface);
2383 super_name = CLASS_SUPER_NAME (interface);
2384 ivar_chain = CLASS_IVARS (interface);
2386 /* Save off a pristine copy of the leaf ivars (i.e, those not
2387 inherited from a super class). */
2388 if (!CLASS_OWN_IVARS (interface))
2389 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2394 tree super_interface = lookup_interface (super_name);
2396 if (!super_interface)
2398 /* fatal did not work with 2 args...should fix */
2399 error ("cannot find interface declaration for `%s', superclass of `%s'",
2400 IDENTIFIER_POINTER (super_name),
2401 IDENTIFIER_POINTER (my_name));
2402 exit (FATAL_EXIT_CODE);
2405 if (super_interface == interface)
2406 fatal_error ("circular inheritance in interface declaration for `%s'",
2407 IDENTIFIER_POINTER (super_name));
2409 interface = super_interface;
2410 my_name = CLASS_NAME (interface);
2411 super_name = CLASS_SUPER_NAME (interface);
2413 op1 = CLASS_OWN_IVARS (interface);
2416 tree head = copy_list (op1);
2418 /* Prepend super class ivars...make a copy of the list, we
2419 do not want to alter the original. */
2420 chainon (head, ivar_chain);
2427 /* struct <classname> {
2428 struct objc_class *isa;
2433 build_private_template (tree class)
2437 if (CLASS_STATIC_TEMPLATE (class))
2439 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2440 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2444 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2446 ivar_context = get_class_ivars (class);
2448 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2450 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2452 /* mark this record as class template - for class type checking */
2453 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2457 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2459 build1 (INDIRECT_REF, NULL_TREE,
2462 return ivar_context;
2465 /* Begin code generation for protocols... */
2467 /* struct objc_protocol {
2468 char *protocol_name;
2469 struct objc_protocol **protocol_list;
2470 struct objc_method_desc *instance_methods;
2471 struct objc_method_desc *class_methods;
2475 build_protocol_template (void)
2477 tree decl_specs, field_decl, field_decl_chain;
2480 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2482 /* struct objc_class *isa; */
2484 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2485 get_identifier (UTAG_CLASS)));
2486 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2487 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2488 field_decl_chain = field_decl;
2490 /* char *protocol_name; */
2492 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2494 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2495 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2496 chainon (field_decl_chain, field_decl);
2498 /* struct objc_protocol **protocol_list; */
2500 decl_specs = build_tree_list (NULL_TREE, template);
2502 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2503 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2504 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2505 chainon (field_decl_chain, field_decl);
2507 /* struct objc_method_list *instance_methods; */
2510 = build_tree_list (NULL_TREE,
2511 xref_tag (RECORD_TYPE,
2512 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2514 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2515 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2516 chainon (field_decl_chain, field_decl);
2518 /* struct objc_method_list *class_methods; */
2521 = build_tree_list (NULL_TREE,
2522 xref_tag (RECORD_TYPE,
2523 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2525 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2526 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2527 chainon (field_decl_chain, field_decl);
2529 return finish_struct (template, field_decl_chain, NULL_TREE);
2533 build_descriptor_table_initializer (tree type, tree entries)
2535 tree initlist = NULL_TREE;
2539 tree eltlist = NULL_TREE;
2542 = tree_cons (NULL_TREE,
2543 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2545 = tree_cons (NULL_TREE,
2546 add_objc_string (METHOD_ENCODING (entries),
2551 = tree_cons (NULL_TREE,
2552 objc_build_constructor (type, nreverse (eltlist)),
2555 entries = TREE_CHAIN (entries);
2559 return objc_build_constructor (build_array_type (type, 0),
2560 nreverse (initlist));
2563 /* struct objc_method_prototype_list {
2565 struct objc_method_prototype {
2572 build_method_prototype_list_template (tree list_type, int size)
2574 tree objc_ivar_list_record;
2575 tree decl_specs, field_decl, field_decl_chain;
2577 /* Generate an unnamed struct definition. */
2579 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2581 /* int method_count; */
2583 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2584 field_decl = get_identifier ("method_count");
2585 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2586 field_decl_chain = field_decl;
2588 /* struct objc_method method_list[]; */
2590 decl_specs = build_tree_list (NULL_TREE, list_type);
2591 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2592 build_int_2 (size, 0));
2593 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2594 chainon (field_decl_chain, field_decl);
2596 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2598 return objc_ivar_list_record;
2602 build_method_prototype_template (void)
2605 tree decl_specs, field_decl, field_decl_chain;
2608 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2610 /* struct objc_selector *_cmd; */
2611 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2612 get_identifier (TAG_SELECTOR)), NULL_TREE);
2613 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2614 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2615 field_decl_chain = field_decl;
2617 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2619 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2620 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2621 chainon (field_decl_chain, field_decl);
2623 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2625 return proto_record;
2628 /* True if last call to forwarding_offset yielded a register offset. */
2629 static int offset_is_register;
2632 forwarding_offset (tree parm)
2634 int offset_in_bytes;
2636 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2638 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2640 /* ??? Here we assume that the parm address is indexed
2641 off the frame pointer or arg pointer.
2642 If that is not true, we produce meaningless results,
2643 but do not crash. */
2644 if (GET_CODE (addr) == PLUS
2645 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2646 offset_in_bytes = INTVAL (XEXP (addr, 1));
2648 offset_in_bytes = 0;
2650 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2651 offset_is_register = 0;
2653 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2655 int regno = REGNO (DECL_INCOMING_RTL (parm));
2656 offset_in_bytes = apply_args_register_offset (regno);
2657 offset_is_register = 1;
2662 /* This is the case where the parm is passed as an int or double
2663 and it is converted to a char, short or float and stored back
2664 in the parmlist. In this case, describe the parm
2665 with the variable's declared type, and adjust the address
2666 if the least significant bytes (which we are using) are not
2668 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2669 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2670 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2672 return offset_in_bytes;
2676 encode_method_prototype (tree method_decl, tree func_decl)
2681 HOST_WIDE_INT max_parm_end = 0;
2685 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2686 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2689 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2690 obstack_object_size (&util_obstack),
2691 OBJC_ENCODE_INLINE_DEFS);
2694 for (parms = DECL_ARGUMENTS (func_decl); parms;
2695 parms = TREE_CHAIN (parms))
2697 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2698 + int_size_in_bytes (TREE_TYPE (parms)));
2700 if (!offset_is_register && max_parm_end < parm_end)
2701 max_parm_end = parm_end;
2704 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2706 sprintf (buf, "%d", stack_size);
2707 obstack_grow (&util_obstack, buf, strlen (buf));
2709 user_args = METHOD_SEL_ARGS (method_decl);
2711 /* Argument types. */
2712 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2713 parms = TREE_CHAIN (parms), i++)
2715 /* Process argument qualifiers for user supplied arguments. */
2718 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2719 user_args = TREE_CHAIN (user_args);
2723 encode_type (TREE_TYPE (parms),
2724 obstack_object_size (&util_obstack),
2725 OBJC_ENCODE_INLINE_DEFS);
2727 /* Compute offset. */
2728 sprintf (buf, "%d", forwarding_offset (parms));
2730 /* Indicate register. */
2731 if (offset_is_register)
2732 obstack_1grow (&util_obstack, '+');
2734 obstack_grow (&util_obstack, buf, strlen (buf));
2737 obstack_1grow (&util_obstack, '\0');
2738 result = get_identifier (obstack_finish (&util_obstack));
2739 obstack_free (&util_obstack, util_firstobj);
2744 generate_descriptor_table (tree type, const char *name, int size, tree list,
2747 tree sc_spec, decl_specs, decl, initlist;
2749 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2750 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2752 decl = start_decl (synth_id_with_class_suffix (name, proto),
2753 decl_specs, 1, NULL_TREE);
2754 DECL_CONTEXT (decl) = NULL_TREE;
2756 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2757 initlist = tree_cons (NULL_TREE, list, initlist);
2759 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
2766 generate_method_descriptors (tree protocol)
2768 tree initlist, chain, method_list_template;
2769 tree cast, variable_length_type;
2772 if (!objc_method_prototype_template)
2773 objc_method_prototype_template = build_method_prototype_template ();
2775 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2776 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2778 variable_length_type = groktypename (cast);
2780 chain = PROTOCOL_CLS_METHODS (protocol);
2783 size = list_length (chain);
2785 method_list_template
2786 = build_method_prototype_list_template (objc_method_prototype_template,
2790 = build_descriptor_table_initializer (objc_method_prototype_template,
2793 UOBJC_CLASS_METHODS_decl
2794 = generate_descriptor_table (method_list_template,
2795 "_OBJC_PROTOCOL_CLASS_METHODS",
2796 size, initlist, protocol);
2797 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2800 UOBJC_CLASS_METHODS_decl = 0;
2802 chain = PROTOCOL_NST_METHODS (protocol);
2805 size = list_length (chain);
2807 method_list_template
2808 = build_method_prototype_list_template (objc_method_prototype_template,
2811 = build_descriptor_table_initializer (objc_method_prototype_template,
2814 UOBJC_INSTANCE_METHODS_decl
2815 = generate_descriptor_table (method_list_template,
2816 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2817 size, initlist, protocol);
2818 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2821 UOBJC_INSTANCE_METHODS_decl = 0;
2824 /* Generate a temporary FUNCTION_DECL node to be used in
2825 hack_method_prototype below. */
2827 static GTY(()) int build_tmp_function_decl_xxx;
2829 build_tmp_function_decl (void)
2831 tree decl_specs, expr_decl, parms;
2835 /* struct objc_object *objc_xxx (id, SEL, ...); */
2837 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2838 push_parm_decl (build_tree_list
2839 (build_tree_list (decl_specs,
2840 build1 (INDIRECT_REF, NULL_TREE,
2844 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2845 get_identifier (TAG_SELECTOR)));
2846 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2848 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2850 parms = get_parm_info (0);
2853 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2854 sprintf (buffer, "__objc_tmp_%x", build_tmp_function_decl_xxx++);
2855 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2856 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2858 tmp_decl = define_decl (expr_decl, decl_specs);
2863 /* Generate the prototypes for protocol methods. This is used to
2864 generate method encodings for these.
2866 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2867 a decl node to be used. This is also where the return value is
2871 hack_method_prototype (tree nst_methods, tree tmp_decl)
2876 /* Hack to avoid problem with static typing of self arg. */
2877 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2878 start_method_def (nst_methods);
2879 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2881 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2882 parms = get_parm_info (0); /* we have a `, ...' */
2884 parms = get_parm_info (1); /* place a `void_at_end' */
2886 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2888 /* Usually called from store_parm_decls -> init_function_start. */
2890 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2892 if (current_function_decl)
2894 current_function_decl = tmp_decl;
2897 /* Code taken from start_function. */
2898 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2899 /* Promote the value to int before returning it. */
2900 if (TREE_CODE (restype) == INTEGER_TYPE
2901 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2902 restype = integer_type_node;
2903 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2906 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2907 DECL_CONTEXT (parm) = tmp_decl;
2909 init_function_start (tmp_decl);
2911 /* Typically called from expand_function_start for function definitions. */
2912 assign_parms (tmp_decl);
2914 /* install return type */
2915 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2917 current_function_decl = NULL;
2921 generate_protocol_references (tree plist)
2925 /* Forward declare protocols referenced. */
2926 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2928 tree proto = TREE_VALUE (lproto);
2930 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2931 && PROTOCOL_NAME (proto))
2933 if (! PROTOCOL_FORWARD_DECL (proto))
2934 build_protocol_reference (proto);
2936 if (PROTOCOL_LIST (proto))
2937 generate_protocol_references (PROTOCOL_LIST (proto));
2942 /* For each protocol which was referenced either from a @protocol()
2943 expression, or because a class/category implements it (then a
2944 pointer to the protocol is stored in the struct describing the
2945 class/category), we create a statically allocated instance of the
2946 Protocol class. The code is written in such a way as to generate
2947 as few Protocol objects as possible; we generate a unique Protocol
2948 instance for each protocol, and we don't generate a Protocol
2949 instance if the protocol is never referenced (either from a
2950 @protocol() or from a class/category implementation). These
2951 statically allocated objects can be referred to via the static
2952 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
2954 The statically allocated Protocol objects that we generate here
2955 need to be fixed up at runtime in order to be used: the 'isa'
2956 pointer of the objects need to be set up to point to the 'Protocol'
2957 class, as known at runtime.
2959 The NeXT runtime fixes up all protocols at program startup time,
2960 before main() is entered. It uses a low-level trick to look up all
2961 those symbols, then loops on them and fixes them up.
2963 The GNU runtime as well fixes up all protocols before user code
2964 from the module is executed; it requires pointers to those symbols
2965 to be put in the objc_symtab (which is then passed as argument to
2966 the function __objc_exec_class() which the compiler sets up to be
2967 executed automatically when the module is loaded); setup of those
2968 Protocol objects happen in two ways in the GNU runtime: all
2969 Protocol objects referred to by a class or category implementation
2970 are fixed up when the class/category is loaded; all Protocol
2971 objects referred to by a @protocol() expression are added by the
2972 compiler to the list of statically allocated instances to fixup
2973 (the same list holding the statically allocated constant string
2974 objects). Because, as explained above, the compiler generates as
2975 few Protocol objects as possible, some Protocol object might end up
2976 being referenced multiple times when compiled with the GNU runtime,
2977 and end up being fixed up multiple times at runtime inizialization.
2978 But that doesn't hurt, it's just a little inefficient. */
2980 generate_protocols (void)
2982 tree p, tmp_decl, encoding;
2983 tree sc_spec, decl_specs, decl;
2984 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2987 tmp_decl = build_tmp_function_decl ();
2989 if (! objc_protocol_template)
2990 objc_protocol_template = build_protocol_template ();
2992 /* If a protocol was directly referenced, pull in indirect references. */
2993 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2994 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2995 generate_protocol_references (PROTOCOL_LIST (p));
2997 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2999 tree nst_methods = PROTOCOL_NST_METHODS (p);
3000 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3002 /* If protocol wasn't referenced, don't generate any code. */
3003 if (! PROTOCOL_FORWARD_DECL (p))
3006 /* Make sure we link in the Protocol class. */
3007 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3011 if (! METHOD_ENCODING (nst_methods))
3013 hack_method_prototype (nst_methods, tmp_decl);
3014 encoding = encode_method_prototype (nst_methods, tmp_decl);
3015 METHOD_ENCODING (nst_methods) = encoding;
3017 nst_methods = TREE_CHAIN (nst_methods);
3022 if (! METHOD_ENCODING (cls_methods))
3024 hack_method_prototype (cls_methods, tmp_decl);
3025 encoding = encode_method_prototype (cls_methods, tmp_decl);
3026 METHOD_ENCODING (cls_methods) = encoding;
3029 cls_methods = TREE_CHAIN (cls_methods);
3031 generate_method_descriptors (p);
3033 if (PROTOCOL_LIST (p))
3034 refs_decl = generate_protocol_list (p);
3038 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3040 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3042 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3044 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3045 decl_specs, 1, NULL_TREE);
3047 DECL_CONTEXT (decl) = NULL_TREE;
3049 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3055 (build_tree_list (build_tree_list (NULL_TREE,
3056 objc_protocol_template),
3057 build1 (INDIRECT_REF, NULL_TREE,
3058 build1 (INDIRECT_REF, NULL_TREE,
3061 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3062 TREE_TYPE (refs_expr) = cast_type2;
3065 refs_expr = build_int_2 (0, 0);
3067 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3068 by generate_method_descriptors, which is called above. */
3069 initlist = build_protocol_initializer (TREE_TYPE (decl),
3070 protocol_name_expr, refs_expr,
3071 UOBJC_INSTANCE_METHODS_decl,
3072 UOBJC_CLASS_METHODS_decl);
3073 finish_decl (decl, initlist, NULL_TREE);
3075 /* Mark the decl as used to avoid "defined but not used" warning. */
3076 TREE_USED (decl) = 1;
3081 build_protocol_initializer (tree type, tree protocol_name,
3082 tree protocol_list, tree instance_methods,
3085 tree initlist = NULL_TREE, expr;
3088 cast_type = groktypename
3090 (build_tree_list (NULL_TREE,
3091 xref_tag (RECORD_TYPE,
3092 get_identifier (UTAG_CLASS))),
3093 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3095 /* Filling the "isa" in with one allows the runtime system to
3096 detect that the version change...should remove before final release. */
3098 expr = build_int_2 (PROTOCOL_VERSION, 0);
3099 TREE_TYPE (expr) = cast_type;
3100 initlist = tree_cons (NULL_TREE, expr, initlist);
3101 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3102 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3104 if (!instance_methods)
3105 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3108 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3109 initlist = tree_cons (NULL_TREE, expr, initlist);
3113 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3116 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3117 initlist = tree_cons (NULL_TREE, expr, initlist);
3120 return objc_build_constructor (type, nreverse (initlist));
3123 /* struct objc_category {
3124 char *category_name;
3126 struct objc_method_list *instance_methods;
3127 struct objc_method_list *class_methods;
3128 struct objc_protocol_list *protocols;
3132 build_category_template (void)
3134 tree decl_specs, field_decl, field_decl_chain;
3136 objc_category_template = start_struct (RECORD_TYPE,
3137 get_identifier (UTAG_CATEGORY));
3138 /* char *category_name; */
3140 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3142 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3143 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3144 field_decl_chain = field_decl;
3146 /* char *class_name; */
3148 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3149 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3150 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3151 chainon (field_decl_chain, field_decl);
3153 /* struct objc_method_list *instance_methods; */
3155 decl_specs = build_tree_list (NULL_TREE,
3156 xref_tag (RECORD_TYPE,
3157 get_identifier (UTAG_METHOD_LIST)));
3159 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3160 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3161 chainon (field_decl_chain, field_decl);
3163 /* struct objc_method_list *class_methods; */
3165 decl_specs = build_tree_list (NULL_TREE,
3166 xref_tag (RECORD_TYPE,
3167 get_identifier (UTAG_METHOD_LIST)));
3169 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3170 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3171 chainon (field_decl_chain, field_decl);
3173 /* struct objc_protocol **protocol_list; */
3175 decl_specs = build_tree_list (NULL_TREE,
3176 xref_tag (RECORD_TYPE,
3177 get_identifier (UTAG_PROTOCOL)));
3179 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3180 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3181 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3182 chainon (field_decl_chain, field_decl);
3184 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3187 /* struct objc_selector {
3193 build_selector_template (void)
3196 tree decl_specs, field_decl, field_decl_chain;
3198 objc_selector_template
3199 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3203 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3204 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3205 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3206 field_decl_chain = field_decl;
3208 /* char *sel_type; */
3210 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3211 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3212 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3213 chainon (field_decl_chain, field_decl);
3215 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3218 /* struct objc_class {
3219 struct objc_class *isa;
3220 struct objc_class *super_class;
3225 struct objc_ivar_list *ivars;
3226 struct objc_method_list *methods;
3227 if (flag_next_runtime)
3228 struct objc_cache *cache;
3230 struct sarray *dtable;
3231 struct objc_class *subclass_list;
3232 struct objc_class *sibling_class;
3234 struct objc_protocol_list *protocols;
3235 void *gc_object_type;
3239 build_class_template (void)
3241 tree decl_specs, field_decl, field_decl_chain;
3244 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3246 /* struct objc_class *isa; */
3248 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3249 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3250 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3251 field_decl_chain = field_decl;
3253 /* struct objc_class *super_class; */
3255 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3257 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3258 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3259 chainon (field_decl_chain, field_decl);
3263 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3264 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3265 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3266 chainon (field_decl_chain, field_decl);
3270 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3271 field_decl = get_identifier ("version");
3272 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3273 chainon (field_decl_chain, field_decl);
3277 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3278 field_decl = get_identifier ("info");
3279 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3280 chainon (field_decl_chain, field_decl);
3282 /* long instance_size; */
3284 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3285 field_decl = get_identifier ("instance_size");
3286 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3287 chainon (field_decl_chain, field_decl);
3289 /* struct objc_ivar_list *ivars; */
3291 decl_specs = build_tree_list (NULL_TREE,
3292 xref_tag (RECORD_TYPE,
3293 get_identifier (UTAG_IVAR_LIST)));
3294 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3295 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3296 chainon (field_decl_chain, field_decl);
3298 /* struct objc_method_list *methods; */
3300 decl_specs = build_tree_list (NULL_TREE,
3301 xref_tag (RECORD_TYPE,
3302 get_identifier (UTAG_METHOD_LIST)));
3303 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3304 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3305 chainon (field_decl_chain, field_decl);
3307 if (flag_next_runtime)
3309 /* struct objc_cache *cache; */
3311 decl_specs = build_tree_list (NULL_TREE,
3312 xref_tag (RECORD_TYPE,
3313 get_identifier ("objc_cache")));
3314 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3315 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3316 chainon (field_decl_chain, field_decl);
3320 /* struct sarray *dtable; */
3322 decl_specs = build_tree_list (NULL_TREE,
3323 xref_tag (RECORD_TYPE,
3324 get_identifier ("sarray")));
3325 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3326 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3327 chainon (field_decl_chain, field_decl);
3329 /* struct objc_class *subclass_list; */
3331 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3333 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3334 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3335 chainon (field_decl_chain, field_decl);
3337 /* struct objc_class *sibling_class; */
3339 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3341 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3342 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3343 chainon (field_decl_chain, field_decl);
3346 /* struct objc_protocol **protocol_list; */
3348 decl_specs = build_tree_list (NULL_TREE,
3349 xref_tag (RECORD_TYPE,
3350 get_identifier (UTAG_PROTOCOL)));
3352 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3354 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3355 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3356 chainon (field_decl_chain, field_decl);
3360 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3361 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3362 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3363 chainon (field_decl_chain, field_decl);
3365 /* void *gc_object_type; */
3367 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3368 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3369 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3370 chainon (field_decl_chain, field_decl);
3372 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3375 /* Generate appropriate forward declarations for an implementation. */
3378 synth_forward_declarations (void)
3380 tree sc_spec, decl_specs, an_id;
3382 /* static struct objc_class _OBJC_CLASS_<my_name>; */
3384 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3386 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3387 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3388 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3389 TREE_USED (UOBJC_CLASS_decl) = 1;
3390 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3391 TREE_PUBLIC (UOBJC_CLASS_decl) = 0;
3393 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
3395 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3396 objc_implementation_context);
3398 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3399 TREE_USED (UOBJC_METACLASS_decl) = 1;
3400 DECL_ARTIFICIAL (UOBJC_METACLASS_decl) = 1;
3401 TREE_PUBLIC (UOBJC_METACLASS_decl) = 0;
3403 /* Pre-build the following entities - for speed/convenience. */
3405 an_id = get_identifier ("super_class");
3406 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3407 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3411 error_with_ivar (const char *message, tree decl, tree rawdecl)
3413 error ("%J%s `%s'", decl, message, gen_declaration (rawdecl, errbuf));
3417 check_ivars (tree inter, tree imp)
3419 tree intdecls = CLASS_IVARS (inter);
3420 tree impdecls = CLASS_IVARS (imp);
3421 tree rawintdecls = CLASS_RAW_IVARS (inter);
3422 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3428 if (intdecls == 0 && impdecls == 0)
3430 if (intdecls == 0 || impdecls == 0)
3432 error ("inconsistent instance variable specification");
3436 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3438 if (!comptypes (t1, t2, false))
3440 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3442 error_with_ivar ("conflicting instance variable type",
3443 impdecls, rawimpdecls);
3444 error_with_ivar ("previous declaration of",
3445 intdecls, rawintdecls);
3447 else /* both the type and the name don't match */
3449 error ("inconsistent instance variable specification");
3454 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3456 error_with_ivar ("conflicting instance variable name",
3457 impdecls, rawimpdecls);
3458 error_with_ivar ("previous declaration of",
3459 intdecls, rawintdecls);
3462 intdecls = TREE_CHAIN (intdecls);
3463 impdecls = TREE_CHAIN (impdecls);
3464 rawintdecls = TREE_CHAIN (rawintdecls);
3465 rawimpdecls = TREE_CHAIN (rawimpdecls);
3469 /* Set super_type to the data type node for struct objc_super *,
3470 first defining struct objc_super itself.
3471 This needs to be done just once per compilation. */
3474 build_super_template (void)
3476 tree record, decl_specs, field_decl, field_decl_chain;
3478 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3480 /* struct objc_object *self; */
3482 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3483 field_decl = get_identifier ("self");
3484 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3485 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3486 field_decl_chain = field_decl;
3488 /* struct objc_class *class; */
3490 decl_specs = get_identifier (UTAG_CLASS);
3491 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3492 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3494 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3495 chainon (field_decl_chain, field_decl);
3497 finish_struct (record, field_decl_chain, NULL_TREE);
3499 /* `struct objc_super *' */
3500 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3502 build1 (INDIRECT_REF,
3503 NULL_TREE, NULL_TREE)));
3507 /* struct objc_ivar {
3514 build_ivar_template (void)
3516 tree objc_ivar_id, objc_ivar_record;
3517 tree decl_specs, field_decl, field_decl_chain;
3519 objc_ivar_id = get_identifier (UTAG_IVAR);
3520 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3522 /* char *ivar_name; */
3524 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3525 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3527 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3528 field_decl_chain = field_decl;
3530 /* char *ivar_type; */
3532 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3533 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3535 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3536 chainon (field_decl_chain, field_decl);
3538 /* int ivar_offset; */
3540 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3541 field_decl = get_identifier ("ivar_offset");
3543 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3544 chainon (field_decl_chain, field_decl);
3546 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3548 return objc_ivar_record;
3553 struct objc_ivar ivar_list[ivar_count];
3557 build_ivar_list_template (tree list_type, int size)
3559 tree objc_ivar_list_record;
3560 tree decl_specs, field_decl, field_decl_chain;
3562 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3564 /* int ivar_count; */
3566 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3567 field_decl = get_identifier ("ivar_count");
3569 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3570 field_decl_chain = field_decl;
3572 /* struct objc_ivar ivar_list[]; */
3574 decl_specs = build_tree_list (NULL_TREE, list_type);
3575 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3576 build_int_2 (size, 0));
3578 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3579 chainon (field_decl_chain, field_decl);
3581 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3583 return objc_ivar_list_record;
3589 struct objc_method method_list[method_count];
3593 build_method_list_template (tree list_type, int size)
3595 tree objc_ivar_list_record;
3596 tree decl_specs, field_decl, field_decl_chain;
3598 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3600 /* int method_next; */
3605 xref_tag (RECORD_TYPE,
3606 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3608 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3609 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3610 field_decl_chain = field_decl;
3612 /* int method_count; */
3614 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3615 field_decl = get_identifier ("method_count");
3617 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3618 chainon (field_decl_chain, field_decl);
3620 /* struct objc_method method_list[]; */
3622 decl_specs = build_tree_list (NULL_TREE, list_type);
3623 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3624 build_int_2 (size, 0));
3626 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3627 chainon (field_decl_chain, field_decl);
3629 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3631 return objc_ivar_list_record;
3635 build_ivar_list_initializer (tree type, tree field_decl)
3637 tree initlist = NULL_TREE;
3641 tree ivar = NULL_TREE;
3644 if (DECL_NAME (field_decl))
3645 ivar = tree_cons (NULL_TREE,
3646 add_objc_string (DECL_NAME (field_decl),
3650 /* Unnamed bit-field ivar (yuck). */
3651 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3654 encode_field_decl (field_decl,
3655 obstack_object_size (&util_obstack),
3656 OBJC_ENCODE_DONT_INLINE_DEFS);
3658 /* Null terminate string. */
3659 obstack_1grow (&util_obstack, 0);
3663 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3666 obstack_free (&util_obstack, util_firstobj);
3669 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3670 initlist = tree_cons (NULL_TREE,
3671 objc_build_constructor (type, nreverse (ivar)),
3674 field_decl = TREE_CHAIN (field_decl);
3678 return objc_build_constructor (build_array_type (type, 0),
3679 nreverse (initlist));
3683 generate_ivars_list (tree type, const char *name, int size, tree list)
3685 tree sc_spec, decl_specs, decl, initlist;
3687 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3688 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3690 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3691 decl_specs, 1, NULL_TREE);
3693 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3694 initlist = tree_cons (NULL_TREE, list, initlist);
3697 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3704 generate_ivar_lists (void)
3706 tree initlist, ivar_list_template, chain;
3707 tree cast, variable_length_type;
3710 generating_instance_variables = 1;
3712 if (!objc_ivar_template)
3713 objc_ivar_template = build_ivar_template ();
3717 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3718 get_identifier (UTAG_IVAR_LIST))),
3720 variable_length_type = groktypename (cast);
3722 /* Only generate class variables for the root of the inheritance
3723 hierarchy since these will be the same for every class. */
3725 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3726 && (chain = TYPE_FIELDS (objc_class_template)))
3728 size = list_length (chain);
3730 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3731 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3733 UOBJC_CLASS_VARIABLES_decl
3734 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3736 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3739 UOBJC_CLASS_VARIABLES_decl = 0;
3741 chain = CLASS_IVARS (implementation_template);
3744 size = list_length (chain);
3745 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3746 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3748 UOBJC_INSTANCE_VARIABLES_decl
3749 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3751 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3754 UOBJC_INSTANCE_VARIABLES_decl = 0;
3756 generating_instance_variables = 0;
3760 build_dispatch_table_initializer (tree type, tree entries)
3762 tree initlist = NULL_TREE;
3766 tree elemlist = NULL_TREE;
3768 elemlist = tree_cons (NULL_TREE,
3769 build_selector (METHOD_SEL_NAME (entries)),
3772 /* Generate the method encoding if we don't have one already. */
3773 if (! METHOD_ENCODING (entries))
3774 METHOD_ENCODING (entries) =
3775 encode_method_def (METHOD_DEFINITION (entries));
3777 elemlist = tree_cons (NULL_TREE,
3778 add_objc_string (METHOD_ENCODING (entries),
3782 elemlist = tree_cons (NULL_TREE,
3783 build_unary_op (ADDR_EXPR,
3784 METHOD_DEFINITION (entries), 1),
3787 initlist = tree_cons (NULL_TREE,
3788 objc_build_constructor (type, nreverse (elemlist)),
3791 entries = TREE_CHAIN (entries);
3795 return objc_build_constructor (build_array_type (type, 0),
3796 nreverse (initlist));
3799 /* To accomplish method prototyping without generating all kinds of
3800 inane warnings, the definition of the dispatch table entries were
3803 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3805 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3808 build_method_template (void)
3811 tree decl_specs, field_decl, field_decl_chain;
3813 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3815 /* struct objc_selector *_cmd; */
3816 decl_specs = tree_cons (NULL_TREE,
3817 xref_tag (RECORD_TYPE,
3818 get_identifier (TAG_SELECTOR)),
3820 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3822 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3823 field_decl_chain = field_decl;
3825 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3826 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3827 get_identifier ("method_types"));
3828 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3829 chainon (field_decl_chain, field_decl);
3833 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3834 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3835 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3836 chainon (field_decl_chain, field_decl);
3838 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3845 generate_dispatch_table (tree type, const char *name, int size, tree list)
3847 tree sc_spec, decl_specs, decl, initlist;
3849 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3850 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3852 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3853 decl_specs, 1, NULL_TREE);
3855 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3856 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3857 initlist = tree_cons (NULL_TREE, list, initlist);
3860 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3867 mark_referenced_methods (void)
3869 struct imp_entry *impent;
3872 for (impent = imp_list; impent; impent = impent->next)
3874 chain = CLASS_CLS_METHODS (impent->imp_context);
3877 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
3878 chain = TREE_CHAIN (chain);
3881 chain = CLASS_NST_METHODS (impent->imp_context);
3884 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
3885 chain = TREE_CHAIN (chain);
3891 generate_dispatch_tables (void)
3893 tree initlist, chain, method_list_template;
3894 tree cast, variable_length_type;
3897 if (!objc_method_template)
3898 objc_method_template = build_method_template ();
3902 (build_tree_list (NULL_TREE,
3903 xref_tag (RECORD_TYPE,
3904 get_identifier (UTAG_METHOD_LIST))),
3907 variable_length_type = groktypename (cast);
3909 chain = CLASS_CLS_METHODS (objc_implementation_context);
3912 size = list_length (chain);
3914 method_list_template
3915 = build_method_list_template (objc_method_template, size);
3917 = build_dispatch_table_initializer (objc_method_template, chain);
3919 UOBJC_CLASS_METHODS_decl
3920 = generate_dispatch_table (method_list_template,
3921 ((TREE_CODE (objc_implementation_context)
3922 == CLASS_IMPLEMENTATION_TYPE)
3923 ? "_OBJC_CLASS_METHODS"
3924 : "_OBJC_CATEGORY_CLASS_METHODS"),
3926 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3929 UOBJC_CLASS_METHODS_decl = 0;
3931 chain = CLASS_NST_METHODS (objc_implementation_context);
3934 size = list_length (chain);
3936 method_list_template
3937 = build_method_list_template (objc_method_template, size);
3939 = build_dispatch_table_initializer (objc_method_template, chain);
3941 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3942 UOBJC_INSTANCE_METHODS_decl
3943 = generate_dispatch_table (method_list_template,
3944 "_OBJC_INSTANCE_METHODS",
3947 /* We have a category. */
3948 UOBJC_INSTANCE_METHODS_decl
3949 = generate_dispatch_table (method_list_template,
3950 "_OBJC_CATEGORY_INSTANCE_METHODS",
3952 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3955 UOBJC_INSTANCE_METHODS_decl = 0;
3959 generate_protocol_list (tree i_or_p)
3961 tree initlist, decl_specs, sc_spec;
3962 tree refs_decl, expr_decl, lproto, e, plist;
3966 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3967 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3968 plist = CLASS_PROTOCOL_LIST (i_or_p);
3969 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3970 plist = PROTOCOL_LIST (i_or_p);
3974 cast_type = groktypename
3976 (build_tree_list (NULL_TREE,
3977 xref_tag (RECORD_TYPE,
3978 get_identifier (UTAG_PROTOCOL))),
3979 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3982 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3983 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
3984 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
3987 /* Build initializer. */
3988 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
3990 e = build_int_2 (size, 0);
3991 TREE_TYPE (e) = cast_type;
3992 initlist = tree_cons (NULL_TREE, e, initlist);
3994 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3996 tree pval = TREE_VALUE (lproto);
3998 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
3999 && PROTOCOL_FORWARD_DECL (pval))
4001 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4002 initlist = tree_cons (NULL_TREE, e, initlist);
4006 /* static struct objc_protocol *refs[n]; */
4008 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4009 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4010 get_identifier (UTAG_PROTOCOL)),
4013 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4014 expr_decl = build_nt (ARRAY_REF,
4015 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4017 build_int_2 (size + 2, 0));
4018 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4019 expr_decl = build_nt (ARRAY_REF,
4020 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4022 build_int_2 (size + 2, 0));
4023 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4025 = build_nt (ARRAY_REF,
4026 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4028 build_int_2 (size + 2, 0));
4032 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4034 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4035 DECL_CONTEXT (refs_decl) = NULL_TREE;
4037 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4038 nreverse (initlist)),
4045 build_category_initializer (tree type, tree cat_name, tree class_name,
4046 tree instance_methods, tree class_methods,
4049 tree initlist = NULL_TREE, expr;
4051 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4052 initlist = tree_cons (NULL_TREE, class_name, initlist);
4054 if (!instance_methods)
4055 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4058 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4059 initlist = tree_cons (NULL_TREE, expr, initlist);
4062 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4065 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4066 initlist = tree_cons (NULL_TREE, expr, initlist);
4069 /* protocol_list = */
4071 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4074 tree cast_type2 = groktypename
4076 (build_tree_list (NULL_TREE,
4077 xref_tag (RECORD_TYPE,
4078 get_identifier (UTAG_PROTOCOL))),
4079 build1 (INDIRECT_REF, NULL_TREE,
4080 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4082 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4083 TREE_TYPE (expr) = cast_type2;
4084 initlist = tree_cons (NULL_TREE, expr, initlist);
4087 return objc_build_constructor (type, nreverse (initlist));
4090 /* struct objc_class {
4091 struct objc_class *isa;
4092 struct objc_class *super_class;
4097 struct objc_ivar_list *ivars;
4098 struct objc_method_list *methods;
4099 if (flag_next_runtime)
4100 struct objc_cache *cache;
4102 struct sarray *dtable;
4103 struct objc_class *subclass_list;
4104 struct objc_class *sibling_class;
4106 struct objc_protocol_list *protocols;
4107 void *gc_object_type;
4111 build_shared_structure_initializer (tree type, tree isa, tree super,
4112 tree name, tree size, int status,
4113 tree dispatch_table, tree ivar_list,
4116 tree initlist = NULL_TREE, expr;
4119 initlist = tree_cons (NULL_TREE, isa, initlist);
4122 initlist = tree_cons (NULL_TREE, super, initlist);
4125 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4128 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4131 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4133 /* instance_size = */
4134 initlist = tree_cons (NULL_TREE, size, initlist);
4136 /* objc_ivar_list = */
4138 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4141 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4142 initlist = tree_cons (NULL_TREE, expr, initlist);
4145 /* objc_method_list = */
4146 if (!dispatch_table)
4147 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4150 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4151 initlist = tree_cons (NULL_TREE, expr, initlist);
4154 if (flag_next_runtime)
4155 /* method_cache = */
4156 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4160 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4162 /* subclass_list = */
4163 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4165 /* sibling_class = */
4166 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4169 /* protocol_list = */
4170 if (! protocol_list)
4171 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4177 (build_tree_list (NULL_TREE,
4178 xref_tag (RECORD_TYPE,
4179 get_identifier (UTAG_PROTOCOL))),
4180 build1 (INDIRECT_REF, NULL_TREE,
4181 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4183 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4184 TREE_TYPE (expr) = cast_type2;
4185 initlist = tree_cons (NULL_TREE, expr, initlist);
4188 /* gc_object_type = NULL */
4189 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4191 return objc_build_constructor (type, nreverse (initlist));
4194 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4197 generate_category (tree cat)
4199 tree sc_spec, decl_specs, decl;
4200 tree initlist, cat_name_expr, class_name_expr;
4201 tree protocol_decl, category;
4203 add_class_reference (CLASS_NAME (cat));
4204 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4206 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4208 category = CLASS_CATEGORY_LIST (implementation_template);
4210 /* find the category interface from the class it is associated with */
4213 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4215 category = CLASS_CATEGORY_LIST (category);
4218 if (category && CLASS_PROTOCOL_LIST (category))
4220 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4221 protocol_decl = generate_protocol_list (category);
4226 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4227 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4229 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4230 objc_implementation_context),
4231 decl_specs, 1, NULL_TREE);
4233 initlist = build_category_initializer (TREE_TYPE (decl),
4234 cat_name_expr, class_name_expr,
4235 UOBJC_INSTANCE_METHODS_decl,
4236 UOBJC_CLASS_METHODS_decl,
4239 TREE_USED (decl) = 1;
4240 finish_decl (decl, initlist, NULL_TREE);
4243 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4244 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4247 generate_shared_structures (void)
4249 tree sc_spec, decl_specs, decl;
4250 tree name_expr, super_expr, root_expr;
4251 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4252 tree cast_type, initlist, protocol_decl;
4254 my_super_id = CLASS_SUPER_NAME (implementation_template);
4257 add_class_reference (my_super_id);
4259 /* Compute "my_root_id" - this is required for code generation.
4260 the "isa" for all meta class structures points to the root of
4261 the inheritance hierarchy (e.g. "__Object")... */
4262 my_root_id = my_super_id;
4265 tree my_root_int = lookup_interface (my_root_id);
4267 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4268 my_root_id = CLASS_SUPER_NAME (my_root_int);
4275 /* No super class. */
4276 my_root_id = CLASS_NAME (implementation_template);
4279 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4280 objc_class_template),
4281 build1 (INDIRECT_REF,
4282 NULL_TREE, NULL_TREE)));
4284 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4287 /* Install class `isa' and `super' pointers at runtime. */
4290 super_expr = add_objc_string (my_super_id, class_names);
4291 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4294 super_expr = build_int_2 (0, 0);
4296 root_expr = add_objc_string (my_root_id, class_names);
4297 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4299 if (CLASS_PROTOCOL_LIST (implementation_template))
4301 generate_protocol_references
4302 (CLASS_PROTOCOL_LIST (implementation_template));
4303 protocol_decl = generate_protocol_list (implementation_template);
4308 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4310 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4311 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4313 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4317 = build_shared_structure_initializer
4319 root_expr, super_expr, name_expr,
4320 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4322 UOBJC_CLASS_METHODS_decl,
4323 UOBJC_CLASS_VARIABLES_decl,
4326 finish_decl (decl, initlist, NULL_TREE);
4328 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4330 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4334 = build_shared_structure_initializer
4336 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4337 super_expr, name_expr,
4338 convert (integer_type_node,
4339 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4340 (implementation_template))),
4342 UOBJC_INSTANCE_METHODS_decl,
4343 UOBJC_INSTANCE_VARIABLES_decl,
4346 finish_decl (decl, initlist, NULL_TREE);
4350 synth_id_with_class_suffix (const char *preamble, tree ctxt)
4353 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4354 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4356 const char *const class_name
4357 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4358 string = alloca (strlen (preamble) + strlen (class_name) + 3);
4359 sprintf (string, "%s_%s", preamble,
4360 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4362 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4363 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4365 /* We have a category. */
4366 const char *const class_name
4367 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4368 const char *const class_super_name
4369 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4370 string = alloca (strlen (preamble) + strlen (class_name)
4371 + strlen (class_super_name) + 3);
4372 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4374 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4376 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4377 string = alloca (strlen (preamble) + strlen (protocol_name) + 3);
4378 sprintf (string, "%s_%s", preamble, protocol_name);
4383 return get_identifier (string);
4387 is_objc_type_qualifier (tree node)
4389 return (TREE_CODE (node) == IDENTIFIER_NODE
4390 && (node == ridpointers [(int) RID_CONST]
4391 || node == ridpointers [(int) RID_VOLATILE]
4392 || node == ridpointers [(int) RID_IN]
4393 || node == ridpointers [(int) RID_OUT]
4394 || node == ridpointers [(int) RID_INOUT]
4395 || node == ridpointers [(int) RID_BYCOPY]
4396 || node == ridpointers [(int) RID_BYREF]
4397 || node == ridpointers [(int) RID_ONEWAY]));
4400 /* If type is empty or only type qualifiers are present, add default
4401 type of id (otherwise grokdeclarator will default to int). */
4404 adjust_type_for_id_default (tree type)
4406 tree declspecs, chain;
4409 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4410 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4412 declspecs = TREE_PURPOSE (type);
4414 /* Determine if a typespec is present. */
4415 for (chain = declspecs;
4417 chain = TREE_CHAIN (chain))
4419 if (TYPED_OBJECT (TREE_VALUE (chain))
4420 && !(TREE_VALUE (type)
4421 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4422 error ("can not use an object as parameter to a method\n");
4423 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4427 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4429 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4434 selector ':' '(' typename ')' identifier
4437 Transform an Objective-C keyword argument into
4438 the C equivalent parameter declarator.
4440 In: key_name, an "identifier_node" (optional).
4441 arg_type, a "tree_list" (optional).
4442 arg_name, an "identifier_node".
4444 Note: It would be really nice to strongly type the preceding
4445 arguments in the function prototype; however, then I
4446 could not use the "accessor" macros defined in "tree.h".
4448 Out: an instance of "keyword_decl". */
4451 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
4455 /* If no type is specified, default to "id". */
4456 arg_type = adjust_type_for_id_default (arg_type);
4458 keyword_decl = make_node (KEYWORD_DECL);
4460 TREE_TYPE (keyword_decl) = arg_type;
4461 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4462 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4464 return keyword_decl;
4467 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4470 build_keyword_selector (tree selector)
4473 tree key_chain, key_name;
4476 /* Scan the selector to see how much space we'll need. */
4477 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4479 if (TREE_CODE (selector) == KEYWORD_DECL)
4480 key_name = KEYWORD_KEY_NAME (key_chain);
4481 else if (TREE_CODE (selector) == TREE_LIST)
4482 key_name = TREE_PURPOSE (key_chain);
4487 len += IDENTIFIER_LENGTH (key_name) + 1;
4489 /* Just a ':' arg. */
4493 buf = alloca (len + 1);
4494 /* Start the buffer out as an empty string. */
4497 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4499 if (TREE_CODE (selector) == KEYWORD_DECL)
4500 key_name = KEYWORD_KEY_NAME (key_chain);
4501 else if (TREE_CODE (selector) == TREE_LIST)
4502 key_name = TREE_PURPOSE (key_chain);
4507 strcat (buf, IDENTIFIER_POINTER (key_name));
4511 return get_identifier (buf);
4514 /* Used for declarations and definitions. */
4517 build_method_decl (enum tree_code code, tree ret_type, tree selector,
4522 /* If no type is specified, default to "id". */
4523 ret_type = adjust_type_for_id_default (ret_type);
4525 method_decl = make_node (code);
4526 TREE_TYPE (method_decl) = ret_type;
4528 /* If we have a keyword selector, create an identifier_node that
4529 represents the full selector name (`:' included)... */
4530 if (TREE_CODE (selector) == KEYWORD_DECL)
4532 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4533 METHOD_SEL_ARGS (method_decl) = selector;
4534 METHOD_ADD_ARGS (method_decl) = add_args;
4538 METHOD_SEL_NAME (method_decl) = selector;
4539 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4540 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4546 #define METHOD_DEF 0
4547 #define METHOD_REF 1
4549 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4550 an argument list for method METH. CONTEXT is either METHOD_DEF or
4551 METHOD_REF, saying whether we are trying to define a method or call
4552 one. SUPERFLAG says this is for a send to super; this makes a
4553 difference for the NeXT calling sequence in which the lookup and
4554 the method call are done together. */
4557 get_arg_type_list (tree meth, int context, int superflag)
4561 /* Receiver type. */
4562 if (flag_next_runtime && superflag)
4563 arglist = build_tree_list (NULL_TREE, super_type);
4564 else if (context == METHOD_DEF)
4565 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4567 arglist = build_tree_list (NULL_TREE, id_type);
4569 /* Selector type - will eventually change to `int'. */
4570 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4572 /* Build a list of argument types. */
4573 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4575 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4576 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4579 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4580 /* We have a `, ...' immediately following the selector,
4581 finalize the arglist...simulate get_parm_info (0). */
4583 else if (METHOD_ADD_ARGS (meth))
4585 /* we have a variable length selector */
4586 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4587 chainon (arglist, add_arg_list);
4590 /* finalize the arglist...simulate get_parm_info (1) */
4591 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4597 check_duplicates (hash hsh)
4599 tree meth = NULL_TREE;
4607 /* We have two methods with the same name and different types. */
4609 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4611 warning ("multiple declarations for method `%s'",
4612 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4614 warn_with_method ("using", type, meth);
4615 for (loop = hsh->list; loop; loop = loop->next)
4616 warn_with_method ("also found", type, loop->value);
4622 /* If RECEIVER is a class reference, return the identifier node for
4623 the referenced class. RECEIVER is created by get_class_reference,
4624 so we check the exact form created depending on which runtimes are
4628 receiver_is_class_object (tree receiver)
4630 tree chain, exp, arg;
4632 /* The receiver is 'self' in the context of a class method. */
4633 if (objc_method_context
4634 && receiver == self_decl
4635 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4637 return CLASS_NAME (objc_implementation_context);
4640 if (flag_next_runtime)
4642 /* The receiver is a variable created by
4643 build_class_reference_decl. */
4644 if (TREE_CODE (receiver) == VAR_DECL
4645 && TREE_TYPE (receiver) == objc_class_type)
4646 /* Look up the identifier. */
4647 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4648 if (TREE_PURPOSE (chain) == receiver)
4649 return TREE_VALUE (chain);
4653 /* The receiver is a function call that returns an id. Check if
4654 it is a call to objc_getClass, if so, pick up the class name. */
4655 if (TREE_CODE (receiver) == CALL_EXPR
4656 && (exp = TREE_OPERAND (receiver, 0))
4657 && TREE_CODE (exp) == ADDR_EXPR
4658 && (exp = TREE_OPERAND (exp, 0))
4659 && TREE_CODE (exp) == FUNCTION_DECL
4660 && exp == objc_get_class_decl
4661 /* We have a call to objc_getClass! */
4662 && (arg = TREE_OPERAND (receiver, 1))
4663 && TREE_CODE (arg) == TREE_LIST
4664 && (arg = TREE_VALUE (arg)))
4667 if (TREE_CODE (arg) == ADDR_EXPR
4668 && (arg = TREE_OPERAND (arg, 0))
4669 && TREE_CODE (arg) == STRING_CST)
4670 /* Finally, we have the class name. */
4671 return get_identifier (TREE_STRING_POINTER (arg));
4677 /* If we are currently building a message expr, this holds
4678 the identifier of the selector of the message. This is
4679 used when printing warnings about argument mismatches. */
4681 static tree current_objc_message_selector = 0;
4684 objc_message_selector (void)
4686 return current_objc_message_selector;
4689 /* Construct an expression for sending a message.
4690 MESS has the object to send to in TREE_PURPOSE
4691 and the argument list (including selector) in TREE_VALUE.
4693 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4694 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4697 build_message_expr (tree mess)
4699 tree receiver = TREE_PURPOSE (mess);
4701 tree args = TREE_VALUE (mess);
4702 tree method_params = NULL_TREE;
4704 if (TREE_CODE (receiver) == ERROR_MARK)
4705 return error_mark_node;
4707 /* Obtain the full selector name. */
4708 if (TREE_CODE (args) == IDENTIFIER_NODE)
4709 /* A unary selector. */
4711 else if (TREE_CODE (args) == TREE_LIST)
4712 sel_name = build_keyword_selector (args);
4716 /* Build the parameter list to give to the method. */
4717 if (TREE_CODE (args) == TREE_LIST)
4719 tree chain = args, prev = NULL_TREE;
4721 /* We have a keyword selector--check for comma expressions. */
4724 tree element = TREE_VALUE (chain);
4726 /* We have a comma expression, must collapse... */
4727 if (TREE_CODE (element) == TREE_LIST)
4730 TREE_CHAIN (prev) = element;
4735 chain = TREE_CHAIN (chain);
4737 method_params = args;
4740 return finish_message_expr (receiver, sel_name, method_params);
4743 /* The 'finish_message_expr' routine is called from within
4744 'build_message_expr' for non-template functions. In the case of
4745 C++ template functions, it is called from 'build_expr_from_tree'
4746 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4749 finish_message_expr (tree receiver, tree sel_name, tree method_params)
4751 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4752 tree selector, self_object, retval;
4753 int statically_typed = 0, statically_allocated = 0;
4755 /* Determine receiver type. */
4756 tree rtype = TREE_TYPE (receiver);
4757 int super = IS_SUPER (rtype);
4761 if (TREE_STATIC_TEMPLATE (rtype))
4762 statically_allocated = 1;
4763 else if (TREE_CODE (rtype) == POINTER_TYPE
4764 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4765 statically_typed = 1;
4766 else if ((flag_next_runtime
4768 && (class_ident = receiver_is_class_object (receiver)))
4770 else if (! IS_ID (rtype)
4771 /* Allow any type that matches objc_class_type. */
4772 && ! comptypes (rtype, objc_class_type, false))
4774 warning ("invalid receiver type `%s'",
4775 gen_declaration (rtype, errbuf));
4777 if (statically_allocated)
4778 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4780 /* Don't evaluate the receiver twice. */
4781 receiver = save_expr (receiver);
4782 self_object = receiver;
4785 /* If sending to `super', use current self as the object. */
4786 self_object = self_decl;
4788 /* Determine operation return type. */
4794 if (CLASS_SUPER_NAME (implementation_template))
4797 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4799 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4800 method_prototype = lookup_instance_method_static (iface, sel_name);
4802 method_prototype = lookup_class_method_static (iface, sel_name);
4804 if (iface && !method_prototype)
4805 warning ("`%s' does not respond to `%s'",
4806 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4807 IDENTIFIER_POINTER (sel_name));
4811 error ("no super class declared in interface for `%s'",
4812 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4813 return error_mark_node;
4817 else if (statically_allocated)
4819 tree ctype = TREE_TYPE (rtype);
4820 tree iface = lookup_interface (TYPE_NAME (rtype));
4823 method_prototype = lookup_instance_method_static (iface, sel_name);
4825 if (! method_prototype && ctype && TYPE_PROTOCOL_LIST (ctype))
4827 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4830 if (!method_prototype)
4831 warning ("`%s' does not respond to `%s'",
4832 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4833 IDENTIFIER_POINTER (sel_name));
4835 else if (statically_typed)
4837 tree ctype = TREE_TYPE (rtype);
4839 /* `self' is now statically_typed. All methods should be visible
4840 within the context of the implementation. */
4841 if (objc_implementation_context
4842 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4845 = lookup_instance_method_static (implementation_template,
4848 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4850 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4853 if (! method_prototype
4854 && implementation_template != objc_implementation_context)
4855 /* The method is not published in the interface. Check
4858 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4865 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4866 method_prototype = lookup_instance_method_static (iface, sel_name);
4868 if (! method_prototype)
4870 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4873 = lookup_method_in_protocol_list (protocol_list,
4878 if (!method_prototype)
4879 warning ("`%s' does not respond to `%s'",
4880 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4881 IDENTIFIER_POINTER (sel_name));
4883 else if (class_ident)
4885 if (objc_implementation_context
4886 && CLASS_NAME (objc_implementation_context) == class_ident)
4889 = lookup_class_method_static (implementation_template, sel_name);
4891 if (!method_prototype
4892 && implementation_template != objc_implementation_context)
4893 /* The method is not published in the interface. Check
4896 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
4903 if ((iface = lookup_interface (class_ident)))
4904 method_prototype = lookup_class_method_static (iface, sel_name);
4907 if (!method_prototype)
4909 warning ("cannot find class (factory) method");
4910 warning ("return type for `%s' defaults to id",
4911 IDENTIFIER_POINTER (sel_name));
4914 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4916 /* An anonymous object that has been qualified with a protocol. */
4918 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4920 method_prototype = lookup_method_in_protocol_list (protocol_list,
4923 if (!method_prototype)
4927 warning ("method `%s' not implemented by protocol",
4928 IDENTIFIER_POINTER (sel_name));
4930 /* Try and find the method signature in the global pools. */
4932 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4933 hsh = hash_lookup (cls_method_hash_list, sel_name);
4935 if (!(method_prototype = check_duplicates (hsh)))
4936 warning ("return type defaults to id");
4943 /* We think we have an instance...loophole: extern id Object; */
4944 hsh = hash_lookup (nst_method_hash_list, sel_name);
4947 /* For various loopholes */
4948 hsh = hash_lookup (cls_method_hash_list, sel_name);
4950 method_prototype = check_duplicates (hsh);
4951 if (!method_prototype)
4953 warning ("cannot find method");
4954 warning ("return type for `%s' defaults to id",
4955 IDENTIFIER_POINTER (sel_name));
4959 /* Save the selector name for printing error messages. */
4960 current_objc_message_selector = sel_name;
4962 /* Build the parameters list for looking up the method.
4963 These are the object itself and the selector. */
4965 if (flag_typed_selectors)
4966 selector = build_typed_selector_reference (sel_name, method_prototype);
4968 selector = build_selector_reference (sel_name);
4970 retval = build_objc_method_call (super, method_prototype,
4971 receiver, self_object,
4972 selector, method_params);
4974 current_objc_message_selector = 0;
4979 /* Build a tree expression to send OBJECT the operation SELECTOR,
4980 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
4981 assuming the method has prototype METHOD_PROTOTYPE.
4982 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
4983 Use METHOD_PARAMS as list of args to pass to the method.
4984 If SUPER_FLAG is nonzero, we look up the superclass's method. */
4987 build_objc_method_call (int super_flag, tree method_prototype,
4988 tree lookup_object, tree object, tree selector,
4991 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
4992 tree rcv_p = (super_flag
4993 ? build_pointer_type (xref_tag (RECORD_TYPE,
4994 get_identifier (TAG_SUPER)))
4997 if (flag_next_runtime)
4999 if (! method_prototype)
5001 method_params = tree_cons (NULL_TREE, lookup_object,
5002 tree_cons (NULL_TREE, selector,
5004 assemble_external (sender);
5005 return build_function_call (sender, method_params);
5009 /* This is a real kludge, but it is used only for the Next.
5010 Clobber the data type of SENDER temporarily to accept
5011 all the arguments for this operation, and to return
5012 whatever this operation returns. */
5013 tree arglist = NULL_TREE, retval, savarg, savret;
5014 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5016 /* Save the proper contents of SENDER's data type. */
5017 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5018 savret = TREE_TYPE (TREE_TYPE (sender));
5020 /* Install this method's argument types. */
5021 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5023 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5025 /* Install this method's return type. */
5026 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5028 /* Call SENDER with all the parameters. This will do type
5029 checking using the arg types for this method. */
5030 method_params = tree_cons (NULL_TREE, lookup_object,
5031 tree_cons (NULL_TREE, selector,
5033 assemble_external (sender);
5034 retval = build_function_call (sender, method_params);
5036 /* Restore SENDER's return/argument types. */
5037 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5038 TREE_TYPE (TREE_TYPE (sender)) = savret;
5044 /* This is the portable way.
5045 First call the lookup function to get a pointer to the method,
5046 then cast the pointer, then call it with the method arguments. */
5049 /* Avoid trouble since we may evaluate each of these twice. */
5050 object = save_expr (object);
5051 selector = save_expr (selector);
5053 lookup_object = build_c_cast (rcv_p, lookup_object);
5055 assemble_external (sender);
5057 = build_function_call (sender,
5058 tree_cons (NULL_TREE, lookup_object,
5059 tree_cons (NULL_TREE, selector,
5062 /* If we have a method prototype, construct the data type this
5063 method needs, and cast what we got from SENDER into a pointer
5065 if (method_prototype)
5067 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5069 tree valtype = groktypename (TREE_TYPE (method_prototype));
5070 tree fake_function_type = build_function_type (valtype, arglist);
5071 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5075 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5077 /* Pass the object to the method. */
5078 assemble_external (method);
5079 return build_function_call (method,
5080 tree_cons (NULL_TREE, object,
5081 tree_cons (NULL_TREE, selector,
5087 build_protocol_reference (tree p)
5089 tree decl, ident, ptype;
5091 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5093 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5095 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5096 objc_protocol_template),
5099 if (identifier_global_value (ident))
5100 decl = identifier_global_value (ident); /* Set by pushdecl. */
5103 decl = build_decl (VAR_DECL, ident, ptype);
5104 DECL_EXTERNAL (decl) = 1;
5105 TREE_PUBLIC (decl) = 0;
5106 TREE_USED (decl) = 1;
5107 DECL_ARTIFICIAL (decl) = 1;
5109 make_decl_rtl (decl, 0);
5110 pushdecl_top_level (decl);
5113 PROTOCOL_FORWARD_DECL (p) = decl;
5116 /* This function is called by the parser when (and only when) a
5117 @protocol() expression is found, in order to compile it. */
5119 build_protocol_expr (tree protoname)
5122 tree p = lookup_protocol (protoname);
5126 error ("cannot find protocol declaration for `%s'",
5127 IDENTIFIER_POINTER (protoname));
5128 return error_mark_node;
5131 if (!PROTOCOL_FORWARD_DECL (p))
5132 build_protocol_reference (p);
5134 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5136 TREE_TYPE (expr) = protocol_type;
5138 /* The @protocol() expression is being compiled into a pointer to a
5139 statically allocated instance of the Protocol class. To become
5140 usable at runtime, the 'isa' pointer of the instance need to be
5141 fixed up at runtime by the runtime library, to point to the
5142 actual 'Protocol' class. */
5144 /* For the GNU runtime, put the static Protocol instance in the list
5145 of statically allocated instances, so that we make sure that its
5146 'isa' pointer is fixed up at runtime by the GNU runtime library
5147 to point to the Protocol class (at runtime, when loading the
5148 module, the GNU runtime library loops on the statically allocated
5149 instances (as found in the defs field in objc_symtab) and fixups
5150 all the 'isa' pointers of those objects). */
5151 if (! flag_next_runtime)
5153 /* This type is a struct containing the fields of a Protocol
5154 object. (Cfr. protocol_type instead is the type of a pointer
5155 to such a struct). */
5156 tree protocol_struct_type = xref_tag
5157 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5160 /* Look for the list of Protocol statically allocated instances
5161 to fixup at runtime. Create a new list to hold Protocol
5162 statically allocated instances, if the list is not found. At
5163 present there is only another list, holding NSConstantString
5164 static instances to be fixed up at runtime. */
5165 for (chain = &objc_static_instances;
5166 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5167 chain = &TREE_CHAIN (*chain));
5170 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5171 add_objc_string (TYPE_NAME (protocol_struct_type),
5175 /* Add this statically allocated instance to the Protocol list. */
5176 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5177 PROTOCOL_FORWARD_DECL (p),
5178 TREE_PURPOSE (*chain));
5185 /* This function is called by the parser when a @selector() expression
5186 is found, in order to compile it. It is only called by the parser
5187 and only to compile a @selector(). */
5189 build_selector_expr (tree selnamelist)
5193 /* Obtain the full selector name. */
5194 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5195 /* A unary selector. */
5196 selname = selnamelist;
5197 else if (TREE_CODE (selnamelist) == TREE_LIST)
5198 selname = build_keyword_selector (selnamelist);
5202 /* If we are required to check @selector() expressions as they
5203 are found, check that the selector has been declared. */
5204 if (warn_undeclared_selector)
5206 /* Look the selector up in the list of all known class and
5207 instance methods (up to this line) to check that the selector
5211 /* First try with instance methods. */
5212 hsh = hash_lookup (nst_method_hash_list, selname);
5214 /* If not found, try with class methods. */
5217 hsh = hash_lookup (cls_method_hash_list, selname);
5220 /* If still not found, print out a warning. */
5223 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5228 if (flag_typed_selectors)
5229 return build_typed_selector_reference (selname, 0);
5231 return build_selector_reference (selname);
5235 build_encode_expr (tree type)
5240 encode_type (type, obstack_object_size (&util_obstack),
5241 OBJC_ENCODE_INLINE_DEFS);
5242 obstack_1grow (&util_obstack, 0); /* null terminate string */
5243 string = obstack_finish (&util_obstack);
5245 /* Synthesize a string that represents the encoded struct/union. */
5246 result = my_build_string (strlen (string) + 1, string);
5247 obstack_free (&util_obstack, util_firstobj);
5252 build_ivar_reference (tree id)
5254 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5256 /* Historically, a class method that produced objects (factory
5257 method) would assign `self' to the instance that it
5258 allocated. This would effectively turn the class method into
5259 an instance method. Following this assignment, the instance
5260 variables could be accessed. That practice, while safe,
5261 violates the simple rule that a class method should not refer
5262 to an instance variable. It's better to catch the cases
5263 where this is done unknowingly than to support the above
5265 warning ("instance variable `%s' accessed in class method",
5266 IDENTIFIER_POINTER (id));
5267 TREE_TYPE (self_decl) = instance_type; /* cast */
5270 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5273 /* Compute a hash value for a given method SEL_NAME. */
5276 hash_func (tree sel_name)
5278 const unsigned char *s
5279 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5283 h = h * 67 + *s++ - 113;
5290 nst_method_hash_list = ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5291 cls_method_hash_list = ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5294 /* WARNING!!!! hash_enter is called with a method, and will peek
5295 inside to find its selector! But hash_lookup is given a selector
5296 directly, and looks for the selector that's inside the found
5297 entry's key (method) for comparison. */
5300 hash_enter (hash *hashlist, tree method)
5303 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5305 obj = ggc_alloc (sizeof (struct hashed_entry));
5307 obj->next = hashlist[slot];
5310 hashlist[slot] = obj; /* append to front */
5314 hash_lookup (hash *hashlist, tree sel_name)
5318 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5322 if (sel_name == METHOD_SEL_NAME (target->key))
5325 target = target->next;
5331 hash_add_attr (hash entry, tree value)
5335 obj = ggc_alloc (sizeof (struct hashed_attribute));
5336 obj->next = entry->list;
5339 entry->list = obj; /* append to front */
5343 lookup_method (tree mchain, tree method)
5347 if (TREE_CODE (method) == IDENTIFIER_NODE)
5350 key = METHOD_SEL_NAME (method);
5354 if (METHOD_SEL_NAME (mchain) == key)
5357 mchain = TREE_CHAIN (mchain);
5363 lookup_instance_method_static (tree interface, tree ident)
5365 tree inter = interface;
5366 tree chain = CLASS_NST_METHODS (inter);
5367 tree meth = NULL_TREE;
5371 if ((meth = lookup_method (chain, ident)))
5374 if (CLASS_CATEGORY_LIST (inter))
5376 tree category = CLASS_CATEGORY_LIST (inter);
5377 chain = CLASS_NST_METHODS (category);
5381 if ((meth = lookup_method (chain, ident)))
5384 /* Check for instance methods in protocols in categories. */
5385 if (CLASS_PROTOCOL_LIST (category))
5387 if ((meth = (lookup_method_in_protocol_list
5388 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5392 if ((category = CLASS_CATEGORY_LIST (category)))
5393 chain = CLASS_NST_METHODS (category);
5398 if (CLASS_PROTOCOL_LIST (inter))
5400 if ((meth = (lookup_method_in_protocol_list
5401 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5405 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5406 chain = CLASS_NST_METHODS (inter);
5414 lookup_class_method_static (tree interface, tree ident)
5416 tree inter = interface;
5417 tree chain = CLASS_CLS_METHODS (inter);
5418 tree meth = NULL_TREE;
5419 tree root_inter = NULL_TREE;
5423 if ((meth = lookup_method (chain, ident)))
5426 if (CLASS_CATEGORY_LIST (inter))
5428 tree category = CLASS_CATEGORY_LIST (inter);
5429 chain = CLASS_CLS_METHODS (category);
5433 if ((meth = lookup_method (chain, ident)))
5436 /* Check for class methods in protocols in categories. */
5437 if (CLASS_PROTOCOL_LIST (category))
5439 if ((meth = (lookup_method_in_protocol_list
5440 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5444 if ((category = CLASS_CATEGORY_LIST (category)))
5445 chain = CLASS_CLS_METHODS (category);
5450 /* Check for class methods in protocols. */
5451 if (CLASS_PROTOCOL_LIST (inter))
5453 if ((meth = (lookup_method_in_protocol_list
5454 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5459 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5460 chain = CLASS_CLS_METHODS (inter);
5464 /* If no class (factory) method was found, check if an _instance_
5465 method of the same name exists in the root class. This is what
5466 the Objective-C runtime will do. */
5467 return lookup_instance_method_static (root_inter, ident);
5471 add_class_method (tree class, tree method)
5476 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5478 /* put method on list in reverse order */
5479 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5480 CLASS_CLS_METHODS (class) = method;
5484 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5485 error ("duplicate definition of class method `%s'",
5486 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5489 /* Check types; if different, complain. */
5490 if (!comp_proto_with_proto (method, mth))
5491 error ("duplicate declaration of class method `%s'",
5492 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5496 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5498 /* Install on a global chain. */
5499 hash_enter (cls_method_hash_list, method);
5503 /* Check types; if different, add to a list. */
5504 if (!comp_proto_with_proto (method, hsh->key))
5505 hash_add_attr (hsh, method);
5511 add_instance_method (tree class, tree method)
5516 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5518 /* Put method on list in reverse order. */
5519 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5520 CLASS_NST_METHODS (class) = method;
5524 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5525 error ("duplicate definition of instance method `%s'",
5526 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5529 /* Check types; if different, complain. */
5530 if (!comp_proto_with_proto (method, mth))
5531 error ("duplicate declaration of instance method `%s'",
5532 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5536 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5538 /* Install on a global chain. */
5539 hash_enter (nst_method_hash_list, method);
5543 /* Check types; if different, add to a list. */
5544 if (!comp_proto_with_proto (method, hsh->key))
5545 hash_add_attr (hsh, method);
5551 add_class (tree class)
5553 /* Put interfaces on list in reverse order. */
5554 TREE_CHAIN (class) = interface_chain;
5555 interface_chain = class;
5556 return interface_chain;
5560 add_category (tree class, tree category)
5562 /* Put categories on list in reverse order. */
5563 tree cat = CLASS_CATEGORY_LIST (class);
5567 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5568 warning ("duplicate interface declaration for category `%s(%s)'",
5569 IDENTIFIER_POINTER (CLASS_NAME (class)),
5570 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5571 cat = CLASS_CATEGORY_LIST (cat);
5574 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5575 CLASS_CATEGORY_LIST (class) = category;
5578 /* Called after parsing each instance variable declaration. Necessary to
5579 preserve typedefs and implement public/private...
5581 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5584 add_instance_variable (tree class, int public, tree declarator,
5585 tree declspecs, tree width)
5587 tree field_decl, raw_decl;
5589 raw_decl = build_tree_list (declspecs, declarator);
5591 if (CLASS_RAW_IVARS (class))
5592 chainon (CLASS_RAW_IVARS (class), raw_decl);
5594 CLASS_RAW_IVARS (class) = raw_decl;
5596 field_decl = grokfield (declarator, declspecs, width);
5598 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5602 TREE_PUBLIC (field_decl) = 0;
5603 TREE_PRIVATE (field_decl) = 0;
5604 TREE_PROTECTED (field_decl) = 1;
5608 TREE_PUBLIC (field_decl) = 1;
5609 TREE_PRIVATE (field_decl) = 0;
5610 TREE_PROTECTED (field_decl) = 0;
5614 TREE_PUBLIC (field_decl) = 0;
5615 TREE_PRIVATE (field_decl) = 1;
5616 TREE_PROTECTED (field_decl) = 0;
5621 if (CLASS_IVARS (class))
5622 chainon (CLASS_IVARS (class), field_decl);
5624 CLASS_IVARS (class) = field_decl;
5630 is_ivar (tree decl_chain, tree ident)
5632 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5633 if (DECL_NAME (decl_chain) == ident)
5638 /* True if the ivar is private and we are not in its implementation. */
5641 is_private (tree decl)
5643 if (TREE_PRIVATE (decl)
5644 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5646 error ("instance variable `%s' is declared private",
5647 IDENTIFIER_POINTER (DECL_NAME (decl)));
5654 /* We have an instance variable reference;, check to see if it is public. */
5657 is_public (tree expr, tree identifier)
5659 tree basetype = TREE_TYPE (expr);
5660 enum tree_code code = TREE_CODE (basetype);
5663 if (code == RECORD_TYPE)
5665 if (TREE_STATIC_TEMPLATE (basetype))
5667 if (!lookup_interface (TYPE_NAME (basetype)))
5669 error ("cannot find interface declaration for `%s'",
5670 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5674 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5676 if (TREE_PUBLIC (decl))
5679 /* Important difference between the Stepstone translator:
5680 all instance variables should be public within the context
5681 of the implementation. */
5682 if (objc_implementation_context
5683 && (((TREE_CODE (objc_implementation_context)
5684 == CLASS_IMPLEMENTATION_TYPE)
5685 || (TREE_CODE (objc_implementation_context)
5686 == CATEGORY_IMPLEMENTATION_TYPE))
5687 && (CLASS_NAME (objc_implementation_context)
5688 == TYPE_NAME (basetype))))
5689 return ! is_private (decl);
5691 error ("instance variable `%s' is declared %s",
5692 IDENTIFIER_POINTER (identifier),
5693 TREE_PRIVATE (decl) ? "private" : "protected");
5698 else if (objc_implementation_context && (basetype == objc_object_reference))
5700 TREE_TYPE (expr) = uprivate_record;
5701 warning ("static access to object of type `id'");
5708 /* Make sure all entries in CHAIN are also in LIST. */
5711 check_methods (tree chain, tree list, int mtype)
5717 if (!lookup_method (list, chain))
5721 if (TREE_CODE (objc_implementation_context)
5722 == CLASS_IMPLEMENTATION_TYPE)
5723 warning ("incomplete implementation of class `%s'",
5724 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5725 else if (TREE_CODE (objc_implementation_context)
5726 == CATEGORY_IMPLEMENTATION_TYPE)
5727 warning ("incomplete implementation of category `%s'",
5728 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5732 warning ("method definition for `%c%s' not found",
5733 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5736 chain = TREE_CHAIN (chain);
5742 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5745 conforms_to_protocol (tree class, tree protocol)
5747 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5749 tree p = CLASS_PROTOCOL_LIST (class);
5750 while (p && TREE_VALUE (p) != protocol)
5755 tree super = (CLASS_SUPER_NAME (class)
5756 ? lookup_interface (CLASS_SUPER_NAME (class))
5758 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5767 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5768 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5771 check_methods_accessible (tree chain, tree context, int mtype)
5775 tree base_context = context;
5779 context = base_context;
5783 list = CLASS_CLS_METHODS (context);
5785 list = CLASS_NST_METHODS (context);
5787 if (lookup_method (list, chain))
5790 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5791 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5792 context = (CLASS_SUPER_NAME (context)
5793 ? lookup_interface (CLASS_SUPER_NAME (context))
5796 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5797 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5798 context = (CLASS_NAME (context)
5799 ? lookup_interface (CLASS_NAME (context))
5805 if (context == NULL_TREE)
5809 if (TREE_CODE (objc_implementation_context)
5810 == CLASS_IMPLEMENTATION_TYPE)
5811 warning ("incomplete implementation of class `%s'",
5813 (CLASS_NAME (objc_implementation_context)));
5814 else if (TREE_CODE (objc_implementation_context)
5815 == CATEGORY_IMPLEMENTATION_TYPE)
5816 warning ("incomplete implementation of category `%s'",
5818 (CLASS_SUPER_NAME (objc_implementation_context)));
5821 warning ("method definition for `%c%s' not found",
5822 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5825 chain = TREE_CHAIN (chain); /* next method... */
5830 /* Check whether the current interface (accessible via
5831 'objc_implementation_context') actually implements protocol P, along
5832 with any protocols that P inherits. */
5835 check_protocol (tree p, const char *type, const char *name)
5837 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5841 /* Ensure that all protocols have bodies! */
5844 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5845 CLASS_CLS_METHODS (objc_implementation_context),
5847 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5848 CLASS_NST_METHODS (objc_implementation_context),
5853 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5854 objc_implementation_context,
5856 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5857 objc_implementation_context,
5862 warning ("%s `%s' does not fully implement the `%s' protocol",
5863 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5866 /* Check protocols recursively. */
5867 if (PROTOCOL_LIST (p))
5869 tree subs = PROTOCOL_LIST (p);
5871 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5875 tree sub = TREE_VALUE (subs);
5877 /* If the superclass does not conform to the protocols
5878 inherited by P, then we must! */
5879 if (!super_class || !conforms_to_protocol (super_class, sub))
5880 check_protocol (sub, type, name);
5881 subs = TREE_CHAIN (subs);
5886 /* Check whether the current interface (accessible via
5887 'objc_implementation_context') actually implements the protocols listed
5891 check_protocols (tree proto_list, const char *type, const char *name)
5893 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5895 tree p = TREE_VALUE (proto_list);
5897 check_protocol (p, type, name);
5901 /* Make sure that the class CLASS_NAME is defined
5902 CODE says which kind of thing CLASS_NAME ought to be.
5903 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5904 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5907 start_class (enum tree_code code, tree class_name, tree super_name,
5912 if (objc_implementation_context)
5914 warning ("`@end' missing in implementation context");
5915 finish_class (objc_implementation_context);
5916 objc_ivar_chain = NULL_TREE;
5917 objc_implementation_context = NULL_TREE;
5920 class = make_node (code);
5921 TYPE_BINFO (class) = make_tree_vec (BINFO_ELTS);
5923 CLASS_NAME (class) = class_name;
5924 CLASS_SUPER_NAME (class) = super_name;
5925 CLASS_CLS_METHODS (class) = NULL_TREE;
5927 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5929 error ("`%s' redeclared as different kind of symbol",
5930 IDENTIFIER_POINTER (class_name));
5931 error ("%Jprevious declaration of '%D'", decl, decl);
5934 if (code == CLASS_IMPLEMENTATION_TYPE)
5939 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5940 if (TREE_VALUE (chain) == class_name)
5942 error ("reimplementation of class `%s'",
5943 IDENTIFIER_POINTER (class_name));
5944 return error_mark_node;
5946 implemented_classes = tree_cons (NULL_TREE, class_name,
5947 implemented_classes);
5950 /* Pre-build the following entities - for speed/convenience. */
5952 self_id = get_identifier ("self");
5954 ucmd_id = get_identifier ("_cmd");
5957 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
5958 if (!objc_super_template)
5959 objc_super_template = build_super_template ();
5961 /* Reset for multiple classes per file. */
5964 objc_implementation_context = class;
5966 /* Lookup the interface for this implementation. */
5968 if (!(implementation_template = lookup_interface (class_name)))
5970 warning ("cannot find interface declaration for `%s'",
5971 IDENTIFIER_POINTER (class_name));
5972 add_class (implementation_template = objc_implementation_context);
5975 /* If a super class has been specified in the implementation,
5976 insure it conforms to the one specified in the interface. */
5979 && (super_name != CLASS_SUPER_NAME (implementation_template)))
5981 tree previous_name = CLASS_SUPER_NAME (implementation_template);
5982 const char *const name =
5983 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
5984 error ("conflicting super class name `%s'",
5985 IDENTIFIER_POINTER (super_name));
5986 error ("previous declaration of `%s'", name);
5989 else if (! super_name)
5991 CLASS_SUPER_NAME (objc_implementation_context)
5992 = CLASS_SUPER_NAME (implementation_template);
5996 else if (code == CLASS_INTERFACE_TYPE)
5998 if (lookup_interface (class_name))
5999 warning ("duplicate interface declaration for class `%s'",
6000 IDENTIFIER_POINTER (class_name));
6005 CLASS_PROTOCOL_LIST (class)
6006 = lookup_and_install_protocols (protocol_list);
6009 else if (code == CATEGORY_INTERFACE_TYPE)
6011 tree class_category_is_assoc_with;
6013 /* For a category, class_name is really the name of the class that
6014 the following set of methods will be associated with. We must
6015 find the interface so that can derive the objects template. */
6017 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6019 error ("cannot find interface declaration for `%s'",
6020 IDENTIFIER_POINTER (class_name));
6021 exit (FATAL_EXIT_CODE);
6024 add_category (class_category_is_assoc_with, class);
6027 CLASS_PROTOCOL_LIST (class)
6028 = lookup_and_install_protocols (protocol_list);
6031 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6033 /* Pre-build the following entities for speed/convenience. */
6035 self_id = get_identifier ("self");
6037 ucmd_id = get_identifier ("_cmd");
6040 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6041 if (!objc_super_template)
6042 objc_super_template = build_super_template ();
6044 /* Reset for multiple classes per file. */
6047 objc_implementation_context = class;
6049 /* For a category, class_name is really the name of the class that
6050 the following set of methods will be associated with. We must
6051 find the interface so that can derive the objects template. */
6053 if (!(implementation_template = lookup_interface (class_name)))
6055 error ("cannot find interface declaration for `%s'",
6056 IDENTIFIER_POINTER (class_name));
6057 exit (FATAL_EXIT_CODE);
6064 continue_class (tree class)
6066 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6067 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6069 struct imp_entry *imp_entry;
6072 /* Check consistency of the instance variables. */
6074 if (CLASS_IVARS (class))
6075 check_ivars (implementation_template, class);
6077 /* code generation */
6079 ivar_context = build_private_template (implementation_template);
6081 if (!objc_class_template)
6082 build_class_template ();
6084 imp_entry = ggc_alloc (sizeof (struct imp_entry));
6086 imp_entry->next = imp_list;
6087 imp_entry->imp_context = class;
6088 imp_entry->imp_template = implementation_template;
6090 synth_forward_declarations ();
6091 imp_entry->class_decl = UOBJC_CLASS_decl;
6092 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6094 /* Append to front and increment count. */
6095 imp_list = imp_entry;
6096 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6101 return ivar_context;
6104 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6106 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6108 if (!TYPE_FIELDS (record))
6110 finish_struct (record, get_class_ivars (class), NULL_TREE);
6111 CLASS_STATIC_TEMPLATE (class) = record;
6113 /* Mark this record as a class template for static typing. */
6114 TREE_STATIC_TEMPLATE (record) = 1;
6121 return error_mark_node;
6124 /* This is called once we see the "@end" in an interface/implementation. */
6127 finish_class (tree class)
6129 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6131 /* All code generation is done in finish_objc. */
6133 if (implementation_template != objc_implementation_context)
6135 /* Ensure that all method listed in the interface contain bodies. */
6136 check_methods (CLASS_CLS_METHODS (implementation_template),
6137 CLASS_CLS_METHODS (objc_implementation_context), '+');
6138 check_methods (CLASS_NST_METHODS (implementation_template),
6139 CLASS_NST_METHODS (objc_implementation_context), '-');
6141 if (CLASS_PROTOCOL_LIST (implementation_template))
6142 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6144 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6148 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6150 tree category = CLASS_CATEGORY_LIST (implementation_template);
6152 /* Find the category interface from the class it is associated with. */
6155 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6157 category = CLASS_CATEGORY_LIST (category);
6162 /* Ensure all method listed in the interface contain bodies. */
6163 check_methods (CLASS_CLS_METHODS (category),
6164 CLASS_CLS_METHODS (objc_implementation_context), '+');
6165 check_methods (CLASS_NST_METHODS (category),
6166 CLASS_NST_METHODS (objc_implementation_context), '-');
6168 if (CLASS_PROTOCOL_LIST (category))
6169 check_protocols (CLASS_PROTOCOL_LIST (category),
6171 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6175 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6178 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6179 char *string = alloca (strlen (class_name) + 3);
6181 /* extern struct objc_object *_<my_name>; */
6183 sprintf (string, "_%s", class_name);
6185 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6186 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6187 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6193 add_protocol (tree protocol)
6195 /* Put protocol on list in reverse order. */
6196 TREE_CHAIN (protocol) = protocol_chain;
6197 protocol_chain = protocol;
6198 return protocol_chain;
6202 lookup_protocol (tree ident)
6206 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6207 if (ident == PROTOCOL_NAME (chain))
6213 /* This function forward declares the protocols named by NAMES. If
6214 they are already declared or defined, the function has no effect. */
6217 objc_declare_protocols (tree names)
6221 for (list = names; list; list = TREE_CHAIN (list))
6223 tree name = TREE_VALUE (list);
6225 if (lookup_protocol (name) == NULL_TREE)
6227 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6229 TYPE_BINFO (protocol) = make_tree_vec (2);
6230 PROTOCOL_NAME (protocol) = name;
6231 PROTOCOL_LIST (protocol) = NULL_TREE;
6232 add_protocol (protocol);
6233 PROTOCOL_DEFINED (protocol) = 0;
6234 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6240 start_protocol (enum tree_code code, tree name, tree list)
6244 /* This is as good a place as any. Need to invoke
6245 push_tag_toplevel. */
6246 if (!objc_protocol_template)
6247 objc_protocol_template = build_protocol_template ();
6249 protocol = lookup_protocol (name);
6253 protocol = make_node (code);
6254 TYPE_BINFO (protocol) = make_tree_vec (2);
6256 PROTOCOL_NAME (protocol) = name;
6257 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6258 add_protocol (protocol);
6259 PROTOCOL_DEFINED (protocol) = 1;
6260 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6262 check_protocol_recursively (protocol, list);
6264 else if (! PROTOCOL_DEFINED (protocol))
6266 PROTOCOL_DEFINED (protocol) = 1;
6267 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6269 check_protocol_recursively (protocol, list);
6273 warning ("duplicate declaration for protocol `%s'",
6274 IDENTIFIER_POINTER (name));
6280 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
6285 /* "Encode" a data type into a string, which grows in util_obstack.
6286 ??? What is the FORMAT? Someone please document this! */
6289 encode_type_qualifiers (tree declspecs)
6293 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6295 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6296 obstack_1grow (&util_obstack, 'r');
6297 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6298 obstack_1grow (&util_obstack, 'n');
6299 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6300 obstack_1grow (&util_obstack, 'N');
6301 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6302 obstack_1grow (&util_obstack, 'o');
6303 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6304 obstack_1grow (&util_obstack, 'O');
6305 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6306 obstack_1grow (&util_obstack, 'R');
6307 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6308 obstack_1grow (&util_obstack, 'V');
6312 /* Encode a pointer type. */
6315 encode_pointer (tree type, int curtype, int format)
6317 tree pointer_to = TREE_TYPE (type);
6319 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6321 if (TYPE_NAME (pointer_to)
6322 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6324 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6326 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6328 obstack_1grow (&util_obstack, '@');
6331 else if (TREE_STATIC_TEMPLATE (pointer_to))
6333 if (generating_instance_variables)
6335 obstack_1grow (&util_obstack, '@');
6336 obstack_1grow (&util_obstack, '"');
6337 obstack_grow (&util_obstack, name, strlen (name));
6338 obstack_1grow (&util_obstack, '"');
6343 obstack_1grow (&util_obstack, '@');
6347 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6349 obstack_1grow (&util_obstack, '#');
6352 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6354 obstack_1grow (&util_obstack, ':');
6359 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6360 && TYPE_MODE (pointer_to) == QImode)
6362 obstack_1grow (&util_obstack, '*');
6366 /* We have a type that does not get special treatment. */
6368 /* NeXT extension */
6369 obstack_1grow (&util_obstack, '^');
6370 encode_type (pointer_to, curtype, format);
6374 encode_array (tree type, int curtype, int format)
6376 tree an_int_cst = TYPE_SIZE (type);
6377 tree array_of = TREE_TYPE (type);
6380 /* An incomplete array is treated like a pointer. */
6381 if (an_int_cst == NULL)
6383 encode_pointer (type, curtype, format);
6387 sprintf (buffer, "[%ld",
6388 (long) (TREE_INT_CST_LOW (an_int_cst)
6389 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6391 obstack_grow (&util_obstack, buffer, strlen (buffer));
6392 encode_type (array_of, curtype, format);
6393 obstack_1grow (&util_obstack, ']');
6398 encode_aggregate_within (tree type, int curtype, int format, int left,
6401 /* The RECORD_TYPE may in fact be a typedef! For purposes
6402 of encoding, we need the real underlying enchilada. */
6403 if (TYPE_MAIN_VARIANT (type))
6404 type = TYPE_MAIN_VARIANT (type);
6406 if (obstack_object_size (&util_obstack) > 0
6407 && *(obstack_next_free (&util_obstack) - 1) == '^')
6409 tree name = TYPE_NAME (type);
6411 /* we have a reference; this is a NeXT extension. */
6413 if (obstack_object_size (&util_obstack) - curtype == 1
6414 && format == OBJC_ENCODE_INLINE_DEFS)
6416 /* Output format of struct for first level only. */
6417 tree fields = TYPE_FIELDS (type);
6419 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6421 obstack_1grow (&util_obstack, left);
6422 obstack_grow (&util_obstack,
6423 IDENTIFIER_POINTER (name),
6424 strlen (IDENTIFIER_POINTER (name)));
6425 obstack_1grow (&util_obstack, '=');
6429 obstack_1grow (&util_obstack, left);
6430 obstack_grow (&util_obstack, "?=", 2);
6433 for ( ; fields; fields = TREE_CHAIN (fields))
6434 encode_field_decl (fields, curtype, format);
6436 obstack_1grow (&util_obstack, right);
6439 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6441 obstack_1grow (&util_obstack, left);
6442 obstack_grow (&util_obstack,
6443 IDENTIFIER_POINTER (name),
6444 strlen (IDENTIFIER_POINTER (name)));
6445 obstack_1grow (&util_obstack, right);
6450 /* We have an untagged structure or a typedef. */
6451 obstack_1grow (&util_obstack, left);
6452 obstack_1grow (&util_obstack, '?');
6453 obstack_1grow (&util_obstack, right);
6459 tree name = TYPE_NAME (type);
6460 tree fields = TYPE_FIELDS (type);
6462 if (format == OBJC_ENCODE_INLINE_DEFS
6463 || generating_instance_variables)
6465 obstack_1grow (&util_obstack, left);
6466 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6467 obstack_grow (&util_obstack,
6468 IDENTIFIER_POINTER (name),
6469 strlen (IDENTIFIER_POINTER (name)));
6471 obstack_1grow (&util_obstack, '?');
6473 obstack_1grow (&util_obstack, '=');
6475 for (; fields; fields = TREE_CHAIN (fields))
6477 if (generating_instance_variables)
6479 tree fname = DECL_NAME (fields);
6481 obstack_1grow (&util_obstack, '"');
6482 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6484 obstack_grow (&util_obstack,
6485 IDENTIFIER_POINTER (fname),
6486 strlen (IDENTIFIER_POINTER (fname)));
6489 obstack_1grow (&util_obstack, '"');
6492 encode_field_decl (fields, curtype, format);
6495 obstack_1grow (&util_obstack, right);
6500 obstack_1grow (&util_obstack, left);
6501 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6502 obstack_grow (&util_obstack,
6503 IDENTIFIER_POINTER (name),
6504 strlen (IDENTIFIER_POINTER (name)));
6506 /* We have an untagged structure or a typedef. */
6507 obstack_1grow (&util_obstack, '?');
6509 obstack_1grow (&util_obstack, right);
6515 encode_aggregate (tree type, int curtype, int format)
6517 enum tree_code code = TREE_CODE (type);
6523 encode_aggregate_within(type, curtype, format, '{', '}');
6528 encode_aggregate_within(type, curtype, format, '(', ')');
6533 obstack_1grow (&util_obstack, 'i');
6541 /* Support bitfields. The current version of Objective-C does not support
6542 them. The string will consist of one or more "b:n"'s where n is an
6543 integer describing the width of the bitfield. Currently, classes in
6544 the kit implement a method "-(char *)describeBitfieldStruct:" that
6545 simulates this. If they do not implement this method, the archiver
6546 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6547 according to the GNU compiler. After looking at the "kit", it appears
6548 that all classes currently rely on this default behavior, rather than
6549 hand generating this string (which is tedious). */
6552 encode_bitfield (int width)
6555 sprintf (buffer, "b%d", width);
6556 obstack_grow (&util_obstack, buffer, strlen (buffer));
6559 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6562 encode_type (tree type, int curtype, int format)
6564 enum tree_code code = TREE_CODE (type);
6566 if (code == INTEGER_TYPE)
6568 if (integer_zerop (TYPE_MIN_VALUE (type)))
6570 /* Unsigned integer types. */
6572 if (TYPE_MODE (type) == QImode)
6573 obstack_1grow (&util_obstack, 'C');
6574 else if (TYPE_MODE (type) == HImode)
6575 obstack_1grow (&util_obstack, 'S');
6576 else if (TYPE_MODE (type) == SImode)
6578 if (type == long_unsigned_type_node)
6579 obstack_1grow (&util_obstack, 'L');
6581 obstack_1grow (&util_obstack, 'I');
6583 else if (TYPE_MODE (type) == DImode)
6584 obstack_1grow (&util_obstack, 'Q');
6588 /* Signed integer types. */
6590 if (TYPE_MODE (type) == QImode)
6591 obstack_1grow (&util_obstack, 'c');
6592 else if (TYPE_MODE (type) == HImode)
6593 obstack_1grow (&util_obstack, 's');
6594 else if (TYPE_MODE (type) == SImode)
6596 if (type == long_integer_type_node)
6597 obstack_1grow (&util_obstack, 'l');
6599 obstack_1grow (&util_obstack, 'i');
6602 else if (TYPE_MODE (type) == DImode)
6603 obstack_1grow (&util_obstack, 'q');
6607 else if (code == REAL_TYPE)
6609 /* Floating point types. */
6611 if (TYPE_MODE (type) == SFmode)
6612 obstack_1grow (&util_obstack, 'f');
6613 else if (TYPE_MODE (type) == DFmode
6614 || TYPE_MODE (type) == TFmode)
6615 obstack_1grow (&util_obstack, 'd');
6618 else if (code == VOID_TYPE)
6619 obstack_1grow (&util_obstack, 'v');
6621 else if (code == ARRAY_TYPE)
6622 encode_array (type, curtype, format);
6624 else if (code == POINTER_TYPE)
6625 encode_pointer (type, curtype, format);
6627 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6628 encode_aggregate (type, curtype, format);
6630 else if (code == FUNCTION_TYPE) /* '?' */
6631 obstack_1grow (&util_obstack, '?');
6635 encode_complete_bitfield (int position, tree type, int size)
6637 enum tree_code code = TREE_CODE (type);
6639 char charType = '?';
6641 if (code == INTEGER_TYPE)
6643 if (integer_zerop (TYPE_MIN_VALUE (type)))
6645 /* Unsigned integer types. */
6647 if (TYPE_MODE (type) == QImode)
6649 else if (TYPE_MODE (type) == HImode)
6651 else if (TYPE_MODE (type) == SImode)
6653 if (type == long_unsigned_type_node)
6658 else if (TYPE_MODE (type) == DImode)
6663 /* Signed integer types. */
6665 if (TYPE_MODE (type) == QImode)
6667 else if (TYPE_MODE (type) == HImode)
6669 else if (TYPE_MODE (type) == SImode)
6671 if (type == long_integer_type_node)
6677 else if (TYPE_MODE (type) == DImode)
6681 else if (code == ENUMERAL_TYPE)
6686 sprintf (buffer, "b%d%c%d", position, charType, size);
6687 obstack_grow (&util_obstack, buffer, strlen (buffer));
6691 encode_field_decl (tree field_decl, int curtype, int format)
6695 type = TREE_TYPE (field_decl);
6697 /* If this field is obviously a bitfield, or is a bitfield that has been
6698 clobbered to look like a ordinary integer mode, go ahead and generate
6699 the bitfield typing information. */
6700 if (flag_next_runtime)
6702 if (DECL_BIT_FIELD_TYPE (field_decl))
6703 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6705 encode_type (TREE_TYPE (field_decl), curtype, format);
6709 if (DECL_BIT_FIELD_TYPE (field_decl))
6710 encode_complete_bitfield (int_bit_position (field_decl),
6711 DECL_BIT_FIELD_TYPE (field_decl),
6712 tree_low_cst (DECL_SIZE (field_decl), 1));
6714 encode_type (TREE_TYPE (field_decl), curtype, format);
6719 objc_expr_last (tree complex_expr)
6724 while ((next = TREE_OPERAND (complex_expr, 0)))
6725 complex_expr = next;
6727 return complex_expr;
6730 /* Transform a method definition into a function definition as follows:
6731 - synthesize the first two arguments, "self" and "_cmd". */
6734 start_method_def (tree method)
6738 /* Required to implement _msgSuper. */
6739 objc_method_context = method;
6740 UOBJC_SUPER_decl = NULL_TREE;
6742 /* Must be called BEFORE start_function. */
6745 /* Generate prototype declarations for arguments..."new-style". */
6747 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6748 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6750 /* Really a `struct objc_class *'. However, we allow people to
6751 assign to self, which changes its type midstream. */
6752 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6754 push_parm_decl (build_tree_list
6755 (build_tree_list (decl_specs,
6756 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6759 decl_specs = build_tree_list (NULL_TREE,
6760 xref_tag (RECORD_TYPE,
6761 get_identifier (TAG_SELECTOR)));
6762 push_parm_decl (build_tree_list
6763 (build_tree_list (decl_specs,
6764 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6767 /* Generate argument declarations if a keyword_decl. */
6768 if (METHOD_SEL_ARGS (method))
6770 tree arglist = METHOD_SEL_ARGS (method);
6773 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6774 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6778 tree last_expr = objc_expr_last (arg_decl);
6780 /* Unite the abstract decl with its name. */
6781 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6782 push_parm_decl (build_tree_list
6783 (build_tree_list (arg_spec, arg_decl),
6786 /* Unhook: restore the abstract declarator. */
6787 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6791 push_parm_decl (build_tree_list
6792 (build_tree_list (arg_spec,
6793 KEYWORD_ARG_NAME (arglist)),
6796 arglist = TREE_CHAIN (arglist);
6801 if (METHOD_ADD_ARGS (method) != NULL_TREE
6802 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6804 /* We have a variable length selector - in "prototype" format. */
6805 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6808 /* This must be done prior to calling pushdecl. pushdecl is
6809 going to change our chain on us. */
6810 tree nextkey = TREE_CHAIN (akey);
6818 warn_with_method (const char *message, int mtype, tree method)
6820 /* Add a readable method name to the warning. */
6821 warning ("%J%s `%c%s'", method, message, mtype,
6822 gen_method_decl (method, errbuf));
6825 /* Return 1 if METHOD is consistent with PROTO. */
6828 comp_method_with_proto (tree method, tree proto)
6830 /* Create a function template node at most once. */
6831 if (!function1_template)
6832 function1_template = make_node (FUNCTION_TYPE);
6834 /* Install argument types - normally set by build_function_type. */
6835 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6837 /* install return type */
6838 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6840 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template,
6844 /* Return 1 if PROTO1 is consistent with PROTO2. */
6847 comp_proto_with_proto (tree proto0, tree proto1)
6849 /* Create a couple of function_template nodes at most once. */
6850 if (!function1_template)
6851 function1_template = make_node (FUNCTION_TYPE);
6852 if (!function2_template)
6853 function2_template = make_node (FUNCTION_TYPE);
6855 /* Install argument types; normally set by build_function_type. */
6856 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6857 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6859 /* Install return type. */
6860 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6861 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6863 return comptypes (function1_template, function2_template, false);
6866 /* - Generate an identifier for the function. the format is "_n_cls",
6867 where 1 <= n <= nMethods, and cls is the name the implementation we
6869 - Install the return type from the method declaration.
6870 - If we have a prototype, check for type consistency. */
6873 really_start_method (tree method, tree parmlist)
6875 tree sc_spec, ret_spec, ret_decl, decl_specs;
6876 tree method_decl, method_id;
6877 const char *sel_name, *class_name, *cat_name;
6880 /* Synth the storage class & assemble the return type. */
6881 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6882 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6883 decl_specs = chainon (sc_spec, ret_spec);
6885 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6886 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6887 cat_name = ((TREE_CODE (objc_implementation_context)
6888 == CLASS_IMPLEMENTATION_TYPE)
6890 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6893 /* Make sure this is big enough for any plausible method label. */
6894 buf = alloca (50 + strlen (sel_name) + strlen (class_name)
6895 + (cat_name ? strlen (cat_name) : 0));
6897 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6898 class_name, cat_name, sel_name, method_slot);
6900 method_id = get_identifier (buf);
6902 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
6904 /* Check the declarator portion of the return type for the method. */
6905 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6907 /* Unite the complex decl (specified in the abstract decl) with the
6908 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6909 tree save_expr = objc_expr_last (ret_decl);
6911 TREE_OPERAND (save_expr, 0) = method_decl;
6912 method_decl = ret_decl;
6914 /* Fool the parser into thinking it is starting a function. */
6915 start_function (decl_specs, method_decl, NULL_TREE);
6917 /* Unhook: this has the effect of restoring the abstract declarator. */
6918 TREE_OPERAND (save_expr, 0) = NULL_TREE;
6923 TREE_VALUE (TREE_TYPE (method)) = method_decl;
6925 /* Fool the parser into thinking it is starting a function. */
6926 start_function (decl_specs, method_decl, NULL_TREE);
6928 /* Unhook: this has the effect of restoring the abstract declarator. */
6929 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
6932 METHOD_DEFINITION (method) = current_function_decl;
6934 /* Check consistency...start_function, pushdecl, duplicate_decls. */
6936 if (implementation_template != objc_implementation_context)
6940 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
6941 proto = lookup_instance_method_static (implementation_template,
6942 METHOD_SEL_NAME (method));
6944 proto = lookup_class_method_static (implementation_template,
6945 METHOD_SEL_NAME (method));
6947 if (proto && ! comp_method_with_proto (method, proto))
6949 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
6951 warn_with_method ("conflicting types for", type, method);
6952 warn_with_method ("previous declaration of", type, proto);
6957 /* The following routine is always called...this "architecture" is to
6958 accommodate "old-style" variable length selectors.
6960 - a:a b:b // prototype ; id c; id d; // old-style. */
6963 continue_method_def (void)
6967 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
6968 /* We have a `, ...' immediately following the selector. */
6969 parmlist = get_parm_info (0);
6971 parmlist = get_parm_info (1); /* place a `void_at_end' */
6973 /* Set self_decl from the first argument...this global is used by
6974 build_ivar_reference calling build_indirect_ref. */
6975 self_decl = TREE_PURPOSE (parmlist);
6978 really_start_method (objc_method_context, parmlist);
6979 store_parm_decls ();
6982 /* Called by the parser, from the `pushlevel' production. */
6985 add_objc_decls (void)
6987 if (!UOBJC_SUPER_decl)
6989 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
6990 build_tree_list (NULL_TREE,
6991 objc_super_template),
6994 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
6996 /* This prevents `unused variable' warnings when compiling with -Wall. */
6997 TREE_USED (UOBJC_SUPER_decl) = 1;
6998 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7002 /* _n_Method (id self, SEL sel, ...)
7004 struct objc_super _S;
7005 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7009 get_super_receiver (void)
7011 if (objc_method_context)
7013 tree super_expr, super_expr_list;
7015 /* Set receiver to self. */
7016 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7017 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7018 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7020 /* Set class to begin searching. */
7021 super_expr = build_component_ref (UOBJC_SUPER_decl,
7022 get_identifier ("class"));
7024 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7026 /* [_cls, __cls]Super are "pre-built" in
7027 synth_forward_declarations. */
7029 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7030 ((TREE_CODE (objc_method_context)
7031 == INSTANCE_METHOD_DECL)
7033 : uucls_super_ref));
7037 /* We have a category. */
7039 tree super_name = CLASS_SUPER_NAME (implementation_template);
7042 /* Barf if super used in a category of Object. */
7045 error ("no super class declared in interface for `%s'",
7046 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7047 return error_mark_node;
7050 if (flag_next_runtime)
7052 super_class = get_class_reference (super_name);
7053 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7054 /* Cast the super class to 'id', since the user may not have
7055 included <objc/objc-class.h>, leaving 'struct objc_class'
7056 an incomplete type. */
7058 = build_component_ref (build_indirect_ref
7059 (build_c_cast (id_type, super_class), "->"),
7060 get_identifier ("isa"));
7064 add_class_reference (super_name);
7065 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7066 ? objc_get_class_decl : objc_get_meta_class_decl);
7067 assemble_external (super_class);
7069 = build_function_call
7073 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7074 IDENTIFIER_POINTER (super_name))));
7077 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7078 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7081 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7083 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7084 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7086 return build_compound_expr (super_expr_list);
7090 error ("[super ...] must appear in a method context");
7091 return error_mark_node;
7096 encode_method_def (tree func_decl)
7100 HOST_WIDE_INT max_parm_end = 0;
7105 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7106 obstack_object_size (&util_obstack),
7107 OBJC_ENCODE_INLINE_DEFS);
7110 for (parms = DECL_ARGUMENTS (func_decl); parms;
7111 parms = TREE_CHAIN (parms))
7113 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7114 + int_size_in_bytes (TREE_TYPE (parms)));
7116 if (! offset_is_register && parm_end > max_parm_end)
7117 max_parm_end = parm_end;
7120 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7122 sprintf (buffer, "%d", stack_size);
7123 obstack_grow (&util_obstack, buffer, strlen (buffer));
7125 /* Argument types. */
7126 for (parms = DECL_ARGUMENTS (func_decl); parms;
7127 parms = TREE_CHAIN (parms))
7130 encode_type (TREE_TYPE (parms),
7131 obstack_object_size (&util_obstack),
7132 OBJC_ENCODE_INLINE_DEFS);
7134 /* Compute offset. */
7135 sprintf (buffer, "%d", forwarding_offset (parms));
7137 /* Indicate register. */
7138 if (offset_is_register)
7139 obstack_1grow (&util_obstack, '+');
7141 obstack_grow (&util_obstack, buffer, strlen (buffer));
7144 /* Null terminate string. */
7145 obstack_1grow (&util_obstack, 0);
7146 result = get_identifier (obstack_finish (&util_obstack));
7147 obstack_free (&util_obstack, util_firstobj);
7152 objc_expand_function_end (void)
7154 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7158 finish_method_def (void)
7160 lang_expand_function_end = objc_expand_function_end;
7162 lang_expand_function_end = NULL;
7164 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7165 since the optimizer may find "may be used before set" errors. */
7166 objc_method_context = NULL_TREE;
7171 lang_report_error_function (tree decl)
7173 if (objc_method_context)
7175 fprintf (stderr, "In method `%s'\n",
7176 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7186 is_complex_decl (tree type)
7188 return (TREE_CODE (type) == ARRAY_TYPE
7189 || TREE_CODE (type) == FUNCTION_TYPE
7190 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7194 /* Code to convert a decl node into text for a declaration in C. */
7196 static char tmpbuf[256];
7199 adorn_decl (tree decl, char *str)
7201 enum tree_code code = TREE_CODE (decl);
7203 if (code == ARRAY_REF)
7205 tree an_int_cst = TREE_OPERAND (decl, 1);
7207 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7208 sprintf (str + strlen (str), "[%ld]",
7209 (long) TREE_INT_CST_LOW (an_int_cst));
7214 else if (code == ARRAY_TYPE)
7216 tree an_int_cst = TYPE_SIZE (decl);
7217 tree array_of = TREE_TYPE (decl);
7219 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7220 sprintf (str + strlen (str), "[%ld]",
7221 (long) (TREE_INT_CST_LOW (an_int_cst)
7222 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7227 else if (code == CALL_EXPR)
7229 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7234 gen_declaration_1 (chain, str);
7235 chain = TREE_CHAIN (chain);
7242 else if (code == FUNCTION_TYPE)
7244 tree chain = TYPE_ARG_TYPES (decl);
7247 while (chain && TREE_VALUE (chain) != void_type_node)
7249 gen_declaration_1 (TREE_VALUE (chain), str);
7250 chain = TREE_CHAIN (chain);
7251 if (chain && TREE_VALUE (chain) != void_type_node)
7257 else if (code == INDIRECT_REF)
7259 strcpy (tmpbuf, "*");
7260 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7264 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7266 chain = TREE_CHAIN (chain))
7268 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7270 strcat (tmpbuf, " ");
7271 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7275 strcat (tmpbuf, " ");
7277 strcat (tmpbuf, str);
7278 strcpy (str, tmpbuf);
7281 else if (code == POINTER_TYPE)
7283 strcpy (tmpbuf, "*");
7284 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7286 if (TREE_READONLY (decl))
7287 strcat (tmpbuf, " const");
7288 if (TYPE_VOLATILE (decl))
7289 strcat (tmpbuf, " volatile");
7291 strcat (tmpbuf, " ");
7293 strcat (tmpbuf, str);
7294 strcpy (str, tmpbuf);
7299 gen_declarator (tree decl, char *buf, const char *name)
7303 enum tree_code code = TREE_CODE (decl);
7313 op = TREE_OPERAND (decl, 0);
7315 /* We have a pointer to a function or array...(*)(), (*)[] */
7316 if ((code == ARRAY_REF || code == CALL_EXPR)
7317 && op && TREE_CODE (op) == INDIRECT_REF)
7320 str = gen_declarator (op, buf, name);
7324 strcpy (tmpbuf, "(");
7325 strcat (tmpbuf, str);
7326 strcat (tmpbuf, ")");
7327 strcpy (str, tmpbuf);
7330 adorn_decl (decl, str);
7339 /* This clause is done iteratively rather than recursively. */
7342 op = (is_complex_decl (TREE_TYPE (decl))
7343 ? TREE_TYPE (decl) : NULL_TREE);
7345 adorn_decl (decl, str);
7347 /* We have a pointer to a function or array...(*)(), (*)[] */
7348 if (code == POINTER_TYPE
7349 && op && (TREE_CODE (op) == FUNCTION_TYPE
7350 || TREE_CODE (op) == ARRAY_TYPE))
7352 strcpy (tmpbuf, "(");
7353 strcat (tmpbuf, str);
7354 strcat (tmpbuf, ")");
7355 strcpy (str, tmpbuf);
7358 decl = (is_complex_decl (TREE_TYPE (decl))
7359 ? TREE_TYPE (decl) : NULL_TREE);
7362 while (decl && (code = TREE_CODE (decl)))
7367 case IDENTIFIER_NODE:
7368 /* Will only happen if we are processing a "raw" expr-decl. */
7369 strcpy (buf, IDENTIFIER_POINTER (decl));
7380 /* We have an abstract declarator or a _DECL node. */
7388 gen_declspecs (tree declspecs, char *buf, int raw)
7394 for (chain = nreverse (copy_list (declspecs));
7395 chain; chain = TREE_CHAIN (chain))
7397 tree aspec = TREE_VALUE (chain);
7399 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7400 strcat (buf, IDENTIFIER_POINTER (aspec));
7401 else if (TREE_CODE (aspec) == RECORD_TYPE)
7403 if (TYPE_NAME (aspec))
7405 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7407 if (! TREE_STATIC_TEMPLATE (aspec))
7408 strcat (buf, "struct ");
7409 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7414 tree chain = protocol_list;
7421 (PROTOCOL_NAME (TREE_VALUE (chain))));
7422 chain = TREE_CHAIN (chain);
7431 strcat (buf, "untagged struct");
7434 else if (TREE_CODE (aspec) == UNION_TYPE)
7436 if (TYPE_NAME (aspec))
7438 if (! TREE_STATIC_TEMPLATE (aspec))
7439 strcat (buf, "union ");
7440 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7443 strcat (buf, "untagged union");
7446 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7448 if (TYPE_NAME (aspec))
7450 if (! TREE_STATIC_TEMPLATE (aspec))
7451 strcat (buf, "enum ");
7452 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7455 strcat (buf, "untagged enum");
7458 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7459 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7461 else if (IS_ID (aspec))
7463 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7468 tree chain = protocol_list;
7475 (PROTOCOL_NAME (TREE_VALUE (chain))));
7476 chain = TREE_CHAIN (chain);
7483 if (TREE_CHAIN (chain))
7489 /* Type qualifiers. */
7490 if (TREE_READONLY (declspecs))
7491 strcat (buf, "const ");
7492 if (TYPE_VOLATILE (declspecs))
7493 strcat (buf, "volatile ");
7495 switch (TREE_CODE (declspecs))
7497 /* Type specifiers. */
7500 declspecs = TYPE_MAIN_VARIANT (declspecs);
7502 /* Signed integer types. */
7504 if (declspecs == short_integer_type_node)
7505 strcat (buf, "short int ");
7506 else if (declspecs == integer_type_node)
7507 strcat (buf, "int ");
7508 else if (declspecs == long_integer_type_node)
7509 strcat (buf, "long int ");
7510 else if (declspecs == long_long_integer_type_node)
7511 strcat (buf, "long long int ");
7512 else if (declspecs == signed_char_type_node
7513 || declspecs == char_type_node)
7514 strcat (buf, "char ");
7516 /* Unsigned integer types. */
7518 else if (declspecs == short_unsigned_type_node)
7519 strcat (buf, "unsigned short ");
7520 else if (declspecs == unsigned_type_node)
7521 strcat (buf, "unsigned int ");
7522 else if (declspecs == long_unsigned_type_node)
7523 strcat (buf, "unsigned long ");
7524 else if (declspecs == long_long_unsigned_type_node)
7525 strcat (buf, "unsigned long long ");
7526 else if (declspecs == unsigned_char_type_node)
7527 strcat (buf, "unsigned char ");
7531 declspecs = TYPE_MAIN_VARIANT (declspecs);
7533 if (declspecs == float_type_node)
7534 strcat (buf, "float ");
7535 else if (declspecs == double_type_node)
7536 strcat (buf, "double ");
7537 else if (declspecs == long_double_type_node)
7538 strcat (buf, "long double ");
7542 if (TYPE_NAME (declspecs)
7543 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7545 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7547 if (! TREE_STATIC_TEMPLATE (declspecs))
7548 strcat (buf, "struct ");
7549 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7553 tree chain = protocol_list;
7560 (PROTOCOL_NAME (TREE_VALUE (chain))));
7561 chain = TREE_CHAIN (chain);
7570 strcat (buf, "untagged struct");
7576 if (TYPE_NAME (declspecs)
7577 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7579 strcat (buf, "union ");
7580 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7585 strcat (buf, "untagged union ");
7589 if (TYPE_NAME (declspecs)
7590 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7592 strcat (buf, "enum ");
7593 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7598 strcat (buf, "untagged enum ");
7602 strcat (buf, "void ");
7607 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7612 tree chain = protocol_list;
7619 (PROTOCOL_NAME (TREE_VALUE (chain))));
7620 chain = TREE_CHAIN (chain);
7636 /* Given a tree node, produce a printable description of it in the given
7637 buffer, overwriting the buffer. */
7640 gen_declaration (tree atype_or_adecl, char *buf)
7643 gen_declaration_1 (atype_or_adecl, buf);
7647 /* Given a tree node, append a printable description to the end of the
7651 gen_declaration_1 (tree atype_or_adecl, char *buf)
7655 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7657 tree declspecs; /* "identifier_node", "record_type" */
7658 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7660 /* We have a "raw", abstract declarator (typename). */
7661 declarator = TREE_VALUE (atype_or_adecl);
7662 declspecs = TREE_PURPOSE (atype_or_adecl);
7664 gen_declspecs (declspecs, buf, 1);
7668 strcat (buf, gen_declarator (declarator, declbuf, ""));
7675 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7676 tree declarator; /* "array_type", "function_type", "pointer_type". */
7678 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7679 || TREE_CODE (atype_or_adecl) == PARM_DECL
7680 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7681 atype = TREE_TYPE (atype_or_adecl);
7683 /* Assume we have a *_type node. */
7684 atype = atype_or_adecl;
7686 if (is_complex_decl (atype))
7690 /* Get the declaration specifier; it is at the end of the list. */
7691 declarator = chain = atype;
7693 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7694 while (is_complex_decl (chain));
7701 declarator = NULL_TREE;
7704 gen_declspecs (declspecs, buf, 0);
7706 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7707 || TREE_CODE (atype_or_adecl) == PARM_DECL
7708 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7710 const char *const decl_name =
7711 (DECL_NAME (atype_or_adecl)
7712 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7717 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7720 else if (decl_name[0])
7723 strcat (buf, decl_name);
7726 else if (declarator)
7729 strcat (buf, gen_declarator (declarator, declbuf, ""));
7734 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7736 /* Given a method tree, put a printable description into the given
7737 buffer (overwriting) and return a pointer to the buffer. */
7740 gen_method_decl (tree method, char *buf)
7745 if (RAW_TYPESPEC (method) != objc_object_reference)
7748 gen_declaration_1 (TREE_TYPE (method), buf);
7752 chain = METHOD_SEL_ARGS (method);
7755 /* We have a chain of keyword_decls. */
7758 if (KEYWORD_KEY_NAME (chain))
7759 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7762 if (RAW_TYPESPEC (chain) != objc_object_reference)
7765 gen_declaration_1 (TREE_TYPE (chain), buf);
7769 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7770 if ((chain = TREE_CHAIN (chain)))
7775 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7776 strcat (buf, ", ...");
7777 else if (METHOD_ADD_ARGS (method))
7779 /* We have a tree list node as generate by get_parm_info. */
7780 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7782 /* Know we have a chain of parm_decls. */
7786 gen_declaration_1 (chain, buf);
7787 chain = TREE_CHAIN (chain);
7793 /* We have a unary selector. */
7794 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7802 /* Dump an @interface declaration of the supplied class CHAIN to the
7803 supplied file FP. Used to implement the -gen-decls option (which
7804 prints out an @interface declaration of all classes compiled in
7805 this run); potentially useful for debugging the compiler too. */
7807 dump_interface (FILE *fp, tree chain)
7809 /* FIXME: A heap overflow here whenever a method (or ivar)
7810 declaration is so long that it doesn't fit in the buffer. The
7811 code and all the related functions should be rewritten to avoid
7812 using fixed size buffers. */
7813 char *buf = xmalloc (1024 * 10);
7814 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7815 tree ivar_decls = CLASS_RAW_IVARS (chain);
7816 tree nst_methods = CLASS_NST_METHODS (chain);
7817 tree cls_methods = CLASS_CLS_METHODS (chain);
7819 fprintf (fp, "\n@interface %s", my_name);
7821 /* CLASS_SUPER_NAME is used to store the superclass name for
7822 classes, and the category name for categories. */
7823 if (CLASS_SUPER_NAME (chain))
7825 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7827 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
7828 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
7830 fprintf (fp, " (%s)\n", name);
7834 fprintf (fp, " : %s\n", name);
7840 /* FIXME - the following doesn't seem to work at the moment. */
7843 fprintf (fp, "{\n");
7846 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7847 ivar_decls = TREE_CHAIN (ivar_decls);
7850 fprintf (fp, "}\n");
7855 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7856 nst_methods = TREE_CHAIN (nst_methods);
7861 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7862 cls_methods = TREE_CHAIN (cls_methods);
7865 fprintf (fp, "@end\n");
7868 /* Demangle function for Objective-C */
7870 objc_demangle (const char *mangled)
7872 char *demangled, *cp;
7874 if (mangled[0] == '_' &&
7875 (mangled[1] == 'i' || mangled[1] == 'c') &&
7878 cp = demangled = xmalloc(strlen(mangled) + 2);
7879 if (mangled[1] == 'i')
7880 *cp++ = '-'; /* for instance method */
7882 *cp++ = '+'; /* for class method */
7883 *cp++ = '['; /* opening left brace */
7884 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
7885 while (*cp && *cp == '_')
7886 cp++; /* skip any initial underbars in class name */
7887 cp = strchr(cp, '_'); /* find first non-initial underbar */
7890 free(demangled); /* not mangled name */
7893 if (cp[1] == '_') /* easy case: no category name */
7895 *cp++ = ' '; /* replace two '_' with one ' ' */
7896 strcpy(cp, mangled + (cp - demangled) + 2);
7900 *cp++ = '('; /* less easy case: category name */
7901 cp = strchr(cp, '_');
7904 free(demangled); /* not mangled name */
7908 *cp++ = ' '; /* overwriting 1st char of method name... */
7909 strcpy(cp, mangled + (cp - demangled)); /* get it back */
7911 while (*cp && *cp == '_')
7912 cp++; /* skip any initial underbars in method name */
7915 *cp = ':'; /* replace remaining '_' with ':' */
7916 *cp++ = ']'; /* closing right brace */
7917 *cp++ = 0; /* string terminator */
7921 return mangled; /* not an objc mangled name */
7925 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
7927 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
7933 gcc_obstack_init (&util_obstack);
7934 util_firstobj = (char *) obstack_finish (&util_obstack);
7936 errbuf = xmalloc (BUFSIZE);
7938 synth_module_prologue ();
7944 struct imp_entry *impent;
7946 /* The internally generated initializers appear to have missing braces.
7947 Don't warn about this. */
7948 int save_warn_missing_braces = warn_missing_braces;
7949 warn_missing_braces = 0;
7951 /* A missing @end may not be detected by the parser. */
7952 if (objc_implementation_context)
7954 warning ("`@end' missing in implementation context");
7955 finish_class (objc_implementation_context);
7956 objc_ivar_chain = NULL_TREE;
7957 objc_implementation_context = NULL_TREE;
7960 generate_forward_declaration_to_string_table ();
7962 /* Process the static instances here because initialization of objc_symtab
7964 if (objc_static_instances)
7965 generate_static_references ();
7967 if (imp_list || class_names_chain
7968 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7969 generate_objc_symtab_decl ();
7971 for (impent = imp_list; impent; impent = impent->next)
7973 objc_implementation_context = impent->imp_context;
7974 implementation_template = impent->imp_template;
7976 UOBJC_CLASS_decl = impent->class_decl;
7977 UOBJC_METACLASS_decl = impent->meta_decl;
7979 /* Dump the @interface of each class as we compile it, if the
7980 -gen-decls option is in use. TODO: Dump the classes in the
7981 order they were found, rather than in reverse order as we
7983 if (flag_gen_declaration)
7985 dump_interface (gen_declaration_file, objc_implementation_context);
7988 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7990 /* all of the following reference the string pool... */
7991 generate_ivar_lists ();
7992 generate_dispatch_tables ();
7993 generate_shared_structures ();
7997 generate_dispatch_tables ();
7998 generate_category (objc_implementation_context);
8002 /* If we are using an array of selectors, we must always
8003 finish up the array decl even if no selectors were used. */
8004 if (! flag_next_runtime || sel_ref_chain)
8005 build_selector_translation_table ();
8008 generate_protocols ();
8010 if (objc_implementation_context || class_names_chain || objc_static_instances
8011 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8013 /* Arrange for ObjC data structures to be initialized at run time. */
8014 rtx init_sym = build_module_descriptor ();
8015 if (init_sym && targetm.have_ctors_dtors)
8016 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8019 /* Dump the class references. This forces the appropriate classes
8020 to be linked into the executable image, preserving unix archive
8021 semantics. This can be removed when we move to a more dynamically
8022 linked environment. */
8024 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8026 handle_class_ref (chain);
8027 if (TREE_PURPOSE (chain))
8028 generate_classref_translation_entry (chain);
8031 for (impent = imp_list; impent; impent = impent->next)
8032 handle_impent (impent);
8034 /* Dump the string table last. */
8036 generate_strings ();
8043 /* Run through the selector hash tables and print a warning for any
8044 selector which has multiple methods. */
8046 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8047 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8050 tree meth = hsh->key;
8051 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8055 warning ("potential selector conflict for method `%s'",
8056 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8057 warn_with_method ("found", type, meth);
8058 for (loop = hsh->list; loop; loop = loop->next)
8059 warn_with_method ("found", type, loop->value);
8062 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8063 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8066 tree meth = hsh->key;
8067 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8071 warning ("potential selector conflict for method `%s'",
8072 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8073 warn_with_method ("found", type, meth);
8074 for (loop = hsh->list; loop; loop = loop->next)
8075 warn_with_method ("found", type, loop->value);
8079 warn_missing_braces = save_warn_missing_braces;
8082 /* Subroutines of finish_objc. */
8085 generate_classref_translation_entry (tree chain)
8087 tree expr, name, decl_specs, decl, sc_spec;
8090 type = TREE_TYPE (TREE_PURPOSE (chain));
8092 expr = add_objc_string (TREE_VALUE (chain), class_names);
8093 expr = build_c_cast (type, expr); /* cast! */
8095 name = DECL_NAME (TREE_PURPOSE (chain));
8097 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8099 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8100 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8102 /* The decl that is returned from start_decl is the one that we
8103 forward declared in build_class_reference. */
8104 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8105 DECL_CONTEXT (decl) = NULL_TREE;
8106 finish_decl (decl, expr, NULL_TREE);
8111 handle_class_ref (tree chain)
8113 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8114 char *string = alloca (strlen (name) + 30);
8118 sprintf (string, "%sobjc_class_name_%s",
8119 (flag_next_runtime ? "." : "__"), name);
8121 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8122 if (flag_next_runtime)
8124 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8129 /* Make a decl for this name, so we can use its address in a tree. */
8130 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8131 DECL_EXTERNAL (decl) = 1;
8132 TREE_PUBLIC (decl) = 1;
8135 rest_of_decl_compilation (decl, 0, 0, 0);
8137 /* Make a decl for the address. */
8138 sprintf (string, "%sobjc_class_ref_%s",
8139 (flag_next_runtime ? "." : "__"), name);
8140 exp = build1 (ADDR_EXPR, string_type_node, decl);
8141 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8142 DECL_INITIAL (decl) = exp;
8143 TREE_STATIC (decl) = 1;
8144 TREE_USED (decl) = 1;
8147 rest_of_decl_compilation (decl, 0, 0, 0);
8151 handle_impent (struct imp_entry *impent)
8155 objc_implementation_context = impent->imp_context;
8156 implementation_template = impent->imp_template;
8158 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8160 const char *const class_name =
8161 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8163 string = alloca (strlen (class_name) + 30);
8165 sprintf (string, "%sobjc_class_name_%s",
8166 (flag_next_runtime ? "." : "__"), class_name);
8168 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8170 const char *const class_name =
8171 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8172 const char *const class_super_name =
8173 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8175 string = alloca (strlen (class_name)
8176 + strlen (class_super_name) + 30);
8178 /* Do the same for categories. Even though no references to
8179 these symbols are generated automatically by the compiler, it
8180 gives you a handle to pull them into an archive by hand. */
8181 sprintf (string, "*%sobjc_category_name_%s_%s",
8182 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8187 #ifdef ASM_DECLARE_CLASS_REFERENCE
8188 if (flag_next_runtime)
8190 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8198 init = build_int_2 (0, 0);
8199 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8200 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8201 TREE_PUBLIC (decl) = 1;
8202 TREE_READONLY (decl) = 1;
8203 TREE_USED (decl) = 1;
8204 TREE_CONSTANT (decl) = 1;
8205 DECL_CONTEXT (decl) = 0;
8206 DECL_ARTIFICIAL (decl) = 1;
8207 DECL_INITIAL (decl) = init;
8208 assemble_variable (decl, 1, 0, 0);
8212 /* Look up ID as an instance variable. */
8214 lookup_objc_ivar (tree id)
8218 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8219 /* We have a message to super. */
8220 return get_super_receiver ();
8221 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8223 if (is_private (decl))
8224 return error_mark_node;
8226 return build_ivar_reference (id);
8232 #include "gt-objc-objc-act.h"
8233 #include "gtype-objc.h"