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':
62 /* This is the default way of generating a method name. */
63 /* I am not sure it is really correct.
64 Perhaps there's a danger that it will make name conflicts
65 if method names contain underscores. -- rms. */
66 #ifndef OBJC_GEN_METHOD_LABEL
67 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
70 sprintf ((BUF), "_%s_%s_%s_%s", \
71 ((IS_INST) ? "i" : "c"), \
73 ((CAT_NAME)? (CAT_NAME) : ""), \
75 for (temp = (BUF); *temp; temp++) \
76 if (*temp == ':') *temp = '_'; \
80 /* These need specifying. */
81 #ifndef OBJC_FORWARDING_STACK_OFFSET
82 #define OBJC_FORWARDING_STACK_OFFSET 0
85 #ifndef OBJC_FORWARDING_MIN_OFFSET
86 #define OBJC_FORWARDING_MIN_OFFSET 0
90 /* Set up for use of obstacks. */
94 #define obstack_chunk_alloc xmalloc
95 #define obstack_chunk_free free
97 /* This obstack is used to accumulate the encoding of a data type. */
98 static struct obstack util_obstack
;
99 /* This points to the beginning of obstack contents,
100 so we can free the whole contents. */
103 /* for encode_method_def */
106 /* The version identifies which language generation and runtime
107 the module (file) was compiled for, and is recorded in the
108 module descriptor. */
110 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
111 #define PROTOCOL_VERSION 2
113 /* (Decide if these can ever be validly changed.) */
114 #define OBJC_ENCODE_INLINE_DEFS 0
115 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
117 /*** Private Interface (procedures) ***/
119 /* Used by compile_file. */
121 static void init_objc
PARAMS ((void));
122 static void finish_objc
PARAMS ((void));
124 /* Code generation. */
126 static void synth_module_prologue
PARAMS ((void));
127 static tree build_constructor
PARAMS ((tree
, tree
));
128 static rtx build_module_descriptor
PARAMS ((void));
129 static tree init_module_descriptor
PARAMS ((tree
));
130 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
132 static void generate_strings
PARAMS ((void));
133 static tree get_proto_encoding
PARAMS ((tree
));
134 static void build_selector_translation_table
PARAMS ((void));
135 static tree build_ivar_chain
PARAMS ((tree
, int));
137 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
139 static tree build_ivar_template
PARAMS ((void));
140 static tree build_method_template
PARAMS ((void));
141 static tree build_private_template
PARAMS ((tree
));
142 static void build_class_template
PARAMS ((void));
143 static void build_selector_template
PARAMS ((void));
144 static void build_category_template
PARAMS ((void));
145 static tree build_super_template
PARAMS ((void));
146 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
148 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
151 static void synth_forward_declarations
PARAMS ((void));
152 static void generate_ivar_lists
PARAMS ((void));
153 static void generate_dispatch_tables
PARAMS ((void));
154 static void generate_shared_structures
PARAMS ((void));
155 static tree generate_protocol_list
PARAMS ((tree
));
156 static void generate_forward_declaration_to_string_table
PARAMS ((void));
157 static void build_protocol_reference
PARAMS ((tree
));
159 static tree build_keyword_selector
PARAMS ((tree
));
160 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
162 static void generate_static_references
PARAMS ((void));
163 static int check_methods_accessible
PARAMS ((tree
, tree
,
165 static void encode_aggregate_within
PARAMS ((tree
, int, int,
167 static const char *objc_demangle
PARAMS ((const char *));
168 static void objc_expand_function_end
PARAMS ((void));
170 /* Hash tables to manage the global pool of method prototypes. */
172 hash
*nst_method_hash_list
= 0;
173 hash
*cls_method_hash_list
= 0;
175 static size_t hash_func
PARAMS ((tree
));
176 static void hash_init
PARAMS ((void));
177 static void hash_enter
PARAMS ((hash
*, tree
));
178 static hash hash_lookup
PARAMS ((hash
*, tree
));
179 static void hash_add_attr
PARAMS ((hash
, tree
));
180 static tree lookup_method
PARAMS ((tree
, tree
));
181 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
182 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
183 static tree add_class
PARAMS ((tree
));
184 static void add_category
PARAMS ((tree
, tree
));
188 class_names
, /* class, category, protocol, module names */
189 meth_var_names
, /* method and variable names */
190 meth_var_types
/* method and variable type descriptors */
193 static tree add_objc_string
PARAMS ((tree
,
194 enum string_section
));
195 static tree get_objc_string_decl
PARAMS ((tree
,
196 enum string_section
));
197 static tree build_objc_string_decl
PARAMS ((enum string_section
));
198 static tree build_selector_reference_decl
PARAMS ((void));
200 /* Protocol additions. */
202 static tree add_protocol
PARAMS ((tree
));
203 static tree lookup_protocol
PARAMS ((tree
));
204 static void check_protocol_recursively
PARAMS ((tree
, tree
));
205 static tree lookup_and_install_protocols
PARAMS ((tree
));
209 static void encode_type_qualifiers
PARAMS ((tree
));
210 static void encode_pointer
PARAMS ((tree
, int, int));
211 static void encode_array
PARAMS ((tree
, int, int));
212 static void encode_aggregate
PARAMS ((tree
, int, int));
213 static void encode_bitfield
PARAMS ((int));
214 static void encode_type
PARAMS ((tree
, int, int));
215 static void encode_field_decl
PARAMS ((tree
, int, int));
217 static void really_start_method
PARAMS ((tree
, tree
));
218 static int comp_method_with_proto
PARAMS ((tree
, tree
));
219 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
220 static tree get_arg_type_list
PARAMS ((tree
, int, int));
221 static tree expr_last
PARAMS ((tree
));
223 /* Utilities for debugging and error diagnostics. */
225 static void warn_with_method
PARAMS ((const char *, int, tree
));
226 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
227 static char *gen_method_decl
PARAMS ((tree
, char *));
228 static char *gen_declaration
PARAMS ((tree
, char *));
229 static void gen_declaration_1
PARAMS ((tree
, char *));
230 static char *gen_declarator
PARAMS ((tree
, char *,
232 static int is_complex_decl
PARAMS ((tree
));
233 static void adorn_decl
PARAMS ((tree
, char *));
234 static void dump_interface
PARAMS ((FILE *, tree
));
236 /* Everything else. */
238 static tree define_decl
PARAMS ((tree
, tree
));
239 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
240 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
241 static tree create_builtin_decl
PARAMS ((enum tree_code
,
242 tree
, const char *));
243 static void setup_string_decl
PARAMS ((void));
244 static void build_string_class_template
PARAMS ((void));
245 static tree my_build_string
PARAMS ((int, const char *));
246 static void build_objc_symtab_template
PARAMS ((void));
247 static tree init_def_list
PARAMS ((tree
));
248 static tree init_objc_symtab
PARAMS ((tree
));
249 static void forward_declare_categories
PARAMS ((void));
250 static void generate_objc_symtab_decl
PARAMS ((void));
251 static tree build_selector
PARAMS ((tree
));
252 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
253 static tree build_selector_reference
PARAMS ((tree
));
254 static tree build_class_reference_decl
PARAMS ((void));
255 static void add_class_reference
PARAMS ((tree
));
256 static tree objc_copy_list
PARAMS ((tree
, tree
*));
257 static tree build_protocol_template
PARAMS ((void));
258 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
259 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
260 static tree build_method_prototype_template
PARAMS ((void));
261 static int forwarding_offset
PARAMS ((tree
));
262 static tree encode_method_prototype
PARAMS ((tree
, tree
));
263 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
265 static void generate_method_descriptors
PARAMS ((tree
));
266 static tree build_tmp_function_decl
PARAMS ((void));
267 static void hack_method_prototype
PARAMS ((tree
, tree
));
268 static void generate_protocol_references
PARAMS ((tree
));
269 static void generate_protocols
PARAMS ((void));
270 static void check_ivars
PARAMS ((tree
, tree
));
271 static tree build_ivar_list_template
PARAMS ((tree
, int));
272 static tree build_method_list_template
PARAMS ((tree
, int));
273 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
274 static tree generate_ivars_list
PARAMS ((tree
, const char *,
276 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
277 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
279 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
280 tree
, int, tree
, tree
,
282 static void generate_category
PARAMS ((tree
));
283 static int is_objc_type_qualifier
PARAMS ((tree
));
284 static tree adjust_type_for_id_default
PARAMS ((tree
));
285 static tree check_duplicates
PARAMS ((hash
));
286 static tree receiver_is_class_object
PARAMS ((tree
));
287 static int check_methods
PARAMS ((tree
, tree
, int));
288 static int conforms_to_protocol
PARAMS ((tree
, tree
));
289 static void check_protocol
PARAMS ((tree
, const char *,
291 static void check_protocols
PARAMS ((tree
, const char *,
293 static tree encode_method_def
PARAMS ((tree
));
294 static void gen_declspecs
PARAMS ((tree
, char *, int));
295 static void generate_classref_translation_entry
PARAMS ((tree
));
296 static void handle_class_ref
PARAMS ((tree
));
297 static void generate_struct_by_value_array
PARAMS ((void))
299 static void objc_act_parse_init
PARAMS ((void));
300 static void ggc_mark_imp_list
PARAMS ((void *));
301 static void ggc_mark_hash_table
PARAMS ((void *));
303 /*** Private Interface (data) ***/
305 /* Reserved tag definitions. */
308 #define TAG_OBJECT "objc_object"
309 #define TAG_CLASS "objc_class"
310 #define TAG_SUPER "objc_super"
311 #define TAG_SELECTOR "objc_selector"
313 #define UTAG_CLASS "_objc_class"
314 #define UTAG_IVAR "_objc_ivar"
315 #define UTAG_IVAR_LIST "_objc_ivar_list"
316 #define UTAG_METHOD "_objc_method"
317 #define UTAG_METHOD_LIST "_objc_method_list"
318 #define UTAG_CATEGORY "_objc_category"
319 #define UTAG_MODULE "_objc_module"
320 #define UTAG_STATICS "_objc_statics"
321 #define UTAG_SYMTAB "_objc_symtab"
322 #define UTAG_SUPER "_objc_super"
323 #define UTAG_SELECTOR "_objc_selector"
325 #define UTAG_PROTOCOL "_objc_protocol"
326 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
327 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
328 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
330 /* Note that the string object global name is only needed for the
332 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
334 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
336 static const char *constant_string_class_name
= NULL
;
338 static const char *TAG_GETCLASS
;
339 static const char *TAG_GETMETACLASS
;
340 static const char *TAG_MSGSEND
;
341 static const char *TAG_MSGSENDSUPER
;
342 static const char *TAG_EXECCLASS
;
343 static const char *default_constant_string_class_name
;
345 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
346 tree objc_global_trees
[OCTI_MAX
];
348 int objc_receiver_context
;
350 static void handle_impent
PARAMS ((struct imp_entry
*));
352 struct imp_entry
*imp_list
= 0;
353 int imp_count
= 0; /* `@implementation' */
354 int cat_count
= 0; /* `@category' */
356 static int method_slot
= 0; /* Used by start_method_def, */
360 static char *errbuf
; /* Buffer for error diagnostics */
362 /* Data imported from tree.c. */
364 extern enum debug_info_type write_symbols
;
366 /* Data imported from toplev.c. */
368 extern const char *dump_base_name
;
370 /* Generate code for GNU or NeXT runtime environment. */
372 #ifdef NEXT_OBJC_RUNTIME
373 int flag_next_runtime
= 1;
375 int flag_next_runtime
= 0;
378 int flag_typed_selectors
;
380 /* Open and close the file for outputting class declarations, if requested. */
382 int flag_gen_declaration
= 0;
384 FILE *gen_declaration_file
;
386 /* Warn if multiple methods are seen for the same selector, but with
387 different argument types. */
389 int warn_selector
= 0;
391 /* Warn if methods required by a protocol are not implemented in the
392 class adopting it. When turned off, methods inherited to that
393 class are also considered implemented */
395 int flag_warn_protocol
= 1;
397 /* Tells "encode_pointer/encode_aggregate" whether we are generating
398 type descriptors for instance variables (as opposed to methods).
399 Type descriptors for instance variables contain more information
400 than methods (for static typing and embedded structures). */
402 static int generating_instance_variables
= 0;
404 /* Tells the compiler that this is a special run. Do not perform any
405 compiling, instead we are to test some platform dependent features
406 and output a C header file with appropriate definitions. */
408 static int print_struct_values
= 0;
410 /* Some platforms pass small structures through registers versus
411 through an invisible pointer. Determine at what size structure is
412 the transition point between the two possibilities. */
415 generate_struct_by_value_array ()
418 tree field_decl
, field_decl_chain
;
420 int aggregate_in_mem
[32];
423 /* Presumably no platform passes 32 byte structures in a register. */
424 for (i
= 1; i
< 32; i
++)
428 /* Create an unnamed struct that has `i' character components */
429 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
431 strcpy (buffer
, "c1");
432 field_decl
= create_builtin_decl (FIELD_DECL
,
435 field_decl_chain
= field_decl
;
437 for (j
= 1; j
< i
; j
++)
439 sprintf (buffer
, "c%d", j
+ 1);
440 field_decl
= create_builtin_decl (FIELD_DECL
,
443 chainon (field_decl_chain
, field_decl
);
445 finish_struct (type
, field_decl_chain
, NULL_TREE
);
447 aggregate_in_mem
[i
] = aggregate_value_p (type
);
448 if (!aggregate_in_mem
[i
])
452 /* We found some structures that are returned in registers instead of memory
453 so output the necessary data. */
456 for (i
= 31; i
>= 0; i
--)
457 if (!aggregate_in_mem
[i
])
459 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
461 /* The first member of the structure is always 0 because we don't handle
462 structures with 0 members */
463 printf ("static int struct_forward_array[] = {\n 0");
465 for (j
= 1; j
<= i
; j
++)
466 printf (", %d", aggregate_in_mem
[j
]);
475 const char *filename
;
477 filename
= c_objc_common_init (filename
);
479 /* Force the line number back to 0; check_newline will have
480 raised it to 1, which will make the builtin functions appear
481 not to be built in. */
484 /* If gen_declaration desired, open the output file. */
485 if (flag_gen_declaration
)
487 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
488 gen_declaration_file
= fopen (dumpname
, "w");
489 if (gen_declaration_file
== 0)
490 fatal_io_error ("can't open %s", dumpname
);
494 if (flag_next_runtime
)
496 TAG_GETCLASS
= "objc_getClass";
497 TAG_GETMETACLASS
= "objc_getMetaClass";
498 TAG_MSGSEND
= "objc_msgSend";
499 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
500 TAG_EXECCLASS
= "__objc_execClass";
501 default_constant_string_class_name
= "NSConstantString";
505 TAG_GETCLASS
= "objc_get_class";
506 TAG_GETMETACLASS
= "objc_get_meta_class";
507 TAG_MSGSEND
= "objc_msg_lookup";
508 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
509 TAG_EXECCLASS
= "__objc_exec_class";
510 default_constant_string_class_name
= "NXConstantString";
511 flag_typed_selectors
= 1;
514 objc_ellipsis_node
= make_node (ERROR_MARK
);
518 if (print_struct_values
)
519 generate_struct_by_value_array ();
521 objc_act_parse_init ();
529 c_objc_common_finish_file ();
531 finish_objc (); /* Objective-C finalization */
533 if (gen_declaration_file
)
534 fclose (gen_declaration_file
);
538 objc_decode_option (argc
, argv
)
542 const char *p
= argv
[0];
544 if (!strcmp (p
, "-gen-decls"))
545 flag_gen_declaration
= 1;
546 else if (!strcmp (p
, "-Wselector"))
548 else if (!strcmp (p
, "-Wno-selector"))
550 else if (!strcmp (p
, "-Wprotocol"))
551 flag_warn_protocol
= 1;
552 else if (!strcmp (p
, "-Wno-protocol"))
553 flag_warn_protocol
= 0;
554 else if (!strcmp (p
, "-fgnu-runtime"))
555 flag_next_runtime
= 0;
556 else if (!strcmp (p
, "-fno-next-runtime"))
557 flag_next_runtime
= 0;
558 else if (!strcmp (p
, "-fno-gnu-runtime"))
559 flag_next_runtime
= 1;
560 else if (!strcmp (p
, "-fnext-runtime"))
561 flag_next_runtime
= 1;
562 else if (!strcmp (p
, "-print-objc-runtime-info"))
563 print_struct_values
= 1;
564 #define CSTSTRCLASS "-fconstant-string-class="
565 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
566 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
567 error ("no class name specified as argument to -fconstant-string-class");
568 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
572 return c_decode_option (argc
, argv
);
579 define_decl (declarator
, declspecs
)
583 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
584 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
588 /* Return 1 if LHS and RHS are compatible types for assignment or
589 various other operations. Return 0 if they are incompatible, and
590 return -1 if we choose to not decide. When the operation is
591 REFLEXIVE, check for compatibility in either direction.
593 For statically typed objects, an assignment of the form `a' = `b'
597 `a' and `b' are the same class type, or
598 `a' and `b' are of class types A and B such that B is a descendant of A. */
601 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
605 return objc_comptypes (lhs
, rhs
, reflexive
);
609 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
617 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
619 p
= TREE_VALUE (rproto
);
621 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
623 if ((fnd
= lookup_method (class_meth
624 ? PROTOCOL_CLS_METHODS (p
)
625 : PROTOCOL_NST_METHODS (p
), sel_name
)))
627 else if (PROTOCOL_LIST (p
))
628 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
629 sel_name
, class_meth
);
633 ; /* An identifier...if we could not find a protocol. */
644 lookup_protocol_in_reflist (rproto_list
, lproto
)
650 /* Make sure the protocol is supported by the object on the rhs. */
651 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
654 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
656 p
= TREE_VALUE (rproto
);
658 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
663 else if (PROTOCOL_LIST (p
))
664 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
673 ; /* An identifier...if we could not find a protocol. */
679 /* Return 1 if LHS and RHS are compatible types for assignment
680 or various other operations. Return 0 if they are incompatible,
681 and return -1 if we choose to not decide. When the operation
682 is REFLEXIVE, check for compatibility in either direction. */
685 objc_comptypes (lhs
, rhs
, reflexive
)
690 /* New clause for protocols. */
692 if (TREE_CODE (lhs
) == POINTER_TYPE
693 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
694 && TREE_CODE (rhs
) == POINTER_TYPE
695 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
697 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
698 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
702 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
703 tree rproto
, rproto_list
;
708 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
710 /* Make sure the protocol is supported by the object
712 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
714 p
= TREE_VALUE (lproto
);
715 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
718 warning ("object does not conform to the `%s' protocol",
719 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
722 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
724 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
727 /* Make sure the protocol is supported by the object
729 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
731 p
= TREE_VALUE (lproto
);
733 rinter
= lookup_interface (rname
);
735 while (rinter
&& !rproto
)
739 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
740 /* If the underlying ObjC class does not have
741 protocols attached to it, perhaps there are
742 "one-off" protocols attached to the rhs?
743 E.g., 'id<MyProt> foo;'. */
745 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
746 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
748 /* Check for protocols adopted by categories. */
749 cat
= CLASS_CATEGORY_LIST (rinter
);
750 while (cat
&& !rproto
)
752 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
753 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
755 cat
= CLASS_CATEGORY_LIST (cat
);
758 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
762 warning ("class `%s' does not implement the `%s' protocol",
763 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
764 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
768 /* May change...based on whether there was any mismatch */
771 else if (rhs_is_proto
)
772 /* Lhs is not a protocol...warn if it is statically typed */
773 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
776 /* Defer to comptypes. */
780 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
781 ; /* Fall thru. This is the case we have been handling all along */
783 /* Defer to comptypes. */
786 /* `id' = `<class> *', `<class> *' = `id' */
788 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
789 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
792 /* `id' = `Class', `Class' = `id' */
794 else if ((TYPE_NAME (lhs
) == objc_object_id
795 && TYPE_NAME (rhs
) == objc_class_id
)
796 || (TYPE_NAME (lhs
) == objc_class_id
797 && TYPE_NAME (rhs
) == objc_object_id
))
800 /* `<class> *' = `<class> *' */
802 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
804 tree lname
= TYPE_NAME (lhs
);
805 tree rname
= TYPE_NAME (rhs
);
811 /* If the left hand side is a super class of the right hand side,
813 for (inter
= lookup_interface (rname
); inter
;
814 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
815 if (lname
== CLASS_SUPER_NAME (inter
))
818 /* Allow the reverse when reflexive. */
820 for (inter
= lookup_interface (lname
); inter
;
821 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
822 if (rname
== CLASS_SUPER_NAME (inter
))
828 /* Defer to comptypes. */
832 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
835 objc_check_decl (decl
)
838 tree type
= TREE_TYPE (decl
);
840 if (TREE_CODE (type
) == RECORD_TYPE
841 && TREE_STATIC_TEMPLATE (type
)
842 && type
!= constant_string_type
)
843 error_with_decl (decl
, "`%s' cannot be statically allocated");
847 maybe_objc_check_decl (decl
)
850 objc_check_decl (decl
);
853 /* Implement static typing. At this point, we know we have an interface. */
856 get_static_reference (interface
, protocols
)
860 tree type
= xref_tag (RECORD_TYPE
, interface
);
864 tree t
, m
= TYPE_MAIN_VARIANT (type
);
866 t
= copy_node (type
);
867 TYPE_BINFO (t
) = make_tree_vec (2);
869 /* Add this type to the chain of variants of TYPE. */
870 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
871 TYPE_NEXT_VARIANT (m
) = t
;
873 /* Look up protocols and install in lang specific list. Note
874 that the protocol list can have a different lifetime than T! */
875 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
877 /* This forces a new pointer type to be created later
878 (in build_pointer_type)...so that the new template
879 we just created will actually be used...what a hack! */
880 if (TYPE_POINTER_TO (t
))
881 TYPE_POINTER_TO (t
) = NULL_TREE
;
890 get_object_reference (protocols
)
893 tree type_decl
= lookup_name (objc_id_id
);
896 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
898 type
= TREE_TYPE (type_decl
);
899 if (TYPE_MAIN_VARIANT (type
) != id_type
)
900 warning ("unexpected type for `id' (%s)",
901 gen_declaration (type
, errbuf
));
905 error ("undefined type `id', please import <objc/objc.h>");
906 return error_mark_node
;
909 /* This clause creates a new pointer type that is qualified with
910 the protocol specification...this info is used later to do more
911 elaborate type checking. */
915 tree t
, m
= TYPE_MAIN_VARIANT (type
);
917 t
= copy_node (type
);
918 TYPE_BINFO (t
) = make_tree_vec (2);
920 /* Add this type to the chain of variants of TYPE. */
921 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
922 TYPE_NEXT_VARIANT (m
) = t
;
924 /* Look up protocols...and install in lang specific list */
925 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
927 /* This forces a new pointer type to be created later
928 (in build_pointer_type)...so that the new template
929 we just created will actually be used...what a hack! */
930 if (TYPE_POINTER_TO (t
))
931 TYPE_POINTER_TO (t
) = NULL_TREE
;
938 /* Check for circular dependencies in protocols. The arguments are
939 PROTO, the protocol to check, and LIST, a list of protocol it
943 check_protocol_recursively (proto
, list
)
949 for (p
= list
; p
; p
= TREE_CHAIN (p
))
951 tree pp
= TREE_VALUE (p
);
953 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
954 pp
= lookup_protocol (pp
);
957 fatal_error ("protocol `%s' has circular dependency",
958 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
960 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
965 lookup_and_install_protocols (protocols
)
970 tree return_value
= protocols
;
972 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
974 tree ident
= TREE_VALUE (proto
);
975 tree p
= lookup_protocol (ident
);
979 error ("cannot find protocol declaration for `%s'",
980 IDENTIFIER_POINTER (ident
));
982 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
984 return_value
= TREE_CHAIN (proto
);
988 /* Replace identifier with actual protocol node. */
989 TREE_VALUE (proto
) = p
;
997 /* Create and push a decl for a built-in external variable or field NAME.
999 TYPE is its data type. */
1002 create_builtin_decl (code
, type
, name
)
1003 enum tree_code code
;
1007 tree decl
= build_decl (code
, get_identifier (name
), type
);
1009 if (code
== VAR_DECL
)
1011 TREE_STATIC (decl
) = 1;
1012 make_decl_rtl (decl
, 0);
1016 DECL_ARTIFICIAL (decl
) = 1;
1020 /* Find the decl for the constant string class. */
1023 setup_string_decl ()
1025 if (!string_class_decl
)
1027 if (!constant_string_global_id
)
1028 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
1029 string_class_decl
= lookup_name (constant_string_global_id
);
1033 /* Purpose: "play" parser, creating/installing representations
1034 of the declarations that are required by Objective-C.
1038 type_spec--------->sc_spec
1039 (tree_list) (tree_list)
1042 identifier_node identifier_node */
1045 synth_module_prologue ()
1050 /* Defined in `objc.h' */
1051 objc_object_id
= get_identifier (TAG_OBJECT
);
1053 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1055 id_type
= build_pointer_type (objc_object_reference
);
1057 objc_id_id
= get_identifier (TYPE_ID
);
1058 objc_class_id
= get_identifier (TAG_CLASS
);
1060 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1061 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1062 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1064 /* Declare type of selector-objects that represent an operation name. */
1066 /* `struct objc_selector *' */
1068 = build_pointer_type (xref_tag (RECORD_TYPE
,
1069 get_identifier (TAG_SELECTOR
)));
1071 /* Forward declare type, or else the prototype for msgSendSuper will
1074 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1075 get_identifier (TAG_SUPER
)));
1078 /* id objc_msgSend (id, SEL, ...); */
1081 = build_function_type (id_type
,
1082 tree_cons (NULL_TREE
, id_type
,
1083 tree_cons (NULL_TREE
, selector_type
,
1086 if (! flag_next_runtime
)
1088 umsg_decl
= build_decl (FUNCTION_DECL
,
1089 get_identifier (TAG_MSGSEND
), temp_type
);
1090 DECL_EXTERNAL (umsg_decl
) = 1;
1091 TREE_PUBLIC (umsg_decl
) = 1;
1092 DECL_INLINE (umsg_decl
) = 1;
1093 DECL_ARTIFICIAL (umsg_decl
) = 1;
1095 make_decl_rtl (umsg_decl
, NULL
);
1096 pushdecl (umsg_decl
);
1099 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1101 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1104 = build_function_type (id_type
,
1105 tree_cons (NULL_TREE
, super_p
,
1106 tree_cons (NULL_TREE
, selector_type
,
1109 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1110 temp_type
, 0, NOT_BUILT_IN
, 0);
1112 /* id objc_getClass (const char *); */
1114 temp_type
= build_function_type (id_type
,
1115 tree_cons (NULL_TREE
,
1116 const_string_type_node
,
1117 tree_cons (NULL_TREE
, void_type_node
,
1121 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1123 /* id objc_getMetaClass (const char *); */
1125 objc_get_meta_class_decl
1126 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1128 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1130 if (! flag_next_runtime
)
1132 if (flag_typed_selectors
)
1134 /* Suppress outputting debug symbols, because
1135 dbxout_init hasn'r been called yet. */
1136 enum debug_info_type save_write_symbols
= write_symbols
;
1137 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
1138 write_symbols
= NO_DEBUG
;
1139 debug_hooks
= &do_nothing_debug_hooks
;
1141 build_selector_template ();
1142 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1144 write_symbols
= save_write_symbols
;
1145 debug_hooks
= save_hooks
;
1148 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1150 layout_type (temp_type
);
1151 UOBJC_SELECTOR_TABLE_decl
1152 = create_builtin_decl (VAR_DECL
, temp_type
,
1153 "_OBJC_SELECTOR_TABLE");
1155 /* Avoid warning when not sending messages. */
1156 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1159 generate_forward_declaration_to_string_table ();
1161 /* Forward declare constant_string_id and constant_string_type. */
1162 if (!constant_string_class_name
)
1163 constant_string_class_name
= default_constant_string_class_name
;
1165 constant_string_id
= get_identifier (constant_string_class_name
);
1166 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1169 /* Predefine the following data type:
1171 struct STRING_OBJECT_CLASS_NAME
1175 unsigned int length;
1179 build_string_class_template ()
1181 tree field_decl
, field_decl_chain
;
1183 field_decl
= create_builtin_decl (FIELD_DECL
, id_type
, "isa");
1184 field_decl_chain
= field_decl
;
1186 field_decl
= create_builtin_decl (FIELD_DECL
,
1187 build_pointer_type (char_type_node
),
1189 chainon (field_decl_chain
, field_decl
);
1191 field_decl
= create_builtin_decl (FIELD_DECL
, unsigned_type_node
, "length");
1192 chainon (field_decl_chain
, field_decl
);
1194 finish_struct (constant_string_type
, field_decl_chain
, NULL_TREE
);
1197 /* Custom build_string which sets TREE_TYPE! */
1200 my_build_string (len
, str
)
1204 return fix_string_type (build_string (len
, str
));
1207 /* Given a chain of STRING_CST's, build a static instance of
1208 NXConstantString which points at the concatenation of those strings.
1209 We place the string object in the __string_objects section of the
1210 __OBJC segment. The Objective-C runtime will initialize the isa
1211 pointers of the string objects to point at the NXConstantString
1215 build_objc_string_object (strings
)
1218 tree string
, initlist
, constructor
;
1221 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1223 error ("cannot find interface declaration for `%s'",
1224 IDENTIFIER_POINTER (constant_string_id
));
1225 return error_mark_node
;
1228 add_class_reference (constant_string_id
);
1230 if (TREE_CHAIN (strings
))
1232 varray_type vstrings
;
1233 VARRAY_TREE_INIT (vstrings
, 32, "strings");
1235 for (; strings
; strings
= TREE_CHAIN (strings
))
1236 VARRAY_PUSH_TREE (vstrings
, strings
);
1238 string
= combine_strings (vstrings
);
1240 VARRAY_FREE (vstrings
);
1245 string
= fix_string_type (string
);
1247 TREE_SET_CODE (string
, STRING_CST
);
1248 length
= TREE_STRING_LENGTH (string
) - 1;
1250 /* We could not properly create NXConstantString in synth_module_prologue,
1251 because that's called before debugging is initialized. Do it now. */
1252 if (TYPE_FIELDS (constant_string_type
) == NULL_TREE
)
1253 build_string_class_template ();
1255 /* & ((NXConstantString) { NULL, string, length }) */
1257 if (flag_next_runtime
)
1259 /* For the NeXT runtime, we can generate a literal reference
1260 to the string class, don't need to run a constructor. */
1261 setup_string_decl ();
1262 if (string_class_decl
== NULL_TREE
)
1264 error ("cannot find reference tag for class `%s'",
1265 IDENTIFIER_POINTER (constant_string_id
));
1266 return error_mark_node
;
1268 initlist
= build_tree_list
1270 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1274 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1278 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1280 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1281 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1283 if (!flag_next_runtime
)
1286 = objc_add_static_instance (constructor
, constant_string_type
);
1289 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1292 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1295 objc_add_static_instance (constructor
, class_decl
)
1296 tree constructor
, class_decl
;
1298 static int num_static_inst
;
1302 /* Find the list of static instances for the CLASS_DECL. Create one if
1304 for (chain
= &objc_static_instances
;
1305 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1306 chain
= &TREE_CHAIN (*chain
));
1309 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1310 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1313 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1314 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1315 DECL_COMMON (decl
) = 1;
1316 TREE_STATIC (decl
) = 1;
1317 DECL_ARTIFICIAL (decl
) = 1;
1318 DECL_INITIAL (decl
) = constructor
;
1320 /* We may be writing something else just now.
1321 Postpone till end of input. */
1322 DECL_DEFER_OUTPUT (decl
) = 1;
1323 pushdecl_top_level (decl
);
1324 rest_of_decl_compilation (decl
, 0, 1, 0);
1326 /* Add the DECL to the head of this CLASS' list. */
1327 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1332 /* Build a static constant CONSTRUCTOR
1333 with type TYPE and elements ELTS. */
1336 build_constructor (type
, elts
)
1339 tree constructor
, f
, e
;
1341 /* ??? Most of the places that we build constructors, we don't fill in
1342 the type of integers properly. Convert them all en masse. */
1343 if (TREE_CODE (type
) == ARRAY_TYPE
)
1345 f
= TREE_TYPE (type
);
1346 if (TREE_CODE (f
) == POINTER_TYPE
|| TREE_CODE (f
) == INTEGER_TYPE
)
1347 for (e
= elts
; e
; e
= TREE_CHAIN (e
))
1348 TREE_VALUE (e
) = convert (f
, TREE_VALUE (e
));
1352 f
= TYPE_FIELDS (type
);
1353 for (e
= elts
; e
; e
= TREE_CHAIN (e
), f
= TREE_CHAIN (f
))
1354 if (TREE_CODE (TREE_TYPE (f
)) == POINTER_TYPE
1355 || TREE_CODE (TREE_TYPE (f
)) == INTEGER_TYPE
)
1356 TREE_VALUE (e
) = convert (TREE_TYPE (f
), TREE_VALUE (e
));
1359 constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1360 TREE_CONSTANT (constructor
) = 1;
1361 TREE_STATIC (constructor
) = 1;
1362 TREE_READONLY (constructor
) = 1;
1367 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1369 /* Predefine the following data type:
1377 void *defs[cls_def_cnt + cat_def_cnt];
1381 build_objc_symtab_template ()
1383 tree field_decl
, field_decl_chain
, index
;
1385 objc_symtab_template
1386 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1388 /* long sel_ref_cnt; */
1390 field_decl
= create_builtin_decl (FIELD_DECL
,
1391 long_integer_type_node
,
1393 field_decl_chain
= field_decl
;
1397 field_decl
= create_builtin_decl (FIELD_DECL
,
1398 build_pointer_type (selector_type
),
1400 chainon (field_decl_chain
, field_decl
);
1402 /* short cls_def_cnt; */
1404 field_decl
= create_builtin_decl (FIELD_DECL
,
1405 short_integer_type_node
,
1407 chainon (field_decl_chain
, field_decl
);
1409 /* short cat_def_cnt; */
1411 field_decl
= create_builtin_decl (FIELD_DECL
,
1412 short_integer_type_node
,
1414 chainon (field_decl_chain
, field_decl
);
1416 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1418 if (!flag_next_runtime
)
1419 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1421 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1422 imp_count
== 0 && cat_count
== 0
1424 field_decl
= create_builtin_decl (FIELD_DECL
,
1425 build_array_type (ptr_type_node
, index
),
1427 chainon (field_decl_chain
, field_decl
);
1429 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1432 /* Create the initial value for the `defs' field of _objc_symtab.
1433 This is a CONSTRUCTOR. */
1436 init_def_list (type
)
1439 tree expr
, initlist
= NULL_TREE
;
1440 struct imp_entry
*impent
;
1443 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1445 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1447 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1448 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1453 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1455 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1457 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1458 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1462 if (!flag_next_runtime
)
1464 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1467 if (static_instances_decl
)
1468 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1470 expr
= build_int_2 (0, 0);
1472 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1475 return build_constructor (type
, nreverse (initlist
));
1478 /* Construct the initial value for all of _objc_symtab. */
1481 init_objc_symtab (type
)
1486 /* sel_ref_cnt = { ..., 5, ... } */
1488 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1490 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1492 if (flag_next_runtime
|| ! sel_ref_chain
)
1493 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1495 initlist
= tree_cons (NULL_TREE
,
1496 build_unary_op (ADDR_EXPR
,
1497 UOBJC_SELECTOR_TABLE_decl
, 1),
1500 /* cls_def_cnt = { ..., 5, ... } */
1502 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1504 /* cat_def_cnt = { ..., 5, ... } */
1506 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1508 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1510 if (imp_count
|| cat_count
|| static_instances_decl
)
1513 tree field
= TYPE_FIELDS (type
);
1514 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1516 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1520 return build_constructor (type
, nreverse (initlist
));
1523 /* Push forward-declarations of all the categories so that
1524 init_def_list can use them in a CONSTRUCTOR. */
1527 forward_declare_categories ()
1529 struct imp_entry
*impent
;
1530 tree sav
= objc_implementation_context
;
1532 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1534 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1536 /* Set an invisible arg to synth_id_with_class_suffix. */
1537 objc_implementation_context
= impent
->imp_context
;
1539 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1540 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context
)));
1543 objc_implementation_context
= sav
;
1546 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1547 and initialized appropriately. */
1550 generate_objc_symtab_decl ()
1554 if (!objc_category_template
)
1555 build_category_template ();
1557 /* forward declare categories */
1559 forward_declare_categories ();
1561 if (!objc_symtab_template
)
1562 build_objc_symtab_template ();
1564 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1566 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1567 tree_cons (NULL_TREE
,
1568 objc_symtab_template
, sc_spec
),
1572 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1573 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1574 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1575 finish_decl (UOBJC_SYMBOLS_decl
,
1576 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1581 init_module_descriptor (type
)
1584 tree initlist
, expr
;
1586 /* version = { 1, ... } */
1588 expr
= build_int_2 (OBJC_VERSION
, 0);
1589 initlist
= build_tree_list (NULL_TREE
, expr
);
1591 /* size = { ..., sizeof (struct objc_module), ... } */
1593 expr
= size_in_bytes (objc_module_template
);
1594 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1596 /* name = { ..., "foo.m", ... } */
1598 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1599 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1601 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1603 if (UOBJC_SYMBOLS_decl
)
1604 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1606 expr
= build_int_2 (0, 0);
1607 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1609 return build_constructor (type
, nreverse (initlist
));
1612 /* Write out the data structures to describe Objective C classes defined.
1613 If appropriate, compile and output a setup function to initialize them.
1614 Return a symbol_ref to the function to call to initialize the Objective C
1615 data structures for this file (and perhaps for other files also).
1617 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1620 build_module_descriptor ()
1622 tree decl_specs
, field_decl
, field_decl_chain
;
1624 objc_module_template
1625 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1629 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1630 field_decl
= get_identifier ("version");
1632 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1633 field_decl_chain
= field_decl
;
1637 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1638 field_decl
= get_identifier ("size");
1640 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1641 chainon (field_decl_chain
, field_decl
);
1645 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1646 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1648 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1649 chainon (field_decl_chain
, field_decl
);
1651 /* struct objc_symtab *symtab; */
1653 decl_specs
= get_identifier (UTAG_SYMTAB
);
1654 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1655 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1657 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1658 chainon (field_decl_chain
, field_decl
);
1660 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1662 /* Create an instance of "objc_module". */
1664 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1665 build_tree_list (NULL_TREE
,
1666 ridpointers
[(int) RID_STATIC
]));
1668 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1669 decl_specs
, 1, NULL_TREE
);
1671 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1672 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1673 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1675 finish_decl (UOBJC_MODULES_decl
,
1676 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1679 /* Mark the decl to avoid "defined but not used" warning. */
1680 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1682 /* Generate a constructor call for the module descriptor.
1683 This code was generated by reading the grammar rules
1684 of c-parse.in; Therefore, it may not be the most efficient
1685 way of generating the requisite code. */
1687 if (flag_next_runtime
)
1691 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1692 tree init_function_name
, init_function_decl
;
1694 /* Declare void __objc_execClass (void *); */
1696 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1697 execclass_decl
= build_decl (FUNCTION_DECL
,
1698 get_identifier (TAG_EXECCLASS
),
1699 build_function_type (void_type_node
,
1700 tree_cons (NULL_TREE
, ptr_type_node
,
1701 void_list_node_1
)));
1702 DECL_EXTERNAL (execclass_decl
) = 1;
1703 DECL_ARTIFICIAL (execclass_decl
) = 1;
1704 TREE_PUBLIC (execclass_decl
) = 1;
1705 pushdecl (execclass_decl
);
1706 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1707 assemble_external (execclass_decl
);
1709 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1711 init_function_name
= get_file_function_name ('I');
1712 start_function (void_list_node_1
,
1713 build_nt (CALL_EXPR
, init_function_name
,
1714 tree_cons (NULL_TREE
, NULL_TREE
,
1718 store_parm_decls ();
1720 init_function_decl
= current_function_decl
;
1721 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1722 TREE_USED (init_function_decl
) = 1;
1723 /* Don't let this one be deferred. */
1724 DECL_INLINE (init_function_decl
) = 0;
1725 DECL_UNINLINABLE (init_function_decl
) = 1;
1726 current_function_cannot_inline
1727 = "static constructors and destructors cannot be inlined";
1730 = build_tree_list (NULL_TREE
,
1731 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1732 decelerator
= build_function_call (execclass_decl
, parms
);
1734 c_expand_expr_stmt (decelerator
);
1736 finish_function (0, 0);
1738 return XEXP (DECL_RTL (init_function_decl
), 0);
1742 /* extern const char _OBJC_STRINGS[]; */
1745 generate_forward_declaration_to_string_table ()
1747 tree sc_spec
, decl_specs
, expr_decl
;
1749 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1750 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1753 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1755 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1758 /* Return the DECL of the string IDENT in the SECTION. */
1761 get_objc_string_decl (ident
, section
)
1763 enum string_section section
;
1767 if (section
== class_names
)
1768 chain
= class_names_chain
;
1769 else if (section
== meth_var_names
)
1770 chain
= meth_var_names_chain
;
1771 else if (section
== meth_var_types
)
1772 chain
= meth_var_types_chain
;
1776 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1777 if (TREE_VALUE (chain
) == ident
)
1778 return (TREE_PURPOSE (chain
));
1784 /* Output references to all statically allocated objects. Return the DECL
1785 for the array built. */
1788 generate_static_references ()
1790 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1791 tree class_name
, class, decl
, initlist
;
1792 tree cl_chain
, in_chain
, type
;
1793 int num_inst
, num_class
;
1796 if (flag_next_runtime
)
1799 for (cl_chain
= objc_static_instances
, num_class
= 0;
1800 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1802 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1803 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1805 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1806 ident
= get_identifier (buf
);
1808 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1809 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1810 build_tree_list (NULL_TREE
,
1811 ridpointers
[(int) RID_STATIC
]));
1812 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1813 DECL_CONTEXT (decl
) = 0;
1814 DECL_ARTIFICIAL (decl
) = 1;
1816 /* Output {class_name, ...}. */
1817 class = TREE_VALUE (cl_chain
);
1818 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1819 initlist
= build_tree_list (NULL_TREE
,
1820 build_unary_op (ADDR_EXPR
, class_name
, 1));
1822 /* Output {..., instance, ...}. */
1823 for (in_chain
= TREE_PURPOSE (cl_chain
);
1824 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1826 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1827 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1830 /* Output {..., NULL}. */
1831 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1833 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1834 finish_decl (decl
, expr
, NULL_TREE
);
1835 TREE_USED (decl
) = 1;
1837 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1838 decl
= build_decl (VAR_DECL
, ident
, type
);
1839 TREE_USED (decl
) = 1;
1840 TREE_STATIC (decl
) = 1;
1842 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1845 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1846 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1847 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1848 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1849 build_tree_list (NULL_TREE
,
1850 ridpointers
[(int) RID_STATIC
]));
1851 static_instances_decl
1852 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1853 TREE_USED (static_instances_decl
) = 1;
1854 DECL_CONTEXT (static_instances_decl
) = 0;
1855 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1856 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1858 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1861 /* Output all strings. */
1866 tree sc_spec
, decl_specs
, expr_decl
;
1867 tree chain
, string_expr
;
1870 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1872 string
= TREE_VALUE (chain
);
1873 decl
= TREE_PURPOSE (chain
);
1875 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1876 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1877 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1878 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1879 DECL_CONTEXT (decl
) = NULL_TREE
;
1880 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1881 IDENTIFIER_POINTER (string
));
1882 finish_decl (decl
, string_expr
, NULL_TREE
);
1885 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1887 string
= TREE_VALUE (chain
);
1888 decl
= TREE_PURPOSE (chain
);
1890 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1891 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1892 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1893 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1894 DECL_CONTEXT (decl
) = NULL_TREE
;
1895 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1896 IDENTIFIER_POINTER (string
));
1897 finish_decl (decl
, string_expr
, NULL_TREE
);
1900 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1902 string
= TREE_VALUE (chain
);
1903 decl
= TREE_PURPOSE (chain
);
1905 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1906 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1907 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1908 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1909 DECL_CONTEXT (decl
) = NULL_TREE
;
1910 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1911 IDENTIFIER_POINTER (string
));
1912 finish_decl (decl
, string_expr
, NULL_TREE
);
1917 build_selector_reference_decl ()
1923 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1925 ident
= get_identifier (buf
);
1927 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1928 DECL_EXTERNAL (decl
) = 1;
1929 TREE_PUBLIC (decl
) = 1;
1930 TREE_USED (decl
) = 1;
1931 TREE_READONLY (decl
) = 1;
1932 DECL_ARTIFICIAL (decl
) = 1;
1933 DECL_CONTEXT (decl
) = 0;
1935 make_decl_rtl (decl
, 0);
1936 pushdecl_top_level (decl
);
1941 /* Just a handy wrapper for add_objc_string. */
1944 build_selector (ident
)
1947 tree expr
= add_objc_string (ident
, meth_var_names
);
1948 if (flag_typed_selectors
)
1951 return build_c_cast (selector_type
, expr
); /* cast! */
1955 build_selector_translation_table ()
1957 tree sc_spec
, decl_specs
;
1958 tree chain
, initlist
= NULL_TREE
;
1960 tree decl
= NULL_TREE
, var_decl
, name
;
1962 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1966 expr
= build_selector (TREE_VALUE (chain
));
1968 if (flag_next_runtime
)
1970 name
= DECL_NAME (TREE_PURPOSE (chain
));
1972 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1974 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1975 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
1979 /* The `decl' that is returned from start_decl is the one that we
1980 forward declared in `build_selector_reference' */
1981 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
1984 /* add one for the '\0' character */
1985 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
1987 if (flag_next_runtime
)
1988 finish_decl (decl
, expr
, NULL_TREE
);
1991 if (flag_typed_selectors
)
1993 tree eltlist
= NULL_TREE
;
1994 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
1995 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
1996 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
1997 expr
= build_constructor (objc_selector_template
,
1998 nreverse (eltlist
));
2000 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2005 if (! flag_next_runtime
)
2007 /* Cause the variable and its initial value to be actually output. */
2008 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2009 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2010 /* NULL terminate the list and fix the decl for output. */
2011 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2012 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2013 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2014 nreverse (initlist
));
2015 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2016 current_function_decl
= NULL_TREE
;
2021 get_proto_encoding (proto
)
2029 if (! METHOD_ENCODING (proto
))
2031 tmp_decl
= build_tmp_function_decl ();
2032 hack_method_prototype (proto
, tmp_decl
);
2033 encoding
= encode_method_prototype (proto
, tmp_decl
);
2034 METHOD_ENCODING (proto
) = encoding
;
2037 encoding
= METHOD_ENCODING (proto
);
2039 return add_objc_string (encoding
, meth_var_types
);
2042 return build_int_2 (0, 0);
2045 /* sel_ref_chain is a list whose "value" fields will be instances of
2046 identifier_node that represent the selector. */
2049 build_typed_selector_reference (ident
, proto
)
2052 tree
*chain
= &sel_ref_chain
;
2058 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2059 goto return_at_index
;
2062 chain
= &TREE_CHAIN (*chain
);
2065 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2068 expr
= build_unary_op (ADDR_EXPR
,
2069 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2070 build_int_2 (index
, 0)),
2072 return build_c_cast (selector_type
, expr
);
2076 build_selector_reference (ident
)
2079 tree
*chain
= &sel_ref_chain
;
2085 if (TREE_VALUE (*chain
) == ident
)
2086 return (flag_next_runtime
2087 ? TREE_PURPOSE (*chain
)
2088 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2089 build_int_2 (index
, 0)));
2092 chain
= &TREE_CHAIN (*chain
);
2095 expr
= build_selector_reference_decl ();
2097 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2099 return (flag_next_runtime
2101 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2102 build_int_2 (index
, 0)));
2106 build_class_reference_decl ()
2112 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2114 ident
= get_identifier (buf
);
2116 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2117 DECL_EXTERNAL (decl
) = 1;
2118 TREE_PUBLIC (decl
) = 1;
2119 TREE_USED (decl
) = 1;
2120 TREE_READONLY (decl
) = 1;
2121 DECL_CONTEXT (decl
) = 0;
2122 DECL_ARTIFICIAL (decl
) = 1;
2124 make_decl_rtl (decl
, 0);
2125 pushdecl_top_level (decl
);
2130 /* Create a class reference, but don't create a variable to reference
2134 add_class_reference (ident
)
2139 if ((chain
= cls_ref_chain
))
2144 if (ident
== TREE_VALUE (chain
))
2148 chain
= TREE_CHAIN (chain
);
2152 /* Append to the end of the list */
2153 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2156 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2159 /* Get a class reference, creating it if necessary. Also create the
2160 reference variable. */
2163 get_class_reference (ident
)
2166 if (flag_next_runtime
)
2171 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2172 if (TREE_VALUE (*chain
) == ident
)
2174 if (! TREE_PURPOSE (*chain
))
2175 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2177 return TREE_PURPOSE (*chain
);
2180 decl
= build_class_reference_decl ();
2181 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2188 add_class_reference (ident
);
2190 params
= build_tree_list (NULL_TREE
,
2191 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2192 IDENTIFIER_POINTER (ident
)));
2194 assemble_external (objc_get_class_decl
);
2195 return build_function_call (objc_get_class_decl
, params
);
2199 /* For each string section we have a chain which maps identifier nodes
2200 to decls for the strings. */
2203 add_objc_string (ident
, section
)
2205 enum string_section section
;
2209 if (section
== class_names
)
2210 chain
= &class_names_chain
;
2211 else if (section
== meth_var_names
)
2212 chain
= &meth_var_names_chain
;
2213 else if (section
== meth_var_types
)
2214 chain
= &meth_var_types_chain
;
2220 if (TREE_VALUE (*chain
) == ident
)
2221 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2223 chain
= &TREE_CHAIN (*chain
);
2226 decl
= build_objc_string_decl (section
);
2228 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2230 return build_unary_op (ADDR_EXPR
, decl
, 1);
2234 build_objc_string_decl (section
)
2235 enum string_section section
;
2239 static int class_names_idx
= 0;
2240 static int meth_var_names_idx
= 0;
2241 static int meth_var_types_idx
= 0;
2243 if (section
== class_names
)
2244 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2245 else if (section
== meth_var_names
)
2246 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2247 else if (section
== meth_var_types
)
2248 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2250 ident
= get_identifier (buf
);
2252 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2253 DECL_EXTERNAL (decl
) = 1;
2254 TREE_PUBLIC (decl
) = 1;
2255 TREE_USED (decl
) = 1;
2256 TREE_READONLY (decl
) = 1;
2257 TREE_CONSTANT (decl
) = 1;
2258 DECL_CONTEXT (decl
) = 0;
2259 DECL_ARTIFICIAL (decl
) = 1;
2261 make_decl_rtl (decl
, 0);
2262 pushdecl_top_level (decl
);
2269 objc_declare_alias (alias_ident
, class_ident
)
2273 if (is_class_name (class_ident
) != class_ident
)
2274 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2275 else if (is_class_name (alias_ident
))
2276 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2278 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2282 objc_declare_class (ident_list
)
2287 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2289 tree ident
= TREE_VALUE (list
);
2292 if ((decl
= lookup_name (ident
)))
2294 error ("`%s' redeclared as different kind of symbol",
2295 IDENTIFIER_POINTER (ident
));
2296 error_with_decl (decl
, "previous declaration of `%s'");
2299 if (! is_class_name (ident
))
2301 tree record
= xref_tag (RECORD_TYPE
, ident
);
2302 TREE_STATIC_TEMPLATE (record
) = 1;
2303 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2309 is_class_name (ident
)
2314 if (lookup_interface (ident
))
2317 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2319 if (ident
== TREE_VALUE (chain
))
2323 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2325 if (ident
== TREE_VALUE (chain
))
2326 return TREE_PURPOSE (chain
);
2333 lookup_interface (ident
)
2338 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2340 if (ident
== CLASS_NAME (chain
))
2347 objc_copy_list (list
, head
)
2351 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2355 tail
= copy_node (list
);
2357 /* The following statement fixes a bug when inheriting instance
2358 variables that are declared to be bitfields. finish_struct
2359 expects to find the width of the bitfield in DECL_INITIAL. */
2360 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2361 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2363 newlist
= chainon (newlist
, tail
);
2364 list
= TREE_CHAIN (list
);
2371 /* Used by: build_private_template, get_class_ivars, and
2372 continue_class. COPY is 1 when called from @defs. In this case
2373 copy all fields. Otherwise don't copy leaf ivars since we rely on
2374 them being side-effected exactly once by finish_struct. */
2377 build_ivar_chain (interface
, copy
)
2381 tree my_name
, super_name
, ivar_chain
;
2383 my_name
= CLASS_NAME (interface
);
2384 super_name
= CLASS_SUPER_NAME (interface
);
2386 /* Possibly copy leaf ivars. */
2388 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2390 ivar_chain
= CLASS_IVARS (interface
);
2395 tree super_interface
= lookup_interface (super_name
);
2397 if (!super_interface
)
2399 /* fatal did not work with 2 args...should fix */
2400 error ("cannot find interface declaration for `%s', superclass of `%s'",
2401 IDENTIFIER_POINTER (super_name
),
2402 IDENTIFIER_POINTER (my_name
));
2403 exit (FATAL_EXIT_CODE
);
2406 if (super_interface
== interface
)
2407 fatal_error ("circular inheritance in interface declaration for `%s'",
2408 IDENTIFIER_POINTER (super_name
));
2410 interface
= super_interface
;
2411 my_name
= CLASS_NAME (interface
);
2412 super_name
= CLASS_SUPER_NAME (interface
);
2414 op1
= CLASS_IVARS (interface
);
2417 tree head
, tail
= objc_copy_list (op1
, &head
);
2419 /* Prepend super class ivars...make a copy of the list, we
2420 do not want to alter the original. */
2421 TREE_CHAIN (tail
) = ivar_chain
;
2428 /* struct <classname> {
2429 struct objc_class *isa;
2434 build_private_template (class)
2439 if (CLASS_STATIC_TEMPLATE (class))
2441 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2442 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2446 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2448 ivar_context
= build_ivar_chain (class, 0);
2450 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2452 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2454 /* mark this record as class template - for class type checking */
2455 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2459 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2461 build1 (INDIRECT_REF
, NULL_TREE
,
2464 return ivar_context
;
2467 /* Begin code generation for protocols... */
2469 /* struct objc_protocol {
2470 char *protocol_name;
2471 struct objc_protocol **protocol_list;
2472 struct objc_method_desc *instance_methods;
2473 struct objc_method_desc *class_methods;
2477 build_protocol_template ()
2479 tree decl_specs
, field_decl
, field_decl_chain
;
2482 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2484 /* struct objc_class *isa; */
2486 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2487 get_identifier (UTAG_CLASS
)));
2488 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2490 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2491 field_decl_chain
= field_decl
;
2493 /* char *protocol_name; */
2495 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2497 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2499 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2500 chainon (field_decl_chain
, field_decl
);
2502 /* struct objc_protocol **protocol_list; */
2504 decl_specs
= build_tree_list (NULL_TREE
, template);
2506 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2507 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2509 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2510 chainon (field_decl_chain
, field_decl
);
2512 /* struct objc_method_list *instance_methods; */
2515 = build_tree_list (NULL_TREE
,
2516 xref_tag (RECORD_TYPE
,
2517 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2519 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2521 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2522 chainon (field_decl_chain
, field_decl
);
2524 /* struct objc_method_list *class_methods; */
2527 = build_tree_list (NULL_TREE
,
2528 xref_tag (RECORD_TYPE
,
2529 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2531 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2533 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2534 chainon (field_decl_chain
, field_decl
);
2536 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2540 build_descriptor_table_initializer (type
, entries
)
2544 tree initlist
= NULL_TREE
;
2548 tree eltlist
= NULL_TREE
;
2551 = tree_cons (NULL_TREE
,
2552 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2554 = tree_cons (NULL_TREE
,
2555 add_objc_string (METHOD_ENCODING (entries
),
2560 = tree_cons (NULL_TREE
,
2561 build_constructor (type
, nreverse (eltlist
)), initlist
);
2563 entries
= TREE_CHAIN (entries
);
2567 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2570 /* struct objc_method_prototype_list {
2572 struct objc_method_prototype {
2579 build_method_prototype_list_template (list_type
, size
)
2583 tree objc_ivar_list_record
;
2584 tree decl_specs
, field_decl
, field_decl_chain
;
2586 /* Generate an unnamed struct definition. */
2588 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2590 /* int method_count; */
2592 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2593 field_decl
= get_identifier ("method_count");
2596 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2597 field_decl_chain
= field_decl
;
2599 /* struct objc_method method_list[]; */
2601 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2602 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2603 build_int_2 (size
, 0));
2606 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2607 chainon (field_decl_chain
, field_decl
);
2609 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2611 return objc_ivar_list_record
;
2615 build_method_prototype_template ()
2618 tree decl_specs
, field_decl
, field_decl_chain
;
2621 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2623 /* struct objc_selector *_cmd; */
2624 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2625 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2626 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2629 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2630 field_decl_chain
= field_decl
;
2632 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2634 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2636 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2637 chainon (field_decl_chain
, field_decl
);
2639 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2641 return proto_record
;
2644 /* True if last call to forwarding_offset yielded a register offset. */
2645 static int offset_is_register
;
2648 forwarding_offset (parm
)
2651 int offset_in_bytes
;
2653 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2655 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2657 /* ??? Here we assume that the parm address is indexed
2658 off the frame pointer or arg pointer.
2659 If that is not true, we produce meaningless results,
2660 but do not crash. */
2661 if (GET_CODE (addr
) == PLUS
2662 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2663 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2665 offset_in_bytes
= 0;
2667 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2668 offset_is_register
= 0;
2670 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2672 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2673 offset_in_bytes
= apply_args_register_offset (regno
);
2674 offset_is_register
= 1;
2679 /* This is the case where the parm is passed as an int or double
2680 and it is converted to a char, short or float and stored back
2681 in the parmlist. In this case, describe the parm
2682 with the variable's declared type, and adjust the address
2683 if the least significant bytes (which we are using) are not
2685 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2686 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2687 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2689 return offset_in_bytes
;
2693 encode_method_prototype (method_decl
, func_decl
)
2700 HOST_WIDE_INT max_parm_end
= 0;
2704 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2705 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2708 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2709 obstack_object_size (&util_obstack
),
2710 OBJC_ENCODE_INLINE_DEFS
);
2713 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2714 parms
= TREE_CHAIN (parms
))
2716 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2717 + int_size_in_bytes (TREE_TYPE (parms
)));
2719 if (!offset_is_register
&& max_parm_end
< parm_end
)
2720 max_parm_end
= parm_end
;
2723 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2725 sprintf (buf
, "%d", stack_size
);
2726 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2728 user_args
= METHOD_SEL_ARGS (method_decl
);
2730 /* Argument types. */
2731 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2732 parms
= TREE_CHAIN (parms
), i
++)
2734 /* Process argument qualifiers for user supplied arguments. */
2737 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2738 user_args
= TREE_CHAIN (user_args
);
2742 encode_type (TREE_TYPE (parms
),
2743 obstack_object_size (&util_obstack
),
2744 OBJC_ENCODE_INLINE_DEFS
);
2746 /* Compute offset. */
2747 sprintf (buf
, "%d", forwarding_offset (parms
));
2749 /* Indicate register. */
2750 if (offset_is_register
)
2751 obstack_1grow (&util_obstack
, '+');
2753 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2756 obstack_1grow (&util_obstack
, '\0');
2757 result
= get_identifier (obstack_finish (&util_obstack
));
2758 obstack_free (&util_obstack
, util_firstobj
);
2763 generate_descriptor_table (type
, name
, size
, list
, proto
)
2770 tree sc_spec
, decl_specs
, decl
, initlist
;
2772 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2773 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2775 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2776 decl_specs
, 1, NULL_TREE
);
2777 DECL_CONTEXT (decl
) = NULL_TREE
;
2779 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2780 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2782 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2789 generate_method_descriptors (protocol
)
2792 tree initlist
, chain
, method_list_template
;
2793 tree cast
, variable_length_type
;
2796 if (!objc_method_prototype_template
)
2797 objc_method_prototype_template
= build_method_prototype_template ();
2799 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2800 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2802 variable_length_type
= groktypename (cast
);
2804 chain
= PROTOCOL_CLS_METHODS (protocol
);
2807 size
= list_length (chain
);
2809 method_list_template
2810 = build_method_prototype_list_template (objc_method_prototype_template
,
2814 = build_descriptor_table_initializer (objc_method_prototype_template
,
2817 UOBJC_CLASS_METHODS_decl
2818 = generate_descriptor_table (method_list_template
,
2819 "_OBJC_PROTOCOL_CLASS_METHODS",
2820 size
, initlist
, protocol
);
2821 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2824 UOBJC_CLASS_METHODS_decl
= 0;
2826 chain
= PROTOCOL_NST_METHODS (protocol
);
2829 size
= list_length (chain
);
2831 method_list_template
2832 = build_method_prototype_list_template (objc_method_prototype_template
,
2835 = build_descriptor_table_initializer (objc_method_prototype_template
,
2838 UOBJC_INSTANCE_METHODS_decl
2839 = generate_descriptor_table (method_list_template
,
2840 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2841 size
, initlist
, protocol
);
2842 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2845 UOBJC_INSTANCE_METHODS_decl
= 0;
2848 /* Generate a temporary FUNCTION_DECL node to be used in
2849 hack_method_prototype below. */
2852 build_tmp_function_decl ()
2854 tree decl_specs
, expr_decl
, parms
;
2858 /* struct objc_object *objc_xxx (id, SEL, ...); */
2860 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2861 push_parm_decl (build_tree_list
2862 (build_tree_list (decl_specs
,
2863 build1 (INDIRECT_REF
, NULL_TREE
,
2867 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2868 get_identifier (TAG_SELECTOR
)));
2869 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2871 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2873 parms
= get_parm_info (0);
2876 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2877 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2878 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2879 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
2881 return define_decl (expr_decl
, decl_specs
);
2884 /* Generate the prototypes for protocol methods. This is used to
2885 generate method encodings for these.
2887 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2888 a decl node to be used. This is also where the return value is
2892 hack_method_prototype (nst_methods
, tmp_decl
)
2899 /* Hack to avoid problem with static typing of self arg. */
2900 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2901 start_method_def (nst_methods
);
2902 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2904 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
2905 parms
= get_parm_info (0); /* we have a `, ...' */
2907 parms
= get_parm_info (1); /* place a `void_at_end' */
2909 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2911 /* Usually called from store_parm_decls -> init_function_start. */
2913 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2915 if (current_function_decl
)
2917 current_function_decl
= tmp_decl
;
2920 /* Code taken from start_function. */
2921 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2922 /* Promote the value to int before returning it. */
2923 if (TREE_CODE (restype
) == INTEGER_TYPE
2924 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
2925 restype
= integer_type_node
;
2926 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
2929 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
2930 DECL_CONTEXT (parm
) = tmp_decl
;
2932 init_function_start (tmp_decl
, "objc-act", 0);
2934 /* Typically called from expand_function_start for function definitions. */
2935 assign_parms (tmp_decl
);
2937 /* install return type */
2938 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
2940 current_function_decl
= NULL
;
2944 generate_protocol_references (plist
)
2949 /* Forward declare protocols referenced. */
2950 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
2952 tree proto
= TREE_VALUE (lproto
);
2954 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
2955 && PROTOCOL_NAME (proto
))
2957 if (! PROTOCOL_FORWARD_DECL (proto
))
2958 build_protocol_reference (proto
);
2960 if (PROTOCOL_LIST (proto
))
2961 generate_protocol_references (PROTOCOL_LIST (proto
));
2967 generate_protocols ()
2969 tree p
, tmp_decl
, encoding
;
2970 tree sc_spec
, decl_specs
, decl
;
2971 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
2974 tmp_decl
= build_tmp_function_decl ();
2976 if (! objc_protocol_template
)
2977 objc_protocol_template
= build_protocol_template ();
2979 /* If a protocol was directly referenced, pull in indirect references. */
2980 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
2981 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
2982 generate_protocol_references (PROTOCOL_LIST (p
));
2984 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
2986 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
2987 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
2989 /* If protocol wasn't referenced, don't generate any code. */
2990 if (! PROTOCOL_FORWARD_DECL (p
))
2993 /* Make sure we link in the Protocol class. */
2994 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
2998 if (! METHOD_ENCODING (nst_methods
))
3000 hack_method_prototype (nst_methods
, tmp_decl
);
3001 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3002 METHOD_ENCODING (nst_methods
) = encoding
;
3004 nst_methods
= TREE_CHAIN (nst_methods
);
3009 if (! METHOD_ENCODING (cls_methods
))
3011 hack_method_prototype (cls_methods
, tmp_decl
);
3012 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3013 METHOD_ENCODING (cls_methods
) = encoding
;
3016 cls_methods
= TREE_CHAIN (cls_methods
);
3018 generate_method_descriptors (p
);
3020 if (PROTOCOL_LIST (p
))
3021 refs_decl
= generate_protocol_list (p
);
3025 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3027 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3029 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3031 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3032 decl_specs
, 1, NULL_TREE
);
3034 DECL_CONTEXT (decl
) = NULL_TREE
;
3036 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3042 (build_tree_list (build_tree_list (NULL_TREE
,
3043 objc_protocol_template
),
3044 build1 (INDIRECT_REF
, NULL_TREE
,
3045 build1 (INDIRECT_REF
, NULL_TREE
,
3048 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3049 TREE_TYPE (refs_expr
) = cast_type2
;
3052 refs_expr
= build_int_2 (0, 0);
3054 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3055 by generate_method_descriptors, which is called above. */
3056 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3057 protocol_name_expr
, refs_expr
,
3058 UOBJC_INSTANCE_METHODS_decl
,
3059 UOBJC_CLASS_METHODS_decl
);
3060 finish_decl (decl
, initlist
, NULL_TREE
);
3062 /* Mark the decl as used to avoid "defined but not used" warning. */
3063 TREE_USED (decl
) = 1;
3068 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3069 instance_methods
, class_methods
)
3073 tree instance_methods
;
3076 tree initlist
= NULL_TREE
, expr
;
3079 cast_type
= groktypename
3081 (build_tree_list (NULL_TREE
,
3082 xref_tag (RECORD_TYPE
,
3083 get_identifier (UTAG_CLASS
))),
3084 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3086 /* Filling the "isa" in with one allows the runtime system to
3087 detect that the version change...should remove before final release. */
3089 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3090 TREE_TYPE (expr
) = cast_type
;
3091 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3092 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3093 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3095 if (!instance_methods
)
3096 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3099 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3100 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3104 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3107 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3108 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3111 return build_constructor (type
, nreverse (initlist
));
3114 /* struct objc_category {
3115 char *category_name;
3117 struct objc_method_list *instance_methods;
3118 struct objc_method_list *class_methods;
3119 struct objc_protocol_list *protocols;
3123 build_category_template ()
3125 tree decl_specs
, field_decl
, field_decl_chain
;
3127 objc_category_template
= start_struct (RECORD_TYPE
,
3128 get_identifier (UTAG_CATEGORY
));
3129 /* char *category_name; */
3131 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3133 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3135 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3136 field_decl_chain
= field_decl
;
3138 /* char *class_name; */
3140 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3141 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3143 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3144 chainon (field_decl_chain
, field_decl
);
3146 /* struct objc_method_list *instance_methods; */
3148 decl_specs
= build_tree_list (NULL_TREE
,
3149 xref_tag (RECORD_TYPE
,
3150 get_identifier (UTAG_METHOD_LIST
)));
3152 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3154 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3155 chainon (field_decl_chain
, field_decl
);
3157 /* struct objc_method_list *class_methods; */
3159 decl_specs
= build_tree_list (NULL_TREE
,
3160 xref_tag (RECORD_TYPE
,
3161 get_identifier (UTAG_METHOD_LIST
)));
3163 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3165 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3166 chainon (field_decl_chain
, field_decl
);
3168 /* struct objc_protocol **protocol_list; */
3170 decl_specs
= build_tree_list (NULL_TREE
,
3171 xref_tag (RECORD_TYPE
,
3172 get_identifier (UTAG_PROTOCOL
)));
3174 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3175 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3177 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3178 chainon (field_decl_chain
, field_decl
);
3180 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3183 /* struct objc_selector {
3189 build_selector_template ()
3192 tree decl_specs
, field_decl
, field_decl_chain
;
3194 objc_selector_template
3195 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3199 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3200 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3202 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3203 field_decl_chain
= field_decl
;
3205 /* char *sel_type; */
3207 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3208 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3210 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3211 chainon (field_decl_chain
, field_decl
);
3213 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3216 /* struct objc_class {
3217 struct objc_class *isa;
3218 struct objc_class *super_class;
3223 struct objc_ivar_list *ivars;
3224 struct objc_method_list *methods;
3225 if (flag_next_runtime)
3226 struct objc_cache *cache;
3228 struct sarray *dtable;
3229 struct objc_class *subclass_list;
3230 struct objc_class *sibling_class;
3232 struct objc_protocol_list *protocols;
3233 void *gc_object_type;
3237 build_class_template ()
3239 tree decl_specs
, field_decl
, field_decl_chain
;
3242 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3244 /* struct objc_class *isa; */
3246 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3247 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3249 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3250 field_decl_chain
= field_decl
;
3252 /* struct objc_class *super_class; */
3254 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3256 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3258 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3259 chainon (field_decl_chain
, field_decl
);
3263 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3264 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3266 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3267 chainon (field_decl_chain
, field_decl
);
3271 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3272 field_decl
= get_identifier ("version");
3274 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3275 chainon (field_decl_chain
, field_decl
);
3279 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3280 field_decl
= get_identifier ("info");
3282 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3283 chainon (field_decl_chain
, field_decl
);
3285 /* long instance_size; */
3287 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3288 field_decl
= get_identifier ("instance_size");
3290 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3291 chainon (field_decl_chain
, field_decl
);
3293 /* struct objc_ivar_list *ivars; */
3295 decl_specs
= build_tree_list (NULL_TREE
,
3296 xref_tag (RECORD_TYPE
,
3297 get_identifier (UTAG_IVAR_LIST
)));
3298 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3300 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3301 chainon (field_decl_chain
, field_decl
);
3303 /* struct objc_method_list *methods; */
3305 decl_specs
= build_tree_list (NULL_TREE
,
3306 xref_tag (RECORD_TYPE
,
3307 get_identifier (UTAG_METHOD_LIST
)));
3308 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3310 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3311 chainon (field_decl_chain
, field_decl
);
3313 if (flag_next_runtime
)
3315 /* struct objc_cache *cache; */
3317 decl_specs
= build_tree_list (NULL_TREE
,
3318 xref_tag (RECORD_TYPE
,
3319 get_identifier ("objc_cache")));
3320 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3321 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3322 decl_specs
, NULL_TREE
);
3323 chainon (field_decl_chain
, field_decl
);
3327 /* struct sarray *dtable; */
3329 decl_specs
= build_tree_list (NULL_TREE
,
3330 xref_tag (RECORD_TYPE
,
3331 get_identifier ("sarray")));
3332 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3333 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3334 decl_specs
, NULL_TREE
);
3335 chainon (field_decl_chain
, field_decl
);
3337 /* struct objc_class *subclass_list; */
3339 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3341 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3342 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3343 decl_specs
, NULL_TREE
);
3344 chainon (field_decl_chain
, field_decl
);
3346 /* struct objc_class *sibling_class; */
3348 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3350 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3351 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3352 decl_specs
, NULL_TREE
);
3353 chainon (field_decl_chain
, field_decl
);
3356 /* struct objc_protocol **protocol_list; */
3358 decl_specs
= build_tree_list (NULL_TREE
,
3359 xref_tag (RECORD_TYPE
,
3360 get_identifier (UTAG_PROTOCOL
)));
3362 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3364 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3365 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3366 decl_specs
, NULL_TREE
);
3367 chainon (field_decl_chain
, field_decl
);
3371 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3372 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3374 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3375 chainon (field_decl_chain
, field_decl
);
3377 /* void *gc_object_type; */
3379 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3380 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3382 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3383 chainon (field_decl_chain
, field_decl
);
3385 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3388 /* Generate appropriate forward declarations for an implementation. */
3391 synth_forward_declarations ()
3393 tree sc_spec
, decl_specs
, an_id
;
3395 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3397 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context
);
3399 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3400 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3401 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3402 TREE_USED (UOBJC_CLASS_decl
) = 1;
3403 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3405 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3407 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3408 objc_implementation_context
);
3410 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3411 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3412 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3414 /* Pre-build the following entities - for speed/convenience. */
3416 an_id
= get_identifier ("super_class");
3417 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3418 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3422 error_with_ivar (message
, decl
, rawdecl
)
3423 const char *message
;
3429 report_error_function (DECL_SOURCE_FILE (decl
));
3431 error_with_file_and_line (DECL_SOURCE_FILE (decl
),
3432 DECL_SOURCE_LINE (decl
),
3434 message
, gen_declaration (rawdecl
, errbuf
));
3438 #define USERTYPE(t) \
3439 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3440 || TREE_CODE (t) == ENUMERAL_TYPE)
3443 check_ivars (inter
, imp
)
3447 tree intdecls
= CLASS_IVARS (inter
);
3448 tree impdecls
= CLASS_IVARS (imp
);
3449 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3450 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3456 if (intdecls
== 0 && impdecls
== 0)
3458 if (intdecls
== 0 || impdecls
== 0)
3460 error ("inconsistent instance variable specification");
3464 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3466 if (!comptypes (t1
, t2
))
3468 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3470 error_with_ivar ("conflicting instance variable type",
3471 impdecls
, rawimpdecls
);
3472 error_with_ivar ("previous declaration of",
3473 intdecls
, rawintdecls
);
3475 else /* both the type and the name don't match */
3477 error ("inconsistent instance variable specification");
3482 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3484 error_with_ivar ("conflicting instance variable name",
3485 impdecls
, rawimpdecls
);
3486 error_with_ivar ("previous declaration of",
3487 intdecls
, rawintdecls
);
3490 intdecls
= TREE_CHAIN (intdecls
);
3491 impdecls
= TREE_CHAIN (impdecls
);
3492 rawintdecls
= TREE_CHAIN (rawintdecls
);
3493 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3497 /* Set super_type to the data type node for struct objc_super *,
3498 first defining struct objc_super itself.
3499 This needs to be done just once per compilation. */
3502 build_super_template ()
3504 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3506 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3508 /* struct objc_object *self; */
3510 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3511 field_decl
= get_identifier ("self");
3512 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3513 field_decl
= grokfield (input_filename
, lineno
,
3514 field_decl
, decl_specs
, NULL_TREE
);
3515 field_decl_chain
= field_decl
;
3517 /* struct objc_class *class; */
3519 decl_specs
= get_identifier (UTAG_CLASS
);
3520 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3521 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3523 field_decl
= grokfield (input_filename
, lineno
,
3524 field_decl
, decl_specs
, NULL_TREE
);
3525 chainon (field_decl_chain
, field_decl
);
3527 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3529 /* `struct objc_super *' */
3530 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3532 build1 (INDIRECT_REF
,
3533 NULL_TREE
, NULL_TREE
)));
3537 /* struct objc_ivar {
3544 build_ivar_template ()
3546 tree objc_ivar_id
, objc_ivar_record
;
3547 tree decl_specs
, field_decl
, field_decl_chain
;
3549 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3550 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3552 /* char *ivar_name; */
3554 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3555 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3557 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3558 decl_specs
, NULL_TREE
);
3559 field_decl_chain
= field_decl
;
3561 /* char *ivar_type; */
3563 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3564 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3566 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3567 decl_specs
, NULL_TREE
);
3568 chainon (field_decl_chain
, field_decl
);
3570 /* int ivar_offset; */
3572 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3573 field_decl
= get_identifier ("ivar_offset");
3575 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3576 decl_specs
, NULL_TREE
);
3577 chainon (field_decl_chain
, field_decl
);
3579 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3581 return objc_ivar_record
;
3586 struct objc_ivar ivar_list[ivar_count];
3590 build_ivar_list_template (list_type
, size
)
3594 tree objc_ivar_list_record
;
3595 tree decl_specs
, field_decl
, field_decl_chain
;
3597 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3599 /* int ivar_count; */
3601 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3602 field_decl
= get_identifier ("ivar_count");
3604 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3605 decl_specs
, NULL_TREE
);
3606 field_decl_chain
= field_decl
;
3608 /* struct objc_ivar ivar_list[]; */
3610 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3611 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3612 build_int_2 (size
, 0));
3614 field_decl
= grokfield (input_filename
, lineno
,
3615 field_decl
, decl_specs
, NULL_TREE
);
3616 chainon (field_decl_chain
, field_decl
);
3618 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3620 return objc_ivar_list_record
;
3626 struct objc_method method_list[method_count];
3630 build_method_list_template (list_type
, size
)
3634 tree objc_ivar_list_record
;
3635 tree decl_specs
, field_decl
, field_decl_chain
;
3637 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3639 /* int method_next; */
3644 xref_tag (RECORD_TYPE
,
3645 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3647 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3648 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3649 decl_specs
, NULL_TREE
);
3650 field_decl_chain
= field_decl
;
3652 /* int method_count; */
3654 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3655 field_decl
= get_identifier ("method_count");
3657 field_decl
= grokfield (input_filename
, lineno
,
3658 field_decl
, decl_specs
, NULL_TREE
);
3659 chainon (field_decl_chain
, field_decl
);
3661 /* struct objc_method method_list[]; */
3663 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3664 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3665 build_int_2 (size
, 0));
3667 field_decl
= grokfield (input_filename
, lineno
,
3668 field_decl
, decl_specs
, NULL_TREE
);
3669 chainon (field_decl_chain
, field_decl
);
3671 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3673 return objc_ivar_list_record
;
3677 build_ivar_list_initializer (type
, field_decl
)
3681 tree initlist
= NULL_TREE
;
3685 tree ivar
= NULL_TREE
;
3688 if (DECL_NAME (field_decl
))
3689 ivar
= tree_cons (NULL_TREE
,
3690 add_objc_string (DECL_NAME (field_decl
),
3694 /* Unnamed bit-field ivar (yuck). */
3695 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3698 encode_field_decl (field_decl
,
3699 obstack_object_size (&util_obstack
),
3700 OBJC_ENCODE_DONT_INLINE_DEFS
);
3702 /* Null terminate string. */
3703 obstack_1grow (&util_obstack
, 0);
3707 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3710 obstack_free (&util_obstack
, util_firstobj
);
3713 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3714 initlist
= tree_cons (NULL_TREE
,
3715 build_constructor (type
, nreverse (ivar
)),
3718 field_decl
= TREE_CHAIN (field_decl
);
3722 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3726 generate_ivars_list (type
, name
, size
, list
)
3732 tree sc_spec
, decl_specs
, decl
, initlist
;
3734 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3735 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3737 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3738 decl_specs
, 1, NULL_TREE
);
3740 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3741 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3744 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3751 generate_ivar_lists ()
3753 tree initlist
, ivar_list_template
, chain
;
3754 tree cast
, variable_length_type
;
3757 generating_instance_variables
= 1;
3759 if (!objc_ivar_template
)
3760 objc_ivar_template
= build_ivar_template ();
3764 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3765 get_identifier (UTAG_IVAR_LIST
))),
3767 variable_length_type
= groktypename (cast
);
3769 /* Only generate class variables for the root of the inheritance
3770 hierarchy since these will be the same for every class. */
3772 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3773 && (chain
= TYPE_FIELDS (objc_class_template
)))
3775 size
= list_length (chain
);
3777 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3778 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3780 UOBJC_CLASS_VARIABLES_decl
3781 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3783 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3786 UOBJC_CLASS_VARIABLES_decl
= 0;
3788 chain
= CLASS_IVARS (implementation_template
);
3791 size
= list_length (chain
);
3792 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3793 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3795 UOBJC_INSTANCE_VARIABLES_decl
3796 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3798 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3801 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3803 generating_instance_variables
= 0;
3807 build_dispatch_table_initializer (type
, entries
)
3811 tree initlist
= NULL_TREE
;
3815 tree elemlist
= NULL_TREE
;
3817 elemlist
= tree_cons (NULL_TREE
,
3818 build_selector (METHOD_SEL_NAME (entries
)),
3821 /* Generate the method encoding if we don't have one already. */
3822 if (! METHOD_ENCODING (entries
))
3823 METHOD_ENCODING (entries
) =
3824 encode_method_def (METHOD_DEFINITION (entries
));
3826 elemlist
= tree_cons (NULL_TREE
,
3827 add_objc_string (METHOD_ENCODING (entries
),
3831 elemlist
= tree_cons (NULL_TREE
,
3832 build_unary_op (ADDR_EXPR
,
3833 METHOD_DEFINITION (entries
), 1),
3836 initlist
= tree_cons (NULL_TREE
,
3837 build_constructor (type
, nreverse (elemlist
)),
3840 entries
= TREE_CHAIN (entries
);
3844 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3847 /* To accomplish method prototyping without generating all kinds of
3848 inane warnings, the definition of the dispatch table entries were
3851 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3853 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3856 build_method_template ()
3859 tree decl_specs
, field_decl
, field_decl_chain
;
3861 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3863 /* struct objc_selector *_cmd; */
3864 decl_specs
= tree_cons (NULL_TREE
,
3865 xref_tag (RECORD_TYPE
,
3866 get_identifier (TAG_SELECTOR
)),
3868 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3870 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3871 decl_specs
, NULL_TREE
);
3872 field_decl_chain
= field_decl
;
3874 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3875 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3876 get_identifier ("method_types"));
3877 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3878 decl_specs
, NULL_TREE
);
3879 chainon (field_decl_chain
, field_decl
);
3883 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
3884 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
3885 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3886 decl_specs
, NULL_TREE
);
3887 chainon (field_decl_chain
, field_decl
);
3889 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
3896 generate_dispatch_table (type
, name
, size
, list
)
3902 tree sc_spec
, decl_specs
, decl
, initlist
;
3904 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3905 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3907 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3908 decl_specs
, 1, NULL_TREE
);
3910 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
3911 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
3912 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3915 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3922 generate_dispatch_tables ()
3924 tree initlist
, chain
, method_list_template
;
3925 tree cast
, variable_length_type
;
3928 if (!objc_method_template
)
3929 objc_method_template
= build_method_template ();
3933 (build_tree_list (NULL_TREE
,
3934 xref_tag (RECORD_TYPE
,
3935 get_identifier (UTAG_METHOD_LIST
))),
3938 variable_length_type
= groktypename (cast
);
3940 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
3943 size
= list_length (chain
);
3945 method_list_template
3946 = build_method_list_template (objc_method_template
, size
);
3948 = build_dispatch_table_initializer (objc_method_template
, chain
);
3950 UOBJC_CLASS_METHODS_decl
3951 = generate_dispatch_table (method_list_template
,
3952 ((TREE_CODE (objc_implementation_context
)
3953 == CLASS_IMPLEMENTATION_TYPE
)
3954 ? "_OBJC_CLASS_METHODS"
3955 : "_OBJC_CATEGORY_CLASS_METHODS"),
3957 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3960 UOBJC_CLASS_METHODS_decl
= 0;
3962 chain
= CLASS_NST_METHODS (objc_implementation_context
);
3965 size
= list_length (chain
);
3967 method_list_template
3968 = build_method_list_template (objc_method_template
, size
);
3970 = build_dispatch_table_initializer (objc_method_template
, chain
);
3972 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
3973 UOBJC_INSTANCE_METHODS_decl
3974 = generate_dispatch_table (method_list_template
,
3975 "_OBJC_INSTANCE_METHODS",
3978 /* We have a category. */
3979 UOBJC_INSTANCE_METHODS_decl
3980 = generate_dispatch_table (method_list_template
,
3981 "_OBJC_CATEGORY_INSTANCE_METHODS",
3983 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3986 UOBJC_INSTANCE_METHODS_decl
= 0;
3990 generate_protocol_list (i_or_p
)
3993 tree initlist
, decl_specs
, sc_spec
;
3994 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
3998 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
3999 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4000 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4001 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4002 plist
= PROTOCOL_LIST (i_or_p
);
4006 cast_type
= groktypename
4008 (build_tree_list (NULL_TREE
,
4009 xref_tag (RECORD_TYPE
,
4010 get_identifier (UTAG_PROTOCOL
))),
4011 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4014 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4015 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4016 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4019 /* Build initializer. */
4020 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4022 e
= build_int_2 (size
, 0);
4023 TREE_TYPE (e
) = cast_type
;
4024 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4026 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4028 tree pval
= TREE_VALUE (lproto
);
4030 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4031 && PROTOCOL_FORWARD_DECL (pval
))
4033 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4034 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4038 /* static struct objc_protocol *refs[n]; */
4040 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4041 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4042 get_identifier (UTAG_PROTOCOL
)),
4045 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4046 expr_decl
= build_nt (ARRAY_REF
,
4047 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4049 build_int_2 (size
+ 2, 0));
4050 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4051 expr_decl
= build_nt (ARRAY_REF
,
4052 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4054 build_int_2 (size
+ 2, 0));
4055 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4057 = build_nt (ARRAY_REF
,
4058 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4060 build_int_2 (size
+ 2, 0));
4064 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4066 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4067 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4069 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4070 nreverse (initlist
)),
4077 build_category_initializer (type
, cat_name
, class_name
,
4078 instance_methods
, class_methods
, protocol_list
)
4082 tree instance_methods
;
4086 tree initlist
= NULL_TREE
, expr
;
4088 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4089 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4091 if (!instance_methods
)
4092 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4095 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4096 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4099 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4102 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4103 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4106 /* protocol_list = */
4108 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4111 tree cast_type2
= groktypename
4113 (build_tree_list (NULL_TREE
,
4114 xref_tag (RECORD_TYPE
,
4115 get_identifier (UTAG_PROTOCOL
))),
4116 build1 (INDIRECT_REF
, NULL_TREE
,
4117 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4119 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4120 TREE_TYPE (expr
) = cast_type2
;
4121 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4124 return build_constructor (type
, nreverse (initlist
));
4127 /* struct objc_class {
4128 struct objc_class *isa;
4129 struct objc_class *super_class;
4134 struct objc_ivar_list *ivars;
4135 struct objc_method_list *methods;
4136 if (flag_next_runtime)
4137 struct objc_cache *cache;
4139 struct sarray *dtable;
4140 struct objc_class *subclass_list;
4141 struct objc_class *sibling_class;
4143 struct objc_protocol_list *protocols;
4144 void *gc_object_type;
4148 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4149 dispatch_table
, ivar_list
, protocol_list
)
4156 tree dispatch_table
;
4160 tree initlist
= NULL_TREE
, expr
;
4163 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4166 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4169 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4172 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4175 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4177 /* instance_size = */
4178 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4180 /* objc_ivar_list = */
4182 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4185 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4186 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4189 /* objc_method_list = */
4190 if (!dispatch_table
)
4191 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4194 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4195 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4198 if (flag_next_runtime
)
4199 /* method_cache = */
4200 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4204 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4206 /* subclass_list = */
4207 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4209 /* sibling_class = */
4210 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4213 /* protocol_list = */
4214 if (! protocol_list
)
4215 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4221 (build_tree_list (NULL_TREE
,
4222 xref_tag (RECORD_TYPE
,
4223 get_identifier (UTAG_PROTOCOL
))),
4224 build1 (INDIRECT_REF
, NULL_TREE
,
4225 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4227 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4228 TREE_TYPE (expr
) = cast_type2
;
4229 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4232 /* gc_object_type = NULL */
4233 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4235 return build_constructor (type
, nreverse (initlist
));
4238 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4241 generate_category (cat
)
4244 tree sc_spec
, decl_specs
, decl
;
4245 tree initlist
, cat_name_expr
, class_name_expr
;
4246 tree protocol_decl
, category
;
4248 add_class_reference (CLASS_NAME (cat
));
4249 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4251 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4253 category
= CLASS_CATEGORY_LIST (implementation_template
);
4255 /* find the category interface from the class it is associated with */
4258 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4260 category
= CLASS_CATEGORY_LIST (category
);
4263 if (category
&& CLASS_PROTOCOL_LIST (category
))
4265 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4266 protocol_decl
= generate_protocol_list (category
);
4271 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4272 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4274 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4275 objc_implementation_context
),
4276 decl_specs
, 1, NULL_TREE
);
4278 initlist
= build_category_initializer (TREE_TYPE (decl
),
4279 cat_name_expr
, class_name_expr
,
4280 UOBJC_INSTANCE_METHODS_decl
,
4281 UOBJC_CLASS_METHODS_decl
,
4284 TREE_USED (decl
) = 1;
4285 finish_decl (decl
, initlist
, NULL_TREE
);
4288 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4289 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4292 generate_shared_structures ()
4294 tree sc_spec
, decl_specs
, decl
;
4295 tree name_expr
, super_expr
, root_expr
;
4296 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4297 tree cast_type
, initlist
, protocol_decl
;
4299 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4302 add_class_reference (my_super_id
);
4304 /* Compute "my_root_id" - this is required for code generation.
4305 the "isa" for all meta class structures points to the root of
4306 the inheritance hierarchy (e.g. "__Object")... */
4307 my_root_id
= my_super_id
;
4310 tree my_root_int
= lookup_interface (my_root_id
);
4312 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4313 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4320 /* No super class. */
4321 my_root_id
= CLASS_NAME (implementation_template
);
4324 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4325 objc_class_template
),
4326 build1 (INDIRECT_REF
,
4327 NULL_TREE
, NULL_TREE
)));
4329 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4332 /* Install class `isa' and `super' pointers at runtime. */
4335 super_expr
= add_objc_string (my_super_id
, class_names
);
4336 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4339 super_expr
= build_int_2 (0, 0);
4341 root_expr
= add_objc_string (my_root_id
, class_names
);
4342 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4344 if (CLASS_PROTOCOL_LIST (implementation_template
))
4346 generate_protocol_references
4347 (CLASS_PROTOCOL_LIST (implementation_template
));
4348 protocol_decl
= generate_protocol_list (implementation_template
);
4353 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4355 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4356 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4358 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4362 = build_shared_structure_initializer
4364 root_expr
, super_expr
, name_expr
,
4365 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4367 UOBJC_CLASS_METHODS_decl
,
4368 UOBJC_CLASS_VARIABLES_decl
,
4371 finish_decl (decl
, initlist
, NULL_TREE
);
4373 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4375 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4379 = build_shared_structure_initializer
4381 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4382 super_expr
, name_expr
,
4383 convert (integer_type_node
,
4384 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4385 (implementation_template
))),
4387 UOBJC_INSTANCE_METHODS_decl
,
4388 UOBJC_INSTANCE_VARIABLES_decl
,
4391 finish_decl (decl
, initlist
, NULL_TREE
);
4395 synth_id_with_class_suffix (preamble
, ctxt
)
4396 const char *preamble
;
4400 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4401 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4403 const char *const class_name
4404 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4405 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4406 sprintf (string
, "%s_%s", preamble
,
4407 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4409 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4410 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4412 /* We have a category. */
4413 const char *const class_name
4414 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4415 const char *const class_super_name
4416 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
4417 string
= (char *) alloca (strlen (preamble
)
4418 + strlen (class_name
)
4419 + strlen (class_super_name
)
4421 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4423 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4425 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4427 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4428 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4433 return get_identifier (string
);
4437 is_objc_type_qualifier (node
)
4440 return (TREE_CODE (node
) == IDENTIFIER_NODE
4441 && (node
== ridpointers
[(int) RID_CONST
]
4442 || node
== ridpointers
[(int) RID_VOLATILE
]
4443 || node
== ridpointers
[(int) RID_IN
]
4444 || node
== ridpointers
[(int) RID_OUT
]
4445 || node
== ridpointers
[(int) RID_INOUT
]
4446 || node
== ridpointers
[(int) RID_BYCOPY
]
4447 || node
== ridpointers
[(int) RID_BYREF
]
4448 || node
== ridpointers
[(int) RID_ONEWAY
]));
4451 /* If type is empty or only type qualifiers are present, add default
4452 type of id (otherwise grokdeclarator will default to int). */
4455 adjust_type_for_id_default (type
)
4458 tree declspecs
, chain
;
4461 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4462 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4464 declspecs
= TREE_PURPOSE (type
);
4466 /* Determine if a typespec is present. */
4467 for (chain
= declspecs
;
4469 chain
= TREE_CHAIN (chain
))
4471 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4475 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4477 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4482 selector ':' '(' typename ')' identifier
4485 Transform an Objective-C keyword argument into
4486 the C equivalent parameter declarator.
4488 In: key_name, an "identifier_node" (optional).
4489 arg_type, a "tree_list" (optional).
4490 arg_name, an "identifier_node".
4492 Note: It would be really nice to strongly type the preceding
4493 arguments in the function prototype; however, then I
4494 could not use the "accessor" macros defined in "tree.h".
4496 Out: an instance of "keyword_decl". */
4499 build_keyword_decl (key_name
, arg_type
, arg_name
)
4506 /* If no type is specified, default to "id". */
4507 arg_type
= adjust_type_for_id_default (arg_type
);
4509 keyword_decl
= make_node (KEYWORD_DECL
);
4511 TREE_TYPE (keyword_decl
) = arg_type
;
4512 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4513 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4515 return keyword_decl
;
4518 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4521 build_keyword_selector (selector
)
4525 tree key_chain
, key_name
;
4528 /* Scan the selector to see how much space we'll need. */
4529 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4531 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4532 key_name
= KEYWORD_KEY_NAME (key_chain
);
4533 else if (TREE_CODE (selector
) == TREE_LIST
)
4534 key_name
= TREE_PURPOSE (key_chain
);
4539 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4541 /* Just a ':' arg. */
4545 buf
= (char *) alloca (len
+ 1);
4546 /* Start the buffer out as an empty string. */
4549 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4551 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4552 key_name
= KEYWORD_KEY_NAME (key_chain
);
4553 else if (TREE_CODE (selector
) == TREE_LIST
)
4554 key_name
= TREE_PURPOSE (key_chain
);
4559 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4563 return get_identifier (buf
);
4566 /* Used for declarations and definitions. */
4569 build_method_decl (code
, ret_type
, selector
, add_args
)
4570 enum tree_code code
;
4577 /* If no type is specified, default to "id". */
4578 ret_type
= adjust_type_for_id_default (ret_type
);
4580 method_decl
= make_node (code
);
4581 TREE_TYPE (method_decl
) = ret_type
;
4583 /* If we have a keyword selector, create an identifier_node that
4584 represents the full selector name (`:' included)... */
4585 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4587 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4588 METHOD_SEL_ARGS (method_decl
) = selector
;
4589 METHOD_ADD_ARGS (method_decl
) = add_args
;
4593 METHOD_SEL_NAME (method_decl
) = selector
;
4594 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4595 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4601 #define METHOD_DEF 0
4602 #define METHOD_REF 1
4604 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4605 an argument list for method METH. CONTEXT is either METHOD_DEF or
4606 METHOD_REF, saying whether we are trying to define a method or call
4607 one. SUPERFLAG says this is for a send to super; this makes a
4608 difference for the NeXT calling sequence in which the lookup and
4609 the method call are done together. */
4612 get_arg_type_list (meth
, context
, superflag
)
4619 /* Receiver type. */
4620 if (flag_next_runtime
&& superflag
)
4621 arglist
= build_tree_list (NULL_TREE
, super_type
);
4622 else if (context
== METHOD_DEF
)
4623 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4625 arglist
= build_tree_list (NULL_TREE
, id_type
);
4627 /* Selector type - will eventually change to `int'. */
4628 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4630 /* Build a list of argument types. */
4631 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4633 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4634 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4637 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4638 /* We have a `, ...' immediately following the selector,
4639 finalize the arglist...simulate get_parm_info (0). */
4641 else if (METHOD_ADD_ARGS (meth
))
4643 /* we have a variable length selector */
4644 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4645 chainon (arglist
, add_arg_list
);
4648 /* finalize the arglist...simulate get_parm_info (1) */
4649 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4655 check_duplicates (hsh
)
4658 tree meth
= NULL_TREE
;
4666 /* We have two methods with the same name and different types. */
4668 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4670 warning ("multiple declarations for method `%s'",
4671 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4673 warn_with_method ("using", type
, meth
);
4674 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4675 warn_with_method ("also found", type
, loop
->value
);
4681 /* If RECEIVER is a class reference, return the identifier node for
4682 the referenced class. RECEIVER is created by get_class_reference,
4683 so we check the exact form created depending on which runtimes are
4687 receiver_is_class_object (receiver
)
4690 tree chain
, exp
, arg
;
4692 /* The receiver is 'self' in the context of a class method. */
4693 if (objc_method_context
4694 && receiver
== self_decl
4695 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4697 return CLASS_NAME (objc_implementation_context
);
4700 if (flag_next_runtime
)
4702 /* The receiver is a variable created by
4703 build_class_reference_decl. */
4704 if (TREE_CODE (receiver
) == VAR_DECL
4705 && TREE_TYPE (receiver
) == objc_class_type
)
4706 /* Look up the identifier. */
4707 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4708 if (TREE_PURPOSE (chain
) == receiver
)
4709 return TREE_VALUE (chain
);
4713 /* The receiver is a function call that returns an id. Check if
4714 it is a call to objc_getClass, if so, pick up the class name. */
4715 if (TREE_CODE (receiver
) == CALL_EXPR
4716 && (exp
= TREE_OPERAND (receiver
, 0))
4717 && TREE_CODE (exp
) == ADDR_EXPR
4718 && (exp
= TREE_OPERAND (exp
, 0))
4719 && TREE_CODE (exp
) == FUNCTION_DECL
4720 && exp
== objc_get_class_decl
4721 /* We have a call to objc_getClass! */
4722 && (arg
= TREE_OPERAND (receiver
, 1))
4723 && TREE_CODE (arg
) == TREE_LIST
4724 && (arg
= TREE_VALUE (arg
)))
4727 if (TREE_CODE (arg
) == ADDR_EXPR
4728 && (arg
= TREE_OPERAND (arg
, 0))
4729 && TREE_CODE (arg
) == STRING_CST
)
4730 /* Finally, we have the class name. */
4731 return get_identifier (TREE_STRING_POINTER (arg
));
4737 /* If we are currently building a message expr, this holds
4738 the identifier of the selector of the message. This is
4739 used when printing warnings about argument mismatches. */
4741 static tree building_objc_message_expr
= 0;
4744 maybe_building_objc_message_expr ()
4746 return building_objc_message_expr
;
4749 /* Construct an expression for sending a message.
4750 MESS has the object to send to in TREE_PURPOSE
4751 and the argument list (including selector) in TREE_VALUE.
4753 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4754 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4757 build_message_expr (mess
)
4760 tree receiver
= TREE_PURPOSE (mess
);
4762 tree args
= TREE_VALUE (mess
);
4763 tree method_params
= NULL_TREE
;
4765 if (TREE_CODE (receiver
) == ERROR_MARK
)
4766 return error_mark_node
;
4768 /* Obtain the full selector name. */
4769 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4770 /* A unary selector. */
4772 else if (TREE_CODE (args
) == TREE_LIST
)
4773 sel_name
= build_keyword_selector (args
);
4777 /* Build the parameter list to give to the method. */
4778 if (TREE_CODE (args
) == TREE_LIST
)
4780 tree chain
= args
, prev
= NULL_TREE
;
4782 /* We have a keyword selector--check for comma expressions. */
4785 tree element
= TREE_VALUE (chain
);
4787 /* We have a comma expression, must collapse... */
4788 if (TREE_CODE (element
) == TREE_LIST
)
4791 TREE_CHAIN (prev
) = element
;
4796 chain
= TREE_CHAIN (chain
);
4798 method_params
= args
;
4801 return finish_message_expr (receiver
, sel_name
, method_params
);
4804 /* The 'finish_message_expr' routine is called from within
4805 'build_message_expr' for non-template functions. In the case of
4806 C++ template functions, it is called from 'build_expr_from_tree'
4807 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4810 finish_message_expr (receiver
, sel_name
, method_params
)
4811 tree receiver
, sel_name
, method_params
;
4813 tree method_prototype
= NULL_TREE
, class_ident
= NULL_TREE
;
4814 tree selector
, self_object
, retval
;
4815 int statically_typed
= 0, statically_allocated
= 0;
4817 /* Determine receiver type. */
4818 tree rtype
= TREE_TYPE (receiver
);
4819 int super
= IS_SUPER (rtype
);
4823 if (TREE_STATIC_TEMPLATE (rtype
))
4824 statically_allocated
= 1;
4825 else if (TREE_CODE (rtype
) == POINTER_TYPE
4826 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4827 statically_typed
= 1;
4828 else if ((flag_next_runtime
4830 && (class_ident
= receiver_is_class_object (receiver
)))
4832 else if (! IS_ID (rtype
)
4833 /* Allow any type that matches objc_class_type. */
4834 && ! comptypes (rtype
, objc_class_type
))
4836 warning ("invalid receiver type `%s'",
4837 gen_declaration (rtype
, errbuf
));
4839 if (statically_allocated
)
4840 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4842 /* Don't evaluate the receiver twice. */
4843 receiver
= save_expr (receiver
);
4844 self_object
= receiver
;
4847 /* If sending to `super', use current self as the object. */
4848 self_object
= self_decl
;
4850 /* Determine operation return type. */
4856 if (CLASS_SUPER_NAME (implementation_template
))
4859 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4861 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
4862 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4864 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4866 if (iface
&& !method_prototype
)
4867 warning ("`%s' does not respond to `%s'",
4868 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4869 IDENTIFIER_POINTER (sel_name
));
4873 error ("no super class declared in interface for `%s'",
4874 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4875 return error_mark_node
;
4879 else if (statically_allocated
)
4881 tree ctype
= TREE_TYPE (rtype
);
4882 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4885 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4887 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4889 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4892 if (!method_prototype
)
4893 warning ("`%s' does not respond to `%s'",
4894 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
4895 IDENTIFIER_POINTER (sel_name
));
4897 else if (statically_typed
)
4899 tree ctype
= TREE_TYPE (rtype
);
4901 /* `self' is now statically_typed. All methods should be visible
4902 within the context of the implementation. */
4903 if (objc_implementation_context
4904 && CLASS_NAME (objc_implementation_context
) == TYPE_NAME (ctype
))
4907 = lookup_instance_method_static (implementation_template
,
4910 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4912 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4915 if (! method_prototype
4916 && implementation_template
!= objc_implementation_context
)
4917 /* The method is not published in the interface. Check
4920 = lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
4927 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
4928 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4930 if (! method_prototype
)
4932 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
4935 = lookup_method_in_protocol_list (protocol_list
,
4940 if (!method_prototype
)
4941 warning ("`%s' does not respond to `%s'",
4942 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
4943 IDENTIFIER_POINTER (sel_name
));
4945 else if (class_ident
)
4947 if (objc_implementation_context
4948 && CLASS_NAME (objc_implementation_context
) == class_ident
)
4951 = lookup_class_method_static (implementation_template
, sel_name
);
4953 if (!method_prototype
4954 && implementation_template
!= objc_implementation_context
)
4955 /* The method is not published in the interface. Check
4958 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context
),
4965 if ((iface
= lookup_interface (class_ident
)))
4966 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4969 if (!method_prototype
)
4971 warning ("cannot find class (factory) method");
4972 warning ("return type for `%s' defaults to id",
4973 IDENTIFIER_POINTER (sel_name
));
4976 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
4978 /* An anonymous object that has been qualified with a protocol. */
4980 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
4982 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
4985 if (!method_prototype
)
4989 warning ("method `%s' not implemented by protocol",
4990 IDENTIFIER_POINTER (sel_name
));
4992 /* Try and find the method signature in the global pools. */
4994 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
4995 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
4997 if (!(method_prototype
= check_duplicates (hsh
)))
4998 warning ("return type defaults to id");
5005 /* We think we have an instance...loophole: extern id Object; */
5006 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5009 /* For various loopholes */
5010 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5012 method_prototype
= check_duplicates (hsh
);
5013 if (!method_prototype
)
5015 warning ("cannot find method");
5016 warning ("return type for `%s' defaults to id",
5017 IDENTIFIER_POINTER (sel_name
));
5021 /* Save the selector name for printing error messages. */
5022 building_objc_message_expr
= sel_name
;
5024 /* Build the parameters list for looking up the method.
5025 These are the object itself and the selector. */
5027 if (flag_typed_selectors
)
5028 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5030 selector
= build_selector_reference (sel_name
);
5032 retval
= build_objc_method_call (super
, method_prototype
,
5033 receiver
, self_object
,
5034 selector
, method_params
);
5036 building_objc_message_expr
= 0;
5041 /* Build a tree expression to send OBJECT the operation SELECTOR,
5042 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5043 assuming the method has prototype METHOD_PROTOTYPE.
5044 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5045 Use METHOD_PARAMS as list of args to pass to the method.
5046 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5049 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5050 selector
, method_params
)
5052 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5054 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5055 tree rcv_p
= (super_flag
5056 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5057 get_identifier (TAG_SUPER
)))
5060 if (flag_next_runtime
)
5062 if (! method_prototype
)
5064 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5065 tree_cons (NULL_TREE
, selector
,
5067 assemble_external (sender
);
5068 return build_function_call (sender
, method_params
);
5072 /* This is a real kludge, but it is used only for the Next.
5073 Clobber the data type of SENDER temporarily to accept
5074 all the arguments for this operation, and to return
5075 whatever this operation returns. */
5076 tree arglist
= NULL_TREE
, retval
, savarg
, savret
;
5077 tree ret_type
= groktypename (TREE_TYPE (method_prototype
));
5079 /* Save the proper contents of SENDER's data type. */
5080 savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5081 savret
= TREE_TYPE (TREE_TYPE (sender
));
5083 /* Install this method's argument types. */
5084 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5086 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5088 /* Install this method's return type. */
5089 TREE_TYPE (TREE_TYPE (sender
)) = ret_type
;
5091 /* Call SENDER with all the parameters. This will do type
5092 checking using the arg types for this method. */
5093 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5094 tree_cons (NULL_TREE
, selector
,
5096 assemble_external (sender
);
5097 retval
= build_function_call (sender
, method_params
);
5099 /* Restore SENDER's return/argument types. */
5100 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5101 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5107 /* This is the portable way.
5108 First call the lookup function to get a pointer to the method,
5109 then cast the pointer, then call it with the method arguments. */
5112 /* Avoid trouble since we may evaluate each of these twice. */
5113 object
= save_expr (object
);
5114 selector
= save_expr (selector
);
5116 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5118 assemble_external (sender
);
5120 = build_function_call (sender
,
5121 tree_cons (NULL_TREE
, lookup_object
,
5122 tree_cons (NULL_TREE
, selector
,
5125 /* If we have a method prototype, construct the data type this
5126 method needs, and cast what we got from SENDER into a pointer
5128 if (method_prototype
)
5130 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5132 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5133 tree fake_function_type
= build_function_type (valtype
, arglist
);
5134 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5138 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5140 /* Pass the object to the method. */
5141 assemble_external (method
);
5142 return build_function_call (method
,
5143 tree_cons (NULL_TREE
, object
,
5144 tree_cons (NULL_TREE
, selector
,
5150 build_protocol_reference (p
)
5153 tree decl
, ident
, ptype
;
5155 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5157 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5159 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5160 objc_protocol_template
),
5163 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5164 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5167 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5168 DECL_EXTERNAL (decl
) = 1;
5169 TREE_PUBLIC (decl
) = 1;
5170 TREE_USED (decl
) = 1;
5171 DECL_ARTIFICIAL (decl
) = 1;
5173 make_decl_rtl (decl
, 0);
5174 pushdecl_top_level (decl
);
5177 PROTOCOL_FORWARD_DECL (p
) = decl
;
5181 build_protocol_expr (protoname
)
5185 tree p
= lookup_protocol (protoname
);
5189 error ("cannot find protocol declaration for `%s'",
5190 IDENTIFIER_POINTER (protoname
));
5191 return error_mark_node
;
5194 if (!PROTOCOL_FORWARD_DECL (p
))
5195 build_protocol_reference (p
);
5197 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5199 TREE_TYPE (expr
) = protocol_type
;
5205 build_selector_expr (selnamelist
)
5210 /* Obtain the full selector name. */
5211 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5212 /* A unary selector. */
5213 selname
= selnamelist
;
5214 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5215 selname
= build_keyword_selector (selnamelist
);
5219 if (flag_typed_selectors
)
5220 return build_typed_selector_reference (selname
, 0);
5222 return build_selector_reference (selname
);
5226 build_encode_expr (type
)
5232 encode_type (type
, obstack_object_size (&util_obstack
),
5233 OBJC_ENCODE_INLINE_DEFS
);
5234 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5235 string
= obstack_finish (&util_obstack
);
5237 /* Synthesize a string that represents the encoded struct/union. */
5238 result
= my_build_string (strlen (string
) + 1, string
);
5239 obstack_free (&util_obstack
, util_firstobj
);
5244 build_ivar_reference (id
)
5247 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5249 /* Historically, a class method that produced objects (factory
5250 method) would assign `self' to the instance that it
5251 allocated. This would effectively turn the class method into
5252 an instance method. Following this assignment, the instance
5253 variables could be accessed. That practice, while safe,
5254 violates the simple rule that a class method should not refer
5255 to an instance variable. It's better to catch the cases
5256 where this is done unknowingly than to support the above
5258 warning ("instance variable `%s' accessed in class method",
5259 IDENTIFIER_POINTER (id
));
5260 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5263 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5266 /* Compute a hash value for a given method SEL_NAME. */
5269 hash_func (sel_name
)
5272 const unsigned char *s
5273 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
5277 h
= h
* 67 + *s
++ - 113;
5284 nst_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5285 cls_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5288 /* WARNING!!!! hash_enter is called with a method, and will peek
5289 inside to find its selector! But hash_lookup is given a selector
5290 directly, and looks for the selector that's inside the found
5291 entry's key (method) for comparison. */
5294 hash_enter (hashlist
, method
)
5298 static hash hash_alloc_list
= 0;
5299 static int hash_alloc_index
= 0;
5301 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5303 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5305 hash_alloc_index
= 0;
5306 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5307 * HASH_ALLOC_LIST_SIZE
);
5309 obj
= &hash_alloc_list
[hash_alloc_index
++];
5311 obj
->next
= hashlist
[slot
];
5314 hashlist
[slot
] = obj
; /* append to front */
5318 hash_lookup (hashlist
, sel_name
)
5324 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
5328 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5331 target
= target
->next
;
5337 hash_add_attr (entry
, value
)
5341 static attr attr_alloc_list
= 0;
5342 static int attr_alloc_index
= 0;
5345 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5347 attr_alloc_index
= 0;
5348 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5349 * ATTR_ALLOC_LIST_SIZE
);
5351 obj
= &attr_alloc_list
[attr_alloc_index
++];
5352 obj
->next
= entry
->list
;
5355 entry
->list
= obj
; /* append to front */
5359 lookup_method (mchain
, method
)
5365 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5368 key
= METHOD_SEL_NAME (method
);
5372 if (METHOD_SEL_NAME (mchain
) == key
)
5374 mchain
= TREE_CHAIN (mchain
);
5380 lookup_instance_method_static (interface
, ident
)
5384 tree inter
= interface
;
5385 tree chain
= CLASS_NST_METHODS (inter
);
5386 tree meth
= NULL_TREE
;
5390 if ((meth
= lookup_method (chain
, ident
)))
5393 if (CLASS_CATEGORY_LIST (inter
))
5395 tree category
= CLASS_CATEGORY_LIST (inter
);
5396 chain
= CLASS_NST_METHODS (category
);
5400 if ((meth
= lookup_method (chain
, ident
)))
5403 /* Check for instance methods in protocols in categories. */
5404 if (CLASS_PROTOCOL_LIST (category
))
5406 if ((meth
= (lookup_method_in_protocol_list
5407 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5411 if ((category
= CLASS_CATEGORY_LIST (category
)))
5412 chain
= CLASS_NST_METHODS (category
);
5417 if (CLASS_PROTOCOL_LIST (inter
))
5419 if ((meth
= (lookup_method_in_protocol_list
5420 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5424 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5425 chain
= CLASS_NST_METHODS (inter
);
5433 lookup_class_method_static (interface
, ident
)
5437 tree inter
= interface
;
5438 tree chain
= CLASS_CLS_METHODS (inter
);
5439 tree meth
= NULL_TREE
;
5440 tree root_inter
= NULL_TREE
;
5444 if ((meth
= lookup_method (chain
, ident
)))
5447 if (CLASS_CATEGORY_LIST (inter
))
5449 tree category
= CLASS_CATEGORY_LIST (inter
);
5450 chain
= CLASS_CLS_METHODS (category
);
5454 if ((meth
= lookup_method (chain
, ident
)))
5457 /* Check for class methods in protocols in categories. */
5458 if (CLASS_PROTOCOL_LIST (category
))
5460 if ((meth
= (lookup_method_in_protocol_list
5461 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5465 if ((category
= CLASS_CATEGORY_LIST (category
)))
5466 chain
= CLASS_CLS_METHODS (category
);
5471 /* Check for class methods in protocols. */
5472 if (CLASS_PROTOCOL_LIST (inter
))
5474 if ((meth
= (lookup_method_in_protocol_list
5475 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5480 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5481 chain
= CLASS_CLS_METHODS (inter
);
5485 /* If no class (factory) method was found, check if an _instance_
5486 method of the same name exists in the root class. This is what
5487 the Objective-C runtime will do. */
5488 return lookup_instance_method_static (root_inter
, ident
);
5492 add_class_method (class, method
)
5499 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5501 /* put method on list in reverse order */
5502 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5503 CLASS_CLS_METHODS (class) = method
;
5507 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5508 error ("duplicate definition of class method `%s'",
5509 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5512 /* Check types; if different, complain. */
5513 if (!comp_proto_with_proto (method
, mth
))
5514 error ("duplicate declaration of class method `%s'",
5515 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5519 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5521 /* Install on a global chain. */
5522 hash_enter (cls_method_hash_list
, method
);
5526 /* Check types; if different, add to a list. */
5527 if (!comp_proto_with_proto (method
, hsh
->key
))
5528 hash_add_attr (hsh
, method
);
5534 add_instance_method (class, method
)
5541 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5543 /* Put method on list in reverse order. */
5544 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5545 CLASS_NST_METHODS (class) = method
;
5549 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5550 error ("duplicate definition of instance method `%s'",
5551 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5554 /* Check types; if different, complain. */
5555 if (!comp_proto_with_proto (method
, mth
))
5556 error ("duplicate declaration of instance method `%s'",
5557 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5561 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5563 /* Install on a global chain. */
5564 hash_enter (nst_method_hash_list
, method
);
5568 /* Check types; if different, add to a list. */
5569 if (!comp_proto_with_proto (method
, hsh
->key
))
5570 hash_add_attr (hsh
, method
);
5579 /* Put interfaces on list in reverse order. */
5580 TREE_CHAIN (class) = interface_chain
;
5581 interface_chain
= class;
5582 return interface_chain
;
5586 add_category (class, category
)
5590 /* Put categories on list in reverse order. */
5591 tree cat
= CLASS_CATEGORY_LIST (class);
5595 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5596 warning ("duplicate interface declaration for category `%s(%s)'",
5597 IDENTIFIER_POINTER (CLASS_NAME (class)),
5598 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5599 cat
= CLASS_CATEGORY_LIST (cat
);
5602 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5603 CLASS_CATEGORY_LIST (class) = category
;
5606 /* Called after parsing each instance variable declaration. Necessary to
5607 preserve typedefs and implement public/private...
5609 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5612 add_instance_variable (class, public, declarator
, declspecs
, width
)
5619 tree field_decl
, raw_decl
;
5621 raw_decl
= build_tree_list (declspecs
, declarator
);
5623 if (CLASS_RAW_IVARS (class))
5624 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5626 CLASS_RAW_IVARS (class) = raw_decl
;
5628 field_decl
= grokfield (input_filename
, lineno
,
5629 declarator
, declspecs
, width
);
5631 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5635 TREE_PUBLIC (field_decl
) = 0;
5636 TREE_PRIVATE (field_decl
) = 0;
5637 TREE_PROTECTED (field_decl
) = 1;
5641 TREE_PUBLIC (field_decl
) = 1;
5642 TREE_PRIVATE (field_decl
) = 0;
5643 TREE_PROTECTED (field_decl
) = 0;
5647 TREE_PUBLIC (field_decl
) = 0;
5648 TREE_PRIVATE (field_decl
) = 1;
5649 TREE_PROTECTED (field_decl
) = 0;
5654 if (CLASS_IVARS (class))
5655 chainon (CLASS_IVARS (class), field_decl
);
5657 CLASS_IVARS (class) = field_decl
;
5663 is_ivar (decl_chain
, ident
)
5667 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5668 if (DECL_NAME (decl_chain
) == ident
)
5673 /* True if the ivar is private and we are not in its implementation. */
5679 if (TREE_PRIVATE (decl
)
5680 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5682 error ("instance variable `%s' is declared private",
5683 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5690 /* We have an instance variable reference;, check to see if it is public. */
5693 is_public (expr
, identifier
)
5697 tree basetype
= TREE_TYPE (expr
);
5698 enum tree_code code
= TREE_CODE (basetype
);
5701 if (code
== RECORD_TYPE
)
5703 if (TREE_STATIC_TEMPLATE (basetype
))
5705 if (!lookup_interface (TYPE_NAME (basetype
)))
5707 error ("cannot find interface declaration for `%s'",
5708 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5712 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5714 if (TREE_PUBLIC (decl
))
5717 /* Important difference between the Stepstone translator:
5718 all instance variables should be public within the context
5719 of the implementation. */
5720 if (objc_implementation_context
5721 && (((TREE_CODE (objc_implementation_context
)
5722 == CLASS_IMPLEMENTATION_TYPE
)
5723 || (TREE_CODE (objc_implementation_context
)
5724 == CATEGORY_IMPLEMENTATION_TYPE
))
5725 && (CLASS_NAME (objc_implementation_context
)
5726 == TYPE_NAME (basetype
))))
5727 return ! is_private (decl
);
5729 error ("instance variable `%s' is declared %s",
5730 IDENTIFIER_POINTER (identifier
),
5731 TREE_PRIVATE (decl
) ? "private" : "protected");
5736 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
5738 TREE_TYPE (expr
) = uprivate_record
;
5739 warning ("static access to object of type `id'");
5746 /* Implement @defs (<classname>) within struct bodies. */
5749 get_class_ivars (interface
)
5752 /* Make sure we copy the leaf ivars in case @defs is used in a local
5753 context. Otherwise finish_struct will overwrite the layout info
5754 using temporary storage. */
5755 return build_ivar_chain (interface
, 1);
5758 /* Make sure all entries in CHAIN are also in LIST. */
5761 check_methods (chain
, list
, mtype
)
5770 if (!lookup_method (list
, chain
))
5774 if (TREE_CODE (objc_implementation_context
)
5775 == CLASS_IMPLEMENTATION_TYPE
)
5776 warning ("incomplete implementation of class `%s'",
5777 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
5778 else if (TREE_CODE (objc_implementation_context
)
5779 == CATEGORY_IMPLEMENTATION_TYPE
)
5780 warning ("incomplete implementation of category `%s'",
5781 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
5785 warning ("method definition for `%c%s' not found",
5786 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5789 chain
= TREE_CHAIN (chain
);
5795 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5798 conforms_to_protocol (class, protocol
)
5802 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
5804 tree p
= CLASS_PROTOCOL_LIST (class);
5805 while (p
&& TREE_VALUE (p
) != protocol
)
5810 tree super
= (CLASS_SUPER_NAME (class)
5811 ? lookup_interface (CLASS_SUPER_NAME (class))
5813 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5822 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5823 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5826 check_methods_accessible (chain
, context
, mtype
)
5833 tree base_context
= context
;
5837 context
= base_context
;
5841 list
= CLASS_CLS_METHODS (context
);
5843 list
= CLASS_NST_METHODS (context
);
5845 if (lookup_method (list
, chain
))
5848 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5849 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5850 context
= (CLASS_SUPER_NAME (context
)
5851 ? lookup_interface (CLASS_SUPER_NAME (context
))
5854 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5855 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5856 context
= (CLASS_NAME (context
)
5857 ? lookup_interface (CLASS_NAME (context
))
5863 if (context
== NULL_TREE
)
5867 if (TREE_CODE (objc_implementation_context
)
5868 == CLASS_IMPLEMENTATION_TYPE
)
5869 warning ("incomplete implementation of class `%s'",
5871 (CLASS_NAME (objc_implementation_context
)));
5872 else if (TREE_CODE (objc_implementation_context
)
5873 == CATEGORY_IMPLEMENTATION_TYPE
)
5874 warning ("incomplete implementation of category `%s'",
5876 (CLASS_SUPER_NAME (objc_implementation_context
)));
5879 warning ("method definition for `%c%s' not found",
5880 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5883 chain
= TREE_CHAIN (chain
); /* next method... */
5888 /* Check whether the current interface (accessible via
5889 'objc_implementation_context') actually implements protocol P, along
5890 with any protocols that P inherits. */
5893 check_protocol (p
, type
, name
)
5898 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
5902 /* Ensure that all protocols have bodies! */
5903 if (flag_warn_protocol
)
5905 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
5906 CLASS_CLS_METHODS (objc_implementation_context
),
5908 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
5909 CLASS_NST_METHODS (objc_implementation_context
),
5914 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
5915 objc_implementation_context
,
5917 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
5918 objc_implementation_context
,
5923 warning ("%s `%s' does not fully implement the `%s' protocol",
5924 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
5927 /* Check protocols recursively. */
5928 if (PROTOCOL_LIST (p
))
5930 tree subs
= PROTOCOL_LIST (p
);
5932 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5936 tree sub
= TREE_VALUE (subs
);
5938 /* If the superclass does not conform to the protocols
5939 inherited by P, then we must! */
5940 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
5941 check_protocol (sub
, type
, name
);
5942 subs
= TREE_CHAIN (subs
);
5947 /* Check whether the current interface (accessible via
5948 'objc_implementation_context') actually implements the protocols listed
5952 check_protocols (proto_list
, type
, name
)
5957 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
5959 tree p
= TREE_VALUE (proto_list
);
5961 check_protocol (p
, type
, name
);
5965 /* Make sure that the class CLASS_NAME is defined
5966 CODE says which kind of thing CLASS_NAME ought to be.
5967 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5968 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5971 start_class (code
, class_name
, super_name
, protocol_list
)
5972 enum tree_code code
;
5979 if (objc_implementation_context
)
5981 warning ("`@end' missing in implementation context");
5982 finish_class (objc_implementation_context
);
5983 objc_ivar_chain
= NULL_TREE
;
5984 objc_implementation_context
= NULL_TREE
;
5987 class = make_node (code
);
5988 TYPE_BINFO (class) = make_tree_vec (5);
5990 CLASS_NAME (class) = class_name
;
5991 CLASS_SUPER_NAME (class) = super_name
;
5992 CLASS_CLS_METHODS (class) = NULL_TREE
;
5994 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
5996 error ("`%s' redeclared as different kind of symbol",
5997 IDENTIFIER_POINTER (class_name
));
5998 error_with_decl (decl
, "previous declaration of `%s'");
6001 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6006 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6007 if (TREE_VALUE (chain
) == class_name
)
6009 error ("reimplementation of class `%s'",
6010 IDENTIFIER_POINTER (class_name
));
6011 return error_mark_node
;
6013 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6014 implemented_classes
);
6017 /* Pre-build the following entities - for speed/convenience. */
6019 self_id
= get_identifier ("self");
6021 ucmd_id
= get_identifier ("_cmd");
6024 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6025 if (!objc_super_template
)
6026 objc_super_template
= build_super_template ();
6028 /* Reset for multiple classes per file. */
6031 objc_implementation_context
= class;
6033 /* Lookup the interface for this implementation. */
6035 if (!(implementation_template
= lookup_interface (class_name
)))
6037 warning ("cannot find interface declaration for `%s'",
6038 IDENTIFIER_POINTER (class_name
));
6039 add_class (implementation_template
= objc_implementation_context
);
6042 /* If a super class has been specified in the implementation,
6043 insure it conforms to the one specified in the interface. */
6046 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6048 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6049 const char *const name
=
6050 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6051 error ("conflicting super class name `%s'",
6052 IDENTIFIER_POINTER (super_name
));
6053 error ("previous declaration of `%s'", name
);
6056 else if (! super_name
)
6058 CLASS_SUPER_NAME (objc_implementation_context
)
6059 = CLASS_SUPER_NAME (implementation_template
);
6063 else if (code
== CLASS_INTERFACE_TYPE
)
6065 if (lookup_interface (class_name
))
6066 warning ("duplicate interface declaration for class `%s'",
6067 IDENTIFIER_POINTER (class_name
));
6072 CLASS_PROTOCOL_LIST (class)
6073 = lookup_and_install_protocols (protocol_list
);
6076 else if (code
== CATEGORY_INTERFACE_TYPE
)
6078 tree class_category_is_assoc_with
;
6080 /* For a category, class_name is really the name of the class that
6081 the following set of methods will be associated with. We must
6082 find the interface so that can derive the objects template. */
6084 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6086 error ("cannot find interface declaration for `%s'",
6087 IDENTIFIER_POINTER (class_name
));
6088 exit (FATAL_EXIT_CODE
);
6091 add_category (class_category_is_assoc_with
, class);
6094 CLASS_PROTOCOL_LIST (class)
6095 = lookup_and_install_protocols (protocol_list
);
6098 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6100 /* Pre-build the following entities for speed/convenience. */
6102 self_id
= get_identifier ("self");
6104 ucmd_id
= get_identifier ("_cmd");
6107 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6108 if (!objc_super_template
)
6109 objc_super_template
= build_super_template ();
6111 /* Reset for multiple classes per file. */
6114 objc_implementation_context
= class;
6116 /* For a category, class_name is really the name of the class that
6117 the following set of methods will be associated with. We must
6118 find the interface so that can derive the objects template. */
6120 if (!(implementation_template
= lookup_interface (class_name
)))
6122 error ("cannot find interface declaration for `%s'",
6123 IDENTIFIER_POINTER (class_name
));
6124 exit (FATAL_EXIT_CODE
);
6131 continue_class (class)
6134 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6135 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6137 struct imp_entry
*imp_entry
;
6140 /* Check consistency of the instance variables. */
6142 if (CLASS_IVARS (class))
6143 check_ivars (implementation_template
, class);
6145 /* code generation */
6147 ivar_context
= build_private_template (implementation_template
);
6149 if (!objc_class_template
)
6150 build_class_template ();
6152 imp_entry
= (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
));
6154 imp_entry
->next
= imp_list
;
6155 imp_entry
->imp_context
= class;
6156 imp_entry
->imp_template
= implementation_template
;
6158 synth_forward_declarations ();
6159 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6160 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6162 /* Append to front and increment count. */
6163 imp_list
= imp_entry
;
6164 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6169 return ivar_context
;
6172 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6174 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6176 if (!TYPE_FIELDS (record
))
6178 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6179 CLASS_STATIC_TEMPLATE (class) = record
;
6181 /* Mark this record as a class template for static typing. */
6182 TREE_STATIC_TEMPLATE (record
) = 1;
6189 return error_mark_node
;
6192 /* This is called once we see the "@end" in an interface/implementation. */
6195 finish_class (class)
6198 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6200 /* All code generation is done in finish_objc. */
6202 if (implementation_template
!= objc_implementation_context
)
6204 /* Ensure that all method listed in the interface contain bodies. */
6205 check_methods (CLASS_CLS_METHODS (implementation_template
),
6206 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6207 check_methods (CLASS_NST_METHODS (implementation_template
),
6208 CLASS_NST_METHODS (objc_implementation_context
), '-');
6210 if (CLASS_PROTOCOL_LIST (implementation_template
))
6211 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6213 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6217 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6219 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6221 /* Find the category interface from the class it is associated with. */
6224 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6226 category
= CLASS_CATEGORY_LIST (category
);
6231 /* Ensure all method listed in the interface contain bodies. */
6232 check_methods (CLASS_CLS_METHODS (category
),
6233 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6234 check_methods (CLASS_NST_METHODS (category
),
6235 CLASS_NST_METHODS (objc_implementation_context
), '-');
6237 if (CLASS_PROTOCOL_LIST (category
))
6238 check_protocols (CLASS_PROTOCOL_LIST (category
),
6240 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6244 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6247 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6248 char *string
= (char *) alloca (strlen (class_name
) + 3);
6250 /* extern struct objc_object *_<my_name>; */
6252 sprintf (string
, "_%s", class_name
);
6254 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6255 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6256 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6262 add_protocol (protocol
)
6265 /* Put protocol on list in reverse order. */
6266 TREE_CHAIN (protocol
) = protocol_chain
;
6267 protocol_chain
= protocol
;
6268 return protocol_chain
;
6272 lookup_protocol (ident
)
6277 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6278 if (ident
== PROTOCOL_NAME (chain
))
6284 /* This function forward declares the protocols named by NAMES. If
6285 they are already declared or defined, the function has no effect. */
6288 objc_declare_protocols (names
)
6293 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6295 tree name
= TREE_VALUE (list
);
6297 if (lookup_protocol (name
) == NULL_TREE
)
6299 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6301 TYPE_BINFO (protocol
) = make_tree_vec (2);
6302 PROTOCOL_NAME (protocol
) = name
;
6303 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6304 add_protocol (protocol
);
6305 PROTOCOL_DEFINED (protocol
) = 0;
6306 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6312 start_protocol (code
, name
, list
)
6313 enum tree_code code
;
6319 /* This is as good a place as any. Need to invoke
6320 push_tag_toplevel. */
6321 if (!objc_protocol_template
)
6322 objc_protocol_template
= build_protocol_template ();
6324 protocol
= lookup_protocol (name
);
6328 protocol
= make_node (code
);
6329 TYPE_BINFO (protocol
) = make_tree_vec (2);
6331 PROTOCOL_NAME (protocol
) = name
;
6332 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6333 add_protocol (protocol
);
6334 PROTOCOL_DEFINED (protocol
) = 1;
6335 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6337 check_protocol_recursively (protocol
, list
);
6339 else if (! PROTOCOL_DEFINED (protocol
))
6341 PROTOCOL_DEFINED (protocol
) = 1;
6342 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6344 check_protocol_recursively (protocol
, list
);
6348 warning ("duplicate declaration for protocol `%s'",
6349 IDENTIFIER_POINTER (name
));
6355 finish_protocol (protocol
)
6356 tree protocol ATTRIBUTE_UNUSED
;
6361 /* "Encode" a data type into a string, which grows in util_obstack.
6362 ??? What is the FORMAT? Someone please document this! */
6365 encode_type_qualifiers (declspecs
)
6370 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6372 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6373 obstack_1grow (&util_obstack
, 'r');
6374 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6375 obstack_1grow (&util_obstack
, 'n');
6376 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6377 obstack_1grow (&util_obstack
, 'N');
6378 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6379 obstack_1grow (&util_obstack
, 'o');
6380 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6381 obstack_1grow (&util_obstack
, 'O');
6382 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6383 obstack_1grow (&util_obstack
, 'R');
6384 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6385 obstack_1grow (&util_obstack
, 'V');
6389 /* Encode a pointer type. */
6392 encode_pointer (type
, curtype
, format
)
6397 tree pointer_to
= TREE_TYPE (type
);
6399 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6401 if (TYPE_NAME (pointer_to
)
6402 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6404 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6406 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6408 obstack_1grow (&util_obstack
, '@');
6411 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6413 if (generating_instance_variables
)
6415 obstack_1grow (&util_obstack
, '@');
6416 obstack_1grow (&util_obstack
, '"');
6417 obstack_grow (&util_obstack
, name
, strlen (name
));
6418 obstack_1grow (&util_obstack
, '"');
6423 obstack_1grow (&util_obstack
, '@');
6427 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6429 obstack_1grow (&util_obstack
, '#');
6432 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6434 obstack_1grow (&util_obstack
, ':');
6439 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6440 && TYPE_MODE (pointer_to
) == QImode
)
6442 obstack_1grow (&util_obstack
, '*');
6446 /* We have a type that does not get special treatment. */
6448 /* NeXT extension */
6449 obstack_1grow (&util_obstack
, '^');
6450 encode_type (pointer_to
, curtype
, format
);
6454 encode_array (type
, curtype
, format
)
6459 tree an_int_cst
= TYPE_SIZE (type
);
6460 tree array_of
= TREE_TYPE (type
);
6463 /* An incomplete array is treated like a pointer. */
6464 if (an_int_cst
== NULL
)
6466 encode_pointer (type
, curtype
, format
);
6470 sprintf (buffer
, "[%ld",
6471 (long) (TREE_INT_CST_LOW (an_int_cst
)
6472 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6474 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6475 encode_type (array_of
, curtype
, format
);
6476 obstack_1grow (&util_obstack
, ']');
6481 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6488 /* The RECORD_TYPE may in fact be a typedef! For purposes
6489 of encoding, we need the real underlying enchilada. */
6490 if (TYPE_MAIN_VARIANT (type
))
6491 type
= TYPE_MAIN_VARIANT (type
);
6493 if (obstack_object_size (&util_obstack
) > 0
6494 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6496 tree name
= TYPE_NAME (type
);
6498 /* we have a reference; this is a NeXT extension. */
6500 if (obstack_object_size (&util_obstack
) - curtype
== 1
6501 && format
== OBJC_ENCODE_INLINE_DEFS
)
6503 /* Output format of struct for first level only. */
6504 tree fields
= TYPE_FIELDS (type
);
6506 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6508 obstack_1grow (&util_obstack
, left
);
6509 obstack_grow (&util_obstack
,
6510 IDENTIFIER_POINTER (name
),
6511 strlen (IDENTIFIER_POINTER (name
)));
6512 obstack_1grow (&util_obstack
, '=');
6516 obstack_1grow (&util_obstack
, left
);
6517 obstack_grow (&util_obstack
, "?=", 2);
6520 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6521 encode_field_decl (fields
, curtype
, format
);
6523 obstack_1grow (&util_obstack
, right
);
6526 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6528 obstack_1grow (&util_obstack
, left
);
6529 obstack_grow (&util_obstack
,
6530 IDENTIFIER_POINTER (name
),
6531 strlen (IDENTIFIER_POINTER (name
)));
6532 obstack_1grow (&util_obstack
, right
);
6537 /* We have an untagged structure or a typedef. */
6538 obstack_1grow (&util_obstack
, left
);
6539 obstack_1grow (&util_obstack
, '?');
6540 obstack_1grow (&util_obstack
, right
);
6546 tree name
= TYPE_NAME (type
);
6547 tree fields
= TYPE_FIELDS (type
);
6549 if (format
== OBJC_ENCODE_INLINE_DEFS
6550 || generating_instance_variables
)
6552 obstack_1grow (&util_obstack
, left
);
6553 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6554 obstack_grow (&util_obstack
,
6555 IDENTIFIER_POINTER (name
),
6556 strlen (IDENTIFIER_POINTER (name
)));
6558 obstack_1grow (&util_obstack
, '?');
6560 obstack_1grow (&util_obstack
, '=');
6562 for (; fields
; fields
= TREE_CHAIN (fields
))
6564 if (generating_instance_variables
)
6566 tree fname
= DECL_NAME (fields
);
6568 obstack_1grow (&util_obstack
, '"');
6569 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6571 obstack_grow (&util_obstack
,
6572 IDENTIFIER_POINTER (fname
),
6573 strlen (IDENTIFIER_POINTER (fname
)));
6576 obstack_1grow (&util_obstack
, '"');
6579 encode_field_decl (fields
, curtype
, format
);
6582 obstack_1grow (&util_obstack
, right
);
6587 obstack_1grow (&util_obstack
, left
);
6588 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6589 obstack_grow (&util_obstack
,
6590 IDENTIFIER_POINTER (name
),
6591 strlen (IDENTIFIER_POINTER (name
)));
6593 /* We have an untagged structure or a typedef. */
6594 obstack_1grow (&util_obstack
, '?');
6596 obstack_1grow (&util_obstack
, right
);
6602 encode_aggregate (type
, curtype
, format
)
6607 enum tree_code code
= TREE_CODE (type
);
6613 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6618 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6623 obstack_1grow (&util_obstack
, 'i');
6631 /* Support bitfields. The current version of Objective-C does not support
6632 them. The string will consist of one or more "b:n"'s where n is an
6633 integer describing the width of the bitfield. Currently, classes in
6634 the kit implement a method "-(char *)describeBitfieldStruct:" that
6635 simulates this. If they do not implement this method, the archiver
6636 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6637 according to the GNU compiler. After looking at the "kit", it appears
6638 that all classes currently rely on this default behavior, rather than
6639 hand generating this string (which is tedious). */
6642 encode_bitfield (width
)
6646 sprintf (buffer
, "b%d", width
);
6647 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6650 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6653 encode_type (type
, curtype
, format
)
6658 enum tree_code code
= TREE_CODE (type
);
6660 if (code
== INTEGER_TYPE
)
6662 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6664 /* Unsigned integer types. */
6666 if (TYPE_MODE (type
) == QImode
)
6667 obstack_1grow (&util_obstack
, 'C');
6668 else if (TYPE_MODE (type
) == HImode
)
6669 obstack_1grow (&util_obstack
, 'S');
6670 else if (TYPE_MODE (type
) == SImode
)
6672 if (type
== long_unsigned_type_node
)
6673 obstack_1grow (&util_obstack
, 'L');
6675 obstack_1grow (&util_obstack
, 'I');
6677 else if (TYPE_MODE (type
) == DImode
)
6678 obstack_1grow (&util_obstack
, 'Q');
6682 /* Signed integer types. */
6684 if (TYPE_MODE (type
) == QImode
)
6685 obstack_1grow (&util_obstack
, 'c');
6686 else if (TYPE_MODE (type
) == HImode
)
6687 obstack_1grow (&util_obstack
, 's');
6688 else if (TYPE_MODE (type
) == SImode
)
6690 if (type
== long_integer_type_node
)
6691 obstack_1grow (&util_obstack
, 'l');
6693 obstack_1grow (&util_obstack
, 'i');
6696 else if (TYPE_MODE (type
) == DImode
)
6697 obstack_1grow (&util_obstack
, 'q');
6701 else if (code
== REAL_TYPE
)
6703 /* Floating point types. */
6705 if (TYPE_MODE (type
) == SFmode
)
6706 obstack_1grow (&util_obstack
, 'f');
6707 else if (TYPE_MODE (type
) == DFmode
6708 || TYPE_MODE (type
) == TFmode
)
6709 obstack_1grow (&util_obstack
, 'd');
6712 else if (code
== VOID_TYPE
)
6713 obstack_1grow (&util_obstack
, 'v');
6715 else if (code
== ARRAY_TYPE
)
6716 encode_array (type
, curtype
, format
);
6718 else if (code
== POINTER_TYPE
)
6719 encode_pointer (type
, curtype
, format
);
6721 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6722 encode_aggregate (type
, curtype
, format
);
6724 else if (code
== FUNCTION_TYPE
) /* '?' */
6725 obstack_1grow (&util_obstack
, '?');
6729 encode_complete_bitfield (int position
, tree type
, int size
)
6731 enum tree_code code
= TREE_CODE (type
);
6733 char charType
= '?';
6735 if (code
== INTEGER_TYPE
)
6737 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6739 /* Unsigned integer types. */
6741 if (TYPE_MODE (type
) == QImode
)
6743 else if (TYPE_MODE (type
) == HImode
)
6745 else if (TYPE_MODE (type
) == SImode
)
6747 if (type
== long_unsigned_type_node
)
6752 else if (TYPE_MODE (type
) == DImode
)
6757 /* Signed integer types. */
6759 if (TYPE_MODE (type
) == QImode
)
6761 else if (TYPE_MODE (type
) == HImode
)
6763 else if (TYPE_MODE (type
) == SImode
)
6765 if (type
== long_integer_type_node
)
6771 else if (TYPE_MODE (type
) == DImode
)
6775 else if (code
== ENUMERAL_TYPE
)
6780 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6781 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6785 encode_field_decl (field_decl
, curtype
, format
)
6792 type
= TREE_TYPE (field_decl
);
6794 /* If this field is obviously a bitfield, or is a bitfield that has been
6795 clobbered to look like a ordinary integer mode, go ahead and generate
6796 the bitfield typing information. */
6797 if (flag_next_runtime
)
6799 if (DECL_BIT_FIELD (field_decl
))
6800 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6802 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6806 if (DECL_BIT_FIELD (field_decl
))
6807 encode_complete_bitfield (int_bit_position (field_decl
),
6808 DECL_BIT_FIELD_TYPE (field_decl
),
6809 tree_low_cst (DECL_SIZE (field_decl
), 1));
6811 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6816 expr_last (complex_expr
)
6822 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6823 complex_expr
= next
;
6825 return complex_expr
;
6828 /* Transform a method definition into a function definition as follows:
6829 - synthesize the first two arguments, "self" and "_cmd". */
6832 start_method_def (method
)
6837 /* Required to implement _msgSuper. */
6838 objc_method_context
= method
;
6839 UOBJC_SUPER_decl
= NULL_TREE
;
6841 /* Must be called BEFORE start_function. */
6844 /* Generate prototype declarations for arguments..."new-style". */
6846 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
6847 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6849 /* Really a `struct objc_class *'. However, we allow people to
6850 assign to self, which changes its type midstream. */
6851 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6853 push_parm_decl (build_tree_list
6854 (build_tree_list (decl_specs
,
6855 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6858 decl_specs
= build_tree_list (NULL_TREE
,
6859 xref_tag (RECORD_TYPE
,
6860 get_identifier (TAG_SELECTOR
)));
6861 push_parm_decl (build_tree_list
6862 (build_tree_list (decl_specs
,
6863 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6866 /* Generate argument declarations if a keyword_decl. */
6867 if (METHOD_SEL_ARGS (method
))
6869 tree arglist
= METHOD_SEL_ARGS (method
);
6872 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6873 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6877 tree last_expr
= expr_last (arg_decl
);
6879 /* Unite the abstract decl with its name. */
6880 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6881 push_parm_decl (build_tree_list
6882 (build_tree_list (arg_spec
, arg_decl
),
6885 /* Unhook: restore the abstract declarator. */
6886 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6890 push_parm_decl (build_tree_list
6891 (build_tree_list (arg_spec
,
6892 KEYWORD_ARG_NAME (arglist
)),
6895 arglist
= TREE_CHAIN (arglist
);
6900 if (METHOD_ADD_ARGS (method
) != NULL_TREE
6901 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
6903 /* We have a variable length selector - in "prototype" format. */
6904 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6907 /* This must be done prior to calling pushdecl. pushdecl is
6908 going to change our chain on us. */
6909 tree nextkey
= TREE_CHAIN (akey
);
6917 warn_with_method (message
, mtype
, method
)
6918 const char *message
;
6922 if (count_error (1) == 0)
6925 report_error_function (DECL_SOURCE_FILE (method
));
6927 /* Add a readable method name to the warning. */
6928 warning_with_file_and_line (DECL_SOURCE_FILE (method
),
6929 DECL_SOURCE_LINE (method
),
6932 gen_method_decl (method
, errbuf
));
6935 /* Return 1 if METHOD is consistent with PROTO. */
6938 comp_method_with_proto (method
, proto
)
6941 /* Create a function template node at most once. */
6942 if (!function1_template
)
6943 function1_template
= make_node (FUNCTION_TYPE
);
6945 /* Install argument types - normally set by build_function_type. */
6946 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
6948 /* install return type */
6949 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto
));
6951 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function1_template
);
6954 /* Return 1 if PROTO1 is consistent with PROTO2. */
6957 comp_proto_with_proto (proto0
, proto1
)
6958 tree proto0
, proto1
;
6960 /* Create a couple of function_template nodes at most once. */
6961 if (!function1_template
)
6962 function1_template
= make_node (FUNCTION_TYPE
);
6963 if (!function2_template
)
6964 function2_template
= make_node (FUNCTION_TYPE
);
6966 /* Install argument types; normally set by build_function_type. */
6967 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto0
, METHOD_REF
, 0);
6968 TYPE_ARG_TYPES (function2_template
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
6970 /* Install return type. */
6971 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto0
));
6972 TREE_TYPE (function2_template
) = groktypename (TREE_TYPE (proto1
));
6974 return comptypes (function1_template
, function2_template
);
6977 /* - Generate an identifier for the function. the format is "_n_cls",
6978 where 1 <= n <= nMethods, and cls is the name the implementation we
6980 - Install the return type from the method declaration.
6981 - If we have a prototype, check for type consistency. */
6984 really_start_method (method
, parmlist
)
6985 tree method
, parmlist
;
6987 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
6988 tree method_decl
, method_id
;
6989 const char *sel_name
, *class_name
, *cat_name
;
6992 /* Synth the storage class & assemble the return type. */
6993 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
6994 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
6995 decl_specs
= chainon (sc_spec
, ret_spec
);
6997 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
6998 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
6999 cat_name
= ((TREE_CODE (objc_implementation_context
)
7000 == CLASS_IMPLEMENTATION_TYPE
)
7002 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7005 /* Make sure this is big enough for any plausible method label. */
7006 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7007 + (cat_name
? strlen (cat_name
) : 0));
7009 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7010 class_name
, cat_name
, sel_name
, method_slot
);
7012 method_id
= get_identifier (buf
);
7014 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7016 /* Check the declarator portion of the return type for the method. */
7017 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7019 /* Unite the complex decl (specified in the abstract decl) with the
7020 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7021 tree save_expr
= expr_last (ret_decl
);
7023 TREE_OPERAND (save_expr
, 0) = method_decl
;
7024 method_decl
= ret_decl
;
7026 /* Fool the parser into thinking it is starting a function. */
7027 start_function (decl_specs
, method_decl
, NULL_TREE
);
7029 /* Unhook: this has the effect of restoring the abstract declarator. */
7030 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7035 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7037 /* Fool the parser into thinking it is starting a function. */
7038 start_function (decl_specs
, method_decl
, NULL_TREE
);
7040 /* Unhook: this has the effect of restoring the abstract declarator. */
7041 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7044 METHOD_DEFINITION (method
) = current_function_decl
;
7046 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7048 if (implementation_template
!= objc_implementation_context
)
7052 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7053 proto
= lookup_instance_method_static (implementation_template
,
7054 METHOD_SEL_NAME (method
));
7056 proto
= lookup_class_method_static (implementation_template
,
7057 METHOD_SEL_NAME (method
));
7059 if (proto
&& ! comp_method_with_proto (method
, proto
))
7061 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7063 warn_with_method ("conflicting types for", type
, method
);
7064 warn_with_method ("previous declaration of", type
, proto
);
7069 /* The following routine is always called...this "architecture" is to
7070 accommodate "old-style" variable length selectors.
7072 - a:a b:b // prototype ; id c; id d; // old-style. */
7075 continue_method_def ()
7079 if (METHOD_ADD_ARGS (objc_method_context
) == objc_ellipsis_node
)
7080 /* We have a `, ...' immediately following the selector. */
7081 parmlist
= get_parm_info (0);
7083 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7085 /* Set self_decl from the first argument...this global is used by
7086 build_ivar_reference calling build_indirect_ref. */
7087 self_decl
= TREE_PURPOSE (parmlist
);
7090 really_start_method (objc_method_context
, parmlist
);
7091 store_parm_decls ();
7094 /* Called by the parser, from the `pushlevel' production. */
7099 if (!UOBJC_SUPER_decl
)
7101 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7102 build_tree_list (NULL_TREE
,
7103 objc_super_template
),
7106 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7108 /* This prevents `unused variable' warnings when compiling with -Wall. */
7109 TREE_USED (UOBJC_SUPER_decl
) = 1;
7110 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7114 /* _n_Method (id self, SEL sel, ...)
7116 struct objc_super _S;
7117 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7121 get_super_receiver ()
7123 if (objc_method_context
)
7125 tree super_expr
, super_expr_list
;
7127 /* Set receiver to self. */
7128 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7129 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7130 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7132 /* Set class to begin searching. */
7133 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7134 get_identifier ("class"));
7136 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7138 /* [_cls, __cls]Super are "pre-built" in
7139 synth_forward_declarations. */
7141 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7142 ((TREE_CODE (objc_method_context
)
7143 == INSTANCE_METHOD_DECL
)
7145 : uucls_super_ref
));
7149 /* We have a category. */
7151 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7154 /* Barf if super used in a category of Object. */
7157 error ("no super class declared in interface for `%s'",
7158 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7159 return error_mark_node
;
7162 if (flag_next_runtime
)
7164 super_class
= get_class_reference (super_name
);
7165 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7167 = build_component_ref (build_indirect_ref (super_class
, "->"),
7168 get_identifier ("isa"));
7172 add_class_reference (super_name
);
7173 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7174 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7175 assemble_external (super_class
);
7177 = build_function_call
7181 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7182 IDENTIFIER_POINTER (super_name
))));
7185 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7186 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7189 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7191 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7192 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7194 return build_compound_expr (super_expr_list
);
7198 error ("[super ...] must appear in a method context");
7199 return error_mark_node
;
7204 encode_method_def (func_decl
)
7209 HOST_WIDE_INT max_parm_end
= 0;
7214 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7215 obstack_object_size (&util_obstack
),
7216 OBJC_ENCODE_INLINE_DEFS
);
7219 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7220 parms
= TREE_CHAIN (parms
))
7222 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7223 + int_size_in_bytes (TREE_TYPE (parms
)));
7225 if (! offset_is_register
&& parm_end
> max_parm_end
)
7226 max_parm_end
= parm_end
;
7229 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7231 sprintf (buffer
, "%d", stack_size
);
7232 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7234 /* Argument types. */
7235 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7236 parms
= TREE_CHAIN (parms
))
7239 encode_type (TREE_TYPE (parms
),
7240 obstack_object_size (&util_obstack
),
7241 OBJC_ENCODE_INLINE_DEFS
);
7243 /* Compute offset. */
7244 sprintf (buffer
, "%d", forwarding_offset (parms
));
7246 /* Indicate register. */
7247 if (offset_is_register
)
7248 obstack_1grow (&util_obstack
, '+');
7250 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7253 /* Null terminate string. */
7254 obstack_1grow (&util_obstack
, 0);
7255 result
= get_identifier (obstack_finish (&util_obstack
));
7256 obstack_free (&util_obstack
, util_firstobj
);
7261 objc_expand_function_end ()
7263 METHOD_ENCODING (objc_method_context
) = encode_method_def (current_function_decl
);
7267 finish_method_def ()
7269 lang_expand_function_end
= objc_expand_function_end
;
7270 finish_function (0, 1);
7271 lang_expand_function_end
= NULL
;
7273 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7274 since the optimizer may find "may be used before set" errors. */
7275 objc_method_context
= NULL_TREE
;
7280 lang_report_error_function (decl
)
7283 if (objc_method_context
)
7285 fprintf (stderr
, "In method `%s'\n",
7286 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7296 is_complex_decl (type
)
7299 return (TREE_CODE (type
) == ARRAY_TYPE
7300 || TREE_CODE (type
) == FUNCTION_TYPE
7301 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7305 /* Code to convert a decl node into text for a declaration in C. */
7307 static char tmpbuf
[256];
7310 adorn_decl (decl
, str
)
7314 enum tree_code code
= TREE_CODE (decl
);
7316 if (code
== ARRAY_REF
)
7318 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7320 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7321 sprintf (str
+ strlen (str
), "[%ld]",
7322 (long) TREE_INT_CST_LOW (an_int_cst
));
7327 else if (code
== ARRAY_TYPE
)
7329 tree an_int_cst
= TYPE_SIZE (decl
);
7330 tree array_of
= TREE_TYPE (decl
);
7332 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7333 sprintf (str
+ strlen (str
), "[%ld]",
7334 (long) (TREE_INT_CST_LOW (an_int_cst
)
7335 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7340 else if (code
== CALL_EXPR
)
7342 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7347 gen_declaration_1 (chain
, str
);
7348 chain
= TREE_CHAIN (chain
);
7355 else if (code
== FUNCTION_TYPE
)
7357 tree chain
= TYPE_ARG_TYPES (decl
);
7360 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7362 gen_declaration_1 (TREE_VALUE (chain
), str
);
7363 chain
= TREE_CHAIN (chain
);
7364 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7370 else if (code
== INDIRECT_REF
)
7372 strcpy (tmpbuf
, "*");
7373 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7377 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7379 chain
= TREE_CHAIN (chain
))
7381 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7383 strcat (tmpbuf
, " ");
7384 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7388 strcat (tmpbuf
, " ");
7390 strcat (tmpbuf
, str
);
7391 strcpy (str
, tmpbuf
);
7394 else if (code
== POINTER_TYPE
)
7396 strcpy (tmpbuf
, "*");
7397 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7399 if (TREE_READONLY (decl
))
7400 strcat (tmpbuf
, " const");
7401 if (TYPE_VOLATILE (decl
))
7402 strcat (tmpbuf
, " volatile");
7404 strcat (tmpbuf
, " ");
7406 strcat (tmpbuf
, str
);
7407 strcpy (str
, tmpbuf
);
7412 gen_declarator (decl
, buf
, name
)
7419 enum tree_code code
= TREE_CODE (decl
);
7429 op
= TREE_OPERAND (decl
, 0);
7431 /* We have a pointer to a function or array...(*)(), (*)[] */
7432 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7433 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7436 str
= gen_declarator (op
, buf
, name
);
7440 strcpy (tmpbuf
, "(");
7441 strcat (tmpbuf
, str
);
7442 strcat (tmpbuf
, ")");
7443 strcpy (str
, tmpbuf
);
7446 adorn_decl (decl
, str
);
7455 /* This clause is done iteratively rather than recursively. */
7458 op
= (is_complex_decl (TREE_TYPE (decl
))
7459 ? TREE_TYPE (decl
) : NULL_TREE
);
7461 adorn_decl (decl
, str
);
7463 /* We have a pointer to a function or array...(*)(), (*)[] */
7464 if (code
== POINTER_TYPE
7465 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7466 || TREE_CODE (op
) == ARRAY_TYPE
))
7468 strcpy (tmpbuf
, "(");
7469 strcat (tmpbuf
, str
);
7470 strcat (tmpbuf
, ")");
7471 strcpy (str
, tmpbuf
);
7474 decl
= (is_complex_decl (TREE_TYPE (decl
))
7475 ? TREE_TYPE (decl
) : NULL_TREE
);
7478 while (decl
&& (code
= TREE_CODE (decl
)))
7483 case IDENTIFIER_NODE
:
7484 /* Will only happen if we are processing a "raw" expr-decl. */
7485 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7496 /* We have an abstract declarator or a _DECL node. */
7504 gen_declspecs (declspecs
, buf
, raw
)
7513 for (chain
= nreverse (copy_list (declspecs
));
7514 chain
; chain
= TREE_CHAIN (chain
))
7516 tree aspec
= TREE_VALUE (chain
);
7518 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7519 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7520 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7522 if (TYPE_NAME (aspec
))
7524 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7526 if (! TREE_STATIC_TEMPLATE (aspec
))
7527 strcat (buf
, "struct ");
7528 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7533 tree chain
= protocol_list
;
7540 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7541 chain
= TREE_CHAIN (chain
);
7550 strcat (buf
, "untagged struct");
7553 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7555 if (TYPE_NAME (aspec
))
7557 if (! TREE_STATIC_TEMPLATE (aspec
))
7558 strcat (buf
, "union ");
7559 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7562 strcat (buf
, "untagged union");
7565 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7567 if (TYPE_NAME (aspec
))
7569 if (! TREE_STATIC_TEMPLATE (aspec
))
7570 strcat (buf
, "enum ");
7571 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7574 strcat (buf
, "untagged enum");
7577 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7578 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7580 else if (IS_ID (aspec
))
7582 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7587 tree chain
= protocol_list
;
7594 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7595 chain
= TREE_CHAIN (chain
);
7602 if (TREE_CHAIN (chain
))
7608 /* Type qualifiers. */
7609 if (TREE_READONLY (declspecs
))
7610 strcat (buf
, "const ");
7611 if (TYPE_VOLATILE (declspecs
))
7612 strcat (buf
, "volatile ");
7614 switch (TREE_CODE (declspecs
))
7616 /* Type specifiers. */
7619 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7621 /* Signed integer types. */
7623 if (declspecs
== short_integer_type_node
)
7624 strcat (buf
, "short int ");
7625 else if (declspecs
== integer_type_node
)
7626 strcat (buf
, "int ");
7627 else if (declspecs
== long_integer_type_node
)
7628 strcat (buf
, "long int ");
7629 else if (declspecs
== long_long_integer_type_node
)
7630 strcat (buf
, "long long int ");
7631 else if (declspecs
== signed_char_type_node
7632 || declspecs
== char_type_node
)
7633 strcat (buf
, "char ");
7635 /* Unsigned integer types. */
7637 else if (declspecs
== short_unsigned_type_node
)
7638 strcat (buf
, "unsigned short ");
7639 else if (declspecs
== unsigned_type_node
)
7640 strcat (buf
, "unsigned int ");
7641 else if (declspecs
== long_unsigned_type_node
)
7642 strcat (buf
, "unsigned long ");
7643 else if (declspecs
== long_long_unsigned_type_node
)
7644 strcat (buf
, "unsigned long long ");
7645 else if (declspecs
== unsigned_char_type_node
)
7646 strcat (buf
, "unsigned char ");
7650 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7652 if (declspecs
== float_type_node
)
7653 strcat (buf
, "float ");
7654 else if (declspecs
== double_type_node
)
7655 strcat (buf
, "double ");
7656 else if (declspecs
== long_double_type_node
)
7657 strcat (buf
, "long double ");
7661 if (TYPE_NAME (declspecs
)
7662 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7664 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7666 if (! TREE_STATIC_TEMPLATE (declspecs
))
7667 strcat (buf
, "struct ");
7668 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7672 tree chain
= protocol_list
;
7679 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7680 chain
= TREE_CHAIN (chain
);
7689 strcat (buf
, "untagged struct");
7695 if (TYPE_NAME (declspecs
)
7696 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7698 strcat (buf
, "union ");
7699 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7704 strcat (buf
, "untagged union ");
7708 if (TYPE_NAME (declspecs
)
7709 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7711 strcat (buf
, "enum ");
7712 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7717 strcat (buf
, "untagged enum ");
7721 strcat (buf
, "void ");
7726 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7731 tree chain
= protocol_list
;
7738 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7739 chain
= TREE_CHAIN (chain
);
7755 /* Given a tree node, produce a printable description of it in the given
7756 buffer, overwriting the buffer. */
7759 gen_declaration (atype_or_adecl
, buf
)
7760 tree atype_or_adecl
;
7764 gen_declaration_1 (atype_or_adecl
, buf
);
7768 /* Given a tree node, append a printable description to the end of the
7772 gen_declaration_1 (atype_or_adecl
, buf
)
7773 tree atype_or_adecl
;
7778 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7780 tree declspecs
; /* "identifier_node", "record_type" */
7781 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7783 /* We have a "raw", abstract declarator (typename). */
7784 declarator
= TREE_VALUE (atype_or_adecl
);
7785 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7787 gen_declspecs (declspecs
, buf
, 1);
7791 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7798 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7799 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7801 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7802 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7803 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7804 atype
= TREE_TYPE (atype_or_adecl
);
7806 /* Assume we have a *_type node. */
7807 atype
= atype_or_adecl
;
7809 if (is_complex_decl (atype
))
7813 /* Get the declaration specifier; it is at the end of the list. */
7814 declarator
= chain
= atype
;
7816 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7817 while (is_complex_decl (chain
));
7824 declarator
= NULL_TREE
;
7827 gen_declspecs (declspecs
, buf
, 0);
7829 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7830 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7831 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7833 const char *const decl_name
=
7834 (DECL_NAME (atype_or_adecl
)
7835 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7840 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7843 else if (decl_name
[0])
7846 strcat (buf
, decl_name
);
7849 else if (declarator
)
7852 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7857 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7859 /* Given a method tree, put a printable description into the given
7860 buffer (overwriting) and return a pointer to the buffer. */
7863 gen_method_decl (method
, buf
)
7870 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7873 gen_declaration_1 (TREE_TYPE (method
), buf
);
7877 chain
= METHOD_SEL_ARGS (method
);
7880 /* We have a chain of keyword_decls. */
7883 if (KEYWORD_KEY_NAME (chain
))
7884 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7887 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7890 gen_declaration_1 (TREE_TYPE (chain
), buf
);
7894 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7895 if ((chain
= TREE_CHAIN (chain
)))
7900 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7901 strcat (buf
, ", ...");
7902 else if (METHOD_ADD_ARGS (method
))
7904 /* We have a tree list node as generate by get_parm_info. */
7905 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7907 /* Know we have a chain of parm_decls. */
7911 gen_declaration_1 (chain
, buf
);
7912 chain
= TREE_CHAIN (chain
);
7918 /* We have a unary selector. */
7919 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7927 dump_interface (fp
, chain
)
7931 char *buf
= (char *) xmalloc (256);
7932 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7933 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7934 tree nst_methods
= CLASS_NST_METHODS (chain
);
7935 tree cls_methods
= CLASS_CLS_METHODS (chain
);
7937 fprintf (fp
, "\n@interface %s", my_name
);
7939 if (CLASS_SUPER_NAME (chain
))
7941 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
7942 fprintf (fp
, " : %s\n", super_name
);
7949 fprintf (fp
, "{\n");
7952 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
7953 ivar_decls
= TREE_CHAIN (ivar_decls
);
7956 fprintf (fp
, "}\n");
7961 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
7962 nst_methods
= TREE_CHAIN (nst_methods
);
7967 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
7968 cls_methods
= TREE_CHAIN (cls_methods
);
7970 fprintf (fp
, "\n@end");
7973 /* Demangle function for Objective-C */
7975 objc_demangle (mangled
)
7976 const char *mangled
;
7978 char *demangled
, *cp
;
7980 if (mangled
[0] == '_' &&
7981 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
7984 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
7985 if (mangled
[1] == 'i')
7986 *cp
++ = '-'; /* for instance method */
7988 *cp
++ = '+'; /* for class method */
7989 *cp
++ = '['; /* opening left brace */
7990 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
7991 while (*cp
&& *cp
== '_')
7992 cp
++; /* skip any initial underbars in class name */
7993 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
7996 free(demangled
); /* not mangled name */
7999 if (cp
[1] == '_') /* easy case: no category name */
8001 *cp
++ = ' '; /* replace two '_' with one ' ' */
8002 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8006 *cp
++ = '('; /* less easy case: category name */
8007 cp
= strchr(cp
, '_');
8010 free(demangled
); /* not mangled name */
8014 *cp
++ = ' '; /* overwriting 1st char of method name... */
8015 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8017 while (*cp
&& *cp
== '_')
8018 cp
++; /* skip any initial underbars in method name */
8021 *cp
= ':'; /* replace remaining '_' with ':' */
8022 *cp
++ = ']'; /* closing right brace */
8023 *cp
++ = 0; /* string terminator */
8027 return mangled
; /* not an objc mangled name */
8031 objc_printable_name (decl
, kind
)
8033 int kind ATTRIBUTE_UNUSED
;
8035 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8041 gcc_obstack_init (&util_obstack
);
8042 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8044 errbuf
= (char *) xmalloc (BUFSIZE
);
8046 synth_module_prologue ();
8052 struct imp_entry
*impent
;
8054 /* The internally generated initializers appear to have missing braces.
8055 Don't warn about this. */
8056 int save_warn_missing_braces
= warn_missing_braces
;
8057 warn_missing_braces
= 0;
8059 /* A missing @end may not be detected by the parser. */
8060 if (objc_implementation_context
)
8062 warning ("`@end' missing in implementation context");
8063 finish_class (objc_implementation_context
);
8064 objc_ivar_chain
= NULL_TREE
;
8065 objc_implementation_context
= NULL_TREE
;
8068 generate_forward_declaration_to_string_table ();
8070 #ifdef OBJC_PROLOGUE
8074 /* Process the static instances here because initialization of objc_symtab
8076 if (objc_static_instances
)
8077 generate_static_references ();
8079 if (imp_list
|| class_names_chain
8080 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8081 generate_objc_symtab_decl ();
8083 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8085 objc_implementation_context
= impent
->imp_context
;
8086 implementation_template
= impent
->imp_template
;
8088 UOBJC_CLASS_decl
= impent
->class_decl
;
8089 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8091 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8093 /* all of the following reference the string pool... */
8094 generate_ivar_lists ();
8095 generate_dispatch_tables ();
8096 generate_shared_structures ();
8100 generate_dispatch_tables ();
8101 generate_category (objc_implementation_context
);
8105 /* If we are using an array of selectors, we must always
8106 finish up the array decl even if no selectors were used. */
8107 if (! flag_next_runtime
|| sel_ref_chain
)
8108 build_selector_translation_table ();
8111 generate_protocols ();
8113 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8114 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8116 /* Arrange for ObjC data structures to be initialized at run time. */
8117 rtx init_sym
= build_module_descriptor ();
8118 if (init_sym
&& targetm
.have_ctors_dtors
)
8119 (* targetm
.asm_out
.constructor
) (init_sym
, DEFAULT_INIT_PRIORITY
);
8122 /* Dump the class references. This forces the appropriate classes
8123 to be linked into the executable image, preserving unix archive
8124 semantics. This can be removed when we move to a more dynamically
8125 linked environment. */
8127 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8129 handle_class_ref (chain
);
8130 if (TREE_PURPOSE (chain
))
8131 generate_classref_translation_entry (chain
);
8134 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8135 handle_impent (impent
);
8137 /* Dump the string table last. */
8139 generate_strings ();
8141 if (flag_gen_declaration
)
8143 add_class (objc_implementation_context
);
8144 dump_interface (gen_declaration_file
, objc_implementation_context
);
8152 /* Run through the selector hash tables and print a warning for any
8153 selector which has multiple methods. */
8155 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8156 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8159 tree meth
= hsh
->key
;
8160 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8164 warning ("potential selector conflict for method `%s'",
8165 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8166 warn_with_method ("found", type
, meth
);
8167 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8168 warn_with_method ("found", type
, loop
->value
);
8171 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8172 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8175 tree meth
= hsh
->key
;
8176 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8180 warning ("potential selector conflict for method `%s'",
8181 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8182 warn_with_method ("found", type
, meth
);
8183 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8184 warn_with_method ("found", type
, loop
->value
);
8188 warn_missing_braces
= save_warn_missing_braces
;
8191 /* Subroutines of finish_objc. */
8194 generate_classref_translation_entry (chain
)
8197 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8200 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8202 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8203 expr
= build_c_cast (type
, expr
); /* cast! */
8205 name
= DECL_NAME (TREE_PURPOSE (chain
));
8207 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8209 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8210 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8212 /* The decl that is returned from start_decl is the one that we
8213 forward declared in build_class_reference. */
8214 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
);
8215 DECL_CONTEXT (decl
) = NULL_TREE
;
8216 finish_decl (decl
, expr
, NULL_TREE
);
8221 handle_class_ref (chain
)
8224 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8225 char *string
= (char *) alloca (strlen (name
) + 30);
8229 sprintf (string
, "%sobjc_class_name_%s",
8230 (flag_next_runtime
? "." : "__"), name
);
8232 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8233 if (flag_next_runtime
)
8235 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8240 /* Make a decl for this name, so we can use its address in a tree. */
8241 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8242 DECL_EXTERNAL (decl
) = 1;
8243 TREE_PUBLIC (decl
) = 1;
8246 rest_of_decl_compilation (decl
, 0, 0, 0);
8248 /* Make a decl for the address. */
8249 sprintf (string
, "%sobjc_class_ref_%s",
8250 (flag_next_runtime
? "." : "__"), name
);
8251 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8252 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8253 DECL_INITIAL (decl
) = exp
;
8254 TREE_STATIC (decl
) = 1;
8255 TREE_USED (decl
) = 1;
8258 rest_of_decl_compilation (decl
, 0, 0, 0);
8262 handle_impent (impent
)
8263 struct imp_entry
*impent
;
8267 objc_implementation_context
= impent
->imp_context
;
8268 implementation_template
= impent
->imp_template
;
8270 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8272 const char *const class_name
=
8273 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8275 string
= (char *) alloca (strlen (class_name
) + 30);
8277 sprintf (string
, "%sobjc_class_name_%s",
8278 (flag_next_runtime
? "." : "__"), class_name
);
8280 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8282 const char *const class_name
=
8283 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8284 const char *const class_super_name
=
8285 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8287 string
= (char *) alloca (strlen (class_name
)
8288 + strlen (class_super_name
) + 30);
8290 /* Do the same for categories. Even though no references to
8291 these symbols are generated automatically by the compiler, it
8292 gives you a handle to pull them into an archive by hand. */
8293 sprintf (string
, "*%sobjc_category_name_%s_%s",
8294 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8299 #ifdef ASM_DECLARE_CLASS_REFERENCE
8300 if (flag_next_runtime
)
8302 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8310 init
= build_int_2 (0, 0);
8311 TREE_TYPE (init
) = c_common_type_for_size (BITS_PER_WORD
, 1);
8312 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
8313 TREE_PUBLIC (decl
) = 1;
8314 TREE_READONLY (decl
) = 1;
8315 TREE_USED (decl
) = 1;
8316 TREE_CONSTANT (decl
) = 1;
8317 DECL_CONTEXT (decl
) = 0;
8318 DECL_ARTIFICIAL (decl
) = 1;
8319 DECL_INITIAL (decl
) = init
;
8320 assemble_variable (decl
, 1, 0, 0);
8325 ggc_mark_imp_list (arg
)
8328 struct imp_entry
*impent
;
8330 for (impent
= *(struct imp_entry
**)arg
; impent
; impent
= impent
->next
)
8332 ggc_mark_tree (impent
->imp_context
);
8333 ggc_mark_tree (impent
->imp_template
);
8334 ggc_mark_tree (impent
->class_decl
);
8335 ggc_mark_tree (impent
->meta_decl
);
8340 ggc_mark_hash_table (arg
)
8343 hash
*hash_table
= *(hash
**)arg
;
8348 if (hash_table
== NULL
)
8350 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8351 for (hst
= hash_table
[i
]; hst
; hst
= hst
->next
)
8353 ggc_mark_tree (hst
->key
);
8354 for (list
= hst
->list
; list
; list
= list
->next
)
8355 ggc_mark_tree (list
->value
);
8359 /* Add GC roots for variables local to this file. */
8361 objc_act_parse_init ()
8363 ggc_add_tree_root (objc_global_trees
, OCTI_MAX
);
8364 ggc_add_root (&imp_list
, 1, sizeof imp_list
, ggc_mark_imp_list
);
8365 ggc_add_root (&nst_method_hash_list
, 1, sizeof nst_method_hash_list
, ggc_mark_hash_table
);
8366 ggc_add_root (&cls_method_hash_list
, 1, sizeof cls_method_hash_list
, ggc_mark_hash_table
);
8369 /* Look up ID as an instance variable. */
8371 lookup_objc_ivar (id
)
8376 if (objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8377 /* we have a message to super */
8378 return get_super_receiver ();
8379 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8381 if (is_private (decl
))
8382 return error_mark_node
;
8384 return build_ivar_reference (id
);