1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GNU CC.
8 GNU CC 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 GNU CC 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 GNU CC; 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':
59 #include "diagnostic.h"
61 /* This is the default way of generating a method name. */
62 /* I am not sure it is really correct.
63 Perhaps there's a danger that it will make name conflicts
64 if method names contain underscores. -- rms. */
65 #ifndef OBJC_GEN_METHOD_LABEL
66 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
69 sprintf ((BUF), "_%s_%s_%s_%s", \
70 ((IS_INST) ? "i" : "c"), \
72 ((CAT_NAME)? (CAT_NAME) : ""), \
74 for (temp = (BUF); *temp; temp++) \
75 if (*temp == ':') *temp = '_'; \
79 /* These need specifying. */
80 #ifndef OBJC_FORWARDING_STACK_OFFSET
81 #define OBJC_FORWARDING_STACK_OFFSET 0
84 #ifndef OBJC_FORWARDING_MIN_OFFSET
85 #define OBJC_FORWARDING_MIN_OFFSET 0
89 /* Set up for use of obstacks. */
93 /* This obstack is used to accumulate the encoding of a data type. */
94 static struct obstack util_obstack
;
95 /* This points to the beginning of obstack contents,
96 so we can free the whole contents. */
99 /* for encode_method_def */
102 /* The version identifies which language generation and runtime
103 the module (file) was compiled for, and is recorded in the
104 module descriptor. */
106 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
107 #define PROTOCOL_VERSION 2
109 /* (Decide if these can ever be validly changed.) */
110 #define OBJC_ENCODE_INLINE_DEFS 0
111 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
113 /*** Private Interface (procedures) ***/
115 /* Used by compile_file. */
117 static void init_objc
PARAMS ((void));
118 static void finish_objc
PARAMS ((void));
120 /* Code generation. */
122 static void synth_module_prologue
PARAMS ((void));
123 static tree build_constructor
PARAMS ((tree
, tree
));
124 static rtx build_module_descriptor
PARAMS ((void));
125 static tree init_module_descriptor
PARAMS ((tree
));
126 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
128 static void generate_strings
PARAMS ((void));
129 static tree get_proto_encoding
PARAMS ((tree
));
130 static void build_selector_translation_table
PARAMS ((void));
132 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
134 static tree build_ivar_template
PARAMS ((void));
135 static tree build_method_template
PARAMS ((void));
136 static tree build_private_template
PARAMS ((tree
));
137 static void build_class_template
PARAMS ((void));
138 static void build_selector_template
PARAMS ((void));
139 static void build_category_template
PARAMS ((void));
140 static tree build_super_template
PARAMS ((void));
141 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
143 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
146 static void synth_forward_declarations
PARAMS ((void));
147 static void generate_ivar_lists
PARAMS ((void));
148 static void generate_dispatch_tables
PARAMS ((void));
149 static void generate_shared_structures
PARAMS ((void));
150 static tree generate_protocol_list
PARAMS ((tree
));
151 static void generate_forward_declaration_to_string_table
PARAMS ((void));
152 static void build_protocol_reference
PARAMS ((tree
));
154 static tree build_keyword_selector
PARAMS ((tree
));
155 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
157 static void generate_static_references
PARAMS ((void));
158 static int check_methods_accessible
PARAMS ((tree
, tree
,
160 static void encode_aggregate_within
PARAMS ((tree
, int, int,
162 static const char *objc_demangle
PARAMS ((const char *));
163 static void objc_expand_function_end
PARAMS ((void));
165 /* Hash tables to manage the global pool of method prototypes. */
167 hash
*nst_method_hash_list
= 0;
168 hash
*cls_method_hash_list
= 0;
170 static size_t hash_func
PARAMS ((tree
));
171 static void hash_init
PARAMS ((void));
172 static void hash_enter
PARAMS ((hash
*, tree
));
173 static hash hash_lookup
PARAMS ((hash
*, tree
));
174 static void hash_add_attr
PARAMS ((hash
, tree
));
175 static tree lookup_method
PARAMS ((tree
, tree
));
176 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
177 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
178 static tree add_class
PARAMS ((tree
));
179 static void add_category
PARAMS ((tree
, tree
));
183 class_names
, /* class, category, protocol, module names */
184 meth_var_names
, /* method and variable names */
185 meth_var_types
/* method and variable type descriptors */
188 static tree add_objc_string
PARAMS ((tree
,
189 enum string_section
));
190 static tree get_objc_string_decl
PARAMS ((tree
,
191 enum string_section
));
192 static tree build_objc_string_decl
PARAMS ((enum string_section
));
193 static tree build_selector_reference_decl
PARAMS ((void));
195 /* Protocol additions. */
197 static tree add_protocol
PARAMS ((tree
));
198 static tree lookup_protocol
PARAMS ((tree
));
199 static void check_protocol_recursively
PARAMS ((tree
, tree
));
200 static tree lookup_and_install_protocols
PARAMS ((tree
));
204 static void encode_type_qualifiers
PARAMS ((tree
));
205 static void encode_pointer
PARAMS ((tree
, int, int));
206 static void encode_array
PARAMS ((tree
, int, int));
207 static void encode_aggregate
PARAMS ((tree
, int, int));
208 static void encode_bitfield
PARAMS ((int));
209 static void encode_type
PARAMS ((tree
, int, int));
210 static void encode_field_decl
PARAMS ((tree
, int, int));
212 static void really_start_method
PARAMS ((tree
, tree
));
213 static int comp_method_with_proto
PARAMS ((tree
, tree
));
214 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
215 static tree get_arg_type_list
PARAMS ((tree
, int, int));
216 static tree expr_last
PARAMS ((tree
));
218 /* Utilities for debugging and error diagnostics. */
220 static void warn_with_method
PARAMS ((const char *, int, tree
));
221 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
222 static char *gen_method_decl
PARAMS ((tree
, char *));
223 static char *gen_declaration
PARAMS ((tree
, char *));
224 static void gen_declaration_1
PARAMS ((tree
, char *));
225 static char *gen_declarator
PARAMS ((tree
, char *,
227 static int is_complex_decl
PARAMS ((tree
));
228 static void adorn_decl
PARAMS ((tree
, char *));
229 static void dump_interface
PARAMS ((FILE *, tree
));
231 /* Everything else. */
233 static tree define_decl
PARAMS ((tree
, tree
));
234 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
235 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
236 static tree create_builtin_decl
PARAMS ((enum tree_code
,
237 tree
, const char *));
238 static void setup_string_decl
PARAMS ((void));
239 static void build_string_class_template
PARAMS ((void));
240 static tree my_build_string
PARAMS ((int, const char *));
241 static void build_objc_symtab_template
PARAMS ((void));
242 static tree init_def_list
PARAMS ((tree
));
243 static tree init_objc_symtab
PARAMS ((tree
));
244 static void forward_declare_categories
PARAMS ((void));
245 static void generate_objc_symtab_decl
PARAMS ((void));
246 static tree build_selector
PARAMS ((tree
));
247 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
248 static tree build_selector_reference
PARAMS ((tree
));
249 static tree build_class_reference_decl
PARAMS ((void));
250 static void add_class_reference
PARAMS ((tree
));
251 static tree build_protocol_template
PARAMS ((void));
252 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
253 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
254 static tree build_method_prototype_template
PARAMS ((void));
255 static int forwarding_offset
PARAMS ((tree
));
256 static tree encode_method_prototype
PARAMS ((tree
, tree
));
257 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
259 static void generate_method_descriptors
PARAMS ((tree
));
260 static tree build_tmp_function_decl
PARAMS ((void));
261 static void hack_method_prototype
PARAMS ((tree
, tree
));
262 static void generate_protocol_references
PARAMS ((tree
));
263 static void generate_protocols
PARAMS ((void));
264 static void check_ivars
PARAMS ((tree
, tree
));
265 static tree build_ivar_list_template
PARAMS ((tree
, int));
266 static tree build_method_list_template
PARAMS ((tree
, int));
267 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
268 static tree generate_ivars_list
PARAMS ((tree
, const char *,
270 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
271 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
273 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
274 tree
, int, tree
, tree
,
276 static void generate_category
PARAMS ((tree
));
277 static int is_objc_type_qualifier
PARAMS ((tree
));
278 static tree adjust_type_for_id_default
PARAMS ((tree
));
279 static tree check_duplicates
PARAMS ((hash
));
280 static tree receiver_is_class_object
PARAMS ((tree
));
281 static int check_methods
PARAMS ((tree
, tree
, int));
282 static int conforms_to_protocol
PARAMS ((tree
, tree
));
283 static void check_protocol
PARAMS ((tree
, const char *,
285 static void check_protocols
PARAMS ((tree
, const char *,
287 static tree encode_method_def
PARAMS ((tree
));
288 static void gen_declspecs
PARAMS ((tree
, char *, int));
289 static void generate_classref_translation_entry
PARAMS ((tree
));
290 static void handle_class_ref
PARAMS ((tree
));
291 static void generate_struct_by_value_array
PARAMS ((void))
293 static void encode_complete_bitfield
PARAMS ((int, tree
, int));
295 /*** Private Interface (data) ***/
297 /* Reserved tag definitions. */
300 #define TAG_OBJECT "objc_object"
301 #define TAG_CLASS "objc_class"
302 #define TAG_SUPER "objc_super"
303 #define TAG_SELECTOR "objc_selector"
305 #define UTAG_CLASS "_objc_class"
306 #define UTAG_IVAR "_objc_ivar"
307 #define UTAG_IVAR_LIST "_objc_ivar_list"
308 #define UTAG_METHOD "_objc_method"
309 #define UTAG_METHOD_LIST "_objc_method_list"
310 #define UTAG_CATEGORY "_objc_category"
311 #define UTAG_MODULE "_objc_module"
312 #define UTAG_SYMTAB "_objc_symtab"
313 #define UTAG_SUPER "_objc_super"
314 #define UTAG_SELECTOR "_objc_selector"
316 #define UTAG_PROTOCOL "_objc_protocol"
317 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
318 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
320 /* Note that the string object global name is only needed for the
322 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
324 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
326 static const char *TAG_GETCLASS
;
327 static const char *TAG_GETMETACLASS
;
328 static const char *TAG_MSGSEND
;
329 static const char *TAG_MSGSENDSUPER
;
330 static const char *TAG_EXECCLASS
;
331 static const char *default_constant_string_class_name
;
333 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
334 tree objc_global_trees
[OCTI_MAX
];
336 static void handle_impent
PARAMS ((struct imp_entry
*));
338 struct imp_entry
*imp_list
= 0;
339 int imp_count
= 0; /* `@implementation' */
340 int cat_count
= 0; /* `@category' */
342 static int method_slot
= 0; /* Used by start_method_def, */
346 static char *errbuf
; /* Buffer for error diagnostics */
348 /* Data imported from tree.c. */
350 extern enum debug_info_type write_symbols
;
352 /* Data imported from toplev.c. */
354 extern const char *dump_base_name
;
356 static int flag_typed_selectors
;
358 FILE *gen_declaration_file
;
360 /* Tells "encode_pointer/encode_aggregate" whether we are generating
361 type descriptors for instance variables (as opposed to methods).
362 Type descriptors for instance variables contain more information
363 than methods (for static typing and embedded structures). */
365 static int generating_instance_variables
= 0;
367 /* Some platforms pass small structures through registers versus
368 through an invisible pointer. Determine at what size structure is
369 the transition point between the two possibilities. */
372 generate_struct_by_value_array ()
375 tree field_decl
, field_decl_chain
;
377 int aggregate_in_mem
[32];
380 /* Presumably no platform passes 32 byte structures in a register. */
381 for (i
= 1; i
< 32; i
++)
385 /* Create an unnamed struct that has `i' character components */
386 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
388 strcpy (buffer
, "c1");
389 field_decl
= create_builtin_decl (FIELD_DECL
,
392 field_decl_chain
= field_decl
;
394 for (j
= 1; j
< i
; j
++)
396 sprintf (buffer
, "c%d", j
+ 1);
397 field_decl
= create_builtin_decl (FIELD_DECL
,
400 chainon (field_decl_chain
, field_decl
);
402 finish_struct (type
, field_decl_chain
, NULL_TREE
);
404 aggregate_in_mem
[i
] = aggregate_value_p (type
);
405 if (!aggregate_in_mem
[i
])
409 /* We found some structures that are returned in registers instead of memory
410 so output the necessary data. */
413 for (i
= 31; i
>= 0; i
--)
414 if (!aggregate_in_mem
[i
])
416 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
418 /* The first member of the structure is always 0 because we don't handle
419 structures with 0 members */
420 printf ("static int struct_forward_array[] = {\n 0");
422 for (j
= 1; j
<= i
; j
++)
423 printf (", %d", aggregate_in_mem
[j
]);
432 const char *filename
;
434 filename
= c_objc_common_init (filename
);
435 if (filename
== NULL
)
438 /* Force the line number back to 0; check_newline will have
439 raised it to 1, which will make the builtin functions appear
440 not to be built in. */
443 /* If gen_declaration desired, open the output file. */
444 if (flag_gen_declaration
)
446 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
447 gen_declaration_file
= fopen (dumpname
, "w");
448 if (gen_declaration_file
== 0)
449 fatal_io_error ("can't open %s", dumpname
);
453 if (flag_next_runtime
)
455 TAG_GETCLASS
= "objc_getClass";
456 TAG_GETMETACLASS
= "objc_getMetaClass";
457 TAG_MSGSEND
= "objc_msgSend";
458 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
459 TAG_EXECCLASS
= "__objc_execClass";
460 default_constant_string_class_name
= "NSConstantString";
464 TAG_GETCLASS
= "objc_get_class";
465 TAG_GETMETACLASS
= "objc_get_meta_class";
466 TAG_MSGSEND
= "objc_msg_lookup";
467 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
468 TAG_EXECCLASS
= "__objc_exec_class";
469 default_constant_string_class_name
= "NXConstantString";
470 flag_typed_selectors
= 1;
473 objc_ellipsis_node
= make_node (ERROR_MARK
);
477 if (print_struct_values
)
478 generate_struct_by_value_array ();
486 c_objc_common_finish_file ();
488 /* Finalize Objective-C runtime data. No need to generate tables
489 and code if only checking syntax. */
490 if (!flag_syntax_only
)
493 if (gen_declaration_file
)
494 fclose (gen_declaration_file
);
498 define_decl (declarator
, declspecs
)
502 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
503 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
507 /* Return 1 if LHS and RHS are compatible types for assignment or
508 various other operations. Return 0 if they are incompatible, and
509 return -1 if we choose to not decide. When the operation is
510 REFLEXIVE, check for compatibility in either direction.
512 For statically typed objects, an assignment of the form `a' = `b'
516 `a' and `b' are the same class type, or
517 `a' and `b' are of class types A and B such that B is a descendant of A. */
520 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
528 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
530 p
= TREE_VALUE (rproto
);
532 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
534 if ((fnd
= lookup_method (class_meth
535 ? PROTOCOL_CLS_METHODS (p
)
536 : PROTOCOL_NST_METHODS (p
), sel_name
)))
538 else if (PROTOCOL_LIST (p
))
539 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
540 sel_name
, class_meth
);
544 ; /* An identifier...if we could not find a protocol. */
555 lookup_protocol_in_reflist (rproto_list
, lproto
)
561 /* Make sure the protocol is supported by the object on the rhs. */
562 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
565 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
567 p
= TREE_VALUE (rproto
);
569 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
574 else if (PROTOCOL_LIST (p
))
575 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
584 ; /* An identifier...if we could not find a protocol. */
590 /* Return 1 if LHS and RHS are compatible types for assignment or
591 various other operations. Return 0 if they are incompatible, and
592 return -1 if we choose to not decide (because the types are really
593 just C types, not ObjC specific ones). When the operation is
594 REFLEXIVE (typically comparisons), check for compatibility in
595 either direction; when it's not (typically assignments), don't.
597 This function is called in two cases: when both lhs and rhs are
598 pointers to records (in which case we check protocols too), and
599 when both lhs and rhs are records (in which case we check class
602 Warnings about classes/protocols not implementing a protocol are
603 emitted here (multiple of those warnings might be emitted for a
604 single line!); generic warnings about incompatible assignments and
605 lacks of casts in comparisons are/must be emitted by the caller if
610 objc_comptypes (lhs
, rhs
, reflexive
)
615 /* New clause for protocols. */
617 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
618 manage the ObjC ones, and leave the rest to the C code. */
619 if (TREE_CODE (lhs
) == POINTER_TYPE
620 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
621 && TREE_CODE (rhs
) == POINTER_TYPE
622 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
624 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
625 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
629 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
630 tree rproto
, rproto_list
;
633 /* <Protocol> = <Protocol> */
636 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
640 /* An assignment between objects of type 'id
641 <Protocol>'; make sure the protocol on the lhs is
642 supported by the object on the rhs. */
643 for (lproto
= lproto_list
; lproto
;
644 lproto
= TREE_CHAIN (lproto
))
646 p
= TREE_VALUE (lproto
);
647 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
651 ("object does not conform to the `%s' protocol",
652 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
658 /* Obscure case - a comparison between two objects
659 of type 'id <Protocol>'. Check that either the
660 protocol on the lhs is supported by the object on
661 the rhs, or viceversa. */
663 /* Check if the protocol on the lhs is supported by the
664 object on the rhs. */
665 for (lproto
= lproto_list
; lproto
;
666 lproto
= TREE_CHAIN (lproto
))
668 p
= TREE_VALUE (lproto
);
669 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
673 /* Check failed - check if the protocol on the rhs
674 is supported by the object on the lhs. */
675 for (rproto
= rproto_list
; rproto
;
676 rproto
= TREE_CHAIN (rproto
))
678 p
= TREE_VALUE (rproto
);
679 lproto
= lookup_protocol_in_reflist (lproto_list
,
684 /* This check failed too: incompatible */
694 /* <Protocol> = <class> * */
695 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
697 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
700 /* Make sure the protocol is supported by the object on
702 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
704 p
= TREE_VALUE (lproto
);
706 rinter
= lookup_interface (rname
);
708 while (rinter
&& !rproto
)
712 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
713 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
714 /* If the underlying ObjC class does not have
715 the protocol we're looking for, check for "one-off"
716 protocols (e.g., `NSObject<MyProt> *foo;') attached
720 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
721 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
724 /* Check for protocols adopted by categories. */
725 cat
= CLASS_CATEGORY_LIST (rinter
);
726 while (cat
&& !rproto
)
728 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
729 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
730 cat
= CLASS_CATEGORY_LIST (cat
);
733 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
737 warning ("class `%s' does not implement the `%s' protocol",
738 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
739 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
743 /* <Protocol> = id */
744 else if (TYPE_NAME (TREE_TYPE (rhs
)) == objc_object_id
)
748 /* <Protocol> = Class */
749 else if (TYPE_NAME (TREE_TYPE (rhs
)) == objc_class_id
)
753 /* <Protocol> = ?? : let comptypes decide. */
756 else if (rhs_is_proto
)
758 /* <class> * = <Protocol> */
759 if (TYPED_OBJECT (TREE_TYPE (lhs
)))
763 tree rname
= TYPE_NAME (TREE_TYPE (lhs
));
765 tree rproto
, rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
767 /* Make sure the protocol is supported by the object on
769 for (rproto
= rproto_list
; rproto
;
770 rproto
= TREE_CHAIN (rproto
))
772 tree p
= TREE_VALUE (rproto
);
774 rinter
= lookup_interface (rname
);
776 while (rinter
&& !lproto
)
780 tree lproto_list
= CLASS_PROTOCOL_LIST (rinter
);
781 lproto
= lookup_protocol_in_reflist (lproto_list
, p
);
782 /* If the underlying ObjC class does not
783 have the protocol we're looking for,
784 check for "one-off" protocols (e.g.,
785 `NSObject<MyProt> *foo;') attached to the
789 lproto_list
= TYPE_PROTOCOL_LIST
791 lproto
= lookup_protocol_in_reflist
795 /* Check for protocols adopted by categories. */
796 cat
= CLASS_CATEGORY_LIST (rinter
);
797 while (cat
&& !lproto
)
799 lproto_list
= CLASS_PROTOCOL_LIST (cat
);
800 lproto
= lookup_protocol_in_reflist (lproto_list
,
802 cat
= CLASS_CATEGORY_LIST (cat
);
805 rinter
= lookup_interface (CLASS_SUPER_NAME
810 warning ("class `%s' does not implement the `%s' protocol",
811 IDENTIFIER_POINTER (TYPE_NAME
813 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
820 /* id = <Protocol> */
821 else if (TYPE_NAME (TREE_TYPE (lhs
)) == objc_object_id
)
825 /* Class = <Protocol> */
826 else if (TYPE_NAME (TREE_TYPE (lhs
)) == objc_class_id
)
830 /* ??? = <Protocol> : let comptypes decide */
838 /* Attention: we shouldn't defer to comptypes here. One bad
839 side effect would be that we might loose the REFLEXIVE
842 lhs
= TREE_TYPE (lhs
);
843 rhs
= TREE_TYPE (rhs
);
847 if (TREE_CODE (lhs
) != RECORD_TYPE
|| TREE_CODE (rhs
) != RECORD_TYPE
)
849 /* Nothing to do with ObjC - let immediately comptypes take
850 responsibility for checking. */
854 /* `id' = `<class> *' `<class> *' = `id': always allow it.
856 'Object *o = [[Object alloc] init]; falls
857 in the case <class> * = `id'.
859 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
860 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
863 /* `id' = `Class', `Class' = `id' */
865 else if ((TYPE_NAME (lhs
) == objc_object_id
866 && TYPE_NAME (rhs
) == objc_class_id
)
867 || (TYPE_NAME (lhs
) == objc_class_id
868 && TYPE_NAME (rhs
) == objc_object_id
))
871 /* `<class> *' = `<class> *' */
873 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
875 tree lname
= TYPE_NAME (lhs
);
876 tree rname
= TYPE_NAME (rhs
);
882 /* If the left hand side is a super class of the right hand side,
884 for (inter
= lookup_interface (rname
); inter
;
885 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
886 if (lname
== CLASS_SUPER_NAME (inter
))
889 /* Allow the reverse when reflexive. */
891 for (inter
= lookup_interface (lname
); inter
;
892 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
893 if (rname
== CLASS_SUPER_NAME (inter
))
899 /* Not an ObjC type - let comptypes do the check. */
903 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
906 objc_check_decl (decl
)
909 tree type
= TREE_TYPE (decl
);
911 if (TREE_CODE (type
) == RECORD_TYPE
912 && TREE_STATIC_TEMPLATE (type
)
913 && type
!= constant_string_type
)
914 error_with_decl (decl
, "`%s' cannot be statically allocated");
917 /* Implement static typing. At this point, we know we have an interface. */
920 get_static_reference (interface
, protocols
)
924 tree type
= xref_tag (RECORD_TYPE
, interface
);
928 tree t
, m
= TYPE_MAIN_VARIANT (type
);
930 t
= copy_node (type
);
932 /* Add this type to the chain of variants of TYPE. */
933 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
934 TYPE_NEXT_VARIANT (m
) = t
;
936 /* Look up protocols and install in lang specific list. Note
937 that the protocol list can have a different lifetime than T! */
938 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
940 /* This forces a new pointer type to be created later
941 (in build_pointer_type)...so that the new template
942 we just created will actually be used...what a hack! */
943 if (TYPE_POINTER_TO (t
))
944 TYPE_POINTER_TO (t
) = NULL_TREE
;
953 get_object_reference (protocols
)
956 tree type_decl
= lookup_name (objc_id_id
);
959 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
961 type
= TREE_TYPE (type_decl
);
962 if (TYPE_MAIN_VARIANT (type
) != id_type
)
963 warning ("unexpected type for `id' (%s)",
964 gen_declaration (type
, errbuf
));
968 error ("undefined type `id', please import <objc/objc.h>");
969 return error_mark_node
;
972 /* This clause creates a new pointer type that is qualified with
973 the protocol specification...this info is used later to do more
974 elaborate type checking. */
978 tree t
, m
= TYPE_MAIN_VARIANT (type
);
980 t
= copy_node (type
);
982 /* Add this type to the chain of variants of TYPE. */
983 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
984 TYPE_NEXT_VARIANT (m
) = t
;
986 /* Look up protocols...and install in lang specific list */
987 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
989 /* This forces a new pointer type to be created later
990 (in build_pointer_type)...so that the new template
991 we just created will actually be used...what a hack! */
992 if (TYPE_POINTER_TO (t
))
993 TYPE_POINTER_TO (t
) = NULL_TREE
;
1000 /* Check for circular dependencies in protocols. The arguments are
1001 PROTO, the protocol to check, and LIST, a list of protocol it
1005 check_protocol_recursively (proto
, list
)
1011 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1013 tree pp
= TREE_VALUE (p
);
1015 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1016 pp
= lookup_protocol (pp
);
1019 fatal_error ("protocol `%s' has circular dependency",
1020 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1022 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1027 lookup_and_install_protocols (protocols
)
1032 tree return_value
= protocols
;
1034 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1036 tree ident
= TREE_VALUE (proto
);
1037 tree p
= lookup_protocol (ident
);
1041 error ("cannot find protocol declaration for `%s'",
1042 IDENTIFIER_POINTER (ident
));
1044 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1046 return_value
= TREE_CHAIN (proto
);
1050 /* Replace identifier with actual protocol node. */
1051 TREE_VALUE (proto
) = p
;
1056 return return_value
;
1059 /* Create and push a decl for a built-in external variable or field NAME.
1061 TYPE is its data type. */
1064 create_builtin_decl (code
, type
, name
)
1065 enum tree_code code
;
1069 tree decl
= build_decl (code
, get_identifier (name
), type
);
1071 if (code
== VAR_DECL
)
1073 TREE_STATIC (decl
) = 1;
1074 make_decl_rtl (decl
, 0);
1078 DECL_ARTIFICIAL (decl
) = 1;
1082 /* Find the decl for the constant string class. */
1085 setup_string_decl ()
1087 if (!string_class_decl
)
1089 if (!constant_string_global_id
)
1090 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
1091 string_class_decl
= lookup_name (constant_string_global_id
);
1095 /* Purpose: "play" parser, creating/installing representations
1096 of the declarations that are required by Objective-C.
1100 type_spec--------->sc_spec
1101 (tree_list) (tree_list)
1104 identifier_node identifier_node */
1107 synth_module_prologue ()
1112 /* Defined in `objc.h' */
1113 objc_object_id
= get_identifier (TAG_OBJECT
);
1115 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1117 id_type
= build_pointer_type (objc_object_reference
);
1119 objc_id_id
= get_identifier (TYPE_ID
);
1120 objc_class_id
= get_identifier (TAG_CLASS
);
1122 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1123 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1124 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1126 /* Declare type of selector-objects that represent an operation name. */
1128 /* `struct objc_selector *' */
1130 = build_pointer_type (xref_tag (RECORD_TYPE
,
1131 get_identifier (TAG_SELECTOR
)));
1133 /* Forward declare type, or else the prototype for msgSendSuper will
1136 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1137 get_identifier (TAG_SUPER
)));
1140 /* id objc_msgSend (id, SEL, ...); */
1143 = build_function_type (id_type
,
1144 tree_cons (NULL_TREE
, id_type
,
1145 tree_cons (NULL_TREE
, selector_type
,
1148 if (! flag_next_runtime
)
1150 umsg_decl
= build_decl (FUNCTION_DECL
,
1151 get_identifier (TAG_MSGSEND
), temp_type
);
1152 DECL_EXTERNAL (umsg_decl
) = 1;
1153 TREE_PUBLIC (umsg_decl
) = 1;
1154 DECL_INLINE (umsg_decl
) = 1;
1155 DECL_ARTIFICIAL (umsg_decl
) = 1;
1157 make_decl_rtl (umsg_decl
, NULL
);
1158 pushdecl (umsg_decl
);
1161 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
,
1164 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1167 = build_function_type (id_type
,
1168 tree_cons (NULL_TREE
, super_p
,
1169 tree_cons (NULL_TREE
, selector_type
,
1172 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1173 temp_type
, 0, NOT_BUILT_IN
,
1176 /* id objc_getClass (const char *); */
1178 temp_type
= build_function_type (id_type
,
1179 tree_cons (NULL_TREE
,
1180 const_string_type_node
,
1181 tree_cons (NULL_TREE
, void_type_node
,
1185 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
,
1188 /* id objc_getMetaClass (const char *); */
1190 objc_get_meta_class_decl
1191 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
,
1194 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1196 if (! flag_next_runtime
)
1198 if (flag_typed_selectors
)
1200 /* Suppress outputting debug symbols, because
1201 dbxout_init hasn'r been called yet. */
1202 enum debug_info_type save_write_symbols
= write_symbols
;
1203 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
1204 write_symbols
= NO_DEBUG
;
1205 debug_hooks
= &do_nothing_debug_hooks
;
1207 build_selector_template ();
1208 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1210 write_symbols
= save_write_symbols
;
1211 debug_hooks
= save_hooks
;
1214 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1216 layout_type (temp_type
);
1217 UOBJC_SELECTOR_TABLE_decl
1218 = create_builtin_decl (VAR_DECL
, temp_type
,
1219 "_OBJC_SELECTOR_TABLE");
1221 /* Avoid warning when not sending messages. */
1222 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1225 generate_forward_declaration_to_string_table ();
1227 /* Forward declare constant_string_id and constant_string_type. */
1228 if (!constant_string_class_name
)
1229 constant_string_class_name
= default_constant_string_class_name
;
1231 constant_string_id
= get_identifier (constant_string_class_name
);
1232 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1235 /* Predefine the following data type:
1237 struct STRING_OBJECT_CLASS_NAME
1241 unsigned int length;
1245 build_string_class_template ()
1247 tree field_decl
, field_decl_chain
;
1249 field_decl
= create_builtin_decl (FIELD_DECL
, id_type
, "isa");
1250 field_decl_chain
= field_decl
;
1252 field_decl
= create_builtin_decl (FIELD_DECL
,
1253 build_pointer_type (char_type_node
),
1255 chainon (field_decl_chain
, field_decl
);
1257 field_decl
= create_builtin_decl (FIELD_DECL
, unsigned_type_node
, "length");
1258 chainon (field_decl_chain
, field_decl
);
1260 finish_struct (constant_string_type
, field_decl_chain
, NULL_TREE
);
1263 /* Custom build_string which sets TREE_TYPE! */
1266 my_build_string (len
, str
)
1270 return fix_string_type (build_string (len
, str
));
1273 /* Given a chain of STRING_CST's, build a static instance of
1274 NXConstantString which points at the concatenation of those strings.
1275 We place the string object in the __string_objects section of the
1276 __OBJC segment. The Objective-C runtime will initialize the isa
1277 pointers of the string objects to point at the NXConstantString
1281 build_objc_string_object (strings
)
1284 tree string
, initlist
, constructor
;
1287 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1289 error ("cannot find interface declaration for `%s'",
1290 IDENTIFIER_POINTER (constant_string_id
));
1291 return error_mark_node
;
1294 add_class_reference (constant_string_id
);
1296 if (TREE_CHAIN (strings
))
1298 varray_type vstrings
;
1299 VARRAY_TREE_INIT (vstrings
, 32, "strings");
1301 for (; strings
; strings
= TREE_CHAIN (strings
))
1302 VARRAY_PUSH_TREE (vstrings
, strings
);
1304 string
= combine_strings (vstrings
);
1309 string
= fix_string_type (string
);
1311 TREE_SET_CODE (string
, STRING_CST
);
1312 length
= TREE_STRING_LENGTH (string
) - 1;
1314 /* We could not properly create NXConstantString in synth_module_prologue,
1315 because that's called before debugging is initialized. Do it now. */
1316 if (TYPE_FIELDS (constant_string_type
) == NULL_TREE
)
1317 build_string_class_template ();
1319 /* & ((NXConstantString) { NULL, string, length }) */
1321 if (flag_next_runtime
)
1323 /* For the NeXT runtime, we can generate a literal reference
1324 to the string class, don't need to run a constructor. */
1325 setup_string_decl ();
1326 if (string_class_decl
== NULL_TREE
)
1328 error ("cannot find reference tag for class `%s'",
1329 IDENTIFIER_POINTER (constant_string_id
));
1330 return error_mark_node
;
1332 initlist
= build_tree_list
1334 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1338 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1342 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1344 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1345 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1347 if (!flag_next_runtime
)
1350 = objc_add_static_instance (constructor
, constant_string_type
);
1353 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1356 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1359 objc_add_static_instance (constructor
, class_decl
)
1360 tree constructor
, class_decl
;
1362 static int num_static_inst
;
1366 /* Find the list of static instances for the CLASS_DECL. Create one if
1368 for (chain
= &objc_static_instances
;
1369 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1370 chain
= &TREE_CHAIN (*chain
));
1373 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1374 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1377 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1378 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1379 DECL_COMMON (decl
) = 1;
1380 TREE_STATIC (decl
) = 1;
1381 DECL_ARTIFICIAL (decl
) = 1;
1382 DECL_INITIAL (decl
) = constructor
;
1384 /* We may be writing something else just now.
1385 Postpone till end of input. */
1386 DECL_DEFER_OUTPUT (decl
) = 1;
1387 pushdecl_top_level (decl
);
1388 rest_of_decl_compilation (decl
, 0, 1, 0);
1390 /* Add the DECL to the head of this CLASS' list. */
1391 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1396 /* Build a static constant CONSTRUCTOR
1397 with type TYPE and elements ELTS. */
1400 build_constructor (type
, elts
)
1403 tree constructor
, f
, e
;
1405 /* ??? Most of the places that we build constructors, we don't fill in
1406 the type of integers properly. Convert them all en masse. */
1407 if (TREE_CODE (type
) == ARRAY_TYPE
)
1409 f
= TREE_TYPE (type
);
1410 if (TREE_CODE (f
) == POINTER_TYPE
|| TREE_CODE (f
) == INTEGER_TYPE
)
1411 for (e
= elts
; e
; e
= TREE_CHAIN (e
))
1412 TREE_VALUE (e
) = convert (f
, TREE_VALUE (e
));
1416 f
= TYPE_FIELDS (type
);
1417 for (e
= elts
; e
&& f
; e
= TREE_CHAIN (e
), f
= TREE_CHAIN (f
))
1418 if (TREE_CODE (TREE_TYPE (f
)) == POINTER_TYPE
1419 || TREE_CODE (TREE_TYPE (f
)) == INTEGER_TYPE
)
1420 TREE_VALUE (e
) = convert (TREE_TYPE (f
), TREE_VALUE (e
));
1423 constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1424 TREE_CONSTANT (constructor
) = 1;
1425 TREE_STATIC (constructor
) = 1;
1426 TREE_READONLY (constructor
) = 1;
1431 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1433 /* Predefine the following data type:
1441 void *defs[cls_def_cnt + cat_def_cnt];
1445 build_objc_symtab_template ()
1447 tree field_decl
, field_decl_chain
, index
;
1449 objc_symtab_template
1450 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1452 /* long sel_ref_cnt; */
1454 field_decl
= create_builtin_decl (FIELD_DECL
,
1455 long_integer_type_node
,
1457 field_decl_chain
= field_decl
;
1461 field_decl
= create_builtin_decl (FIELD_DECL
,
1462 build_pointer_type (selector_type
),
1464 chainon (field_decl_chain
, field_decl
);
1466 /* short cls_def_cnt; */
1468 field_decl
= create_builtin_decl (FIELD_DECL
,
1469 short_integer_type_node
,
1471 chainon (field_decl_chain
, field_decl
);
1473 /* short cat_def_cnt; */
1475 field_decl
= create_builtin_decl (FIELD_DECL
,
1476 short_integer_type_node
,
1478 chainon (field_decl_chain
, field_decl
);
1480 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1482 if (!flag_next_runtime
)
1483 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1485 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1486 imp_count
== 0 && cat_count
== 0
1488 field_decl
= create_builtin_decl (FIELD_DECL
,
1489 build_array_type (ptr_type_node
, index
),
1491 chainon (field_decl_chain
, field_decl
);
1493 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1496 /* Create the initial value for the `defs' field of _objc_symtab.
1497 This is a CONSTRUCTOR. */
1500 init_def_list (type
)
1503 tree expr
, initlist
= NULL_TREE
;
1504 struct imp_entry
*impent
;
1507 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1509 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1511 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1512 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1517 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1519 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1521 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1522 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1526 if (!flag_next_runtime
)
1528 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1531 if (static_instances_decl
)
1532 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1534 expr
= build_int_2 (0, 0);
1536 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1539 return build_constructor (type
, nreverse (initlist
));
1542 /* Construct the initial value for all of _objc_symtab. */
1545 init_objc_symtab (type
)
1550 /* sel_ref_cnt = { ..., 5, ... } */
1552 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1554 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1556 if (flag_next_runtime
|| ! sel_ref_chain
)
1557 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1559 initlist
= tree_cons (NULL_TREE
,
1560 build_unary_op (ADDR_EXPR
,
1561 UOBJC_SELECTOR_TABLE_decl
, 1),
1564 /* cls_def_cnt = { ..., 5, ... } */
1566 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1568 /* cat_def_cnt = { ..., 5, ... } */
1570 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1572 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1574 if (imp_count
|| cat_count
|| static_instances_decl
)
1577 tree field
= TYPE_FIELDS (type
);
1578 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1580 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1584 return build_constructor (type
, nreverse (initlist
));
1587 /* Push forward-declarations of all the categories so that
1588 init_def_list can use them in a CONSTRUCTOR. */
1591 forward_declare_categories ()
1593 struct imp_entry
*impent
;
1594 tree sav
= objc_implementation_context
;
1596 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1598 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1600 /* Set an invisible arg to synth_id_with_class_suffix. */
1601 objc_implementation_context
= impent
->imp_context
;
1603 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1604 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context
)));
1607 objc_implementation_context
= sav
;
1610 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1611 and initialized appropriately. */
1614 generate_objc_symtab_decl ()
1618 if (!objc_category_template
)
1619 build_category_template ();
1621 /* forward declare categories */
1623 forward_declare_categories ();
1625 if (!objc_symtab_template
)
1626 build_objc_symtab_template ();
1628 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1630 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1631 tree_cons (NULL_TREE
,
1632 objc_symtab_template
, sc_spec
),
1636 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1637 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1638 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1639 finish_decl (UOBJC_SYMBOLS_decl
,
1640 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1645 init_module_descriptor (type
)
1648 tree initlist
, expr
;
1650 /* version = { 1, ... } */
1652 expr
= build_int_2 (OBJC_VERSION
, 0);
1653 initlist
= build_tree_list (NULL_TREE
, expr
);
1655 /* size = { ..., sizeof (struct objc_module), ... } */
1657 expr
= size_in_bytes (objc_module_template
);
1658 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1660 /* name = { ..., "foo.m", ... } */
1662 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1663 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1665 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1667 if (UOBJC_SYMBOLS_decl
)
1668 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1670 expr
= build_int_2 (0, 0);
1671 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1673 return build_constructor (type
, nreverse (initlist
));
1676 /* Write out the data structures to describe Objective C classes defined.
1677 If appropriate, compile and output a setup function to initialize them.
1678 Return a symbol_ref to the function to call to initialize the Objective C
1679 data structures for this file (and perhaps for other files also).
1681 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1684 build_module_descriptor ()
1686 tree decl_specs
, field_decl
, field_decl_chain
;
1688 objc_module_template
1689 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1693 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1694 field_decl
= get_identifier ("version");
1696 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1697 field_decl_chain
= field_decl
;
1701 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1702 field_decl
= get_identifier ("size");
1704 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1705 chainon (field_decl_chain
, field_decl
);
1709 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1710 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1712 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1713 chainon (field_decl_chain
, field_decl
);
1715 /* struct objc_symtab *symtab; */
1717 decl_specs
= get_identifier (UTAG_SYMTAB
);
1718 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1719 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1721 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1722 chainon (field_decl_chain
, field_decl
);
1724 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1726 /* Create an instance of "objc_module". */
1728 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1729 build_tree_list (NULL_TREE
,
1730 ridpointers
[(int) RID_STATIC
]));
1732 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1733 decl_specs
, 1, NULL_TREE
);
1735 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1736 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1737 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1739 finish_decl (UOBJC_MODULES_decl
,
1740 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1743 /* Mark the decl to avoid "defined but not used" warning. */
1744 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1746 /* Generate a constructor call for the module descriptor.
1747 This code was generated by reading the grammar rules
1748 of c-parse.in; Therefore, it may not be the most efficient
1749 way of generating the requisite code. */
1751 if (flag_next_runtime
)
1755 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1756 tree init_function_name
, init_function_decl
;
1758 /* Declare void __objc_execClass (void *); */
1760 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1761 execclass_decl
= build_decl (FUNCTION_DECL
,
1762 get_identifier (TAG_EXECCLASS
),
1763 build_function_type (void_type_node
,
1764 tree_cons (NULL_TREE
, ptr_type_node
,
1765 void_list_node_1
)));
1766 DECL_EXTERNAL (execclass_decl
) = 1;
1767 DECL_ARTIFICIAL (execclass_decl
) = 1;
1768 TREE_PUBLIC (execclass_decl
) = 1;
1769 pushdecl (execclass_decl
);
1770 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1771 assemble_external (execclass_decl
);
1773 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1775 init_function_name
= get_file_function_name ('I');
1776 start_function (void_list_node_1
,
1777 build_nt (CALL_EXPR
, init_function_name
,
1778 tree_cons (NULL_TREE
, NULL_TREE
,
1782 store_parm_decls ();
1784 init_function_decl
= current_function_decl
;
1785 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1786 TREE_USED (init_function_decl
) = 1;
1787 /* Don't let this one be deferred. */
1788 DECL_INLINE (init_function_decl
) = 0;
1789 DECL_UNINLINABLE (init_function_decl
) = 1;
1790 current_function_cannot_inline
1791 = "static constructors and destructors cannot be inlined";
1794 = build_tree_list (NULL_TREE
,
1795 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1796 decelerator
= build_function_call (execclass_decl
, parms
);
1798 c_expand_expr_stmt (decelerator
);
1800 finish_function (0, 0);
1802 return XEXP (DECL_RTL (init_function_decl
), 0);
1806 /* extern const char _OBJC_STRINGS[]; */
1809 generate_forward_declaration_to_string_table ()
1811 tree sc_spec
, decl_specs
, expr_decl
;
1813 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1814 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1817 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1819 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1822 /* Return the DECL of the string IDENT in the SECTION. */
1825 get_objc_string_decl (ident
, section
)
1827 enum string_section section
;
1831 if (section
== class_names
)
1832 chain
= class_names_chain
;
1833 else if (section
== meth_var_names
)
1834 chain
= meth_var_names_chain
;
1835 else if (section
== meth_var_types
)
1836 chain
= meth_var_types_chain
;
1840 for (; chain
!= 0; chain
= TREE_CHAIN (chain
))
1841 if (TREE_VALUE (chain
) == ident
)
1842 return (TREE_PURPOSE (chain
));
1848 /* Output references to all statically allocated objects. Return the DECL
1849 for the array built. */
1852 generate_static_references ()
1854 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1855 tree class_name
, class, decl
, initlist
;
1856 tree cl_chain
, in_chain
, type
;
1857 int num_inst
, num_class
;
1860 if (flag_next_runtime
)
1863 for (cl_chain
= objc_static_instances
, num_class
= 0;
1864 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1866 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1867 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1869 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1870 ident
= get_identifier (buf
);
1872 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1873 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1874 build_tree_list (NULL_TREE
,
1875 ridpointers
[(int) RID_STATIC
]));
1876 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1877 DECL_CONTEXT (decl
) = 0;
1878 DECL_ARTIFICIAL (decl
) = 1;
1880 /* Output {class_name, ...}. */
1881 class = TREE_VALUE (cl_chain
);
1882 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1883 initlist
= build_tree_list (NULL_TREE
,
1884 build_unary_op (ADDR_EXPR
, class_name
, 1));
1886 /* Output {..., instance, ...}. */
1887 for (in_chain
= TREE_PURPOSE (cl_chain
);
1888 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1890 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1891 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1894 /* Output {..., NULL}. */
1895 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1897 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1898 finish_decl (decl
, expr
, NULL_TREE
);
1899 TREE_USED (decl
) = 1;
1901 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1902 decl
= build_decl (VAR_DECL
, ident
, type
);
1903 TREE_USED (decl
) = 1;
1904 TREE_STATIC (decl
) = 1;
1906 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1909 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1910 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1911 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1912 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1913 build_tree_list (NULL_TREE
,
1914 ridpointers
[(int) RID_STATIC
]));
1915 static_instances_decl
1916 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1917 TREE_USED (static_instances_decl
) = 1;
1918 DECL_CONTEXT (static_instances_decl
) = 0;
1919 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1920 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1922 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1925 /* Output all strings. */
1930 tree sc_spec
, decl_specs
, expr_decl
;
1931 tree chain
, string_expr
;
1934 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1936 string
= TREE_VALUE (chain
);
1937 decl
= TREE_PURPOSE (chain
);
1939 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1940 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1941 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1942 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1943 DECL_CONTEXT (decl
) = NULL_TREE
;
1944 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1945 IDENTIFIER_POINTER (string
));
1946 finish_decl (decl
, string_expr
, NULL_TREE
);
1949 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1951 string
= TREE_VALUE (chain
);
1952 decl
= TREE_PURPOSE (chain
);
1954 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1955 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1956 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1957 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1958 DECL_CONTEXT (decl
) = NULL_TREE
;
1959 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1960 IDENTIFIER_POINTER (string
));
1961 finish_decl (decl
, string_expr
, NULL_TREE
);
1964 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1966 string
= TREE_VALUE (chain
);
1967 decl
= TREE_PURPOSE (chain
);
1969 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1970 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1971 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1972 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1973 DECL_CONTEXT (decl
) = NULL_TREE
;
1974 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1975 IDENTIFIER_POINTER (string
));
1976 finish_decl (decl
, string_expr
, NULL_TREE
);
1981 build_selector_reference_decl ()
1987 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1989 ident
= get_identifier (buf
);
1991 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1992 DECL_EXTERNAL (decl
) = 1;
1993 TREE_PUBLIC (decl
) = 1;
1994 TREE_USED (decl
) = 1;
1995 TREE_READONLY (decl
) = 1;
1996 DECL_ARTIFICIAL (decl
) = 1;
1997 DECL_CONTEXT (decl
) = 0;
1999 make_decl_rtl (decl
, 0);
2000 pushdecl_top_level (decl
);
2005 /* Just a handy wrapper for add_objc_string. */
2008 build_selector (ident
)
2011 tree expr
= add_objc_string (ident
, meth_var_names
);
2012 if (flag_typed_selectors
)
2015 return build_c_cast (selector_type
, expr
); /* cast! */
2019 build_selector_translation_table ()
2021 tree sc_spec
, decl_specs
;
2022 tree chain
, initlist
= NULL_TREE
;
2024 tree decl
= NULL_TREE
, var_decl
, name
;
2026 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2030 if (warn_selector
&& objc_implementation_context
)
2034 for (method_chain
= meth_var_names_chain
;
2036 method_chain
= TREE_CHAIN (method_chain
))
2038 if (TREE_VALUE (method_chain
) == TREE_VALUE (chain
))
2046 /* Adjust line number for warning message. */
2047 int save_lineno
= lineno
;
2048 if (flag_next_runtime
&& TREE_PURPOSE (chain
))
2049 lineno
= DECL_SOURCE_LINE (TREE_PURPOSE (chain
));
2050 warning ("creating selector for non existant method %s",
2051 IDENTIFIER_POINTER (TREE_VALUE (chain
)));
2052 lineno
= save_lineno
;
2056 expr
= build_selector (TREE_VALUE (chain
));
2058 if (flag_next_runtime
)
2060 name
= DECL_NAME (TREE_PURPOSE (chain
));
2062 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2064 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2065 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2069 /* The `decl' that is returned from start_decl is the one that we
2070 forward declared in `build_selector_reference' */
2071 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
2074 /* add one for the '\0' character */
2075 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2077 if (flag_next_runtime
)
2078 finish_decl (decl
, expr
, NULL_TREE
);
2081 if (flag_typed_selectors
)
2083 tree eltlist
= NULL_TREE
;
2084 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2085 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2086 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2087 expr
= build_constructor (objc_selector_template
,
2088 nreverse (eltlist
));
2090 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2095 if (! flag_next_runtime
)
2097 /* Cause the variable and its initial value to be actually output. */
2098 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2099 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2100 /* NULL terminate the list and fix the decl for output. */
2101 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2102 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2103 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2104 nreverse (initlist
));
2105 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2106 current_function_decl
= NULL_TREE
;
2111 get_proto_encoding (proto
)
2119 if (! METHOD_ENCODING (proto
))
2121 tmp_decl
= build_tmp_function_decl ();
2122 hack_method_prototype (proto
, tmp_decl
);
2123 encoding
= encode_method_prototype (proto
, tmp_decl
);
2124 METHOD_ENCODING (proto
) = encoding
;
2127 encoding
= METHOD_ENCODING (proto
);
2129 return add_objc_string (encoding
, meth_var_types
);
2132 return build_int_2 (0, 0);
2135 /* sel_ref_chain is a list whose "value" fields will be instances of
2136 identifier_node that represent the selector. */
2139 build_typed_selector_reference (ident
, prototype
)
2140 tree ident
, prototype
;
2142 tree
*chain
= &sel_ref_chain
;
2148 if (TREE_PURPOSE (*chain
) == prototype
&& TREE_VALUE (*chain
) == ident
)
2149 goto return_at_index
;
2152 chain
= &TREE_CHAIN (*chain
);
2155 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
2158 expr
= build_unary_op (ADDR_EXPR
,
2159 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2160 build_int_2 (index
, 0)),
2162 return build_c_cast (selector_type
, expr
);
2166 build_selector_reference (ident
)
2169 tree
*chain
= &sel_ref_chain
;
2175 if (TREE_VALUE (*chain
) == ident
)
2176 return (flag_next_runtime
2177 ? TREE_PURPOSE (*chain
)
2178 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2179 build_int_2 (index
, 0)));
2182 chain
= &TREE_CHAIN (*chain
);
2185 expr
= build_selector_reference_decl ();
2187 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2189 return (flag_next_runtime
2191 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2192 build_int_2 (index
, 0)));
2196 build_class_reference_decl ()
2202 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2204 ident
= get_identifier (buf
);
2206 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2207 DECL_EXTERNAL (decl
) = 1;
2208 TREE_PUBLIC (decl
) = 1;
2209 TREE_USED (decl
) = 1;
2210 TREE_READONLY (decl
) = 1;
2211 DECL_CONTEXT (decl
) = 0;
2212 DECL_ARTIFICIAL (decl
) = 1;
2214 make_decl_rtl (decl
, 0);
2215 pushdecl_top_level (decl
);
2220 /* Create a class reference, but don't create a variable to reference
2224 add_class_reference (ident
)
2229 if ((chain
= cls_ref_chain
))
2234 if (ident
== TREE_VALUE (chain
))
2238 chain
= TREE_CHAIN (chain
);
2242 /* Append to the end of the list */
2243 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2246 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2249 /* Get a class reference, creating it if necessary. Also create the
2250 reference variable. */
2253 get_class_reference (ident
)
2256 if (flag_next_runtime
)
2261 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2262 if (TREE_VALUE (*chain
) == ident
)
2264 if (! TREE_PURPOSE (*chain
))
2265 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2267 return TREE_PURPOSE (*chain
);
2270 decl
= build_class_reference_decl ();
2271 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2278 add_class_reference (ident
);
2280 params
= build_tree_list (NULL_TREE
,
2281 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2282 IDENTIFIER_POINTER (ident
)));
2284 assemble_external (objc_get_class_decl
);
2285 return build_function_call (objc_get_class_decl
, params
);
2289 /* For each string section we have a chain which maps identifier nodes
2290 to decls for the strings. */
2293 add_objc_string (ident
, section
)
2295 enum string_section section
;
2299 if (section
== class_names
)
2300 chain
= &class_names_chain
;
2301 else if (section
== meth_var_names
)
2302 chain
= &meth_var_names_chain
;
2303 else if (section
== meth_var_types
)
2304 chain
= &meth_var_types_chain
;
2310 if (TREE_VALUE (*chain
) == ident
)
2311 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2313 chain
= &TREE_CHAIN (*chain
);
2316 decl
= build_objc_string_decl (section
);
2318 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2320 return build_unary_op (ADDR_EXPR
, decl
, 1);
2324 build_objc_string_decl (section
)
2325 enum string_section section
;
2329 static int class_names_idx
= 0;
2330 static int meth_var_names_idx
= 0;
2331 static int meth_var_types_idx
= 0;
2333 if (section
== class_names
)
2334 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2335 else if (section
== meth_var_names
)
2336 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2337 else if (section
== meth_var_types
)
2338 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2340 ident
= get_identifier (buf
);
2342 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2343 DECL_EXTERNAL (decl
) = 1;
2344 TREE_PUBLIC (decl
) = 1;
2345 TREE_USED (decl
) = 1;
2346 TREE_READONLY (decl
) = 1;
2347 TREE_CONSTANT (decl
) = 1;
2348 DECL_CONTEXT (decl
) = 0;
2349 DECL_ARTIFICIAL (decl
) = 1;
2351 make_decl_rtl (decl
, 0);
2352 pushdecl_top_level (decl
);
2359 objc_declare_alias (alias_ident
, class_ident
)
2363 if (is_class_name (class_ident
) != class_ident
)
2364 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2365 else if (is_class_name (alias_ident
))
2366 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2368 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2372 objc_declare_class (ident_list
)
2377 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2379 tree ident
= TREE_VALUE (list
);
2382 if ((decl
= lookup_name (ident
)))
2384 error ("`%s' redeclared as different kind of symbol",
2385 IDENTIFIER_POINTER (ident
));
2386 error_with_decl (decl
, "previous declaration of `%s'");
2389 if (! is_class_name (ident
))
2391 tree record
= xref_tag (RECORD_TYPE
, ident
);
2392 TREE_STATIC_TEMPLATE (record
) = 1;
2393 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2399 is_class_name (ident
)
2404 if (lookup_interface (ident
))
2407 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2409 if (ident
== TREE_VALUE (chain
))
2413 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2415 if (ident
== TREE_VALUE (chain
))
2416 return TREE_PURPOSE (chain
);
2426 /* NB: This function may be called before the ObjC front-end
2427 has been initialized, in which case ID_TYPE will be NULL. */
2428 return (id_type
&& ident
&& TYPE_P (ident
) && IS_ID (ident
))
2434 lookup_interface (ident
)
2439 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2441 if (ident
== CLASS_NAME (chain
))
2447 /* Used by: build_private_template, continue_class,
2448 and for @defs constructs. */
2451 get_class_ivars (interface
)
2454 tree my_name
, super_name
, ivar_chain
;
2456 my_name
= CLASS_NAME (interface
);
2457 super_name
= CLASS_SUPER_NAME (interface
);
2458 ivar_chain
= CLASS_IVARS (interface
);
2460 /* Save off a pristine copy of the leaf ivars (i.e, those not
2461 inherited from a super class). */
2462 if (!CLASS_OWN_IVARS (interface
))
2463 CLASS_OWN_IVARS (interface
) = copy_list (ivar_chain
);
2468 tree super_interface
= lookup_interface (super_name
);
2470 if (!super_interface
)
2472 /* fatal did not work with 2 args...should fix */
2473 error ("cannot find interface declaration for `%s', superclass of `%s'",
2474 IDENTIFIER_POINTER (super_name
),
2475 IDENTIFIER_POINTER (my_name
));
2476 exit (FATAL_EXIT_CODE
);
2479 if (super_interface
== interface
)
2480 fatal_error ("circular inheritance in interface declaration for `%s'",
2481 IDENTIFIER_POINTER (super_name
));
2483 interface
= super_interface
;
2484 my_name
= CLASS_NAME (interface
);
2485 super_name
= CLASS_SUPER_NAME (interface
);
2487 op1
= CLASS_OWN_IVARS (interface
);
2490 tree head
= copy_list (op1
);
2492 /* Prepend super class ivars...make a copy of the list, we
2493 do not want to alter the original. */
2494 chainon (head
, ivar_chain
);
2501 /* struct <classname> {
2502 struct objc_class *isa;
2507 build_private_template (class)
2512 if (CLASS_STATIC_TEMPLATE (class))
2514 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2515 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2519 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2521 ivar_context
= get_class_ivars (class);
2523 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2525 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2527 /* mark this record as class template - for class type checking */
2528 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2532 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2534 build1 (INDIRECT_REF
, NULL_TREE
,
2537 return ivar_context
;
2540 /* Begin code generation for protocols... */
2542 /* struct objc_protocol {
2543 char *protocol_name;
2544 struct objc_protocol **protocol_list;
2545 struct objc_method_desc *instance_methods;
2546 struct objc_method_desc *class_methods;
2550 build_protocol_template ()
2552 tree decl_specs
, field_decl
, field_decl_chain
;
2555 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2557 /* struct objc_class *isa; */
2559 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2560 get_identifier (UTAG_CLASS
)));
2561 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2563 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2564 field_decl_chain
= field_decl
;
2566 /* char *protocol_name; */
2568 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2570 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2572 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2573 chainon (field_decl_chain
, field_decl
);
2575 /* struct objc_protocol **protocol_list; */
2577 decl_specs
= build_tree_list (NULL_TREE
, template);
2579 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2580 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2582 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2583 chainon (field_decl_chain
, field_decl
);
2585 /* struct objc_method_list *instance_methods; */
2588 = build_tree_list (NULL_TREE
,
2589 xref_tag (RECORD_TYPE
,
2590 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2592 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2594 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2595 chainon (field_decl_chain
, field_decl
);
2597 /* struct objc_method_list *class_methods; */
2600 = build_tree_list (NULL_TREE
,
2601 xref_tag (RECORD_TYPE
,
2602 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2604 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2606 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2607 chainon (field_decl_chain
, field_decl
);
2609 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2613 build_descriptor_table_initializer (type
, entries
)
2617 tree initlist
= NULL_TREE
;
2621 tree eltlist
= NULL_TREE
;
2624 = tree_cons (NULL_TREE
,
2625 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2627 = tree_cons (NULL_TREE
,
2628 add_objc_string (METHOD_ENCODING (entries
),
2633 = tree_cons (NULL_TREE
,
2634 build_constructor (type
, nreverse (eltlist
)), initlist
);
2636 entries
= TREE_CHAIN (entries
);
2640 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2643 /* struct objc_method_prototype_list {
2645 struct objc_method_prototype {
2652 build_method_prototype_list_template (list_type
, size
)
2656 tree objc_ivar_list_record
;
2657 tree decl_specs
, field_decl
, field_decl_chain
;
2659 /* Generate an unnamed struct definition. */
2661 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2663 /* int method_count; */
2665 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2666 field_decl
= get_identifier ("method_count");
2669 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2670 field_decl_chain
= field_decl
;
2672 /* struct objc_method method_list[]; */
2674 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2675 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2676 build_int_2 (size
, 0));
2679 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2680 chainon (field_decl_chain
, field_decl
);
2682 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2684 return objc_ivar_list_record
;
2688 build_method_prototype_template ()
2691 tree decl_specs
, field_decl
, field_decl_chain
;
2694 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2696 /* struct objc_selector *_cmd; */
2697 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2698 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2699 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2702 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2703 field_decl_chain
= field_decl
;
2705 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2707 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2709 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2710 chainon (field_decl_chain
, field_decl
);
2712 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2714 return proto_record
;
2717 /* True if last call to forwarding_offset yielded a register offset. */
2718 static int offset_is_register
;
2721 forwarding_offset (parm
)
2724 int offset_in_bytes
;
2726 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2728 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2730 /* ??? Here we assume that the parm address is indexed
2731 off the frame pointer or arg pointer.
2732 If that is not true, we produce meaningless results,
2733 but do not crash. */
2734 if (GET_CODE (addr
) == PLUS
2735 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2736 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2738 offset_in_bytes
= 0;
2740 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2741 offset_is_register
= 0;
2743 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2745 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2746 offset_in_bytes
= apply_args_register_offset (regno
);
2747 offset_is_register
= 1;
2752 /* This is the case where the parm is passed as an int or double
2753 and it is converted to a char, short or float and stored back
2754 in the parmlist. In this case, describe the parm
2755 with the variable's declared type, and adjust the address
2756 if the least significant bytes (which we are using) are not
2758 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2759 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2760 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2762 return offset_in_bytes
;
2766 encode_method_prototype (method_decl
, func_decl
)
2773 HOST_WIDE_INT max_parm_end
= 0;
2777 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2778 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2781 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2782 obstack_object_size (&util_obstack
),
2783 OBJC_ENCODE_INLINE_DEFS
);
2786 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2787 parms
= TREE_CHAIN (parms
))
2789 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2790 + int_size_in_bytes (TREE_TYPE (parms
)));
2792 if (!offset_is_register
&& max_parm_end
< parm_end
)
2793 max_parm_end
= parm_end
;
2796 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2798 sprintf (buf
, "%d", stack_size
);
2799 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2801 user_args
= METHOD_SEL_ARGS (method_decl
);
2803 /* Argument types. */
2804 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2805 parms
= TREE_CHAIN (parms
), i
++)
2807 /* Process argument qualifiers for user supplied arguments. */
2810 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2811 user_args
= TREE_CHAIN (user_args
);
2815 encode_type (TREE_TYPE (parms
),
2816 obstack_object_size (&util_obstack
),
2817 OBJC_ENCODE_INLINE_DEFS
);
2819 /* Compute offset. */
2820 sprintf (buf
, "%d", forwarding_offset (parms
));
2822 /* Indicate register. */
2823 if (offset_is_register
)
2824 obstack_1grow (&util_obstack
, '+');
2826 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2829 obstack_1grow (&util_obstack
, '\0');
2830 result
= get_identifier (obstack_finish (&util_obstack
));
2831 obstack_free (&util_obstack
, util_firstobj
);
2836 generate_descriptor_table (type
, name
, size
, list
, proto
)
2843 tree sc_spec
, decl_specs
, decl
, initlist
;
2845 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2846 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2848 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2849 decl_specs
, 1, NULL_TREE
);
2850 DECL_CONTEXT (decl
) = NULL_TREE
;
2852 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2853 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2855 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2862 generate_method_descriptors (protocol
)
2865 tree initlist
, chain
, method_list_template
;
2866 tree cast
, variable_length_type
;
2869 if (!objc_method_prototype_template
)
2870 objc_method_prototype_template
= build_method_prototype_template ();
2872 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2873 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2875 variable_length_type
= groktypename (cast
);
2877 chain
= PROTOCOL_CLS_METHODS (protocol
);
2880 size
= list_length (chain
);
2882 method_list_template
2883 = build_method_prototype_list_template (objc_method_prototype_template
,
2887 = build_descriptor_table_initializer (objc_method_prototype_template
,
2890 UOBJC_CLASS_METHODS_decl
2891 = generate_descriptor_table (method_list_template
,
2892 "_OBJC_PROTOCOL_CLASS_METHODS",
2893 size
, initlist
, protocol
);
2894 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2897 UOBJC_CLASS_METHODS_decl
= 0;
2899 chain
= PROTOCOL_NST_METHODS (protocol
);
2902 size
= list_length (chain
);
2904 method_list_template
2905 = build_method_prototype_list_template (objc_method_prototype_template
,
2908 = build_descriptor_table_initializer (objc_method_prototype_template
,
2911 UOBJC_INSTANCE_METHODS_decl
2912 = generate_descriptor_table (method_list_template
,
2913 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2914 size
, initlist
, protocol
);
2915 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2918 UOBJC_INSTANCE_METHODS_decl
= 0;
2921 /* Generate a temporary FUNCTION_DECL node to be used in
2922 hack_method_prototype below. */
2925 build_tmp_function_decl ()
2927 tree decl_specs
, expr_decl
, parms
;
2931 /* struct objc_object *objc_xxx (id, SEL, ...); */
2933 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2934 push_parm_decl (build_tree_list
2935 (build_tree_list (decl_specs
,
2936 build1 (INDIRECT_REF
, NULL_TREE
,
2940 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2941 get_identifier (TAG_SELECTOR
)));
2942 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2944 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2946 parms
= get_parm_info (0);
2949 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2950 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2951 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2952 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
2954 return define_decl (expr_decl
, decl_specs
);
2957 /* Generate the prototypes for protocol methods. This is used to
2958 generate method encodings for these.
2960 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2961 a decl node to be used. This is also where the return value is
2965 hack_method_prototype (nst_methods
, tmp_decl
)
2972 /* Hack to avoid problem with static typing of self arg. */
2973 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2974 start_method_def (nst_methods
);
2975 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2977 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
2978 parms
= get_parm_info (0); /* we have a `, ...' */
2980 parms
= get_parm_info (1); /* place a `void_at_end' */
2982 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2984 /* Usually called from store_parm_decls -> init_function_start. */
2986 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2988 if (current_function_decl
)
2990 current_function_decl
= tmp_decl
;
2993 /* Code taken from start_function. */
2994 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2995 /* Promote the value to int before returning it. */
2996 if (TREE_CODE (restype
) == INTEGER_TYPE
2997 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
2998 restype
= integer_type_node
;
2999 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3002 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3003 DECL_CONTEXT (parm
) = tmp_decl
;
3005 init_function_start (tmp_decl
, "objc-act", 0);
3007 /* Typically called from expand_function_start for function definitions. */
3008 assign_parms (tmp_decl
);
3010 /* install return type */
3011 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3013 current_function_decl
= NULL
;
3017 generate_protocol_references (plist
)
3022 /* Forward declare protocols referenced. */
3023 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3025 tree proto
= TREE_VALUE (lproto
);
3027 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3028 && PROTOCOL_NAME (proto
))
3030 if (! PROTOCOL_FORWARD_DECL (proto
))
3031 build_protocol_reference (proto
);
3033 if (PROTOCOL_LIST (proto
))
3034 generate_protocol_references (PROTOCOL_LIST (proto
));
3039 /* For each protocol which was referenced either from a @protocol()
3040 expression, or because a class/category implements it (then a
3041 pointer to the protocol is stored in the struct describing the
3042 class/category), we create a statically allocated instance of the
3043 Protocol class. The code is written in such a way as to generate
3044 as few Protocol objects as possible; we generate a unique Protocol
3045 instance for each protocol, and we don't generate a Protocol
3046 instance if the protocol is never referenced (either from a
3047 @protocol() or from a class/category implementation). These
3048 statically allocated objects can be referred to via the static
3049 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3051 The statically allocated Protocol objects that we generate here
3052 need to be fixed up at runtime in order to be used: the 'isa'
3053 pointer of the objects need to be set up to point to the 'Protocol'
3054 class, as known at runtime.
3056 The NeXT runtime fixes up all protocols at program startup time,
3057 before main() is entered. It uses a low-level trick to look up all
3058 those symbols, then loops on them and fixes them up.
3060 The GNU runtime as well fixes up all protocols before user code
3061 from the module is executed; it requires pointers to those symbols
3062 to be put in the objc_symtab (which is then passed as argument to
3063 the function __objc_exec_class() which the compiler sets up to be
3064 executed automatically when the module is loaded); setup of those
3065 Protocol objects happen in two ways in the GNU runtime: all
3066 Protocol objects referred to by a class or category implementation
3067 are fixed up when the class/category is loaded; all Protocol
3068 objects referred to by a @protocol() expression are added by the
3069 compiler to the list of statically allocated instances to fixup
3070 (the same list holding the statically allocated constant string
3071 objects). Because, as explained above, the compiler generates as
3072 few Protocol objects as possible, some Protocol object might end up
3073 being referenced multiple times when compiled with the GNU runtime,
3074 and end up being fixed up multiple times at runtime inizialization.
3075 But that doesn't hurt, it's just a little inefficient. */
3077 generate_protocols ()
3079 tree p
, tmp_decl
, encoding
;
3080 tree sc_spec
, decl_specs
, decl
;
3081 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3084 tmp_decl
= build_tmp_function_decl ();
3086 if (! objc_protocol_template
)
3087 objc_protocol_template
= build_protocol_template ();
3089 /* If a protocol was directly referenced, pull in indirect references. */
3090 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3091 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3092 generate_protocol_references (PROTOCOL_LIST (p
));
3094 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3096 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3097 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3099 /* If protocol wasn't referenced, don't generate any code. */
3100 if (! PROTOCOL_FORWARD_DECL (p
))
3103 /* Make sure we link in the Protocol class. */
3104 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3108 if (! METHOD_ENCODING (nst_methods
))
3110 hack_method_prototype (nst_methods
, tmp_decl
);
3111 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3112 METHOD_ENCODING (nst_methods
) = encoding
;
3114 nst_methods
= TREE_CHAIN (nst_methods
);
3119 if (! METHOD_ENCODING (cls_methods
))
3121 hack_method_prototype (cls_methods
, tmp_decl
);
3122 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3123 METHOD_ENCODING (cls_methods
) = encoding
;
3126 cls_methods
= TREE_CHAIN (cls_methods
);
3128 generate_method_descriptors (p
);
3130 if (PROTOCOL_LIST (p
))
3131 refs_decl
= generate_protocol_list (p
);
3135 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3137 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3139 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3141 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3142 decl_specs
, 1, NULL_TREE
);
3144 DECL_CONTEXT (decl
) = NULL_TREE
;
3146 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3152 (build_tree_list (build_tree_list (NULL_TREE
,
3153 objc_protocol_template
),
3154 build1 (INDIRECT_REF
, NULL_TREE
,
3155 build1 (INDIRECT_REF
, NULL_TREE
,
3158 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3159 TREE_TYPE (refs_expr
) = cast_type2
;
3162 refs_expr
= build_int_2 (0, 0);
3164 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3165 by generate_method_descriptors, which is called above. */
3166 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3167 protocol_name_expr
, refs_expr
,
3168 UOBJC_INSTANCE_METHODS_decl
,
3169 UOBJC_CLASS_METHODS_decl
);
3170 finish_decl (decl
, initlist
, NULL_TREE
);
3172 /* Mark the decl as used to avoid "defined but not used" warning. */
3173 TREE_USED (decl
) = 1;
3178 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3179 instance_methods
, class_methods
)
3183 tree instance_methods
;
3186 tree initlist
= NULL_TREE
, expr
;
3189 cast_type
= groktypename
3191 (build_tree_list (NULL_TREE
,
3192 xref_tag (RECORD_TYPE
,
3193 get_identifier (UTAG_CLASS
))),
3194 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3196 /* Filling the "isa" in with one allows the runtime system to
3197 detect that the version change...should remove before final release. */
3199 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3200 TREE_TYPE (expr
) = cast_type
;
3201 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3202 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3203 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3205 if (!instance_methods
)
3206 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3209 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3210 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3214 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3217 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3218 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3221 return build_constructor (type
, nreverse (initlist
));
3224 /* struct objc_category {
3225 char *category_name;
3227 struct objc_method_list *instance_methods;
3228 struct objc_method_list *class_methods;
3229 struct objc_protocol_list *protocols;
3233 build_category_template ()
3235 tree decl_specs
, field_decl
, field_decl_chain
;
3237 objc_category_template
= start_struct (RECORD_TYPE
,
3238 get_identifier (UTAG_CATEGORY
));
3239 /* char *category_name; */
3241 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3243 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3245 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3246 field_decl_chain
= field_decl
;
3248 /* char *class_name; */
3250 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3251 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3253 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3254 chainon (field_decl_chain
, field_decl
);
3256 /* struct objc_method_list *instance_methods; */
3258 decl_specs
= build_tree_list (NULL_TREE
,
3259 xref_tag (RECORD_TYPE
,
3260 get_identifier (UTAG_METHOD_LIST
)));
3262 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3264 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3265 chainon (field_decl_chain
, field_decl
);
3267 /* struct objc_method_list *class_methods; */
3269 decl_specs
= build_tree_list (NULL_TREE
,
3270 xref_tag (RECORD_TYPE
,
3271 get_identifier (UTAG_METHOD_LIST
)));
3273 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3275 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3276 chainon (field_decl_chain
, field_decl
);
3278 /* struct objc_protocol **protocol_list; */
3280 decl_specs
= build_tree_list (NULL_TREE
,
3281 xref_tag (RECORD_TYPE
,
3282 get_identifier (UTAG_PROTOCOL
)));
3284 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3285 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3287 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3288 chainon (field_decl_chain
, field_decl
);
3290 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3293 /* struct objc_selector {
3299 build_selector_template ()
3302 tree decl_specs
, field_decl
, field_decl_chain
;
3304 objc_selector_template
3305 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3309 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3310 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3312 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3313 field_decl_chain
= field_decl
;
3315 /* char *sel_type; */
3317 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3318 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3320 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3321 chainon (field_decl_chain
, field_decl
);
3323 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3326 /* struct objc_class {
3327 struct objc_class *isa;
3328 struct objc_class *super_class;
3333 struct objc_ivar_list *ivars;
3334 struct objc_method_list *methods;
3335 if (flag_next_runtime)
3336 struct objc_cache *cache;
3338 struct sarray *dtable;
3339 struct objc_class *subclass_list;
3340 struct objc_class *sibling_class;
3342 struct objc_protocol_list *protocols;
3343 void *gc_object_type;
3347 build_class_template ()
3349 tree decl_specs
, field_decl
, field_decl_chain
;
3352 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3354 /* struct objc_class *isa; */
3356 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3357 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3359 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3360 field_decl_chain
= field_decl
;
3362 /* struct objc_class *super_class; */
3364 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3366 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3368 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3369 chainon (field_decl_chain
, field_decl
);
3373 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3374 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3376 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3377 chainon (field_decl_chain
, field_decl
);
3381 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3382 field_decl
= get_identifier ("version");
3384 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3385 chainon (field_decl_chain
, field_decl
);
3389 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3390 field_decl
= get_identifier ("info");
3392 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3393 chainon (field_decl_chain
, field_decl
);
3395 /* long instance_size; */
3397 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3398 field_decl
= get_identifier ("instance_size");
3400 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3401 chainon (field_decl_chain
, field_decl
);
3403 /* struct objc_ivar_list *ivars; */
3405 decl_specs
= build_tree_list (NULL_TREE
,
3406 xref_tag (RECORD_TYPE
,
3407 get_identifier (UTAG_IVAR_LIST
)));
3408 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3410 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3411 chainon (field_decl_chain
, field_decl
);
3413 /* struct objc_method_list *methods; */
3415 decl_specs
= build_tree_list (NULL_TREE
,
3416 xref_tag (RECORD_TYPE
,
3417 get_identifier (UTAG_METHOD_LIST
)));
3418 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3420 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3421 chainon (field_decl_chain
, field_decl
);
3423 if (flag_next_runtime
)
3425 /* struct objc_cache *cache; */
3427 decl_specs
= build_tree_list (NULL_TREE
,
3428 xref_tag (RECORD_TYPE
,
3429 get_identifier ("objc_cache")));
3430 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3431 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3432 decl_specs
, NULL_TREE
);
3433 chainon (field_decl_chain
, field_decl
);
3437 /* struct sarray *dtable; */
3439 decl_specs
= build_tree_list (NULL_TREE
,
3440 xref_tag (RECORD_TYPE
,
3441 get_identifier ("sarray")));
3442 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3443 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3444 decl_specs
, NULL_TREE
);
3445 chainon (field_decl_chain
, field_decl
);
3447 /* struct objc_class *subclass_list; */
3449 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3451 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3452 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3453 decl_specs
, NULL_TREE
);
3454 chainon (field_decl_chain
, field_decl
);
3456 /* struct objc_class *sibling_class; */
3458 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3460 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3461 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3462 decl_specs
, NULL_TREE
);
3463 chainon (field_decl_chain
, field_decl
);
3466 /* struct objc_protocol **protocol_list; */
3468 decl_specs
= build_tree_list (NULL_TREE
,
3469 xref_tag (RECORD_TYPE
,
3470 get_identifier (UTAG_PROTOCOL
)));
3472 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3474 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3475 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3476 decl_specs
, NULL_TREE
);
3477 chainon (field_decl_chain
, field_decl
);
3481 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3482 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3484 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3485 chainon (field_decl_chain
, field_decl
);
3487 /* void *gc_object_type; */
3489 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3490 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3492 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3493 chainon (field_decl_chain
, field_decl
);
3495 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3498 /* Generate appropriate forward declarations for an implementation. */
3501 synth_forward_declarations ()
3503 tree sc_spec
, decl_specs
, an_id
;
3505 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3507 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context
);
3509 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3510 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3511 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3512 TREE_USED (UOBJC_CLASS_decl
) = 1;
3513 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3515 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3517 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3518 objc_implementation_context
);
3520 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3521 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3522 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3524 /* Pre-build the following entities - for speed/convenience. */
3526 an_id
= get_identifier ("super_class");
3527 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3528 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3532 error_with_ivar (message
, decl
, rawdecl
)
3533 const char *message
;
3537 diagnostic_count_diagnostic (global_dc
, DK_ERROR
);
3539 diagnostic_report_current_function (global_dc
);
3541 error_with_file_and_line (DECL_SOURCE_FILE (decl
),
3542 DECL_SOURCE_LINE (decl
),
3544 message
, gen_declaration (rawdecl
, errbuf
));
3549 check_ivars (inter
, imp
)
3553 tree intdecls
= CLASS_IVARS (inter
);
3554 tree impdecls
= CLASS_IVARS (imp
);
3555 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3556 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3562 if (intdecls
== 0 && impdecls
== 0)
3564 if (intdecls
== 0 || impdecls
== 0)
3566 error ("inconsistent instance variable specification");
3570 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3572 if (!comptypes (t1
, t2
))
3574 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3576 error_with_ivar ("conflicting instance variable type",
3577 impdecls
, rawimpdecls
);
3578 error_with_ivar ("previous declaration of",
3579 intdecls
, rawintdecls
);
3581 else /* both the type and the name don't match */
3583 error ("inconsistent instance variable specification");
3588 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3590 error_with_ivar ("conflicting instance variable name",
3591 impdecls
, rawimpdecls
);
3592 error_with_ivar ("previous declaration of",
3593 intdecls
, rawintdecls
);
3596 intdecls
= TREE_CHAIN (intdecls
);
3597 impdecls
= TREE_CHAIN (impdecls
);
3598 rawintdecls
= TREE_CHAIN (rawintdecls
);
3599 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3603 /* Set super_type to the data type node for struct objc_super *,
3604 first defining struct objc_super itself.
3605 This needs to be done just once per compilation. */
3608 build_super_template ()
3610 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3612 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3614 /* struct objc_object *self; */
3616 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3617 field_decl
= get_identifier ("self");
3618 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3619 field_decl
= grokfield (input_filename
, lineno
,
3620 field_decl
, decl_specs
, NULL_TREE
);
3621 field_decl_chain
= field_decl
;
3623 /* struct objc_class *class; */
3625 decl_specs
= get_identifier (UTAG_CLASS
);
3626 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3627 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3629 field_decl
= grokfield (input_filename
, lineno
,
3630 field_decl
, decl_specs
, NULL_TREE
);
3631 chainon (field_decl_chain
, field_decl
);
3633 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3635 /* `struct objc_super *' */
3636 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3638 build1 (INDIRECT_REF
,
3639 NULL_TREE
, NULL_TREE
)));
3643 /* struct objc_ivar {
3650 build_ivar_template ()
3652 tree objc_ivar_id
, objc_ivar_record
;
3653 tree decl_specs
, field_decl
, field_decl_chain
;
3655 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3656 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3658 /* char *ivar_name; */
3660 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3661 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3663 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3664 decl_specs
, NULL_TREE
);
3665 field_decl_chain
= field_decl
;
3667 /* char *ivar_type; */
3669 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3670 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3672 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3673 decl_specs
, NULL_TREE
);
3674 chainon (field_decl_chain
, field_decl
);
3676 /* int ivar_offset; */
3678 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3679 field_decl
= get_identifier ("ivar_offset");
3681 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3682 decl_specs
, NULL_TREE
);
3683 chainon (field_decl_chain
, field_decl
);
3685 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3687 return objc_ivar_record
;
3692 struct objc_ivar ivar_list[ivar_count];
3696 build_ivar_list_template (list_type
, size
)
3700 tree objc_ivar_list_record
;
3701 tree decl_specs
, field_decl
, field_decl_chain
;
3703 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3705 /* int ivar_count; */
3707 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3708 field_decl
= get_identifier ("ivar_count");
3710 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3711 decl_specs
, NULL_TREE
);
3712 field_decl_chain
= field_decl
;
3714 /* struct objc_ivar ivar_list[]; */
3716 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3717 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3718 build_int_2 (size
, 0));
3720 field_decl
= grokfield (input_filename
, lineno
,
3721 field_decl
, decl_specs
, NULL_TREE
);
3722 chainon (field_decl_chain
, field_decl
);
3724 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3726 return objc_ivar_list_record
;
3732 struct objc_method method_list[method_count];
3736 build_method_list_template (list_type
, size
)
3740 tree objc_ivar_list_record
;
3741 tree decl_specs
, field_decl
, field_decl_chain
;
3743 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3745 /* int method_next; */
3750 xref_tag (RECORD_TYPE
,
3751 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3753 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3754 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3755 decl_specs
, NULL_TREE
);
3756 field_decl_chain
= field_decl
;
3758 /* int method_count; */
3760 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3761 field_decl
= get_identifier ("method_count");
3763 field_decl
= grokfield (input_filename
, lineno
,
3764 field_decl
, decl_specs
, NULL_TREE
);
3765 chainon (field_decl_chain
, field_decl
);
3767 /* struct objc_method method_list[]; */
3769 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3770 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3771 build_int_2 (size
, 0));
3773 field_decl
= grokfield (input_filename
, lineno
,
3774 field_decl
, decl_specs
, NULL_TREE
);
3775 chainon (field_decl_chain
, field_decl
);
3777 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3779 return objc_ivar_list_record
;
3783 build_ivar_list_initializer (type
, field_decl
)
3787 tree initlist
= NULL_TREE
;
3791 tree ivar
= NULL_TREE
;
3794 if (DECL_NAME (field_decl
))
3795 ivar
= tree_cons (NULL_TREE
,
3796 add_objc_string (DECL_NAME (field_decl
),
3800 /* Unnamed bit-field ivar (yuck). */
3801 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3804 encode_field_decl (field_decl
,
3805 obstack_object_size (&util_obstack
),
3806 OBJC_ENCODE_DONT_INLINE_DEFS
);
3808 /* Null terminate string. */
3809 obstack_1grow (&util_obstack
, 0);
3813 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3816 obstack_free (&util_obstack
, util_firstobj
);
3819 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3820 initlist
= tree_cons (NULL_TREE
,
3821 build_constructor (type
, nreverse (ivar
)),
3824 field_decl
= TREE_CHAIN (field_decl
);
3828 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3832 generate_ivars_list (type
, name
, size
, list
)
3838 tree sc_spec
, decl_specs
, decl
, initlist
;
3840 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3841 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3843 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3844 decl_specs
, 1, NULL_TREE
);
3846 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3847 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3850 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3857 generate_ivar_lists ()
3859 tree initlist
, ivar_list_template
, chain
;
3860 tree cast
, variable_length_type
;
3863 generating_instance_variables
= 1;
3865 if (!objc_ivar_template
)
3866 objc_ivar_template
= build_ivar_template ();
3870 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3871 get_identifier (UTAG_IVAR_LIST
))),
3873 variable_length_type
= groktypename (cast
);
3875 /* Only generate class variables for the root of the inheritance
3876 hierarchy since these will be the same for every class. */
3878 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3879 && (chain
= TYPE_FIELDS (objc_class_template
)))
3881 size
= list_length (chain
);
3883 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3884 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3886 UOBJC_CLASS_VARIABLES_decl
3887 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3889 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3892 UOBJC_CLASS_VARIABLES_decl
= 0;
3894 chain
= CLASS_IVARS (implementation_template
);
3897 size
= list_length (chain
);
3898 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3899 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3901 UOBJC_INSTANCE_VARIABLES_decl
3902 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3904 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3907 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3909 generating_instance_variables
= 0;
3913 build_dispatch_table_initializer (type
, entries
)
3917 tree initlist
= NULL_TREE
;
3921 tree elemlist
= NULL_TREE
;
3923 elemlist
= tree_cons (NULL_TREE
,
3924 build_selector (METHOD_SEL_NAME (entries
)),
3927 /* Generate the method encoding if we don't have one already. */
3928 if (! METHOD_ENCODING (entries
))
3929 METHOD_ENCODING (entries
) =
3930 encode_method_def (METHOD_DEFINITION (entries
));
3932 elemlist
= tree_cons (NULL_TREE
,
3933 add_objc_string (METHOD_ENCODING (entries
),
3937 elemlist
= tree_cons (NULL_TREE
,
3938 build_unary_op (ADDR_EXPR
,
3939 METHOD_DEFINITION (entries
), 1),
3942 initlist
= tree_cons (NULL_TREE
,
3943 build_constructor (type
, nreverse (elemlist
)),
3946 entries
= TREE_CHAIN (entries
);
3950 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3953 /* To accomplish method prototyping without generating all kinds of
3954 inane warnings, the definition of the dispatch table entries were
3957 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3959 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3962 build_method_template ()
3965 tree decl_specs
, field_decl
, field_decl_chain
;
3967 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3969 /* struct objc_selector *_cmd; */
3970 decl_specs
= tree_cons (NULL_TREE
,
3971 xref_tag (RECORD_TYPE
,
3972 get_identifier (TAG_SELECTOR
)),
3974 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3976 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3977 decl_specs
, NULL_TREE
);
3978 field_decl_chain
= field_decl
;
3980 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3981 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3982 get_identifier ("method_types"));
3983 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3984 decl_specs
, NULL_TREE
);
3985 chainon (field_decl_chain
, field_decl
);
3989 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
3990 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
3991 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3992 decl_specs
, NULL_TREE
);
3993 chainon (field_decl_chain
, field_decl
);
3995 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4002 generate_dispatch_table (type
, name
, size
, list
)
4008 tree sc_spec
, decl_specs
, decl
, initlist
;
4010 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4011 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4013 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
4014 decl_specs
, 1, NULL_TREE
);
4016 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4017 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4018 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4021 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4028 generate_dispatch_tables ()
4030 tree initlist
, chain
, method_list_template
;
4031 tree cast
, variable_length_type
;
4034 if (!objc_method_template
)
4035 objc_method_template
= build_method_template ();
4039 (build_tree_list (NULL_TREE
,
4040 xref_tag (RECORD_TYPE
,
4041 get_identifier (UTAG_METHOD_LIST
))),
4044 variable_length_type
= groktypename (cast
);
4046 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
4049 size
= list_length (chain
);
4051 method_list_template
4052 = build_method_list_template (objc_method_template
, size
);
4054 = build_dispatch_table_initializer (objc_method_template
, chain
);
4056 UOBJC_CLASS_METHODS_decl
4057 = generate_dispatch_table (method_list_template
,
4058 ((TREE_CODE (objc_implementation_context
)
4059 == CLASS_IMPLEMENTATION_TYPE
)
4060 ? "_OBJC_CLASS_METHODS"
4061 : "_OBJC_CATEGORY_CLASS_METHODS"),
4063 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4066 UOBJC_CLASS_METHODS_decl
= 0;
4068 chain
= CLASS_NST_METHODS (objc_implementation_context
);
4071 size
= list_length (chain
);
4073 method_list_template
4074 = build_method_list_template (objc_method_template
, size
);
4076 = build_dispatch_table_initializer (objc_method_template
, chain
);
4078 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4079 UOBJC_INSTANCE_METHODS_decl
4080 = generate_dispatch_table (method_list_template
,
4081 "_OBJC_INSTANCE_METHODS",
4084 /* We have a category. */
4085 UOBJC_INSTANCE_METHODS_decl
4086 = generate_dispatch_table (method_list_template
,
4087 "_OBJC_CATEGORY_INSTANCE_METHODS",
4089 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4092 UOBJC_INSTANCE_METHODS_decl
= 0;
4096 generate_protocol_list (i_or_p
)
4099 tree initlist
, decl_specs
, sc_spec
;
4100 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4104 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4105 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4106 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4107 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4108 plist
= PROTOCOL_LIST (i_or_p
);
4112 cast_type
= groktypename
4114 (build_tree_list (NULL_TREE
,
4115 xref_tag (RECORD_TYPE
,
4116 get_identifier (UTAG_PROTOCOL
))),
4117 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4120 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4121 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4122 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4125 /* Build initializer. */
4126 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4128 e
= build_int_2 (size
, 0);
4129 TREE_TYPE (e
) = cast_type
;
4130 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4132 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4134 tree pval
= TREE_VALUE (lproto
);
4136 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4137 && PROTOCOL_FORWARD_DECL (pval
))
4139 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4140 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4144 /* static struct objc_protocol *refs[n]; */
4146 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4147 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4148 get_identifier (UTAG_PROTOCOL
)),
4151 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4152 expr_decl
= build_nt (ARRAY_REF
,
4153 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4155 build_int_2 (size
+ 2, 0));
4156 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4157 expr_decl
= build_nt (ARRAY_REF
,
4158 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4160 build_int_2 (size
+ 2, 0));
4161 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4163 = build_nt (ARRAY_REF
,
4164 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4166 build_int_2 (size
+ 2, 0));
4170 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4172 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4173 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4175 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4176 nreverse (initlist
)),
4183 build_category_initializer (type
, cat_name
, class_name
,
4184 instance_methods
, class_methods
, protocol_list
)
4188 tree instance_methods
;
4192 tree initlist
= NULL_TREE
, expr
;
4194 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4195 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4197 if (!instance_methods
)
4198 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4201 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4202 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4205 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4208 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4209 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4212 /* protocol_list = */
4214 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4217 tree cast_type2
= groktypename
4219 (build_tree_list (NULL_TREE
,
4220 xref_tag (RECORD_TYPE
,
4221 get_identifier (UTAG_PROTOCOL
))),
4222 build1 (INDIRECT_REF
, NULL_TREE
,
4223 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4225 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4226 TREE_TYPE (expr
) = cast_type2
;
4227 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4230 return build_constructor (type
, nreverse (initlist
));
4233 /* struct objc_class {
4234 struct objc_class *isa;
4235 struct objc_class *super_class;
4240 struct objc_ivar_list *ivars;
4241 struct objc_method_list *methods;
4242 if (flag_next_runtime)
4243 struct objc_cache *cache;
4245 struct sarray *dtable;
4246 struct objc_class *subclass_list;
4247 struct objc_class *sibling_class;
4249 struct objc_protocol_list *protocols;
4250 void *gc_object_type;
4254 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4255 dispatch_table
, ivar_list
, protocol_list
)
4262 tree dispatch_table
;
4266 tree initlist
= NULL_TREE
, expr
;
4269 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4272 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4275 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4278 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4281 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4283 /* instance_size = */
4284 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4286 /* objc_ivar_list = */
4288 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4291 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4292 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4295 /* objc_method_list = */
4296 if (!dispatch_table
)
4297 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4300 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4301 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4304 if (flag_next_runtime
)
4305 /* method_cache = */
4306 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4310 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4312 /* subclass_list = */
4313 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4315 /* sibling_class = */
4316 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4319 /* protocol_list = */
4320 if (! protocol_list
)
4321 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4327 (build_tree_list (NULL_TREE
,
4328 xref_tag (RECORD_TYPE
,
4329 get_identifier (UTAG_PROTOCOL
))),
4330 build1 (INDIRECT_REF
, NULL_TREE
,
4331 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4333 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4334 TREE_TYPE (expr
) = cast_type2
;
4335 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4338 /* gc_object_type = NULL */
4339 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4341 return build_constructor (type
, nreverse (initlist
));
4344 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4347 generate_category (cat
)
4350 tree sc_spec
, decl_specs
, decl
;
4351 tree initlist
, cat_name_expr
, class_name_expr
;
4352 tree protocol_decl
, category
;
4354 add_class_reference (CLASS_NAME (cat
));
4355 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4357 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4359 category
= CLASS_CATEGORY_LIST (implementation_template
);
4361 /* find the category interface from the class it is associated with */
4364 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4366 category
= CLASS_CATEGORY_LIST (category
);
4369 if (category
&& CLASS_PROTOCOL_LIST (category
))
4371 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4372 protocol_decl
= generate_protocol_list (category
);
4377 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4378 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4380 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4381 objc_implementation_context
),
4382 decl_specs
, 1, NULL_TREE
);
4384 initlist
= build_category_initializer (TREE_TYPE (decl
),
4385 cat_name_expr
, class_name_expr
,
4386 UOBJC_INSTANCE_METHODS_decl
,
4387 UOBJC_CLASS_METHODS_decl
,
4390 TREE_USED (decl
) = 1;
4391 finish_decl (decl
, initlist
, NULL_TREE
);
4394 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4395 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4398 generate_shared_structures ()
4400 tree sc_spec
, decl_specs
, decl
;
4401 tree name_expr
, super_expr
, root_expr
;
4402 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4403 tree cast_type
, initlist
, protocol_decl
;
4405 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4408 add_class_reference (my_super_id
);
4410 /* Compute "my_root_id" - this is required for code generation.
4411 the "isa" for all meta class structures points to the root of
4412 the inheritance hierarchy (e.g. "__Object")... */
4413 my_root_id
= my_super_id
;
4416 tree my_root_int
= lookup_interface (my_root_id
);
4418 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4419 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4426 /* No super class. */
4427 my_root_id
= CLASS_NAME (implementation_template
);
4430 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4431 objc_class_template
),
4432 build1 (INDIRECT_REF
,
4433 NULL_TREE
, NULL_TREE
)));
4435 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4438 /* Install class `isa' and `super' pointers at runtime. */
4441 super_expr
= add_objc_string (my_super_id
, class_names
);
4442 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4445 super_expr
= build_int_2 (0, 0);
4447 root_expr
= add_objc_string (my_root_id
, class_names
);
4448 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4450 if (CLASS_PROTOCOL_LIST (implementation_template
))
4452 generate_protocol_references
4453 (CLASS_PROTOCOL_LIST (implementation_template
));
4454 protocol_decl
= generate_protocol_list (implementation_template
);
4459 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4461 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4462 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4464 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4468 = build_shared_structure_initializer
4470 root_expr
, super_expr
, name_expr
,
4471 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4473 UOBJC_CLASS_METHODS_decl
,
4474 UOBJC_CLASS_VARIABLES_decl
,
4477 finish_decl (decl
, initlist
, NULL_TREE
);
4479 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4481 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4485 = build_shared_structure_initializer
4487 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4488 super_expr
, name_expr
,
4489 convert (integer_type_node
,
4490 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4491 (implementation_template
))),
4493 UOBJC_INSTANCE_METHODS_decl
,
4494 UOBJC_INSTANCE_VARIABLES_decl
,
4497 finish_decl (decl
, initlist
, NULL_TREE
);
4501 synth_id_with_class_suffix (preamble
, ctxt
)
4502 const char *preamble
;
4506 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4507 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4509 const char *const class_name
4510 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4511 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4512 sprintf (string
, "%s_%s", preamble
,
4513 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4515 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4516 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4518 /* We have a category. */
4519 const char *const class_name
4520 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4521 const char *const class_super_name
4522 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
4523 string
= (char *) alloca (strlen (preamble
)
4524 + strlen (class_name
)
4525 + strlen (class_super_name
)
4527 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4529 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4531 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4533 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4534 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4539 return get_identifier (string
);
4543 is_objc_type_qualifier (node
)
4546 return (TREE_CODE (node
) == IDENTIFIER_NODE
4547 && (node
== ridpointers
[(int) RID_CONST
]
4548 || node
== ridpointers
[(int) RID_VOLATILE
]
4549 || node
== ridpointers
[(int) RID_IN
]
4550 || node
== ridpointers
[(int) RID_OUT
]
4551 || node
== ridpointers
[(int) RID_INOUT
]
4552 || node
== ridpointers
[(int) RID_BYCOPY
]
4553 || node
== ridpointers
[(int) RID_BYREF
]
4554 || node
== ridpointers
[(int) RID_ONEWAY
]));
4557 /* If type is empty or only type qualifiers are present, add default
4558 type of id (otherwise grokdeclarator will default to int). */
4561 adjust_type_for_id_default (type
)
4564 tree declspecs
, chain
;
4567 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4568 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4570 declspecs
= TREE_PURPOSE (type
);
4572 /* Determine if a typespec is present. */
4573 for (chain
= declspecs
;
4575 chain
= TREE_CHAIN (chain
))
4577 if (TYPED_OBJECT (TREE_VALUE (chain
))
4578 && !(TREE_VALUE (type
)
4579 && TREE_CODE (TREE_VALUE (type
)) == INDIRECT_REF
))
4580 error ("can not use an object as parameter to a method\n");
4581 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4585 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4587 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4592 selector ':' '(' typename ')' identifier
4595 Transform an Objective-C keyword argument into
4596 the C equivalent parameter declarator.
4598 In: key_name, an "identifier_node" (optional).
4599 arg_type, a "tree_list" (optional).
4600 arg_name, an "identifier_node".
4602 Note: It would be really nice to strongly type the preceding
4603 arguments in the function prototype; however, then I
4604 could not use the "accessor" macros defined in "tree.h".
4606 Out: an instance of "keyword_decl". */
4609 build_keyword_decl (key_name
, arg_type
, arg_name
)
4616 /* If no type is specified, default to "id". */
4617 arg_type
= adjust_type_for_id_default (arg_type
);
4619 keyword_decl
= make_node (KEYWORD_DECL
);
4621 TREE_TYPE (keyword_decl
) = arg_type
;
4622 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4623 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4625 return keyword_decl
;
4628 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4631 build_keyword_selector (selector
)
4635 tree key_chain
, key_name
;
4638 /* Scan the selector to see how much space we'll need. */
4639 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4641 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4642 key_name
= KEYWORD_KEY_NAME (key_chain
);
4643 else if (TREE_CODE (selector
) == TREE_LIST
)
4644 key_name
= TREE_PURPOSE (key_chain
);
4649 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4651 /* Just a ':' arg. */
4655 buf
= (char *) alloca (len
+ 1);
4656 /* Start the buffer out as an empty string. */
4659 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4661 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4662 key_name
= KEYWORD_KEY_NAME (key_chain
);
4663 else if (TREE_CODE (selector
) == TREE_LIST
)
4664 key_name
= TREE_PURPOSE (key_chain
);
4669 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4673 return get_identifier (buf
);
4676 /* Used for declarations and definitions. */
4679 build_method_decl (code
, ret_type
, selector
, add_args
)
4680 enum tree_code code
;
4687 /* If no type is specified, default to "id". */
4688 ret_type
= adjust_type_for_id_default (ret_type
);
4690 method_decl
= make_node (code
);
4691 TREE_TYPE (method_decl
) = ret_type
;
4693 /* If we have a keyword selector, create an identifier_node that
4694 represents the full selector name (`:' included)... */
4695 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4697 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4698 METHOD_SEL_ARGS (method_decl
) = selector
;
4699 METHOD_ADD_ARGS (method_decl
) = add_args
;
4703 METHOD_SEL_NAME (method_decl
) = selector
;
4704 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4705 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4711 #define METHOD_DEF 0
4712 #define METHOD_REF 1
4714 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4715 an argument list for method METH. CONTEXT is either METHOD_DEF or
4716 METHOD_REF, saying whether we are trying to define a method or call
4717 one. SUPERFLAG says this is for a send to super; this makes a
4718 difference for the NeXT calling sequence in which the lookup and
4719 the method call are done together. */
4722 get_arg_type_list (meth
, context
, superflag
)
4729 /* Receiver type. */
4730 if (flag_next_runtime
&& superflag
)
4731 arglist
= build_tree_list (NULL_TREE
, super_type
);
4732 else if (context
== METHOD_DEF
)
4733 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4735 arglist
= build_tree_list (NULL_TREE
, id_type
);
4737 /* Selector type - will eventually change to `int'. */
4738 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4740 /* Build a list of argument types. */
4741 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4743 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4744 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4747 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4748 /* We have a `, ...' immediately following the selector,
4749 finalize the arglist...simulate get_parm_info (0). */
4751 else if (METHOD_ADD_ARGS (meth
))
4753 /* we have a variable length selector */
4754 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4755 chainon (arglist
, add_arg_list
);
4758 /* finalize the arglist...simulate get_parm_info (1) */
4759 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4765 check_duplicates (hsh
)
4768 tree meth
= NULL_TREE
;
4776 /* We have two methods with the same name and different types. */
4778 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4780 warning ("multiple declarations for method `%s'",
4781 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4783 warn_with_method ("using", type
, meth
);
4784 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4785 warn_with_method ("also found", type
, loop
->value
);
4791 /* If RECEIVER is a class reference, return the identifier node for
4792 the referenced class. RECEIVER is created by get_class_reference,
4793 so we check the exact form created depending on which runtimes are
4797 receiver_is_class_object (receiver
)
4800 tree chain
, exp
, arg
;
4802 /* The receiver is 'self' in the context of a class method. */
4803 if (objc_method_context
4804 && receiver
== self_decl
4805 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4807 return CLASS_NAME (objc_implementation_context
);
4810 if (flag_next_runtime
)
4812 /* The receiver is a variable created by
4813 build_class_reference_decl. */
4814 if (TREE_CODE (receiver
) == VAR_DECL
4815 && TREE_TYPE (receiver
) == objc_class_type
)
4816 /* Look up the identifier. */
4817 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4818 if (TREE_PURPOSE (chain
) == receiver
)
4819 return TREE_VALUE (chain
);
4823 /* The receiver is a function call that returns an id. Check if
4824 it is a call to objc_getClass, if so, pick up the class name. */
4825 if (TREE_CODE (receiver
) == CALL_EXPR
4826 && (exp
= TREE_OPERAND (receiver
, 0))
4827 && TREE_CODE (exp
) == ADDR_EXPR
4828 && (exp
= TREE_OPERAND (exp
, 0))
4829 && TREE_CODE (exp
) == FUNCTION_DECL
4830 && exp
== objc_get_class_decl
4831 /* We have a call to objc_getClass! */
4832 && (arg
= TREE_OPERAND (receiver
, 1))
4833 && TREE_CODE (arg
) == TREE_LIST
4834 && (arg
= TREE_VALUE (arg
)))
4837 if (TREE_CODE (arg
) == ADDR_EXPR
4838 && (arg
= TREE_OPERAND (arg
, 0))
4839 && TREE_CODE (arg
) == STRING_CST
)
4840 /* Finally, we have the class name. */
4841 return get_identifier (TREE_STRING_POINTER (arg
));
4847 /* If we are currently building a message expr, this holds
4848 the identifier of the selector of the message. This is
4849 used when printing warnings about argument mismatches. */
4851 static tree current_objc_message_selector
= 0;
4854 objc_message_selector ()
4856 return current_objc_message_selector
;
4859 /* Construct an expression for sending a message.
4860 MESS has the object to send to in TREE_PURPOSE
4861 and the argument list (including selector) in TREE_VALUE.
4863 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4864 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4867 build_message_expr (mess
)
4870 tree receiver
= TREE_PURPOSE (mess
);
4872 tree args
= TREE_VALUE (mess
);
4873 tree method_params
= NULL_TREE
;
4875 if (TREE_CODE (receiver
) == ERROR_MARK
)
4876 return error_mark_node
;
4878 /* Obtain the full selector name. */
4879 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4880 /* A unary selector. */
4882 else if (TREE_CODE (args
) == TREE_LIST
)
4883 sel_name
= build_keyword_selector (args
);
4887 /* Build the parameter list to give to the method. */
4888 if (TREE_CODE (args
) == TREE_LIST
)
4890 tree chain
= args
, prev
= NULL_TREE
;
4892 /* We have a keyword selector--check for comma expressions. */
4895 tree element
= TREE_VALUE (chain
);
4897 /* We have a comma expression, must collapse... */
4898 if (TREE_CODE (element
) == TREE_LIST
)
4901 TREE_CHAIN (prev
) = element
;
4906 chain
= TREE_CHAIN (chain
);
4908 method_params
= args
;
4911 return finish_message_expr (receiver
, sel_name
, method_params
);
4914 /* The 'finish_message_expr' routine is called from within
4915 'build_message_expr' for non-template functions. In the case of
4916 C++ template functions, it is called from 'build_expr_from_tree'
4917 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4920 finish_message_expr (receiver
, sel_name
, method_params
)
4921 tree receiver
, sel_name
, method_params
;
4923 tree method_prototype
= NULL_TREE
, class_ident
= NULL_TREE
;
4924 tree selector
, self_object
, retval
;
4925 int statically_typed
= 0, statically_allocated
= 0;
4927 /* Determine receiver type. */
4928 tree rtype
= TREE_TYPE (receiver
);
4929 int super
= IS_SUPER (rtype
);
4933 if (TREE_STATIC_TEMPLATE (rtype
))
4934 statically_allocated
= 1;
4935 else if (TREE_CODE (rtype
) == POINTER_TYPE
4936 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4937 statically_typed
= 1;
4938 else if ((flag_next_runtime
4940 && (class_ident
= receiver_is_class_object (receiver
)))
4942 else if (! IS_ID (rtype
)
4943 /* Allow any type that matches objc_class_type. */
4944 && ! comptypes (rtype
, objc_class_type
))
4946 warning ("invalid receiver type `%s'",
4947 gen_declaration (rtype
, errbuf
));
4949 if (statically_allocated
)
4950 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4952 /* Don't evaluate the receiver twice. */
4953 receiver
= save_expr (receiver
);
4954 self_object
= receiver
;
4957 /* If sending to `super', use current self as the object. */
4958 self_object
= self_decl
;
4960 /* Determine operation return type. */
4966 if (CLASS_SUPER_NAME (implementation_template
))
4969 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4971 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
4972 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4974 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4976 if (iface
&& !method_prototype
)
4977 warning ("`%s' does not respond to `%s'",
4978 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4979 IDENTIFIER_POINTER (sel_name
));
4983 error ("no super class declared in interface for `%s'",
4984 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4985 return error_mark_node
;
4989 else if (statically_allocated
)
4991 tree ctype
= TREE_TYPE (rtype
);
4992 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4995 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4997 if (! method_prototype
&& ctype
&& TYPE_PROTOCOL_LIST (ctype
))
4999 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5002 if (!method_prototype
)
5003 warning ("`%s' does not respond to `%s'",
5004 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5005 IDENTIFIER_POINTER (sel_name
));
5007 else if (statically_typed
)
5009 tree ctype
= TREE_TYPE (rtype
);
5011 /* `self' is now statically_typed. All methods should be visible
5012 within the context of the implementation. */
5013 if (objc_implementation_context
5014 && CLASS_NAME (objc_implementation_context
) == TYPE_NAME (ctype
))
5017 = lookup_instance_method_static (implementation_template
,
5020 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5022 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5025 if (! method_prototype
5026 && implementation_template
!= objc_implementation_context
)
5027 /* The method is not published in the interface. Check
5030 = lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
5037 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5038 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5040 if (! method_prototype
)
5042 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5045 = lookup_method_in_protocol_list (protocol_list
,
5050 if (!method_prototype
)
5051 warning ("`%s' does not respond to `%s'",
5052 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5053 IDENTIFIER_POINTER (sel_name
));
5055 else if (class_ident
)
5057 if (objc_implementation_context
5058 && CLASS_NAME (objc_implementation_context
) == class_ident
)
5061 = lookup_class_method_static (implementation_template
, sel_name
);
5063 if (!method_prototype
5064 && implementation_template
!= objc_implementation_context
)
5065 /* The method is not published in the interface. Check
5068 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context
),
5075 if ((iface
= lookup_interface (class_ident
)))
5076 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5079 if (!method_prototype
)
5081 warning ("cannot find class (factory) method");
5082 warning ("return type for `%s' defaults to id",
5083 IDENTIFIER_POINTER (sel_name
));
5086 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5088 /* An anonymous object that has been qualified with a protocol. */
5090 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5092 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5095 if (!method_prototype
)
5099 warning ("method `%s' not implemented by protocol",
5100 IDENTIFIER_POINTER (sel_name
));
5102 /* Try and find the method signature in the global pools. */
5104 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5105 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5107 if (!(method_prototype
= check_duplicates (hsh
)))
5108 warning ("return type defaults to id");
5115 /* We think we have an instance...loophole: extern id Object; */
5116 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5119 /* For various loopholes */
5120 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5122 method_prototype
= check_duplicates (hsh
);
5123 if (!method_prototype
)
5125 warning ("cannot find method");
5126 warning ("return type for `%s' defaults to id",
5127 IDENTIFIER_POINTER (sel_name
));
5131 /* Save the selector name for printing error messages. */
5132 current_objc_message_selector
= sel_name
;
5134 /* Build the parameters list for looking up the method.
5135 These are the object itself and the selector. */
5137 if (flag_typed_selectors
)
5138 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5140 selector
= build_selector_reference (sel_name
);
5142 retval
= build_objc_method_call (super
, method_prototype
,
5143 receiver
, self_object
,
5144 selector
, method_params
);
5146 current_objc_message_selector
= 0;
5151 /* Build a tree expression to send OBJECT the operation SELECTOR,
5152 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5153 assuming the method has prototype METHOD_PROTOTYPE.
5154 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5155 Use METHOD_PARAMS as list of args to pass to the method.
5156 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5159 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5160 selector
, method_params
)
5162 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5164 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5165 tree rcv_p
= (super_flag
5166 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5167 get_identifier (TAG_SUPER
)))
5170 if (flag_next_runtime
)
5172 if (! method_prototype
)
5174 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5175 tree_cons (NULL_TREE
, selector
,
5177 assemble_external (sender
);
5178 return build_function_call (sender
, method_params
);
5182 /* This is a real kludge, but it is used only for the Next.
5183 Clobber the data type of SENDER temporarily to accept
5184 all the arguments for this operation, and to return
5185 whatever this operation returns. */
5186 tree arglist
= NULL_TREE
, retval
, savarg
, savret
;
5187 tree ret_type
= groktypename (TREE_TYPE (method_prototype
));
5189 /* Save the proper contents of SENDER's data type. */
5190 savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5191 savret
= TREE_TYPE (TREE_TYPE (sender
));
5193 /* Install this method's argument types. */
5194 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5196 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5198 /* Install this method's return type. */
5199 TREE_TYPE (TREE_TYPE (sender
)) = ret_type
;
5201 /* Call SENDER with all the parameters. This will do type
5202 checking using the arg types for this method. */
5203 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5204 tree_cons (NULL_TREE
, selector
,
5206 assemble_external (sender
);
5207 retval
= build_function_call (sender
, method_params
);
5209 /* Restore SENDER's return/argument types. */
5210 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5211 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5217 /* This is the portable way.
5218 First call the lookup function to get a pointer to the method,
5219 then cast the pointer, then call it with the method arguments. */
5222 /* Avoid trouble since we may evaluate each of these twice. */
5223 object
= save_expr (object
);
5224 selector
= save_expr (selector
);
5226 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5228 assemble_external (sender
);
5230 = build_function_call (sender
,
5231 tree_cons (NULL_TREE
, lookup_object
,
5232 tree_cons (NULL_TREE
, selector
,
5235 /* If we have a method prototype, construct the data type this
5236 method needs, and cast what we got from SENDER into a pointer
5238 if (method_prototype
)
5240 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5242 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5243 tree fake_function_type
= build_function_type (valtype
, arglist
);
5244 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5248 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5250 /* Pass the object to the method. */
5251 assemble_external (method
);
5252 return build_function_call (method
,
5253 tree_cons (NULL_TREE
, object
,
5254 tree_cons (NULL_TREE
, selector
,
5260 build_protocol_reference (p
)
5263 tree decl
, ident
, ptype
;
5265 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5267 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5269 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5270 objc_protocol_template
),
5273 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5274 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5277 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5278 DECL_EXTERNAL (decl
) = 1;
5279 TREE_PUBLIC (decl
) = 1;
5280 TREE_USED (decl
) = 1;
5281 DECL_ARTIFICIAL (decl
) = 1;
5283 make_decl_rtl (decl
, 0);
5284 pushdecl_top_level (decl
);
5287 PROTOCOL_FORWARD_DECL (p
) = decl
;
5290 /* This function is called by the parser when (and only when) a
5291 @protocol() expression is found, in order to compile it. */
5293 build_protocol_expr (protoname
)
5297 tree p
= lookup_protocol (protoname
);
5301 error ("cannot find protocol declaration for `%s'",
5302 IDENTIFIER_POINTER (protoname
));
5303 return error_mark_node
;
5306 if (!PROTOCOL_FORWARD_DECL (p
))
5307 build_protocol_reference (p
);
5309 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5311 TREE_TYPE (expr
) = protocol_type
;
5313 /* The @protocol() expression is being compiled into a pointer to a
5314 statically allocated instance of the Protocol class. To become
5315 usable at runtime, the 'isa' pointer of the instance need to be
5316 fixed up at runtime by the runtime library, to point to the
5317 actual 'Protocol' class. */
5319 /* For the GNU runtime, put the static Protocol instance in the list
5320 of statically allocated instances, so that we make sure that its
5321 'isa' pointer is fixed up at runtime by the GNU runtime library
5322 to point to the Protocol class (at runtime, when loading the
5323 module, the GNU runtime library loops on the statically allocated
5324 instances (as found in the defs field in objc_symtab) and fixups
5325 all the 'isa' pointers of those objects). */
5326 if (! flag_next_runtime
)
5328 /* This type is a struct containing the fields of a Protocol
5329 object. (Cfr. protocol_type instead is the type of a pointer
5330 to such a struct). */
5331 tree protocol_struct_type
= xref_tag
5332 (RECORD_TYPE
, get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
5335 /* Look for the list of Protocol statically allocated instances
5336 to fixup at runtime. Create a new list to hold Protocol
5337 statically allocated instances, if the list is not found. At
5338 present there is only another list, holding NSConstantString
5339 static instances to be fixed up at runtime. */
5340 for (chain
= &objc_static_instances
;
5341 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
5342 chain
= &TREE_CHAIN (*chain
));
5345 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
5346 add_objc_string (TYPE_NAME (protocol_struct_type
),
5350 /* Add this statically allocated instance to the Protocol list. */
5351 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
5352 PROTOCOL_FORWARD_DECL (p
),
5353 TREE_PURPOSE (*chain
));
5360 /* This function is called by the parser when a @selector() expression
5361 is found, in order to compile it. It is only called by the parser
5362 and only to compile a @selector(). */
5364 build_selector_expr (selnamelist
)
5369 /* Obtain the full selector name. */
5370 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5371 /* A unary selector. */
5372 selname
= selnamelist
;
5373 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5374 selname
= build_keyword_selector (selnamelist
);
5378 /* If we are required to check @selector() expressions as they
5379 are found, check that the selector has been declared. */
5380 if (warn_undeclared_selector
)
5382 /* Look the selector up in the list of all known class and
5383 instance methods (up to this line) to check that the selector
5387 /* First try with instance methods. */
5388 hsh
= hash_lookup (nst_method_hash_list
, selname
);
5390 /* If not found, try with class methods. */
5393 hsh
= hash_lookup (cls_method_hash_list
, selname
);
5396 /* If still not found, print out a warning. */
5399 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname
));
5404 if (flag_typed_selectors
)
5405 return build_typed_selector_reference (selname
, 0);
5407 return build_selector_reference (selname
);
5411 build_encode_expr (type
)
5417 encode_type (type
, obstack_object_size (&util_obstack
),
5418 OBJC_ENCODE_INLINE_DEFS
);
5419 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5420 string
= obstack_finish (&util_obstack
);
5422 /* Synthesize a string that represents the encoded struct/union. */
5423 result
= my_build_string (strlen (string
) + 1, string
);
5424 obstack_free (&util_obstack
, util_firstobj
);
5429 build_ivar_reference (id
)
5432 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5434 /* Historically, a class method that produced objects (factory
5435 method) would assign `self' to the instance that it
5436 allocated. This would effectively turn the class method into
5437 an instance method. Following this assignment, the instance
5438 variables could be accessed. That practice, while safe,
5439 violates the simple rule that a class method should not refer
5440 to an instance variable. It's better to catch the cases
5441 where this is done unknowingly than to support the above
5443 warning ("instance variable `%s' accessed in class method",
5444 IDENTIFIER_POINTER (id
));
5445 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5448 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5451 /* Compute a hash value for a given method SEL_NAME. */
5454 hash_func (sel_name
)
5457 const unsigned char *s
5458 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
5462 h
= h
* 67 + *s
++ - 113;
5469 nst_method_hash_list
= (hash
*) ggc_calloc (SIZEHASHTABLE
, sizeof (hash
));
5470 cls_method_hash_list
= (hash
*) ggc_calloc (SIZEHASHTABLE
, sizeof (hash
));
5473 /* WARNING!!!! hash_enter is called with a method, and will peek
5474 inside to find its selector! But hash_lookup is given a selector
5475 directly, and looks for the selector that's inside the found
5476 entry's key (method) for comparison. */
5479 hash_enter (hashlist
, method
)
5484 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5486 obj
= (hash
) ggc_alloc (sizeof (struct hashed_entry
));
5488 obj
->next
= hashlist
[slot
];
5491 hashlist
[slot
] = obj
; /* append to front */
5495 hash_lookup (hashlist
, sel_name
)
5501 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
5505 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5508 target
= target
->next
;
5514 hash_add_attr (entry
, value
)
5520 obj
= (attr
) ggc_alloc (sizeof (struct hashed_attribute
));
5521 obj
->next
= entry
->list
;
5524 entry
->list
= obj
; /* append to front */
5528 lookup_method (mchain
, method
)
5534 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5537 key
= METHOD_SEL_NAME (method
);
5541 if (METHOD_SEL_NAME (mchain
) == key
)
5544 mchain
= TREE_CHAIN (mchain
);
5550 lookup_instance_method_static (interface
, ident
)
5554 tree inter
= interface
;
5555 tree chain
= CLASS_NST_METHODS (inter
);
5556 tree meth
= NULL_TREE
;
5560 if ((meth
= lookup_method (chain
, ident
)))
5563 if (CLASS_CATEGORY_LIST (inter
))
5565 tree category
= CLASS_CATEGORY_LIST (inter
);
5566 chain
= CLASS_NST_METHODS (category
);
5570 if ((meth
= lookup_method (chain
, ident
)))
5573 /* Check for instance methods in protocols in categories. */
5574 if (CLASS_PROTOCOL_LIST (category
))
5576 if ((meth
= (lookup_method_in_protocol_list
5577 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5581 if ((category
= CLASS_CATEGORY_LIST (category
)))
5582 chain
= CLASS_NST_METHODS (category
);
5587 if (CLASS_PROTOCOL_LIST (inter
))
5589 if ((meth
= (lookup_method_in_protocol_list
5590 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5594 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5595 chain
= CLASS_NST_METHODS (inter
);
5603 lookup_class_method_static (interface
, ident
)
5607 tree inter
= interface
;
5608 tree chain
= CLASS_CLS_METHODS (inter
);
5609 tree meth
= NULL_TREE
;
5610 tree root_inter
= NULL_TREE
;
5614 if ((meth
= lookup_method (chain
, ident
)))
5617 if (CLASS_CATEGORY_LIST (inter
))
5619 tree category
= CLASS_CATEGORY_LIST (inter
);
5620 chain
= CLASS_CLS_METHODS (category
);
5624 if ((meth
= lookup_method (chain
, ident
)))
5627 /* Check for class methods in protocols in categories. */
5628 if (CLASS_PROTOCOL_LIST (category
))
5630 if ((meth
= (lookup_method_in_protocol_list
5631 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5635 if ((category
= CLASS_CATEGORY_LIST (category
)))
5636 chain
= CLASS_CLS_METHODS (category
);
5641 /* Check for class methods in protocols. */
5642 if (CLASS_PROTOCOL_LIST (inter
))
5644 if ((meth
= (lookup_method_in_protocol_list
5645 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5650 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5651 chain
= CLASS_CLS_METHODS (inter
);
5655 /* If no class (factory) method was found, check if an _instance_
5656 method of the same name exists in the root class. This is what
5657 the Objective-C runtime will do. */
5658 return lookup_instance_method_static (root_inter
, ident
);
5662 add_class_method (class, method
)
5669 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5671 /* put method on list in reverse order */
5672 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5673 CLASS_CLS_METHODS (class) = method
;
5677 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5678 error ("duplicate definition of class method `%s'",
5679 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5682 /* Check types; if different, complain. */
5683 if (!comp_proto_with_proto (method
, mth
))
5684 error ("duplicate declaration of class method `%s'",
5685 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5689 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5691 /* Install on a global chain. */
5692 hash_enter (cls_method_hash_list
, method
);
5696 /* Check types; if different, add to a list. */
5697 if (!comp_proto_with_proto (method
, hsh
->key
))
5698 hash_add_attr (hsh
, method
);
5704 add_instance_method (class, method
)
5711 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5713 /* Put method on list in reverse order. */
5714 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5715 CLASS_NST_METHODS (class) = method
;
5719 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5720 error ("duplicate definition of instance method `%s'",
5721 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5724 /* Check types; if different, complain. */
5725 if (!comp_proto_with_proto (method
, mth
))
5726 error ("duplicate declaration of instance method `%s'",
5727 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5731 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5733 /* Install on a global chain. */
5734 hash_enter (nst_method_hash_list
, method
);
5738 /* Check types; if different, add to a list. */
5739 if (!comp_proto_with_proto (method
, hsh
->key
))
5740 hash_add_attr (hsh
, method
);
5749 /* Put interfaces on list in reverse order. */
5750 TREE_CHAIN (class) = interface_chain
;
5751 interface_chain
= class;
5752 return interface_chain
;
5756 add_category (class, category
)
5760 /* Put categories on list in reverse order. */
5761 tree cat
= CLASS_CATEGORY_LIST (class);
5765 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5766 warning ("duplicate interface declaration for category `%s(%s)'",
5767 IDENTIFIER_POINTER (CLASS_NAME (class)),
5768 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5769 cat
= CLASS_CATEGORY_LIST (cat
);
5772 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5773 CLASS_CATEGORY_LIST (class) = category
;
5776 /* Called after parsing each instance variable declaration. Necessary to
5777 preserve typedefs and implement public/private...
5779 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5782 add_instance_variable (class, public, declarator
, declspecs
, width
)
5789 tree field_decl
, raw_decl
;
5791 raw_decl
= build_tree_list (declspecs
, declarator
);
5793 if (CLASS_RAW_IVARS (class))
5794 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5796 CLASS_RAW_IVARS (class) = raw_decl
;
5798 field_decl
= grokfield (input_filename
, lineno
,
5799 declarator
, declspecs
, width
);
5801 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5805 TREE_PUBLIC (field_decl
) = 0;
5806 TREE_PRIVATE (field_decl
) = 0;
5807 TREE_PROTECTED (field_decl
) = 1;
5811 TREE_PUBLIC (field_decl
) = 1;
5812 TREE_PRIVATE (field_decl
) = 0;
5813 TREE_PROTECTED (field_decl
) = 0;
5817 TREE_PUBLIC (field_decl
) = 0;
5818 TREE_PRIVATE (field_decl
) = 1;
5819 TREE_PROTECTED (field_decl
) = 0;
5824 if (CLASS_IVARS (class))
5825 chainon (CLASS_IVARS (class), field_decl
);
5827 CLASS_IVARS (class) = field_decl
;
5833 is_ivar (decl_chain
, ident
)
5837 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5838 if (DECL_NAME (decl_chain
) == ident
)
5843 /* True if the ivar is private and we are not in its implementation. */
5849 if (TREE_PRIVATE (decl
)
5850 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5852 error ("instance variable `%s' is declared private",
5853 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5860 /* We have an instance variable reference;, check to see if it is public. */
5863 is_public (expr
, identifier
)
5867 tree basetype
= TREE_TYPE (expr
);
5868 enum tree_code code
= TREE_CODE (basetype
);
5871 if (code
== RECORD_TYPE
)
5873 if (TREE_STATIC_TEMPLATE (basetype
))
5875 if (!lookup_interface (TYPE_NAME (basetype
)))
5877 error ("cannot find interface declaration for `%s'",
5878 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5882 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5884 if (TREE_PUBLIC (decl
))
5887 /* Important difference between the Stepstone translator:
5888 all instance variables should be public within the context
5889 of the implementation. */
5890 if (objc_implementation_context
5891 && (((TREE_CODE (objc_implementation_context
)
5892 == CLASS_IMPLEMENTATION_TYPE
)
5893 || (TREE_CODE (objc_implementation_context
)
5894 == CATEGORY_IMPLEMENTATION_TYPE
))
5895 && (CLASS_NAME (objc_implementation_context
)
5896 == TYPE_NAME (basetype
))))
5897 return ! is_private (decl
);
5899 error ("instance variable `%s' is declared %s",
5900 IDENTIFIER_POINTER (identifier
),
5901 TREE_PRIVATE (decl
) ? "private" : "protected");
5906 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
5908 TREE_TYPE (expr
) = uprivate_record
;
5909 warning ("static access to object of type `id'");
5916 /* Make sure all entries in CHAIN are also in LIST. */
5919 check_methods (chain
, list
, mtype
)
5928 if (!lookup_method (list
, chain
))
5932 if (TREE_CODE (objc_implementation_context
)
5933 == CLASS_IMPLEMENTATION_TYPE
)
5934 warning ("incomplete implementation of class `%s'",
5935 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
5936 else if (TREE_CODE (objc_implementation_context
)
5937 == CATEGORY_IMPLEMENTATION_TYPE
)
5938 warning ("incomplete implementation of category `%s'",
5939 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
5943 warning ("method definition for `%c%s' not found",
5944 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5947 chain
= TREE_CHAIN (chain
);
5953 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5956 conforms_to_protocol (class, protocol
)
5960 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
5962 tree p
= CLASS_PROTOCOL_LIST (class);
5963 while (p
&& TREE_VALUE (p
) != protocol
)
5968 tree super
= (CLASS_SUPER_NAME (class)
5969 ? lookup_interface (CLASS_SUPER_NAME (class))
5971 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5980 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5981 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5984 check_methods_accessible (chain
, context
, mtype
)
5991 tree base_context
= context
;
5995 context
= base_context
;
5999 list
= CLASS_CLS_METHODS (context
);
6001 list
= CLASS_NST_METHODS (context
);
6003 if (lookup_method (list
, chain
))
6006 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
6007 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6008 context
= (CLASS_SUPER_NAME (context
)
6009 ? lookup_interface (CLASS_SUPER_NAME (context
))
6012 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6013 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6014 context
= (CLASS_NAME (context
)
6015 ? lookup_interface (CLASS_NAME (context
))
6021 if (context
== NULL_TREE
)
6025 if (TREE_CODE (objc_implementation_context
)
6026 == CLASS_IMPLEMENTATION_TYPE
)
6027 warning ("incomplete implementation of class `%s'",
6029 (CLASS_NAME (objc_implementation_context
)));
6030 else if (TREE_CODE (objc_implementation_context
)
6031 == CATEGORY_IMPLEMENTATION_TYPE
)
6032 warning ("incomplete implementation of category `%s'",
6034 (CLASS_SUPER_NAME (objc_implementation_context
)));
6037 warning ("method definition for `%c%s' not found",
6038 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6041 chain
= TREE_CHAIN (chain
); /* next method... */
6046 /* Check whether the current interface (accessible via
6047 'objc_implementation_context') actually implements protocol P, along
6048 with any protocols that P inherits. */
6051 check_protocol (p
, type
, name
)
6056 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6060 /* Ensure that all protocols have bodies! */
6063 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6064 CLASS_CLS_METHODS (objc_implementation_context
),
6066 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6067 CLASS_NST_METHODS (objc_implementation_context
),
6072 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6073 objc_implementation_context
,
6075 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6076 objc_implementation_context
,
6081 warning ("%s `%s' does not fully implement the `%s' protocol",
6082 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6085 /* Check protocols recursively. */
6086 if (PROTOCOL_LIST (p
))
6088 tree subs
= PROTOCOL_LIST (p
);
6090 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6094 tree sub
= TREE_VALUE (subs
);
6096 /* If the superclass does not conform to the protocols
6097 inherited by P, then we must! */
6098 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
6099 check_protocol (sub
, type
, name
);
6100 subs
= TREE_CHAIN (subs
);
6105 /* Check whether the current interface (accessible via
6106 'objc_implementation_context') actually implements the protocols listed
6110 check_protocols (proto_list
, type
, name
)
6115 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6117 tree p
= TREE_VALUE (proto_list
);
6119 check_protocol (p
, type
, name
);
6123 /* Make sure that the class CLASS_NAME is defined
6124 CODE says which kind of thing CLASS_NAME ought to be.
6125 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6126 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6129 start_class (code
, class_name
, super_name
, protocol_list
)
6130 enum tree_code code
;
6137 if (objc_implementation_context
)
6139 warning ("`@end' missing in implementation context");
6140 finish_class (objc_implementation_context
);
6141 objc_ivar_chain
= NULL_TREE
;
6142 objc_implementation_context
= NULL_TREE
;
6145 class = make_node (code
);
6146 TYPE_BINFO (class) = make_tree_vec (6);
6148 CLASS_NAME (class) = class_name
;
6149 CLASS_SUPER_NAME (class) = super_name
;
6150 CLASS_CLS_METHODS (class) = NULL_TREE
;
6152 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6154 error ("`%s' redeclared as different kind of symbol",
6155 IDENTIFIER_POINTER (class_name
));
6156 error_with_decl (decl
, "previous declaration of `%s'");
6159 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6164 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6165 if (TREE_VALUE (chain
) == class_name
)
6167 error ("reimplementation of class `%s'",
6168 IDENTIFIER_POINTER (class_name
));
6169 return error_mark_node
;
6171 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6172 implemented_classes
);
6175 /* Pre-build the following entities - for speed/convenience. */
6177 self_id
= get_identifier ("self");
6179 ucmd_id
= get_identifier ("_cmd");
6182 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6183 if (!objc_super_template
)
6184 objc_super_template
= build_super_template ();
6186 /* Reset for multiple classes per file. */
6189 objc_implementation_context
= class;
6191 /* Lookup the interface for this implementation. */
6193 if (!(implementation_template
= lookup_interface (class_name
)))
6195 warning ("cannot find interface declaration for `%s'",
6196 IDENTIFIER_POINTER (class_name
));
6197 add_class (implementation_template
= objc_implementation_context
);
6200 /* If a super class has been specified in the implementation,
6201 insure it conforms to the one specified in the interface. */
6204 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6206 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6207 const char *const name
=
6208 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6209 error ("conflicting super class name `%s'",
6210 IDENTIFIER_POINTER (super_name
));
6211 error ("previous declaration of `%s'", name
);
6214 else if (! super_name
)
6216 CLASS_SUPER_NAME (objc_implementation_context
)
6217 = CLASS_SUPER_NAME (implementation_template
);
6221 else if (code
== CLASS_INTERFACE_TYPE
)
6223 if (lookup_interface (class_name
))
6224 warning ("duplicate interface declaration for class `%s'",
6225 IDENTIFIER_POINTER (class_name
));
6230 CLASS_PROTOCOL_LIST (class)
6231 = lookup_and_install_protocols (protocol_list
);
6234 else if (code
== CATEGORY_INTERFACE_TYPE
)
6236 tree class_category_is_assoc_with
;
6238 /* For a category, class_name is really the name of the class that
6239 the following set of methods will be associated with. We must
6240 find the interface so that can derive the objects template. */
6242 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6244 error ("cannot find interface declaration for `%s'",
6245 IDENTIFIER_POINTER (class_name
));
6246 exit (FATAL_EXIT_CODE
);
6249 add_category (class_category_is_assoc_with
, class);
6252 CLASS_PROTOCOL_LIST (class)
6253 = lookup_and_install_protocols (protocol_list
);
6256 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6258 /* Pre-build the following entities for speed/convenience. */
6260 self_id
= get_identifier ("self");
6262 ucmd_id
= get_identifier ("_cmd");
6265 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6266 if (!objc_super_template
)
6267 objc_super_template
= build_super_template ();
6269 /* Reset for multiple classes per file. */
6272 objc_implementation_context
= class;
6274 /* For a category, class_name is really the name of the class that
6275 the following set of methods will be associated with. We must
6276 find the interface so that can derive the objects template. */
6278 if (!(implementation_template
= lookup_interface (class_name
)))
6280 error ("cannot find interface declaration for `%s'",
6281 IDENTIFIER_POINTER (class_name
));
6282 exit (FATAL_EXIT_CODE
);
6289 continue_class (class)
6292 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6293 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6295 struct imp_entry
*imp_entry
;
6298 /* Check consistency of the instance variables. */
6300 if (CLASS_IVARS (class))
6301 check_ivars (implementation_template
, class);
6303 /* code generation */
6305 ivar_context
= build_private_template (implementation_template
);
6307 if (!objc_class_template
)
6308 build_class_template ();
6310 imp_entry
= (struct imp_entry
*) ggc_alloc (sizeof (struct imp_entry
));
6312 imp_entry
->next
= imp_list
;
6313 imp_entry
->imp_context
= class;
6314 imp_entry
->imp_template
= implementation_template
;
6316 synth_forward_declarations ();
6317 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6318 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6320 /* Append to front and increment count. */
6321 imp_list
= imp_entry
;
6322 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6327 return ivar_context
;
6330 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6332 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6334 if (!TYPE_FIELDS (record
))
6336 finish_struct (record
, get_class_ivars (class), NULL_TREE
);
6337 CLASS_STATIC_TEMPLATE (class) = record
;
6339 /* Mark this record as a class template for static typing. */
6340 TREE_STATIC_TEMPLATE (record
) = 1;
6347 return error_mark_node
;
6350 /* This is called once we see the "@end" in an interface/implementation. */
6353 finish_class (class)
6356 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6358 /* All code generation is done in finish_objc. */
6360 if (implementation_template
!= objc_implementation_context
)
6362 /* Ensure that all method listed in the interface contain bodies. */
6363 check_methods (CLASS_CLS_METHODS (implementation_template
),
6364 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6365 check_methods (CLASS_NST_METHODS (implementation_template
),
6366 CLASS_NST_METHODS (objc_implementation_context
), '-');
6368 if (CLASS_PROTOCOL_LIST (implementation_template
))
6369 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6371 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6375 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6377 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6379 /* Find the category interface from the class it is associated with. */
6382 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6384 category
= CLASS_CATEGORY_LIST (category
);
6389 /* Ensure all method listed in the interface contain bodies. */
6390 check_methods (CLASS_CLS_METHODS (category
),
6391 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6392 check_methods (CLASS_NST_METHODS (category
),
6393 CLASS_NST_METHODS (objc_implementation_context
), '-');
6395 if (CLASS_PROTOCOL_LIST (category
))
6396 check_protocols (CLASS_PROTOCOL_LIST (category
),
6398 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6402 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6405 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6406 char *string
= (char *) alloca (strlen (class_name
) + 3);
6408 /* extern struct objc_object *_<my_name>; */
6410 sprintf (string
, "_%s", class_name
);
6412 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6413 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6414 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6420 add_protocol (protocol
)
6423 /* Put protocol on list in reverse order. */
6424 TREE_CHAIN (protocol
) = protocol_chain
;
6425 protocol_chain
= protocol
;
6426 return protocol_chain
;
6430 lookup_protocol (ident
)
6435 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6436 if (ident
== PROTOCOL_NAME (chain
))
6442 /* This function forward declares the protocols named by NAMES. If
6443 they are already declared or defined, the function has no effect. */
6446 objc_declare_protocols (names
)
6451 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6453 tree name
= TREE_VALUE (list
);
6455 if (lookup_protocol (name
) == NULL_TREE
)
6457 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6459 TYPE_BINFO (protocol
) = make_tree_vec (2);
6460 PROTOCOL_NAME (protocol
) = name
;
6461 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6462 add_protocol (protocol
);
6463 PROTOCOL_DEFINED (protocol
) = 0;
6464 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6470 start_protocol (code
, name
, list
)
6471 enum tree_code code
;
6477 /* This is as good a place as any. Need to invoke
6478 push_tag_toplevel. */
6479 if (!objc_protocol_template
)
6480 objc_protocol_template
= build_protocol_template ();
6482 protocol
= lookup_protocol (name
);
6486 protocol
= make_node (code
);
6487 TYPE_BINFO (protocol
) = make_tree_vec (2);
6489 PROTOCOL_NAME (protocol
) = name
;
6490 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6491 add_protocol (protocol
);
6492 PROTOCOL_DEFINED (protocol
) = 1;
6493 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6495 check_protocol_recursively (protocol
, list
);
6497 else if (! PROTOCOL_DEFINED (protocol
))
6499 PROTOCOL_DEFINED (protocol
) = 1;
6500 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6502 check_protocol_recursively (protocol
, list
);
6506 warning ("duplicate declaration for protocol `%s'",
6507 IDENTIFIER_POINTER (name
));
6513 finish_protocol (protocol
)
6514 tree protocol ATTRIBUTE_UNUSED
;
6519 /* "Encode" a data type into a string, which grows in util_obstack.
6520 ??? What is the FORMAT? Someone please document this! */
6523 encode_type_qualifiers (declspecs
)
6528 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6530 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6531 obstack_1grow (&util_obstack
, 'r');
6532 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6533 obstack_1grow (&util_obstack
, 'n');
6534 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6535 obstack_1grow (&util_obstack
, 'N');
6536 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6537 obstack_1grow (&util_obstack
, 'o');
6538 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6539 obstack_1grow (&util_obstack
, 'O');
6540 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6541 obstack_1grow (&util_obstack
, 'R');
6542 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6543 obstack_1grow (&util_obstack
, 'V');
6547 /* Encode a pointer type. */
6550 encode_pointer (type
, curtype
, format
)
6555 tree pointer_to
= TREE_TYPE (type
);
6557 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6559 if (TYPE_NAME (pointer_to
)
6560 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6562 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6564 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6566 obstack_1grow (&util_obstack
, '@');
6569 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6571 if (generating_instance_variables
)
6573 obstack_1grow (&util_obstack
, '@');
6574 obstack_1grow (&util_obstack
, '"');
6575 obstack_grow (&util_obstack
, name
, strlen (name
));
6576 obstack_1grow (&util_obstack
, '"');
6581 obstack_1grow (&util_obstack
, '@');
6585 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6587 obstack_1grow (&util_obstack
, '#');
6590 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6592 obstack_1grow (&util_obstack
, ':');
6597 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6598 && TYPE_MODE (pointer_to
) == QImode
)
6600 obstack_1grow (&util_obstack
, '*');
6604 /* We have a type that does not get special treatment. */
6606 /* NeXT extension */
6607 obstack_1grow (&util_obstack
, '^');
6608 encode_type (pointer_to
, curtype
, format
);
6612 encode_array (type
, curtype
, format
)
6617 tree an_int_cst
= TYPE_SIZE (type
);
6618 tree array_of
= TREE_TYPE (type
);
6621 /* An incomplete array is treated like a pointer. */
6622 if (an_int_cst
== NULL
)
6624 encode_pointer (type
, curtype
, format
);
6628 sprintf (buffer
, "[%ld",
6629 (long) (TREE_INT_CST_LOW (an_int_cst
)
6630 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6632 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6633 encode_type (array_of
, curtype
, format
);
6634 obstack_1grow (&util_obstack
, ']');
6639 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6646 /* The RECORD_TYPE may in fact be a typedef! For purposes
6647 of encoding, we need the real underlying enchilada. */
6648 if (TYPE_MAIN_VARIANT (type
))
6649 type
= TYPE_MAIN_VARIANT (type
);
6651 if (obstack_object_size (&util_obstack
) > 0
6652 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6654 tree name
= TYPE_NAME (type
);
6656 /* we have a reference; this is a NeXT extension. */
6658 if (obstack_object_size (&util_obstack
) - curtype
== 1
6659 && format
== OBJC_ENCODE_INLINE_DEFS
)
6661 /* Output format of struct for first level only. */
6662 tree fields
= TYPE_FIELDS (type
);
6664 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6666 obstack_1grow (&util_obstack
, left
);
6667 obstack_grow (&util_obstack
,
6668 IDENTIFIER_POINTER (name
),
6669 strlen (IDENTIFIER_POINTER (name
)));
6670 obstack_1grow (&util_obstack
, '=');
6674 obstack_1grow (&util_obstack
, left
);
6675 obstack_grow (&util_obstack
, "?=", 2);
6678 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6679 encode_field_decl (fields
, curtype
, format
);
6681 obstack_1grow (&util_obstack
, right
);
6684 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6686 obstack_1grow (&util_obstack
, left
);
6687 obstack_grow (&util_obstack
,
6688 IDENTIFIER_POINTER (name
),
6689 strlen (IDENTIFIER_POINTER (name
)));
6690 obstack_1grow (&util_obstack
, right
);
6695 /* We have an untagged structure or a typedef. */
6696 obstack_1grow (&util_obstack
, left
);
6697 obstack_1grow (&util_obstack
, '?');
6698 obstack_1grow (&util_obstack
, right
);
6704 tree name
= TYPE_NAME (type
);
6705 tree fields
= TYPE_FIELDS (type
);
6707 if (format
== OBJC_ENCODE_INLINE_DEFS
6708 || generating_instance_variables
)
6710 obstack_1grow (&util_obstack
, left
);
6711 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6712 obstack_grow (&util_obstack
,
6713 IDENTIFIER_POINTER (name
),
6714 strlen (IDENTIFIER_POINTER (name
)));
6716 obstack_1grow (&util_obstack
, '?');
6718 obstack_1grow (&util_obstack
, '=');
6720 for (; fields
; fields
= TREE_CHAIN (fields
))
6722 if (generating_instance_variables
)
6724 tree fname
= DECL_NAME (fields
);
6726 obstack_1grow (&util_obstack
, '"');
6727 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6729 obstack_grow (&util_obstack
,
6730 IDENTIFIER_POINTER (fname
),
6731 strlen (IDENTIFIER_POINTER (fname
)));
6734 obstack_1grow (&util_obstack
, '"');
6737 encode_field_decl (fields
, curtype
, format
);
6740 obstack_1grow (&util_obstack
, right
);
6745 obstack_1grow (&util_obstack
, left
);
6746 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6747 obstack_grow (&util_obstack
,
6748 IDENTIFIER_POINTER (name
),
6749 strlen (IDENTIFIER_POINTER (name
)));
6751 /* We have an untagged structure or a typedef. */
6752 obstack_1grow (&util_obstack
, '?');
6754 obstack_1grow (&util_obstack
, right
);
6760 encode_aggregate (type
, curtype
, format
)
6765 enum tree_code code
= TREE_CODE (type
);
6771 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6776 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6781 obstack_1grow (&util_obstack
, 'i');
6789 /* Support bitfields. The current version of Objective-C does not support
6790 them. The string will consist of one or more "b:n"'s where n is an
6791 integer describing the width of the bitfield. Currently, classes in
6792 the kit implement a method "-(char *)describeBitfieldStruct:" that
6793 simulates this. If they do not implement this method, the archiver
6794 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6795 according to the GNU compiler. After looking at the "kit", it appears
6796 that all classes currently rely on this default behavior, rather than
6797 hand generating this string (which is tedious). */
6800 encode_bitfield (width
)
6804 sprintf (buffer
, "b%d", width
);
6805 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6808 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6811 encode_type (type
, curtype
, format
)
6816 enum tree_code code
= TREE_CODE (type
);
6818 if (code
== INTEGER_TYPE
)
6820 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6822 /* Unsigned integer types. */
6824 if (TYPE_MODE (type
) == QImode
)
6825 obstack_1grow (&util_obstack
, 'C');
6826 else if (TYPE_MODE (type
) == HImode
)
6827 obstack_1grow (&util_obstack
, 'S');
6828 else if (TYPE_MODE (type
) == SImode
)
6830 if (type
== long_unsigned_type_node
)
6831 obstack_1grow (&util_obstack
, 'L');
6833 obstack_1grow (&util_obstack
, 'I');
6835 else if (TYPE_MODE (type
) == DImode
)
6836 obstack_1grow (&util_obstack
, 'Q');
6840 /* Signed integer types. */
6842 if (TYPE_MODE (type
) == QImode
)
6843 obstack_1grow (&util_obstack
, 'c');
6844 else if (TYPE_MODE (type
) == HImode
)
6845 obstack_1grow (&util_obstack
, 's');
6846 else if (TYPE_MODE (type
) == SImode
)
6848 if (type
== long_integer_type_node
)
6849 obstack_1grow (&util_obstack
, 'l');
6851 obstack_1grow (&util_obstack
, 'i');
6854 else if (TYPE_MODE (type
) == DImode
)
6855 obstack_1grow (&util_obstack
, 'q');
6859 else if (code
== REAL_TYPE
)
6861 /* Floating point types. */
6863 if (TYPE_MODE (type
) == SFmode
)
6864 obstack_1grow (&util_obstack
, 'f');
6865 else if (TYPE_MODE (type
) == DFmode
6866 || TYPE_MODE (type
) == TFmode
)
6867 obstack_1grow (&util_obstack
, 'd');
6870 else if (code
== VOID_TYPE
)
6871 obstack_1grow (&util_obstack
, 'v');
6873 else if (code
== ARRAY_TYPE
)
6874 encode_array (type
, curtype
, format
);
6876 else if (code
== POINTER_TYPE
)
6877 encode_pointer (type
, curtype
, format
);
6879 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6880 encode_aggregate (type
, curtype
, format
);
6882 else if (code
== FUNCTION_TYPE
) /* '?' */
6883 obstack_1grow (&util_obstack
, '?');
6887 encode_complete_bitfield (position
, type
, size
)
6892 enum tree_code code
= TREE_CODE (type
);
6894 char charType
= '?';
6896 if (code
== INTEGER_TYPE
)
6898 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6900 /* Unsigned integer types. */
6902 if (TYPE_MODE (type
) == QImode
)
6904 else if (TYPE_MODE (type
) == HImode
)
6906 else if (TYPE_MODE (type
) == SImode
)
6908 if (type
== long_unsigned_type_node
)
6913 else if (TYPE_MODE (type
) == DImode
)
6918 /* Signed integer types. */
6920 if (TYPE_MODE (type
) == QImode
)
6922 else if (TYPE_MODE (type
) == HImode
)
6924 else if (TYPE_MODE (type
) == SImode
)
6926 if (type
== long_integer_type_node
)
6932 else if (TYPE_MODE (type
) == DImode
)
6936 else if (code
== ENUMERAL_TYPE
)
6941 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6942 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6946 encode_field_decl (field_decl
, curtype
, format
)
6953 type
= TREE_TYPE (field_decl
);
6955 /* If this field is obviously a bitfield, or is a bitfield that has been
6956 clobbered to look like a ordinary integer mode, go ahead and generate
6957 the bitfield typing information. */
6958 if (flag_next_runtime
)
6960 if (DECL_BIT_FIELD_TYPE (field_decl
))
6961 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6963 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6967 if (DECL_BIT_FIELD_TYPE (field_decl
))
6968 encode_complete_bitfield (int_bit_position (field_decl
),
6969 DECL_BIT_FIELD_TYPE (field_decl
),
6970 tree_low_cst (DECL_SIZE (field_decl
), 1));
6972 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6977 expr_last (complex_expr
)
6983 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6984 complex_expr
= next
;
6986 return complex_expr
;
6989 /* Transform a method definition into a function definition as follows:
6990 - synthesize the first two arguments, "self" and "_cmd". */
6993 start_method_def (method
)
6998 /* Required to implement _msgSuper. */
6999 objc_method_context
= method
;
7000 UOBJC_SUPER_decl
= NULL_TREE
;
7002 /* Must be called BEFORE start_function. */
7005 /* Generate prototype declarations for arguments..."new-style". */
7007 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
7008 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
7010 /* Really a `struct objc_class *'. However, we allow people to
7011 assign to self, which changes its type midstream. */
7012 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
7014 push_parm_decl (build_tree_list
7015 (build_tree_list (decl_specs
,
7016 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
7019 decl_specs
= build_tree_list (NULL_TREE
,
7020 xref_tag (RECORD_TYPE
,
7021 get_identifier (TAG_SELECTOR
)));
7022 push_parm_decl (build_tree_list
7023 (build_tree_list (decl_specs
,
7024 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
7027 /* Generate argument declarations if a keyword_decl. */
7028 if (METHOD_SEL_ARGS (method
))
7030 tree arglist
= METHOD_SEL_ARGS (method
);
7033 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
7034 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
7038 tree last_expr
= expr_last (arg_decl
);
7040 /* Unite the abstract decl with its name. */
7041 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
7042 push_parm_decl (build_tree_list
7043 (build_tree_list (arg_spec
, arg_decl
),
7046 /* Unhook: restore the abstract declarator. */
7047 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
7051 push_parm_decl (build_tree_list
7052 (build_tree_list (arg_spec
,
7053 KEYWORD_ARG_NAME (arglist
)),
7056 arglist
= TREE_CHAIN (arglist
);
7061 if (METHOD_ADD_ARGS (method
) != NULL_TREE
7062 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
7064 /* We have a variable length selector - in "prototype" format. */
7065 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7068 /* This must be done prior to calling pushdecl. pushdecl is
7069 going to change our chain on us. */
7070 tree nextkey
= TREE_CHAIN (akey
);
7078 warn_with_method (message
, mtype
, method
)
7079 const char *message
;
7083 if (!diagnostic_count_diagnostic (global_dc
, DK_WARNING
))
7086 diagnostic_report_current_function (global_dc
);
7088 /* Add a readable method name to the warning. */
7089 warning_with_file_and_line (DECL_SOURCE_FILE (method
),
7090 DECL_SOURCE_LINE (method
),
7093 gen_method_decl (method
, errbuf
));
7096 /* Return 1 if METHOD is consistent with PROTO. */
7099 comp_method_with_proto (method
, proto
)
7102 /* Create a function template node at most once. */
7103 if (!function1_template
)
7104 function1_template
= make_node (FUNCTION_TYPE
);
7106 /* Install argument types - normally set by build_function_type. */
7107 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7109 /* install return type */
7110 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto
));
7112 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function1_template
);
7115 /* Return 1 if PROTO1 is consistent with PROTO2. */
7118 comp_proto_with_proto (proto0
, proto1
)
7119 tree proto0
, proto1
;
7121 /* Create a couple of function_template nodes at most once. */
7122 if (!function1_template
)
7123 function1_template
= make_node (FUNCTION_TYPE
);
7124 if (!function2_template
)
7125 function2_template
= make_node (FUNCTION_TYPE
);
7127 /* Install argument types; normally set by build_function_type. */
7128 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto0
, METHOD_REF
, 0);
7129 TYPE_ARG_TYPES (function2_template
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7131 /* Install return type. */
7132 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto0
));
7133 TREE_TYPE (function2_template
) = groktypename (TREE_TYPE (proto1
));
7135 return comptypes (function1_template
, function2_template
);
7138 /* - Generate an identifier for the function. the format is "_n_cls",
7139 where 1 <= n <= nMethods, and cls is the name the implementation we
7141 - Install the return type from the method declaration.
7142 - If we have a prototype, check for type consistency. */
7145 really_start_method (method
, parmlist
)
7146 tree method
, parmlist
;
7148 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7149 tree method_decl
, method_id
;
7150 const char *sel_name
, *class_name
, *cat_name
;
7153 /* Synth the storage class & assemble the return type. */
7154 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7155 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7156 decl_specs
= chainon (sc_spec
, ret_spec
);
7158 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7159 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
7160 cat_name
= ((TREE_CODE (objc_implementation_context
)
7161 == CLASS_IMPLEMENTATION_TYPE
)
7163 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7166 /* Make sure this is big enough for any plausible method label. */
7167 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7168 + (cat_name
? strlen (cat_name
) : 0));
7170 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7171 class_name
, cat_name
, sel_name
, method_slot
);
7173 method_id
= get_identifier (buf
);
7175 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7177 /* Check the declarator portion of the return type for the method. */
7178 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7180 /* Unite the complex decl (specified in the abstract decl) with the
7181 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7182 tree save_expr
= expr_last (ret_decl
);
7184 TREE_OPERAND (save_expr
, 0) = method_decl
;
7185 method_decl
= ret_decl
;
7187 /* Fool the parser into thinking it is starting a function. */
7188 start_function (decl_specs
, method_decl
, NULL_TREE
);
7190 /* Unhook: this has the effect of restoring the abstract declarator. */
7191 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7196 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7198 /* Fool the parser into thinking it is starting a function. */
7199 start_function (decl_specs
, method_decl
, NULL_TREE
);
7201 /* Unhook: this has the effect of restoring the abstract declarator. */
7202 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7205 METHOD_DEFINITION (method
) = current_function_decl
;
7207 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7209 if (implementation_template
!= objc_implementation_context
)
7213 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7214 proto
= lookup_instance_method_static (implementation_template
,
7215 METHOD_SEL_NAME (method
));
7217 proto
= lookup_class_method_static (implementation_template
,
7218 METHOD_SEL_NAME (method
));
7220 if (proto
&& ! comp_method_with_proto (method
, proto
))
7222 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7224 warn_with_method ("conflicting types for", type
, method
);
7225 warn_with_method ("previous declaration of", type
, proto
);
7230 /* The following routine is always called...this "architecture" is to
7231 accommodate "old-style" variable length selectors.
7233 - a:a b:b // prototype ; id c; id d; // old-style. */
7236 continue_method_def ()
7240 if (METHOD_ADD_ARGS (objc_method_context
) == objc_ellipsis_node
)
7241 /* We have a `, ...' immediately following the selector. */
7242 parmlist
= get_parm_info (0);
7244 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7246 /* Set self_decl from the first argument...this global is used by
7247 build_ivar_reference calling build_indirect_ref. */
7248 self_decl
= TREE_PURPOSE (parmlist
);
7251 really_start_method (objc_method_context
, parmlist
);
7252 store_parm_decls ();
7255 /* Called by the parser, from the `pushlevel' production. */
7260 if (!UOBJC_SUPER_decl
)
7262 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7263 build_tree_list (NULL_TREE
,
7264 objc_super_template
),
7267 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7269 /* This prevents `unused variable' warnings when compiling with -Wall. */
7270 TREE_USED (UOBJC_SUPER_decl
) = 1;
7271 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7275 /* _n_Method (id self, SEL sel, ...)
7277 struct objc_super _S;
7278 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7282 get_super_receiver ()
7284 if (objc_method_context
)
7286 tree super_expr
, super_expr_list
;
7288 /* Set receiver to self. */
7289 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7290 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7291 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7293 /* Set class to begin searching. */
7294 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7295 get_identifier ("class"));
7297 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7299 /* [_cls, __cls]Super are "pre-built" in
7300 synth_forward_declarations. */
7302 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7303 ((TREE_CODE (objc_method_context
)
7304 == INSTANCE_METHOD_DECL
)
7306 : uucls_super_ref
));
7310 /* We have a category. */
7312 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7315 /* Barf if super used in a category of Object. */
7318 error ("no super class declared in interface for `%s'",
7319 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7320 return error_mark_node
;
7323 if (flag_next_runtime
)
7325 super_class
= get_class_reference (super_name
);
7326 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7327 /* Cast the super class to 'id', since the user may not have
7328 included <objc/objc-class.h>, leaving 'struct objc_class'
7329 an incomplete type. */
7331 = build_component_ref (build_indirect_ref
7332 (build_c_cast (id_type
, super_class
), "->"),
7333 get_identifier ("isa"));
7337 add_class_reference (super_name
);
7338 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7339 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7340 assemble_external (super_class
);
7342 = build_function_call
7346 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7347 IDENTIFIER_POINTER (super_name
))));
7350 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7351 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7354 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7356 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7357 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7359 return build_compound_expr (super_expr_list
);
7363 error ("[super ...] must appear in a method context");
7364 return error_mark_node
;
7369 encode_method_def (func_decl
)
7374 HOST_WIDE_INT max_parm_end
= 0;
7379 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7380 obstack_object_size (&util_obstack
),
7381 OBJC_ENCODE_INLINE_DEFS
);
7384 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7385 parms
= TREE_CHAIN (parms
))
7387 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7388 + int_size_in_bytes (TREE_TYPE (parms
)));
7390 if (! offset_is_register
&& parm_end
> max_parm_end
)
7391 max_parm_end
= parm_end
;
7394 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7396 sprintf (buffer
, "%d", stack_size
);
7397 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7399 /* Argument types. */
7400 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7401 parms
= TREE_CHAIN (parms
))
7404 encode_type (TREE_TYPE (parms
),
7405 obstack_object_size (&util_obstack
),
7406 OBJC_ENCODE_INLINE_DEFS
);
7408 /* Compute offset. */
7409 sprintf (buffer
, "%d", forwarding_offset (parms
));
7411 /* Indicate register. */
7412 if (offset_is_register
)
7413 obstack_1grow (&util_obstack
, '+');
7415 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7418 /* Null terminate string. */
7419 obstack_1grow (&util_obstack
, 0);
7420 result
= get_identifier (obstack_finish (&util_obstack
));
7421 obstack_free (&util_obstack
, util_firstobj
);
7426 objc_expand_function_end ()
7428 METHOD_ENCODING (objc_method_context
) = encode_method_def (current_function_decl
);
7432 finish_method_def ()
7434 lang_expand_function_end
= objc_expand_function_end
;
7435 finish_function (0, 1);
7436 lang_expand_function_end
= NULL
;
7438 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7439 since the optimizer may find "may be used before set" errors. */
7440 objc_method_context
= NULL_TREE
;
7445 lang_report_error_function (decl
)
7448 if (objc_method_context
)
7450 fprintf (stderr
, "In method `%s'\n",
7451 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7461 is_complex_decl (type
)
7464 return (TREE_CODE (type
) == ARRAY_TYPE
7465 || TREE_CODE (type
) == FUNCTION_TYPE
7466 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7470 /* Code to convert a decl node into text for a declaration in C. */
7472 static char tmpbuf
[256];
7475 adorn_decl (decl
, str
)
7479 enum tree_code code
= TREE_CODE (decl
);
7481 if (code
== ARRAY_REF
)
7483 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7485 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7486 sprintf (str
+ strlen (str
), "[%ld]",
7487 (long) TREE_INT_CST_LOW (an_int_cst
));
7492 else if (code
== ARRAY_TYPE
)
7494 tree an_int_cst
= TYPE_SIZE (decl
);
7495 tree array_of
= TREE_TYPE (decl
);
7497 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7498 sprintf (str
+ strlen (str
), "[%ld]",
7499 (long) (TREE_INT_CST_LOW (an_int_cst
)
7500 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7505 else if (code
== CALL_EXPR
)
7507 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7512 gen_declaration_1 (chain
, str
);
7513 chain
= TREE_CHAIN (chain
);
7520 else if (code
== FUNCTION_TYPE
)
7522 tree chain
= TYPE_ARG_TYPES (decl
);
7525 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7527 gen_declaration_1 (TREE_VALUE (chain
), str
);
7528 chain
= TREE_CHAIN (chain
);
7529 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7535 else if (code
== INDIRECT_REF
)
7537 strcpy (tmpbuf
, "*");
7538 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7542 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7544 chain
= TREE_CHAIN (chain
))
7546 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7548 strcat (tmpbuf
, " ");
7549 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7553 strcat (tmpbuf
, " ");
7555 strcat (tmpbuf
, str
);
7556 strcpy (str
, tmpbuf
);
7559 else if (code
== POINTER_TYPE
)
7561 strcpy (tmpbuf
, "*");
7562 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7564 if (TREE_READONLY (decl
))
7565 strcat (tmpbuf
, " const");
7566 if (TYPE_VOLATILE (decl
))
7567 strcat (tmpbuf
, " volatile");
7569 strcat (tmpbuf
, " ");
7571 strcat (tmpbuf
, str
);
7572 strcpy (str
, tmpbuf
);
7577 gen_declarator (decl
, buf
, name
)
7584 enum tree_code code
= TREE_CODE (decl
);
7594 op
= TREE_OPERAND (decl
, 0);
7596 /* We have a pointer to a function or array...(*)(), (*)[] */
7597 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7598 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7601 str
= gen_declarator (op
, buf
, name
);
7605 strcpy (tmpbuf
, "(");
7606 strcat (tmpbuf
, str
);
7607 strcat (tmpbuf
, ")");
7608 strcpy (str
, tmpbuf
);
7611 adorn_decl (decl
, str
);
7620 /* This clause is done iteratively rather than recursively. */
7623 op
= (is_complex_decl (TREE_TYPE (decl
))
7624 ? TREE_TYPE (decl
) : NULL_TREE
);
7626 adorn_decl (decl
, str
);
7628 /* We have a pointer to a function or array...(*)(), (*)[] */
7629 if (code
== POINTER_TYPE
7630 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7631 || TREE_CODE (op
) == ARRAY_TYPE
))
7633 strcpy (tmpbuf
, "(");
7634 strcat (tmpbuf
, str
);
7635 strcat (tmpbuf
, ")");
7636 strcpy (str
, tmpbuf
);
7639 decl
= (is_complex_decl (TREE_TYPE (decl
))
7640 ? TREE_TYPE (decl
) : NULL_TREE
);
7643 while (decl
&& (code
= TREE_CODE (decl
)))
7648 case IDENTIFIER_NODE
:
7649 /* Will only happen if we are processing a "raw" expr-decl. */
7650 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7661 /* We have an abstract declarator or a _DECL node. */
7669 gen_declspecs (declspecs
, buf
, raw
)
7678 for (chain
= nreverse (copy_list (declspecs
));
7679 chain
; chain
= TREE_CHAIN (chain
))
7681 tree aspec
= TREE_VALUE (chain
);
7683 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7684 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7685 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7687 if (TYPE_NAME (aspec
))
7689 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7691 if (! TREE_STATIC_TEMPLATE (aspec
))
7692 strcat (buf
, "struct ");
7693 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7698 tree chain
= protocol_list
;
7705 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7706 chain
= TREE_CHAIN (chain
);
7715 strcat (buf
, "untagged struct");
7718 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7720 if (TYPE_NAME (aspec
))
7722 if (! TREE_STATIC_TEMPLATE (aspec
))
7723 strcat (buf
, "union ");
7724 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7727 strcat (buf
, "untagged union");
7730 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7732 if (TYPE_NAME (aspec
))
7734 if (! TREE_STATIC_TEMPLATE (aspec
))
7735 strcat (buf
, "enum ");
7736 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7739 strcat (buf
, "untagged enum");
7742 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7743 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7745 else if (IS_ID (aspec
))
7747 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7752 tree chain
= protocol_list
;
7759 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7760 chain
= TREE_CHAIN (chain
);
7767 if (TREE_CHAIN (chain
))
7773 /* Type qualifiers. */
7774 if (TREE_READONLY (declspecs
))
7775 strcat (buf
, "const ");
7776 if (TYPE_VOLATILE (declspecs
))
7777 strcat (buf
, "volatile ");
7779 switch (TREE_CODE (declspecs
))
7781 /* Type specifiers. */
7784 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7786 /* Signed integer types. */
7788 if (declspecs
== short_integer_type_node
)
7789 strcat (buf
, "short int ");
7790 else if (declspecs
== integer_type_node
)
7791 strcat (buf
, "int ");
7792 else if (declspecs
== long_integer_type_node
)
7793 strcat (buf
, "long int ");
7794 else if (declspecs
== long_long_integer_type_node
)
7795 strcat (buf
, "long long int ");
7796 else if (declspecs
== signed_char_type_node
7797 || declspecs
== char_type_node
)
7798 strcat (buf
, "char ");
7800 /* Unsigned integer types. */
7802 else if (declspecs
== short_unsigned_type_node
)
7803 strcat (buf
, "unsigned short ");
7804 else if (declspecs
== unsigned_type_node
)
7805 strcat (buf
, "unsigned int ");
7806 else if (declspecs
== long_unsigned_type_node
)
7807 strcat (buf
, "unsigned long ");
7808 else if (declspecs
== long_long_unsigned_type_node
)
7809 strcat (buf
, "unsigned long long ");
7810 else if (declspecs
== unsigned_char_type_node
)
7811 strcat (buf
, "unsigned char ");
7815 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7817 if (declspecs
== float_type_node
)
7818 strcat (buf
, "float ");
7819 else if (declspecs
== double_type_node
)
7820 strcat (buf
, "double ");
7821 else if (declspecs
== long_double_type_node
)
7822 strcat (buf
, "long double ");
7826 if (TYPE_NAME (declspecs
)
7827 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7829 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7831 if (! TREE_STATIC_TEMPLATE (declspecs
))
7832 strcat (buf
, "struct ");
7833 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7837 tree chain
= protocol_list
;
7844 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7845 chain
= TREE_CHAIN (chain
);
7854 strcat (buf
, "untagged struct");
7860 if (TYPE_NAME (declspecs
)
7861 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7863 strcat (buf
, "union ");
7864 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7869 strcat (buf
, "untagged union ");
7873 if (TYPE_NAME (declspecs
)
7874 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7876 strcat (buf
, "enum ");
7877 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7882 strcat (buf
, "untagged enum ");
7886 strcat (buf
, "void ");
7891 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7896 tree chain
= protocol_list
;
7903 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7904 chain
= TREE_CHAIN (chain
);
7920 /* Given a tree node, produce a printable description of it in the given
7921 buffer, overwriting the buffer. */
7924 gen_declaration (atype_or_adecl
, buf
)
7925 tree atype_or_adecl
;
7929 gen_declaration_1 (atype_or_adecl
, buf
);
7933 /* Given a tree node, append a printable description to the end of the
7937 gen_declaration_1 (atype_or_adecl
, buf
)
7938 tree atype_or_adecl
;
7943 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7945 tree declspecs
; /* "identifier_node", "record_type" */
7946 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7948 /* We have a "raw", abstract declarator (typename). */
7949 declarator
= TREE_VALUE (atype_or_adecl
);
7950 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7952 gen_declspecs (declspecs
, buf
, 1);
7956 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7963 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7964 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7966 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7967 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7968 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7969 atype
= TREE_TYPE (atype_or_adecl
);
7971 /* Assume we have a *_type node. */
7972 atype
= atype_or_adecl
;
7974 if (is_complex_decl (atype
))
7978 /* Get the declaration specifier; it is at the end of the list. */
7979 declarator
= chain
= atype
;
7981 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7982 while (is_complex_decl (chain
));
7989 declarator
= NULL_TREE
;
7992 gen_declspecs (declspecs
, buf
, 0);
7994 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7995 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7996 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7998 const char *const decl_name
=
7999 (DECL_NAME (atype_or_adecl
)
8000 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
8005 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
8008 else if (decl_name
[0])
8011 strcat (buf
, decl_name
);
8014 else if (declarator
)
8017 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
8022 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8024 /* Given a method tree, put a printable description into the given
8025 buffer (overwriting) and return a pointer to the buffer. */
8028 gen_method_decl (method
, buf
)
8035 if (RAW_TYPESPEC (method
) != objc_object_reference
)
8038 gen_declaration_1 (TREE_TYPE (method
), buf
);
8042 chain
= METHOD_SEL_ARGS (method
);
8045 /* We have a chain of keyword_decls. */
8048 if (KEYWORD_KEY_NAME (chain
))
8049 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
8052 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
8055 gen_declaration_1 (TREE_TYPE (chain
), buf
);
8059 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
8060 if ((chain
= TREE_CHAIN (chain
)))
8065 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
8066 strcat (buf
, ", ...");
8067 else if (METHOD_ADD_ARGS (method
))
8069 /* We have a tree list node as generate by get_parm_info. */
8070 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
8072 /* Know we have a chain of parm_decls. */
8076 gen_declaration_1 (chain
, buf
);
8077 chain
= TREE_CHAIN (chain
);
8083 /* We have a unary selector. */
8084 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8092 /* Dump an @interface declaration of the supplied class CHAIN to the
8093 supplied file FP. Used to implement the -gen-decls option (which
8094 prints out an @interface declaration of all classes compiled in
8095 this run); potentially useful for debugging the compiler too. */
8097 dump_interface (fp
, chain
)
8101 /* FIXME: A heap overflow here whenever a method (or ivar)
8102 declaration is so long that it doesn't fit in the buffer. The
8103 code and all the related functions should be rewritten to avoid
8104 using fixed size buffers. */
8105 char *buf
= (char *) xmalloc (1024 * 10);
8106 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8107 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8108 tree nst_methods
= CLASS_NST_METHODS (chain
);
8109 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8111 fprintf (fp
, "\n@interface %s", my_name
);
8113 /* CLASS_SUPER_NAME is used to store the superclass name for
8114 classes, and the category name for categories. */
8115 if (CLASS_SUPER_NAME (chain
))
8117 const char *name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8119 if (TREE_CODE (chain
) == CATEGORY_IMPLEMENTATION_TYPE
8120 || TREE_CODE (chain
) == CATEGORY_INTERFACE_TYPE
)
8122 fprintf (fp
, " (%s)\n", name
);
8126 fprintf (fp
, " : %s\n", name
);
8132 /* FIXME - the following doesn't seem to work at the moment. */
8135 fprintf (fp
, "{\n");
8138 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8139 ivar_decls
= TREE_CHAIN (ivar_decls
);
8142 fprintf (fp
, "}\n");
8147 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8148 nst_methods
= TREE_CHAIN (nst_methods
);
8153 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8154 cls_methods
= TREE_CHAIN (cls_methods
);
8157 fprintf (fp
, "@end\n");
8160 /* Demangle function for Objective-C */
8162 objc_demangle (mangled
)
8163 const char *mangled
;
8165 char *demangled
, *cp
;
8167 if (mangled
[0] == '_' &&
8168 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8171 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8172 if (mangled
[1] == 'i')
8173 *cp
++ = '-'; /* for instance method */
8175 *cp
++ = '+'; /* for class method */
8176 *cp
++ = '['; /* opening left brace */
8177 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8178 while (*cp
&& *cp
== '_')
8179 cp
++; /* skip any initial underbars in class name */
8180 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8183 free(demangled
); /* not mangled name */
8186 if (cp
[1] == '_') /* easy case: no category name */
8188 *cp
++ = ' '; /* replace two '_' with one ' ' */
8189 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8193 *cp
++ = '('; /* less easy case: category name */
8194 cp
= strchr(cp
, '_');
8197 free(demangled
); /* not mangled name */
8201 *cp
++ = ' '; /* overwriting 1st char of method name... */
8202 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8204 while (*cp
&& *cp
== '_')
8205 cp
++; /* skip any initial underbars in method name */
8208 *cp
= ':'; /* replace remaining '_' with ':' */
8209 *cp
++ = ']'; /* closing right brace */
8210 *cp
++ = 0; /* string terminator */
8214 return mangled
; /* not an objc mangled name */
8218 objc_printable_name (decl
, kind
)
8220 int kind ATTRIBUTE_UNUSED
;
8222 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8228 gcc_obstack_init (&util_obstack
);
8229 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8231 errbuf
= (char *) xmalloc (BUFSIZE
);
8233 synth_module_prologue ();
8239 struct imp_entry
*impent
;
8241 /* The internally generated initializers appear to have missing braces.
8242 Don't warn about this. */
8243 int save_warn_missing_braces
= warn_missing_braces
;
8244 warn_missing_braces
= 0;
8246 /* A missing @end may not be detected by the parser. */
8247 if (objc_implementation_context
)
8249 warning ("`@end' missing in implementation context");
8250 finish_class (objc_implementation_context
);
8251 objc_ivar_chain
= NULL_TREE
;
8252 objc_implementation_context
= NULL_TREE
;
8255 generate_forward_declaration_to_string_table ();
8257 #ifdef OBJC_PROLOGUE
8261 /* Process the static instances here because initialization of objc_symtab
8263 if (objc_static_instances
)
8264 generate_static_references ();
8266 if (imp_list
|| class_names_chain
8267 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8268 generate_objc_symtab_decl ();
8270 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8272 objc_implementation_context
= impent
->imp_context
;
8273 implementation_template
= impent
->imp_template
;
8275 UOBJC_CLASS_decl
= impent
->class_decl
;
8276 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8278 /* Dump the @interface of each class as we compile it, if the
8279 -gen-decls option is in use. TODO: Dump the classes in the
8280 order they were found, rather than in reverse order as we
8282 if (flag_gen_declaration
)
8284 dump_interface (gen_declaration_file
, objc_implementation_context
);
8287 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8289 /* all of the following reference the string pool... */
8290 generate_ivar_lists ();
8291 generate_dispatch_tables ();
8292 generate_shared_structures ();
8296 generate_dispatch_tables ();
8297 generate_category (objc_implementation_context
);
8301 /* If we are using an array of selectors, we must always
8302 finish up the array decl even if no selectors were used. */
8303 if (! flag_next_runtime
|| sel_ref_chain
)
8304 build_selector_translation_table ();
8307 generate_protocols ();
8309 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8310 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8312 /* Arrange for ObjC data structures to be initialized at run time. */
8313 rtx init_sym
= build_module_descriptor ();
8314 if (init_sym
&& targetm
.have_ctors_dtors
)
8315 (* targetm
.asm_out
.constructor
) (init_sym
, DEFAULT_INIT_PRIORITY
);
8318 /* Dump the class references. This forces the appropriate classes
8319 to be linked into the executable image, preserving unix archive
8320 semantics. This can be removed when we move to a more dynamically
8321 linked environment. */
8323 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8325 handle_class_ref (chain
);
8326 if (TREE_PURPOSE (chain
))
8327 generate_classref_translation_entry (chain
);
8330 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8331 handle_impent (impent
);
8333 /* Dump the string table last. */
8335 generate_strings ();
8342 /* Run through the selector hash tables and print a warning for any
8343 selector which has multiple methods. */
8345 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8346 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8349 tree meth
= hsh
->key
;
8350 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8354 warning ("potential selector conflict for method `%s'",
8355 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8356 warn_with_method ("found", type
, meth
);
8357 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8358 warn_with_method ("found", type
, loop
->value
);
8361 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8362 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8365 tree meth
= hsh
->key
;
8366 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8370 warning ("potential selector conflict for method `%s'",
8371 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8372 warn_with_method ("found", type
, meth
);
8373 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8374 warn_with_method ("found", type
, loop
->value
);
8378 warn_missing_braces
= save_warn_missing_braces
;
8381 /* Subroutines of finish_objc. */
8384 generate_classref_translation_entry (chain
)
8387 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8390 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8392 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8393 expr
= build_c_cast (type
, expr
); /* cast! */
8395 name
= DECL_NAME (TREE_PURPOSE (chain
));
8397 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8399 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8400 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8402 /* The decl that is returned from start_decl is the one that we
8403 forward declared in build_class_reference. */
8404 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
);
8405 DECL_CONTEXT (decl
) = NULL_TREE
;
8406 finish_decl (decl
, expr
, NULL_TREE
);
8411 handle_class_ref (chain
)
8414 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8415 char *string
= (char *) alloca (strlen (name
) + 30);
8419 sprintf (string
, "%sobjc_class_name_%s",
8420 (flag_next_runtime
? "." : "__"), name
);
8422 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8423 if (flag_next_runtime
)
8425 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8430 /* Make a decl for this name, so we can use its address in a tree. */
8431 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8432 DECL_EXTERNAL (decl
) = 1;
8433 TREE_PUBLIC (decl
) = 1;
8436 rest_of_decl_compilation (decl
, 0, 0, 0);
8438 /* Make a decl for the address. */
8439 sprintf (string
, "%sobjc_class_ref_%s",
8440 (flag_next_runtime
? "." : "__"), name
);
8441 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8442 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8443 DECL_INITIAL (decl
) = exp
;
8444 TREE_STATIC (decl
) = 1;
8445 TREE_USED (decl
) = 1;
8448 rest_of_decl_compilation (decl
, 0, 0, 0);
8452 handle_impent (impent
)
8453 struct imp_entry
*impent
;
8457 objc_implementation_context
= impent
->imp_context
;
8458 implementation_template
= impent
->imp_template
;
8460 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8462 const char *const class_name
=
8463 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8465 string
= (char *) alloca (strlen (class_name
) + 30);
8467 sprintf (string
, "%sobjc_class_name_%s",
8468 (flag_next_runtime
? "." : "__"), class_name
);
8470 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8472 const char *const class_name
=
8473 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8474 const char *const class_super_name
=
8475 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8477 string
= (char *) alloca (strlen (class_name
)
8478 + strlen (class_super_name
) + 30);
8480 /* Do the same for categories. Even though no references to
8481 these symbols are generated automatically by the compiler, it
8482 gives you a handle to pull them into an archive by hand. */
8483 sprintf (string
, "*%sobjc_category_name_%s_%s",
8484 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8489 #ifdef ASM_DECLARE_CLASS_REFERENCE
8490 if (flag_next_runtime
)
8492 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8500 init
= build_int_2 (0, 0);
8501 TREE_TYPE (init
) = c_common_type_for_size (BITS_PER_WORD
, 1);
8502 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
8503 TREE_PUBLIC (decl
) = 1;
8504 TREE_READONLY (decl
) = 1;
8505 TREE_USED (decl
) = 1;
8506 TREE_CONSTANT (decl
) = 1;
8507 DECL_CONTEXT (decl
) = 0;
8508 DECL_ARTIFICIAL (decl
) = 1;
8509 DECL_INITIAL (decl
) = init
;
8510 assemble_variable (decl
, 1, 0, 0);
8514 /* Look up ID as an instance variable. */
8516 lookup_objc_ivar (id
)
8521 if (objc_method_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8522 /* We have a message to super. */
8523 return get_super_receiver ();
8524 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8526 if (is_private (decl
))
8527 return error_mark_node
;
8529 return build_ivar_reference (id
);
8535 #include "gtype-objc.h"