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 /* Adjust line number for warning message. */
1988 int save_lineno = input_line;
1989 if (flag_next_runtime && TREE_PURPOSE (chain))
1990 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
1991 warning ("creating selector for non existant method %s",
1992 IDENTIFIER_POINTER (TREE_VALUE (chain)));
1993 input_line = save_lineno;
1997 expr = build_selector (TREE_VALUE (chain));
1999 if (flag_next_runtime)
2001 name = DECL_NAME (TREE_PURPOSE (chain));
2003 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2005 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2006 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2010 /* The `decl' that is returned from start_decl is the one that we
2011 forward declared in `build_selector_reference' */
2012 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2015 /* add one for the '\0' character */
2016 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2018 if (flag_next_runtime)
2019 finish_decl (decl, expr, NULL_TREE);
2022 if (flag_typed_selectors)
2024 tree eltlist = NULL_TREE;
2025 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2026 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2027 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2028 expr = objc_build_constructor (objc_selector_template,
2029 nreverse (eltlist));
2031 initlist = tree_cons (NULL_TREE, expr, initlist);
2036 if (! flag_next_runtime)
2038 /* Cause the variable and its initial value to be actually output. */
2039 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2040 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2041 /* NULL terminate the list and fix the decl for output. */
2042 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2043 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2044 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2045 nreverse (initlist));
2046 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2047 current_function_decl = NULL_TREE;
2052 get_proto_encoding (tree proto)
2059 if (! METHOD_ENCODING (proto))
2061 tmp_decl = build_tmp_function_decl ();
2062 hack_method_prototype (proto, tmp_decl);
2063 encoding = encode_method_prototype (proto, tmp_decl);
2064 METHOD_ENCODING (proto) = encoding;
2067 encoding = METHOD_ENCODING (proto);
2069 return add_objc_string (encoding, meth_var_types);
2072 return build_int_2 (0, 0);
2075 /* sel_ref_chain is a list whose "value" fields will be instances of
2076 identifier_node that represent the selector. */
2079 build_typed_selector_reference (tree ident, tree prototype)
2081 tree *chain = &sel_ref_chain;
2087 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2088 goto return_at_index;
2091 chain = &TREE_CHAIN (*chain);
2094 *chain = tree_cons (prototype, ident, NULL_TREE);
2097 expr = build_unary_op (ADDR_EXPR,
2098 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2099 build_int_2 (index, 0)),
2101 return build_c_cast (selector_type, expr);
2105 build_selector_reference (tree ident)
2107 tree *chain = &sel_ref_chain;
2113 if (TREE_VALUE (*chain) == ident)
2114 return (flag_next_runtime
2115 ? TREE_PURPOSE (*chain)
2116 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2117 build_int_2 (index, 0)));
2120 chain = &TREE_CHAIN (*chain);
2123 expr = build_selector_reference_decl ();
2125 *chain = tree_cons (expr, ident, NULL_TREE);
2127 return (flag_next_runtime
2129 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2130 build_int_2 (index, 0)));
2133 static GTY(()) int class_reference_idx;
2135 build_class_reference_decl (void)
2140 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2142 ident = get_identifier (buf);
2144 decl = build_decl (VAR_DECL, ident, objc_class_type);
2145 DECL_EXTERNAL (decl) = 1;
2146 TREE_PUBLIC (decl) = 0;
2147 TREE_USED (decl) = 1;
2148 TREE_READONLY (decl) = 1;
2149 DECL_CONTEXT (decl) = 0;
2150 DECL_ARTIFICIAL (decl) = 1;
2152 make_decl_rtl (decl, 0);
2153 pushdecl_top_level (decl);
2158 /* Create a class reference, but don't create a variable to reference
2162 add_class_reference (tree ident)
2166 if ((chain = cls_ref_chain))
2171 if (ident == TREE_VALUE (chain))
2175 chain = TREE_CHAIN (chain);
2179 /* Append to the end of the list */
2180 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2183 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2186 /* Get a class reference, creating it if necessary. Also create the
2187 reference variable. */
2190 get_class_reference (tree ident)
2192 if (flag_next_runtime)
2197 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2198 if (TREE_VALUE (*chain) == ident)
2200 if (! TREE_PURPOSE (*chain))
2201 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2203 return TREE_PURPOSE (*chain);
2206 decl = build_class_reference_decl ();
2207 *chain = tree_cons (decl, ident, NULL_TREE);
2214 add_class_reference (ident);
2216 params = build_tree_list (NULL_TREE,
2217 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2218 IDENTIFIER_POINTER (ident)));
2220 assemble_external (objc_get_class_decl);
2221 return build_function_call (objc_get_class_decl, params);
2225 /* For each string section we have a chain which maps identifier nodes
2226 to decls for the strings. */
2229 add_objc_string (tree ident, enum string_section section)
2233 if (section == class_names)
2234 chain = &class_names_chain;
2235 else if (section == meth_var_names)
2236 chain = &meth_var_names_chain;
2237 else if (section == meth_var_types)
2238 chain = &meth_var_types_chain;
2244 if (TREE_VALUE (*chain) == ident)
2245 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2247 chain = &TREE_CHAIN (*chain);
2250 decl = build_objc_string_decl (section);
2252 *chain = tree_cons (decl, ident, NULL_TREE);
2254 return build_unary_op (ADDR_EXPR, decl, 1);
2257 static GTY(()) int class_names_idx;
2258 static GTY(()) int meth_var_names_idx;
2259 static GTY(()) int meth_var_types_idx;
2262 build_objc_string_decl (enum string_section section)
2267 if (section == class_names)
2268 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2269 else if (section == meth_var_names)
2270 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2271 else if (section == meth_var_types)
2272 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2274 ident = get_identifier (buf);
2276 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2277 DECL_EXTERNAL (decl) = 1;
2278 TREE_PUBLIC (decl) = 0;
2279 TREE_USED (decl) = 1;
2280 TREE_READONLY (decl) = 1;
2281 TREE_CONSTANT (decl) = 1;
2282 DECL_CONTEXT (decl) = 0;
2283 DECL_ARTIFICIAL (decl) = 1;
2285 make_decl_rtl (decl, 0);
2286 pushdecl_top_level (decl);
2293 objc_declare_alias (tree alias_ident, tree class_ident)
2295 if (is_class_name (class_ident) != class_ident)
2296 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2297 else if (is_class_name (alias_ident))
2298 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2300 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2304 objc_declare_class (tree ident_list)
2308 for (list = ident_list; list; list = TREE_CHAIN (list))
2310 tree ident = TREE_VALUE (list);
2313 if ((decl = lookup_name (ident)))
2315 error ("`%s' redeclared as different kind of symbol",
2316 IDENTIFIER_POINTER (ident));
2317 error ("%Jprevious declaration of '%D'", decl, decl);
2320 if (! is_class_name (ident))
2322 tree record = xref_tag (RECORD_TYPE, ident);
2323 TREE_STATIC_TEMPLATE (record) = 1;
2324 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2330 is_class_name (tree ident)
2334 if (lookup_interface (ident))
2337 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2339 if (ident == TREE_VALUE (chain))
2343 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2345 if (ident == TREE_VALUE (chain))
2346 return TREE_PURPOSE (chain);
2353 objc_is_id (tree ident)
2355 /* NB: This function may be called before the ObjC front-end
2356 has been initialized, in which case ID_TYPE will be NULL. */
2357 return (id_type && ident && TYPE_P (ident) && IS_ID (ident))
2363 lookup_interface (tree ident)
2367 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2369 if (ident == CLASS_NAME (chain))
2375 /* Used by: build_private_template, continue_class,
2376 and for @defs constructs. */
2379 get_class_ivars (tree interface)
2381 tree my_name, super_name, ivar_chain;
2383 my_name = CLASS_NAME (interface);
2384 super_name = CLASS_SUPER_NAME (interface);
2385 ivar_chain = CLASS_IVARS (interface);
2387 /* Save off a pristine copy of the leaf ivars (i.e, those not
2388 inherited from a super class). */
2389 if (!CLASS_OWN_IVARS (interface))
2390 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2395 tree super_interface = lookup_interface (super_name);
2397 if (!super_interface)
2399 /* fatal did not work with 2 args...should fix */
2400 error ("cannot find interface declaration for `%s', superclass of `%s'",
2401 IDENTIFIER_POINTER (super_name),
2402 IDENTIFIER_POINTER (my_name));
2403 exit (FATAL_EXIT_CODE);
2406 if (super_interface == interface)
2407 fatal_error ("circular inheritance in interface declaration for `%s'",
2408 IDENTIFIER_POINTER (super_name));
2410 interface = super_interface;
2411 my_name = CLASS_NAME (interface);
2412 super_name = CLASS_SUPER_NAME (interface);
2414 op1 = CLASS_OWN_IVARS (interface);
2417 tree head = copy_list (op1);
2419 /* Prepend super class ivars...make a copy of the list, we
2420 do not want to alter the original. */
2421 chainon (head, ivar_chain);
2428 /* struct <classname> {
2429 struct objc_class *isa;
2434 build_private_template (tree class)
2438 if (CLASS_STATIC_TEMPLATE (class))
2440 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2441 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2445 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2447 ivar_context = get_class_ivars (class);
2449 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2451 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2453 /* mark this record as class template - for class type checking */
2454 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2458 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2460 build1 (INDIRECT_REF, NULL_TREE,
2463 return ivar_context;
2466 /* Begin code generation for protocols... */
2468 /* struct objc_protocol {
2469 char *protocol_name;
2470 struct objc_protocol **protocol_list;
2471 struct objc_method_desc *instance_methods;
2472 struct objc_method_desc *class_methods;
2476 build_protocol_template (void)
2478 tree decl_specs, field_decl, field_decl_chain;
2481 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2483 /* struct objc_class *isa; */
2485 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2486 get_identifier (UTAG_CLASS)));
2487 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2488 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2489 field_decl_chain = field_decl;
2491 /* char *protocol_name; */
2493 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2495 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2496 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2497 chainon (field_decl_chain, field_decl);
2499 /* struct objc_protocol **protocol_list; */
2501 decl_specs = build_tree_list (NULL_TREE, template);
2503 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2504 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2505 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2506 chainon (field_decl_chain, field_decl);
2508 /* struct objc_method_list *instance_methods; */
2511 = build_tree_list (NULL_TREE,
2512 xref_tag (RECORD_TYPE,
2513 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2515 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2516 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2517 chainon (field_decl_chain, field_decl);
2519 /* struct objc_method_list *class_methods; */
2522 = build_tree_list (NULL_TREE,
2523 xref_tag (RECORD_TYPE,
2524 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2526 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2527 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2528 chainon (field_decl_chain, field_decl);
2530 return finish_struct (template, field_decl_chain, NULL_TREE);
2534 build_descriptor_table_initializer (tree type, tree entries)
2536 tree initlist = NULL_TREE;
2540 tree eltlist = NULL_TREE;
2543 = tree_cons (NULL_TREE,
2544 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2546 = tree_cons (NULL_TREE,
2547 add_objc_string (METHOD_ENCODING (entries),
2552 = tree_cons (NULL_TREE,
2553 objc_build_constructor (type, nreverse (eltlist)),
2556 entries = TREE_CHAIN (entries);
2560 return objc_build_constructor (build_array_type (type, 0),
2561 nreverse (initlist));
2564 /* struct objc_method_prototype_list {
2566 struct objc_method_prototype {
2573 build_method_prototype_list_template (tree list_type, int size)
2575 tree objc_ivar_list_record;
2576 tree decl_specs, field_decl, field_decl_chain;
2578 /* Generate an unnamed struct definition. */
2580 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2582 /* int method_count; */
2584 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2585 field_decl = get_identifier ("method_count");
2586 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2587 field_decl_chain = field_decl;
2589 /* struct objc_method method_list[]; */
2591 decl_specs = build_tree_list (NULL_TREE, list_type);
2592 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2593 build_int_2 (size, 0));
2594 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2595 chainon (field_decl_chain, field_decl);
2597 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2599 return objc_ivar_list_record;
2603 build_method_prototype_template (void)
2606 tree decl_specs, field_decl, field_decl_chain;
2609 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2611 /* struct objc_selector *_cmd; */
2612 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2613 get_identifier (TAG_SELECTOR)), NULL_TREE);
2614 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2615 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2616 field_decl_chain = field_decl;
2618 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2620 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2621 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
2622 chainon (field_decl_chain, field_decl);
2624 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2626 return proto_record;
2629 /* True if last call to forwarding_offset yielded a register offset. */
2630 static int offset_is_register;
2633 forwarding_offset (tree parm)
2635 int offset_in_bytes;
2637 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2639 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2641 /* ??? Here we assume that the parm address is indexed
2642 off the frame pointer or arg pointer.
2643 If that is not true, we produce meaningless results,
2644 but do not crash. */
2645 if (GET_CODE (addr) == PLUS
2646 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2647 offset_in_bytes = INTVAL (XEXP (addr, 1));
2649 offset_in_bytes = 0;
2651 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2652 offset_is_register = 0;
2654 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2656 int regno = REGNO (DECL_INCOMING_RTL (parm));
2657 offset_in_bytes = apply_args_register_offset (regno);
2658 offset_is_register = 1;
2663 /* This is the case where the parm is passed as an int or double
2664 and it is converted to a char, short or float and stored back
2665 in the parmlist. In this case, describe the parm
2666 with the variable's declared type, and adjust the address
2667 if the least significant bytes (which we are using) are not
2669 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2670 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2671 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2673 return offset_in_bytes;
2677 encode_method_prototype (tree method_decl, tree func_decl)
2682 HOST_WIDE_INT max_parm_end = 0;
2686 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2687 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2690 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2691 obstack_object_size (&util_obstack),
2692 OBJC_ENCODE_INLINE_DEFS);
2695 for (parms = DECL_ARGUMENTS (func_decl); parms;
2696 parms = TREE_CHAIN (parms))
2698 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2699 + int_size_in_bytes (TREE_TYPE (parms)));
2701 if (!offset_is_register && max_parm_end < parm_end)
2702 max_parm_end = parm_end;
2705 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2707 sprintf (buf, "%d", stack_size);
2708 obstack_grow (&util_obstack, buf, strlen (buf));
2710 user_args = METHOD_SEL_ARGS (method_decl);
2712 /* Argument types. */
2713 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2714 parms = TREE_CHAIN (parms), i++)
2716 /* Process argument qualifiers for user supplied arguments. */
2719 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2720 user_args = TREE_CHAIN (user_args);
2724 encode_type (TREE_TYPE (parms),
2725 obstack_object_size (&util_obstack),
2726 OBJC_ENCODE_INLINE_DEFS);
2728 /* Compute offset. */
2729 sprintf (buf, "%d", forwarding_offset (parms));
2731 /* Indicate register. */
2732 if (offset_is_register)
2733 obstack_1grow (&util_obstack, '+');
2735 obstack_grow (&util_obstack, buf, strlen (buf));
2738 obstack_1grow (&util_obstack, '\0');
2739 result = get_identifier (obstack_finish (&util_obstack));
2740 obstack_free (&util_obstack, util_firstobj);
2745 generate_descriptor_table (tree type, const char *name, int size, tree list,
2748 tree sc_spec, decl_specs, decl, initlist;
2750 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2751 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2753 decl = start_decl (synth_id_with_class_suffix (name, proto),
2754 decl_specs, 1, NULL_TREE);
2755 DECL_CONTEXT (decl) = NULL_TREE;
2757 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2758 initlist = tree_cons (NULL_TREE, list, initlist);
2760 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
2767 generate_method_descriptors (tree protocol)
2769 tree initlist, chain, method_list_template;
2770 tree cast, variable_length_type;
2773 if (!objc_method_prototype_template)
2774 objc_method_prototype_template = build_method_prototype_template ();
2776 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2777 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2779 variable_length_type = groktypename (cast);
2781 chain = PROTOCOL_CLS_METHODS (protocol);
2784 size = list_length (chain);
2786 method_list_template
2787 = build_method_prototype_list_template (objc_method_prototype_template,
2791 = build_descriptor_table_initializer (objc_method_prototype_template,
2794 UOBJC_CLASS_METHODS_decl
2795 = generate_descriptor_table (method_list_template,
2796 "_OBJC_PROTOCOL_CLASS_METHODS",
2797 size, initlist, protocol);
2798 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2801 UOBJC_CLASS_METHODS_decl = 0;
2803 chain = PROTOCOL_NST_METHODS (protocol);
2806 size = list_length (chain);
2808 method_list_template
2809 = build_method_prototype_list_template (objc_method_prototype_template,
2812 = build_descriptor_table_initializer (objc_method_prototype_template,
2815 UOBJC_INSTANCE_METHODS_decl
2816 = generate_descriptor_table (method_list_template,
2817 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2818 size, initlist, protocol);
2819 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2822 UOBJC_INSTANCE_METHODS_decl = 0;
2825 /* Generate a temporary FUNCTION_DECL node to be used in
2826 hack_method_prototype below. */
2828 static GTY(()) int build_tmp_function_decl_xxx;
2830 build_tmp_function_decl (void)
2832 tree decl_specs, expr_decl, parms;
2836 /* struct objc_object *objc_xxx (id, SEL, ...); */
2838 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2839 push_parm_decl (build_tree_list
2840 (build_tree_list (decl_specs,
2841 build1 (INDIRECT_REF, NULL_TREE,
2845 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2846 get_identifier (TAG_SELECTOR)));
2847 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2849 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2851 parms = get_parm_info (0);
2854 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2855 sprintf (buffer, "__objc_tmp_%x", build_tmp_function_decl_xxx++);
2856 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2857 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2859 tmp_decl = define_decl (expr_decl, decl_specs);
2860 DECL_SOURCE_LINE (tmp_decl) = 0;
2865 /* Generate the prototypes for protocol methods. This is used to
2866 generate method encodings for these.
2868 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2869 a decl node to be used. This is also where the return value is
2873 hack_method_prototype (tree nst_methods, tree tmp_decl)
2878 /* Hack to avoid problem with static typing of self arg. */
2879 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2880 start_method_def (nst_methods);
2881 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2883 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2884 parms = get_parm_info (0); /* we have a `, ...' */
2886 parms = get_parm_info (1); /* place a `void_at_end' */
2888 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2890 /* Usually called from store_parm_decls -> init_function_start. */
2892 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2894 if (current_function_decl)
2896 current_function_decl = tmp_decl;
2899 /* Code taken from start_function. */
2900 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2901 /* Promote the value to int before returning it. */
2902 if (TREE_CODE (restype) == INTEGER_TYPE
2903 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2904 restype = integer_type_node;
2905 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2908 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2909 DECL_CONTEXT (parm) = tmp_decl;
2911 init_function_start (tmp_decl);
2913 /* Typically called from expand_function_start for function definitions. */
2914 assign_parms (tmp_decl);
2916 /* install return type */
2917 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2919 current_function_decl = NULL;
2923 generate_protocol_references (tree plist)
2927 /* Forward declare protocols referenced. */
2928 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2930 tree proto = TREE_VALUE (lproto);
2932 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2933 && PROTOCOL_NAME (proto))
2935 if (! PROTOCOL_FORWARD_DECL (proto))
2936 build_protocol_reference (proto);
2938 if (PROTOCOL_LIST (proto))
2939 generate_protocol_references (PROTOCOL_LIST (proto));
2944 /* For each protocol which was referenced either from a @protocol()
2945 expression, or because a class/category implements it (then a
2946 pointer to the protocol is stored in the struct describing the
2947 class/category), we create a statically allocated instance of the
2948 Protocol class. The code is written in such a way as to generate
2949 as few Protocol objects as possible; we generate a unique Protocol
2950 instance for each protocol, and we don't generate a Protocol
2951 instance if the protocol is never referenced (either from a
2952 @protocol() or from a class/category implementation). These
2953 statically allocated objects can be referred to via the static
2954 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
2956 The statically allocated Protocol objects that we generate here
2957 need to be fixed up at runtime in order to be used: the 'isa'
2958 pointer of the objects need to be set up to point to the 'Protocol'
2959 class, as known at runtime.
2961 The NeXT runtime fixes up all protocols at program startup time,
2962 before main() is entered. It uses a low-level trick to look up all
2963 those symbols, then loops on them and fixes them up.
2965 The GNU runtime as well fixes up all protocols before user code
2966 from the module is executed; it requires pointers to those symbols
2967 to be put in the objc_symtab (which is then passed as argument to
2968 the function __objc_exec_class() which the compiler sets up to be
2969 executed automatically when the module is loaded); setup of those
2970 Protocol objects happen in two ways in the GNU runtime: all
2971 Protocol objects referred to by a class or category implementation
2972 are fixed up when the class/category is loaded; all Protocol
2973 objects referred to by a @protocol() expression are added by the
2974 compiler to the list of statically allocated instances to fixup
2975 (the same list holding the statically allocated constant string
2976 objects). Because, as explained above, the compiler generates as
2977 few Protocol objects as possible, some Protocol object might end up
2978 being referenced multiple times when compiled with the GNU runtime,
2979 and end up being fixed up multiple times at runtime inizialization.
2980 But that doesn't hurt, it's just a little inefficient. */
2982 generate_protocols (void)
2984 tree p, tmp_decl, encoding;
2985 tree sc_spec, decl_specs, decl;
2986 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2989 tmp_decl = build_tmp_function_decl ();
2991 if (! objc_protocol_template)
2992 objc_protocol_template = build_protocol_template ();
2994 /* If a protocol was directly referenced, pull in indirect references. */
2995 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2996 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2997 generate_protocol_references (PROTOCOL_LIST (p));
2999 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3001 tree nst_methods = PROTOCOL_NST_METHODS (p);
3002 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3004 /* If protocol wasn't referenced, don't generate any code. */
3005 if (! PROTOCOL_FORWARD_DECL (p))
3008 /* Make sure we link in the Protocol class. */
3009 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3013 if (! METHOD_ENCODING (nst_methods))
3015 hack_method_prototype (nst_methods, tmp_decl);
3016 encoding = encode_method_prototype (nst_methods, tmp_decl);
3017 METHOD_ENCODING (nst_methods) = encoding;
3019 nst_methods = TREE_CHAIN (nst_methods);
3024 if (! METHOD_ENCODING (cls_methods))
3026 hack_method_prototype (cls_methods, tmp_decl);
3027 encoding = encode_method_prototype (cls_methods, tmp_decl);
3028 METHOD_ENCODING (cls_methods) = encoding;
3031 cls_methods = TREE_CHAIN (cls_methods);
3033 generate_method_descriptors (p);
3035 if (PROTOCOL_LIST (p))
3036 refs_decl = generate_protocol_list (p);
3040 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3042 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3044 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3046 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3047 decl_specs, 1, NULL_TREE);
3049 DECL_CONTEXT (decl) = NULL_TREE;
3051 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3057 (build_tree_list (build_tree_list (NULL_TREE,
3058 objc_protocol_template),
3059 build1 (INDIRECT_REF, NULL_TREE,
3060 build1 (INDIRECT_REF, NULL_TREE,
3063 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3064 TREE_TYPE (refs_expr) = cast_type2;
3067 refs_expr = build_int_2 (0, 0);
3069 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3070 by generate_method_descriptors, which is called above. */
3071 initlist = build_protocol_initializer (TREE_TYPE (decl),
3072 protocol_name_expr, refs_expr,
3073 UOBJC_INSTANCE_METHODS_decl,
3074 UOBJC_CLASS_METHODS_decl);
3075 finish_decl (decl, initlist, NULL_TREE);
3077 /* Mark the decl as used to avoid "defined but not used" warning. */
3078 TREE_USED (decl) = 1;
3083 build_protocol_initializer (tree type, tree protocol_name,
3084 tree protocol_list, tree instance_methods,
3087 tree initlist = NULL_TREE, expr;
3090 cast_type = groktypename
3092 (build_tree_list (NULL_TREE,
3093 xref_tag (RECORD_TYPE,
3094 get_identifier (UTAG_CLASS))),
3095 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3097 /* Filling the "isa" in with one allows the runtime system to
3098 detect that the version change...should remove before final release. */
3100 expr = build_int_2 (PROTOCOL_VERSION, 0);
3101 TREE_TYPE (expr) = cast_type;
3102 initlist = tree_cons (NULL_TREE, expr, initlist);
3103 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3104 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3106 if (!instance_methods)
3107 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3110 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3111 initlist = tree_cons (NULL_TREE, expr, initlist);
3115 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3118 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3119 initlist = tree_cons (NULL_TREE, expr, initlist);
3122 return objc_build_constructor (type, nreverse (initlist));
3125 /* struct objc_category {
3126 char *category_name;
3128 struct objc_method_list *instance_methods;
3129 struct objc_method_list *class_methods;
3130 struct objc_protocol_list *protocols;
3134 build_category_template (void)
3136 tree decl_specs, field_decl, field_decl_chain;
3138 objc_category_template = start_struct (RECORD_TYPE,
3139 get_identifier (UTAG_CATEGORY));
3140 /* char *category_name; */
3142 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3144 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3145 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3146 field_decl_chain = field_decl;
3148 /* char *class_name; */
3150 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3151 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3152 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3153 chainon (field_decl_chain, field_decl);
3155 /* struct objc_method_list *instance_methods; */
3157 decl_specs = build_tree_list (NULL_TREE,
3158 xref_tag (RECORD_TYPE,
3159 get_identifier (UTAG_METHOD_LIST)));
3161 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3162 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3163 chainon (field_decl_chain, field_decl);
3165 /* struct objc_method_list *class_methods; */
3167 decl_specs = build_tree_list (NULL_TREE,
3168 xref_tag (RECORD_TYPE,
3169 get_identifier (UTAG_METHOD_LIST)));
3171 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3172 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3173 chainon (field_decl_chain, field_decl);
3175 /* struct objc_protocol **protocol_list; */
3177 decl_specs = build_tree_list (NULL_TREE,
3178 xref_tag (RECORD_TYPE,
3179 get_identifier (UTAG_PROTOCOL)));
3181 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3182 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3183 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3184 chainon (field_decl_chain, field_decl);
3186 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3189 /* struct objc_selector {
3195 build_selector_template (void)
3198 tree decl_specs, field_decl, field_decl_chain;
3200 objc_selector_template
3201 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3205 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3206 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3207 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3208 field_decl_chain = field_decl;
3210 /* char *sel_type; */
3212 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3213 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3214 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3215 chainon (field_decl_chain, field_decl);
3217 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3220 /* struct objc_class {
3221 struct objc_class *isa;
3222 struct objc_class *super_class;
3227 struct objc_ivar_list *ivars;
3228 struct objc_method_list *methods;
3229 if (flag_next_runtime)
3230 struct objc_cache *cache;
3232 struct sarray *dtable;
3233 struct objc_class *subclass_list;
3234 struct objc_class *sibling_class;
3236 struct objc_protocol_list *protocols;
3237 void *gc_object_type;
3241 build_class_template (void)
3243 tree decl_specs, field_decl, field_decl_chain;
3246 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3248 /* struct objc_class *isa; */
3250 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3251 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3252 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3253 field_decl_chain = field_decl;
3255 /* struct objc_class *super_class; */
3257 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3259 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3260 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3261 chainon (field_decl_chain, field_decl);
3265 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3266 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3267 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3268 chainon (field_decl_chain, field_decl);
3272 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3273 field_decl = get_identifier ("version");
3274 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3275 chainon (field_decl_chain, field_decl);
3279 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3280 field_decl = get_identifier ("info");
3281 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3282 chainon (field_decl_chain, field_decl);
3284 /* long instance_size; */
3286 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3287 field_decl = get_identifier ("instance_size");
3288 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3289 chainon (field_decl_chain, field_decl);
3291 /* struct objc_ivar_list *ivars; */
3293 decl_specs = build_tree_list (NULL_TREE,
3294 xref_tag (RECORD_TYPE,
3295 get_identifier (UTAG_IVAR_LIST)));
3296 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3297 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3298 chainon (field_decl_chain, field_decl);
3300 /* struct objc_method_list *methods; */
3302 decl_specs = build_tree_list (NULL_TREE,
3303 xref_tag (RECORD_TYPE,
3304 get_identifier (UTAG_METHOD_LIST)));
3305 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3306 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3307 chainon (field_decl_chain, field_decl);
3309 if (flag_next_runtime)
3311 /* struct objc_cache *cache; */
3313 decl_specs = build_tree_list (NULL_TREE,
3314 xref_tag (RECORD_TYPE,
3315 get_identifier ("objc_cache")));
3316 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3317 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3318 chainon (field_decl_chain, field_decl);
3322 /* struct sarray *dtable; */
3324 decl_specs = build_tree_list (NULL_TREE,
3325 xref_tag (RECORD_TYPE,
3326 get_identifier ("sarray")));
3327 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3328 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3329 chainon (field_decl_chain, field_decl);
3331 /* struct objc_class *subclass_list; */
3333 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3335 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3336 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3337 chainon (field_decl_chain, field_decl);
3339 /* struct objc_class *sibling_class; */
3341 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3343 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3344 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3345 chainon (field_decl_chain, field_decl);
3348 /* struct objc_protocol **protocol_list; */
3350 decl_specs = build_tree_list (NULL_TREE,
3351 xref_tag (RECORD_TYPE,
3352 get_identifier (UTAG_PROTOCOL)));
3354 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3356 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3357 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3358 chainon (field_decl_chain, field_decl);
3362 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3363 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3364 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3365 chainon (field_decl_chain, field_decl);
3367 /* void *gc_object_type; */
3369 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3370 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3371 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3372 chainon (field_decl_chain, field_decl);
3374 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3377 /* Generate appropriate forward declarations for an implementation. */
3380 synth_forward_declarations (void)
3382 tree sc_spec, decl_specs, an_id;
3384 /* static struct objc_class _OBJC_CLASS_<my_name>; */
3386 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3388 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3389 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3390 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3391 TREE_USED (UOBJC_CLASS_decl) = 1;
3392 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3393 TREE_PUBLIC (UOBJC_CLASS_decl) = 0;
3395 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
3397 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3398 objc_implementation_context);
3400 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3401 TREE_USED (UOBJC_METACLASS_decl) = 1;
3402 DECL_ARTIFICIAL (UOBJC_METACLASS_decl) = 1;
3403 TREE_PUBLIC (UOBJC_METACLASS_decl) = 0;
3405 /* Pre-build the following entities - for speed/convenience. */
3407 an_id = get_identifier ("super_class");
3408 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3409 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3413 error_with_ivar (const char *message, tree decl, tree rawdecl)
3415 error ("%J%s `%s'", decl, message, gen_declaration (rawdecl, errbuf));
3419 check_ivars (tree inter, tree imp)
3421 tree intdecls = CLASS_IVARS (inter);
3422 tree impdecls = CLASS_IVARS (imp);
3423 tree rawintdecls = CLASS_RAW_IVARS (inter);
3424 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3430 if (intdecls == 0 && impdecls == 0)
3432 if (intdecls == 0 || impdecls == 0)
3434 error ("inconsistent instance variable specification");
3438 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3440 if (!comptypes (t1, t2, false))
3442 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3444 error_with_ivar ("conflicting instance variable type",
3445 impdecls, rawimpdecls);
3446 error_with_ivar ("previous declaration of",
3447 intdecls, rawintdecls);
3449 else /* both the type and the name don't match */
3451 error ("inconsistent instance variable specification");
3456 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3458 error_with_ivar ("conflicting instance variable name",
3459 impdecls, rawimpdecls);
3460 error_with_ivar ("previous declaration of",
3461 intdecls, rawintdecls);
3464 intdecls = TREE_CHAIN (intdecls);
3465 impdecls = TREE_CHAIN (impdecls);
3466 rawintdecls = TREE_CHAIN (rawintdecls);
3467 rawimpdecls = TREE_CHAIN (rawimpdecls);
3471 /* Set super_type to the data type node for struct objc_super *,
3472 first defining struct objc_super itself.
3473 This needs to be done just once per compilation. */
3476 build_super_template (void)
3478 tree record, decl_specs, field_decl, field_decl_chain;
3480 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3482 /* struct objc_object *self; */
3484 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3485 field_decl = get_identifier ("self");
3486 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3487 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3488 field_decl_chain = field_decl;
3490 /* struct objc_class *class; */
3492 decl_specs = get_identifier (UTAG_CLASS);
3493 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3494 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3496 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3497 chainon (field_decl_chain, field_decl);
3499 finish_struct (record, field_decl_chain, NULL_TREE);
3501 /* `struct objc_super *' */
3502 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3504 build1 (INDIRECT_REF,
3505 NULL_TREE, NULL_TREE)));
3509 /* struct objc_ivar {
3516 build_ivar_template (void)
3518 tree objc_ivar_id, objc_ivar_record;
3519 tree decl_specs, field_decl, field_decl_chain;
3521 objc_ivar_id = get_identifier (UTAG_IVAR);
3522 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3524 /* char *ivar_name; */
3526 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3527 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3529 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3530 field_decl_chain = field_decl;
3532 /* char *ivar_type; */
3534 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3535 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3537 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3538 chainon (field_decl_chain, field_decl);
3540 /* int ivar_offset; */
3542 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3543 field_decl = get_identifier ("ivar_offset");
3545 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3546 chainon (field_decl_chain, field_decl);
3548 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3550 return objc_ivar_record;
3555 struct objc_ivar ivar_list[ivar_count];
3559 build_ivar_list_template (tree list_type, int size)
3561 tree objc_ivar_list_record;
3562 tree decl_specs, field_decl, field_decl_chain;
3564 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3566 /* int ivar_count; */
3568 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3569 field_decl = get_identifier ("ivar_count");
3571 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3572 field_decl_chain = field_decl;
3574 /* struct objc_ivar ivar_list[]; */
3576 decl_specs = build_tree_list (NULL_TREE, list_type);
3577 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3578 build_int_2 (size, 0));
3580 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3581 chainon (field_decl_chain, field_decl);
3583 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3585 return objc_ivar_list_record;
3591 struct objc_method method_list[method_count];
3595 build_method_list_template (tree list_type, int size)
3597 tree objc_ivar_list_record;
3598 tree decl_specs, field_decl, field_decl_chain;
3600 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3602 /* int method_next; */
3607 xref_tag (RECORD_TYPE,
3608 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3610 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3611 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3612 field_decl_chain = field_decl;
3614 /* int method_count; */
3616 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3617 field_decl = get_identifier ("method_count");
3619 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3620 chainon (field_decl_chain, field_decl);
3622 /* struct objc_method method_list[]; */
3624 decl_specs = build_tree_list (NULL_TREE, list_type);
3625 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3626 build_int_2 (size, 0));
3628 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3629 chainon (field_decl_chain, field_decl);
3631 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3633 return objc_ivar_list_record;
3637 build_ivar_list_initializer (tree type, tree field_decl)
3639 tree initlist = NULL_TREE;
3643 tree ivar = NULL_TREE;
3646 if (DECL_NAME (field_decl))
3647 ivar = tree_cons (NULL_TREE,
3648 add_objc_string (DECL_NAME (field_decl),
3652 /* Unnamed bit-field ivar (yuck). */
3653 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3656 encode_field_decl (field_decl,
3657 obstack_object_size (&util_obstack),
3658 OBJC_ENCODE_DONT_INLINE_DEFS);
3660 /* Null terminate string. */
3661 obstack_1grow (&util_obstack, 0);
3665 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3668 obstack_free (&util_obstack, util_firstobj);
3671 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3672 initlist = tree_cons (NULL_TREE,
3673 objc_build_constructor (type, nreverse (ivar)),
3676 field_decl = TREE_CHAIN (field_decl);
3680 return objc_build_constructor (build_array_type (type, 0),
3681 nreverse (initlist));
3685 generate_ivars_list (tree type, const char *name, int size, tree list)
3687 tree sc_spec, decl_specs, decl, initlist;
3689 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3690 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3692 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3693 decl_specs, 1, NULL_TREE);
3695 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3696 initlist = tree_cons (NULL_TREE, list, initlist);
3699 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3706 generate_ivar_lists (void)
3708 tree initlist, ivar_list_template, chain;
3709 tree cast, variable_length_type;
3712 generating_instance_variables = 1;
3714 if (!objc_ivar_template)
3715 objc_ivar_template = build_ivar_template ();
3719 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3720 get_identifier (UTAG_IVAR_LIST))),
3722 variable_length_type = groktypename (cast);
3724 /* Only generate class variables for the root of the inheritance
3725 hierarchy since these will be the same for every class. */
3727 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3728 && (chain = TYPE_FIELDS (objc_class_template)))
3730 size = list_length (chain);
3732 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3733 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3735 UOBJC_CLASS_VARIABLES_decl
3736 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3738 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3741 UOBJC_CLASS_VARIABLES_decl = 0;
3743 chain = CLASS_IVARS (implementation_template);
3746 size = list_length (chain);
3747 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3748 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3750 UOBJC_INSTANCE_VARIABLES_decl
3751 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3753 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3756 UOBJC_INSTANCE_VARIABLES_decl = 0;
3758 generating_instance_variables = 0;
3762 build_dispatch_table_initializer (tree type, tree entries)
3764 tree initlist = NULL_TREE;
3768 tree elemlist = NULL_TREE;
3770 elemlist = tree_cons (NULL_TREE,
3771 build_selector (METHOD_SEL_NAME (entries)),
3774 /* Generate the method encoding if we don't have one already. */
3775 if (! METHOD_ENCODING (entries))
3776 METHOD_ENCODING (entries) =
3777 encode_method_def (METHOD_DEFINITION (entries));
3779 elemlist = tree_cons (NULL_TREE,
3780 add_objc_string (METHOD_ENCODING (entries),
3784 elemlist = tree_cons (NULL_TREE,
3785 build_unary_op (ADDR_EXPR,
3786 METHOD_DEFINITION (entries), 1),
3789 initlist = tree_cons (NULL_TREE,
3790 objc_build_constructor (type, nreverse (elemlist)),
3793 entries = TREE_CHAIN (entries);
3797 return objc_build_constructor (build_array_type (type, 0),
3798 nreverse (initlist));
3801 /* To accomplish method prototyping without generating all kinds of
3802 inane warnings, the definition of the dispatch table entries were
3805 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3807 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3810 build_method_template (void)
3813 tree decl_specs, field_decl, field_decl_chain;
3815 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3817 /* struct objc_selector *_cmd; */
3818 decl_specs = tree_cons (NULL_TREE,
3819 xref_tag (RECORD_TYPE,
3820 get_identifier (TAG_SELECTOR)),
3822 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3824 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3825 field_decl_chain = field_decl;
3827 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3828 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3829 get_identifier ("method_types"));
3830 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3831 chainon (field_decl_chain, field_decl);
3835 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3836 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3837 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3838 chainon (field_decl_chain, field_decl);
3840 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3847 generate_dispatch_table (tree type, const char *name, int size, tree list)
3849 tree sc_spec, decl_specs, decl, initlist;
3851 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3852 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3854 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3855 decl_specs, 1, NULL_TREE);
3857 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3858 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3859 initlist = tree_cons (NULL_TREE, list, initlist);
3862 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3869 mark_referenced_methods (void)
3871 struct imp_entry *impent;
3874 for (impent = imp_list; impent; impent = impent->next)
3876 chain = CLASS_CLS_METHODS (impent->imp_context);
3879 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
3880 chain = TREE_CHAIN (chain);
3883 chain = CLASS_NST_METHODS (impent->imp_context);
3886 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
3887 chain = TREE_CHAIN (chain);
3893 generate_dispatch_tables (void)
3895 tree initlist, chain, method_list_template;
3896 tree cast, variable_length_type;
3899 if (!objc_method_template)
3900 objc_method_template = build_method_template ();
3904 (build_tree_list (NULL_TREE,
3905 xref_tag (RECORD_TYPE,
3906 get_identifier (UTAG_METHOD_LIST))),
3909 variable_length_type = groktypename (cast);
3911 chain = CLASS_CLS_METHODS (objc_implementation_context);
3914 size = list_length (chain);
3916 method_list_template
3917 = build_method_list_template (objc_method_template, size);
3919 = build_dispatch_table_initializer (objc_method_template, chain);
3921 UOBJC_CLASS_METHODS_decl
3922 = generate_dispatch_table (method_list_template,
3923 ((TREE_CODE (objc_implementation_context)
3924 == CLASS_IMPLEMENTATION_TYPE)
3925 ? "_OBJC_CLASS_METHODS"
3926 : "_OBJC_CATEGORY_CLASS_METHODS"),
3928 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3931 UOBJC_CLASS_METHODS_decl = 0;
3933 chain = CLASS_NST_METHODS (objc_implementation_context);
3936 size = list_length (chain);
3938 method_list_template
3939 = build_method_list_template (objc_method_template, size);
3941 = build_dispatch_table_initializer (objc_method_template, chain);
3943 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3944 UOBJC_INSTANCE_METHODS_decl
3945 = generate_dispatch_table (method_list_template,
3946 "_OBJC_INSTANCE_METHODS",
3949 /* We have a category. */
3950 UOBJC_INSTANCE_METHODS_decl
3951 = generate_dispatch_table (method_list_template,
3952 "_OBJC_CATEGORY_INSTANCE_METHODS",
3954 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3957 UOBJC_INSTANCE_METHODS_decl = 0;
3961 generate_protocol_list (tree i_or_p)
3963 tree initlist, decl_specs, sc_spec;
3964 tree refs_decl, expr_decl, lproto, e, plist;
3968 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3969 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3970 plist = CLASS_PROTOCOL_LIST (i_or_p);
3971 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3972 plist = PROTOCOL_LIST (i_or_p);
3976 cast_type = groktypename
3978 (build_tree_list (NULL_TREE,
3979 xref_tag (RECORD_TYPE,
3980 get_identifier (UTAG_PROTOCOL))),
3981 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3984 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3985 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
3986 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
3989 /* Build initializer. */
3990 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
3992 e = build_int_2 (size, 0);
3993 TREE_TYPE (e) = cast_type;
3994 initlist = tree_cons (NULL_TREE, e, initlist);
3996 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3998 tree pval = TREE_VALUE (lproto);
4000 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4001 && PROTOCOL_FORWARD_DECL (pval))
4003 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4004 initlist = tree_cons (NULL_TREE, e, initlist);
4008 /* static struct objc_protocol *refs[n]; */
4010 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4011 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4012 get_identifier (UTAG_PROTOCOL)),
4015 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4016 expr_decl = build_nt (ARRAY_REF,
4017 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4019 build_int_2 (size + 2, 0));
4020 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4021 expr_decl = build_nt (ARRAY_REF,
4022 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4024 build_int_2 (size + 2, 0));
4025 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4027 = build_nt (ARRAY_REF,
4028 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4030 build_int_2 (size + 2, 0));
4034 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4036 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4037 DECL_CONTEXT (refs_decl) = NULL_TREE;
4039 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4040 nreverse (initlist)),
4047 build_category_initializer (tree type, tree cat_name, tree class_name,
4048 tree instance_methods, tree class_methods,
4051 tree initlist = NULL_TREE, expr;
4053 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4054 initlist = tree_cons (NULL_TREE, class_name, initlist);
4056 if (!instance_methods)
4057 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4060 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4061 initlist = tree_cons (NULL_TREE, expr, initlist);
4064 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4067 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4068 initlist = tree_cons (NULL_TREE, expr, initlist);
4071 /* protocol_list = */
4073 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4076 tree cast_type2 = groktypename
4078 (build_tree_list (NULL_TREE,
4079 xref_tag (RECORD_TYPE,
4080 get_identifier (UTAG_PROTOCOL))),
4081 build1 (INDIRECT_REF, NULL_TREE,
4082 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4084 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4085 TREE_TYPE (expr) = cast_type2;
4086 initlist = tree_cons (NULL_TREE, expr, initlist);
4089 return objc_build_constructor (type, nreverse (initlist));
4092 /* struct objc_class {
4093 struct objc_class *isa;
4094 struct objc_class *super_class;
4099 struct objc_ivar_list *ivars;
4100 struct objc_method_list *methods;
4101 if (flag_next_runtime)
4102 struct objc_cache *cache;
4104 struct sarray *dtable;
4105 struct objc_class *subclass_list;
4106 struct objc_class *sibling_class;
4108 struct objc_protocol_list *protocols;
4109 void *gc_object_type;
4113 build_shared_structure_initializer (tree type, tree isa, tree super,
4114 tree name, tree size, int status,
4115 tree dispatch_table, tree ivar_list,
4118 tree initlist = NULL_TREE, expr;
4121 initlist = tree_cons (NULL_TREE, isa, initlist);
4124 initlist = tree_cons (NULL_TREE, super, initlist);
4127 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4130 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4133 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4135 /* instance_size = */
4136 initlist = tree_cons (NULL_TREE, size, initlist);
4138 /* objc_ivar_list = */
4140 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4143 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4144 initlist = tree_cons (NULL_TREE, expr, initlist);
4147 /* objc_method_list = */
4148 if (!dispatch_table)
4149 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4152 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4153 initlist = tree_cons (NULL_TREE, expr, initlist);
4156 if (flag_next_runtime)
4157 /* method_cache = */
4158 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4162 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4164 /* subclass_list = */
4165 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4167 /* sibling_class = */
4168 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4171 /* protocol_list = */
4172 if (! protocol_list)
4173 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4179 (build_tree_list (NULL_TREE,
4180 xref_tag (RECORD_TYPE,
4181 get_identifier (UTAG_PROTOCOL))),
4182 build1 (INDIRECT_REF, NULL_TREE,
4183 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4185 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4186 TREE_TYPE (expr) = cast_type2;
4187 initlist = tree_cons (NULL_TREE, expr, initlist);
4190 /* gc_object_type = NULL */
4191 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4193 return objc_build_constructor (type, nreverse (initlist));
4196 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4199 generate_category (tree cat)
4201 tree sc_spec, decl_specs, decl;
4202 tree initlist, cat_name_expr, class_name_expr;
4203 tree protocol_decl, category;
4205 add_class_reference (CLASS_NAME (cat));
4206 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4208 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4210 category = CLASS_CATEGORY_LIST (implementation_template);
4212 /* find the category interface from the class it is associated with */
4215 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4217 category = CLASS_CATEGORY_LIST (category);
4220 if (category && CLASS_PROTOCOL_LIST (category))
4222 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4223 protocol_decl = generate_protocol_list (category);
4228 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4229 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4231 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4232 objc_implementation_context),
4233 decl_specs, 1, NULL_TREE);
4235 initlist = build_category_initializer (TREE_TYPE (decl),
4236 cat_name_expr, class_name_expr,
4237 UOBJC_INSTANCE_METHODS_decl,
4238 UOBJC_CLASS_METHODS_decl,
4241 TREE_USED (decl) = 1;
4242 finish_decl (decl, initlist, NULL_TREE);
4245 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4246 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4249 generate_shared_structures (void)
4251 tree sc_spec, decl_specs, decl;
4252 tree name_expr, super_expr, root_expr;
4253 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4254 tree cast_type, initlist, protocol_decl;
4256 my_super_id = CLASS_SUPER_NAME (implementation_template);
4259 add_class_reference (my_super_id);
4261 /* Compute "my_root_id" - this is required for code generation.
4262 the "isa" for all meta class structures points to the root of
4263 the inheritance hierarchy (e.g. "__Object")... */
4264 my_root_id = my_super_id;
4267 tree my_root_int = lookup_interface (my_root_id);
4269 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4270 my_root_id = CLASS_SUPER_NAME (my_root_int);
4277 /* No super class. */
4278 my_root_id = CLASS_NAME (implementation_template);
4281 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4282 objc_class_template),
4283 build1 (INDIRECT_REF,
4284 NULL_TREE, NULL_TREE)));
4286 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4289 /* Install class `isa' and `super' pointers at runtime. */
4292 super_expr = add_objc_string (my_super_id, class_names);
4293 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4296 super_expr = build_int_2 (0, 0);
4298 root_expr = add_objc_string (my_root_id, class_names);
4299 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4301 if (CLASS_PROTOCOL_LIST (implementation_template))
4303 generate_protocol_references
4304 (CLASS_PROTOCOL_LIST (implementation_template));
4305 protocol_decl = generate_protocol_list (implementation_template);
4310 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4312 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4313 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4315 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4319 = build_shared_structure_initializer
4321 root_expr, super_expr, name_expr,
4322 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4324 UOBJC_CLASS_METHODS_decl,
4325 UOBJC_CLASS_VARIABLES_decl,
4328 finish_decl (decl, initlist, NULL_TREE);
4330 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4332 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4336 = build_shared_structure_initializer
4338 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4339 super_expr, name_expr,
4340 convert (integer_type_node,
4341 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4342 (implementation_template))),
4344 UOBJC_INSTANCE_METHODS_decl,
4345 UOBJC_INSTANCE_VARIABLES_decl,
4348 finish_decl (decl, initlist, NULL_TREE);
4352 synth_id_with_class_suffix (const char *preamble, tree ctxt)
4355 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4356 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4358 const char *const class_name
4359 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4360 string = alloca (strlen (preamble) + strlen (class_name) + 3);
4361 sprintf (string, "%s_%s", preamble,
4362 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4364 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4365 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4367 /* We have a category. */
4368 const char *const class_name
4369 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4370 const char *const class_super_name
4371 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4372 string = alloca (strlen (preamble) + strlen (class_name)
4373 + strlen (class_super_name) + 3);
4374 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4376 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4378 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4379 string = alloca (strlen (preamble) + strlen (protocol_name) + 3);
4380 sprintf (string, "%s_%s", preamble, protocol_name);
4385 return get_identifier (string);
4389 is_objc_type_qualifier (tree node)
4391 return (TREE_CODE (node) == IDENTIFIER_NODE
4392 && (node == ridpointers [(int) RID_CONST]
4393 || node == ridpointers [(int) RID_VOLATILE]
4394 || node == ridpointers [(int) RID_IN]
4395 || node == ridpointers [(int) RID_OUT]
4396 || node == ridpointers [(int) RID_INOUT]
4397 || node == ridpointers [(int) RID_BYCOPY]
4398 || node == ridpointers [(int) RID_BYREF]
4399 || node == ridpointers [(int) RID_ONEWAY]));
4402 /* If type is empty or only type qualifiers are present, add default
4403 type of id (otherwise grokdeclarator will default to int). */
4406 adjust_type_for_id_default (tree type)
4408 tree declspecs, chain;
4411 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4412 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4414 declspecs = TREE_PURPOSE (type);
4416 /* Determine if a typespec is present. */
4417 for (chain = declspecs;
4419 chain = TREE_CHAIN (chain))
4421 if (TYPED_OBJECT (TREE_VALUE (chain))
4422 && !(TREE_VALUE (type)
4423 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4424 error ("can not use an object as parameter to a method\n");
4425 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4429 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4431 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4436 selector ':' '(' typename ')' identifier
4439 Transform an Objective-C keyword argument into
4440 the C equivalent parameter declarator.
4442 In: key_name, an "identifier_node" (optional).
4443 arg_type, a "tree_list" (optional).
4444 arg_name, an "identifier_node".
4446 Note: It would be really nice to strongly type the preceding
4447 arguments in the function prototype; however, then I
4448 could not use the "accessor" macros defined in "tree.h".
4450 Out: an instance of "keyword_decl". */
4453 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
4457 /* If no type is specified, default to "id". */
4458 arg_type = adjust_type_for_id_default (arg_type);
4460 keyword_decl = make_node (KEYWORD_DECL);
4462 TREE_TYPE (keyword_decl) = arg_type;
4463 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4464 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4466 return keyword_decl;
4469 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4472 build_keyword_selector (tree selector)
4475 tree key_chain, key_name;
4478 /* Scan the selector to see how much space we'll need. */
4479 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4481 if (TREE_CODE (selector) == KEYWORD_DECL)
4482 key_name = KEYWORD_KEY_NAME (key_chain);
4483 else if (TREE_CODE (selector) == TREE_LIST)
4484 key_name = TREE_PURPOSE (key_chain);
4489 len += IDENTIFIER_LENGTH (key_name) + 1;
4491 /* Just a ':' arg. */
4495 buf = alloca (len + 1);
4496 /* Start the buffer out as an empty string. */
4499 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4501 if (TREE_CODE (selector) == KEYWORD_DECL)
4502 key_name = KEYWORD_KEY_NAME (key_chain);
4503 else if (TREE_CODE (selector) == TREE_LIST)
4504 key_name = TREE_PURPOSE (key_chain);
4509 strcat (buf, IDENTIFIER_POINTER (key_name));
4513 return get_identifier (buf);
4516 /* Used for declarations and definitions. */
4519 build_method_decl (enum tree_code code, tree ret_type, tree selector,
4524 /* If no type is specified, default to "id". */
4525 ret_type = adjust_type_for_id_default (ret_type);
4527 method_decl = make_node (code);
4528 TREE_TYPE (method_decl) = ret_type;
4530 /* If we have a keyword selector, create an identifier_node that
4531 represents the full selector name (`:' included)... */
4532 if (TREE_CODE (selector) == KEYWORD_DECL)
4534 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4535 METHOD_SEL_ARGS (method_decl) = selector;
4536 METHOD_ADD_ARGS (method_decl) = add_args;
4540 METHOD_SEL_NAME (method_decl) = selector;
4541 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4542 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4548 #define METHOD_DEF 0
4549 #define METHOD_REF 1
4551 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4552 an argument list for method METH. CONTEXT is either METHOD_DEF or
4553 METHOD_REF, saying whether we are trying to define a method or call
4554 one. SUPERFLAG says this is for a send to super; this makes a
4555 difference for the NeXT calling sequence in which the lookup and
4556 the method call are done together. */
4559 get_arg_type_list (tree meth, int context, int superflag)
4563 /* Receiver type. */
4564 if (flag_next_runtime && superflag)
4565 arglist = build_tree_list (NULL_TREE, super_type);
4566 else if (context == METHOD_DEF)
4567 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4569 arglist = build_tree_list (NULL_TREE, id_type);
4571 /* Selector type - will eventually change to `int'. */
4572 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4574 /* Build a list of argument types. */
4575 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4577 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4578 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4581 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4582 /* We have a `, ...' immediately following the selector,
4583 finalize the arglist...simulate get_parm_info (0). */
4585 else if (METHOD_ADD_ARGS (meth))
4587 /* we have a variable length selector */
4588 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4589 chainon (arglist, add_arg_list);
4592 /* finalize the arglist...simulate get_parm_info (1) */
4593 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4599 check_duplicates (hash hsh)
4601 tree meth = NULL_TREE;
4609 /* We have two methods with the same name and different types. */
4611 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4613 warning ("multiple declarations for method `%s'",
4614 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4616 warn_with_method ("using", type, meth);
4617 for (loop = hsh->list; loop; loop = loop->next)
4618 warn_with_method ("also found", type, loop->value);
4624 /* If RECEIVER is a class reference, return the identifier node for
4625 the referenced class. RECEIVER is created by get_class_reference,
4626 so we check the exact form created depending on which runtimes are
4630 receiver_is_class_object (tree receiver)
4632 tree chain, exp, arg;
4634 /* The receiver is 'self' in the context of a class method. */
4635 if (objc_method_context
4636 && receiver == self_decl
4637 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4639 return CLASS_NAME (objc_implementation_context);
4642 if (flag_next_runtime)
4644 /* The receiver is a variable created by
4645 build_class_reference_decl. */
4646 if (TREE_CODE (receiver) == VAR_DECL
4647 && TREE_TYPE (receiver) == objc_class_type)
4648 /* Look up the identifier. */
4649 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4650 if (TREE_PURPOSE (chain) == receiver)
4651 return TREE_VALUE (chain);
4655 /* The receiver is a function call that returns an id. Check if
4656 it is a call to objc_getClass, if so, pick up the class name. */
4657 if (TREE_CODE (receiver) == CALL_EXPR
4658 && (exp = TREE_OPERAND (receiver, 0))
4659 && TREE_CODE (exp) == ADDR_EXPR
4660 && (exp = TREE_OPERAND (exp, 0))
4661 && TREE_CODE (exp) == FUNCTION_DECL
4662 && exp == objc_get_class_decl
4663 /* We have a call to objc_getClass! */
4664 && (arg = TREE_OPERAND (receiver, 1))
4665 && TREE_CODE (arg) == TREE_LIST
4666 && (arg = TREE_VALUE (arg)))
4669 if (TREE_CODE (arg) == ADDR_EXPR
4670 && (arg = TREE_OPERAND (arg, 0))
4671 && TREE_CODE (arg) == STRING_CST)
4672 /* Finally, we have the class name. */
4673 return get_identifier (TREE_STRING_POINTER (arg));
4679 /* If we are currently building a message expr, this holds
4680 the identifier of the selector of the message. This is
4681 used when printing warnings about argument mismatches. */
4683 static tree current_objc_message_selector = 0;
4686 objc_message_selector (void)
4688 return current_objc_message_selector;
4691 /* Construct an expression for sending a message.
4692 MESS has the object to send to in TREE_PURPOSE
4693 and the argument list (including selector) in TREE_VALUE.
4695 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4696 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4699 build_message_expr (tree mess)
4701 tree receiver = TREE_PURPOSE (mess);
4703 tree args = TREE_VALUE (mess);
4704 tree method_params = NULL_TREE;
4706 if (TREE_CODE (receiver) == ERROR_MARK)
4707 return error_mark_node;
4709 /* Obtain the full selector name. */
4710 if (TREE_CODE (args) == IDENTIFIER_NODE)
4711 /* A unary selector. */
4713 else if (TREE_CODE (args) == TREE_LIST)
4714 sel_name = build_keyword_selector (args);
4718 /* Build the parameter list to give to the method. */
4719 if (TREE_CODE (args) == TREE_LIST)
4721 tree chain = args, prev = NULL_TREE;
4723 /* We have a keyword selector--check for comma expressions. */
4726 tree element = TREE_VALUE (chain);
4728 /* We have a comma expression, must collapse... */
4729 if (TREE_CODE (element) == TREE_LIST)
4732 TREE_CHAIN (prev) = element;
4737 chain = TREE_CHAIN (chain);
4739 method_params = args;
4742 return finish_message_expr (receiver, sel_name, method_params);
4745 /* The 'finish_message_expr' routine is called from within
4746 'build_message_expr' for non-template functions. In the case of
4747 C++ template functions, it is called from 'build_expr_from_tree'
4748 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4751 finish_message_expr (tree receiver, tree sel_name, tree method_params)
4753 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4754 tree selector, self_object, retval;
4755 int statically_typed = 0, statically_allocated = 0;
4757 /* Determine receiver type. */
4758 tree rtype = TREE_TYPE (receiver);
4759 int super = IS_SUPER (rtype);
4763 if (TREE_STATIC_TEMPLATE (rtype))
4764 statically_allocated = 1;
4765 else if (TREE_CODE (rtype) == POINTER_TYPE
4766 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4767 statically_typed = 1;
4768 else if ((flag_next_runtime
4770 && (class_ident = receiver_is_class_object (receiver)))
4772 else if (! IS_ID (rtype)
4773 /* Allow any type that matches objc_class_type. */
4774 && ! comptypes (rtype, objc_class_type, false))
4776 warning ("invalid receiver type `%s'",
4777 gen_declaration (rtype, errbuf));
4779 if (statically_allocated)
4780 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4782 /* Don't evaluate the receiver twice. */
4783 receiver = save_expr (receiver);
4784 self_object = receiver;
4787 /* If sending to `super', use current self as the object. */
4788 self_object = self_decl;
4790 /* Determine operation return type. */
4796 if (CLASS_SUPER_NAME (implementation_template))
4799 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4801 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4802 method_prototype = lookup_instance_method_static (iface, sel_name);
4804 method_prototype = lookup_class_method_static (iface, sel_name);
4806 if (iface && !method_prototype)
4807 warning ("`%s' does not respond to `%s'",
4808 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4809 IDENTIFIER_POINTER (sel_name));
4813 error ("no super class declared in interface for `%s'",
4814 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4815 return error_mark_node;
4819 else if (statically_allocated)
4821 tree ctype = TREE_TYPE (rtype);
4822 tree iface = lookup_interface (TYPE_NAME (rtype));
4825 method_prototype = lookup_instance_method_static (iface, sel_name);
4827 if (! method_prototype && ctype && TYPE_PROTOCOL_LIST (ctype))
4829 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4832 if (!method_prototype)
4833 warning ("`%s' does not respond to `%s'",
4834 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4835 IDENTIFIER_POINTER (sel_name));
4837 else if (statically_typed)
4839 tree ctype = TREE_TYPE (rtype);
4841 /* `self' is now statically_typed. All methods should be visible
4842 within the context of the implementation. */
4843 if (objc_implementation_context
4844 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4847 = lookup_instance_method_static (implementation_template,
4850 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4852 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4855 if (! method_prototype
4856 && implementation_template != objc_implementation_context)
4857 /* The method is not published in the interface. Check
4860 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4867 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4868 method_prototype = lookup_instance_method_static (iface, sel_name);
4870 if (! method_prototype)
4872 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4875 = lookup_method_in_protocol_list (protocol_list,
4880 if (!method_prototype)
4881 warning ("`%s' does not respond to `%s'",
4882 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4883 IDENTIFIER_POINTER (sel_name));
4885 else if (class_ident)
4887 if (objc_implementation_context
4888 && CLASS_NAME (objc_implementation_context) == class_ident)
4891 = lookup_class_method_static (implementation_template, sel_name);
4893 if (!method_prototype
4894 && implementation_template != objc_implementation_context)
4895 /* The method is not published in the interface. Check
4898 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
4905 if ((iface = lookup_interface (class_ident)))
4906 method_prototype = lookup_class_method_static (iface, sel_name);
4909 if (!method_prototype)
4911 warning ("cannot find class (factory) method");
4912 warning ("return type for `%s' defaults to id",
4913 IDENTIFIER_POINTER (sel_name));
4916 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4918 /* An anonymous object that has been qualified with a protocol. */
4920 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4922 method_prototype = lookup_method_in_protocol_list (protocol_list,
4925 if (!method_prototype)
4929 warning ("method `%s' not implemented by protocol",
4930 IDENTIFIER_POINTER (sel_name));
4932 /* Try and find the method signature in the global pools. */
4934 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4935 hsh = hash_lookup (cls_method_hash_list, sel_name);
4937 if (!(method_prototype = check_duplicates (hsh)))
4938 warning ("return type defaults to id");
4945 /* We think we have an instance...loophole: extern id Object; */
4946 hsh = hash_lookup (nst_method_hash_list, sel_name);
4949 /* For various loopholes */
4950 hsh = hash_lookup (cls_method_hash_list, sel_name);
4952 method_prototype = check_duplicates (hsh);
4953 if (!method_prototype)
4955 warning ("cannot find method");
4956 warning ("return type for `%s' defaults to id",
4957 IDENTIFIER_POINTER (sel_name));
4961 /* Save the selector name for printing error messages. */
4962 current_objc_message_selector = sel_name;
4964 /* Build the parameters list for looking up the method.
4965 These are the object itself and the selector. */
4967 if (flag_typed_selectors)
4968 selector = build_typed_selector_reference (sel_name, method_prototype);
4970 selector = build_selector_reference (sel_name);
4972 retval = build_objc_method_call (super, method_prototype,
4973 receiver, self_object,
4974 selector, method_params);
4976 current_objc_message_selector = 0;
4981 /* Build a tree expression to send OBJECT the operation SELECTOR,
4982 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
4983 assuming the method has prototype METHOD_PROTOTYPE.
4984 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
4985 Use METHOD_PARAMS as list of args to pass to the method.
4986 If SUPER_FLAG is nonzero, we look up the superclass's method. */
4989 build_objc_method_call (int super_flag, tree method_prototype,
4990 tree lookup_object, tree object, tree selector,
4993 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
4994 tree rcv_p = (super_flag
4995 ? build_pointer_type (xref_tag (RECORD_TYPE,
4996 get_identifier (TAG_SUPER)))
4999 if (flag_next_runtime)
5001 if (! method_prototype)
5003 method_params = tree_cons (NULL_TREE, lookup_object,
5004 tree_cons (NULL_TREE, selector,
5006 assemble_external (sender);
5007 return build_function_call (sender, method_params);
5011 /* This is a real kludge, but it is used only for the Next.
5012 Clobber the data type of SENDER temporarily to accept
5013 all the arguments for this operation, and to return
5014 whatever this operation returns. */
5015 tree arglist = NULL_TREE, retval, savarg, savret;
5016 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5018 /* Save the proper contents of SENDER's data type. */
5019 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5020 savret = TREE_TYPE (TREE_TYPE (sender));
5022 /* Install this method's argument types. */
5023 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5025 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5027 /* Install this method's return type. */
5028 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5030 /* Call SENDER with all the parameters. This will do type
5031 checking using the arg types for this method. */
5032 method_params = tree_cons (NULL_TREE, lookup_object,
5033 tree_cons (NULL_TREE, selector,
5035 assemble_external (sender);
5036 retval = build_function_call (sender, method_params);
5038 /* Restore SENDER's return/argument types. */
5039 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5040 TREE_TYPE (TREE_TYPE (sender)) = savret;
5046 /* This is the portable way.
5047 First call the lookup function to get a pointer to the method,
5048 then cast the pointer, then call it with the method arguments. */
5051 /* Avoid trouble since we may evaluate each of these twice. */
5052 object = save_expr (object);
5053 selector = save_expr (selector);
5055 lookup_object = build_c_cast (rcv_p, lookup_object);
5057 assemble_external (sender);
5059 = build_function_call (sender,
5060 tree_cons (NULL_TREE, lookup_object,
5061 tree_cons (NULL_TREE, selector,
5064 /* If we have a method prototype, construct the data type this
5065 method needs, and cast what we got from SENDER into a pointer
5067 if (method_prototype)
5069 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5071 tree valtype = groktypename (TREE_TYPE (method_prototype));
5072 tree fake_function_type = build_function_type (valtype, arglist);
5073 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5077 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5079 /* Pass the object to the method. */
5080 assemble_external (method);
5081 return build_function_call (method,
5082 tree_cons (NULL_TREE, object,
5083 tree_cons (NULL_TREE, selector,
5089 build_protocol_reference (tree p)
5091 tree decl, ident, ptype;
5093 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5095 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5097 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5098 objc_protocol_template),
5101 if (identifier_global_value (ident))
5102 decl = identifier_global_value (ident); /* Set by pushdecl. */
5105 decl = build_decl (VAR_DECL, ident, ptype);
5106 DECL_EXTERNAL (decl) = 1;
5107 TREE_PUBLIC (decl) = 0;
5108 TREE_USED (decl) = 1;
5109 DECL_ARTIFICIAL (decl) = 1;
5111 make_decl_rtl (decl, 0);
5112 pushdecl_top_level (decl);
5115 PROTOCOL_FORWARD_DECL (p) = decl;
5118 /* This function is called by the parser when (and only when) a
5119 @protocol() expression is found, in order to compile it. */
5121 build_protocol_expr (tree protoname)
5124 tree p = lookup_protocol (protoname);
5128 error ("cannot find protocol declaration for `%s'",
5129 IDENTIFIER_POINTER (protoname));
5130 return error_mark_node;
5133 if (!PROTOCOL_FORWARD_DECL (p))
5134 build_protocol_reference (p);
5136 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5138 TREE_TYPE (expr) = protocol_type;
5140 /* The @protocol() expression is being compiled into a pointer to a
5141 statically allocated instance of the Protocol class. To become
5142 usable at runtime, the 'isa' pointer of the instance need to be
5143 fixed up at runtime by the runtime library, to point to the
5144 actual 'Protocol' class. */
5146 /* For the GNU runtime, put the static Protocol instance in the list
5147 of statically allocated instances, so that we make sure that its
5148 'isa' pointer is fixed up at runtime by the GNU runtime library
5149 to point to the Protocol class (at runtime, when loading the
5150 module, the GNU runtime library loops on the statically allocated
5151 instances (as found in the defs field in objc_symtab) and fixups
5152 all the 'isa' pointers of those objects). */
5153 if (! flag_next_runtime)
5155 /* This type is a struct containing the fields of a Protocol
5156 object. (Cfr. protocol_type instead is the type of a pointer
5157 to such a struct). */
5158 tree protocol_struct_type = xref_tag
5159 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5162 /* Look for the list of Protocol statically allocated instances
5163 to fixup at runtime. Create a new list to hold Protocol
5164 statically allocated instances, if the list is not found. At
5165 present there is only another list, holding NSConstantString
5166 static instances to be fixed up at runtime. */
5167 for (chain = &objc_static_instances;
5168 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5169 chain = &TREE_CHAIN (*chain));
5172 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5173 add_objc_string (TYPE_NAME (protocol_struct_type),
5177 /* Add this statically allocated instance to the Protocol list. */
5178 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5179 PROTOCOL_FORWARD_DECL (p),
5180 TREE_PURPOSE (*chain));
5187 /* This function is called by the parser when a @selector() expression
5188 is found, in order to compile it. It is only called by the parser
5189 and only to compile a @selector(). */
5191 build_selector_expr (tree selnamelist)
5195 /* Obtain the full selector name. */
5196 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5197 /* A unary selector. */
5198 selname = selnamelist;
5199 else if (TREE_CODE (selnamelist) == TREE_LIST)
5200 selname = build_keyword_selector (selnamelist);
5204 /* If we are required to check @selector() expressions as they
5205 are found, check that the selector has been declared. */
5206 if (warn_undeclared_selector)
5208 /* Look the selector up in the list of all known class and
5209 instance methods (up to this line) to check that the selector
5213 /* First try with instance methods. */
5214 hsh = hash_lookup (nst_method_hash_list, selname);
5216 /* If not found, try with class methods. */
5219 hsh = hash_lookup (cls_method_hash_list, selname);
5222 /* If still not found, print out a warning. */
5225 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5230 if (flag_typed_selectors)
5231 return build_typed_selector_reference (selname, 0);
5233 return build_selector_reference (selname);
5237 build_encode_expr (tree type)
5242 encode_type (type, obstack_object_size (&util_obstack),
5243 OBJC_ENCODE_INLINE_DEFS);
5244 obstack_1grow (&util_obstack, 0); /* null terminate string */
5245 string = obstack_finish (&util_obstack);
5247 /* Synthesize a string that represents the encoded struct/union. */
5248 result = my_build_string (strlen (string) + 1, string);
5249 obstack_free (&util_obstack, util_firstobj);
5254 build_ivar_reference (tree id)
5256 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5258 /* Historically, a class method that produced objects (factory
5259 method) would assign `self' to the instance that it
5260 allocated. This would effectively turn the class method into
5261 an instance method. Following this assignment, the instance
5262 variables could be accessed. That practice, while safe,
5263 violates the simple rule that a class method should not refer
5264 to an instance variable. It's better to catch the cases
5265 where this is done unknowingly than to support the above
5267 warning ("instance variable `%s' accessed in class method",
5268 IDENTIFIER_POINTER (id));
5269 TREE_TYPE (self_decl) = instance_type; /* cast */
5272 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5275 /* Compute a hash value for a given method SEL_NAME. */
5278 hash_func (tree sel_name)
5280 const unsigned char *s
5281 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5285 h = h * 67 + *s++ - 113;
5292 nst_method_hash_list = ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5293 cls_method_hash_list = ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5296 /* WARNING!!!! hash_enter is called with a method, and will peek
5297 inside to find its selector! But hash_lookup is given a selector
5298 directly, and looks for the selector that's inside the found
5299 entry's key (method) for comparison. */
5302 hash_enter (hash *hashlist, tree method)
5305 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5307 obj = ggc_alloc (sizeof (struct hashed_entry));
5309 obj->next = hashlist[slot];
5312 hashlist[slot] = obj; /* append to front */
5316 hash_lookup (hash *hashlist, tree sel_name)
5320 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5324 if (sel_name == METHOD_SEL_NAME (target->key))
5327 target = target->next;
5333 hash_add_attr (hash entry, tree value)
5337 obj = ggc_alloc (sizeof (struct hashed_attribute));
5338 obj->next = entry->list;
5341 entry->list = obj; /* append to front */
5345 lookup_method (tree mchain, tree method)
5349 if (TREE_CODE (method) == IDENTIFIER_NODE)
5352 key = METHOD_SEL_NAME (method);
5356 if (METHOD_SEL_NAME (mchain) == key)
5359 mchain = TREE_CHAIN (mchain);
5365 lookup_instance_method_static (tree interface, tree ident)
5367 tree inter = interface;
5368 tree chain = CLASS_NST_METHODS (inter);
5369 tree meth = NULL_TREE;
5373 if ((meth = lookup_method (chain, ident)))
5376 if (CLASS_CATEGORY_LIST (inter))
5378 tree category = CLASS_CATEGORY_LIST (inter);
5379 chain = CLASS_NST_METHODS (category);
5383 if ((meth = lookup_method (chain, ident)))
5386 /* Check for instance methods in protocols in categories. */
5387 if (CLASS_PROTOCOL_LIST (category))
5389 if ((meth = (lookup_method_in_protocol_list
5390 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5394 if ((category = CLASS_CATEGORY_LIST (category)))
5395 chain = CLASS_NST_METHODS (category);
5400 if (CLASS_PROTOCOL_LIST (inter))
5402 if ((meth = (lookup_method_in_protocol_list
5403 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5407 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5408 chain = CLASS_NST_METHODS (inter);
5416 lookup_class_method_static (tree interface, tree ident)
5418 tree inter = interface;
5419 tree chain = CLASS_CLS_METHODS (inter);
5420 tree meth = NULL_TREE;
5421 tree root_inter = NULL_TREE;
5425 if ((meth = lookup_method (chain, ident)))
5428 if (CLASS_CATEGORY_LIST (inter))
5430 tree category = CLASS_CATEGORY_LIST (inter);
5431 chain = CLASS_CLS_METHODS (category);
5435 if ((meth = lookup_method (chain, ident)))
5438 /* Check for class methods in protocols in categories. */
5439 if (CLASS_PROTOCOL_LIST (category))
5441 if ((meth = (lookup_method_in_protocol_list
5442 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5446 if ((category = CLASS_CATEGORY_LIST (category)))
5447 chain = CLASS_CLS_METHODS (category);
5452 /* Check for class methods in protocols. */
5453 if (CLASS_PROTOCOL_LIST (inter))
5455 if ((meth = (lookup_method_in_protocol_list
5456 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5461 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5462 chain = CLASS_CLS_METHODS (inter);
5466 /* If no class (factory) method was found, check if an _instance_
5467 method of the same name exists in the root class. This is what
5468 the Objective-C runtime will do. */
5469 return lookup_instance_method_static (root_inter, ident);
5473 add_class_method (tree class, tree method)
5478 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5480 /* put method on list in reverse order */
5481 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5482 CLASS_CLS_METHODS (class) = method;
5486 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5487 error ("duplicate definition of class method `%s'",
5488 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5491 /* Check types; if different, complain. */
5492 if (!comp_proto_with_proto (method, mth))
5493 error ("duplicate declaration of class method `%s'",
5494 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5498 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5500 /* Install on a global chain. */
5501 hash_enter (cls_method_hash_list, method);
5505 /* Check types; if different, add to a list. */
5506 if (!comp_proto_with_proto (method, hsh->key))
5507 hash_add_attr (hsh, method);
5513 add_instance_method (tree class, tree method)
5518 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5520 /* Put method on list in reverse order. */
5521 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5522 CLASS_NST_METHODS (class) = method;
5526 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5527 error ("duplicate definition of instance method `%s'",
5528 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5531 /* Check types; if different, complain. */
5532 if (!comp_proto_with_proto (method, mth))
5533 error ("duplicate declaration of instance method `%s'",
5534 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5538 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5540 /* Install on a global chain. */
5541 hash_enter (nst_method_hash_list, method);
5545 /* Check types; if different, add to a list. */
5546 if (!comp_proto_with_proto (method, hsh->key))
5547 hash_add_attr (hsh, method);
5553 add_class (tree class)
5555 /* Put interfaces on list in reverse order. */
5556 TREE_CHAIN (class) = interface_chain;
5557 interface_chain = class;
5558 return interface_chain;
5562 add_category (tree class, tree category)
5564 /* Put categories on list in reverse order. */
5565 tree cat = CLASS_CATEGORY_LIST (class);
5569 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5570 warning ("duplicate interface declaration for category `%s(%s)'",
5571 IDENTIFIER_POINTER (CLASS_NAME (class)),
5572 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5573 cat = CLASS_CATEGORY_LIST (cat);
5576 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5577 CLASS_CATEGORY_LIST (class) = category;
5580 /* Called after parsing each instance variable declaration. Necessary to
5581 preserve typedefs and implement public/private...
5583 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5586 add_instance_variable (tree class, int public, tree declarator,
5587 tree declspecs, tree width)
5589 tree field_decl, raw_decl;
5591 raw_decl = build_tree_list (declspecs, declarator);
5593 if (CLASS_RAW_IVARS (class))
5594 chainon (CLASS_RAW_IVARS (class), raw_decl);
5596 CLASS_RAW_IVARS (class) = raw_decl;
5598 field_decl = grokfield (declarator, declspecs, width);
5600 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5604 TREE_PUBLIC (field_decl) = 0;
5605 TREE_PRIVATE (field_decl) = 0;
5606 TREE_PROTECTED (field_decl) = 1;
5610 TREE_PUBLIC (field_decl) = 1;
5611 TREE_PRIVATE (field_decl) = 0;
5612 TREE_PROTECTED (field_decl) = 0;
5616 TREE_PUBLIC (field_decl) = 0;
5617 TREE_PRIVATE (field_decl) = 1;
5618 TREE_PROTECTED (field_decl) = 0;
5623 if (CLASS_IVARS (class))
5624 chainon (CLASS_IVARS (class), field_decl);
5626 CLASS_IVARS (class) = field_decl;
5632 is_ivar (tree decl_chain, tree ident)
5634 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5635 if (DECL_NAME (decl_chain) == ident)
5640 /* True if the ivar is private and we are not in its implementation. */
5643 is_private (tree decl)
5645 if (TREE_PRIVATE (decl)
5646 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5648 error ("instance variable `%s' is declared private",
5649 IDENTIFIER_POINTER (DECL_NAME (decl)));
5656 /* We have an instance variable reference;, check to see if it is public. */
5659 is_public (tree expr, tree identifier)
5661 tree basetype = TREE_TYPE (expr);
5662 enum tree_code code = TREE_CODE (basetype);
5665 if (code == RECORD_TYPE)
5667 if (TREE_STATIC_TEMPLATE (basetype))
5669 if (!lookup_interface (TYPE_NAME (basetype)))
5671 error ("cannot find interface declaration for `%s'",
5672 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5676 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5678 if (TREE_PUBLIC (decl))
5681 /* Important difference between the Stepstone translator:
5682 all instance variables should be public within the context
5683 of the implementation. */
5684 if (objc_implementation_context
5685 && (((TREE_CODE (objc_implementation_context)
5686 == CLASS_IMPLEMENTATION_TYPE)
5687 || (TREE_CODE (objc_implementation_context)
5688 == CATEGORY_IMPLEMENTATION_TYPE))
5689 && (CLASS_NAME (objc_implementation_context)
5690 == TYPE_NAME (basetype))))
5691 return ! is_private (decl);
5693 error ("instance variable `%s' is declared %s",
5694 IDENTIFIER_POINTER (identifier),
5695 TREE_PRIVATE (decl) ? "private" : "protected");
5700 else if (objc_implementation_context && (basetype == objc_object_reference))
5702 TREE_TYPE (expr) = uprivate_record;
5703 warning ("static access to object of type `id'");
5710 /* Make sure all entries in CHAIN are also in LIST. */
5713 check_methods (tree chain, tree list, int mtype)
5719 if (!lookup_method (list, chain))
5723 if (TREE_CODE (objc_implementation_context)
5724 == CLASS_IMPLEMENTATION_TYPE)
5725 warning ("incomplete implementation of class `%s'",
5726 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5727 else if (TREE_CODE (objc_implementation_context)
5728 == CATEGORY_IMPLEMENTATION_TYPE)
5729 warning ("incomplete implementation of category `%s'",
5730 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5734 warning ("method definition for `%c%s' not found",
5735 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5738 chain = TREE_CHAIN (chain);
5744 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5747 conforms_to_protocol (tree class, tree protocol)
5749 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5751 tree p = CLASS_PROTOCOL_LIST (class);
5752 while (p && TREE_VALUE (p) != protocol)
5757 tree super = (CLASS_SUPER_NAME (class)
5758 ? lookup_interface (CLASS_SUPER_NAME (class))
5760 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5769 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5770 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5773 check_methods_accessible (tree chain, tree context, int mtype)
5777 tree base_context = context;
5781 context = base_context;
5785 list = CLASS_CLS_METHODS (context);
5787 list = CLASS_NST_METHODS (context);
5789 if (lookup_method (list, chain))
5792 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5793 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5794 context = (CLASS_SUPER_NAME (context)
5795 ? lookup_interface (CLASS_SUPER_NAME (context))
5798 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5799 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5800 context = (CLASS_NAME (context)
5801 ? lookup_interface (CLASS_NAME (context))
5807 if (context == NULL_TREE)
5811 if (TREE_CODE (objc_implementation_context)
5812 == CLASS_IMPLEMENTATION_TYPE)
5813 warning ("incomplete implementation of class `%s'",
5815 (CLASS_NAME (objc_implementation_context)));
5816 else if (TREE_CODE (objc_implementation_context)
5817 == CATEGORY_IMPLEMENTATION_TYPE)
5818 warning ("incomplete implementation of category `%s'",
5820 (CLASS_SUPER_NAME (objc_implementation_context)));
5823 warning ("method definition for `%c%s' not found",
5824 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5827 chain = TREE_CHAIN (chain); /* next method... */
5832 /* Check whether the current interface (accessible via
5833 'objc_implementation_context') actually implements protocol P, along
5834 with any protocols that P inherits. */
5837 check_protocol (tree p, const char *type, const char *name)
5839 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5843 /* Ensure that all protocols have bodies! */
5846 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5847 CLASS_CLS_METHODS (objc_implementation_context),
5849 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5850 CLASS_NST_METHODS (objc_implementation_context),
5855 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5856 objc_implementation_context,
5858 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5859 objc_implementation_context,
5864 warning ("%s `%s' does not fully implement the `%s' protocol",
5865 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5868 /* Check protocols recursively. */
5869 if (PROTOCOL_LIST (p))
5871 tree subs = PROTOCOL_LIST (p);
5873 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5877 tree sub = TREE_VALUE (subs);
5879 /* If the superclass does not conform to the protocols
5880 inherited by P, then we must! */
5881 if (!super_class || !conforms_to_protocol (super_class, sub))
5882 check_protocol (sub, type, name);
5883 subs = TREE_CHAIN (subs);
5888 /* Check whether the current interface (accessible via
5889 'objc_implementation_context') actually implements the protocols listed
5893 check_protocols (tree proto_list, const char *type, const char *name)
5895 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5897 tree p = TREE_VALUE (proto_list);
5899 check_protocol (p, type, name);
5903 /* Make sure that the class CLASS_NAME is defined
5904 CODE says which kind of thing CLASS_NAME ought to be.
5905 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5906 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5909 start_class (enum tree_code code, tree class_name, tree super_name,
5914 if (objc_implementation_context)
5916 warning ("`@end' missing in implementation context");
5917 finish_class (objc_implementation_context);
5918 objc_ivar_chain = NULL_TREE;
5919 objc_implementation_context = NULL_TREE;
5922 class = make_node (code);
5923 TYPE_BINFO (class) = make_tree_vec (BINFO_ELTS);
5925 CLASS_NAME (class) = class_name;
5926 CLASS_SUPER_NAME (class) = super_name;
5927 CLASS_CLS_METHODS (class) = NULL_TREE;
5929 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5931 error ("`%s' redeclared as different kind of symbol",
5932 IDENTIFIER_POINTER (class_name));
5933 error ("%Jprevious declaration of '%D'", decl, decl);
5936 if (code == CLASS_IMPLEMENTATION_TYPE)
5941 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5942 if (TREE_VALUE (chain) == class_name)
5944 error ("reimplementation of class `%s'",
5945 IDENTIFIER_POINTER (class_name));
5946 return error_mark_node;
5948 implemented_classes = tree_cons (NULL_TREE, class_name,
5949 implemented_classes);
5952 /* Pre-build the following entities - for speed/convenience. */
5954 self_id = get_identifier ("self");
5956 ucmd_id = get_identifier ("_cmd");
5959 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
5960 if (!objc_super_template)
5961 objc_super_template = build_super_template ();
5963 /* Reset for multiple classes per file. */
5966 objc_implementation_context = class;
5968 /* Lookup the interface for this implementation. */
5970 if (!(implementation_template = lookup_interface (class_name)))
5972 warning ("cannot find interface declaration for `%s'",
5973 IDENTIFIER_POINTER (class_name));
5974 add_class (implementation_template = objc_implementation_context);
5977 /* If a super class has been specified in the implementation,
5978 insure it conforms to the one specified in the interface. */
5981 && (super_name != CLASS_SUPER_NAME (implementation_template)))
5983 tree previous_name = CLASS_SUPER_NAME (implementation_template);
5984 const char *const name =
5985 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
5986 error ("conflicting super class name `%s'",
5987 IDENTIFIER_POINTER (super_name));
5988 error ("previous declaration of `%s'", name);
5991 else if (! super_name)
5993 CLASS_SUPER_NAME (objc_implementation_context)
5994 = CLASS_SUPER_NAME (implementation_template);
5998 else if (code == CLASS_INTERFACE_TYPE)
6000 if (lookup_interface (class_name))
6001 warning ("duplicate interface declaration for class `%s'",
6002 IDENTIFIER_POINTER (class_name));
6007 CLASS_PROTOCOL_LIST (class)
6008 = lookup_and_install_protocols (protocol_list);
6011 else if (code == CATEGORY_INTERFACE_TYPE)
6013 tree class_category_is_assoc_with;
6015 /* For a category, class_name is really the name of the class that
6016 the following set of methods will be associated with. We must
6017 find the interface so that can derive the objects template. */
6019 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6021 error ("cannot find interface declaration for `%s'",
6022 IDENTIFIER_POINTER (class_name));
6023 exit (FATAL_EXIT_CODE);
6026 add_category (class_category_is_assoc_with, class);
6029 CLASS_PROTOCOL_LIST (class)
6030 = lookup_and_install_protocols (protocol_list);
6033 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6035 /* Pre-build the following entities for speed/convenience. */
6037 self_id = get_identifier ("self");
6039 ucmd_id = get_identifier ("_cmd");
6042 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6043 if (!objc_super_template)
6044 objc_super_template = build_super_template ();
6046 /* Reset for multiple classes per file. */
6049 objc_implementation_context = class;
6051 /* For a category, class_name is really the name of the class that
6052 the following set of methods will be associated with. We must
6053 find the interface so that can derive the objects template. */
6055 if (!(implementation_template = lookup_interface (class_name)))
6057 error ("cannot find interface declaration for `%s'",
6058 IDENTIFIER_POINTER (class_name));
6059 exit (FATAL_EXIT_CODE);
6066 continue_class (tree class)
6068 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6069 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6071 struct imp_entry *imp_entry;
6074 /* Check consistency of the instance variables. */
6076 if (CLASS_IVARS (class))
6077 check_ivars (implementation_template, class);
6079 /* code generation */
6081 ivar_context = build_private_template (implementation_template);
6083 if (!objc_class_template)
6084 build_class_template ();
6086 imp_entry = ggc_alloc (sizeof (struct imp_entry));
6088 imp_entry->next = imp_list;
6089 imp_entry->imp_context = class;
6090 imp_entry->imp_template = implementation_template;
6092 synth_forward_declarations ();
6093 imp_entry->class_decl = UOBJC_CLASS_decl;
6094 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6096 /* Append to front and increment count. */
6097 imp_list = imp_entry;
6098 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6103 return ivar_context;
6106 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6108 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6110 if (!TYPE_FIELDS (record))
6112 finish_struct (record, get_class_ivars (class), NULL_TREE);
6113 CLASS_STATIC_TEMPLATE (class) = record;
6115 /* Mark this record as a class template for static typing. */
6116 TREE_STATIC_TEMPLATE (record) = 1;
6123 return error_mark_node;
6126 /* This is called once we see the "@end" in an interface/implementation. */
6129 finish_class (tree class)
6131 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6133 /* All code generation is done in finish_objc. */
6135 if (implementation_template != objc_implementation_context)
6137 /* Ensure that all method listed in the interface contain bodies. */
6138 check_methods (CLASS_CLS_METHODS (implementation_template),
6139 CLASS_CLS_METHODS (objc_implementation_context), '+');
6140 check_methods (CLASS_NST_METHODS (implementation_template),
6141 CLASS_NST_METHODS (objc_implementation_context), '-');
6143 if (CLASS_PROTOCOL_LIST (implementation_template))
6144 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6146 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6150 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6152 tree category = CLASS_CATEGORY_LIST (implementation_template);
6154 /* Find the category interface from the class it is associated with. */
6157 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6159 category = CLASS_CATEGORY_LIST (category);
6164 /* Ensure all method listed in the interface contain bodies. */
6165 check_methods (CLASS_CLS_METHODS (category),
6166 CLASS_CLS_METHODS (objc_implementation_context), '+');
6167 check_methods (CLASS_NST_METHODS (category),
6168 CLASS_NST_METHODS (objc_implementation_context), '-');
6170 if (CLASS_PROTOCOL_LIST (category))
6171 check_protocols (CLASS_PROTOCOL_LIST (category),
6173 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6177 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6180 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6181 char *string = alloca (strlen (class_name) + 3);
6183 /* extern struct objc_object *_<my_name>; */
6185 sprintf (string, "_%s", class_name);
6187 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6188 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6189 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6195 add_protocol (tree protocol)
6197 /* Put protocol on list in reverse order. */
6198 TREE_CHAIN (protocol) = protocol_chain;
6199 protocol_chain = protocol;
6200 return protocol_chain;
6204 lookup_protocol (tree ident)
6208 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6209 if (ident == PROTOCOL_NAME (chain))
6215 /* This function forward declares the protocols named by NAMES. If
6216 they are already declared or defined, the function has no effect. */
6219 objc_declare_protocols (tree names)
6223 for (list = names; list; list = TREE_CHAIN (list))
6225 tree name = TREE_VALUE (list);
6227 if (lookup_protocol (name) == NULL_TREE)
6229 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6231 TYPE_BINFO (protocol) = make_tree_vec (2);
6232 PROTOCOL_NAME (protocol) = name;
6233 PROTOCOL_LIST (protocol) = NULL_TREE;
6234 add_protocol (protocol);
6235 PROTOCOL_DEFINED (protocol) = 0;
6236 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6242 start_protocol (enum tree_code code, tree name, tree list)
6246 /* This is as good a place as any. Need to invoke
6247 push_tag_toplevel. */
6248 if (!objc_protocol_template)
6249 objc_protocol_template = build_protocol_template ();
6251 protocol = lookup_protocol (name);
6255 protocol = make_node (code);
6256 TYPE_BINFO (protocol) = make_tree_vec (2);
6258 PROTOCOL_NAME (protocol) = name;
6259 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6260 add_protocol (protocol);
6261 PROTOCOL_DEFINED (protocol) = 1;
6262 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6264 check_protocol_recursively (protocol, list);
6266 else if (! PROTOCOL_DEFINED (protocol))
6268 PROTOCOL_DEFINED (protocol) = 1;
6269 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6271 check_protocol_recursively (protocol, list);
6275 warning ("duplicate declaration for protocol `%s'",
6276 IDENTIFIER_POINTER (name));
6282 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
6287 /* "Encode" a data type into a string, which grows in util_obstack.
6288 ??? What is the FORMAT? Someone please document this! */
6291 encode_type_qualifiers (tree declspecs)
6295 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6297 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6298 obstack_1grow (&util_obstack, 'r');
6299 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6300 obstack_1grow (&util_obstack, 'n');
6301 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6302 obstack_1grow (&util_obstack, 'N');
6303 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6304 obstack_1grow (&util_obstack, 'o');
6305 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6306 obstack_1grow (&util_obstack, 'O');
6307 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6308 obstack_1grow (&util_obstack, 'R');
6309 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6310 obstack_1grow (&util_obstack, 'V');
6314 /* Encode a pointer type. */
6317 encode_pointer (tree type, int curtype, int format)
6319 tree pointer_to = TREE_TYPE (type);
6321 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6323 if (TYPE_NAME (pointer_to)
6324 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6326 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6328 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6330 obstack_1grow (&util_obstack, '@');
6333 else if (TREE_STATIC_TEMPLATE (pointer_to))
6335 if (generating_instance_variables)
6337 obstack_1grow (&util_obstack, '@');
6338 obstack_1grow (&util_obstack, '"');
6339 obstack_grow (&util_obstack, name, strlen (name));
6340 obstack_1grow (&util_obstack, '"');
6345 obstack_1grow (&util_obstack, '@');
6349 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6351 obstack_1grow (&util_obstack, '#');
6354 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6356 obstack_1grow (&util_obstack, ':');
6361 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6362 && TYPE_MODE (pointer_to) == QImode)
6364 obstack_1grow (&util_obstack, '*');
6368 /* We have a type that does not get special treatment. */
6370 /* NeXT extension */
6371 obstack_1grow (&util_obstack, '^');
6372 encode_type (pointer_to, curtype, format);
6376 encode_array (tree type, int curtype, int format)
6378 tree an_int_cst = TYPE_SIZE (type);
6379 tree array_of = TREE_TYPE (type);
6382 /* An incomplete array is treated like a pointer. */
6383 if (an_int_cst == NULL)
6385 encode_pointer (type, curtype, format);
6389 sprintf (buffer, "[%ld",
6390 (long) (TREE_INT_CST_LOW (an_int_cst)
6391 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6393 obstack_grow (&util_obstack, buffer, strlen (buffer));
6394 encode_type (array_of, curtype, format);
6395 obstack_1grow (&util_obstack, ']');
6400 encode_aggregate_within (tree type, int curtype, int format, int left,
6403 /* The RECORD_TYPE may in fact be a typedef! For purposes
6404 of encoding, we need the real underlying enchilada. */
6405 if (TYPE_MAIN_VARIANT (type))
6406 type = TYPE_MAIN_VARIANT (type);
6408 if (obstack_object_size (&util_obstack) > 0
6409 && *(obstack_next_free (&util_obstack) - 1) == '^')
6411 tree name = TYPE_NAME (type);
6413 /* we have a reference; this is a NeXT extension. */
6415 if (obstack_object_size (&util_obstack) - curtype == 1
6416 && format == OBJC_ENCODE_INLINE_DEFS)
6418 /* Output format of struct for first level only. */
6419 tree fields = TYPE_FIELDS (type);
6421 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6423 obstack_1grow (&util_obstack, left);
6424 obstack_grow (&util_obstack,
6425 IDENTIFIER_POINTER (name),
6426 strlen (IDENTIFIER_POINTER (name)));
6427 obstack_1grow (&util_obstack, '=');
6431 obstack_1grow (&util_obstack, left);
6432 obstack_grow (&util_obstack, "?=", 2);
6435 for ( ; fields; fields = TREE_CHAIN (fields))
6436 encode_field_decl (fields, curtype, format);
6438 obstack_1grow (&util_obstack, right);
6441 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6443 obstack_1grow (&util_obstack, left);
6444 obstack_grow (&util_obstack,
6445 IDENTIFIER_POINTER (name),
6446 strlen (IDENTIFIER_POINTER (name)));
6447 obstack_1grow (&util_obstack, right);
6452 /* We have an untagged structure or a typedef. */
6453 obstack_1grow (&util_obstack, left);
6454 obstack_1grow (&util_obstack, '?');
6455 obstack_1grow (&util_obstack, right);
6461 tree name = TYPE_NAME (type);
6462 tree fields = TYPE_FIELDS (type);
6464 if (format == OBJC_ENCODE_INLINE_DEFS
6465 || generating_instance_variables)
6467 obstack_1grow (&util_obstack, left);
6468 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6469 obstack_grow (&util_obstack,
6470 IDENTIFIER_POINTER (name),
6471 strlen (IDENTIFIER_POINTER (name)));
6473 obstack_1grow (&util_obstack, '?');
6475 obstack_1grow (&util_obstack, '=');
6477 for (; fields; fields = TREE_CHAIN (fields))
6479 if (generating_instance_variables)
6481 tree fname = DECL_NAME (fields);
6483 obstack_1grow (&util_obstack, '"');
6484 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6486 obstack_grow (&util_obstack,
6487 IDENTIFIER_POINTER (fname),
6488 strlen (IDENTIFIER_POINTER (fname)));
6491 obstack_1grow (&util_obstack, '"');
6494 encode_field_decl (fields, curtype, format);
6497 obstack_1grow (&util_obstack, right);
6502 obstack_1grow (&util_obstack, left);
6503 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6504 obstack_grow (&util_obstack,
6505 IDENTIFIER_POINTER (name),
6506 strlen (IDENTIFIER_POINTER (name)));
6508 /* We have an untagged structure or a typedef. */
6509 obstack_1grow (&util_obstack, '?');
6511 obstack_1grow (&util_obstack, right);
6517 encode_aggregate (tree type, int curtype, int format)
6519 enum tree_code code = TREE_CODE (type);
6525 encode_aggregate_within(type, curtype, format, '{', '}');
6530 encode_aggregate_within(type, curtype, format, '(', ')');
6535 obstack_1grow (&util_obstack, 'i');
6543 /* Support bitfields. The current version of Objective-C does not support
6544 them. The string will consist of one or more "b:n"'s where n is an
6545 integer describing the width of the bitfield. Currently, classes in
6546 the kit implement a method "-(char *)describeBitfieldStruct:" that
6547 simulates this. If they do not implement this method, the archiver
6548 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6549 according to the GNU compiler. After looking at the "kit", it appears
6550 that all classes currently rely on this default behavior, rather than
6551 hand generating this string (which is tedious). */
6554 encode_bitfield (int width)
6557 sprintf (buffer, "b%d", width);
6558 obstack_grow (&util_obstack, buffer, strlen (buffer));
6561 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6564 encode_type (tree type, int curtype, int format)
6566 enum tree_code code = TREE_CODE (type);
6568 if (code == INTEGER_TYPE)
6570 if (integer_zerop (TYPE_MIN_VALUE (type)))
6572 /* Unsigned integer types. */
6574 if (TYPE_MODE (type) == QImode)
6575 obstack_1grow (&util_obstack, 'C');
6576 else if (TYPE_MODE (type) == HImode)
6577 obstack_1grow (&util_obstack, 'S');
6578 else if (TYPE_MODE (type) == SImode)
6580 if (type == long_unsigned_type_node)
6581 obstack_1grow (&util_obstack, 'L');
6583 obstack_1grow (&util_obstack, 'I');
6585 else if (TYPE_MODE (type) == DImode)
6586 obstack_1grow (&util_obstack, 'Q');
6590 /* Signed integer types. */
6592 if (TYPE_MODE (type) == QImode)
6593 obstack_1grow (&util_obstack, 'c');
6594 else if (TYPE_MODE (type) == HImode)
6595 obstack_1grow (&util_obstack, 's');
6596 else if (TYPE_MODE (type) == SImode)
6598 if (type == long_integer_type_node)
6599 obstack_1grow (&util_obstack, 'l');
6601 obstack_1grow (&util_obstack, 'i');
6604 else if (TYPE_MODE (type) == DImode)
6605 obstack_1grow (&util_obstack, 'q');
6609 else if (code == REAL_TYPE)
6611 /* Floating point types. */
6613 if (TYPE_MODE (type) == SFmode)
6614 obstack_1grow (&util_obstack, 'f');
6615 else if (TYPE_MODE (type) == DFmode
6616 || TYPE_MODE (type) == TFmode)
6617 obstack_1grow (&util_obstack, 'd');
6620 else if (code == VOID_TYPE)
6621 obstack_1grow (&util_obstack, 'v');
6623 else if (code == ARRAY_TYPE)
6624 encode_array (type, curtype, format);
6626 else if (code == POINTER_TYPE)
6627 encode_pointer (type, curtype, format);
6629 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6630 encode_aggregate (type, curtype, format);
6632 else if (code == FUNCTION_TYPE) /* '?' */
6633 obstack_1grow (&util_obstack, '?');
6637 encode_complete_bitfield (int position, tree type, int size)
6639 enum tree_code code = TREE_CODE (type);
6641 char charType = '?';
6643 if (code == INTEGER_TYPE)
6645 if (integer_zerop (TYPE_MIN_VALUE (type)))
6647 /* Unsigned integer types. */
6649 if (TYPE_MODE (type) == QImode)
6651 else if (TYPE_MODE (type) == HImode)
6653 else if (TYPE_MODE (type) == SImode)
6655 if (type == long_unsigned_type_node)
6660 else if (TYPE_MODE (type) == DImode)
6665 /* Signed integer types. */
6667 if (TYPE_MODE (type) == QImode)
6669 else if (TYPE_MODE (type) == HImode)
6671 else if (TYPE_MODE (type) == SImode)
6673 if (type == long_integer_type_node)
6679 else if (TYPE_MODE (type) == DImode)
6683 else if (code == ENUMERAL_TYPE)
6688 sprintf (buffer, "b%d%c%d", position, charType, size);
6689 obstack_grow (&util_obstack, buffer, strlen (buffer));
6693 encode_field_decl (tree field_decl, int curtype, int format)
6697 type = TREE_TYPE (field_decl);
6699 /* If this field is obviously a bitfield, or is a bitfield that has been
6700 clobbered to look like a ordinary integer mode, go ahead and generate
6701 the bitfield typing information. */
6702 if (flag_next_runtime)
6704 if (DECL_BIT_FIELD_TYPE (field_decl))
6705 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6707 encode_type (TREE_TYPE (field_decl), curtype, format);
6711 if (DECL_BIT_FIELD_TYPE (field_decl))
6712 encode_complete_bitfield (int_bit_position (field_decl),
6713 DECL_BIT_FIELD_TYPE (field_decl),
6714 tree_low_cst (DECL_SIZE (field_decl), 1));
6716 encode_type (TREE_TYPE (field_decl), curtype, format);
6721 objc_expr_last (tree complex_expr)
6726 while ((next = TREE_OPERAND (complex_expr, 0)))
6727 complex_expr = next;
6729 return complex_expr;
6732 /* Transform a method definition into a function definition as follows:
6733 - synthesize the first two arguments, "self" and "_cmd". */
6736 start_method_def (tree method)
6740 /* Required to implement _msgSuper. */
6741 objc_method_context = method;
6742 UOBJC_SUPER_decl = NULL_TREE;
6744 /* Must be called BEFORE start_function. */
6747 /* Generate prototype declarations for arguments..."new-style". */
6749 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6750 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6752 /* Really a `struct objc_class *'. However, we allow people to
6753 assign to self, which changes its type midstream. */
6754 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6756 push_parm_decl (build_tree_list
6757 (build_tree_list (decl_specs,
6758 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6761 decl_specs = build_tree_list (NULL_TREE,
6762 xref_tag (RECORD_TYPE,
6763 get_identifier (TAG_SELECTOR)));
6764 push_parm_decl (build_tree_list
6765 (build_tree_list (decl_specs,
6766 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6769 /* Generate argument declarations if a keyword_decl. */
6770 if (METHOD_SEL_ARGS (method))
6772 tree arglist = METHOD_SEL_ARGS (method);
6775 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6776 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6780 tree last_expr = objc_expr_last (arg_decl);
6782 /* Unite the abstract decl with its name. */
6783 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6784 push_parm_decl (build_tree_list
6785 (build_tree_list (arg_spec, arg_decl),
6788 /* Unhook: restore the abstract declarator. */
6789 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6793 push_parm_decl (build_tree_list
6794 (build_tree_list (arg_spec,
6795 KEYWORD_ARG_NAME (arglist)),
6798 arglist = TREE_CHAIN (arglist);
6803 if (METHOD_ADD_ARGS (method) != NULL_TREE
6804 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6806 /* We have a variable length selector - in "prototype" format. */
6807 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6810 /* This must be done prior to calling pushdecl. pushdecl is
6811 going to change our chain on us. */
6812 tree nextkey = TREE_CHAIN (akey);
6820 warn_with_method (const char *message, int mtype, tree method)
6822 /* Add a readable method name to the warning. */
6823 warning ("%J%s `%c%s'", method, message, mtype,
6824 gen_method_decl (method, errbuf));
6827 /* Return 1 if METHOD is consistent with PROTO. */
6830 comp_method_with_proto (tree method, tree proto)
6832 /* Create a function template node at most once. */
6833 if (!function1_template)
6834 function1_template = make_node (FUNCTION_TYPE);
6836 /* Install argument types - normally set by build_function_type. */
6837 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6839 /* install return type */
6840 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6842 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template,
6846 /* Return 1 if PROTO1 is consistent with PROTO2. */
6849 comp_proto_with_proto (tree proto0, tree proto1)
6851 /* Create a couple of function_template nodes at most once. */
6852 if (!function1_template)
6853 function1_template = make_node (FUNCTION_TYPE);
6854 if (!function2_template)
6855 function2_template = make_node (FUNCTION_TYPE);
6857 /* Install argument types; normally set by build_function_type. */
6858 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6859 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6861 /* Install return type. */
6862 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6863 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6865 return comptypes (function1_template, function2_template, false);
6868 /* - Generate an identifier for the function. the format is "_n_cls",
6869 where 1 <= n <= nMethods, and cls is the name the implementation we
6871 - Install the return type from the method declaration.
6872 - If we have a prototype, check for type consistency. */
6875 really_start_method (tree method, tree parmlist)
6877 tree sc_spec, ret_spec, ret_decl, decl_specs;
6878 tree method_decl, method_id;
6879 const char *sel_name, *class_name, *cat_name;
6882 /* Synth the storage class & assemble the return type. */
6883 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6884 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6885 decl_specs = chainon (sc_spec, ret_spec);
6887 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6888 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6889 cat_name = ((TREE_CODE (objc_implementation_context)
6890 == CLASS_IMPLEMENTATION_TYPE)
6892 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6895 /* Make sure this is big enough for any plausible method label. */
6896 buf = alloca (50 + strlen (sel_name) + strlen (class_name)
6897 + (cat_name ? strlen (cat_name) : 0));
6899 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6900 class_name, cat_name, sel_name, method_slot);
6902 method_id = get_identifier (buf);
6904 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
6906 /* Check the declarator portion of the return type for the method. */
6907 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
6909 /* Unite the complex decl (specified in the abstract decl) with the
6910 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6911 tree save_expr = objc_expr_last (ret_decl);
6913 TREE_OPERAND (save_expr, 0) = method_decl;
6914 method_decl = ret_decl;
6916 /* Fool the parser into thinking it is starting a function. */
6917 start_function (decl_specs, method_decl, NULL_TREE);
6919 /* Unhook: this has the effect of restoring the abstract declarator. */
6920 TREE_OPERAND (save_expr, 0) = NULL_TREE;
6925 TREE_VALUE (TREE_TYPE (method)) = method_decl;
6927 /* Fool the parser into thinking it is starting a function. */
6928 start_function (decl_specs, method_decl, NULL_TREE);
6930 /* Unhook: this has the effect of restoring the abstract declarator. */
6931 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
6934 METHOD_DEFINITION (method) = current_function_decl;
6936 /* Check consistency...start_function, pushdecl, duplicate_decls. */
6938 if (implementation_template != objc_implementation_context)
6942 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
6943 proto = lookup_instance_method_static (implementation_template,
6944 METHOD_SEL_NAME (method));
6946 proto = lookup_class_method_static (implementation_template,
6947 METHOD_SEL_NAME (method));
6949 if (proto && ! comp_method_with_proto (method, proto))
6951 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
6953 warn_with_method ("conflicting types for", type, method);
6954 warn_with_method ("previous declaration of", type, proto);
6959 /* The following routine is always called...this "architecture" is to
6960 accommodate "old-style" variable length selectors.
6962 - a:a b:b // prototype ; id c; id d; // old-style. */
6965 continue_method_def (void)
6969 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
6970 /* We have a `, ...' immediately following the selector. */
6971 parmlist = get_parm_info (0);
6973 parmlist = get_parm_info (1); /* place a `void_at_end' */
6975 /* Set self_decl from the first argument...this global is used by
6976 build_ivar_reference calling build_indirect_ref. */
6977 self_decl = TREE_PURPOSE (parmlist);
6980 really_start_method (objc_method_context, parmlist);
6981 store_parm_decls ();
6984 /* Called by the parser, from the `pushlevel' production. */
6987 add_objc_decls (void)
6989 if (!UOBJC_SUPER_decl)
6991 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
6992 build_tree_list (NULL_TREE,
6993 objc_super_template),
6996 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
6998 /* This prevents `unused variable' warnings when compiling with -Wall. */
6999 TREE_USED (UOBJC_SUPER_decl) = 1;
7000 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7004 /* _n_Method (id self, SEL sel, ...)
7006 struct objc_super _S;
7007 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7011 get_super_receiver (void)
7013 if (objc_method_context)
7015 tree super_expr, super_expr_list;
7017 /* Set receiver to self. */
7018 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7019 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7020 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7022 /* Set class to begin searching. */
7023 super_expr = build_component_ref (UOBJC_SUPER_decl,
7024 get_identifier ("class"));
7026 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7028 /* [_cls, __cls]Super are "pre-built" in
7029 synth_forward_declarations. */
7031 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7032 ((TREE_CODE (objc_method_context)
7033 == INSTANCE_METHOD_DECL)
7035 : uucls_super_ref));
7039 /* We have a category. */
7041 tree super_name = CLASS_SUPER_NAME (implementation_template);
7044 /* Barf if super used in a category of Object. */
7047 error ("no super class declared in interface for `%s'",
7048 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7049 return error_mark_node;
7052 if (flag_next_runtime)
7054 super_class = get_class_reference (super_name);
7055 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7056 /* Cast the super class to 'id', since the user may not have
7057 included <objc/objc-class.h>, leaving 'struct objc_class'
7058 an incomplete type. */
7060 = build_component_ref (build_indirect_ref
7061 (build_c_cast (id_type, super_class), "->"),
7062 get_identifier ("isa"));
7066 add_class_reference (super_name);
7067 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7068 ? objc_get_class_decl : objc_get_meta_class_decl);
7069 assemble_external (super_class);
7071 = build_function_call
7075 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7076 IDENTIFIER_POINTER (super_name))));
7079 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7080 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7083 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7085 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7086 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7088 return build_compound_expr (super_expr_list);
7092 error ("[super ...] must appear in a method context");
7093 return error_mark_node;
7098 encode_method_def (tree func_decl)
7102 HOST_WIDE_INT max_parm_end = 0;
7107 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7108 obstack_object_size (&util_obstack),
7109 OBJC_ENCODE_INLINE_DEFS);
7112 for (parms = DECL_ARGUMENTS (func_decl); parms;
7113 parms = TREE_CHAIN (parms))
7115 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7116 + int_size_in_bytes (TREE_TYPE (parms)));
7118 if (! offset_is_register && parm_end > max_parm_end)
7119 max_parm_end = parm_end;
7122 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7124 sprintf (buffer, "%d", stack_size);
7125 obstack_grow (&util_obstack, buffer, strlen (buffer));
7127 /* Argument types. */
7128 for (parms = DECL_ARGUMENTS (func_decl); parms;
7129 parms = TREE_CHAIN (parms))
7132 encode_type (TREE_TYPE (parms),
7133 obstack_object_size (&util_obstack),
7134 OBJC_ENCODE_INLINE_DEFS);
7136 /* Compute offset. */
7137 sprintf (buffer, "%d", forwarding_offset (parms));
7139 /* Indicate register. */
7140 if (offset_is_register)
7141 obstack_1grow (&util_obstack, '+');
7143 obstack_grow (&util_obstack, buffer, strlen (buffer));
7146 /* Null terminate string. */
7147 obstack_1grow (&util_obstack, 0);
7148 result = get_identifier (obstack_finish (&util_obstack));
7149 obstack_free (&util_obstack, util_firstobj);
7154 objc_expand_function_end (void)
7156 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7160 finish_method_def (void)
7162 lang_expand_function_end = objc_expand_function_end;
7164 lang_expand_function_end = NULL;
7166 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7167 since the optimizer may find "may be used before set" errors. */
7168 objc_method_context = NULL_TREE;
7173 lang_report_error_function (tree decl)
7175 if (objc_method_context)
7177 fprintf (stderr, "In method `%s'\n",
7178 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7188 is_complex_decl (tree type)
7190 return (TREE_CODE (type) == ARRAY_TYPE
7191 || TREE_CODE (type) == FUNCTION_TYPE
7192 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7196 /* Code to convert a decl node into text for a declaration in C. */
7198 static char tmpbuf[256];
7201 adorn_decl (tree decl, char *str)
7203 enum tree_code code = TREE_CODE (decl);
7205 if (code == ARRAY_REF)
7207 tree an_int_cst = TREE_OPERAND (decl, 1);
7209 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7210 sprintf (str + strlen (str), "[%ld]",
7211 (long) TREE_INT_CST_LOW (an_int_cst));
7216 else if (code == ARRAY_TYPE)
7218 tree an_int_cst = TYPE_SIZE (decl);
7219 tree array_of = TREE_TYPE (decl);
7221 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7222 sprintf (str + strlen (str), "[%ld]",
7223 (long) (TREE_INT_CST_LOW (an_int_cst)
7224 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7229 else if (code == CALL_EXPR)
7231 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7236 gen_declaration_1 (chain, str);
7237 chain = TREE_CHAIN (chain);
7244 else if (code == FUNCTION_TYPE)
7246 tree chain = TYPE_ARG_TYPES (decl);
7249 while (chain && TREE_VALUE (chain) != void_type_node)
7251 gen_declaration_1 (TREE_VALUE (chain), str);
7252 chain = TREE_CHAIN (chain);
7253 if (chain && TREE_VALUE (chain) != void_type_node)
7259 else if (code == INDIRECT_REF)
7261 strcpy (tmpbuf, "*");
7262 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7266 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7268 chain = TREE_CHAIN (chain))
7270 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7272 strcat (tmpbuf, " ");
7273 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7277 strcat (tmpbuf, " ");
7279 strcat (tmpbuf, str);
7280 strcpy (str, tmpbuf);
7283 else if (code == POINTER_TYPE)
7285 strcpy (tmpbuf, "*");
7286 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7288 if (TREE_READONLY (decl))
7289 strcat (tmpbuf, " const");
7290 if (TYPE_VOLATILE (decl))
7291 strcat (tmpbuf, " volatile");
7293 strcat (tmpbuf, " ");
7295 strcat (tmpbuf, str);
7296 strcpy (str, tmpbuf);
7301 gen_declarator (tree decl, char *buf, const char *name)
7305 enum tree_code code = TREE_CODE (decl);
7315 op = TREE_OPERAND (decl, 0);
7317 /* We have a pointer to a function or array...(*)(), (*)[] */
7318 if ((code == ARRAY_REF || code == CALL_EXPR)
7319 && op && TREE_CODE (op) == INDIRECT_REF)
7322 str = gen_declarator (op, buf, name);
7326 strcpy (tmpbuf, "(");
7327 strcat (tmpbuf, str);
7328 strcat (tmpbuf, ")");
7329 strcpy (str, tmpbuf);
7332 adorn_decl (decl, str);
7341 /* This clause is done iteratively rather than recursively. */
7344 op = (is_complex_decl (TREE_TYPE (decl))
7345 ? TREE_TYPE (decl) : NULL_TREE);
7347 adorn_decl (decl, str);
7349 /* We have a pointer to a function or array...(*)(), (*)[] */
7350 if (code == POINTER_TYPE
7351 && op && (TREE_CODE (op) == FUNCTION_TYPE
7352 || TREE_CODE (op) == ARRAY_TYPE))
7354 strcpy (tmpbuf, "(");
7355 strcat (tmpbuf, str);
7356 strcat (tmpbuf, ")");
7357 strcpy (str, tmpbuf);
7360 decl = (is_complex_decl (TREE_TYPE (decl))
7361 ? TREE_TYPE (decl) : NULL_TREE);
7364 while (decl && (code = TREE_CODE (decl)))
7369 case IDENTIFIER_NODE:
7370 /* Will only happen if we are processing a "raw" expr-decl. */
7371 strcpy (buf, IDENTIFIER_POINTER (decl));
7382 /* We have an abstract declarator or a _DECL node. */
7390 gen_declspecs (tree declspecs, char *buf, int raw)
7396 for (chain = nreverse (copy_list (declspecs));
7397 chain; chain = TREE_CHAIN (chain))
7399 tree aspec = TREE_VALUE (chain);
7401 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7402 strcat (buf, IDENTIFIER_POINTER (aspec));
7403 else if (TREE_CODE (aspec) == RECORD_TYPE)
7405 if (TYPE_NAME (aspec))
7407 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7409 if (! TREE_STATIC_TEMPLATE (aspec))
7410 strcat (buf, "struct ");
7411 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7416 tree chain = protocol_list;
7423 (PROTOCOL_NAME (TREE_VALUE (chain))));
7424 chain = TREE_CHAIN (chain);
7433 strcat (buf, "untagged struct");
7436 else if (TREE_CODE (aspec) == UNION_TYPE)
7438 if (TYPE_NAME (aspec))
7440 if (! TREE_STATIC_TEMPLATE (aspec))
7441 strcat (buf, "union ");
7442 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7445 strcat (buf, "untagged union");
7448 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7450 if (TYPE_NAME (aspec))
7452 if (! TREE_STATIC_TEMPLATE (aspec))
7453 strcat (buf, "enum ");
7454 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7457 strcat (buf, "untagged enum");
7460 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7461 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7463 else if (IS_ID (aspec))
7465 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7470 tree chain = protocol_list;
7477 (PROTOCOL_NAME (TREE_VALUE (chain))));
7478 chain = TREE_CHAIN (chain);
7485 if (TREE_CHAIN (chain))
7491 /* Type qualifiers. */
7492 if (TREE_READONLY (declspecs))
7493 strcat (buf, "const ");
7494 if (TYPE_VOLATILE (declspecs))
7495 strcat (buf, "volatile ");
7497 switch (TREE_CODE (declspecs))
7499 /* Type specifiers. */
7502 declspecs = TYPE_MAIN_VARIANT (declspecs);
7504 /* Signed integer types. */
7506 if (declspecs == short_integer_type_node)
7507 strcat (buf, "short int ");
7508 else if (declspecs == integer_type_node)
7509 strcat (buf, "int ");
7510 else if (declspecs == long_integer_type_node)
7511 strcat (buf, "long int ");
7512 else if (declspecs == long_long_integer_type_node)
7513 strcat (buf, "long long int ");
7514 else if (declspecs == signed_char_type_node
7515 || declspecs == char_type_node)
7516 strcat (buf, "char ");
7518 /* Unsigned integer types. */
7520 else if (declspecs == short_unsigned_type_node)
7521 strcat (buf, "unsigned short ");
7522 else if (declspecs == unsigned_type_node)
7523 strcat (buf, "unsigned int ");
7524 else if (declspecs == long_unsigned_type_node)
7525 strcat (buf, "unsigned long ");
7526 else if (declspecs == long_long_unsigned_type_node)
7527 strcat (buf, "unsigned long long ");
7528 else if (declspecs == unsigned_char_type_node)
7529 strcat (buf, "unsigned char ");
7533 declspecs = TYPE_MAIN_VARIANT (declspecs);
7535 if (declspecs == float_type_node)
7536 strcat (buf, "float ");
7537 else if (declspecs == double_type_node)
7538 strcat (buf, "double ");
7539 else if (declspecs == long_double_type_node)
7540 strcat (buf, "long double ");
7544 if (TYPE_NAME (declspecs)
7545 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7547 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7549 if (! TREE_STATIC_TEMPLATE (declspecs))
7550 strcat (buf, "struct ");
7551 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7555 tree chain = protocol_list;
7562 (PROTOCOL_NAME (TREE_VALUE (chain))));
7563 chain = TREE_CHAIN (chain);
7572 strcat (buf, "untagged struct");
7578 if (TYPE_NAME (declspecs)
7579 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7581 strcat (buf, "union ");
7582 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7587 strcat (buf, "untagged union ");
7591 if (TYPE_NAME (declspecs)
7592 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7594 strcat (buf, "enum ");
7595 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7600 strcat (buf, "untagged enum ");
7604 strcat (buf, "void ");
7609 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7614 tree chain = protocol_list;
7621 (PROTOCOL_NAME (TREE_VALUE (chain))));
7622 chain = TREE_CHAIN (chain);
7638 /* Given a tree node, produce a printable description of it in the given
7639 buffer, overwriting the buffer. */
7642 gen_declaration (tree atype_or_adecl, char *buf)
7645 gen_declaration_1 (atype_or_adecl, buf);
7649 /* Given a tree node, append a printable description to the end of the
7653 gen_declaration_1 (tree atype_or_adecl, char *buf)
7657 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7659 tree declspecs; /* "identifier_node", "record_type" */
7660 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7662 /* We have a "raw", abstract declarator (typename). */
7663 declarator = TREE_VALUE (atype_or_adecl);
7664 declspecs = TREE_PURPOSE (atype_or_adecl);
7666 gen_declspecs (declspecs, buf, 1);
7670 strcat (buf, gen_declarator (declarator, declbuf, ""));
7677 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7678 tree declarator; /* "array_type", "function_type", "pointer_type". */
7680 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7681 || TREE_CODE (atype_or_adecl) == PARM_DECL
7682 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7683 atype = TREE_TYPE (atype_or_adecl);
7685 /* Assume we have a *_type node. */
7686 atype = atype_or_adecl;
7688 if (is_complex_decl (atype))
7692 /* Get the declaration specifier; it is at the end of the list. */
7693 declarator = chain = atype;
7695 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7696 while (is_complex_decl (chain));
7703 declarator = NULL_TREE;
7706 gen_declspecs (declspecs, buf, 0);
7708 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7709 || TREE_CODE (atype_or_adecl) == PARM_DECL
7710 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7712 const char *const decl_name =
7713 (DECL_NAME (atype_or_adecl)
7714 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7719 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7722 else if (decl_name[0])
7725 strcat (buf, decl_name);
7728 else if (declarator)
7731 strcat (buf, gen_declarator (declarator, declbuf, ""));
7736 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7738 /* Given a method tree, put a printable description into the given
7739 buffer (overwriting) and return a pointer to the buffer. */
7742 gen_method_decl (tree method, char *buf)
7747 if (RAW_TYPESPEC (method) != objc_object_reference)
7750 gen_declaration_1 (TREE_TYPE (method), buf);
7754 chain = METHOD_SEL_ARGS (method);
7757 /* We have a chain of keyword_decls. */
7760 if (KEYWORD_KEY_NAME (chain))
7761 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7764 if (RAW_TYPESPEC (chain) != objc_object_reference)
7767 gen_declaration_1 (TREE_TYPE (chain), buf);
7771 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7772 if ((chain = TREE_CHAIN (chain)))
7777 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7778 strcat (buf, ", ...");
7779 else if (METHOD_ADD_ARGS (method))
7781 /* We have a tree list node as generate by get_parm_info. */
7782 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7784 /* Know we have a chain of parm_decls. */
7788 gen_declaration_1 (chain, buf);
7789 chain = TREE_CHAIN (chain);
7795 /* We have a unary selector. */
7796 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7804 /* Dump an @interface declaration of the supplied class CHAIN to the
7805 supplied file FP. Used to implement the -gen-decls option (which
7806 prints out an @interface declaration of all classes compiled in
7807 this run); potentially useful for debugging the compiler too. */
7809 dump_interface (FILE *fp, tree chain)
7811 /* FIXME: A heap overflow here whenever a method (or ivar)
7812 declaration is so long that it doesn't fit in the buffer. The
7813 code and all the related functions should be rewritten to avoid
7814 using fixed size buffers. */
7815 char *buf = xmalloc (1024 * 10);
7816 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7817 tree ivar_decls = CLASS_RAW_IVARS (chain);
7818 tree nst_methods = CLASS_NST_METHODS (chain);
7819 tree cls_methods = CLASS_CLS_METHODS (chain);
7821 fprintf (fp, "\n@interface %s", my_name);
7823 /* CLASS_SUPER_NAME is used to store the superclass name for
7824 classes, and the category name for categories. */
7825 if (CLASS_SUPER_NAME (chain))
7827 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7829 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
7830 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
7832 fprintf (fp, " (%s)\n", name);
7836 fprintf (fp, " : %s\n", name);
7842 /* FIXME - the following doesn't seem to work at the moment. */
7845 fprintf (fp, "{\n");
7848 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7849 ivar_decls = TREE_CHAIN (ivar_decls);
7852 fprintf (fp, "}\n");
7857 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7858 nst_methods = TREE_CHAIN (nst_methods);
7863 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7864 cls_methods = TREE_CHAIN (cls_methods);
7867 fprintf (fp, "@end\n");
7870 /* Demangle function for Objective-C */
7872 objc_demangle (const char *mangled)
7874 char *demangled, *cp;
7876 if (mangled[0] == '_' &&
7877 (mangled[1] == 'i' || mangled[1] == 'c') &&
7880 cp = demangled = xmalloc(strlen(mangled) + 2);
7881 if (mangled[1] == 'i')
7882 *cp++ = '-'; /* for instance method */
7884 *cp++ = '+'; /* for class method */
7885 *cp++ = '['; /* opening left brace */
7886 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
7887 while (*cp && *cp == '_')
7888 cp++; /* skip any initial underbars in class name */
7889 cp = strchr(cp, '_'); /* find first non-initial underbar */
7892 free(demangled); /* not mangled name */
7895 if (cp[1] == '_') /* easy case: no category name */
7897 *cp++ = ' '; /* replace two '_' with one ' ' */
7898 strcpy(cp, mangled + (cp - demangled) + 2);
7902 *cp++ = '('; /* less easy case: category name */
7903 cp = strchr(cp, '_');
7906 free(demangled); /* not mangled name */
7910 *cp++ = ' '; /* overwriting 1st char of method name... */
7911 strcpy(cp, mangled + (cp - demangled)); /* get it back */
7913 while (*cp && *cp == '_')
7914 cp++; /* skip any initial underbars in method name */
7917 *cp = ':'; /* replace remaining '_' with ':' */
7918 *cp++ = ']'; /* closing right brace */
7919 *cp++ = 0; /* string terminator */
7923 return mangled; /* not an objc mangled name */
7927 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
7929 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
7935 gcc_obstack_init (&util_obstack);
7936 util_firstobj = (char *) obstack_finish (&util_obstack);
7938 errbuf = xmalloc (BUFSIZE);
7940 synth_module_prologue ();
7946 struct imp_entry *impent;
7948 /* The internally generated initializers appear to have missing braces.
7949 Don't warn about this. */
7950 int save_warn_missing_braces = warn_missing_braces;
7951 warn_missing_braces = 0;
7953 /* A missing @end may not be detected by the parser. */
7954 if (objc_implementation_context)
7956 warning ("`@end' missing in implementation context");
7957 finish_class (objc_implementation_context);
7958 objc_ivar_chain = NULL_TREE;
7959 objc_implementation_context = NULL_TREE;
7962 generate_forward_declaration_to_string_table ();
7964 /* Process the static instances here because initialization of objc_symtab
7966 if (objc_static_instances)
7967 generate_static_references ();
7969 if (imp_list || class_names_chain
7970 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
7971 generate_objc_symtab_decl ();
7973 for (impent = imp_list; impent; impent = impent->next)
7975 objc_implementation_context = impent->imp_context;
7976 implementation_template = impent->imp_template;
7978 UOBJC_CLASS_decl = impent->class_decl;
7979 UOBJC_METACLASS_decl = impent->meta_decl;
7981 /* Dump the @interface of each class as we compile it, if the
7982 -gen-decls option is in use. TODO: Dump the classes in the
7983 order they were found, rather than in reverse order as we
7985 if (flag_gen_declaration)
7987 dump_interface (gen_declaration_file, objc_implementation_context);
7990 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7992 /* all of the following reference the string pool... */
7993 generate_ivar_lists ();
7994 generate_dispatch_tables ();
7995 generate_shared_structures ();
7999 generate_dispatch_tables ();
8000 generate_category (objc_implementation_context);
8004 /* If we are using an array of selectors, we must always
8005 finish up the array decl even if no selectors were used. */
8006 if (! flag_next_runtime || sel_ref_chain)
8007 build_selector_translation_table ();
8010 generate_protocols ();
8012 if (objc_implementation_context || class_names_chain || objc_static_instances
8013 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8015 /* Arrange for ObjC data structures to be initialized at run time. */
8016 rtx init_sym = build_module_descriptor ();
8017 if (init_sym && targetm.have_ctors_dtors)
8018 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8021 /* Dump the class references. This forces the appropriate classes
8022 to be linked into the executable image, preserving unix archive
8023 semantics. This can be removed when we move to a more dynamically
8024 linked environment. */
8026 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8028 handle_class_ref (chain);
8029 if (TREE_PURPOSE (chain))
8030 generate_classref_translation_entry (chain);
8033 for (impent = imp_list; impent; impent = impent->next)
8034 handle_impent (impent);
8036 /* Dump the string table last. */
8038 generate_strings ();
8045 /* Run through the selector hash tables and print a warning for any
8046 selector which has multiple methods. */
8048 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8049 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8052 tree meth = hsh->key;
8053 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8057 warning ("potential selector conflict for method `%s'",
8058 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8059 warn_with_method ("found", type, meth);
8060 for (loop = hsh->list; loop; loop = loop->next)
8061 warn_with_method ("found", type, loop->value);
8064 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8065 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8068 tree meth = hsh->key;
8069 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8073 warning ("potential selector conflict for method `%s'",
8074 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8075 warn_with_method ("found", type, meth);
8076 for (loop = hsh->list; loop; loop = loop->next)
8077 warn_with_method ("found", type, loop->value);
8081 warn_missing_braces = save_warn_missing_braces;
8084 /* Subroutines of finish_objc. */
8087 generate_classref_translation_entry (tree chain)
8089 tree expr, name, decl_specs, decl, sc_spec;
8092 type = TREE_TYPE (TREE_PURPOSE (chain));
8094 expr = add_objc_string (TREE_VALUE (chain), class_names);
8095 expr = build_c_cast (type, expr); /* cast! */
8097 name = DECL_NAME (TREE_PURPOSE (chain));
8099 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8101 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8102 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8104 /* The decl that is returned from start_decl is the one that we
8105 forward declared in build_class_reference. */
8106 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8107 DECL_CONTEXT (decl) = NULL_TREE;
8108 finish_decl (decl, expr, NULL_TREE);
8113 handle_class_ref (tree chain)
8115 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8116 char *string = alloca (strlen (name) + 30);
8120 sprintf (string, "%sobjc_class_name_%s",
8121 (flag_next_runtime ? "." : "__"), name);
8123 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8124 if (flag_next_runtime)
8126 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8131 /* Make a decl for this name, so we can use its address in a tree. */
8132 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8133 DECL_EXTERNAL (decl) = 1;
8134 TREE_PUBLIC (decl) = 1;
8137 rest_of_decl_compilation (decl, 0, 0, 0);
8139 /* Make a decl for the address. */
8140 sprintf (string, "%sobjc_class_ref_%s",
8141 (flag_next_runtime ? "." : "__"), name);
8142 exp = build1 (ADDR_EXPR, string_type_node, decl);
8143 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8144 DECL_INITIAL (decl) = exp;
8145 TREE_STATIC (decl) = 1;
8146 TREE_USED (decl) = 1;
8149 rest_of_decl_compilation (decl, 0, 0, 0);
8153 handle_impent (struct imp_entry *impent)
8157 objc_implementation_context = impent->imp_context;
8158 implementation_template = impent->imp_template;
8160 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8162 const char *const class_name =
8163 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8165 string = alloca (strlen (class_name) + 30);
8167 sprintf (string, "%sobjc_class_name_%s",
8168 (flag_next_runtime ? "." : "__"), class_name);
8170 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8172 const char *const class_name =
8173 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8174 const char *const class_super_name =
8175 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8177 string = alloca (strlen (class_name)
8178 + strlen (class_super_name) + 30);
8180 /* Do the same for categories. Even though no references to
8181 these symbols are generated automatically by the compiler, it
8182 gives you a handle to pull them into an archive by hand. */
8183 sprintf (string, "*%sobjc_category_name_%s_%s",
8184 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8189 #ifdef ASM_DECLARE_CLASS_REFERENCE
8190 if (flag_next_runtime)
8192 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8200 init = build_int_2 (0, 0);
8201 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8202 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8203 TREE_PUBLIC (decl) = 1;
8204 TREE_READONLY (decl) = 1;
8205 TREE_USED (decl) = 1;
8206 TREE_CONSTANT (decl) = 1;
8207 DECL_CONTEXT (decl) = 0;
8208 DECL_ARTIFICIAL (decl) = 1;
8209 DECL_INITIAL (decl) = init;
8210 assemble_variable (decl, 1, 0, 0);
8214 /* Look up ID as an instance variable. */
8216 lookup_objc_ivar (tree id)
8220 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8221 /* We have a message to super. */
8222 return get_super_receiver ();
8223 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8225 if (is_private (decl))
8226 return error_mark_node;
8228 return build_ivar_reference (id);
8234 #include "gt-objc-objc-act.h"
8235 #include "gtype-objc.h"