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':
44 #include "coretypes.h"
61 #include "diagnostic.h"
63 /* This is the default way of generating a method name. */
64 /* I am not sure it is really correct.
65 Perhaps there's a danger that it will make name conflicts
66 if method names contain underscores. -- rms. */
67 #ifndef OBJC_GEN_METHOD_LABEL
68 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
71 sprintf ((BUF), "_%s_%s_%s_%s", \
72 ((IS_INST) ? "i" : "c"), \
74 ((CAT_NAME)? (CAT_NAME) : ""), \
76 for (temp = (BUF); *temp; temp++) \
77 if (*temp == ':') *temp = '_'; \
81 /* These need specifying. */
82 #ifndef OBJC_FORWARDING_STACK_OFFSET
83 #define OBJC_FORWARDING_STACK_OFFSET 0
86 #ifndef OBJC_FORWARDING_MIN_OFFSET
87 #define OBJC_FORWARDING_MIN_OFFSET 0
91 /* Set up for use of obstacks. */
95 /* This obstack is used to accumulate the encoding of a data type. */
96 static struct obstack util_obstack
;
97 /* This points to the beginning of obstack contents,
98 so we can free the whole contents. */
101 /* for encode_method_def */
104 /* The version identifies which language generation and runtime
105 the module (file) was compiled for, and is recorded in the
106 module descriptor. */
108 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
109 #define PROTOCOL_VERSION 2
111 /* (Decide if these can ever be validly changed.) */
112 #define OBJC_ENCODE_INLINE_DEFS 0
113 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
115 /*** Private Interface (procedures) ***/
117 /* Used by compile_file. */
119 static void init_objc
PARAMS ((void));
120 static void finish_objc
PARAMS ((void));
122 /* Code generation. */
124 static void synth_module_prologue
PARAMS ((void));
125 static tree build_constructor
PARAMS ((tree
, tree
));
126 static rtx build_module_descriptor
PARAMS ((void));
127 static tree init_module_descriptor
PARAMS ((tree
));
128 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
130 static void generate_strings
PARAMS ((void));
131 static tree get_proto_encoding
PARAMS ((tree
));
132 static void build_selector_translation_table
PARAMS ((void));
134 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
136 static tree build_ivar_template
PARAMS ((void));
137 static tree build_method_template
PARAMS ((void));
138 static tree build_private_template
PARAMS ((tree
));
139 static void build_class_template
PARAMS ((void));
140 static void build_selector_template
PARAMS ((void));
141 static void build_category_template
PARAMS ((void));
142 static tree build_super_template
PARAMS ((void));
143 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
145 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
148 static void synth_forward_declarations
PARAMS ((void));
149 static void generate_ivar_lists
PARAMS ((void));
150 static void generate_dispatch_tables
PARAMS ((void));
151 static void generate_shared_structures
PARAMS ((void));
152 static tree generate_protocol_list
PARAMS ((tree
));
153 static void generate_forward_declaration_to_string_table
PARAMS ((void));
154 static void build_protocol_reference
PARAMS ((tree
));
156 static tree build_keyword_selector
PARAMS ((tree
));
157 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
159 static void generate_static_references
PARAMS ((void));
160 static int check_methods_accessible
PARAMS ((tree
, tree
,
162 static void encode_aggregate_within
PARAMS ((tree
, int, int,
164 static const char *objc_demangle
PARAMS ((const char *));
165 static void objc_expand_function_end
PARAMS ((void));
167 /* Hash tables to manage the global pool of method prototypes. */
169 hash
*nst_method_hash_list
= 0;
170 hash
*cls_method_hash_list
= 0;
172 static size_t hash_func
PARAMS ((tree
));
173 static void hash_init
PARAMS ((void));
174 static void hash_enter
PARAMS ((hash
*, tree
));
175 static hash hash_lookup
PARAMS ((hash
*, tree
));
176 static void hash_add_attr
PARAMS ((hash
, tree
));
177 static tree lookup_method
PARAMS ((tree
, tree
));
178 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
179 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
180 static tree add_class
PARAMS ((tree
));
181 static void add_category
PARAMS ((tree
, tree
));
185 class_names
, /* class, category, protocol, module names */
186 meth_var_names
, /* method and variable names */
187 meth_var_types
/* method and variable type descriptors */
190 static tree add_objc_string
PARAMS ((tree
,
191 enum string_section
));
192 static tree get_objc_string_decl
PARAMS ((tree
,
193 enum string_section
));
194 static tree build_objc_string_decl
PARAMS ((enum string_section
));
195 static tree build_selector_reference_decl
PARAMS ((void));
197 /* Protocol additions. */
199 static tree add_protocol
PARAMS ((tree
));
200 static tree lookup_protocol
PARAMS ((tree
));
201 static void check_protocol_recursively
PARAMS ((tree
, tree
));
202 static tree lookup_and_install_protocols
PARAMS ((tree
));
206 static void encode_type_qualifiers
PARAMS ((tree
));
207 static void encode_pointer
PARAMS ((tree
, int, int));
208 static void encode_array
PARAMS ((tree
, int, int));
209 static void encode_aggregate
PARAMS ((tree
, int, int));
210 static void encode_bitfield
PARAMS ((int));
211 static void encode_type
PARAMS ((tree
, int, int));
212 static void encode_field_decl
PARAMS ((tree
, int, int));
214 static void really_start_method
PARAMS ((tree
, tree
));
215 static int comp_method_with_proto
PARAMS ((tree
, tree
));
216 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
217 static tree get_arg_type_list
PARAMS ((tree
, int, int));
218 static tree expr_last
PARAMS ((tree
));
220 /* Utilities for debugging and error diagnostics. */
222 static void warn_with_method
PARAMS ((const char *, int, tree
));
223 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
224 static char *gen_method_decl
PARAMS ((tree
, char *));
225 static char *gen_declaration
PARAMS ((tree
, char *));
226 static void gen_declaration_1
PARAMS ((tree
, char *));
227 static char *gen_declarator
PARAMS ((tree
, char *,
229 static int is_complex_decl
PARAMS ((tree
));
230 static void adorn_decl
PARAMS ((tree
, char *));
231 static void dump_interface
PARAMS ((FILE *, tree
));
233 /* Everything else. */
235 static tree define_decl
PARAMS ((tree
, tree
));
236 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
237 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
238 static tree create_builtin_decl
PARAMS ((enum tree_code
,
239 tree
, const char *));
240 static void setup_string_decl
PARAMS ((void));
241 static void build_string_class_template
PARAMS ((void));
242 static tree my_build_string
PARAMS ((int, const char *));
243 static void build_objc_symtab_template
PARAMS ((void));
244 static tree init_def_list
PARAMS ((tree
));
245 static tree init_objc_symtab
PARAMS ((tree
));
246 static void forward_declare_categories
PARAMS ((void));
247 static void generate_objc_symtab_decl
PARAMS ((void));
248 static tree build_selector
PARAMS ((tree
));
249 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
250 static tree build_selector_reference
PARAMS ((tree
));
251 static tree build_class_reference_decl
PARAMS ((void));
252 static void add_class_reference
PARAMS ((tree
));
253 static tree build_protocol_template
PARAMS ((void));
254 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
255 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
256 static tree build_method_prototype_template
PARAMS ((void));
257 static int forwarding_offset
PARAMS ((tree
));
258 static tree encode_method_prototype
PARAMS ((tree
, tree
));
259 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
261 static void generate_method_descriptors
PARAMS ((tree
));
262 static tree build_tmp_function_decl
PARAMS ((void));
263 static void hack_method_prototype
PARAMS ((tree
, tree
));
264 static void generate_protocol_references
PARAMS ((tree
));
265 static void generate_protocols
PARAMS ((void));
266 static void check_ivars
PARAMS ((tree
, tree
));
267 static tree build_ivar_list_template
PARAMS ((tree
, int));
268 static tree build_method_list_template
PARAMS ((tree
, int));
269 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
270 static tree generate_ivars_list
PARAMS ((tree
, const char *,
272 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
273 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
275 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
276 tree
, int, tree
, tree
,
278 static void generate_category
PARAMS ((tree
));
279 static int is_objc_type_qualifier
PARAMS ((tree
));
280 static tree adjust_type_for_id_default
PARAMS ((tree
));
281 static tree check_duplicates
PARAMS ((hash
));
282 static tree receiver_is_class_object
PARAMS ((tree
));
283 static int check_methods
PARAMS ((tree
, tree
, int));
284 static int conforms_to_protocol
PARAMS ((tree
, tree
));
285 static void check_protocol
PARAMS ((tree
, const char *,
287 static void check_protocols
PARAMS ((tree
, const char *,
289 static tree encode_method_def
PARAMS ((tree
));
290 static void gen_declspecs
PARAMS ((tree
, char *, int));
291 static void generate_classref_translation_entry
PARAMS ((tree
));
292 static void handle_class_ref
PARAMS ((tree
));
293 static void generate_struct_by_value_array
PARAMS ((void))
295 static void encode_complete_bitfield
PARAMS ((int, tree
, int));
297 /*** Private Interface (data) ***/
299 /* Reserved tag definitions. */
302 #define TAG_OBJECT "objc_object"
303 #define TAG_CLASS "objc_class"
304 #define TAG_SUPER "objc_super"
305 #define TAG_SELECTOR "objc_selector"
307 #define UTAG_CLASS "_objc_class"
308 #define UTAG_IVAR "_objc_ivar"
309 #define UTAG_IVAR_LIST "_objc_ivar_list"
310 #define UTAG_METHOD "_objc_method"
311 #define UTAG_METHOD_LIST "_objc_method_list"
312 #define UTAG_CATEGORY "_objc_category"
313 #define UTAG_MODULE "_objc_module"
314 #define UTAG_SYMTAB "_objc_symtab"
315 #define UTAG_SUPER "_objc_super"
316 #define UTAG_SELECTOR "_objc_selector"
318 #define UTAG_PROTOCOL "_objc_protocol"
319 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
320 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
322 /* Note that the string object global name is only needed for the
324 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
326 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
328 static const char *TAG_GETCLASS
;
329 static const char *TAG_GETMETACLASS
;
330 static const char *TAG_MSGSEND
;
331 static const char *TAG_MSGSENDSUPER
;
332 static const char *TAG_EXECCLASS
;
333 static const char *default_constant_string_class_name
;
335 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
336 tree objc_global_trees
[OCTI_MAX
];
338 static void handle_impent
PARAMS ((struct imp_entry
*));
340 struct imp_entry
*imp_list
= 0;
341 int imp_count
= 0; /* `@implementation' */
342 int cat_count
= 0; /* `@category' */
344 static int method_slot
= 0; /* Used by start_method_def, */
348 static char *errbuf
; /* Buffer for error diagnostics */
350 /* Data imported from tree.c. */
352 extern enum debug_info_type write_symbols
;
354 /* Data imported from toplev.c. */
356 extern const char *dump_base_name
;
358 static int flag_typed_selectors
;
360 FILE *gen_declaration_file
;
362 /* Tells "encode_pointer/encode_aggregate" whether we are generating
363 type descriptors for instance variables (as opposed to methods).
364 Type descriptors for instance variables contain more information
365 than methods (for static typing and embedded structures). */
367 static int generating_instance_variables
= 0;
369 /* Some platforms pass small structures through registers versus
370 through an invisible pointer. Determine at what size structure is
371 the transition point between the two possibilities. */
374 generate_struct_by_value_array ()
377 tree field_decl
, field_decl_chain
;
379 int aggregate_in_mem
[32];
382 /* Presumably no platform passes 32 byte structures in a register. */
383 for (i
= 1; i
< 32; i
++)
387 /* Create an unnamed struct that has `i' character components */
388 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
390 strcpy (buffer
, "c1");
391 field_decl
= create_builtin_decl (FIELD_DECL
,
394 field_decl_chain
= field_decl
;
396 for (j
= 1; j
< i
; j
++)
398 sprintf (buffer
, "c%d", j
+ 1);
399 field_decl
= create_builtin_decl (FIELD_DECL
,
402 chainon (field_decl_chain
, field_decl
);
404 finish_struct (type
, field_decl_chain
, NULL_TREE
);
406 aggregate_in_mem
[i
] = aggregate_value_p (type
);
407 if (!aggregate_in_mem
[i
])
411 /* We found some structures that are returned in registers instead of memory
412 so output the necessary data. */
415 for (i
= 31; i
>= 0; i
--)
416 if (!aggregate_in_mem
[i
])
418 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
420 /* The first member of the structure is always 0 because we don't handle
421 structures with 0 members */
422 printf ("static int struct_forward_array[] = {\n 0");
424 for (j
= 1; j
<= i
; j
++)
425 printf (", %d", aggregate_in_mem
[j
]);
434 const char *filename
;
436 filename
= c_objc_common_init (filename
);
437 if (filename
== NULL
)
440 /* Force the line number back to 0; check_newline will have
441 raised it to 1, which will make the builtin functions appear
442 not to be built in. */
445 /* If gen_declaration desired, open the output file. */
446 if (flag_gen_declaration
)
448 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
449 gen_declaration_file
= fopen (dumpname
, "w");
450 if (gen_declaration_file
== 0)
451 fatal_io_error ("can't open %s", dumpname
);
455 if (flag_next_runtime
)
457 TAG_GETCLASS
= "objc_getClass";
458 TAG_GETMETACLASS
= "objc_getMetaClass";
459 TAG_MSGSEND
= "objc_msgSend";
460 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
461 TAG_EXECCLASS
= "__objc_execClass";
462 default_constant_string_class_name
= "NSConstantString";
466 TAG_GETCLASS
= "objc_get_class";
467 TAG_GETMETACLASS
= "objc_get_meta_class";
468 TAG_MSGSEND
= "objc_msg_lookup";
469 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
470 TAG_EXECCLASS
= "__objc_exec_class";
471 default_constant_string_class_name
= "NXConstantString";
472 flag_typed_selectors
= 1;
475 objc_ellipsis_node
= make_node (ERROR_MARK
);
479 if (print_struct_values
)
480 generate_struct_by_value_array ();
488 c_objc_common_finish_file ();
490 /* Finalize Objective-C runtime data. No need to generate tables
491 and code if only checking syntax. */
492 if (!flag_syntax_only
)
495 if (gen_declaration_file
)
496 fclose (gen_declaration_file
);
500 define_decl (declarator
, declspecs
)
504 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
505 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
509 /* Return 1 if LHS and RHS are compatible types for assignment or
510 various other operations. Return 0 if they are incompatible, and
511 return -1 if we choose to not decide. When the operation is
512 REFLEXIVE, check for compatibility in either direction.
514 For statically typed objects, an assignment of the form `a' = `b'
518 `a' and `b' are the same class type, or
519 `a' and `b' are of class types A and B such that B is a descendant of A. */
522 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
530 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
532 p
= TREE_VALUE (rproto
);
534 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
536 if ((fnd
= lookup_method (class_meth
537 ? PROTOCOL_CLS_METHODS (p
)
538 : PROTOCOL_NST_METHODS (p
), sel_name
)))
540 else if (PROTOCOL_LIST (p
))
541 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
542 sel_name
, class_meth
);
546 ; /* An identifier...if we could not find a protocol. */
557 lookup_protocol_in_reflist (rproto_list
, lproto
)
563 /* Make sure the protocol is supported by the object on the rhs. */
564 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
567 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
569 p
= TREE_VALUE (rproto
);
571 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
576 else if (PROTOCOL_LIST (p
))
577 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
586 ; /* An identifier...if we could not find a protocol. */
592 /* Return 1 if LHS and RHS are compatible types for assignment or
593 various other operations. Return 0 if they are incompatible, and
594 return -1 if we choose to not decide (because the types are really
595 just C types, not ObjC specific ones). When the operation is
596 REFLEXIVE (typically comparisons), check for compatibility in
597 either direction; when it's not (typically assignments), don't.
599 This function is called in two cases: when both lhs and rhs are
600 pointers to records (in which case we check protocols too), and
601 when both lhs and rhs are records (in which case we check class
604 Warnings about classes/protocols not implementing a protocol are
605 emitted here (multiple of those warnings might be emitted for a
606 single line!); generic warnings about incompatible assignments and
607 lacks of casts in comparisons are/must be emitted by the caller if
612 objc_comptypes (lhs
, rhs
, reflexive
)
617 /* New clause for protocols. */
619 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
620 manage the ObjC ones, and leave the rest to the C code. */
621 if (TREE_CODE (lhs
) == POINTER_TYPE
622 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
623 && TREE_CODE (rhs
) == POINTER_TYPE
624 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
626 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
627 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
631 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
632 tree rproto
, rproto_list
;
635 /* <Protocol> = <Protocol> */
638 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
642 /* An assignment between objects of type 'id
643 <Protocol>'; make sure the protocol on the lhs is
644 supported by the object on the rhs. */
645 for (lproto
= lproto_list
; lproto
;
646 lproto
= TREE_CHAIN (lproto
))
648 p
= TREE_VALUE (lproto
);
649 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
653 ("object does not conform to the `%s' protocol",
654 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
660 /* Obscure case - a comparison between two objects
661 of type 'id <Protocol>'. Check that either the
662 protocol on the lhs is supported by the object on
663 the rhs, or viceversa. */
665 /* Check if the protocol on the lhs is supported by the
666 object on the rhs. */
667 for (lproto
= lproto_list
; lproto
;
668 lproto
= TREE_CHAIN (lproto
))
670 p
= TREE_VALUE (lproto
);
671 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
675 /* Check failed - check if the protocol on the rhs
676 is supported by the object on the lhs. */
677 for (rproto
= rproto_list
; rproto
;
678 rproto
= TREE_CHAIN (rproto
))
680 p
= TREE_VALUE (rproto
);
681 lproto
= lookup_protocol_in_reflist (lproto_list
,
686 /* This check failed too: incompatible */
696 /* <Protocol> = <class> * */
697 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
699 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
702 /* Make sure the protocol is supported by the object on
704 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
706 p
= TREE_VALUE (lproto
);
708 rinter
= lookup_interface (rname
);
710 while (rinter
&& !rproto
)
714 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
715 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
716 /* If the underlying ObjC class does not have
717 the protocol we're looking for, check for "one-off"
718 protocols (e.g., `NSObject<MyProt> *foo;') attached
722 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
723 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
726 /* Check for protocols adopted by categories. */
727 cat
= CLASS_CATEGORY_LIST (rinter
);
728 while (cat
&& !rproto
)
730 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
731 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
732 cat
= CLASS_CATEGORY_LIST (cat
);
735 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
739 warning ("class `%s' does not implement the `%s' protocol",
740 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
741 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
745 /* <Protocol> = id */
746 else if (TYPE_NAME (TREE_TYPE (rhs
)) == objc_object_id
)
750 /* <Protocol> = Class */
751 else if (TYPE_NAME (TREE_TYPE (rhs
)) == objc_class_id
)
755 /* <Protocol> = ?? : let comptypes decide. */
758 else if (rhs_is_proto
)
760 /* <class> * = <Protocol> */
761 if (TYPED_OBJECT (TREE_TYPE (lhs
)))
765 tree rname
= TYPE_NAME (TREE_TYPE (lhs
));
767 tree rproto
, rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
769 /* Make sure the protocol is supported by the object on
771 for (rproto
= rproto_list
; rproto
;
772 rproto
= TREE_CHAIN (rproto
))
774 tree p
= TREE_VALUE (rproto
);
776 rinter
= lookup_interface (rname
);
778 while (rinter
&& !lproto
)
782 tree lproto_list
= CLASS_PROTOCOL_LIST (rinter
);
783 lproto
= lookup_protocol_in_reflist (lproto_list
, p
);
784 /* If the underlying ObjC class does not
785 have the protocol we're looking for,
786 check for "one-off" protocols (e.g.,
787 `NSObject<MyProt> *foo;') attached to the
791 lproto_list
= TYPE_PROTOCOL_LIST
793 lproto
= lookup_protocol_in_reflist
797 /* Check for protocols adopted by categories. */
798 cat
= CLASS_CATEGORY_LIST (rinter
);
799 while (cat
&& !lproto
)
801 lproto_list
= CLASS_PROTOCOL_LIST (cat
);
802 lproto
= lookup_protocol_in_reflist (lproto_list
,
804 cat
= CLASS_CATEGORY_LIST (cat
);
807 rinter
= lookup_interface (CLASS_SUPER_NAME
812 warning ("class `%s' does not implement the `%s' protocol",
813 IDENTIFIER_POINTER (TYPE_NAME
815 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
822 /* id = <Protocol> */
823 else if (TYPE_NAME (TREE_TYPE (lhs
)) == objc_object_id
)
827 /* Class = <Protocol> */
828 else if (TYPE_NAME (TREE_TYPE (lhs
)) == objc_class_id
)
832 /* ??? = <Protocol> : let comptypes decide */
840 /* Attention: we shouldn't defer to comptypes here. One bad
841 side effect would be that we might loose the REFLEXIVE
844 lhs
= TREE_TYPE (lhs
);
845 rhs
= TREE_TYPE (rhs
);
849 if (TREE_CODE (lhs
) != RECORD_TYPE
|| TREE_CODE (rhs
) != RECORD_TYPE
)
851 /* Nothing to do with ObjC - let immediately comptypes take
852 responsibility for checking. */
856 /* `id' = `<class> *' `<class> *' = `id': always allow it.
858 'Object *o = [[Object alloc] init]; falls
859 in the case <class> * = `id'.
861 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
862 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
865 /* `id' = `Class', `Class' = `id' */
867 else if ((TYPE_NAME (lhs
) == objc_object_id
868 && TYPE_NAME (rhs
) == objc_class_id
)
869 || (TYPE_NAME (lhs
) == objc_class_id
870 && TYPE_NAME (rhs
) == objc_object_id
))
873 /* `<class> *' = `<class> *' */
875 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
877 tree lname
= TYPE_NAME (lhs
);
878 tree rname
= TYPE_NAME (rhs
);
884 /* If the left hand side is a super class of the right hand side,
886 for (inter
= lookup_interface (rname
); inter
;
887 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
888 if (lname
== CLASS_SUPER_NAME (inter
))
891 /* Allow the reverse when reflexive. */
893 for (inter
= lookup_interface (lname
); inter
;
894 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
895 if (rname
== CLASS_SUPER_NAME (inter
))
901 /* Not an ObjC type - let comptypes do the check. */
905 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
908 objc_check_decl (decl
)
911 tree type
= TREE_TYPE (decl
);
913 if (TREE_CODE (type
) == RECORD_TYPE
914 && TREE_STATIC_TEMPLATE (type
)
915 && type
!= constant_string_type
)
916 error_with_decl (decl
, "`%s' cannot be statically allocated");
919 /* Implement static typing. At this point, we know we have an interface. */
922 get_static_reference (interface
, protocols
)
926 tree type
= xref_tag (RECORD_TYPE
, interface
);
930 tree t
, m
= TYPE_MAIN_VARIANT (type
);
932 t
= copy_node (type
);
934 /* Add this type to the chain of variants of TYPE. */
935 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
936 TYPE_NEXT_VARIANT (m
) = t
;
938 /* Look up protocols and install in lang specific list. Note
939 that the protocol list can have a different lifetime than T! */
940 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
942 /* This forces a new pointer type to be created later
943 (in build_pointer_type)...so that the new template
944 we just created will actually be used...what a hack! */
945 if (TYPE_POINTER_TO (t
))
946 TYPE_POINTER_TO (t
) = NULL_TREE
;
955 get_object_reference (protocols
)
958 tree type_decl
= lookup_name (objc_id_id
);
961 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
963 type
= TREE_TYPE (type_decl
);
964 if (TYPE_MAIN_VARIANT (type
) != id_type
)
965 warning ("unexpected type for `id' (%s)",
966 gen_declaration (type
, errbuf
));
970 error ("undefined type `id', please import <objc/objc.h>");
971 return error_mark_node
;
974 /* This clause creates a new pointer type that is qualified with
975 the protocol specification...this info is used later to do more
976 elaborate type checking. */
980 tree t
, m
= TYPE_MAIN_VARIANT (type
);
982 t
= copy_node (type
);
984 /* Add this type to the chain of variants of TYPE. */
985 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
986 TYPE_NEXT_VARIANT (m
) = t
;
988 /* Look up protocols...and install in lang specific list */
989 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
991 /* This forces a new pointer type to be created later
992 (in build_pointer_type)...so that the new template
993 we just created will actually be used...what a hack! */
994 if (TYPE_POINTER_TO (t
))
995 TYPE_POINTER_TO (t
) = NULL_TREE
;
1002 /* Check for circular dependencies in protocols. The arguments are
1003 PROTO, the protocol to check, and LIST, a list of protocol it
1007 check_protocol_recursively (proto
, list
)
1013 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1015 tree pp
= TREE_VALUE (p
);
1017 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1018 pp
= lookup_protocol (pp
);
1021 fatal_error ("protocol `%s' has circular dependency",
1022 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1024 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1029 lookup_and_install_protocols (protocols
)
1034 tree return_value
= protocols
;
1036 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1038 tree ident
= TREE_VALUE (proto
);
1039 tree p
= lookup_protocol (ident
);
1043 error ("cannot find protocol declaration for `%s'",
1044 IDENTIFIER_POINTER (ident
));
1046 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1048 return_value
= TREE_CHAIN (proto
);
1052 /* Replace identifier with actual protocol node. */
1053 TREE_VALUE (proto
) = p
;
1058 return return_value
;
1061 /* Create and push a decl for a built-in external variable or field NAME.
1063 TYPE is its data type. */
1066 create_builtin_decl (code
, type
, name
)
1067 enum tree_code code
;
1071 tree decl
= build_decl (code
, get_identifier (name
), type
);
1073 if (code
== VAR_DECL
)
1075 TREE_STATIC (decl
) = 1;
1076 make_decl_rtl (decl
, 0);
1080 DECL_ARTIFICIAL (decl
) = 1;
1084 /* Find the decl for the constant string class. */
1087 setup_string_decl ()
1089 if (!string_class_decl
)
1091 if (!constant_string_global_id
)
1092 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
1093 string_class_decl
= lookup_name (constant_string_global_id
);
1097 /* Purpose: "play" parser, creating/installing representations
1098 of the declarations that are required by Objective-C.
1102 type_spec--------->sc_spec
1103 (tree_list) (tree_list)
1106 identifier_node identifier_node */
1109 synth_module_prologue ()
1114 /* Defined in `objc.h' */
1115 objc_object_id
= get_identifier (TAG_OBJECT
);
1117 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1119 id_type
= build_pointer_type (objc_object_reference
);
1121 objc_id_id
= get_identifier (TYPE_ID
);
1122 objc_class_id
= get_identifier (TAG_CLASS
);
1124 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1125 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1126 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1128 /* Declare type of selector-objects that represent an operation name. */
1130 /* `struct objc_selector *' */
1132 = build_pointer_type (xref_tag (RECORD_TYPE
,
1133 get_identifier (TAG_SELECTOR
)));
1135 /* Forward declare type, or else the prototype for msgSendSuper will
1138 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1139 get_identifier (TAG_SUPER
)));
1142 /* id objc_msgSend (id, SEL, ...); */
1145 = build_function_type (id_type
,
1146 tree_cons (NULL_TREE
, id_type
,
1147 tree_cons (NULL_TREE
, selector_type
,
1150 if (! flag_next_runtime
)
1152 umsg_decl
= build_decl (FUNCTION_DECL
,
1153 get_identifier (TAG_MSGSEND
), temp_type
);
1154 DECL_EXTERNAL (umsg_decl
) = 1;
1155 TREE_PUBLIC (umsg_decl
) = 1;
1156 DECL_INLINE (umsg_decl
) = 1;
1157 DECL_ARTIFICIAL (umsg_decl
) = 1;
1159 make_decl_rtl (umsg_decl
, NULL
);
1160 pushdecl (umsg_decl
);
1163 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
,
1166 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1169 = build_function_type (id_type
,
1170 tree_cons (NULL_TREE
, super_p
,
1171 tree_cons (NULL_TREE
, selector_type
,
1174 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1175 temp_type
, 0, NOT_BUILT_IN
,
1178 /* id objc_getClass (const char *); */
1180 temp_type
= build_function_type (id_type
,
1181 tree_cons (NULL_TREE
,
1182 const_string_type_node
,
1183 tree_cons (NULL_TREE
, void_type_node
,
1187 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
,
1190 /* id objc_getMetaClass (const char *); */
1192 objc_get_meta_class_decl
1193 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
,
1196 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1198 if (! flag_next_runtime
)
1200 if (flag_typed_selectors
)
1202 /* Suppress outputting debug symbols, because
1203 dbxout_init hasn'r been called yet. */
1204 enum debug_info_type save_write_symbols
= write_symbols
;
1205 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
1206 write_symbols
= NO_DEBUG
;
1207 debug_hooks
= &do_nothing_debug_hooks
;
1209 build_selector_template ();
1210 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1212 write_symbols
= save_write_symbols
;
1213 debug_hooks
= save_hooks
;
1216 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1218 layout_type (temp_type
);
1219 UOBJC_SELECTOR_TABLE_decl
1220 = create_builtin_decl (VAR_DECL
, temp_type
,
1221 "_OBJC_SELECTOR_TABLE");
1223 /* Avoid warning when not sending messages. */
1224 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1227 generate_forward_declaration_to_string_table ();
1229 /* Forward declare constant_string_id and constant_string_type. */
1230 if (!constant_string_class_name
)
1231 constant_string_class_name
= default_constant_string_class_name
;
1233 constant_string_id
= get_identifier (constant_string_class_name
);
1234 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1237 /* Predefine the following data type:
1239 struct STRING_OBJECT_CLASS_NAME
1243 unsigned int length;
1247 build_string_class_template ()
1249 tree field_decl
, field_decl_chain
;
1251 field_decl
= create_builtin_decl (FIELD_DECL
, id_type
, "isa");
1252 field_decl_chain
= field_decl
;
1254 field_decl
= create_builtin_decl (FIELD_DECL
,
1255 build_pointer_type (char_type_node
),
1257 chainon (field_decl_chain
, field_decl
);
1259 field_decl
= create_builtin_decl (FIELD_DECL
, unsigned_type_node
, "length");
1260 chainon (field_decl_chain
, field_decl
);
1262 finish_struct (constant_string_type
, field_decl_chain
, NULL_TREE
);
1265 /* Custom build_string which sets TREE_TYPE! */
1268 my_build_string (len
, str
)
1272 return fix_string_type (build_string (len
, str
));
1275 /* Given a chain of STRING_CST's, build a static instance of
1276 NXConstantString which points at the concatenation of those strings.
1277 We place the string object in the __string_objects section of the
1278 __OBJC segment. The Objective-C runtime will initialize the isa
1279 pointers of the string objects to point at the NXConstantString
1283 build_objc_string_object (strings
)
1286 tree string
, initlist
, constructor
;
1289 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1291 error ("cannot find interface declaration for `%s'",
1292 IDENTIFIER_POINTER (constant_string_id
));
1293 return error_mark_node
;
1296 add_class_reference (constant_string_id
);
1298 if (TREE_CHAIN (strings
))
1300 varray_type vstrings
;
1301 VARRAY_TREE_INIT (vstrings
, 32, "strings");
1303 for (; strings
; strings
= TREE_CHAIN (strings
))
1304 VARRAY_PUSH_TREE (vstrings
, strings
);
1306 string
= combine_strings (vstrings
);
1311 string
= fix_string_type (string
);
1313 TREE_SET_CODE (string
, STRING_CST
);
1314 length
= TREE_STRING_LENGTH (string
) - 1;
1316 /* We could not properly create NXConstantString in synth_module_prologue,
1317 because that's called before debugging is initialized. Do it now. */
1318 if (TYPE_FIELDS (constant_string_type
) == NULL_TREE
)
1319 build_string_class_template ();
1321 /* & ((NXConstantString) { NULL, string, length }) */
1323 if (flag_next_runtime
)
1325 /* For the NeXT runtime, we can generate a literal reference
1326 to the string class, don't need to run a constructor. */
1327 setup_string_decl ();
1328 if (string_class_decl
== NULL_TREE
)
1330 error ("cannot find reference tag for class `%s'",
1331 IDENTIFIER_POINTER (constant_string_id
));
1332 return error_mark_node
;
1334 initlist
= build_tree_list
1336 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1340 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1344 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1346 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1347 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1349 if (!flag_next_runtime
)
1352 = objc_add_static_instance (constructor
, constant_string_type
);
1355 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1358 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1361 objc_add_static_instance (constructor
, class_decl
)
1362 tree constructor
, class_decl
;
1364 static int num_static_inst
;
1368 /* Find the list of static instances for the CLASS_DECL. Create one if
1370 for (chain
= &objc_static_instances
;
1371 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1372 chain
= &TREE_CHAIN (*chain
));
1375 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1376 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1379 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1380 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1381 DECL_COMMON (decl
) = 1;
1382 TREE_STATIC (decl
) = 1;
1383 DECL_ARTIFICIAL (decl
) = 1;
1384 DECL_INITIAL (decl
) = constructor
;
1386 /* We may be writing something else just now.
1387 Postpone till end of input. */
1388 DECL_DEFER_OUTPUT (decl
) = 1;
1389 pushdecl_top_level (decl
);
1390 rest_of_decl_compilation (decl
, 0, 1, 0);
1392 /* Add the DECL to the head of this CLASS' list. */
1393 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1398 /* Build a static constant CONSTRUCTOR
1399 with type TYPE and elements ELTS. */
1402 build_constructor (type
, elts
)
1405 tree constructor
, f
, e
;
1407 /* ??? Most of the places that we build constructors, we don't fill in
1408 the type of integers properly. Convert them all en masse. */
1409 if (TREE_CODE (type
) == ARRAY_TYPE
)
1411 f
= TREE_TYPE (type
);
1412 if (TREE_CODE (f
) == POINTER_TYPE
|| TREE_CODE (f
) == INTEGER_TYPE
)
1413 for (e
= elts
; e
; e
= TREE_CHAIN (e
))
1414 TREE_VALUE (e
) = convert (f
, TREE_VALUE (e
));
1418 f
= TYPE_FIELDS (type
);
1419 for (e
= elts
; e
&& f
; e
= TREE_CHAIN (e
), f
= TREE_CHAIN (f
))
1420 if (TREE_CODE (TREE_TYPE (f
)) == POINTER_TYPE
1421 || TREE_CODE (TREE_TYPE (f
)) == INTEGER_TYPE
)
1422 TREE_VALUE (e
) = convert (TREE_TYPE (f
), TREE_VALUE (e
));
1425 constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1426 TREE_CONSTANT (constructor
) = 1;
1427 TREE_STATIC (constructor
) = 1;
1428 TREE_READONLY (constructor
) = 1;
1433 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1435 /* Predefine the following data type:
1443 void *defs[cls_def_cnt + cat_def_cnt];
1447 build_objc_symtab_template ()
1449 tree field_decl
, field_decl_chain
, index
;
1451 objc_symtab_template
1452 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1454 /* long sel_ref_cnt; */
1456 field_decl
= create_builtin_decl (FIELD_DECL
,
1457 long_integer_type_node
,
1459 field_decl_chain
= field_decl
;
1463 field_decl
= create_builtin_decl (FIELD_DECL
,
1464 build_pointer_type (selector_type
),
1466 chainon (field_decl_chain
, field_decl
);
1468 /* short cls_def_cnt; */
1470 field_decl
= create_builtin_decl (FIELD_DECL
,
1471 short_integer_type_node
,
1473 chainon (field_decl_chain
, field_decl
);
1475 /* short cat_def_cnt; */
1477 field_decl
= create_builtin_decl (FIELD_DECL
,
1478 short_integer_type_node
,
1480 chainon (field_decl_chain
, field_decl
);
1482 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1484 if (!flag_next_runtime
)
1485 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1487 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1488 imp_count
== 0 && cat_count
== 0
1490 field_decl
= create_builtin_decl (FIELD_DECL
,
1491 build_array_type (ptr_type_node
, index
),
1493 chainon (field_decl_chain
, field_decl
);
1495 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1498 /* Create the initial value for the `defs' field of _objc_symtab.
1499 This is a CONSTRUCTOR. */
1502 init_def_list (type
)
1505 tree expr
, initlist
= NULL_TREE
;
1506 struct imp_entry
*impent
;
1509 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1511 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1513 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1514 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1519 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1521 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1523 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1524 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1528 if (!flag_next_runtime
)
1530 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1533 if (static_instances_decl
)
1534 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1536 expr
= build_int_2 (0, 0);
1538 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1541 return build_constructor (type
, nreverse (initlist
));
1544 /* Construct the initial value for all of _objc_symtab. */
1547 init_objc_symtab (type
)
1552 /* sel_ref_cnt = { ..., 5, ... } */
1554 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1556 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1558 if (flag_next_runtime
|| ! sel_ref_chain
)
1559 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1561 initlist
= tree_cons (NULL_TREE
,
1562 build_unary_op (ADDR_EXPR
,
1563 UOBJC_SELECTOR_TABLE_decl
, 1),
1566 /* cls_def_cnt = { ..., 5, ... } */
1568 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1570 /* cat_def_cnt = { ..., 5, ... } */
1572 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1574 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1576 if (imp_count
|| cat_count
|| static_instances_decl
)
1579 tree field
= TYPE_FIELDS (type
);
1580 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1582 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1586 return build_constructor (type
, nreverse (initlist
));
1589 /* Push forward-declarations of all the categories so that
1590 init_def_list can use them in a CONSTRUCTOR. */
1593 forward_declare_categories ()
1595 struct imp_entry
*impent
;
1596 tree sav
= objc_implementation_context
;
1598 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1600 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1602 /* Set an invisible arg to synth_id_with_class_suffix. */
1603 objc_implementation_context
= impent
->imp_context
;
1605 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1606 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context
)));
1609 objc_implementation_context
= sav
;
1612 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1613 and initialized appropriately. */
1616 generate_objc_symtab_decl ()
1620 if (!objc_category_template
)
1621 build_category_template ();
1623 /* forward declare categories */
1625 forward_declare_categories ();
1627 if (!objc_symtab_template
)
1628 build_objc_symtab_template ();
1630 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1632 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1633 tree_cons (NULL_TREE
,
1634 objc_symtab_template
, sc_spec
),
1638 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1639 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1640 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1641 finish_decl (UOBJC_SYMBOLS_decl
,
1642 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1647 init_module_descriptor (type
)
1650 tree initlist
, expr
;
1652 /* version = { 1, ... } */
1654 expr
= build_int_2 (OBJC_VERSION
, 0);
1655 initlist
= build_tree_list (NULL_TREE
, expr
);
1657 /* size = { ..., sizeof (struct objc_module), ... } */
1659 expr
= size_in_bytes (objc_module_template
);
1660 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1662 /* name = { ..., "foo.m", ... } */
1664 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1665 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1667 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1669 if (UOBJC_SYMBOLS_decl
)
1670 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1672 expr
= build_int_2 (0, 0);
1673 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1675 return build_constructor (type
, nreverse (initlist
));
1678 /* Write out the data structures to describe Objective C classes defined.
1679 If appropriate, compile and output a setup function to initialize them.
1680 Return a symbol_ref to the function to call to initialize the Objective C
1681 data structures for this file (and perhaps for other files also).
1683 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1686 build_module_descriptor ()
1688 tree decl_specs
, field_decl
, field_decl_chain
;
1690 objc_module_template
1691 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1695 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1696 field_decl
= get_identifier ("version");
1698 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1699 field_decl_chain
= field_decl
;
1703 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1704 field_decl
= get_identifier ("size");
1706 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1707 chainon (field_decl_chain
, field_decl
);
1711 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1712 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1714 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1715 chainon (field_decl_chain
, field_decl
);
1717 /* struct objc_symtab *symtab; */
1719 decl_specs
= get_identifier (UTAG_SYMTAB
);
1720 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1721 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1723 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1724 chainon (field_decl_chain
, field_decl
);
1726 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1728 /* Create an instance of "objc_module". */
1730 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1731 build_tree_list (NULL_TREE
,
1732 ridpointers
[(int) RID_STATIC
]));
1734 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1735 decl_specs
, 1, NULL_TREE
);
1737 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1738 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1739 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1741 finish_decl (UOBJC_MODULES_decl
,
1742 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1745 /* Mark the decl to avoid "defined but not used" warning. */
1746 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1748 /* Generate a constructor call for the module descriptor.
1749 This code was generated by reading the grammar rules
1750 of c-parse.in; Therefore, it may not be the most efficient
1751 way of generating the requisite code. */
1753 if (flag_next_runtime
)
1757 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1758 tree init_function_name
, init_function_decl
;
1760 /* Declare void __objc_execClass (void *); */
1762 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1763 execclass_decl
= build_decl (FUNCTION_DECL
,
1764 get_identifier (TAG_EXECCLASS
),
1765 build_function_type (void_type_node
,
1766 tree_cons (NULL_TREE
, ptr_type_node
,
1767 void_list_node_1
)));
1768 DECL_EXTERNAL (execclass_decl
) = 1;
1769 DECL_ARTIFICIAL (execclass_decl
) = 1;
1770 TREE_PUBLIC (execclass_decl
) = 1;
1771 pushdecl (execclass_decl
);
1772 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1773 assemble_external (execclass_decl
);
1775 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1777 init_function_name
= get_file_function_name ('I');
1778 start_function (void_list_node_1
,
1779 build_nt (CALL_EXPR
, init_function_name
,
1780 tree_cons (NULL_TREE
, NULL_TREE
,
1784 store_parm_decls ();
1786 init_function_decl
= current_function_decl
;
1787 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1788 TREE_USED (init_function_decl
) = 1;
1789 /* Don't let this one be deferred. */
1790 DECL_INLINE (init_function_decl
) = 0;
1791 DECL_UNINLINABLE (init_function_decl
) = 1;
1792 current_function_cannot_inline
1793 = "static constructors and destructors cannot be inlined";
1796 = build_tree_list (NULL_TREE
,
1797 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1798 decelerator
= build_function_call (execclass_decl
, parms
);
1800 c_expand_expr_stmt (decelerator
);
1802 finish_function (0, 0);
1804 return XEXP (DECL_RTL (init_function_decl
), 0);
1808 /* extern const char _OBJC_STRINGS[]; */
1811 generate_forward_declaration_to_string_table ()
1813 tree sc_spec
, decl_specs
, expr_decl
;
1815 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1816 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1819 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1821 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1824 /* Return the DECL of the string IDENT in the SECTION. */
1827 get_objc_string_decl (ident
, section
)
1829 enum string_section section
;
1833 if (section
== class_names
)
1834 chain
= class_names_chain
;
1835 else if (section
== meth_var_names
)
1836 chain
= meth_var_names_chain
;
1837 else if (section
== meth_var_types
)
1838 chain
= meth_var_types_chain
;
1842 for (; chain
!= 0; chain
= TREE_CHAIN (chain
))
1843 if (TREE_VALUE (chain
) == ident
)
1844 return (TREE_PURPOSE (chain
));
1850 /* Output references to all statically allocated objects. Return the DECL
1851 for the array built. */
1854 generate_static_references ()
1856 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1857 tree class_name
, class, decl
, initlist
;
1858 tree cl_chain
, in_chain
, type
;
1859 int num_inst
, num_class
;
1862 if (flag_next_runtime
)
1865 for (cl_chain
= objc_static_instances
, num_class
= 0;
1866 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1868 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1869 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1871 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1872 ident
= get_identifier (buf
);
1874 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1875 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1876 build_tree_list (NULL_TREE
,
1877 ridpointers
[(int) RID_STATIC
]));
1878 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1879 DECL_CONTEXT (decl
) = 0;
1880 DECL_ARTIFICIAL (decl
) = 1;
1882 /* Output {class_name, ...}. */
1883 class = TREE_VALUE (cl_chain
);
1884 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1885 initlist
= build_tree_list (NULL_TREE
,
1886 build_unary_op (ADDR_EXPR
, class_name
, 1));
1888 /* Output {..., instance, ...}. */
1889 for (in_chain
= TREE_PURPOSE (cl_chain
);
1890 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1892 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1893 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1896 /* Output {..., NULL}. */
1897 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1899 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1900 finish_decl (decl
, expr
, NULL_TREE
);
1901 TREE_USED (decl
) = 1;
1903 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1904 decl
= build_decl (VAR_DECL
, ident
, type
);
1905 TREE_USED (decl
) = 1;
1906 TREE_STATIC (decl
) = 1;
1908 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1911 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1912 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1913 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1914 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1915 build_tree_list (NULL_TREE
,
1916 ridpointers
[(int) RID_STATIC
]));
1917 static_instances_decl
1918 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1919 TREE_USED (static_instances_decl
) = 1;
1920 DECL_CONTEXT (static_instances_decl
) = 0;
1921 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1922 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1924 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1927 /* Output all strings. */
1932 tree sc_spec
, decl_specs
, expr_decl
;
1933 tree chain
, string_expr
;
1936 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1938 string
= TREE_VALUE (chain
);
1939 decl
= TREE_PURPOSE (chain
);
1941 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1942 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1943 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1944 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1945 DECL_CONTEXT (decl
) = NULL_TREE
;
1946 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1947 IDENTIFIER_POINTER (string
));
1948 finish_decl (decl
, string_expr
, NULL_TREE
);
1951 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1953 string
= TREE_VALUE (chain
);
1954 decl
= TREE_PURPOSE (chain
);
1956 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1957 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1958 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1959 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1960 DECL_CONTEXT (decl
) = NULL_TREE
;
1961 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1962 IDENTIFIER_POINTER (string
));
1963 finish_decl (decl
, string_expr
, NULL_TREE
);
1966 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1968 string
= TREE_VALUE (chain
);
1969 decl
= TREE_PURPOSE (chain
);
1971 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1972 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1973 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1974 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1975 DECL_CONTEXT (decl
) = NULL_TREE
;
1976 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1977 IDENTIFIER_POINTER (string
));
1978 finish_decl (decl
, string_expr
, NULL_TREE
);
1983 build_selector_reference_decl ()
1989 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1991 ident
= get_identifier (buf
);
1993 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1994 DECL_EXTERNAL (decl
) = 1;
1995 TREE_PUBLIC (decl
) = 1;
1996 TREE_USED (decl
) = 1;
1997 TREE_READONLY (decl
) = 1;
1998 DECL_ARTIFICIAL (decl
) = 1;
1999 DECL_CONTEXT (decl
) = 0;
2001 make_decl_rtl (decl
, 0);
2002 pushdecl_top_level (decl
);
2007 /* Just a handy wrapper for add_objc_string. */
2010 build_selector (ident
)
2013 tree expr
= add_objc_string (ident
, meth_var_names
);
2014 if (flag_typed_selectors
)
2017 return build_c_cast (selector_type
, expr
); /* cast! */
2021 build_selector_translation_table ()
2023 tree sc_spec
, decl_specs
;
2024 tree chain
, initlist
= NULL_TREE
;
2026 tree decl
= NULL_TREE
, var_decl
, name
;
2028 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2032 if (warn_selector
&& objc_implementation_context
)
2036 for (method_chain
= meth_var_names_chain
;
2038 method_chain
= TREE_CHAIN (method_chain
))
2040 if (TREE_VALUE (method_chain
) == TREE_VALUE (chain
))
2048 /* Adjust line number for warning message. */
2049 int save_lineno
= lineno
;
2050 if (flag_next_runtime
&& TREE_PURPOSE (chain
))
2051 lineno
= DECL_SOURCE_LINE (TREE_PURPOSE (chain
));
2052 warning ("creating selector for non existant method %s",
2053 IDENTIFIER_POINTER (TREE_VALUE (chain
)));
2054 lineno
= save_lineno
;
2058 expr
= build_selector (TREE_VALUE (chain
));
2060 if (flag_next_runtime
)
2062 name
= DECL_NAME (TREE_PURPOSE (chain
));
2064 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2066 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2067 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2071 /* The `decl' that is returned from start_decl is the one that we
2072 forward declared in `build_selector_reference' */
2073 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
2076 /* add one for the '\0' character */
2077 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2079 if (flag_next_runtime
)
2080 finish_decl (decl
, expr
, NULL_TREE
);
2083 if (flag_typed_selectors
)
2085 tree eltlist
= NULL_TREE
;
2086 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2087 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2088 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2089 expr
= build_constructor (objc_selector_template
,
2090 nreverse (eltlist
));
2092 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2097 if (! flag_next_runtime
)
2099 /* Cause the variable and its initial value to be actually output. */
2100 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2101 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2102 /* NULL terminate the list and fix the decl for output. */
2103 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2104 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2105 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2106 nreverse (initlist
));
2107 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2108 current_function_decl
= NULL_TREE
;
2113 get_proto_encoding (proto
)
2121 if (! METHOD_ENCODING (proto
))
2123 tmp_decl
= build_tmp_function_decl ();
2124 hack_method_prototype (proto
, tmp_decl
);
2125 encoding
= encode_method_prototype (proto
, tmp_decl
);
2126 METHOD_ENCODING (proto
) = encoding
;
2129 encoding
= METHOD_ENCODING (proto
);
2131 return add_objc_string (encoding
, meth_var_types
);
2134 return build_int_2 (0, 0);
2137 /* sel_ref_chain is a list whose "value" fields will be instances of
2138 identifier_node that represent the selector. */
2141 build_typed_selector_reference (ident
, prototype
)
2142 tree ident
, prototype
;
2144 tree
*chain
= &sel_ref_chain
;
2150 if (TREE_PURPOSE (*chain
) == prototype
&& TREE_VALUE (*chain
) == ident
)
2151 goto return_at_index
;
2154 chain
= &TREE_CHAIN (*chain
);
2157 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
2160 expr
= build_unary_op (ADDR_EXPR
,
2161 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2162 build_int_2 (index
, 0)),
2164 return build_c_cast (selector_type
, expr
);
2168 build_selector_reference (ident
)
2171 tree
*chain
= &sel_ref_chain
;
2177 if (TREE_VALUE (*chain
) == ident
)
2178 return (flag_next_runtime
2179 ? TREE_PURPOSE (*chain
)
2180 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2181 build_int_2 (index
, 0)));
2184 chain
= &TREE_CHAIN (*chain
);
2187 expr
= build_selector_reference_decl ();
2189 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2191 return (flag_next_runtime
2193 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2194 build_int_2 (index
, 0)));
2198 build_class_reference_decl ()
2204 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2206 ident
= get_identifier (buf
);
2208 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2209 DECL_EXTERNAL (decl
) = 1;
2210 TREE_PUBLIC (decl
) = 1;
2211 TREE_USED (decl
) = 1;
2212 TREE_READONLY (decl
) = 1;
2213 DECL_CONTEXT (decl
) = 0;
2214 DECL_ARTIFICIAL (decl
) = 1;
2216 make_decl_rtl (decl
, 0);
2217 pushdecl_top_level (decl
);
2222 /* Create a class reference, but don't create a variable to reference
2226 add_class_reference (ident
)
2231 if ((chain
= cls_ref_chain
))
2236 if (ident
== TREE_VALUE (chain
))
2240 chain
= TREE_CHAIN (chain
);
2244 /* Append to the end of the list */
2245 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2248 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2251 /* Get a class reference, creating it if necessary. Also create the
2252 reference variable. */
2255 get_class_reference (ident
)
2258 if (flag_next_runtime
)
2263 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2264 if (TREE_VALUE (*chain
) == ident
)
2266 if (! TREE_PURPOSE (*chain
))
2267 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2269 return TREE_PURPOSE (*chain
);
2272 decl
= build_class_reference_decl ();
2273 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2280 add_class_reference (ident
);
2282 params
= build_tree_list (NULL_TREE
,
2283 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2284 IDENTIFIER_POINTER (ident
)));
2286 assemble_external (objc_get_class_decl
);
2287 return build_function_call (objc_get_class_decl
, params
);
2291 /* For each string section we have a chain which maps identifier nodes
2292 to decls for the strings. */
2295 add_objc_string (ident
, section
)
2297 enum string_section section
;
2301 if (section
== class_names
)
2302 chain
= &class_names_chain
;
2303 else if (section
== meth_var_names
)
2304 chain
= &meth_var_names_chain
;
2305 else if (section
== meth_var_types
)
2306 chain
= &meth_var_types_chain
;
2312 if (TREE_VALUE (*chain
) == ident
)
2313 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2315 chain
= &TREE_CHAIN (*chain
);
2318 decl
= build_objc_string_decl (section
);
2320 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2322 return build_unary_op (ADDR_EXPR
, decl
, 1);
2326 build_objc_string_decl (section
)
2327 enum string_section section
;
2331 static int class_names_idx
= 0;
2332 static int meth_var_names_idx
= 0;
2333 static int meth_var_types_idx
= 0;
2335 if (section
== class_names
)
2336 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2337 else if (section
== meth_var_names
)
2338 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2339 else if (section
== meth_var_types
)
2340 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2342 ident
= get_identifier (buf
);
2344 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2345 DECL_EXTERNAL (decl
) = 1;
2346 TREE_PUBLIC (decl
) = 1;
2347 TREE_USED (decl
) = 1;
2348 TREE_READONLY (decl
) = 1;
2349 TREE_CONSTANT (decl
) = 1;
2350 DECL_CONTEXT (decl
) = 0;
2351 DECL_ARTIFICIAL (decl
) = 1;
2353 make_decl_rtl (decl
, 0);
2354 pushdecl_top_level (decl
);
2361 objc_declare_alias (alias_ident
, class_ident
)
2365 if (is_class_name (class_ident
) != class_ident
)
2366 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2367 else if (is_class_name (alias_ident
))
2368 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2370 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2374 objc_declare_class (ident_list
)
2379 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2381 tree ident
= TREE_VALUE (list
);
2384 if ((decl
= lookup_name (ident
)))
2386 error ("`%s' redeclared as different kind of symbol",
2387 IDENTIFIER_POINTER (ident
));
2388 error_with_decl (decl
, "previous declaration of `%s'");
2391 if (! is_class_name (ident
))
2393 tree record
= xref_tag (RECORD_TYPE
, ident
);
2394 TREE_STATIC_TEMPLATE (record
) = 1;
2395 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2401 is_class_name (ident
)
2406 if (lookup_interface (ident
))
2409 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2411 if (ident
== TREE_VALUE (chain
))
2415 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2417 if (ident
== TREE_VALUE (chain
))
2418 return TREE_PURPOSE (chain
);
2428 /* NB: This function may be called before the ObjC front-end
2429 has been initialized, in which case ID_TYPE will be NULL. */
2430 return (id_type
&& ident
&& TYPE_P (ident
) && IS_ID (ident
))
2436 lookup_interface (ident
)
2441 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2443 if (ident
== CLASS_NAME (chain
))
2449 /* Used by: build_private_template, continue_class,
2450 and for @defs constructs. */
2453 get_class_ivars (interface
)
2456 tree my_name
, super_name
, ivar_chain
;
2458 my_name
= CLASS_NAME (interface
);
2459 super_name
= CLASS_SUPER_NAME (interface
);
2460 ivar_chain
= CLASS_IVARS (interface
);
2462 /* Save off a pristine copy of the leaf ivars (i.e, those not
2463 inherited from a super class). */
2464 if (!CLASS_OWN_IVARS (interface
))
2465 CLASS_OWN_IVARS (interface
) = copy_list (ivar_chain
);
2470 tree super_interface
= lookup_interface (super_name
);
2472 if (!super_interface
)
2474 /* fatal did not work with 2 args...should fix */
2475 error ("cannot find interface declaration for `%s', superclass of `%s'",
2476 IDENTIFIER_POINTER (super_name
),
2477 IDENTIFIER_POINTER (my_name
));
2478 exit (FATAL_EXIT_CODE
);
2481 if (super_interface
== interface
)
2482 fatal_error ("circular inheritance in interface declaration for `%s'",
2483 IDENTIFIER_POINTER (super_name
));
2485 interface
= super_interface
;
2486 my_name
= CLASS_NAME (interface
);
2487 super_name
= CLASS_SUPER_NAME (interface
);
2489 op1
= CLASS_OWN_IVARS (interface
);
2492 tree head
= copy_list (op1
);
2494 /* Prepend super class ivars...make a copy of the list, we
2495 do not want to alter the original. */
2496 chainon (head
, ivar_chain
);
2503 /* struct <classname> {
2504 struct objc_class *isa;
2509 build_private_template (class)
2514 if (CLASS_STATIC_TEMPLATE (class))
2516 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2517 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2521 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2523 ivar_context
= get_class_ivars (class);
2525 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2527 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2529 /* mark this record as class template - for class type checking */
2530 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2534 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2536 build1 (INDIRECT_REF
, NULL_TREE
,
2539 return ivar_context
;
2542 /* Begin code generation for protocols... */
2544 /* struct objc_protocol {
2545 char *protocol_name;
2546 struct objc_protocol **protocol_list;
2547 struct objc_method_desc *instance_methods;
2548 struct objc_method_desc *class_methods;
2552 build_protocol_template ()
2554 tree decl_specs
, field_decl
, field_decl_chain
;
2557 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2559 /* struct objc_class *isa; */
2561 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2562 get_identifier (UTAG_CLASS
)));
2563 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2565 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2566 field_decl_chain
= field_decl
;
2568 /* char *protocol_name; */
2570 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2572 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2574 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2575 chainon (field_decl_chain
, field_decl
);
2577 /* struct objc_protocol **protocol_list; */
2579 decl_specs
= build_tree_list (NULL_TREE
, template);
2581 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2582 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2584 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2585 chainon (field_decl_chain
, field_decl
);
2587 /* struct objc_method_list *instance_methods; */
2590 = build_tree_list (NULL_TREE
,
2591 xref_tag (RECORD_TYPE
,
2592 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2594 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2596 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2597 chainon (field_decl_chain
, field_decl
);
2599 /* struct objc_method_list *class_methods; */
2602 = build_tree_list (NULL_TREE
,
2603 xref_tag (RECORD_TYPE
,
2604 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2606 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2608 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2609 chainon (field_decl_chain
, field_decl
);
2611 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2615 build_descriptor_table_initializer (type
, entries
)
2619 tree initlist
= NULL_TREE
;
2623 tree eltlist
= NULL_TREE
;
2626 = tree_cons (NULL_TREE
,
2627 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2629 = tree_cons (NULL_TREE
,
2630 add_objc_string (METHOD_ENCODING (entries
),
2635 = tree_cons (NULL_TREE
,
2636 build_constructor (type
, nreverse (eltlist
)), initlist
);
2638 entries
= TREE_CHAIN (entries
);
2642 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2645 /* struct objc_method_prototype_list {
2647 struct objc_method_prototype {
2654 build_method_prototype_list_template (list_type
, size
)
2658 tree objc_ivar_list_record
;
2659 tree decl_specs
, field_decl
, field_decl_chain
;
2661 /* Generate an unnamed struct definition. */
2663 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2665 /* int method_count; */
2667 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2668 field_decl
= get_identifier ("method_count");
2671 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2672 field_decl_chain
= field_decl
;
2674 /* struct objc_method method_list[]; */
2676 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2677 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2678 build_int_2 (size
, 0));
2681 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2682 chainon (field_decl_chain
, field_decl
);
2684 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2686 return objc_ivar_list_record
;
2690 build_method_prototype_template ()
2693 tree decl_specs
, field_decl
, field_decl_chain
;
2696 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2698 /* struct objc_selector *_cmd; */
2699 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2700 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2701 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2704 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2705 field_decl_chain
= field_decl
;
2707 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2709 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2711 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2712 chainon (field_decl_chain
, field_decl
);
2714 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2716 return proto_record
;
2719 /* True if last call to forwarding_offset yielded a register offset. */
2720 static int offset_is_register
;
2723 forwarding_offset (parm
)
2726 int offset_in_bytes
;
2728 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2730 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2732 /* ??? Here we assume that the parm address is indexed
2733 off the frame pointer or arg pointer.
2734 If that is not true, we produce meaningless results,
2735 but do not crash. */
2736 if (GET_CODE (addr
) == PLUS
2737 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2738 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2740 offset_in_bytes
= 0;
2742 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2743 offset_is_register
= 0;
2745 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2747 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2748 offset_in_bytes
= apply_args_register_offset (regno
);
2749 offset_is_register
= 1;
2754 /* This is the case where the parm is passed as an int or double
2755 and it is converted to a char, short or float and stored back
2756 in the parmlist. In this case, describe the parm
2757 with the variable's declared type, and adjust the address
2758 if the least significant bytes (which we are using) are not
2760 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2761 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2762 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2764 return offset_in_bytes
;
2768 encode_method_prototype (method_decl
, func_decl
)
2775 HOST_WIDE_INT max_parm_end
= 0;
2779 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2780 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2783 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2784 obstack_object_size (&util_obstack
),
2785 OBJC_ENCODE_INLINE_DEFS
);
2788 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2789 parms
= TREE_CHAIN (parms
))
2791 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2792 + int_size_in_bytes (TREE_TYPE (parms
)));
2794 if (!offset_is_register
&& max_parm_end
< parm_end
)
2795 max_parm_end
= parm_end
;
2798 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2800 sprintf (buf
, "%d", stack_size
);
2801 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2803 user_args
= METHOD_SEL_ARGS (method_decl
);
2805 /* Argument types. */
2806 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2807 parms
= TREE_CHAIN (parms
), i
++)
2809 /* Process argument qualifiers for user supplied arguments. */
2812 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2813 user_args
= TREE_CHAIN (user_args
);
2817 encode_type (TREE_TYPE (parms
),
2818 obstack_object_size (&util_obstack
),
2819 OBJC_ENCODE_INLINE_DEFS
);
2821 /* Compute offset. */
2822 sprintf (buf
, "%d", forwarding_offset (parms
));
2824 /* Indicate register. */
2825 if (offset_is_register
)
2826 obstack_1grow (&util_obstack
, '+');
2828 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2831 obstack_1grow (&util_obstack
, '\0');
2832 result
= get_identifier (obstack_finish (&util_obstack
));
2833 obstack_free (&util_obstack
, util_firstobj
);
2838 generate_descriptor_table (type
, name
, size
, list
, proto
)
2845 tree sc_spec
, decl_specs
, decl
, initlist
;
2847 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2848 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2850 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2851 decl_specs
, 1, NULL_TREE
);
2852 DECL_CONTEXT (decl
) = NULL_TREE
;
2854 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2855 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2857 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2864 generate_method_descriptors (protocol
)
2867 tree initlist
, chain
, method_list_template
;
2868 tree cast
, variable_length_type
;
2871 if (!objc_method_prototype_template
)
2872 objc_method_prototype_template
= build_method_prototype_template ();
2874 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2875 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2877 variable_length_type
= groktypename (cast
);
2879 chain
= PROTOCOL_CLS_METHODS (protocol
);
2882 size
= list_length (chain
);
2884 method_list_template
2885 = build_method_prototype_list_template (objc_method_prototype_template
,
2889 = build_descriptor_table_initializer (objc_method_prototype_template
,
2892 UOBJC_CLASS_METHODS_decl
2893 = generate_descriptor_table (method_list_template
,
2894 "_OBJC_PROTOCOL_CLASS_METHODS",
2895 size
, initlist
, protocol
);
2896 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2899 UOBJC_CLASS_METHODS_decl
= 0;
2901 chain
= PROTOCOL_NST_METHODS (protocol
);
2904 size
= list_length (chain
);
2906 method_list_template
2907 = build_method_prototype_list_template (objc_method_prototype_template
,
2910 = build_descriptor_table_initializer (objc_method_prototype_template
,
2913 UOBJC_INSTANCE_METHODS_decl
2914 = generate_descriptor_table (method_list_template
,
2915 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2916 size
, initlist
, protocol
);
2917 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2920 UOBJC_INSTANCE_METHODS_decl
= 0;
2923 /* Generate a temporary FUNCTION_DECL node to be used in
2924 hack_method_prototype below. */
2927 build_tmp_function_decl ()
2929 tree decl_specs
, expr_decl
, parms
;
2933 /* struct objc_object *objc_xxx (id, SEL, ...); */
2935 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2936 push_parm_decl (build_tree_list
2937 (build_tree_list (decl_specs
,
2938 build1 (INDIRECT_REF
, NULL_TREE
,
2942 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2943 get_identifier (TAG_SELECTOR
)));
2944 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2946 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2948 parms
= get_parm_info (0);
2951 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2952 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2953 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2954 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
2956 return define_decl (expr_decl
, decl_specs
);
2959 /* Generate the prototypes for protocol methods. This is used to
2960 generate method encodings for these.
2962 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2963 a decl node to be used. This is also where the return value is
2967 hack_method_prototype (nst_methods
, tmp_decl
)
2974 /* Hack to avoid problem with static typing of self arg. */
2975 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2976 start_method_def (nst_methods
);
2977 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2979 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
2980 parms
= get_parm_info (0); /* we have a `, ...' */
2982 parms
= get_parm_info (1); /* place a `void_at_end' */
2984 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2986 /* Usually called from store_parm_decls -> init_function_start. */
2988 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2990 if (current_function_decl
)
2992 current_function_decl
= tmp_decl
;
2995 /* Code taken from start_function. */
2996 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2997 /* Promote the value to int before returning it. */
2998 if (TREE_CODE (restype
) == INTEGER_TYPE
2999 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3000 restype
= integer_type_node
;
3001 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3004 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3005 DECL_CONTEXT (parm
) = tmp_decl
;
3007 init_function_start (tmp_decl
, "objc-act", 0);
3009 /* Typically called from expand_function_start for function definitions. */
3010 assign_parms (tmp_decl
);
3012 /* install return type */
3013 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3015 current_function_decl
= NULL
;
3019 generate_protocol_references (plist
)
3024 /* Forward declare protocols referenced. */
3025 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3027 tree proto
= TREE_VALUE (lproto
);
3029 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3030 && PROTOCOL_NAME (proto
))
3032 if (! PROTOCOL_FORWARD_DECL (proto
))
3033 build_protocol_reference (proto
);
3035 if (PROTOCOL_LIST (proto
))
3036 generate_protocol_references (PROTOCOL_LIST (proto
));
3041 /* For each protocol which was referenced either from a @protocol()
3042 expression, or because a class/category implements it (then a
3043 pointer to the protocol is stored in the struct describing the
3044 class/category), we create a statically allocated instance of the
3045 Protocol class. The code is written in such a way as to generate
3046 as few Protocol objects as possible; we generate a unique Protocol
3047 instance for each protocol, and we don't generate a Protocol
3048 instance if the protocol is never referenced (either from a
3049 @protocol() or from a class/category implementation). These
3050 statically allocated objects can be referred to via the static
3051 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3053 The statically allocated Protocol objects that we generate here
3054 need to be fixed up at runtime in order to be used: the 'isa'
3055 pointer of the objects need to be set up to point to the 'Protocol'
3056 class, as known at runtime.
3058 The NeXT runtime fixes up all protocols at program startup time,
3059 before main() is entered. It uses a low-level trick to look up all
3060 those symbols, then loops on them and fixes them up.
3062 The GNU runtime as well fixes up all protocols before user code
3063 from the module is executed; it requires pointers to those symbols
3064 to be put in the objc_symtab (which is then passed as argument to
3065 the function __objc_exec_class() which the compiler sets up to be
3066 executed automatically when the module is loaded); setup of those
3067 Protocol objects happen in two ways in the GNU runtime: all
3068 Protocol objects referred to by a class or category implementation
3069 are fixed up when the class/category is loaded; all Protocol
3070 objects referred to by a @protocol() expression are added by the
3071 compiler to the list of statically allocated instances to fixup
3072 (the same list holding the statically allocated constant string
3073 objects). Because, as explained above, the compiler generates as
3074 few Protocol objects as possible, some Protocol object might end up
3075 being referenced multiple times when compiled with the GNU runtime,
3076 and end up being fixed up multiple times at runtime inizialization.
3077 But that doesn't hurt, it's just a little inefficient. */
3079 generate_protocols ()
3081 tree p
, tmp_decl
, encoding
;
3082 tree sc_spec
, decl_specs
, decl
;
3083 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3086 tmp_decl
= build_tmp_function_decl ();
3088 if (! objc_protocol_template
)
3089 objc_protocol_template
= build_protocol_template ();
3091 /* If a protocol was directly referenced, pull in indirect references. */
3092 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3093 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3094 generate_protocol_references (PROTOCOL_LIST (p
));
3096 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3098 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3099 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3101 /* If protocol wasn't referenced, don't generate any code. */
3102 if (! PROTOCOL_FORWARD_DECL (p
))
3105 /* Make sure we link in the Protocol class. */
3106 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3110 if (! METHOD_ENCODING (nst_methods
))
3112 hack_method_prototype (nst_methods
, tmp_decl
);
3113 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3114 METHOD_ENCODING (nst_methods
) = encoding
;
3116 nst_methods
= TREE_CHAIN (nst_methods
);
3121 if (! METHOD_ENCODING (cls_methods
))
3123 hack_method_prototype (cls_methods
, tmp_decl
);
3124 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3125 METHOD_ENCODING (cls_methods
) = encoding
;
3128 cls_methods
= TREE_CHAIN (cls_methods
);
3130 generate_method_descriptors (p
);
3132 if (PROTOCOL_LIST (p
))
3133 refs_decl
= generate_protocol_list (p
);
3137 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3139 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3141 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3143 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3144 decl_specs
, 1, NULL_TREE
);
3146 DECL_CONTEXT (decl
) = NULL_TREE
;
3148 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3154 (build_tree_list (build_tree_list (NULL_TREE
,
3155 objc_protocol_template
),
3156 build1 (INDIRECT_REF
, NULL_TREE
,
3157 build1 (INDIRECT_REF
, NULL_TREE
,
3160 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3161 TREE_TYPE (refs_expr
) = cast_type2
;
3164 refs_expr
= build_int_2 (0, 0);
3166 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3167 by generate_method_descriptors, which is called above. */
3168 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3169 protocol_name_expr
, refs_expr
,
3170 UOBJC_INSTANCE_METHODS_decl
,
3171 UOBJC_CLASS_METHODS_decl
);
3172 finish_decl (decl
, initlist
, NULL_TREE
);
3174 /* Mark the decl as used to avoid "defined but not used" warning. */
3175 TREE_USED (decl
) = 1;
3180 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3181 instance_methods
, class_methods
)
3185 tree instance_methods
;
3188 tree initlist
= NULL_TREE
, expr
;
3191 cast_type
= groktypename
3193 (build_tree_list (NULL_TREE
,
3194 xref_tag (RECORD_TYPE
,
3195 get_identifier (UTAG_CLASS
))),
3196 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3198 /* Filling the "isa" in with one allows the runtime system to
3199 detect that the version change...should remove before final release. */
3201 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3202 TREE_TYPE (expr
) = cast_type
;
3203 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3204 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3205 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3207 if (!instance_methods
)
3208 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3211 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3212 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3216 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3219 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3220 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3223 return build_constructor (type
, nreverse (initlist
));
3226 /* struct objc_category {
3227 char *category_name;
3229 struct objc_method_list *instance_methods;
3230 struct objc_method_list *class_methods;
3231 struct objc_protocol_list *protocols;
3235 build_category_template ()
3237 tree decl_specs
, field_decl
, field_decl_chain
;
3239 objc_category_template
= start_struct (RECORD_TYPE
,
3240 get_identifier (UTAG_CATEGORY
));
3241 /* char *category_name; */
3243 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3245 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3247 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3248 field_decl_chain
= field_decl
;
3250 /* char *class_name; */
3252 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3253 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3255 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3256 chainon (field_decl_chain
, field_decl
);
3258 /* struct objc_method_list *instance_methods; */
3260 decl_specs
= build_tree_list (NULL_TREE
,
3261 xref_tag (RECORD_TYPE
,
3262 get_identifier (UTAG_METHOD_LIST
)));
3264 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3266 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3267 chainon (field_decl_chain
, field_decl
);
3269 /* struct objc_method_list *class_methods; */
3271 decl_specs
= build_tree_list (NULL_TREE
,
3272 xref_tag (RECORD_TYPE
,
3273 get_identifier (UTAG_METHOD_LIST
)));
3275 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3277 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3278 chainon (field_decl_chain
, field_decl
);
3280 /* struct objc_protocol **protocol_list; */
3282 decl_specs
= build_tree_list (NULL_TREE
,
3283 xref_tag (RECORD_TYPE
,
3284 get_identifier (UTAG_PROTOCOL
)));
3286 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3287 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3289 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3290 chainon (field_decl_chain
, field_decl
);
3292 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3295 /* struct objc_selector {
3301 build_selector_template ()
3304 tree decl_specs
, field_decl
, field_decl_chain
;
3306 objc_selector_template
3307 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3311 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3312 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3314 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3315 field_decl_chain
= field_decl
;
3317 /* char *sel_type; */
3319 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3320 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3322 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3323 chainon (field_decl_chain
, field_decl
);
3325 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3328 /* struct objc_class {
3329 struct objc_class *isa;
3330 struct objc_class *super_class;
3335 struct objc_ivar_list *ivars;
3336 struct objc_method_list *methods;
3337 if (flag_next_runtime)
3338 struct objc_cache *cache;
3340 struct sarray *dtable;
3341 struct objc_class *subclass_list;
3342 struct objc_class *sibling_class;
3344 struct objc_protocol_list *protocols;
3345 void *gc_object_type;
3349 build_class_template ()
3351 tree decl_specs
, field_decl
, field_decl_chain
;
3354 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3356 /* struct objc_class *isa; */
3358 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3359 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3361 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3362 field_decl_chain
= field_decl
;
3364 /* struct objc_class *super_class; */
3366 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3368 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3370 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3371 chainon (field_decl_chain
, field_decl
);
3375 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3376 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3378 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3379 chainon (field_decl_chain
, field_decl
);
3383 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3384 field_decl
= get_identifier ("version");
3386 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3387 chainon (field_decl_chain
, field_decl
);
3391 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3392 field_decl
= get_identifier ("info");
3394 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3395 chainon (field_decl_chain
, field_decl
);
3397 /* long instance_size; */
3399 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3400 field_decl
= get_identifier ("instance_size");
3402 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3403 chainon (field_decl_chain
, field_decl
);
3405 /* struct objc_ivar_list *ivars; */
3407 decl_specs
= build_tree_list (NULL_TREE
,
3408 xref_tag (RECORD_TYPE
,
3409 get_identifier (UTAG_IVAR_LIST
)));
3410 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3412 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3413 chainon (field_decl_chain
, field_decl
);
3415 /* struct objc_method_list *methods; */
3417 decl_specs
= build_tree_list (NULL_TREE
,
3418 xref_tag (RECORD_TYPE
,
3419 get_identifier (UTAG_METHOD_LIST
)));
3420 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3422 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3423 chainon (field_decl_chain
, field_decl
);
3425 if (flag_next_runtime
)
3427 /* struct objc_cache *cache; */
3429 decl_specs
= build_tree_list (NULL_TREE
,
3430 xref_tag (RECORD_TYPE
,
3431 get_identifier ("objc_cache")));
3432 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3433 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3434 decl_specs
, NULL_TREE
);
3435 chainon (field_decl_chain
, field_decl
);
3439 /* struct sarray *dtable; */
3441 decl_specs
= build_tree_list (NULL_TREE
,
3442 xref_tag (RECORD_TYPE
,
3443 get_identifier ("sarray")));
3444 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3445 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3446 decl_specs
, NULL_TREE
);
3447 chainon (field_decl_chain
, field_decl
);
3449 /* struct objc_class *subclass_list; */
3451 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3453 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3454 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3455 decl_specs
, NULL_TREE
);
3456 chainon (field_decl_chain
, field_decl
);
3458 /* struct objc_class *sibling_class; */
3460 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3462 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3463 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3464 decl_specs
, NULL_TREE
);
3465 chainon (field_decl_chain
, field_decl
);
3468 /* struct objc_protocol **protocol_list; */
3470 decl_specs
= build_tree_list (NULL_TREE
,
3471 xref_tag (RECORD_TYPE
,
3472 get_identifier (UTAG_PROTOCOL
)));
3474 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3476 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3477 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3478 decl_specs
, NULL_TREE
);
3479 chainon (field_decl_chain
, field_decl
);
3483 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3484 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3486 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3487 chainon (field_decl_chain
, field_decl
);
3489 /* void *gc_object_type; */
3491 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3492 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3494 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3495 chainon (field_decl_chain
, field_decl
);
3497 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3500 /* Generate appropriate forward declarations for an implementation. */
3503 synth_forward_declarations ()
3505 tree sc_spec
, decl_specs
, an_id
;
3507 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3509 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context
);
3511 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3512 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3513 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3514 TREE_USED (UOBJC_CLASS_decl
) = 1;
3515 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3517 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3519 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3520 objc_implementation_context
);
3522 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3523 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3524 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3526 /* Pre-build the following entities - for speed/convenience. */
3528 an_id
= get_identifier ("super_class");
3529 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3530 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3534 error_with_ivar (message
, decl
, rawdecl
)
3535 const char *message
;
3539 diagnostic_count_diagnostic (global_dc
, DK_ERROR
);
3541 diagnostic_report_current_function (global_dc
);
3543 error_with_file_and_line (DECL_SOURCE_FILE (decl
),
3544 DECL_SOURCE_LINE (decl
),
3546 message
, gen_declaration (rawdecl
, errbuf
));
3551 check_ivars (inter
, imp
)
3555 tree intdecls
= CLASS_IVARS (inter
);
3556 tree impdecls
= CLASS_IVARS (imp
);
3557 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3558 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3564 if (intdecls
== 0 && impdecls
== 0)
3566 if (intdecls
== 0 || impdecls
== 0)
3568 error ("inconsistent instance variable specification");
3572 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3574 if (!comptypes (t1
, t2
))
3576 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3578 error_with_ivar ("conflicting instance variable type",
3579 impdecls
, rawimpdecls
);
3580 error_with_ivar ("previous declaration of",
3581 intdecls
, rawintdecls
);
3583 else /* both the type and the name don't match */
3585 error ("inconsistent instance variable specification");
3590 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3592 error_with_ivar ("conflicting instance variable name",
3593 impdecls
, rawimpdecls
);
3594 error_with_ivar ("previous declaration of",
3595 intdecls
, rawintdecls
);
3598 intdecls
= TREE_CHAIN (intdecls
);
3599 impdecls
= TREE_CHAIN (impdecls
);
3600 rawintdecls
= TREE_CHAIN (rawintdecls
);
3601 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3605 /* Set super_type to the data type node for struct objc_super *,
3606 first defining struct objc_super itself.
3607 This needs to be done just once per compilation. */
3610 build_super_template ()
3612 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3614 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3616 /* struct objc_object *self; */
3618 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3619 field_decl
= get_identifier ("self");
3620 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3621 field_decl
= grokfield (input_filename
, lineno
,
3622 field_decl
, decl_specs
, NULL_TREE
);
3623 field_decl_chain
= field_decl
;
3625 /* struct objc_class *class; */
3627 decl_specs
= get_identifier (UTAG_CLASS
);
3628 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3629 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3631 field_decl
= grokfield (input_filename
, lineno
,
3632 field_decl
, decl_specs
, NULL_TREE
);
3633 chainon (field_decl_chain
, field_decl
);
3635 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3637 /* `struct objc_super *' */
3638 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3640 build1 (INDIRECT_REF
,
3641 NULL_TREE
, NULL_TREE
)));
3645 /* struct objc_ivar {
3652 build_ivar_template ()
3654 tree objc_ivar_id
, objc_ivar_record
;
3655 tree decl_specs
, field_decl
, field_decl_chain
;
3657 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3658 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3660 /* char *ivar_name; */
3662 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3663 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3665 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3666 decl_specs
, NULL_TREE
);
3667 field_decl_chain
= field_decl
;
3669 /* char *ivar_type; */
3671 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3672 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3674 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3675 decl_specs
, NULL_TREE
);
3676 chainon (field_decl_chain
, field_decl
);
3678 /* int ivar_offset; */
3680 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3681 field_decl
= get_identifier ("ivar_offset");
3683 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3684 decl_specs
, NULL_TREE
);
3685 chainon (field_decl_chain
, field_decl
);
3687 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3689 return objc_ivar_record
;
3694 struct objc_ivar ivar_list[ivar_count];
3698 build_ivar_list_template (list_type
, size
)
3702 tree objc_ivar_list_record
;
3703 tree decl_specs
, field_decl
, field_decl_chain
;
3705 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3707 /* int ivar_count; */
3709 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3710 field_decl
= get_identifier ("ivar_count");
3712 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3713 decl_specs
, NULL_TREE
);
3714 field_decl_chain
= field_decl
;
3716 /* struct objc_ivar ivar_list[]; */
3718 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3719 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3720 build_int_2 (size
, 0));
3722 field_decl
= grokfield (input_filename
, lineno
,
3723 field_decl
, decl_specs
, NULL_TREE
);
3724 chainon (field_decl_chain
, field_decl
);
3726 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3728 return objc_ivar_list_record
;
3734 struct objc_method method_list[method_count];
3738 build_method_list_template (list_type
, size
)
3742 tree objc_ivar_list_record
;
3743 tree decl_specs
, field_decl
, field_decl_chain
;
3745 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3747 /* int method_next; */
3752 xref_tag (RECORD_TYPE
,
3753 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3755 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3756 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3757 decl_specs
, NULL_TREE
);
3758 field_decl_chain
= field_decl
;
3760 /* int method_count; */
3762 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3763 field_decl
= get_identifier ("method_count");
3765 field_decl
= grokfield (input_filename
, lineno
,
3766 field_decl
, decl_specs
, NULL_TREE
);
3767 chainon (field_decl_chain
, field_decl
);
3769 /* struct objc_method method_list[]; */
3771 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3772 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3773 build_int_2 (size
, 0));
3775 field_decl
= grokfield (input_filename
, lineno
,
3776 field_decl
, decl_specs
, NULL_TREE
);
3777 chainon (field_decl_chain
, field_decl
);
3779 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3781 return objc_ivar_list_record
;
3785 build_ivar_list_initializer (type
, field_decl
)
3789 tree initlist
= NULL_TREE
;
3793 tree ivar
= NULL_TREE
;
3796 if (DECL_NAME (field_decl
))
3797 ivar
= tree_cons (NULL_TREE
,
3798 add_objc_string (DECL_NAME (field_decl
),
3802 /* Unnamed bit-field ivar (yuck). */
3803 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3806 encode_field_decl (field_decl
,
3807 obstack_object_size (&util_obstack
),
3808 OBJC_ENCODE_DONT_INLINE_DEFS
);
3810 /* Null terminate string. */
3811 obstack_1grow (&util_obstack
, 0);
3815 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3818 obstack_free (&util_obstack
, util_firstobj
);
3821 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3822 initlist
= tree_cons (NULL_TREE
,
3823 build_constructor (type
, nreverse (ivar
)),
3826 field_decl
= TREE_CHAIN (field_decl
);
3830 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3834 generate_ivars_list (type
, name
, size
, list
)
3840 tree sc_spec
, decl_specs
, decl
, initlist
;
3842 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3843 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3845 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3846 decl_specs
, 1, NULL_TREE
);
3848 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3849 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3852 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3859 generate_ivar_lists ()
3861 tree initlist
, ivar_list_template
, chain
;
3862 tree cast
, variable_length_type
;
3865 generating_instance_variables
= 1;
3867 if (!objc_ivar_template
)
3868 objc_ivar_template
= build_ivar_template ();
3872 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3873 get_identifier (UTAG_IVAR_LIST
))),
3875 variable_length_type
= groktypename (cast
);
3877 /* Only generate class variables for the root of the inheritance
3878 hierarchy since these will be the same for every class. */
3880 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3881 && (chain
= TYPE_FIELDS (objc_class_template
)))
3883 size
= list_length (chain
);
3885 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3886 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3888 UOBJC_CLASS_VARIABLES_decl
3889 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3891 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3894 UOBJC_CLASS_VARIABLES_decl
= 0;
3896 chain
= CLASS_IVARS (implementation_template
);
3899 size
= list_length (chain
);
3900 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3901 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3903 UOBJC_INSTANCE_VARIABLES_decl
3904 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3906 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3909 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3911 generating_instance_variables
= 0;
3915 build_dispatch_table_initializer (type
, entries
)
3919 tree initlist
= NULL_TREE
;
3923 tree elemlist
= NULL_TREE
;
3925 elemlist
= tree_cons (NULL_TREE
,
3926 build_selector (METHOD_SEL_NAME (entries
)),
3929 /* Generate the method encoding if we don't have one already. */
3930 if (! METHOD_ENCODING (entries
))
3931 METHOD_ENCODING (entries
) =
3932 encode_method_def (METHOD_DEFINITION (entries
));
3934 elemlist
= tree_cons (NULL_TREE
,
3935 add_objc_string (METHOD_ENCODING (entries
),
3939 elemlist
= tree_cons (NULL_TREE
,
3940 build_unary_op (ADDR_EXPR
,
3941 METHOD_DEFINITION (entries
), 1),
3944 initlist
= tree_cons (NULL_TREE
,
3945 build_constructor (type
, nreverse (elemlist
)),
3948 entries
= TREE_CHAIN (entries
);
3952 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3955 /* To accomplish method prototyping without generating all kinds of
3956 inane warnings, the definition of the dispatch table entries were
3959 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3961 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3964 build_method_template ()
3967 tree decl_specs
, field_decl
, field_decl_chain
;
3969 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3971 /* struct objc_selector *_cmd; */
3972 decl_specs
= tree_cons (NULL_TREE
,
3973 xref_tag (RECORD_TYPE
,
3974 get_identifier (TAG_SELECTOR
)),
3976 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3978 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3979 decl_specs
, NULL_TREE
);
3980 field_decl_chain
= field_decl
;
3982 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3983 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3984 get_identifier ("method_types"));
3985 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3986 decl_specs
, NULL_TREE
);
3987 chainon (field_decl_chain
, field_decl
);
3991 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
3992 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
3993 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3994 decl_specs
, NULL_TREE
);
3995 chainon (field_decl_chain
, field_decl
);
3997 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4004 generate_dispatch_table (type
, name
, size
, list
)
4010 tree sc_spec
, decl_specs
, decl
, initlist
;
4012 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4013 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4015 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
4016 decl_specs
, 1, NULL_TREE
);
4018 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4019 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4020 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4023 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4030 generate_dispatch_tables ()
4032 tree initlist
, chain
, method_list_template
;
4033 tree cast
, variable_length_type
;
4036 if (!objc_method_template
)
4037 objc_method_template
= build_method_template ();
4041 (build_tree_list (NULL_TREE
,
4042 xref_tag (RECORD_TYPE
,
4043 get_identifier (UTAG_METHOD_LIST
))),
4046 variable_length_type
= groktypename (cast
);
4048 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
4051 size
= list_length (chain
);
4053 method_list_template
4054 = build_method_list_template (objc_method_template
, size
);
4056 = build_dispatch_table_initializer (objc_method_template
, chain
);
4058 UOBJC_CLASS_METHODS_decl
4059 = generate_dispatch_table (method_list_template
,
4060 ((TREE_CODE (objc_implementation_context
)
4061 == CLASS_IMPLEMENTATION_TYPE
)
4062 ? "_OBJC_CLASS_METHODS"
4063 : "_OBJC_CATEGORY_CLASS_METHODS"),
4065 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4068 UOBJC_CLASS_METHODS_decl
= 0;
4070 chain
= CLASS_NST_METHODS (objc_implementation_context
);
4073 size
= list_length (chain
);
4075 method_list_template
4076 = build_method_list_template (objc_method_template
, size
);
4078 = build_dispatch_table_initializer (objc_method_template
, chain
);
4080 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4081 UOBJC_INSTANCE_METHODS_decl
4082 = generate_dispatch_table (method_list_template
,
4083 "_OBJC_INSTANCE_METHODS",
4086 /* We have a category. */
4087 UOBJC_INSTANCE_METHODS_decl
4088 = generate_dispatch_table (method_list_template
,
4089 "_OBJC_CATEGORY_INSTANCE_METHODS",
4091 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4094 UOBJC_INSTANCE_METHODS_decl
= 0;
4098 generate_protocol_list (i_or_p
)
4101 tree initlist
, decl_specs
, sc_spec
;
4102 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4106 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4107 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4108 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4109 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4110 plist
= PROTOCOL_LIST (i_or_p
);
4114 cast_type
= groktypename
4116 (build_tree_list (NULL_TREE
,
4117 xref_tag (RECORD_TYPE
,
4118 get_identifier (UTAG_PROTOCOL
))),
4119 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4122 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4123 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4124 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4127 /* Build initializer. */
4128 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4130 e
= build_int_2 (size
, 0);
4131 TREE_TYPE (e
) = cast_type
;
4132 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4134 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4136 tree pval
= TREE_VALUE (lproto
);
4138 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4139 && PROTOCOL_FORWARD_DECL (pval
))
4141 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4142 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4146 /* static struct objc_protocol *refs[n]; */
4148 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4149 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4150 get_identifier (UTAG_PROTOCOL
)),
4153 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4154 expr_decl
= build_nt (ARRAY_REF
,
4155 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4157 build_int_2 (size
+ 2, 0));
4158 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4159 expr_decl
= build_nt (ARRAY_REF
,
4160 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4162 build_int_2 (size
+ 2, 0));
4163 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4165 = build_nt (ARRAY_REF
,
4166 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4168 build_int_2 (size
+ 2, 0));
4172 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4174 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4175 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4177 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4178 nreverse (initlist
)),
4185 build_category_initializer (type
, cat_name
, class_name
,
4186 instance_methods
, class_methods
, protocol_list
)
4190 tree instance_methods
;
4194 tree initlist
= NULL_TREE
, expr
;
4196 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4197 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4199 if (!instance_methods
)
4200 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4203 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4204 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4207 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4210 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4211 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4214 /* protocol_list = */
4216 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4219 tree cast_type2
= groktypename
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 return build_constructor (type
, nreverse (initlist
));
4235 /* struct objc_class {
4236 struct objc_class *isa;
4237 struct objc_class *super_class;
4242 struct objc_ivar_list *ivars;
4243 struct objc_method_list *methods;
4244 if (flag_next_runtime)
4245 struct objc_cache *cache;
4247 struct sarray *dtable;
4248 struct objc_class *subclass_list;
4249 struct objc_class *sibling_class;
4251 struct objc_protocol_list *protocols;
4252 void *gc_object_type;
4256 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4257 dispatch_table
, ivar_list
, protocol_list
)
4264 tree dispatch_table
;
4268 tree initlist
= NULL_TREE
, expr
;
4271 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4274 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4277 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4280 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4283 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4285 /* instance_size = */
4286 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4288 /* objc_ivar_list = */
4290 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4293 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4294 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4297 /* objc_method_list = */
4298 if (!dispatch_table
)
4299 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4302 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4303 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4306 if (flag_next_runtime
)
4307 /* method_cache = */
4308 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4312 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4314 /* subclass_list = */
4315 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4317 /* sibling_class = */
4318 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4321 /* protocol_list = */
4322 if (! protocol_list
)
4323 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4329 (build_tree_list (NULL_TREE
,
4330 xref_tag (RECORD_TYPE
,
4331 get_identifier (UTAG_PROTOCOL
))),
4332 build1 (INDIRECT_REF
, NULL_TREE
,
4333 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4335 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4336 TREE_TYPE (expr
) = cast_type2
;
4337 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4340 /* gc_object_type = NULL */
4341 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4343 return build_constructor (type
, nreverse (initlist
));
4346 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4349 generate_category (cat
)
4352 tree sc_spec
, decl_specs
, decl
;
4353 tree initlist
, cat_name_expr
, class_name_expr
;
4354 tree protocol_decl
, category
;
4356 add_class_reference (CLASS_NAME (cat
));
4357 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4359 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4361 category
= CLASS_CATEGORY_LIST (implementation_template
);
4363 /* find the category interface from the class it is associated with */
4366 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4368 category
= CLASS_CATEGORY_LIST (category
);
4371 if (category
&& CLASS_PROTOCOL_LIST (category
))
4373 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4374 protocol_decl
= generate_protocol_list (category
);
4379 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4380 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4382 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4383 objc_implementation_context
),
4384 decl_specs
, 1, NULL_TREE
);
4386 initlist
= build_category_initializer (TREE_TYPE (decl
),
4387 cat_name_expr
, class_name_expr
,
4388 UOBJC_INSTANCE_METHODS_decl
,
4389 UOBJC_CLASS_METHODS_decl
,
4392 TREE_USED (decl
) = 1;
4393 finish_decl (decl
, initlist
, NULL_TREE
);
4396 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4397 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4400 generate_shared_structures ()
4402 tree sc_spec
, decl_specs
, decl
;
4403 tree name_expr
, super_expr
, root_expr
;
4404 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4405 tree cast_type
, initlist
, protocol_decl
;
4407 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4410 add_class_reference (my_super_id
);
4412 /* Compute "my_root_id" - this is required for code generation.
4413 the "isa" for all meta class structures points to the root of
4414 the inheritance hierarchy (e.g. "__Object")... */
4415 my_root_id
= my_super_id
;
4418 tree my_root_int
= lookup_interface (my_root_id
);
4420 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4421 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4428 /* No super class. */
4429 my_root_id
= CLASS_NAME (implementation_template
);
4432 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4433 objc_class_template
),
4434 build1 (INDIRECT_REF
,
4435 NULL_TREE
, NULL_TREE
)));
4437 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4440 /* Install class `isa' and `super' pointers at runtime. */
4443 super_expr
= add_objc_string (my_super_id
, class_names
);
4444 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4447 super_expr
= build_int_2 (0, 0);
4449 root_expr
= add_objc_string (my_root_id
, class_names
);
4450 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4452 if (CLASS_PROTOCOL_LIST (implementation_template
))
4454 generate_protocol_references
4455 (CLASS_PROTOCOL_LIST (implementation_template
));
4456 protocol_decl
= generate_protocol_list (implementation_template
);
4461 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4463 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4464 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4466 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4470 = build_shared_structure_initializer
4472 root_expr
, super_expr
, name_expr
,
4473 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4475 UOBJC_CLASS_METHODS_decl
,
4476 UOBJC_CLASS_VARIABLES_decl
,
4479 finish_decl (decl
, initlist
, NULL_TREE
);
4481 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4483 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4487 = build_shared_structure_initializer
4489 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4490 super_expr
, name_expr
,
4491 convert (integer_type_node
,
4492 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4493 (implementation_template
))),
4495 UOBJC_INSTANCE_METHODS_decl
,
4496 UOBJC_INSTANCE_VARIABLES_decl
,
4499 finish_decl (decl
, initlist
, NULL_TREE
);
4503 synth_id_with_class_suffix (preamble
, ctxt
)
4504 const char *preamble
;
4508 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4509 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4511 const char *const class_name
4512 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4513 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4514 sprintf (string
, "%s_%s", preamble
,
4515 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4517 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4518 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4520 /* We have a category. */
4521 const char *const class_name
4522 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4523 const char *const class_super_name
4524 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
4525 string
= (char *) alloca (strlen (preamble
)
4526 + strlen (class_name
)
4527 + strlen (class_super_name
)
4529 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4531 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4533 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4535 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4536 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4541 return get_identifier (string
);
4545 is_objc_type_qualifier (node
)
4548 return (TREE_CODE (node
) == IDENTIFIER_NODE
4549 && (node
== ridpointers
[(int) RID_CONST
]
4550 || node
== ridpointers
[(int) RID_VOLATILE
]
4551 || node
== ridpointers
[(int) RID_IN
]
4552 || node
== ridpointers
[(int) RID_OUT
]
4553 || node
== ridpointers
[(int) RID_INOUT
]
4554 || node
== ridpointers
[(int) RID_BYCOPY
]
4555 || node
== ridpointers
[(int) RID_BYREF
]
4556 || node
== ridpointers
[(int) RID_ONEWAY
]));
4559 /* If type is empty or only type qualifiers are present, add default
4560 type of id (otherwise grokdeclarator will default to int). */
4563 adjust_type_for_id_default (type
)
4566 tree declspecs
, chain
;
4569 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4570 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4572 declspecs
= TREE_PURPOSE (type
);
4574 /* Determine if a typespec is present. */
4575 for (chain
= declspecs
;
4577 chain
= TREE_CHAIN (chain
))
4579 if (TYPED_OBJECT (TREE_VALUE (chain
))
4580 && !(TREE_VALUE (type
)
4581 && TREE_CODE (TREE_VALUE (type
)) == INDIRECT_REF
))
4582 error ("can not use an object as parameter to a method\n");
4583 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4587 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4589 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4594 selector ':' '(' typename ')' identifier
4597 Transform an Objective-C keyword argument into
4598 the C equivalent parameter declarator.
4600 In: key_name, an "identifier_node" (optional).
4601 arg_type, a "tree_list" (optional).
4602 arg_name, an "identifier_node".
4604 Note: It would be really nice to strongly type the preceding
4605 arguments in the function prototype; however, then I
4606 could not use the "accessor" macros defined in "tree.h".
4608 Out: an instance of "keyword_decl". */
4611 build_keyword_decl (key_name
, arg_type
, arg_name
)
4618 /* If no type is specified, default to "id". */
4619 arg_type
= adjust_type_for_id_default (arg_type
);
4621 keyword_decl
= make_node (KEYWORD_DECL
);
4623 TREE_TYPE (keyword_decl
) = arg_type
;
4624 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4625 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4627 return keyword_decl
;
4630 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4633 build_keyword_selector (selector
)
4637 tree key_chain
, key_name
;
4640 /* Scan the selector to see how much space we'll need. */
4641 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4643 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4644 key_name
= KEYWORD_KEY_NAME (key_chain
);
4645 else if (TREE_CODE (selector
) == TREE_LIST
)
4646 key_name
= TREE_PURPOSE (key_chain
);
4651 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4653 /* Just a ':' arg. */
4657 buf
= (char *) alloca (len
+ 1);
4658 /* Start the buffer out as an empty string. */
4661 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4663 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4664 key_name
= KEYWORD_KEY_NAME (key_chain
);
4665 else if (TREE_CODE (selector
) == TREE_LIST
)
4666 key_name
= TREE_PURPOSE (key_chain
);
4671 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4675 return get_identifier (buf
);
4678 /* Used for declarations and definitions. */
4681 build_method_decl (code
, ret_type
, selector
, add_args
)
4682 enum tree_code code
;
4689 /* If no type is specified, default to "id". */
4690 ret_type
= adjust_type_for_id_default (ret_type
);
4692 method_decl
= make_node (code
);
4693 TREE_TYPE (method_decl
) = ret_type
;
4695 /* If we have a keyword selector, create an identifier_node that
4696 represents the full selector name (`:' included)... */
4697 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4699 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4700 METHOD_SEL_ARGS (method_decl
) = selector
;
4701 METHOD_ADD_ARGS (method_decl
) = add_args
;
4705 METHOD_SEL_NAME (method_decl
) = selector
;
4706 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4707 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4713 #define METHOD_DEF 0
4714 #define METHOD_REF 1
4716 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4717 an argument list for method METH. CONTEXT is either METHOD_DEF or
4718 METHOD_REF, saying whether we are trying to define a method or call
4719 one. SUPERFLAG says this is for a send to super; this makes a
4720 difference for the NeXT calling sequence in which the lookup and
4721 the method call are done together. */
4724 get_arg_type_list (meth
, context
, superflag
)
4731 /* Receiver type. */
4732 if (flag_next_runtime
&& superflag
)
4733 arglist
= build_tree_list (NULL_TREE
, super_type
);
4734 else if (context
== METHOD_DEF
)
4735 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4737 arglist
= build_tree_list (NULL_TREE
, id_type
);
4739 /* Selector type - will eventually change to `int'. */
4740 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4742 /* Build a list of argument types. */
4743 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4745 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4746 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4749 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4750 /* We have a `, ...' immediately following the selector,
4751 finalize the arglist...simulate get_parm_info (0). */
4753 else if (METHOD_ADD_ARGS (meth
))
4755 /* we have a variable length selector */
4756 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4757 chainon (arglist
, add_arg_list
);
4760 /* finalize the arglist...simulate get_parm_info (1) */
4761 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4767 check_duplicates (hsh
)
4770 tree meth
= NULL_TREE
;
4778 /* We have two methods with the same name and different types. */
4780 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4782 warning ("multiple declarations for method `%s'",
4783 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4785 warn_with_method ("using", type
, meth
);
4786 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4787 warn_with_method ("also found", type
, loop
->value
);
4793 /* If RECEIVER is a class reference, return the identifier node for
4794 the referenced class. RECEIVER is created by get_class_reference,
4795 so we check the exact form created depending on which runtimes are
4799 receiver_is_class_object (receiver
)
4802 tree chain
, exp
, arg
;
4804 /* The receiver is 'self' in the context of a class method. */
4805 if (objc_method_context
4806 && receiver
== self_decl
4807 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4809 return CLASS_NAME (objc_implementation_context
);
4812 if (flag_next_runtime
)
4814 /* The receiver is a variable created by
4815 build_class_reference_decl. */
4816 if (TREE_CODE (receiver
) == VAR_DECL
4817 && TREE_TYPE (receiver
) == objc_class_type
)
4818 /* Look up the identifier. */
4819 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4820 if (TREE_PURPOSE (chain
) == receiver
)
4821 return TREE_VALUE (chain
);
4825 /* The receiver is a function call that returns an id. Check if
4826 it is a call to objc_getClass, if so, pick up the class name. */
4827 if (TREE_CODE (receiver
) == CALL_EXPR
4828 && (exp
= TREE_OPERAND (receiver
, 0))
4829 && TREE_CODE (exp
) == ADDR_EXPR
4830 && (exp
= TREE_OPERAND (exp
, 0))
4831 && TREE_CODE (exp
) == FUNCTION_DECL
4832 && exp
== objc_get_class_decl
4833 /* We have a call to objc_getClass! */
4834 && (arg
= TREE_OPERAND (receiver
, 1))
4835 && TREE_CODE (arg
) == TREE_LIST
4836 && (arg
= TREE_VALUE (arg
)))
4839 if (TREE_CODE (arg
) == ADDR_EXPR
4840 && (arg
= TREE_OPERAND (arg
, 0))
4841 && TREE_CODE (arg
) == STRING_CST
)
4842 /* Finally, we have the class name. */
4843 return get_identifier (TREE_STRING_POINTER (arg
));
4849 /* If we are currently building a message expr, this holds
4850 the identifier of the selector of the message. This is
4851 used when printing warnings about argument mismatches. */
4853 static tree current_objc_message_selector
= 0;
4856 objc_message_selector ()
4858 return current_objc_message_selector
;
4861 /* Construct an expression for sending a message.
4862 MESS has the object to send to in TREE_PURPOSE
4863 and the argument list (including selector) in TREE_VALUE.
4865 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4866 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4869 build_message_expr (mess
)
4872 tree receiver
= TREE_PURPOSE (mess
);
4874 tree args
= TREE_VALUE (mess
);
4875 tree method_params
= NULL_TREE
;
4877 if (TREE_CODE (receiver
) == ERROR_MARK
)
4878 return error_mark_node
;
4880 /* Obtain the full selector name. */
4881 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4882 /* A unary selector. */
4884 else if (TREE_CODE (args
) == TREE_LIST
)
4885 sel_name
= build_keyword_selector (args
);
4889 /* Build the parameter list to give to the method. */
4890 if (TREE_CODE (args
) == TREE_LIST
)
4892 tree chain
= args
, prev
= NULL_TREE
;
4894 /* We have a keyword selector--check for comma expressions. */
4897 tree element
= TREE_VALUE (chain
);
4899 /* We have a comma expression, must collapse... */
4900 if (TREE_CODE (element
) == TREE_LIST
)
4903 TREE_CHAIN (prev
) = element
;
4908 chain
= TREE_CHAIN (chain
);
4910 method_params
= args
;
4913 return finish_message_expr (receiver
, sel_name
, method_params
);
4916 /* The 'finish_message_expr' routine is called from within
4917 'build_message_expr' for non-template functions. In the case of
4918 C++ template functions, it is called from 'build_expr_from_tree'
4919 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4922 finish_message_expr (receiver
, sel_name
, method_params
)
4923 tree receiver
, sel_name
, method_params
;
4925 tree method_prototype
= NULL_TREE
, class_ident
= NULL_TREE
;
4926 tree selector
, self_object
, retval
;
4927 int statically_typed
= 0, statically_allocated
= 0;
4929 /* Determine receiver type. */
4930 tree rtype
= TREE_TYPE (receiver
);
4931 int super
= IS_SUPER (rtype
);
4935 if (TREE_STATIC_TEMPLATE (rtype
))
4936 statically_allocated
= 1;
4937 else if (TREE_CODE (rtype
) == POINTER_TYPE
4938 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4939 statically_typed
= 1;
4940 else if ((flag_next_runtime
4942 && (class_ident
= receiver_is_class_object (receiver
)))
4944 else if (! IS_ID (rtype
)
4945 /* Allow any type that matches objc_class_type. */
4946 && ! comptypes (rtype
, objc_class_type
))
4948 warning ("invalid receiver type `%s'",
4949 gen_declaration (rtype
, errbuf
));
4951 if (statically_allocated
)
4952 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4954 /* Don't evaluate the receiver twice. */
4955 receiver
= save_expr (receiver
);
4956 self_object
= receiver
;
4959 /* If sending to `super', use current self as the object. */
4960 self_object
= self_decl
;
4962 /* Determine operation return type. */
4968 if (CLASS_SUPER_NAME (implementation_template
))
4971 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4973 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
4974 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4976 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4978 if (iface
&& !method_prototype
)
4979 warning ("`%s' does not respond to `%s'",
4980 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4981 IDENTIFIER_POINTER (sel_name
));
4985 error ("no super class declared in interface for `%s'",
4986 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4987 return error_mark_node
;
4991 else if (statically_allocated
)
4993 tree ctype
= TREE_TYPE (rtype
);
4994 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4997 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4999 if (! method_prototype
&& ctype
&& TYPE_PROTOCOL_LIST (ctype
))
5001 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5004 if (!method_prototype
)
5005 warning ("`%s' does not respond to `%s'",
5006 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5007 IDENTIFIER_POINTER (sel_name
));
5009 else if (statically_typed
)
5011 tree ctype
= TREE_TYPE (rtype
);
5013 /* `self' is now statically_typed. All methods should be visible
5014 within the context of the implementation. */
5015 if (objc_implementation_context
5016 && CLASS_NAME (objc_implementation_context
) == TYPE_NAME (ctype
))
5019 = lookup_instance_method_static (implementation_template
,
5022 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5024 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5027 if (! method_prototype
5028 && implementation_template
!= objc_implementation_context
)
5029 /* The method is not published in the interface. Check
5032 = lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
5039 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5040 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5042 if (! method_prototype
)
5044 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5047 = lookup_method_in_protocol_list (protocol_list
,
5052 if (!method_prototype
)
5053 warning ("`%s' does not respond to `%s'",
5054 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5055 IDENTIFIER_POINTER (sel_name
));
5057 else if (class_ident
)
5059 if (objc_implementation_context
5060 && CLASS_NAME (objc_implementation_context
) == class_ident
)
5063 = lookup_class_method_static (implementation_template
, sel_name
);
5065 if (!method_prototype
5066 && implementation_template
!= objc_implementation_context
)
5067 /* The method is not published in the interface. Check
5070 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context
),
5077 if ((iface
= lookup_interface (class_ident
)))
5078 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5081 if (!method_prototype
)
5083 warning ("cannot find class (factory) method");
5084 warning ("return type for `%s' defaults to id",
5085 IDENTIFIER_POINTER (sel_name
));
5088 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5090 /* An anonymous object that has been qualified with a protocol. */
5092 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5094 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5097 if (!method_prototype
)
5101 warning ("method `%s' not implemented by protocol",
5102 IDENTIFIER_POINTER (sel_name
));
5104 /* Try and find the method signature in the global pools. */
5106 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5107 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5109 if (!(method_prototype
= check_duplicates (hsh
)))
5110 warning ("return type defaults to id");
5117 /* We think we have an instance...loophole: extern id Object; */
5118 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5121 /* For various loopholes */
5122 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5124 method_prototype
= check_duplicates (hsh
);
5125 if (!method_prototype
)
5127 warning ("cannot find method");
5128 warning ("return type for `%s' defaults to id",
5129 IDENTIFIER_POINTER (sel_name
));
5133 /* Save the selector name for printing error messages. */
5134 current_objc_message_selector
= sel_name
;
5136 /* Build the parameters list for looking up the method.
5137 These are the object itself and the selector. */
5139 if (flag_typed_selectors
)
5140 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5142 selector
= build_selector_reference (sel_name
);
5144 retval
= build_objc_method_call (super
, method_prototype
,
5145 receiver
, self_object
,
5146 selector
, method_params
);
5148 current_objc_message_selector
= 0;
5153 /* Build a tree expression to send OBJECT the operation SELECTOR,
5154 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5155 assuming the method has prototype METHOD_PROTOTYPE.
5156 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5157 Use METHOD_PARAMS as list of args to pass to the method.
5158 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5161 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5162 selector
, method_params
)
5164 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5166 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5167 tree rcv_p
= (super_flag
5168 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5169 get_identifier (TAG_SUPER
)))
5172 if (flag_next_runtime
)
5174 if (! method_prototype
)
5176 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5177 tree_cons (NULL_TREE
, selector
,
5179 assemble_external (sender
);
5180 return build_function_call (sender
, method_params
);
5184 /* This is a real kludge, but it is used only for the Next.
5185 Clobber the data type of SENDER temporarily to accept
5186 all the arguments for this operation, and to return
5187 whatever this operation returns. */
5188 tree arglist
= NULL_TREE
, retval
, savarg
, savret
;
5189 tree ret_type
= groktypename (TREE_TYPE (method_prototype
));
5191 /* Save the proper contents of SENDER's data type. */
5192 savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5193 savret
= TREE_TYPE (TREE_TYPE (sender
));
5195 /* Install this method's argument types. */
5196 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5198 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5200 /* Install this method's return type. */
5201 TREE_TYPE (TREE_TYPE (sender
)) = ret_type
;
5203 /* Call SENDER with all the parameters. This will do type
5204 checking using the arg types for this method. */
5205 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5206 tree_cons (NULL_TREE
, selector
,
5208 assemble_external (sender
);
5209 retval
= build_function_call (sender
, method_params
);
5211 /* Restore SENDER's return/argument types. */
5212 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5213 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5219 /* This is the portable way.
5220 First call the lookup function to get a pointer to the method,
5221 then cast the pointer, then call it with the method arguments. */
5224 /* Avoid trouble since we may evaluate each of these twice. */
5225 object
= save_expr (object
);
5226 selector
= save_expr (selector
);
5228 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5230 assemble_external (sender
);
5232 = build_function_call (sender
,
5233 tree_cons (NULL_TREE
, lookup_object
,
5234 tree_cons (NULL_TREE
, selector
,
5237 /* If we have a method prototype, construct the data type this
5238 method needs, and cast what we got from SENDER into a pointer
5240 if (method_prototype
)
5242 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5244 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5245 tree fake_function_type
= build_function_type (valtype
, arglist
);
5246 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5250 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5252 /* Pass the object to the method. */
5253 assemble_external (method
);
5254 return build_function_call (method
,
5255 tree_cons (NULL_TREE
, object
,
5256 tree_cons (NULL_TREE
, selector
,
5262 build_protocol_reference (p
)
5265 tree decl
, ident
, ptype
;
5267 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5269 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5271 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5272 objc_protocol_template
),
5275 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5276 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5279 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5280 DECL_EXTERNAL (decl
) = 1;
5281 TREE_PUBLIC (decl
) = 1;
5282 TREE_USED (decl
) = 1;
5283 DECL_ARTIFICIAL (decl
) = 1;
5285 make_decl_rtl (decl
, 0);
5286 pushdecl_top_level (decl
);
5289 PROTOCOL_FORWARD_DECL (p
) = decl
;
5292 /* This function is called by the parser when (and only when) a
5293 @protocol() expression is found, in order to compile it. */
5295 build_protocol_expr (protoname
)
5299 tree p
= lookup_protocol (protoname
);
5303 error ("cannot find protocol declaration for `%s'",
5304 IDENTIFIER_POINTER (protoname
));
5305 return error_mark_node
;
5308 if (!PROTOCOL_FORWARD_DECL (p
))
5309 build_protocol_reference (p
);
5311 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5313 TREE_TYPE (expr
) = protocol_type
;
5315 /* The @protocol() expression is being compiled into a pointer to a
5316 statically allocated instance of the Protocol class. To become
5317 usable at runtime, the 'isa' pointer of the instance need to be
5318 fixed up at runtime by the runtime library, to point to the
5319 actual 'Protocol' class. */
5321 /* For the GNU runtime, put the static Protocol instance in the list
5322 of statically allocated instances, so that we make sure that its
5323 'isa' pointer is fixed up at runtime by the GNU runtime library
5324 to point to the Protocol class (at runtime, when loading the
5325 module, the GNU runtime library loops on the statically allocated
5326 instances (as found in the defs field in objc_symtab) and fixups
5327 all the 'isa' pointers of those objects). */
5328 if (! flag_next_runtime
)
5330 /* This type is a struct containing the fields of a Protocol
5331 object. (Cfr. protocol_type instead is the type of a pointer
5332 to such a struct). */
5333 tree protocol_struct_type
= xref_tag
5334 (RECORD_TYPE
, get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
5337 /* Look for the list of Protocol statically allocated instances
5338 to fixup at runtime. Create a new list to hold Protocol
5339 statically allocated instances, if the list is not found. At
5340 present there is only another list, holding NSConstantString
5341 static instances to be fixed up at runtime. */
5342 for (chain
= &objc_static_instances
;
5343 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
5344 chain
= &TREE_CHAIN (*chain
));
5347 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
5348 add_objc_string (TYPE_NAME (protocol_struct_type
),
5352 /* Add this statically allocated instance to the Protocol list. */
5353 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
5354 PROTOCOL_FORWARD_DECL (p
),
5355 TREE_PURPOSE (*chain
));
5362 /* This function is called by the parser when a @selector() expression
5363 is found, in order to compile it. It is only called by the parser
5364 and only to compile a @selector(). */
5366 build_selector_expr (selnamelist
)
5371 /* Obtain the full selector name. */
5372 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5373 /* A unary selector. */
5374 selname
= selnamelist
;
5375 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5376 selname
= build_keyword_selector (selnamelist
);
5380 /* If we are required to check @selector() expressions as they
5381 are found, check that the selector has been declared. */
5382 if (warn_undeclared_selector
)
5384 /* Look the selector up in the list of all known class and
5385 instance methods (up to this line) to check that the selector
5389 /* First try with instance methods. */
5390 hsh
= hash_lookup (nst_method_hash_list
, selname
);
5392 /* If not found, try with class methods. */
5395 hsh
= hash_lookup (cls_method_hash_list
, selname
);
5398 /* If still not found, print out a warning. */
5401 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname
));
5406 if (flag_typed_selectors
)
5407 return build_typed_selector_reference (selname
, 0);
5409 return build_selector_reference (selname
);
5413 build_encode_expr (type
)
5419 encode_type (type
, obstack_object_size (&util_obstack
),
5420 OBJC_ENCODE_INLINE_DEFS
);
5421 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5422 string
= obstack_finish (&util_obstack
);
5424 /* Synthesize a string that represents the encoded struct/union. */
5425 result
= my_build_string (strlen (string
) + 1, string
);
5426 obstack_free (&util_obstack
, util_firstobj
);
5431 build_ivar_reference (id
)
5434 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5436 /* Historically, a class method that produced objects (factory
5437 method) would assign `self' to the instance that it
5438 allocated. This would effectively turn the class method into
5439 an instance method. Following this assignment, the instance
5440 variables could be accessed. That practice, while safe,
5441 violates the simple rule that a class method should not refer
5442 to an instance variable. It's better to catch the cases
5443 where this is done unknowingly than to support the above
5445 warning ("instance variable `%s' accessed in class method",
5446 IDENTIFIER_POINTER (id
));
5447 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5450 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5453 /* Compute a hash value for a given method SEL_NAME. */
5456 hash_func (sel_name
)
5459 const unsigned char *s
5460 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
5464 h
= h
* 67 + *s
++ - 113;
5471 nst_method_hash_list
= (hash
*) ggc_calloc (SIZEHASHTABLE
, sizeof (hash
));
5472 cls_method_hash_list
= (hash
*) ggc_calloc (SIZEHASHTABLE
, sizeof (hash
));
5475 /* WARNING!!!! hash_enter is called with a method, and will peek
5476 inside to find its selector! But hash_lookup is given a selector
5477 directly, and looks for the selector that's inside the found
5478 entry's key (method) for comparison. */
5481 hash_enter (hashlist
, method
)
5486 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5488 obj
= (hash
) ggc_alloc (sizeof (struct hashed_entry
));
5490 obj
->next
= hashlist
[slot
];
5493 hashlist
[slot
] = obj
; /* append to front */
5497 hash_lookup (hashlist
, sel_name
)
5503 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
5507 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5510 target
= target
->next
;
5516 hash_add_attr (entry
, value
)
5522 obj
= (attr
) ggc_alloc (sizeof (struct hashed_attribute
));
5523 obj
->next
= entry
->list
;
5526 entry
->list
= obj
; /* append to front */
5530 lookup_method (mchain
, method
)
5536 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5539 key
= METHOD_SEL_NAME (method
);
5543 if (METHOD_SEL_NAME (mchain
) == key
)
5546 mchain
= TREE_CHAIN (mchain
);
5552 lookup_instance_method_static (interface
, ident
)
5556 tree inter
= interface
;
5557 tree chain
= CLASS_NST_METHODS (inter
);
5558 tree meth
= NULL_TREE
;
5562 if ((meth
= lookup_method (chain
, ident
)))
5565 if (CLASS_CATEGORY_LIST (inter
))
5567 tree category
= CLASS_CATEGORY_LIST (inter
);
5568 chain
= CLASS_NST_METHODS (category
);
5572 if ((meth
= lookup_method (chain
, ident
)))
5575 /* Check for instance methods in protocols in categories. */
5576 if (CLASS_PROTOCOL_LIST (category
))
5578 if ((meth
= (lookup_method_in_protocol_list
5579 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5583 if ((category
= CLASS_CATEGORY_LIST (category
)))
5584 chain
= CLASS_NST_METHODS (category
);
5589 if (CLASS_PROTOCOL_LIST (inter
))
5591 if ((meth
= (lookup_method_in_protocol_list
5592 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5596 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5597 chain
= CLASS_NST_METHODS (inter
);
5605 lookup_class_method_static (interface
, ident
)
5609 tree inter
= interface
;
5610 tree chain
= CLASS_CLS_METHODS (inter
);
5611 tree meth
= NULL_TREE
;
5612 tree root_inter
= NULL_TREE
;
5616 if ((meth
= lookup_method (chain
, ident
)))
5619 if (CLASS_CATEGORY_LIST (inter
))
5621 tree category
= CLASS_CATEGORY_LIST (inter
);
5622 chain
= CLASS_CLS_METHODS (category
);
5626 if ((meth
= lookup_method (chain
, ident
)))
5629 /* Check for class methods in protocols in categories. */
5630 if (CLASS_PROTOCOL_LIST (category
))
5632 if ((meth
= (lookup_method_in_protocol_list
5633 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5637 if ((category
= CLASS_CATEGORY_LIST (category
)))
5638 chain
= CLASS_CLS_METHODS (category
);
5643 /* Check for class methods in protocols. */
5644 if (CLASS_PROTOCOL_LIST (inter
))
5646 if ((meth
= (lookup_method_in_protocol_list
5647 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5652 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5653 chain
= CLASS_CLS_METHODS (inter
);
5657 /* If no class (factory) method was found, check if an _instance_
5658 method of the same name exists in the root class. This is what
5659 the Objective-C runtime will do. */
5660 return lookup_instance_method_static (root_inter
, ident
);
5664 add_class_method (class, method
)
5671 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5673 /* put method on list in reverse order */
5674 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5675 CLASS_CLS_METHODS (class) = method
;
5679 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5680 error ("duplicate definition of class method `%s'",
5681 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5684 /* Check types; if different, complain. */
5685 if (!comp_proto_with_proto (method
, mth
))
5686 error ("duplicate declaration of class method `%s'",
5687 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5691 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5693 /* Install on a global chain. */
5694 hash_enter (cls_method_hash_list
, method
);
5698 /* Check types; if different, add to a list. */
5699 if (!comp_proto_with_proto (method
, hsh
->key
))
5700 hash_add_attr (hsh
, method
);
5706 add_instance_method (class, method
)
5713 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5715 /* Put method on list in reverse order. */
5716 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5717 CLASS_NST_METHODS (class) = method
;
5721 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5722 error ("duplicate definition of instance method `%s'",
5723 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5726 /* Check types; if different, complain. */
5727 if (!comp_proto_with_proto (method
, mth
))
5728 error ("duplicate declaration of instance method `%s'",
5729 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5733 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5735 /* Install on a global chain. */
5736 hash_enter (nst_method_hash_list
, method
);
5740 /* Check types; if different, add to a list. */
5741 if (!comp_proto_with_proto (method
, hsh
->key
))
5742 hash_add_attr (hsh
, method
);
5751 /* Put interfaces on list in reverse order. */
5752 TREE_CHAIN (class) = interface_chain
;
5753 interface_chain
= class;
5754 return interface_chain
;
5758 add_category (class, category
)
5762 /* Put categories on list in reverse order. */
5763 tree cat
= CLASS_CATEGORY_LIST (class);
5767 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5768 warning ("duplicate interface declaration for category `%s(%s)'",
5769 IDENTIFIER_POINTER (CLASS_NAME (class)),
5770 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5771 cat
= CLASS_CATEGORY_LIST (cat
);
5774 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5775 CLASS_CATEGORY_LIST (class) = category
;
5778 /* Called after parsing each instance variable declaration. Necessary to
5779 preserve typedefs and implement public/private...
5781 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5784 add_instance_variable (class, public, declarator
, declspecs
, width
)
5791 tree field_decl
, raw_decl
;
5793 raw_decl
= build_tree_list (declspecs
, declarator
);
5795 if (CLASS_RAW_IVARS (class))
5796 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5798 CLASS_RAW_IVARS (class) = raw_decl
;
5800 field_decl
= grokfield (input_filename
, lineno
,
5801 declarator
, declspecs
, width
);
5803 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5807 TREE_PUBLIC (field_decl
) = 0;
5808 TREE_PRIVATE (field_decl
) = 0;
5809 TREE_PROTECTED (field_decl
) = 1;
5813 TREE_PUBLIC (field_decl
) = 1;
5814 TREE_PRIVATE (field_decl
) = 0;
5815 TREE_PROTECTED (field_decl
) = 0;
5819 TREE_PUBLIC (field_decl
) = 0;
5820 TREE_PRIVATE (field_decl
) = 1;
5821 TREE_PROTECTED (field_decl
) = 0;
5826 if (CLASS_IVARS (class))
5827 chainon (CLASS_IVARS (class), field_decl
);
5829 CLASS_IVARS (class) = field_decl
;
5835 is_ivar (decl_chain
, ident
)
5839 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5840 if (DECL_NAME (decl_chain
) == ident
)
5845 /* True if the ivar is private and we are not in its implementation. */
5851 if (TREE_PRIVATE (decl
)
5852 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5854 error ("instance variable `%s' is declared private",
5855 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5862 /* We have an instance variable reference;, check to see if it is public. */
5865 is_public (expr
, identifier
)
5869 tree basetype
= TREE_TYPE (expr
);
5870 enum tree_code code
= TREE_CODE (basetype
);
5873 if (code
== RECORD_TYPE
)
5875 if (TREE_STATIC_TEMPLATE (basetype
))
5877 if (!lookup_interface (TYPE_NAME (basetype
)))
5879 error ("cannot find interface declaration for `%s'",
5880 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5884 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5886 if (TREE_PUBLIC (decl
))
5889 /* Important difference between the Stepstone translator:
5890 all instance variables should be public within the context
5891 of the implementation. */
5892 if (objc_implementation_context
5893 && (((TREE_CODE (objc_implementation_context
)
5894 == CLASS_IMPLEMENTATION_TYPE
)
5895 || (TREE_CODE (objc_implementation_context
)
5896 == CATEGORY_IMPLEMENTATION_TYPE
))
5897 && (CLASS_NAME (objc_implementation_context
)
5898 == TYPE_NAME (basetype
))))
5899 return ! is_private (decl
);
5901 error ("instance variable `%s' is declared %s",
5902 IDENTIFIER_POINTER (identifier
),
5903 TREE_PRIVATE (decl
) ? "private" : "protected");
5908 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
5910 TREE_TYPE (expr
) = uprivate_record
;
5911 warning ("static access to object of type `id'");
5918 /* Make sure all entries in CHAIN are also in LIST. */
5921 check_methods (chain
, list
, mtype
)
5930 if (!lookup_method (list
, chain
))
5934 if (TREE_CODE (objc_implementation_context
)
5935 == CLASS_IMPLEMENTATION_TYPE
)
5936 warning ("incomplete implementation of class `%s'",
5937 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
5938 else if (TREE_CODE (objc_implementation_context
)
5939 == CATEGORY_IMPLEMENTATION_TYPE
)
5940 warning ("incomplete implementation of category `%s'",
5941 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
5945 warning ("method definition for `%c%s' not found",
5946 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5949 chain
= TREE_CHAIN (chain
);
5955 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5958 conforms_to_protocol (class, protocol
)
5962 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
5964 tree p
= CLASS_PROTOCOL_LIST (class);
5965 while (p
&& TREE_VALUE (p
) != protocol
)
5970 tree super
= (CLASS_SUPER_NAME (class)
5971 ? lookup_interface (CLASS_SUPER_NAME (class))
5973 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5982 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5983 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5986 check_methods_accessible (chain
, context
, mtype
)
5993 tree base_context
= context
;
5997 context
= base_context
;
6001 list
= CLASS_CLS_METHODS (context
);
6003 list
= CLASS_NST_METHODS (context
);
6005 if (lookup_method (list
, chain
))
6008 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
6009 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6010 context
= (CLASS_SUPER_NAME (context
)
6011 ? lookup_interface (CLASS_SUPER_NAME (context
))
6014 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6015 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6016 context
= (CLASS_NAME (context
)
6017 ? lookup_interface (CLASS_NAME (context
))
6023 if (context
== NULL_TREE
)
6027 if (TREE_CODE (objc_implementation_context
)
6028 == CLASS_IMPLEMENTATION_TYPE
)
6029 warning ("incomplete implementation of class `%s'",
6031 (CLASS_NAME (objc_implementation_context
)));
6032 else if (TREE_CODE (objc_implementation_context
)
6033 == CATEGORY_IMPLEMENTATION_TYPE
)
6034 warning ("incomplete implementation of category `%s'",
6036 (CLASS_SUPER_NAME (objc_implementation_context
)));
6039 warning ("method definition for `%c%s' not found",
6040 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6043 chain
= TREE_CHAIN (chain
); /* next method... */
6048 /* Check whether the current interface (accessible via
6049 'objc_implementation_context') actually implements protocol P, along
6050 with any protocols that P inherits. */
6053 check_protocol (p
, type
, name
)
6058 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6062 /* Ensure that all protocols have bodies! */
6065 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6066 CLASS_CLS_METHODS (objc_implementation_context
),
6068 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6069 CLASS_NST_METHODS (objc_implementation_context
),
6074 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6075 objc_implementation_context
,
6077 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6078 objc_implementation_context
,
6083 warning ("%s `%s' does not fully implement the `%s' protocol",
6084 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6087 /* Check protocols recursively. */
6088 if (PROTOCOL_LIST (p
))
6090 tree subs
= PROTOCOL_LIST (p
);
6092 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6096 tree sub
= TREE_VALUE (subs
);
6098 /* If the superclass does not conform to the protocols
6099 inherited by P, then we must! */
6100 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
6101 check_protocol (sub
, type
, name
);
6102 subs
= TREE_CHAIN (subs
);
6107 /* Check whether the current interface (accessible via
6108 'objc_implementation_context') actually implements the protocols listed
6112 check_protocols (proto_list
, type
, name
)
6117 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6119 tree p
= TREE_VALUE (proto_list
);
6121 check_protocol (p
, type
, name
);
6125 /* Make sure that the class CLASS_NAME is defined
6126 CODE says which kind of thing CLASS_NAME ought to be.
6127 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6128 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6131 start_class (code
, class_name
, super_name
, protocol_list
)
6132 enum tree_code code
;
6139 if (objc_implementation_context
)
6141 warning ("`@end' missing in implementation context");
6142 finish_class (objc_implementation_context
);
6143 objc_ivar_chain
= NULL_TREE
;
6144 objc_implementation_context
= NULL_TREE
;
6147 class = make_node (code
);
6148 TYPE_BINFO (class) = make_tree_vec (6);
6150 CLASS_NAME (class) = class_name
;
6151 CLASS_SUPER_NAME (class) = super_name
;
6152 CLASS_CLS_METHODS (class) = NULL_TREE
;
6154 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6156 error ("`%s' redeclared as different kind of symbol",
6157 IDENTIFIER_POINTER (class_name
));
6158 error_with_decl (decl
, "previous declaration of `%s'");
6161 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6166 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6167 if (TREE_VALUE (chain
) == class_name
)
6169 error ("reimplementation of class `%s'",
6170 IDENTIFIER_POINTER (class_name
));
6171 return error_mark_node
;
6173 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6174 implemented_classes
);
6177 /* Pre-build the following entities - for speed/convenience. */
6179 self_id
= get_identifier ("self");
6181 ucmd_id
= get_identifier ("_cmd");
6184 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6185 if (!objc_super_template
)
6186 objc_super_template
= build_super_template ();
6188 /* Reset for multiple classes per file. */
6191 objc_implementation_context
= class;
6193 /* Lookup the interface for this implementation. */
6195 if (!(implementation_template
= lookup_interface (class_name
)))
6197 warning ("cannot find interface declaration for `%s'",
6198 IDENTIFIER_POINTER (class_name
));
6199 add_class (implementation_template
= objc_implementation_context
);
6202 /* If a super class has been specified in the implementation,
6203 insure it conforms to the one specified in the interface. */
6206 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6208 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6209 const char *const name
=
6210 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6211 error ("conflicting super class name `%s'",
6212 IDENTIFIER_POINTER (super_name
));
6213 error ("previous declaration of `%s'", name
);
6216 else if (! super_name
)
6218 CLASS_SUPER_NAME (objc_implementation_context
)
6219 = CLASS_SUPER_NAME (implementation_template
);
6223 else if (code
== CLASS_INTERFACE_TYPE
)
6225 if (lookup_interface (class_name
))
6226 warning ("duplicate interface declaration for class `%s'",
6227 IDENTIFIER_POINTER (class_name
));
6232 CLASS_PROTOCOL_LIST (class)
6233 = lookup_and_install_protocols (protocol_list
);
6236 else if (code
== CATEGORY_INTERFACE_TYPE
)
6238 tree class_category_is_assoc_with
;
6240 /* For a category, class_name is really the name of the class that
6241 the following set of methods will be associated with. We must
6242 find the interface so that can derive the objects template. */
6244 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6246 error ("cannot find interface declaration for `%s'",
6247 IDENTIFIER_POINTER (class_name
));
6248 exit (FATAL_EXIT_CODE
);
6251 add_category (class_category_is_assoc_with
, class);
6254 CLASS_PROTOCOL_LIST (class)
6255 = lookup_and_install_protocols (protocol_list
);
6258 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6260 /* Pre-build the following entities for speed/convenience. */
6262 self_id
= get_identifier ("self");
6264 ucmd_id
= get_identifier ("_cmd");
6267 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6268 if (!objc_super_template
)
6269 objc_super_template
= build_super_template ();
6271 /* Reset for multiple classes per file. */
6274 objc_implementation_context
= class;
6276 /* For a category, class_name is really the name of the class that
6277 the following set of methods will be associated with. We must
6278 find the interface so that can derive the objects template. */
6280 if (!(implementation_template
= lookup_interface (class_name
)))
6282 error ("cannot find interface declaration for `%s'",
6283 IDENTIFIER_POINTER (class_name
));
6284 exit (FATAL_EXIT_CODE
);
6291 continue_class (class)
6294 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6295 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6297 struct imp_entry
*imp_entry
;
6300 /* Check consistency of the instance variables. */
6302 if (CLASS_IVARS (class))
6303 check_ivars (implementation_template
, class);
6305 /* code generation */
6307 ivar_context
= build_private_template (implementation_template
);
6309 if (!objc_class_template
)
6310 build_class_template ();
6312 imp_entry
= (struct imp_entry
*) ggc_alloc (sizeof (struct imp_entry
));
6314 imp_entry
->next
= imp_list
;
6315 imp_entry
->imp_context
= class;
6316 imp_entry
->imp_template
= implementation_template
;
6318 synth_forward_declarations ();
6319 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6320 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6322 /* Append to front and increment count. */
6323 imp_list
= imp_entry
;
6324 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6329 return ivar_context
;
6332 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6334 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6336 if (!TYPE_FIELDS (record
))
6338 finish_struct (record
, get_class_ivars (class), NULL_TREE
);
6339 CLASS_STATIC_TEMPLATE (class) = record
;
6341 /* Mark this record as a class template for static typing. */
6342 TREE_STATIC_TEMPLATE (record
) = 1;
6349 return error_mark_node
;
6352 /* This is called once we see the "@end" in an interface/implementation. */
6355 finish_class (class)
6358 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6360 /* All code generation is done in finish_objc. */
6362 if (implementation_template
!= objc_implementation_context
)
6364 /* Ensure that all method listed in the interface contain bodies. */
6365 check_methods (CLASS_CLS_METHODS (implementation_template
),
6366 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6367 check_methods (CLASS_NST_METHODS (implementation_template
),
6368 CLASS_NST_METHODS (objc_implementation_context
), '-');
6370 if (CLASS_PROTOCOL_LIST (implementation_template
))
6371 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6373 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6377 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6379 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6381 /* Find the category interface from the class it is associated with. */
6384 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6386 category
= CLASS_CATEGORY_LIST (category
);
6391 /* Ensure all method listed in the interface contain bodies. */
6392 check_methods (CLASS_CLS_METHODS (category
),
6393 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6394 check_methods (CLASS_NST_METHODS (category
),
6395 CLASS_NST_METHODS (objc_implementation_context
), '-');
6397 if (CLASS_PROTOCOL_LIST (category
))
6398 check_protocols (CLASS_PROTOCOL_LIST (category
),
6400 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6404 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6407 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6408 char *string
= (char *) alloca (strlen (class_name
) + 3);
6410 /* extern struct objc_object *_<my_name>; */
6412 sprintf (string
, "_%s", class_name
);
6414 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6415 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6416 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6422 add_protocol (protocol
)
6425 /* Put protocol on list in reverse order. */
6426 TREE_CHAIN (protocol
) = protocol_chain
;
6427 protocol_chain
= protocol
;
6428 return protocol_chain
;
6432 lookup_protocol (ident
)
6437 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6438 if (ident
== PROTOCOL_NAME (chain
))
6444 /* This function forward declares the protocols named by NAMES. If
6445 they are already declared or defined, the function has no effect. */
6448 objc_declare_protocols (names
)
6453 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6455 tree name
= TREE_VALUE (list
);
6457 if (lookup_protocol (name
) == NULL_TREE
)
6459 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6461 TYPE_BINFO (protocol
) = make_tree_vec (2);
6462 PROTOCOL_NAME (protocol
) = name
;
6463 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6464 add_protocol (protocol
);
6465 PROTOCOL_DEFINED (protocol
) = 0;
6466 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6472 start_protocol (code
, name
, list
)
6473 enum tree_code code
;
6479 /* This is as good a place as any. Need to invoke
6480 push_tag_toplevel. */
6481 if (!objc_protocol_template
)
6482 objc_protocol_template
= build_protocol_template ();
6484 protocol
= lookup_protocol (name
);
6488 protocol
= make_node (code
);
6489 TYPE_BINFO (protocol
) = make_tree_vec (2);
6491 PROTOCOL_NAME (protocol
) = name
;
6492 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6493 add_protocol (protocol
);
6494 PROTOCOL_DEFINED (protocol
) = 1;
6495 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6497 check_protocol_recursively (protocol
, list
);
6499 else if (! PROTOCOL_DEFINED (protocol
))
6501 PROTOCOL_DEFINED (protocol
) = 1;
6502 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6504 check_protocol_recursively (protocol
, list
);
6508 warning ("duplicate declaration for protocol `%s'",
6509 IDENTIFIER_POINTER (name
));
6515 finish_protocol (protocol
)
6516 tree protocol ATTRIBUTE_UNUSED
;
6521 /* "Encode" a data type into a string, which grows in util_obstack.
6522 ??? What is the FORMAT? Someone please document this! */
6525 encode_type_qualifiers (declspecs
)
6530 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6532 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6533 obstack_1grow (&util_obstack
, 'r');
6534 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6535 obstack_1grow (&util_obstack
, 'n');
6536 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6537 obstack_1grow (&util_obstack
, 'N');
6538 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6539 obstack_1grow (&util_obstack
, 'o');
6540 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6541 obstack_1grow (&util_obstack
, 'O');
6542 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6543 obstack_1grow (&util_obstack
, 'R');
6544 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6545 obstack_1grow (&util_obstack
, 'V');
6549 /* Encode a pointer type. */
6552 encode_pointer (type
, curtype
, format
)
6557 tree pointer_to
= TREE_TYPE (type
);
6559 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6561 if (TYPE_NAME (pointer_to
)
6562 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6564 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6566 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6568 obstack_1grow (&util_obstack
, '@');
6571 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6573 if (generating_instance_variables
)
6575 obstack_1grow (&util_obstack
, '@');
6576 obstack_1grow (&util_obstack
, '"');
6577 obstack_grow (&util_obstack
, name
, strlen (name
));
6578 obstack_1grow (&util_obstack
, '"');
6583 obstack_1grow (&util_obstack
, '@');
6587 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6589 obstack_1grow (&util_obstack
, '#');
6592 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6594 obstack_1grow (&util_obstack
, ':');
6599 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6600 && TYPE_MODE (pointer_to
) == QImode
)
6602 obstack_1grow (&util_obstack
, '*');
6606 /* We have a type that does not get special treatment. */
6608 /* NeXT extension */
6609 obstack_1grow (&util_obstack
, '^');
6610 encode_type (pointer_to
, curtype
, format
);
6614 encode_array (type
, curtype
, format
)
6619 tree an_int_cst
= TYPE_SIZE (type
);
6620 tree array_of
= TREE_TYPE (type
);
6623 /* An incomplete array is treated like a pointer. */
6624 if (an_int_cst
== NULL
)
6626 encode_pointer (type
, curtype
, format
);
6630 sprintf (buffer
, "[%ld",
6631 (long) (TREE_INT_CST_LOW (an_int_cst
)
6632 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6634 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6635 encode_type (array_of
, curtype
, format
);
6636 obstack_1grow (&util_obstack
, ']');
6641 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6648 /* The RECORD_TYPE may in fact be a typedef! For purposes
6649 of encoding, we need the real underlying enchilada. */
6650 if (TYPE_MAIN_VARIANT (type
))
6651 type
= TYPE_MAIN_VARIANT (type
);
6653 if (obstack_object_size (&util_obstack
) > 0
6654 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6656 tree name
= TYPE_NAME (type
);
6658 /* we have a reference; this is a NeXT extension. */
6660 if (obstack_object_size (&util_obstack
) - curtype
== 1
6661 && format
== OBJC_ENCODE_INLINE_DEFS
)
6663 /* Output format of struct for first level only. */
6664 tree fields
= TYPE_FIELDS (type
);
6666 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6668 obstack_1grow (&util_obstack
, left
);
6669 obstack_grow (&util_obstack
,
6670 IDENTIFIER_POINTER (name
),
6671 strlen (IDENTIFIER_POINTER (name
)));
6672 obstack_1grow (&util_obstack
, '=');
6676 obstack_1grow (&util_obstack
, left
);
6677 obstack_grow (&util_obstack
, "?=", 2);
6680 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6681 encode_field_decl (fields
, curtype
, format
);
6683 obstack_1grow (&util_obstack
, right
);
6686 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6688 obstack_1grow (&util_obstack
, left
);
6689 obstack_grow (&util_obstack
,
6690 IDENTIFIER_POINTER (name
),
6691 strlen (IDENTIFIER_POINTER (name
)));
6692 obstack_1grow (&util_obstack
, right
);
6697 /* We have an untagged structure or a typedef. */
6698 obstack_1grow (&util_obstack
, left
);
6699 obstack_1grow (&util_obstack
, '?');
6700 obstack_1grow (&util_obstack
, right
);
6706 tree name
= TYPE_NAME (type
);
6707 tree fields
= TYPE_FIELDS (type
);
6709 if (format
== OBJC_ENCODE_INLINE_DEFS
6710 || generating_instance_variables
)
6712 obstack_1grow (&util_obstack
, left
);
6713 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6714 obstack_grow (&util_obstack
,
6715 IDENTIFIER_POINTER (name
),
6716 strlen (IDENTIFIER_POINTER (name
)));
6718 obstack_1grow (&util_obstack
, '?');
6720 obstack_1grow (&util_obstack
, '=');
6722 for (; fields
; fields
= TREE_CHAIN (fields
))
6724 if (generating_instance_variables
)
6726 tree fname
= DECL_NAME (fields
);
6728 obstack_1grow (&util_obstack
, '"');
6729 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6731 obstack_grow (&util_obstack
,
6732 IDENTIFIER_POINTER (fname
),
6733 strlen (IDENTIFIER_POINTER (fname
)));
6736 obstack_1grow (&util_obstack
, '"');
6739 encode_field_decl (fields
, curtype
, format
);
6742 obstack_1grow (&util_obstack
, right
);
6747 obstack_1grow (&util_obstack
, left
);
6748 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6749 obstack_grow (&util_obstack
,
6750 IDENTIFIER_POINTER (name
),
6751 strlen (IDENTIFIER_POINTER (name
)));
6753 /* We have an untagged structure or a typedef. */
6754 obstack_1grow (&util_obstack
, '?');
6756 obstack_1grow (&util_obstack
, right
);
6762 encode_aggregate (type
, curtype
, format
)
6767 enum tree_code code
= TREE_CODE (type
);
6773 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6778 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6783 obstack_1grow (&util_obstack
, 'i');
6791 /* Support bitfields. The current version of Objective-C does not support
6792 them. The string will consist of one or more "b:n"'s where n is an
6793 integer describing the width of the bitfield. Currently, classes in
6794 the kit implement a method "-(char *)describeBitfieldStruct:" that
6795 simulates this. If they do not implement this method, the archiver
6796 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6797 according to the GNU compiler. After looking at the "kit", it appears
6798 that all classes currently rely on this default behavior, rather than
6799 hand generating this string (which is tedious). */
6802 encode_bitfield (width
)
6806 sprintf (buffer
, "b%d", width
);
6807 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6810 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6813 encode_type (type
, curtype
, format
)
6818 enum tree_code code
= TREE_CODE (type
);
6820 if (code
== INTEGER_TYPE
)
6822 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6824 /* Unsigned integer types. */
6826 if (TYPE_MODE (type
) == QImode
)
6827 obstack_1grow (&util_obstack
, 'C');
6828 else if (TYPE_MODE (type
) == HImode
)
6829 obstack_1grow (&util_obstack
, 'S');
6830 else if (TYPE_MODE (type
) == SImode
)
6832 if (type
== long_unsigned_type_node
)
6833 obstack_1grow (&util_obstack
, 'L');
6835 obstack_1grow (&util_obstack
, 'I');
6837 else if (TYPE_MODE (type
) == DImode
)
6838 obstack_1grow (&util_obstack
, 'Q');
6842 /* Signed integer types. */
6844 if (TYPE_MODE (type
) == QImode
)
6845 obstack_1grow (&util_obstack
, 'c');
6846 else if (TYPE_MODE (type
) == HImode
)
6847 obstack_1grow (&util_obstack
, 's');
6848 else if (TYPE_MODE (type
) == SImode
)
6850 if (type
== long_integer_type_node
)
6851 obstack_1grow (&util_obstack
, 'l');
6853 obstack_1grow (&util_obstack
, 'i');
6856 else if (TYPE_MODE (type
) == DImode
)
6857 obstack_1grow (&util_obstack
, 'q');
6861 else if (code
== REAL_TYPE
)
6863 /* Floating point types. */
6865 if (TYPE_MODE (type
) == SFmode
)
6866 obstack_1grow (&util_obstack
, 'f');
6867 else if (TYPE_MODE (type
) == DFmode
6868 || TYPE_MODE (type
) == TFmode
)
6869 obstack_1grow (&util_obstack
, 'd');
6872 else if (code
== VOID_TYPE
)
6873 obstack_1grow (&util_obstack
, 'v');
6875 else if (code
== ARRAY_TYPE
)
6876 encode_array (type
, curtype
, format
);
6878 else if (code
== POINTER_TYPE
)
6879 encode_pointer (type
, curtype
, format
);
6881 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6882 encode_aggregate (type
, curtype
, format
);
6884 else if (code
== FUNCTION_TYPE
) /* '?' */
6885 obstack_1grow (&util_obstack
, '?');
6889 encode_complete_bitfield (position
, type
, size
)
6894 enum tree_code code
= TREE_CODE (type
);
6896 char charType
= '?';
6898 if (code
== INTEGER_TYPE
)
6900 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6902 /* Unsigned integer types. */
6904 if (TYPE_MODE (type
) == QImode
)
6906 else if (TYPE_MODE (type
) == HImode
)
6908 else if (TYPE_MODE (type
) == SImode
)
6910 if (type
== long_unsigned_type_node
)
6915 else if (TYPE_MODE (type
) == DImode
)
6920 /* Signed integer types. */
6922 if (TYPE_MODE (type
) == QImode
)
6924 else if (TYPE_MODE (type
) == HImode
)
6926 else if (TYPE_MODE (type
) == SImode
)
6928 if (type
== long_integer_type_node
)
6934 else if (TYPE_MODE (type
) == DImode
)
6938 else if (code
== ENUMERAL_TYPE
)
6943 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6944 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6948 encode_field_decl (field_decl
, curtype
, format
)
6955 type
= TREE_TYPE (field_decl
);
6957 /* If this field is obviously a bitfield, or is a bitfield that has been
6958 clobbered to look like a ordinary integer mode, go ahead and generate
6959 the bitfield typing information. */
6960 if (flag_next_runtime
)
6962 if (DECL_BIT_FIELD_TYPE (field_decl
))
6963 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6965 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6969 if (DECL_BIT_FIELD_TYPE (field_decl
))
6970 encode_complete_bitfield (int_bit_position (field_decl
),
6971 DECL_BIT_FIELD_TYPE (field_decl
),
6972 tree_low_cst (DECL_SIZE (field_decl
), 1));
6974 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6979 expr_last (complex_expr
)
6985 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6986 complex_expr
= next
;
6988 return complex_expr
;
6991 /* Transform a method definition into a function definition as follows:
6992 - synthesize the first two arguments, "self" and "_cmd". */
6995 start_method_def (method
)
7000 /* Required to implement _msgSuper. */
7001 objc_method_context
= method
;
7002 UOBJC_SUPER_decl
= NULL_TREE
;
7004 /* Must be called BEFORE start_function. */
7007 /* Generate prototype declarations for arguments..."new-style". */
7009 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
7010 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
7012 /* Really a `struct objc_class *'. However, we allow people to
7013 assign to self, which changes its type midstream. */
7014 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
7016 push_parm_decl (build_tree_list
7017 (build_tree_list (decl_specs
,
7018 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
7021 decl_specs
= build_tree_list (NULL_TREE
,
7022 xref_tag (RECORD_TYPE
,
7023 get_identifier (TAG_SELECTOR
)));
7024 push_parm_decl (build_tree_list
7025 (build_tree_list (decl_specs
,
7026 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
7029 /* Generate argument declarations if a keyword_decl. */
7030 if (METHOD_SEL_ARGS (method
))
7032 tree arglist
= METHOD_SEL_ARGS (method
);
7035 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
7036 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
7040 tree last_expr
= expr_last (arg_decl
);
7042 /* Unite the abstract decl with its name. */
7043 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
7044 push_parm_decl (build_tree_list
7045 (build_tree_list (arg_spec
, arg_decl
),
7048 /* Unhook: restore the abstract declarator. */
7049 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
7053 push_parm_decl (build_tree_list
7054 (build_tree_list (arg_spec
,
7055 KEYWORD_ARG_NAME (arglist
)),
7058 arglist
= TREE_CHAIN (arglist
);
7063 if (METHOD_ADD_ARGS (method
) != NULL_TREE
7064 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
7066 /* We have a variable length selector - in "prototype" format. */
7067 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7070 /* This must be done prior to calling pushdecl. pushdecl is
7071 going to change our chain on us. */
7072 tree nextkey
= TREE_CHAIN (akey
);
7080 warn_with_method (message
, mtype
, method
)
7081 const char *message
;
7085 if (!diagnostic_count_diagnostic (global_dc
, DK_WARNING
))
7088 diagnostic_report_current_function (global_dc
);
7090 /* Add a readable method name to the warning. */
7091 warning_with_file_and_line (DECL_SOURCE_FILE (method
),
7092 DECL_SOURCE_LINE (method
),
7095 gen_method_decl (method
, errbuf
));
7098 /* Return 1 if METHOD is consistent with PROTO. */
7101 comp_method_with_proto (method
, proto
)
7104 /* Create a function template node at most once. */
7105 if (!function1_template
)
7106 function1_template
= make_node (FUNCTION_TYPE
);
7108 /* Install argument types - normally set by build_function_type. */
7109 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7111 /* install return type */
7112 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto
));
7114 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function1_template
);
7117 /* Return 1 if PROTO1 is consistent with PROTO2. */
7120 comp_proto_with_proto (proto0
, proto1
)
7121 tree proto0
, proto1
;
7123 /* Create a couple of function_template nodes at most once. */
7124 if (!function1_template
)
7125 function1_template
= make_node (FUNCTION_TYPE
);
7126 if (!function2_template
)
7127 function2_template
= make_node (FUNCTION_TYPE
);
7129 /* Install argument types; normally set by build_function_type. */
7130 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto0
, METHOD_REF
, 0);
7131 TYPE_ARG_TYPES (function2_template
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7133 /* Install return type. */
7134 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto0
));
7135 TREE_TYPE (function2_template
) = groktypename (TREE_TYPE (proto1
));
7137 return comptypes (function1_template
, function2_template
);
7140 /* - Generate an identifier for the function. the format is "_n_cls",
7141 where 1 <= n <= nMethods, and cls is the name the implementation we
7143 - Install the return type from the method declaration.
7144 - If we have a prototype, check for type consistency. */
7147 really_start_method (method
, parmlist
)
7148 tree method
, parmlist
;
7150 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7151 tree method_decl
, method_id
;
7152 const char *sel_name
, *class_name
, *cat_name
;
7155 /* Synth the storage class & assemble the return type. */
7156 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7157 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7158 decl_specs
= chainon (sc_spec
, ret_spec
);
7160 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7161 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
7162 cat_name
= ((TREE_CODE (objc_implementation_context
)
7163 == CLASS_IMPLEMENTATION_TYPE
)
7165 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7168 /* Make sure this is big enough for any plausible method label. */
7169 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7170 + (cat_name
? strlen (cat_name
) : 0));
7172 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7173 class_name
, cat_name
, sel_name
, method_slot
);
7175 method_id
= get_identifier (buf
);
7177 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7179 /* Check the declarator portion of the return type for the method. */
7180 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7182 /* Unite the complex decl (specified in the abstract decl) with the
7183 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7184 tree save_expr
= expr_last (ret_decl
);
7186 TREE_OPERAND (save_expr
, 0) = method_decl
;
7187 method_decl
= ret_decl
;
7189 /* Fool the parser into thinking it is starting a function. */
7190 start_function (decl_specs
, method_decl
, NULL_TREE
);
7192 /* Unhook: this has the effect of restoring the abstract declarator. */
7193 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7198 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7200 /* Fool the parser into thinking it is starting a function. */
7201 start_function (decl_specs
, method_decl
, NULL_TREE
);
7203 /* Unhook: this has the effect of restoring the abstract declarator. */
7204 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7207 METHOD_DEFINITION (method
) = current_function_decl
;
7209 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7211 if (implementation_template
!= objc_implementation_context
)
7215 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7216 proto
= lookup_instance_method_static (implementation_template
,
7217 METHOD_SEL_NAME (method
));
7219 proto
= lookup_class_method_static (implementation_template
,
7220 METHOD_SEL_NAME (method
));
7222 if (proto
&& ! comp_method_with_proto (method
, proto
))
7224 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7226 warn_with_method ("conflicting types for", type
, method
);
7227 warn_with_method ("previous declaration of", type
, proto
);
7232 /* The following routine is always called...this "architecture" is to
7233 accommodate "old-style" variable length selectors.
7235 - a:a b:b // prototype ; id c; id d; // old-style. */
7238 continue_method_def ()
7242 if (METHOD_ADD_ARGS (objc_method_context
) == objc_ellipsis_node
)
7243 /* We have a `, ...' immediately following the selector. */
7244 parmlist
= get_parm_info (0);
7246 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7248 /* Set self_decl from the first argument...this global is used by
7249 build_ivar_reference calling build_indirect_ref. */
7250 self_decl
= TREE_PURPOSE (parmlist
);
7253 really_start_method (objc_method_context
, parmlist
);
7254 store_parm_decls ();
7257 /* Called by the parser, from the `pushlevel' production. */
7262 if (!UOBJC_SUPER_decl
)
7264 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7265 build_tree_list (NULL_TREE
,
7266 objc_super_template
),
7269 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7271 /* This prevents `unused variable' warnings when compiling with -Wall. */
7272 TREE_USED (UOBJC_SUPER_decl
) = 1;
7273 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7277 /* _n_Method (id self, SEL sel, ...)
7279 struct objc_super _S;
7280 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7284 get_super_receiver ()
7286 if (objc_method_context
)
7288 tree super_expr
, super_expr_list
;
7290 /* Set receiver to self. */
7291 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7292 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7293 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7295 /* Set class to begin searching. */
7296 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7297 get_identifier ("class"));
7299 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7301 /* [_cls, __cls]Super are "pre-built" in
7302 synth_forward_declarations. */
7304 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7305 ((TREE_CODE (objc_method_context
)
7306 == INSTANCE_METHOD_DECL
)
7308 : uucls_super_ref
));
7312 /* We have a category. */
7314 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7317 /* Barf if super used in a category of Object. */
7320 error ("no super class declared in interface for `%s'",
7321 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7322 return error_mark_node
;
7325 if (flag_next_runtime
)
7327 super_class
= get_class_reference (super_name
);
7328 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7329 /* Cast the super class to 'id', since the user may not have
7330 included <objc/objc-class.h>, leaving 'struct objc_class'
7331 an incomplete type. */
7333 = build_component_ref (build_indirect_ref
7334 (build_c_cast (id_type
, super_class
), "->"),
7335 get_identifier ("isa"));
7339 add_class_reference (super_name
);
7340 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7341 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7342 assemble_external (super_class
);
7344 = build_function_call
7348 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7349 IDENTIFIER_POINTER (super_name
))));
7352 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7353 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7356 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7358 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7359 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7361 return build_compound_expr (super_expr_list
);
7365 error ("[super ...] must appear in a method context");
7366 return error_mark_node
;
7371 encode_method_def (func_decl
)
7376 HOST_WIDE_INT max_parm_end
= 0;
7381 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7382 obstack_object_size (&util_obstack
),
7383 OBJC_ENCODE_INLINE_DEFS
);
7386 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7387 parms
= TREE_CHAIN (parms
))
7389 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7390 + int_size_in_bytes (TREE_TYPE (parms
)));
7392 if (! offset_is_register
&& parm_end
> max_parm_end
)
7393 max_parm_end
= parm_end
;
7396 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7398 sprintf (buffer
, "%d", stack_size
);
7399 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7401 /* Argument types. */
7402 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7403 parms
= TREE_CHAIN (parms
))
7406 encode_type (TREE_TYPE (parms
),
7407 obstack_object_size (&util_obstack
),
7408 OBJC_ENCODE_INLINE_DEFS
);
7410 /* Compute offset. */
7411 sprintf (buffer
, "%d", forwarding_offset (parms
));
7413 /* Indicate register. */
7414 if (offset_is_register
)
7415 obstack_1grow (&util_obstack
, '+');
7417 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7420 /* Null terminate string. */
7421 obstack_1grow (&util_obstack
, 0);
7422 result
= get_identifier (obstack_finish (&util_obstack
));
7423 obstack_free (&util_obstack
, util_firstobj
);
7428 objc_expand_function_end ()
7430 METHOD_ENCODING (objc_method_context
) = encode_method_def (current_function_decl
);
7434 finish_method_def ()
7436 lang_expand_function_end
= objc_expand_function_end
;
7437 finish_function (0, 1);
7438 lang_expand_function_end
= NULL
;
7440 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7441 since the optimizer may find "may be used before set" errors. */
7442 objc_method_context
= NULL_TREE
;
7447 lang_report_error_function (decl
)
7450 if (objc_method_context
)
7452 fprintf (stderr
, "In method `%s'\n",
7453 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7463 is_complex_decl (type
)
7466 return (TREE_CODE (type
) == ARRAY_TYPE
7467 || TREE_CODE (type
) == FUNCTION_TYPE
7468 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7472 /* Code to convert a decl node into text for a declaration in C. */
7474 static char tmpbuf
[256];
7477 adorn_decl (decl
, str
)
7481 enum tree_code code
= TREE_CODE (decl
);
7483 if (code
== ARRAY_REF
)
7485 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7487 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7488 sprintf (str
+ strlen (str
), "[%ld]",
7489 (long) TREE_INT_CST_LOW (an_int_cst
));
7494 else if (code
== ARRAY_TYPE
)
7496 tree an_int_cst
= TYPE_SIZE (decl
);
7497 tree array_of
= TREE_TYPE (decl
);
7499 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7500 sprintf (str
+ strlen (str
), "[%ld]",
7501 (long) (TREE_INT_CST_LOW (an_int_cst
)
7502 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7507 else if (code
== CALL_EXPR
)
7509 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7514 gen_declaration_1 (chain
, str
);
7515 chain
= TREE_CHAIN (chain
);
7522 else if (code
== FUNCTION_TYPE
)
7524 tree chain
= TYPE_ARG_TYPES (decl
);
7527 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7529 gen_declaration_1 (TREE_VALUE (chain
), str
);
7530 chain
= TREE_CHAIN (chain
);
7531 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7537 else if (code
== INDIRECT_REF
)
7539 strcpy (tmpbuf
, "*");
7540 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7544 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7546 chain
= TREE_CHAIN (chain
))
7548 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7550 strcat (tmpbuf
, " ");
7551 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7555 strcat (tmpbuf
, " ");
7557 strcat (tmpbuf
, str
);
7558 strcpy (str
, tmpbuf
);
7561 else if (code
== POINTER_TYPE
)
7563 strcpy (tmpbuf
, "*");
7564 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7566 if (TREE_READONLY (decl
))
7567 strcat (tmpbuf
, " const");
7568 if (TYPE_VOLATILE (decl
))
7569 strcat (tmpbuf
, " volatile");
7571 strcat (tmpbuf
, " ");
7573 strcat (tmpbuf
, str
);
7574 strcpy (str
, tmpbuf
);
7579 gen_declarator (decl
, buf
, name
)
7586 enum tree_code code
= TREE_CODE (decl
);
7596 op
= TREE_OPERAND (decl
, 0);
7598 /* We have a pointer to a function or array...(*)(), (*)[] */
7599 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7600 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7603 str
= gen_declarator (op
, buf
, name
);
7607 strcpy (tmpbuf
, "(");
7608 strcat (tmpbuf
, str
);
7609 strcat (tmpbuf
, ")");
7610 strcpy (str
, tmpbuf
);
7613 adorn_decl (decl
, str
);
7622 /* This clause is done iteratively rather than recursively. */
7625 op
= (is_complex_decl (TREE_TYPE (decl
))
7626 ? TREE_TYPE (decl
) : NULL_TREE
);
7628 adorn_decl (decl
, str
);
7630 /* We have a pointer to a function or array...(*)(), (*)[] */
7631 if (code
== POINTER_TYPE
7632 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7633 || TREE_CODE (op
) == ARRAY_TYPE
))
7635 strcpy (tmpbuf
, "(");
7636 strcat (tmpbuf
, str
);
7637 strcat (tmpbuf
, ")");
7638 strcpy (str
, tmpbuf
);
7641 decl
= (is_complex_decl (TREE_TYPE (decl
))
7642 ? TREE_TYPE (decl
) : NULL_TREE
);
7645 while (decl
&& (code
= TREE_CODE (decl
)))
7650 case IDENTIFIER_NODE
:
7651 /* Will only happen if we are processing a "raw" expr-decl. */
7652 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7663 /* We have an abstract declarator or a _DECL node. */
7671 gen_declspecs (declspecs
, buf
, raw
)
7680 for (chain
= nreverse (copy_list (declspecs
));
7681 chain
; chain
= TREE_CHAIN (chain
))
7683 tree aspec
= TREE_VALUE (chain
);
7685 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7686 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7687 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7689 if (TYPE_NAME (aspec
))
7691 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7693 if (! TREE_STATIC_TEMPLATE (aspec
))
7694 strcat (buf
, "struct ");
7695 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7700 tree chain
= protocol_list
;
7707 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7708 chain
= TREE_CHAIN (chain
);
7717 strcat (buf
, "untagged struct");
7720 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7722 if (TYPE_NAME (aspec
))
7724 if (! TREE_STATIC_TEMPLATE (aspec
))
7725 strcat (buf
, "union ");
7726 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7729 strcat (buf
, "untagged union");
7732 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7734 if (TYPE_NAME (aspec
))
7736 if (! TREE_STATIC_TEMPLATE (aspec
))
7737 strcat (buf
, "enum ");
7738 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7741 strcat (buf
, "untagged enum");
7744 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7745 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7747 else if (IS_ID (aspec
))
7749 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7754 tree chain
= protocol_list
;
7761 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7762 chain
= TREE_CHAIN (chain
);
7769 if (TREE_CHAIN (chain
))
7775 /* Type qualifiers. */
7776 if (TREE_READONLY (declspecs
))
7777 strcat (buf
, "const ");
7778 if (TYPE_VOLATILE (declspecs
))
7779 strcat (buf
, "volatile ");
7781 switch (TREE_CODE (declspecs
))
7783 /* Type specifiers. */
7786 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7788 /* Signed integer types. */
7790 if (declspecs
== short_integer_type_node
)
7791 strcat (buf
, "short int ");
7792 else if (declspecs
== integer_type_node
)
7793 strcat (buf
, "int ");
7794 else if (declspecs
== long_integer_type_node
)
7795 strcat (buf
, "long int ");
7796 else if (declspecs
== long_long_integer_type_node
)
7797 strcat (buf
, "long long int ");
7798 else if (declspecs
== signed_char_type_node
7799 || declspecs
== char_type_node
)
7800 strcat (buf
, "char ");
7802 /* Unsigned integer types. */
7804 else if (declspecs
== short_unsigned_type_node
)
7805 strcat (buf
, "unsigned short ");
7806 else if (declspecs
== unsigned_type_node
)
7807 strcat (buf
, "unsigned int ");
7808 else if (declspecs
== long_unsigned_type_node
)
7809 strcat (buf
, "unsigned long ");
7810 else if (declspecs
== long_long_unsigned_type_node
)
7811 strcat (buf
, "unsigned long long ");
7812 else if (declspecs
== unsigned_char_type_node
)
7813 strcat (buf
, "unsigned char ");
7817 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7819 if (declspecs
== float_type_node
)
7820 strcat (buf
, "float ");
7821 else if (declspecs
== double_type_node
)
7822 strcat (buf
, "double ");
7823 else if (declspecs
== long_double_type_node
)
7824 strcat (buf
, "long double ");
7828 if (TYPE_NAME (declspecs
)
7829 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7831 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7833 if (! TREE_STATIC_TEMPLATE (declspecs
))
7834 strcat (buf
, "struct ");
7835 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7839 tree chain
= protocol_list
;
7846 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7847 chain
= TREE_CHAIN (chain
);
7856 strcat (buf
, "untagged struct");
7862 if (TYPE_NAME (declspecs
)
7863 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7865 strcat (buf
, "union ");
7866 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7871 strcat (buf
, "untagged union ");
7875 if (TYPE_NAME (declspecs
)
7876 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7878 strcat (buf
, "enum ");
7879 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7884 strcat (buf
, "untagged enum ");
7888 strcat (buf
, "void ");
7893 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7898 tree chain
= protocol_list
;
7905 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7906 chain
= TREE_CHAIN (chain
);
7922 /* Given a tree node, produce a printable description of it in the given
7923 buffer, overwriting the buffer. */
7926 gen_declaration (atype_or_adecl
, buf
)
7927 tree atype_or_adecl
;
7931 gen_declaration_1 (atype_or_adecl
, buf
);
7935 /* Given a tree node, append a printable description to the end of the
7939 gen_declaration_1 (atype_or_adecl
, buf
)
7940 tree atype_or_adecl
;
7945 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7947 tree declspecs
; /* "identifier_node", "record_type" */
7948 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7950 /* We have a "raw", abstract declarator (typename). */
7951 declarator
= TREE_VALUE (atype_or_adecl
);
7952 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7954 gen_declspecs (declspecs
, buf
, 1);
7958 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7965 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7966 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7968 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7969 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7970 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7971 atype
= TREE_TYPE (atype_or_adecl
);
7973 /* Assume we have a *_type node. */
7974 atype
= atype_or_adecl
;
7976 if (is_complex_decl (atype
))
7980 /* Get the declaration specifier; it is at the end of the list. */
7981 declarator
= chain
= atype
;
7983 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7984 while (is_complex_decl (chain
));
7991 declarator
= NULL_TREE
;
7994 gen_declspecs (declspecs
, buf
, 0);
7996 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7997 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7998 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
8000 const char *const decl_name
=
8001 (DECL_NAME (atype_or_adecl
)
8002 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
8007 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
8010 else if (decl_name
[0])
8013 strcat (buf
, decl_name
);
8016 else if (declarator
)
8019 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
8024 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8026 /* Given a method tree, put a printable description into the given
8027 buffer (overwriting) and return a pointer to the buffer. */
8030 gen_method_decl (method
, buf
)
8037 if (RAW_TYPESPEC (method
) != objc_object_reference
)
8040 gen_declaration_1 (TREE_TYPE (method
), buf
);
8044 chain
= METHOD_SEL_ARGS (method
);
8047 /* We have a chain of keyword_decls. */
8050 if (KEYWORD_KEY_NAME (chain
))
8051 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
8054 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
8057 gen_declaration_1 (TREE_TYPE (chain
), buf
);
8061 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
8062 if ((chain
= TREE_CHAIN (chain
)))
8067 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
8068 strcat (buf
, ", ...");
8069 else if (METHOD_ADD_ARGS (method
))
8071 /* We have a tree list node as generate by get_parm_info. */
8072 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
8074 /* Know we have a chain of parm_decls. */
8078 gen_declaration_1 (chain
, buf
);
8079 chain
= TREE_CHAIN (chain
);
8085 /* We have a unary selector. */
8086 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8094 /* Dump an @interface declaration of the supplied class CHAIN to the
8095 supplied file FP. Used to implement the -gen-decls option (which
8096 prints out an @interface declaration of all classes compiled in
8097 this run); potentially useful for debugging the compiler too. */
8099 dump_interface (fp
, chain
)
8103 /* FIXME: A heap overflow here whenever a method (or ivar)
8104 declaration is so long that it doesn't fit in the buffer. The
8105 code and all the related functions should be rewritten to avoid
8106 using fixed size buffers. */
8107 char *buf
= (char *) xmalloc (1024 * 10);
8108 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8109 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8110 tree nst_methods
= CLASS_NST_METHODS (chain
);
8111 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8113 fprintf (fp
, "\n@interface %s", my_name
);
8115 /* CLASS_SUPER_NAME is used to store the superclass name for
8116 classes, and the category name for categories. */
8117 if (CLASS_SUPER_NAME (chain
))
8119 const char *name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8121 if (TREE_CODE (chain
) == CATEGORY_IMPLEMENTATION_TYPE
8122 || TREE_CODE (chain
) == CATEGORY_INTERFACE_TYPE
)
8124 fprintf (fp
, " (%s)\n", name
);
8128 fprintf (fp
, " : %s\n", name
);
8134 /* FIXME - the following doesn't seem to work at the moment. */
8137 fprintf (fp
, "{\n");
8140 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8141 ivar_decls
= TREE_CHAIN (ivar_decls
);
8144 fprintf (fp
, "}\n");
8149 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8150 nst_methods
= TREE_CHAIN (nst_methods
);
8155 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8156 cls_methods
= TREE_CHAIN (cls_methods
);
8159 fprintf (fp
, "@end\n");
8162 /* Demangle function for Objective-C */
8164 objc_demangle (mangled
)
8165 const char *mangled
;
8167 char *demangled
, *cp
;
8169 if (mangled
[0] == '_' &&
8170 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8173 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8174 if (mangled
[1] == 'i')
8175 *cp
++ = '-'; /* for instance method */
8177 *cp
++ = '+'; /* for class method */
8178 *cp
++ = '['; /* opening left brace */
8179 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8180 while (*cp
&& *cp
== '_')
8181 cp
++; /* skip any initial underbars in class name */
8182 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8185 free(demangled
); /* not mangled name */
8188 if (cp
[1] == '_') /* easy case: no category name */
8190 *cp
++ = ' '; /* replace two '_' with one ' ' */
8191 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8195 *cp
++ = '('; /* less easy case: category name */
8196 cp
= strchr(cp
, '_');
8199 free(demangled
); /* not mangled name */
8203 *cp
++ = ' '; /* overwriting 1st char of method name... */
8204 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8206 while (*cp
&& *cp
== '_')
8207 cp
++; /* skip any initial underbars in method name */
8210 *cp
= ':'; /* replace remaining '_' with ':' */
8211 *cp
++ = ']'; /* closing right brace */
8212 *cp
++ = 0; /* string terminator */
8216 return mangled
; /* not an objc mangled name */
8220 objc_printable_name (decl
, kind
)
8222 int kind ATTRIBUTE_UNUSED
;
8224 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8230 gcc_obstack_init (&util_obstack
);
8231 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8233 errbuf
= (char *) xmalloc (BUFSIZE
);
8235 synth_module_prologue ();
8241 struct imp_entry
*impent
;
8243 /* The internally generated initializers appear to have missing braces.
8244 Don't warn about this. */
8245 int save_warn_missing_braces
= warn_missing_braces
;
8246 warn_missing_braces
= 0;
8248 /* A missing @end may not be detected by the parser. */
8249 if (objc_implementation_context
)
8251 warning ("`@end' missing in implementation context");
8252 finish_class (objc_implementation_context
);
8253 objc_ivar_chain
= NULL_TREE
;
8254 objc_implementation_context
= NULL_TREE
;
8257 generate_forward_declaration_to_string_table ();
8259 #ifdef OBJC_PROLOGUE
8263 /* Process the static instances here because initialization of objc_symtab
8265 if (objc_static_instances
)
8266 generate_static_references ();
8268 if (imp_list
|| class_names_chain
8269 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8270 generate_objc_symtab_decl ();
8272 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8274 objc_implementation_context
= impent
->imp_context
;
8275 implementation_template
= impent
->imp_template
;
8277 UOBJC_CLASS_decl
= impent
->class_decl
;
8278 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8280 /* Dump the @interface of each class as we compile it, if the
8281 -gen-decls option is in use. TODO: Dump the classes in the
8282 order they were found, rather than in reverse order as we
8284 if (flag_gen_declaration
)
8286 dump_interface (gen_declaration_file
, objc_implementation_context
);
8289 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8291 /* all of the following reference the string pool... */
8292 generate_ivar_lists ();
8293 generate_dispatch_tables ();
8294 generate_shared_structures ();
8298 generate_dispatch_tables ();
8299 generate_category (objc_implementation_context
);
8303 /* If we are using an array of selectors, we must always
8304 finish up the array decl even if no selectors were used. */
8305 if (! flag_next_runtime
|| sel_ref_chain
)
8306 build_selector_translation_table ();
8309 generate_protocols ();
8311 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8312 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8314 /* Arrange for ObjC data structures to be initialized at run time. */
8315 rtx init_sym
= build_module_descriptor ();
8316 if (init_sym
&& targetm
.have_ctors_dtors
)
8317 (* targetm
.asm_out
.constructor
) (init_sym
, DEFAULT_INIT_PRIORITY
);
8320 /* Dump the class references. This forces the appropriate classes
8321 to be linked into the executable image, preserving unix archive
8322 semantics. This can be removed when we move to a more dynamically
8323 linked environment. */
8325 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8327 handle_class_ref (chain
);
8328 if (TREE_PURPOSE (chain
))
8329 generate_classref_translation_entry (chain
);
8332 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8333 handle_impent (impent
);
8335 /* Dump the string table last. */
8337 generate_strings ();
8344 /* Run through the selector hash tables and print a warning for any
8345 selector which has multiple methods. */
8347 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8348 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8351 tree meth
= hsh
->key
;
8352 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8356 warning ("potential selector conflict for method `%s'",
8357 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8358 warn_with_method ("found", type
, meth
);
8359 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8360 warn_with_method ("found", type
, loop
->value
);
8363 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8364 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8367 tree meth
= hsh
->key
;
8368 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8372 warning ("potential selector conflict for method `%s'",
8373 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8374 warn_with_method ("found", type
, meth
);
8375 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8376 warn_with_method ("found", type
, loop
->value
);
8380 warn_missing_braces
= save_warn_missing_braces
;
8383 /* Subroutines of finish_objc. */
8386 generate_classref_translation_entry (chain
)
8389 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8392 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8394 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8395 expr
= build_c_cast (type
, expr
); /* cast! */
8397 name
= DECL_NAME (TREE_PURPOSE (chain
));
8399 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8401 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8402 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8404 /* The decl that is returned from start_decl is the one that we
8405 forward declared in build_class_reference. */
8406 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
);
8407 DECL_CONTEXT (decl
) = NULL_TREE
;
8408 finish_decl (decl
, expr
, NULL_TREE
);
8413 handle_class_ref (chain
)
8416 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8417 char *string
= (char *) alloca (strlen (name
) + 30);
8421 sprintf (string
, "%sobjc_class_name_%s",
8422 (flag_next_runtime
? "." : "__"), name
);
8424 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8425 if (flag_next_runtime
)
8427 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8432 /* Make a decl for this name, so we can use its address in a tree. */
8433 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8434 DECL_EXTERNAL (decl
) = 1;
8435 TREE_PUBLIC (decl
) = 1;
8438 rest_of_decl_compilation (decl
, 0, 0, 0);
8440 /* Make a decl for the address. */
8441 sprintf (string
, "%sobjc_class_ref_%s",
8442 (flag_next_runtime
? "." : "__"), name
);
8443 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8444 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8445 DECL_INITIAL (decl
) = exp
;
8446 TREE_STATIC (decl
) = 1;
8447 TREE_USED (decl
) = 1;
8450 rest_of_decl_compilation (decl
, 0, 0, 0);
8454 handle_impent (impent
)
8455 struct imp_entry
*impent
;
8459 objc_implementation_context
= impent
->imp_context
;
8460 implementation_template
= impent
->imp_template
;
8462 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8464 const char *const class_name
=
8465 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8467 string
= (char *) alloca (strlen (class_name
) + 30);
8469 sprintf (string
, "%sobjc_class_name_%s",
8470 (flag_next_runtime
? "." : "__"), class_name
);
8472 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8474 const char *const class_name
=
8475 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8476 const char *const class_super_name
=
8477 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8479 string
= (char *) alloca (strlen (class_name
)
8480 + strlen (class_super_name
) + 30);
8482 /* Do the same for categories. Even though no references to
8483 these symbols are generated automatically by the compiler, it
8484 gives you a handle to pull them into an archive by hand. */
8485 sprintf (string
, "*%sobjc_category_name_%s_%s",
8486 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8491 #ifdef ASM_DECLARE_CLASS_REFERENCE
8492 if (flag_next_runtime
)
8494 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8502 init
= build_int_2 (0, 0);
8503 TREE_TYPE (init
) = c_common_type_for_size (BITS_PER_WORD
, 1);
8504 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
8505 TREE_PUBLIC (decl
) = 1;
8506 TREE_READONLY (decl
) = 1;
8507 TREE_USED (decl
) = 1;
8508 TREE_CONSTANT (decl
) = 1;
8509 DECL_CONTEXT (decl
) = 0;
8510 DECL_ARTIFICIAL (decl
) = 1;
8511 DECL_INITIAL (decl
) = init
;
8512 assemble_variable (decl
, 1, 0, 0);
8516 /* Look up ID as an instance variable. */
8518 lookup_objc_ivar (id
)
8523 if (objc_method_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8524 /* We have a message to super. */
8525 return get_super_receiver ();
8526 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8528 if (is_private (decl
))
8529 return error_mark_node
;
8531 return build_ivar_reference (id
);
8537 #include "gtype-objc.h"