1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
62 #include "diagnostic.h"
65 /* This is the default way of generating a method name. */
66 /* I am not sure it is really correct.
67 Perhaps there's a danger that it will make name conflicts
68 if method names contain underscores. -- rms. */
69 #ifndef OBJC_GEN_METHOD_LABEL
70 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
73 sprintf ((BUF), "_%s_%s_%s_%s", \
74 ((IS_INST) ? "i" : "c"), \
76 ((CAT_NAME)? (CAT_NAME) : ""), \
78 for (temp = (BUF); *temp; temp++) \
79 if (*temp == ':') *temp = '_'; \
83 /* These need specifying. */
84 #ifndef OBJC_FORWARDING_STACK_OFFSET
85 #define OBJC_FORWARDING_STACK_OFFSET 0
88 #ifndef OBJC_FORWARDING_MIN_OFFSET
89 #define OBJC_FORWARDING_MIN_OFFSET 0
93 /* Set up for use of obstacks. */
97 /* This obstack is used to accumulate the encoding of a data type. */
98 static struct obstack util_obstack
;
99 /* This points to the beginning of obstack contents,
100 so we can free the whole contents. */
103 /* for encode_method_def */
106 /* The version identifies which language generation and runtime
107 the module (file) was compiled for, and is recorded in the
108 module descriptor. */
110 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
111 #define PROTOCOL_VERSION 2
113 /* (Decide if these can ever be validly changed.) */
114 #define OBJC_ENCODE_INLINE_DEFS 0
115 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
117 /*** Private Interface (procedures) ***/
119 /* Used by compile_file. */
121 static void init_objc
PARAMS ((void));
122 static void finish_objc
PARAMS ((void));
124 /* Code generation. */
126 static void synth_module_prologue
PARAMS ((void));
127 static tree objc_build_constructor
PARAMS ((tree
, tree
));
128 static rtx build_module_descriptor
PARAMS ((void));
129 static tree init_module_descriptor
PARAMS ((tree
));
130 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
132 static void generate_strings
PARAMS ((void));
133 static tree get_proto_encoding
PARAMS ((tree
));
134 static void build_selector_translation_table
PARAMS ((void));
136 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
138 static tree build_ivar_template
PARAMS ((void));
139 static tree build_method_template
PARAMS ((void));
140 static tree build_private_template
PARAMS ((tree
));
141 static void build_class_template
PARAMS ((void));
142 static void build_selector_template
PARAMS ((void));
143 static void build_category_template
PARAMS ((void));
144 static tree build_super_template
PARAMS ((void));
145 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
147 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
150 static void synth_forward_declarations
PARAMS ((void));
151 static void generate_ivar_lists
PARAMS ((void));
152 static void generate_dispatch_tables
PARAMS ((void));
153 static void generate_shared_structures
PARAMS ((void));
154 static tree generate_protocol_list
PARAMS ((tree
));
155 static void generate_forward_declaration_to_string_table
PARAMS ((void));
156 static void build_protocol_reference
PARAMS ((tree
));
158 static tree build_keyword_selector
PARAMS ((tree
));
159 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
161 static void generate_static_references
PARAMS ((void));
162 static int check_methods_accessible
PARAMS ((tree
, tree
,
164 static void encode_aggregate_within
PARAMS ((tree
, int, int,
166 static const char *objc_demangle
PARAMS ((const char *));
167 static void objc_expand_function_end
PARAMS ((void));
169 /* Hash tables to manage the global pool of method prototypes. */
171 hash
*nst_method_hash_list
= 0;
172 hash
*cls_method_hash_list
= 0;
174 static size_t hash_func
PARAMS ((tree
));
175 static void hash_init
PARAMS ((void));
176 static void hash_enter
PARAMS ((hash
*, tree
));
177 static hash hash_lookup
PARAMS ((hash
*, tree
));
178 static void hash_add_attr
PARAMS ((hash
, tree
));
179 static tree lookup_method
PARAMS ((tree
, tree
));
180 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
181 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
182 static tree add_class
PARAMS ((tree
));
183 static void add_category
PARAMS ((tree
, tree
));
187 class_names
, /* class, category, protocol, module names */
188 meth_var_names
, /* method and variable names */
189 meth_var_types
/* method and variable type descriptors */
192 static tree add_objc_string
PARAMS ((tree
,
193 enum string_section
));
194 static tree get_objc_string_decl
PARAMS ((tree
,
195 enum string_section
));
196 static tree build_objc_string_decl
PARAMS ((enum string_section
));
197 static tree build_selector_reference_decl
PARAMS ((void));
199 /* Protocol additions. */
201 static tree add_protocol
PARAMS ((tree
));
202 static tree lookup_protocol
PARAMS ((tree
));
203 static void check_protocol_recursively
PARAMS ((tree
, tree
));
204 static tree lookup_and_install_protocols
PARAMS ((tree
));
208 static void encode_type_qualifiers
PARAMS ((tree
));
209 static void encode_pointer
PARAMS ((tree
, int, int));
210 static void encode_array
PARAMS ((tree
, int, int));
211 static void encode_aggregate
PARAMS ((tree
, int, int));
212 static void encode_bitfield
PARAMS ((int));
213 static void encode_type
PARAMS ((tree
, int, int));
214 static void encode_field_decl
PARAMS ((tree
, int, int));
216 static void really_start_method
PARAMS ((tree
, tree
));
217 static int comp_method_with_proto
PARAMS ((tree
, tree
));
218 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
219 static tree get_arg_type_list
PARAMS ((tree
, int, int));
220 static tree objc_expr_last
PARAMS ((tree
));
222 /* Utilities for debugging and error diagnostics. */
224 static void warn_with_method
PARAMS ((const char *, int, tree
));
225 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
226 static char *gen_method_decl
PARAMS ((tree
, char *));
227 static char *gen_declaration
PARAMS ((tree
, char *));
228 static void gen_declaration_1
PARAMS ((tree
, char *));
229 static char *gen_declarator
PARAMS ((tree
, char *,
231 static int is_complex_decl
PARAMS ((tree
));
232 static void adorn_decl
PARAMS ((tree
, char *));
233 static void dump_interface
PARAMS ((FILE *, tree
));
235 /* Everything else. */
237 static tree define_decl
PARAMS ((tree
, tree
));
238 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
239 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
240 static tree create_builtin_decl
PARAMS ((enum tree_code
,
241 tree
, const char *));
242 static void setup_string_decl
PARAMS ((void));
243 static void build_string_class_template
PARAMS ((void));
244 static tree my_build_string
PARAMS ((int, const char *));
245 static void build_objc_symtab_template
PARAMS ((void));
246 static tree init_def_list
PARAMS ((tree
));
247 static tree init_objc_symtab
PARAMS ((tree
));
248 static void forward_declare_categories
PARAMS ((void));
249 static void generate_objc_symtab_decl
PARAMS ((void));
250 static tree build_selector
PARAMS ((tree
));
251 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
252 static tree build_selector_reference
PARAMS ((tree
));
253 static tree build_class_reference_decl
PARAMS ((void));
254 static void add_class_reference
PARAMS ((tree
));
255 static tree build_protocol_template
PARAMS ((void));
256 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
257 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
258 static tree build_method_prototype_template
PARAMS ((void));
259 static int forwarding_offset
PARAMS ((tree
));
260 static tree encode_method_prototype
PARAMS ((tree
, tree
));
261 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
263 static void generate_method_descriptors
PARAMS ((tree
));
264 static tree build_tmp_function_decl
PARAMS ((void));
265 static void hack_method_prototype
PARAMS ((tree
, tree
));
266 static void generate_protocol_references
PARAMS ((tree
));
267 static void generate_protocols
PARAMS ((void));
268 static void check_ivars
PARAMS ((tree
, tree
));
269 static tree build_ivar_list_template
PARAMS ((tree
, int));
270 static tree build_method_list_template
PARAMS ((tree
, int));
271 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
272 static tree generate_ivars_list
PARAMS ((tree
, const char *,
274 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
275 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
277 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
278 tree
, int, tree
, tree
,
280 static void generate_category
PARAMS ((tree
));
281 static int is_objc_type_qualifier
PARAMS ((tree
));
282 static tree adjust_type_for_id_default
PARAMS ((tree
));
283 static tree check_duplicates
PARAMS ((hash
));
284 static tree receiver_is_class_object
PARAMS ((tree
));
285 static int check_methods
PARAMS ((tree
, tree
, int));
286 static int conforms_to_protocol
PARAMS ((tree
, tree
));
287 static void check_protocol
PARAMS ((tree
, const char *,
289 static void check_protocols
PARAMS ((tree
, const char *,
291 static tree encode_method_def
PARAMS ((tree
));
292 static void gen_declspecs
PARAMS ((tree
, char *, int));
293 static void generate_classref_translation_entry
PARAMS ((tree
));
294 static void handle_class_ref
PARAMS ((tree
));
295 static void generate_struct_by_value_array
PARAMS ((void))
297 static void encode_complete_bitfield
PARAMS ((int, tree
, int));
298 static void mark_referenced_methods
PARAMS ((void));
300 /*** Private Interface (data) ***/
302 /* Reserved tag definitions. */
305 #define TAG_OBJECT "objc_object"
306 #define TAG_CLASS "objc_class"
307 #define TAG_SUPER "objc_super"
308 #define TAG_SELECTOR "objc_selector"
310 #define UTAG_CLASS "_objc_class"
311 #define UTAG_IVAR "_objc_ivar"
312 #define UTAG_IVAR_LIST "_objc_ivar_list"
313 #define UTAG_METHOD "_objc_method"
314 #define UTAG_METHOD_LIST "_objc_method_list"
315 #define UTAG_CATEGORY "_objc_category"
316 #define UTAG_MODULE "_objc_module"
317 #define UTAG_SYMTAB "_objc_symtab"
318 #define UTAG_SUPER "_objc_super"
319 #define UTAG_SELECTOR "_objc_selector"
321 #define UTAG_PROTOCOL "_objc_protocol"
322 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
323 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
325 /* Note that the string object global name is only needed for the
327 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
329 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
331 static const char *TAG_GETCLASS
;
332 static const char *TAG_GETMETACLASS
;
333 static const char *TAG_MSGSEND
;
334 static const char *TAG_MSGSENDSUPER
;
335 static const char *TAG_EXECCLASS
;
336 static const char *default_constant_string_class_name
;
338 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
339 tree objc_global_trees
[OCTI_MAX
];
341 static void handle_impent
PARAMS ((struct imp_entry
*));
343 struct imp_entry
*imp_list
= 0;
344 int imp_count
= 0; /* `@implementation' */
345 int cat_count
= 0; /* `@category' */
347 static int method_slot
= 0; /* Used by start_method_def, */
351 static char *errbuf
; /* Buffer for error diagnostics */
353 /* Data imported from tree.c. */
355 extern enum debug_info_type write_symbols
;
357 /* Data imported from toplev.c. */
359 extern const char *dump_base_name
;
361 static int flag_typed_selectors
;
363 FILE *gen_declaration_file
;
365 /* Tells "encode_pointer/encode_aggregate" whether we are generating
366 type descriptors for instance variables (as opposed to methods).
367 Type descriptors for instance variables contain more information
368 than methods (for static typing and embedded structures). */
370 static int generating_instance_variables
= 0;
372 /* Some platforms pass small structures through registers versus
373 through an invisible pointer. Determine at what size structure is
374 the transition point between the two possibilities. */
377 generate_struct_by_value_array ()
380 tree field_decl
, field_decl_chain
;
382 int aggregate_in_mem
[32];
385 /* Presumably no platform passes 32 byte structures in a register. */
386 for (i
= 1; i
< 32; i
++)
390 /* Create an unnamed struct that has `i' character components */
391 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
393 strcpy (buffer
, "c1");
394 field_decl
= create_builtin_decl (FIELD_DECL
,
397 field_decl_chain
= field_decl
;
399 for (j
= 1; j
< i
; j
++)
401 sprintf (buffer
, "c%d", j
+ 1);
402 field_decl
= create_builtin_decl (FIELD_DECL
,
405 chainon (field_decl_chain
, field_decl
);
407 finish_struct (type
, field_decl_chain
, NULL_TREE
);
409 aggregate_in_mem
[i
] = aggregate_value_p (type
);
410 if (!aggregate_in_mem
[i
])
414 /* We found some structures that are returned in registers instead of memory
415 so output the necessary data. */
418 for (i
= 31; i
>= 0; i
--)
419 if (!aggregate_in_mem
[i
])
421 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
423 /* The first member of the structure is always 0 because we don't handle
424 structures with 0 members */
425 printf ("static int struct_forward_array[] = {\n 0");
427 for (j
= 1; j
<= i
; j
++)
428 printf (", %d", aggregate_in_mem
[j
]);
438 if (c_objc_common_init () == false)
441 /* Force the line number back to 0; check_newline will have
442 raised it to 1, which will make the builtin functions appear
443 not to be built in. */
446 /* If gen_declaration desired, open the output file. */
447 if (flag_gen_declaration
)
449 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
450 gen_declaration_file
= fopen (dumpname
, "w");
451 if (gen_declaration_file
== 0)
452 fatal_error ("can't open %s: %m", dumpname
);
456 if (flag_next_runtime
)
458 TAG_GETCLASS
= "objc_getClass";
459 TAG_GETMETACLASS
= "objc_getMetaClass";
460 TAG_MSGSEND
= "objc_msgSend";
461 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
462 TAG_EXECCLASS
= "__objc_execClass";
463 default_constant_string_class_name
= "NSConstantString";
467 TAG_GETCLASS
= "objc_get_class";
468 TAG_GETMETACLASS
= "objc_get_meta_class";
469 TAG_MSGSEND
= "objc_msg_lookup";
470 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
471 TAG_EXECCLASS
= "__objc_exec_class";
472 default_constant_string_class_name
= "NXConstantString";
473 flag_typed_selectors
= 1;
476 objc_ellipsis_node
= make_node (ERROR_MARK
);
480 if (print_struct_values
)
481 generate_struct_by_value_array ();
489 mark_referenced_methods ();
490 c_objc_common_finish_file ();
492 /* Finalize Objective-C runtime data. No need to generate tables
493 and code if only checking syntax. */
494 if (!flag_syntax_only
)
497 if (gen_declaration_file
)
498 fclose (gen_declaration_file
);
502 define_decl (declarator
, declspecs
)
506 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
507 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
511 /* Return 1 if LHS and RHS are compatible types for assignment or
512 various other operations. Return 0 if they are incompatible, and
513 return -1 if we choose to not decide. When the operation is
514 REFLEXIVE, check for compatibility in either direction.
516 For statically typed objects, an assignment of the form `a' = `b'
520 `a' and `b' are the same class type, or
521 `a' and `b' are of class types A and B such that B is a descendant of A. */
524 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
532 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
534 p
= TREE_VALUE (rproto
);
536 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
538 if ((fnd
= lookup_method (class_meth
539 ? PROTOCOL_CLS_METHODS (p
)
540 : PROTOCOL_NST_METHODS (p
), sel_name
)))
542 else if (PROTOCOL_LIST (p
))
543 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
544 sel_name
, class_meth
);
548 ; /* An identifier...if we could not find a protocol. */
559 lookup_protocol_in_reflist (rproto_list
, lproto
)
565 /* Make sure the protocol is supported by the object on the rhs. */
566 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
569 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
571 p
= TREE_VALUE (rproto
);
573 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
578 else if (PROTOCOL_LIST (p
))
579 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
588 ; /* An identifier...if we could not find a protocol. */
594 /* Return 1 if LHS and RHS are compatible types for assignment or
595 various other operations. Return 0 if they are incompatible, and
596 return -1 if we choose to not decide (because the types are really
597 just C types, not ObjC specific ones). When the operation is
598 REFLEXIVE (typically comparisons), check for compatibility in
599 either direction; when it's not (typically assignments), don't.
601 This function is called in two cases: when both lhs and rhs are
602 pointers to records (in which case we check protocols too), and
603 when both lhs and rhs are records (in which case we check class
606 Warnings about classes/protocols not implementing a protocol are
607 emitted here (multiple of those warnings might be emitted for a
608 single line!); generic warnings about incompatible assignments and
609 lacks of casts in comparisons are/must be emitted by the caller if
614 objc_comptypes (lhs
, rhs
, reflexive
)
619 /* New clause for protocols. */
621 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
622 manage the ObjC ones, and leave the rest to the C code. */
623 if (TREE_CODE (lhs
) == POINTER_TYPE
624 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
625 && TREE_CODE (rhs
) == POINTER_TYPE
626 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
628 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
629 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
633 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
634 tree rproto
, rproto_list
;
637 /* <Protocol> = <Protocol> */
640 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
644 /* An assignment between objects of type 'id
645 <Protocol>'; make sure the protocol on the lhs is
646 supported by the object on the rhs. */
647 for (lproto
= lproto_list
; lproto
;
648 lproto
= TREE_CHAIN (lproto
))
650 p
= TREE_VALUE (lproto
);
651 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
655 ("object does not conform to the `%s' protocol",
656 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
662 /* Obscure case - a comparison between two objects
663 of type 'id <Protocol>'. Check that either the
664 protocol on the lhs is supported by the object on
665 the rhs, or viceversa. */
667 /* Check if the protocol on the lhs is supported by the
668 object on the rhs. */
669 for (lproto
= lproto_list
; lproto
;
670 lproto
= TREE_CHAIN (lproto
))
672 p
= TREE_VALUE (lproto
);
673 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
677 /* Check failed - check if the protocol on the rhs
678 is supported by the object on the lhs. */
679 for (rproto
= rproto_list
; rproto
;
680 rproto
= TREE_CHAIN (rproto
))
682 p
= TREE_VALUE (rproto
);
683 lproto
= lookup_protocol_in_reflist (lproto_list
,
688 /* This check failed too: incompatible */
698 /* <Protocol> = <class> * */
699 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
701 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
704 /* Make sure the protocol is supported by the object on
706 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
708 p
= TREE_VALUE (lproto
);
710 rinter
= lookup_interface (rname
);
712 while (rinter
&& !rproto
)
716 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
717 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
718 /* If the underlying ObjC class does not have
719 the protocol we're looking for, check for "one-off"
720 protocols (e.g., `NSObject<MyProt> *foo;') attached
724 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
725 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
728 /* Check for protocols adopted by categories. */
729 cat
= CLASS_CATEGORY_LIST (rinter
);
730 while (cat
&& !rproto
)
732 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
733 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
734 cat
= CLASS_CATEGORY_LIST (cat
);
737 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
741 warning ("class `%s' does not implement the `%s' protocol",
742 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
743 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
747 /* <Protocol> = id */
748 else if (TYPE_NAME (TREE_TYPE (rhs
)) == objc_object_id
)
752 /* <Protocol> = Class */
753 else if (TYPE_NAME (TREE_TYPE (rhs
)) == objc_class_id
)
757 /* <Protocol> = ?? : let comptypes decide. */
760 else if (rhs_is_proto
)
762 /* <class> * = <Protocol> */
763 if (TYPED_OBJECT (TREE_TYPE (lhs
)))
767 tree rname
= TYPE_NAME (TREE_TYPE (lhs
));
769 tree rproto
, rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
771 /* Make sure the protocol is supported by the object on
773 for (rproto
= rproto_list
; rproto
;
774 rproto
= TREE_CHAIN (rproto
))
776 tree p
= TREE_VALUE (rproto
);
778 rinter
= lookup_interface (rname
);
780 while (rinter
&& !lproto
)
784 tree lproto_list
= CLASS_PROTOCOL_LIST (rinter
);
785 lproto
= lookup_protocol_in_reflist (lproto_list
, p
);
786 /* If the underlying ObjC class does not
787 have the protocol we're looking for,
788 check for "one-off" protocols (e.g.,
789 `NSObject<MyProt> *foo;') attached to the
793 lproto_list
= TYPE_PROTOCOL_LIST
795 lproto
= lookup_protocol_in_reflist
799 /* Check for protocols adopted by categories. */
800 cat
= CLASS_CATEGORY_LIST (rinter
);
801 while (cat
&& !lproto
)
803 lproto_list
= CLASS_PROTOCOL_LIST (cat
);
804 lproto
= lookup_protocol_in_reflist (lproto_list
,
806 cat
= CLASS_CATEGORY_LIST (cat
);
809 rinter
= lookup_interface (CLASS_SUPER_NAME
814 warning ("class `%s' does not implement the `%s' protocol",
815 IDENTIFIER_POINTER (TYPE_NAME
817 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
824 /* id = <Protocol> */
825 else if (TYPE_NAME (TREE_TYPE (lhs
)) == objc_object_id
)
829 /* Class = <Protocol> */
830 else if (TYPE_NAME (TREE_TYPE (lhs
)) == objc_class_id
)
834 /* ??? = <Protocol> : let comptypes decide */
842 /* Attention: we shouldn't defer to comptypes here. One bad
843 side effect would be that we might loose the REFLEXIVE
846 lhs
= TREE_TYPE (lhs
);
847 rhs
= TREE_TYPE (rhs
);
851 if (TREE_CODE (lhs
) != RECORD_TYPE
|| TREE_CODE (rhs
) != RECORD_TYPE
)
853 /* Nothing to do with ObjC - let immediately comptypes take
854 responsibility for checking. */
858 /* `id' = `<class> *' `<class> *' = `id': always allow it.
860 'Object *o = [[Object alloc] init]; falls
861 in the case <class> * = `id'.
863 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
864 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
867 /* `id' = `Class', `Class' = `id' */
869 else if ((TYPE_NAME (lhs
) == objc_object_id
870 && TYPE_NAME (rhs
) == objc_class_id
)
871 || (TYPE_NAME (lhs
) == objc_class_id
872 && TYPE_NAME (rhs
) == objc_object_id
))
875 /* `<class> *' = `<class> *' */
877 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
879 tree lname
= TYPE_NAME (lhs
);
880 tree rname
= TYPE_NAME (rhs
);
886 /* If the left hand side is a super class of the right hand side,
888 for (inter
= lookup_interface (rname
); inter
;
889 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
890 if (lname
== CLASS_SUPER_NAME (inter
))
893 /* Allow the reverse when reflexive. */
895 for (inter
= lookup_interface (lname
); inter
;
896 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
897 if (rname
== CLASS_SUPER_NAME (inter
))
903 /* Not an ObjC type - let comptypes do the check. */
907 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
910 objc_check_decl (decl
)
913 tree type
= TREE_TYPE (decl
);
915 if (TREE_CODE (type
) == RECORD_TYPE
916 && TREE_STATIC_TEMPLATE (type
)
917 && type
!= constant_string_type
)
918 error_with_decl (decl
, "`%s' cannot be statically allocated");
921 /* Implement static typing. At this point, we know we have an interface. */
924 get_static_reference (interface
, protocols
)
928 tree type
= xref_tag (RECORD_TYPE
, interface
);
932 tree t
, m
= TYPE_MAIN_VARIANT (type
);
934 t
= copy_node (type
);
936 /* Add this type to the chain of variants of TYPE. */
937 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
938 TYPE_NEXT_VARIANT (m
) = t
;
940 /* Look up protocols and install in lang specific list. Note
941 that the protocol list can have a different lifetime than T! */
942 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
944 /* This forces a new pointer type to be created later
945 (in build_pointer_type)...so that the new template
946 we just created will actually be used...what a hack! */
947 if (TYPE_POINTER_TO (t
))
948 TYPE_POINTER_TO (t
) = NULL_TREE
;
957 get_object_reference (protocols
)
960 tree type_decl
= lookup_name (objc_id_id
);
963 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
965 type
= TREE_TYPE (type_decl
);
966 if (TYPE_MAIN_VARIANT (type
) != id_type
)
967 warning ("unexpected type for `id' (%s)",
968 gen_declaration (type
, errbuf
));
972 error ("undefined type `id', please import <objc/objc.h>");
973 return error_mark_node
;
976 /* This clause creates a new pointer type that is qualified with
977 the protocol specification...this info is used later to do more
978 elaborate type checking. */
982 tree t
, m
= TYPE_MAIN_VARIANT (type
);
984 t
= copy_node (type
);
986 /* Add this type to the chain of variants of TYPE. */
987 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
988 TYPE_NEXT_VARIANT (m
) = t
;
990 /* Look up protocols...and install in lang specific list */
991 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
993 /* This forces a new pointer type to be created later
994 (in build_pointer_type)...so that the new template
995 we just created will actually be used...what a hack! */
996 if (TYPE_POINTER_TO (t
))
997 TYPE_POINTER_TO (t
) = NULL_TREE
;
1004 /* Check for circular dependencies in protocols. The arguments are
1005 PROTO, the protocol to check, and LIST, a list of protocol it
1009 check_protocol_recursively (proto
, list
)
1015 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1017 tree pp
= TREE_VALUE (p
);
1019 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1020 pp
= lookup_protocol (pp
);
1023 fatal_error ("protocol `%s' has circular dependency",
1024 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1026 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1031 lookup_and_install_protocols (protocols
)
1036 tree return_value
= protocols
;
1038 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1040 tree ident
= TREE_VALUE (proto
);
1041 tree p
= lookup_protocol (ident
);
1045 error ("cannot find protocol declaration for `%s'",
1046 IDENTIFIER_POINTER (ident
));
1048 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1050 return_value
= TREE_CHAIN (proto
);
1054 /* Replace identifier with actual protocol node. */
1055 TREE_VALUE (proto
) = p
;
1060 return return_value
;
1063 /* Create and push a decl for a built-in external variable or field NAME.
1065 TYPE is its data type. */
1068 create_builtin_decl (code
, type
, name
)
1069 enum tree_code code
;
1073 tree decl
= build_decl (code
, get_identifier (name
), type
);
1075 if (code
== VAR_DECL
)
1077 TREE_STATIC (decl
) = 1;
1078 make_decl_rtl (decl
, 0);
1082 DECL_ARTIFICIAL (decl
) = 1;
1086 /* Find the decl for the constant string class. */
1089 setup_string_decl ()
1091 if (!string_class_decl
)
1093 if (!constant_string_global_id
)
1094 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
1095 string_class_decl
= lookup_name (constant_string_global_id
);
1099 /* Purpose: "play" parser, creating/installing representations
1100 of the declarations that are required by Objective-C.
1104 type_spec--------->sc_spec
1105 (tree_list) (tree_list)
1108 identifier_node identifier_node */
1111 synth_module_prologue ()
1116 /* Defined in `objc.h' */
1117 objc_object_id
= get_identifier (TAG_OBJECT
);
1119 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1121 id_type
= build_pointer_type (objc_object_reference
);
1123 objc_id_id
= get_identifier (TYPE_ID
);
1124 objc_class_id
= get_identifier (TAG_CLASS
);
1126 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1127 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1128 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1130 /* Declare type of selector-objects that represent an operation name. */
1132 /* `struct objc_selector *' */
1134 = build_pointer_type (xref_tag (RECORD_TYPE
,
1135 get_identifier (TAG_SELECTOR
)));
1137 /* Forward declare type, or else the prototype for msgSendSuper will
1140 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1141 get_identifier (TAG_SUPER
)));
1144 /* id objc_msgSend (id, SEL, ...); */
1147 = build_function_type (id_type
,
1148 tree_cons (NULL_TREE
, id_type
,
1149 tree_cons (NULL_TREE
, selector_type
,
1152 if (! flag_next_runtime
)
1154 umsg_decl
= build_decl (FUNCTION_DECL
,
1155 get_identifier (TAG_MSGSEND
), temp_type
);
1156 DECL_EXTERNAL (umsg_decl
) = 1;
1157 TREE_PUBLIC (umsg_decl
) = 1;
1158 DECL_INLINE (umsg_decl
) = 1;
1159 DECL_ARTIFICIAL (umsg_decl
) = 1;
1161 make_decl_rtl (umsg_decl
, NULL
);
1162 pushdecl (umsg_decl
);
1165 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
,
1168 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1171 = build_function_type (id_type
,
1172 tree_cons (NULL_TREE
, super_p
,
1173 tree_cons (NULL_TREE
, selector_type
,
1176 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1177 temp_type
, 0, NOT_BUILT_IN
,
1180 /* id objc_getClass (const char *); */
1182 temp_type
= build_function_type (id_type
,
1183 tree_cons (NULL_TREE
,
1184 const_string_type_node
,
1185 tree_cons (NULL_TREE
, void_type_node
,
1189 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
,
1192 /* id objc_getMetaClass (const char *); */
1194 objc_get_meta_class_decl
1195 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
,
1198 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1200 if (! flag_next_runtime
)
1202 if (flag_typed_selectors
)
1204 /* Suppress outputting debug symbols, because
1205 dbxout_init hasn'r been called yet. */
1206 enum debug_info_type save_write_symbols
= write_symbols
;
1207 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
1208 write_symbols
= NO_DEBUG
;
1209 debug_hooks
= &do_nothing_debug_hooks
;
1211 build_selector_template ();
1212 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1214 write_symbols
= save_write_symbols
;
1215 debug_hooks
= save_hooks
;
1218 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1220 layout_type (temp_type
);
1221 UOBJC_SELECTOR_TABLE_decl
1222 = create_builtin_decl (VAR_DECL
, temp_type
,
1223 "_OBJC_SELECTOR_TABLE");
1225 /* Avoid warning when not sending messages. */
1226 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1229 generate_forward_declaration_to_string_table ();
1231 /* Forward declare constant_string_id and constant_string_type. */
1232 if (!constant_string_class_name
)
1233 constant_string_class_name
= default_constant_string_class_name
;
1235 constant_string_id
= get_identifier (constant_string_class_name
);
1236 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1239 /* Predefine the following data type:
1241 struct STRING_OBJECT_CLASS_NAME
1245 unsigned int length;
1249 build_string_class_template ()
1251 tree field_decl
, field_decl_chain
;
1253 field_decl
= create_builtin_decl (FIELD_DECL
, id_type
, "isa");
1254 field_decl_chain
= field_decl
;
1256 field_decl
= create_builtin_decl (FIELD_DECL
,
1257 build_pointer_type (char_type_node
),
1259 chainon (field_decl_chain
, field_decl
);
1261 field_decl
= create_builtin_decl (FIELD_DECL
, unsigned_type_node
, "length");
1262 chainon (field_decl_chain
, field_decl
);
1264 finish_struct (constant_string_type
, field_decl_chain
, NULL_TREE
);
1267 /* Custom build_string which sets TREE_TYPE! */
1270 my_build_string (len
, str
)
1274 return fix_string_type (build_string (len
, str
));
1277 /* Build a static instance of NXConstantString which points at the
1278 string constant STRING.
1279 We place the string object in the __string_objects section of the
1280 __OBJC segment. The Objective-C runtime will initialize the isa
1281 pointers of the string objects to point at the NXConstantString
1285 build_objc_string_object (string
)
1288 tree initlist
, constructor
;
1291 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1293 error ("cannot find interface declaration for `%s'",
1294 IDENTIFIER_POINTER (constant_string_id
));
1295 return error_mark_node
;
1298 add_class_reference (constant_string_id
);
1300 length
= TREE_STRING_LENGTH (string
) - 1;
1302 /* We could not properly create NXConstantString in synth_module_prologue,
1303 because that's called before debugging is initialized. Do it now. */
1304 if (TYPE_FIELDS (constant_string_type
) == NULL_TREE
)
1305 build_string_class_template ();
1307 /* & ((NXConstantString) { NULL, string, length }) */
1309 if (flag_next_runtime
)
1311 /* For the NeXT runtime, we can generate a literal reference
1312 to the string class, don't need to run a constructor. */
1313 setup_string_decl ();
1314 if (string_class_decl
== NULL_TREE
)
1316 error ("cannot find reference tag for class `%s'",
1317 IDENTIFIER_POINTER (constant_string_id
));
1318 return error_mark_node
;
1320 initlist
= build_tree_list
1322 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1326 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1330 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1332 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1333 constructor
= objc_build_constructor (constant_string_type
,
1334 nreverse (initlist
));
1336 if (!flag_next_runtime
)
1339 = objc_add_static_instance (constructor
, constant_string_type
);
1342 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1345 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1347 static GTY(()) int num_static_inst
;
1349 objc_add_static_instance (constructor
, class_decl
)
1350 tree constructor
, class_decl
;
1355 /* Find the list of static instances for the CLASS_DECL. Create one if
1357 for (chain
= &objc_static_instances
;
1358 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1359 chain
= &TREE_CHAIN (*chain
));
1362 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1363 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1366 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1367 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1368 DECL_COMMON (decl
) = 1;
1369 TREE_STATIC (decl
) = 1;
1370 DECL_ARTIFICIAL (decl
) = 1;
1371 DECL_INITIAL (decl
) = constructor
;
1373 /* We may be writing something else just now.
1374 Postpone till end of input. */
1375 DECL_DEFER_OUTPUT (decl
) = 1;
1376 pushdecl_top_level (decl
);
1377 rest_of_decl_compilation (decl
, 0, 1, 0);
1379 /* Add the DECL to the head of this CLASS' list. */
1380 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1385 /* Build a static constant CONSTRUCTOR
1386 with type TYPE and elements ELTS. */
1389 objc_build_constructor (type
, elts
)
1392 tree constructor
, f
, e
;
1394 /* ??? Most of the places that we build constructors, we don't fill in
1395 the type of integers properly. Convert them all en masse. */
1396 if (TREE_CODE (type
) == ARRAY_TYPE
)
1398 f
= TREE_TYPE (type
);
1399 if (TREE_CODE (f
) == POINTER_TYPE
|| TREE_CODE (f
) == INTEGER_TYPE
)
1400 for (e
= elts
; e
; e
= TREE_CHAIN (e
))
1401 TREE_VALUE (e
) = convert (f
, TREE_VALUE (e
));
1405 f
= TYPE_FIELDS (type
);
1406 for (e
= elts
; e
&& f
; e
= TREE_CHAIN (e
), f
= TREE_CHAIN (f
))
1407 if (TREE_CODE (TREE_TYPE (f
)) == POINTER_TYPE
1408 || TREE_CODE (TREE_TYPE (f
)) == INTEGER_TYPE
)
1409 TREE_VALUE (e
) = convert (TREE_TYPE (f
), TREE_VALUE (e
));
1412 constructor
= build_constructor (type
, elts
);
1413 TREE_CONSTANT (constructor
) = 1;
1414 TREE_STATIC (constructor
) = 1;
1415 TREE_READONLY (constructor
) = 1;
1420 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1422 /* Predefine the following data type:
1430 void *defs[cls_def_cnt + cat_def_cnt];
1434 build_objc_symtab_template ()
1436 tree field_decl
, field_decl_chain
, index
;
1438 objc_symtab_template
1439 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1441 /* long sel_ref_cnt; */
1443 field_decl
= create_builtin_decl (FIELD_DECL
,
1444 long_integer_type_node
,
1446 field_decl_chain
= field_decl
;
1450 field_decl
= create_builtin_decl (FIELD_DECL
,
1451 build_pointer_type (selector_type
),
1453 chainon (field_decl_chain
, field_decl
);
1455 /* short cls_def_cnt; */
1457 field_decl
= create_builtin_decl (FIELD_DECL
,
1458 short_integer_type_node
,
1460 chainon (field_decl_chain
, field_decl
);
1462 /* short cat_def_cnt; */
1464 field_decl
= create_builtin_decl (FIELD_DECL
,
1465 short_integer_type_node
,
1467 chainon (field_decl_chain
, field_decl
);
1469 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1471 if (!flag_next_runtime
)
1472 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1474 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1475 imp_count
== 0 && cat_count
== 0
1477 field_decl
= create_builtin_decl (FIELD_DECL
,
1478 build_array_type (ptr_type_node
, index
),
1480 chainon (field_decl_chain
, field_decl
);
1482 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1485 /* Create the initial value for the `defs' field of _objc_symtab.
1486 This is a CONSTRUCTOR. */
1489 init_def_list (type
)
1492 tree expr
, initlist
= NULL_TREE
;
1493 struct imp_entry
*impent
;
1496 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1498 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1500 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1501 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1506 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1508 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1510 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1511 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1515 if (!flag_next_runtime
)
1517 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1520 if (static_instances_decl
)
1521 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1523 expr
= build_int_2 (0, 0);
1525 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1528 return objc_build_constructor (type
, nreverse (initlist
));
1531 /* Construct the initial value for all of _objc_symtab. */
1534 init_objc_symtab (type
)
1539 /* sel_ref_cnt = { ..., 5, ... } */
1541 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1543 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1545 if (flag_next_runtime
|| ! sel_ref_chain
)
1546 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1548 initlist
= tree_cons (NULL_TREE
,
1549 build_unary_op (ADDR_EXPR
,
1550 UOBJC_SELECTOR_TABLE_decl
, 1),
1553 /* cls_def_cnt = { ..., 5, ... } */
1555 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1557 /* cat_def_cnt = { ..., 5, ... } */
1559 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1561 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1563 if (imp_count
|| cat_count
|| static_instances_decl
)
1566 tree field
= TYPE_FIELDS (type
);
1567 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1569 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1573 return objc_build_constructor (type
, nreverse (initlist
));
1576 /* Push forward-declarations of all the categories so that
1577 init_def_list can use them in a CONSTRUCTOR. */
1580 forward_declare_categories ()
1582 struct imp_entry
*impent
;
1583 tree sav
= objc_implementation_context
;
1585 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1587 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1589 /* Set an invisible arg to synth_id_with_class_suffix. */
1590 objc_implementation_context
= impent
->imp_context
;
1592 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1593 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context
)));
1596 objc_implementation_context
= sav
;
1599 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1600 and initialized appropriately. */
1603 generate_objc_symtab_decl ()
1607 if (!objc_category_template
)
1608 build_category_template ();
1610 /* forward declare categories */
1612 forward_declare_categories ();
1614 if (!objc_symtab_template
)
1615 build_objc_symtab_template ();
1617 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1619 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1620 tree_cons (NULL_TREE
,
1621 objc_symtab_template
, sc_spec
),
1625 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1626 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1627 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1628 finish_decl (UOBJC_SYMBOLS_decl
,
1629 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1634 init_module_descriptor (type
)
1637 tree initlist
, expr
;
1639 /* version = { 1, ... } */
1641 expr
= build_int_2 (OBJC_VERSION
, 0);
1642 initlist
= build_tree_list (NULL_TREE
, expr
);
1644 /* size = { ..., sizeof (struct objc_module), ... } */
1646 expr
= size_in_bytes (objc_module_template
);
1647 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1649 /* name = { ..., "foo.m", ... } */
1651 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1652 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1654 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1656 if (UOBJC_SYMBOLS_decl
)
1657 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1659 expr
= build_int_2 (0, 0);
1660 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1662 return objc_build_constructor (type
, nreverse (initlist
));
1665 /* Write out the data structures to describe Objective C classes defined.
1666 If appropriate, compile and output a setup function to initialize them.
1667 Return a symbol_ref to the function to call to initialize the Objective C
1668 data structures for this file (and perhaps for other files also).
1670 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1673 build_module_descriptor ()
1675 tree decl_specs
, field_decl
, field_decl_chain
;
1677 objc_module_template
1678 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1682 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1683 field_decl
= get_identifier ("version");
1684 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
1685 field_decl_chain
= field_decl
;
1689 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1690 field_decl
= get_identifier ("size");
1691 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
1692 chainon (field_decl_chain
, field_decl
);
1696 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1697 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1698 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
1699 chainon (field_decl_chain
, field_decl
);
1701 /* struct objc_symtab *symtab; */
1703 decl_specs
= get_identifier (UTAG_SYMTAB
);
1704 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1705 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1706 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
1707 chainon (field_decl_chain
, field_decl
);
1709 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1711 /* Create an instance of "objc_module". */
1713 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1714 build_tree_list (NULL_TREE
,
1715 ridpointers
[(int) RID_STATIC
]));
1717 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1718 decl_specs
, 1, NULL_TREE
);
1720 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1721 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1722 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1724 finish_decl (UOBJC_MODULES_decl
,
1725 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1728 /* Mark the decl to avoid "defined but not used" warning. */
1729 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1731 /* Generate a constructor call for the module descriptor.
1732 This code was generated by reading the grammar rules
1733 of c-parse.in; Therefore, it may not be the most efficient
1734 way of generating the requisite code. */
1736 if (flag_next_runtime
)
1740 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1741 tree init_function_name
, init_function_decl
;
1743 /* Declare void __objc_execClass (void *); */
1745 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1746 execclass_decl
= build_decl (FUNCTION_DECL
,
1747 get_identifier (TAG_EXECCLASS
),
1748 build_function_type (void_type_node
,
1749 tree_cons (NULL_TREE
, ptr_type_node
,
1750 void_list_node_1
)));
1751 DECL_EXTERNAL (execclass_decl
) = 1;
1752 DECL_ARTIFICIAL (execclass_decl
) = 1;
1753 TREE_PUBLIC (execclass_decl
) = 1;
1754 pushdecl (execclass_decl
);
1755 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1756 assemble_external (execclass_decl
);
1758 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1760 init_function_name
= get_file_function_name ('I');
1761 start_function (void_list_node_1
,
1762 build_nt (CALL_EXPR
, init_function_name
,
1763 tree_cons (NULL_TREE
, NULL_TREE
,
1767 store_parm_decls ();
1769 init_function_decl
= current_function_decl
;
1770 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1771 TREE_USED (init_function_decl
) = 1;
1772 /* Don't let this one be deferred. */
1773 DECL_INLINE (init_function_decl
) = 0;
1774 DECL_UNINLINABLE (init_function_decl
) = 1;
1775 current_function_cannot_inline
1776 = "static constructors and destructors cannot be inlined";
1779 = build_tree_list (NULL_TREE
,
1780 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1781 decelerator
= build_function_call (execclass_decl
, parms
);
1783 c_expand_expr_stmt (decelerator
);
1785 finish_function (0, 0);
1787 return XEXP (DECL_RTL (init_function_decl
), 0);
1791 /* extern const char _OBJC_STRINGS[]; */
1794 generate_forward_declaration_to_string_table ()
1796 tree sc_spec
, decl_specs
, expr_decl
;
1798 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1799 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1802 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1804 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1807 /* Return the DECL of the string IDENT in the SECTION. */
1810 get_objc_string_decl (ident
, section
)
1812 enum string_section section
;
1816 if (section
== class_names
)
1817 chain
= class_names_chain
;
1818 else if (section
== meth_var_names
)
1819 chain
= meth_var_names_chain
;
1820 else if (section
== meth_var_types
)
1821 chain
= meth_var_types_chain
;
1825 for (; chain
!= 0; chain
= TREE_CHAIN (chain
))
1826 if (TREE_VALUE (chain
) == ident
)
1827 return (TREE_PURPOSE (chain
));
1833 /* Output references to all statically allocated objects. Return the DECL
1834 for the array built. */
1837 generate_static_references ()
1839 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1840 tree class_name
, class, decl
, initlist
;
1841 tree cl_chain
, in_chain
, type
;
1842 int num_inst
, num_class
;
1845 if (flag_next_runtime
)
1848 for (cl_chain
= objc_static_instances
, num_class
= 0;
1849 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1851 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1852 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1854 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1855 ident
= get_identifier (buf
);
1857 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1858 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1859 build_tree_list (NULL_TREE
,
1860 ridpointers
[(int) RID_STATIC
]));
1861 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1862 DECL_CONTEXT (decl
) = 0;
1863 DECL_ARTIFICIAL (decl
) = 1;
1865 /* Output {class_name, ...}. */
1866 class = TREE_VALUE (cl_chain
);
1867 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1868 initlist
= build_tree_list (NULL_TREE
,
1869 build_unary_op (ADDR_EXPR
, class_name
, 1));
1871 /* Output {..., instance, ...}. */
1872 for (in_chain
= TREE_PURPOSE (cl_chain
);
1873 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1875 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1876 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1879 /* Output {..., NULL}. */
1880 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1882 expr
= objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1883 finish_decl (decl
, expr
, NULL_TREE
);
1884 TREE_USED (decl
) = 1;
1886 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1887 decl
= build_decl (VAR_DECL
, ident
, type
);
1888 TREE_USED (decl
) = 1;
1889 TREE_STATIC (decl
) = 1;
1891 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1894 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1895 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1896 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1897 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1898 build_tree_list (NULL_TREE
,
1899 ridpointers
[(int) RID_STATIC
]));
1900 static_instances_decl
1901 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1902 TREE_USED (static_instances_decl
) = 1;
1903 DECL_CONTEXT (static_instances_decl
) = 0;
1904 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1905 expr
= objc_build_constructor (TREE_TYPE (static_instances_decl
),
1907 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1910 /* Output all strings. */
1915 tree sc_spec
, decl_specs
, expr_decl
;
1916 tree chain
, string_expr
;
1919 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1921 string
= TREE_VALUE (chain
);
1922 decl
= TREE_PURPOSE (chain
);
1924 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1925 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1926 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1927 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1928 DECL_CONTEXT (decl
) = NULL_TREE
;
1929 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1930 IDENTIFIER_POINTER (string
));
1931 finish_decl (decl
, string_expr
, NULL_TREE
);
1934 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1936 string
= TREE_VALUE (chain
);
1937 decl
= TREE_PURPOSE (chain
);
1939 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1940 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1941 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1942 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1943 DECL_CONTEXT (decl
) = NULL_TREE
;
1944 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1945 IDENTIFIER_POINTER (string
));
1946 finish_decl (decl
, string_expr
, NULL_TREE
);
1949 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1951 string
= TREE_VALUE (chain
);
1952 decl
= TREE_PURPOSE (chain
);
1954 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1955 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1956 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1957 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1958 DECL_CONTEXT (decl
) = NULL_TREE
;
1959 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1960 IDENTIFIER_POINTER (string
));
1961 finish_decl (decl
, string_expr
, NULL_TREE
);
1965 static GTY(()) int selector_reference_idx
;
1967 build_selector_reference_decl ()
1972 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx
++);
1974 ident
= get_identifier (buf
);
1976 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1977 DECL_EXTERNAL (decl
) = 1;
1978 TREE_PUBLIC (decl
) = 1;
1979 TREE_USED (decl
) = 1;
1980 TREE_READONLY (decl
) = 1;
1981 DECL_ARTIFICIAL (decl
) = 1;
1982 DECL_CONTEXT (decl
) = 0;
1984 make_decl_rtl (decl
, 0);
1985 pushdecl_top_level (decl
);
1990 /* Just a handy wrapper for add_objc_string. */
1993 build_selector (ident
)
1996 tree expr
= add_objc_string (ident
, meth_var_names
);
1997 if (flag_typed_selectors
)
2000 return build_c_cast (selector_type
, expr
); /* cast! */
2004 build_selector_translation_table ()
2006 tree sc_spec
, decl_specs
;
2007 tree chain
, initlist
= NULL_TREE
;
2009 tree decl
= NULL_TREE
, var_decl
, name
;
2011 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2015 if (warn_selector
&& objc_implementation_context
)
2019 for (method_chain
= meth_var_names_chain
;
2021 method_chain
= TREE_CHAIN (method_chain
))
2023 if (TREE_VALUE (method_chain
) == TREE_VALUE (chain
))
2031 /* Adjust line number for warning message. */
2032 int save_lineno
= input_line
;
2033 if (flag_next_runtime
&& TREE_PURPOSE (chain
))
2034 input_line
= DECL_SOURCE_LINE (TREE_PURPOSE (chain
));
2035 warning ("creating selector for non existant method %s",
2036 IDENTIFIER_POINTER (TREE_VALUE (chain
)));
2037 input_line
= save_lineno
;
2041 expr
= build_selector (TREE_VALUE (chain
));
2043 if (flag_next_runtime
)
2045 name
= DECL_NAME (TREE_PURPOSE (chain
));
2047 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2049 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2050 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2054 /* The `decl' that is returned from start_decl is the one that we
2055 forward declared in `build_selector_reference' */
2056 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
2059 /* add one for the '\0' character */
2060 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2062 if (flag_next_runtime
)
2063 finish_decl (decl
, expr
, NULL_TREE
);
2066 if (flag_typed_selectors
)
2068 tree eltlist
= NULL_TREE
;
2069 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2070 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2071 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2072 expr
= objc_build_constructor (objc_selector_template
,
2073 nreverse (eltlist
));
2075 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2080 if (! flag_next_runtime
)
2082 /* Cause the variable and its initial value to be actually output. */
2083 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2084 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2085 /* NULL terminate the list and fix the decl for output. */
2086 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2087 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2088 initlist
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2089 nreverse (initlist
));
2090 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2091 current_function_decl
= NULL_TREE
;
2096 get_proto_encoding (proto
)
2104 if (! METHOD_ENCODING (proto
))
2106 tmp_decl
= build_tmp_function_decl ();
2107 hack_method_prototype (proto
, tmp_decl
);
2108 encoding
= encode_method_prototype (proto
, tmp_decl
);
2109 METHOD_ENCODING (proto
) = encoding
;
2112 encoding
= METHOD_ENCODING (proto
);
2114 return add_objc_string (encoding
, meth_var_types
);
2117 return build_int_2 (0, 0);
2120 /* sel_ref_chain is a list whose "value" fields will be instances of
2121 identifier_node that represent the selector. */
2124 build_typed_selector_reference (ident
, prototype
)
2125 tree ident
, prototype
;
2127 tree
*chain
= &sel_ref_chain
;
2133 if (TREE_PURPOSE (*chain
) == prototype
&& TREE_VALUE (*chain
) == ident
)
2134 goto return_at_index
;
2137 chain
= &TREE_CHAIN (*chain
);
2140 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
2143 expr
= build_unary_op (ADDR_EXPR
,
2144 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2145 build_int_2 (index
, 0)),
2147 return build_c_cast (selector_type
, expr
);
2151 build_selector_reference (ident
)
2154 tree
*chain
= &sel_ref_chain
;
2160 if (TREE_VALUE (*chain
) == ident
)
2161 return (flag_next_runtime
2162 ? TREE_PURPOSE (*chain
)
2163 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2164 build_int_2 (index
, 0)));
2167 chain
= &TREE_CHAIN (*chain
);
2170 expr
= build_selector_reference_decl ();
2172 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2174 return (flag_next_runtime
2176 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2177 build_int_2 (index
, 0)));
2180 static GTY(()) int class_reference_idx
;
2182 build_class_reference_decl ()
2187 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx
++);
2189 ident
= get_identifier (buf
);
2191 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2192 DECL_EXTERNAL (decl
) = 1;
2193 TREE_PUBLIC (decl
) = 1;
2194 TREE_USED (decl
) = 1;
2195 TREE_READONLY (decl
) = 1;
2196 DECL_CONTEXT (decl
) = 0;
2197 DECL_ARTIFICIAL (decl
) = 1;
2199 make_decl_rtl (decl
, 0);
2200 pushdecl_top_level (decl
);
2205 /* Create a class reference, but don't create a variable to reference
2209 add_class_reference (ident
)
2214 if ((chain
= cls_ref_chain
))
2219 if (ident
== TREE_VALUE (chain
))
2223 chain
= TREE_CHAIN (chain
);
2227 /* Append to the end of the list */
2228 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2231 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2234 /* Get a class reference, creating it if necessary. Also create the
2235 reference variable. */
2238 get_class_reference (ident
)
2241 if (flag_next_runtime
)
2246 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2247 if (TREE_VALUE (*chain
) == ident
)
2249 if (! TREE_PURPOSE (*chain
))
2250 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2252 return TREE_PURPOSE (*chain
);
2255 decl
= build_class_reference_decl ();
2256 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2263 add_class_reference (ident
);
2265 params
= build_tree_list (NULL_TREE
,
2266 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2267 IDENTIFIER_POINTER (ident
)));
2269 assemble_external (objc_get_class_decl
);
2270 return build_function_call (objc_get_class_decl
, params
);
2274 /* For each string section we have a chain which maps identifier nodes
2275 to decls for the strings. */
2278 add_objc_string (ident
, section
)
2280 enum string_section section
;
2284 if (section
== class_names
)
2285 chain
= &class_names_chain
;
2286 else if (section
== meth_var_names
)
2287 chain
= &meth_var_names_chain
;
2288 else if (section
== meth_var_types
)
2289 chain
= &meth_var_types_chain
;
2295 if (TREE_VALUE (*chain
) == ident
)
2296 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2298 chain
= &TREE_CHAIN (*chain
);
2301 decl
= build_objc_string_decl (section
);
2303 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2305 return build_unary_op (ADDR_EXPR
, decl
, 1);
2308 static GTY(()) int class_names_idx
;
2309 static GTY(()) int meth_var_names_idx
;
2310 static GTY(()) int meth_var_types_idx
;
2313 build_objc_string_decl (section
)
2314 enum string_section section
;
2319 if (section
== class_names
)
2320 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2321 else if (section
== meth_var_names
)
2322 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2323 else if (section
== meth_var_types
)
2324 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2326 ident
= get_identifier (buf
);
2328 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2329 DECL_EXTERNAL (decl
) = 1;
2330 TREE_PUBLIC (decl
) = 1;
2331 TREE_USED (decl
) = 1;
2332 TREE_READONLY (decl
) = 1;
2333 TREE_CONSTANT (decl
) = 1;
2334 DECL_CONTEXT (decl
) = 0;
2335 DECL_ARTIFICIAL (decl
) = 1;
2337 make_decl_rtl (decl
, 0);
2338 pushdecl_top_level (decl
);
2345 objc_declare_alias (alias_ident
, class_ident
)
2349 if (is_class_name (class_ident
) != class_ident
)
2350 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2351 else if (is_class_name (alias_ident
))
2352 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2354 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2358 objc_declare_class (ident_list
)
2363 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2365 tree ident
= TREE_VALUE (list
);
2368 if ((decl
= lookup_name (ident
)))
2370 error ("`%s' redeclared as different kind of symbol",
2371 IDENTIFIER_POINTER (ident
));
2372 error_with_decl (decl
, "previous declaration of `%s'");
2375 if (! is_class_name (ident
))
2377 tree record
= xref_tag (RECORD_TYPE
, ident
);
2378 TREE_STATIC_TEMPLATE (record
) = 1;
2379 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2385 is_class_name (ident
)
2390 if (lookup_interface (ident
))
2393 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2395 if (ident
== TREE_VALUE (chain
))
2399 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2401 if (ident
== TREE_VALUE (chain
))
2402 return TREE_PURPOSE (chain
);
2412 /* NB: This function may be called before the ObjC front-end
2413 has been initialized, in which case ID_TYPE will be NULL. */
2414 return (id_type
&& ident
&& TYPE_P (ident
) && IS_ID (ident
))
2420 lookup_interface (ident
)
2425 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2427 if (ident
== CLASS_NAME (chain
))
2433 /* Used by: build_private_template, continue_class,
2434 and for @defs constructs. */
2437 get_class_ivars (interface
)
2440 tree my_name
, super_name
, ivar_chain
;
2442 my_name
= CLASS_NAME (interface
);
2443 super_name
= CLASS_SUPER_NAME (interface
);
2444 ivar_chain
= CLASS_IVARS (interface
);
2446 /* Save off a pristine copy of the leaf ivars (i.e, those not
2447 inherited from a super class). */
2448 if (!CLASS_OWN_IVARS (interface
))
2449 CLASS_OWN_IVARS (interface
) = copy_list (ivar_chain
);
2454 tree super_interface
= lookup_interface (super_name
);
2456 if (!super_interface
)
2458 /* fatal did not work with 2 args...should fix */
2459 error ("cannot find interface declaration for `%s', superclass of `%s'",
2460 IDENTIFIER_POINTER (super_name
),
2461 IDENTIFIER_POINTER (my_name
));
2462 exit (FATAL_EXIT_CODE
);
2465 if (super_interface
== interface
)
2466 fatal_error ("circular inheritance in interface declaration for `%s'",
2467 IDENTIFIER_POINTER (super_name
));
2469 interface
= super_interface
;
2470 my_name
= CLASS_NAME (interface
);
2471 super_name
= CLASS_SUPER_NAME (interface
);
2473 op1
= CLASS_OWN_IVARS (interface
);
2476 tree head
= copy_list (op1
);
2478 /* Prepend super class ivars...make a copy of the list, we
2479 do not want to alter the original. */
2480 chainon (head
, ivar_chain
);
2487 /* struct <classname> {
2488 struct objc_class *isa;
2493 build_private_template (class)
2498 if (CLASS_STATIC_TEMPLATE (class))
2500 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2501 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2505 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2507 ivar_context
= get_class_ivars (class);
2509 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2511 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2513 /* mark this record as class template - for class type checking */
2514 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2518 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2520 build1 (INDIRECT_REF
, NULL_TREE
,
2523 return ivar_context
;
2526 /* Begin code generation for protocols... */
2528 /* struct objc_protocol {
2529 char *protocol_name;
2530 struct objc_protocol **protocol_list;
2531 struct objc_method_desc *instance_methods;
2532 struct objc_method_desc *class_methods;
2536 build_protocol_template ()
2538 tree decl_specs
, field_decl
, field_decl_chain
;
2541 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2543 /* struct objc_class *isa; */
2545 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2546 get_identifier (UTAG_CLASS
)));
2547 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2548 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
2549 field_decl_chain
= field_decl
;
2551 /* char *protocol_name; */
2553 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2555 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2556 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
2557 chainon (field_decl_chain
, field_decl
);
2559 /* struct objc_protocol **protocol_list; */
2561 decl_specs
= build_tree_list (NULL_TREE
, template);
2563 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2564 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2565 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
2566 chainon (field_decl_chain
, field_decl
);
2568 /* struct objc_method_list *instance_methods; */
2571 = build_tree_list (NULL_TREE
,
2572 xref_tag (RECORD_TYPE
,
2573 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2575 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2576 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
2577 chainon (field_decl_chain
, field_decl
);
2579 /* struct objc_method_list *class_methods; */
2582 = build_tree_list (NULL_TREE
,
2583 xref_tag (RECORD_TYPE
,
2584 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2586 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2587 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
2588 chainon (field_decl_chain
, field_decl
);
2590 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2594 build_descriptor_table_initializer (type
, entries
)
2598 tree initlist
= NULL_TREE
;
2602 tree eltlist
= NULL_TREE
;
2605 = tree_cons (NULL_TREE
,
2606 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2608 = tree_cons (NULL_TREE
,
2609 add_objc_string (METHOD_ENCODING (entries
),
2614 = tree_cons (NULL_TREE
,
2615 objc_build_constructor (type
, nreverse (eltlist
)),
2618 entries
= TREE_CHAIN (entries
);
2622 return objc_build_constructor (build_array_type (type
, 0),
2623 nreverse (initlist
));
2626 /* struct objc_method_prototype_list {
2628 struct objc_method_prototype {
2635 build_method_prototype_list_template (list_type
, size
)
2639 tree objc_ivar_list_record
;
2640 tree decl_specs
, field_decl
, field_decl_chain
;
2642 /* Generate an unnamed struct definition. */
2644 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2646 /* int method_count; */
2648 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2649 field_decl
= get_identifier ("method_count");
2650 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
2651 field_decl_chain
= field_decl
;
2653 /* struct objc_method method_list[]; */
2655 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2656 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2657 build_int_2 (size
, 0));
2658 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
2659 chainon (field_decl_chain
, field_decl
);
2661 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2663 return objc_ivar_list_record
;
2667 build_method_prototype_template ()
2670 tree decl_specs
, field_decl
, field_decl_chain
;
2673 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2675 /* struct objc_selector *_cmd; */
2676 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2677 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2678 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2679 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
2680 field_decl_chain
= field_decl
;
2682 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2684 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2685 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
2686 chainon (field_decl_chain
, field_decl
);
2688 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2690 return proto_record
;
2693 /* True if last call to forwarding_offset yielded a register offset. */
2694 static int offset_is_register
;
2697 forwarding_offset (parm
)
2700 int offset_in_bytes
;
2702 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2704 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2706 /* ??? Here we assume that the parm address is indexed
2707 off the frame pointer or arg pointer.
2708 If that is not true, we produce meaningless results,
2709 but do not crash. */
2710 if (GET_CODE (addr
) == PLUS
2711 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2712 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2714 offset_in_bytes
= 0;
2716 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2717 offset_is_register
= 0;
2719 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2721 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2722 offset_in_bytes
= apply_args_register_offset (regno
);
2723 offset_is_register
= 1;
2728 /* This is the case where the parm is passed as an int or double
2729 and it is converted to a char, short or float and stored back
2730 in the parmlist. In this case, describe the parm
2731 with the variable's declared type, and adjust the address
2732 if the least significant bytes (which we are using) are not
2734 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2735 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2736 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2738 return offset_in_bytes
;
2742 encode_method_prototype (method_decl
, func_decl
)
2749 HOST_WIDE_INT max_parm_end
= 0;
2753 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2754 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2757 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2758 obstack_object_size (&util_obstack
),
2759 OBJC_ENCODE_INLINE_DEFS
);
2762 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2763 parms
= TREE_CHAIN (parms
))
2765 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2766 + int_size_in_bytes (TREE_TYPE (parms
)));
2768 if (!offset_is_register
&& max_parm_end
< parm_end
)
2769 max_parm_end
= parm_end
;
2772 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2774 sprintf (buf
, "%d", stack_size
);
2775 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2777 user_args
= METHOD_SEL_ARGS (method_decl
);
2779 /* Argument types. */
2780 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2781 parms
= TREE_CHAIN (parms
), i
++)
2783 /* Process argument qualifiers for user supplied arguments. */
2786 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2787 user_args
= TREE_CHAIN (user_args
);
2791 encode_type (TREE_TYPE (parms
),
2792 obstack_object_size (&util_obstack
),
2793 OBJC_ENCODE_INLINE_DEFS
);
2795 /* Compute offset. */
2796 sprintf (buf
, "%d", forwarding_offset (parms
));
2798 /* Indicate register. */
2799 if (offset_is_register
)
2800 obstack_1grow (&util_obstack
, '+');
2802 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2805 obstack_1grow (&util_obstack
, '\0');
2806 result
= get_identifier (obstack_finish (&util_obstack
));
2807 obstack_free (&util_obstack
, util_firstobj
);
2812 generate_descriptor_table (type
, name
, size
, list
, proto
)
2819 tree sc_spec
, decl_specs
, decl
, initlist
;
2821 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2822 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2824 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2825 decl_specs
, 1, NULL_TREE
);
2826 DECL_CONTEXT (decl
) = NULL_TREE
;
2828 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2829 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2831 finish_decl (decl
, objc_build_constructor (type
, nreverse (initlist
)),
2838 generate_method_descriptors (protocol
)
2841 tree initlist
, chain
, method_list_template
;
2842 tree cast
, variable_length_type
;
2845 if (!objc_method_prototype_template
)
2846 objc_method_prototype_template
= build_method_prototype_template ();
2848 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2849 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2851 variable_length_type
= groktypename (cast
);
2853 chain
= PROTOCOL_CLS_METHODS (protocol
);
2856 size
= list_length (chain
);
2858 method_list_template
2859 = build_method_prototype_list_template (objc_method_prototype_template
,
2863 = build_descriptor_table_initializer (objc_method_prototype_template
,
2866 UOBJC_CLASS_METHODS_decl
2867 = generate_descriptor_table (method_list_template
,
2868 "_OBJC_PROTOCOL_CLASS_METHODS",
2869 size
, initlist
, protocol
);
2870 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2873 UOBJC_CLASS_METHODS_decl
= 0;
2875 chain
= PROTOCOL_NST_METHODS (protocol
);
2878 size
= list_length (chain
);
2880 method_list_template
2881 = build_method_prototype_list_template (objc_method_prototype_template
,
2884 = build_descriptor_table_initializer (objc_method_prototype_template
,
2887 UOBJC_INSTANCE_METHODS_decl
2888 = generate_descriptor_table (method_list_template
,
2889 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2890 size
, initlist
, protocol
);
2891 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2894 UOBJC_INSTANCE_METHODS_decl
= 0;
2897 /* Generate a temporary FUNCTION_DECL node to be used in
2898 hack_method_prototype below. */
2900 static GTY(()) int build_tmp_function_decl_xxx
;
2902 build_tmp_function_decl ()
2904 tree decl_specs
, expr_decl
, parms
;
2908 /* struct objc_object *objc_xxx (id, SEL, ...); */
2910 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2911 push_parm_decl (build_tree_list
2912 (build_tree_list (decl_specs
,
2913 build1 (INDIRECT_REF
, NULL_TREE
,
2917 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2918 get_identifier (TAG_SELECTOR
)));
2919 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2921 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2923 parms
= get_parm_info (0);
2926 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2927 sprintf (buffer
, "__objc_tmp_%x", build_tmp_function_decl_xxx
++);
2928 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2929 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
2931 tmp_decl
= define_decl (expr_decl
, decl_specs
);
2932 DECL_SOURCE_LINE (tmp_decl
) = 0;
2937 /* Generate the prototypes for protocol methods. This is used to
2938 generate method encodings for these.
2940 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2941 a decl node to be used. This is also where the return value is
2945 hack_method_prototype (nst_methods
, tmp_decl
)
2952 /* Hack to avoid problem with static typing of self arg. */
2953 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2954 start_method_def (nst_methods
);
2955 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2957 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
2958 parms
= get_parm_info (0); /* we have a `, ...' */
2960 parms
= get_parm_info (1); /* place a `void_at_end' */
2962 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2964 /* Usually called from store_parm_decls -> init_function_start. */
2966 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2968 if (current_function_decl
)
2970 current_function_decl
= tmp_decl
;
2973 /* Code taken from start_function. */
2974 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2975 /* Promote the value to int before returning it. */
2976 if (TREE_CODE (restype
) == INTEGER_TYPE
2977 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
2978 restype
= integer_type_node
;
2979 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
2982 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
2983 DECL_CONTEXT (parm
) = tmp_decl
;
2985 init_function_start (tmp_decl
);
2987 /* Typically called from expand_function_start for function definitions. */
2988 assign_parms (tmp_decl
);
2990 /* install return type */
2991 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
2993 current_function_decl
= NULL
;
2997 generate_protocol_references (plist
)
3002 /* Forward declare protocols referenced. */
3003 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3005 tree proto
= TREE_VALUE (lproto
);
3007 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3008 && PROTOCOL_NAME (proto
))
3010 if (! PROTOCOL_FORWARD_DECL (proto
))
3011 build_protocol_reference (proto
);
3013 if (PROTOCOL_LIST (proto
))
3014 generate_protocol_references (PROTOCOL_LIST (proto
));
3019 /* For each protocol which was referenced either from a @protocol()
3020 expression, or because a class/category implements it (then a
3021 pointer to the protocol is stored in the struct describing the
3022 class/category), we create a statically allocated instance of the
3023 Protocol class. The code is written in such a way as to generate
3024 as few Protocol objects as possible; we generate a unique Protocol
3025 instance for each protocol, and we don't generate a Protocol
3026 instance if the protocol is never referenced (either from a
3027 @protocol() or from a class/category implementation). These
3028 statically allocated objects can be referred to via the static
3029 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3031 The statically allocated Protocol objects that we generate here
3032 need to be fixed up at runtime in order to be used: the 'isa'
3033 pointer of the objects need to be set up to point to the 'Protocol'
3034 class, as known at runtime.
3036 The NeXT runtime fixes up all protocols at program startup time,
3037 before main() is entered. It uses a low-level trick to look up all
3038 those symbols, then loops on them and fixes them up.
3040 The GNU runtime as well fixes up all protocols before user code
3041 from the module is executed; it requires pointers to those symbols
3042 to be put in the objc_symtab (which is then passed as argument to
3043 the function __objc_exec_class() which the compiler sets up to be
3044 executed automatically when the module is loaded); setup of those
3045 Protocol objects happen in two ways in the GNU runtime: all
3046 Protocol objects referred to by a class or category implementation
3047 are fixed up when the class/category is loaded; all Protocol
3048 objects referred to by a @protocol() expression are added by the
3049 compiler to the list of statically allocated instances to fixup
3050 (the same list holding the statically allocated constant string
3051 objects). Because, as explained above, the compiler generates as
3052 few Protocol objects as possible, some Protocol object might end up
3053 being referenced multiple times when compiled with the GNU runtime,
3054 and end up being fixed up multiple times at runtime inizialization.
3055 But that doesn't hurt, it's just a little inefficient. */
3057 generate_protocols ()
3059 tree p
, tmp_decl
, encoding
;
3060 tree sc_spec
, decl_specs
, decl
;
3061 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3064 tmp_decl
= build_tmp_function_decl ();
3066 if (! objc_protocol_template
)
3067 objc_protocol_template
= build_protocol_template ();
3069 /* If a protocol was directly referenced, pull in indirect references. */
3070 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3071 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3072 generate_protocol_references (PROTOCOL_LIST (p
));
3074 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3076 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3077 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3079 /* If protocol wasn't referenced, don't generate any code. */
3080 if (! PROTOCOL_FORWARD_DECL (p
))
3083 /* Make sure we link in the Protocol class. */
3084 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3088 if (! METHOD_ENCODING (nst_methods
))
3090 hack_method_prototype (nst_methods
, tmp_decl
);
3091 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3092 METHOD_ENCODING (nst_methods
) = encoding
;
3094 nst_methods
= TREE_CHAIN (nst_methods
);
3099 if (! METHOD_ENCODING (cls_methods
))
3101 hack_method_prototype (cls_methods
, tmp_decl
);
3102 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3103 METHOD_ENCODING (cls_methods
) = encoding
;
3106 cls_methods
= TREE_CHAIN (cls_methods
);
3108 generate_method_descriptors (p
);
3110 if (PROTOCOL_LIST (p
))
3111 refs_decl
= generate_protocol_list (p
);
3115 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3117 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3119 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3121 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3122 decl_specs
, 1, NULL_TREE
);
3124 DECL_CONTEXT (decl
) = NULL_TREE
;
3126 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3132 (build_tree_list (build_tree_list (NULL_TREE
,
3133 objc_protocol_template
),
3134 build1 (INDIRECT_REF
, NULL_TREE
,
3135 build1 (INDIRECT_REF
, NULL_TREE
,
3138 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3139 TREE_TYPE (refs_expr
) = cast_type2
;
3142 refs_expr
= build_int_2 (0, 0);
3144 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3145 by generate_method_descriptors, which is called above. */
3146 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3147 protocol_name_expr
, refs_expr
,
3148 UOBJC_INSTANCE_METHODS_decl
,
3149 UOBJC_CLASS_METHODS_decl
);
3150 finish_decl (decl
, initlist
, NULL_TREE
);
3152 /* Mark the decl as used to avoid "defined but not used" warning. */
3153 TREE_USED (decl
) = 1;
3158 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3159 instance_methods
, class_methods
)
3163 tree instance_methods
;
3166 tree initlist
= NULL_TREE
, expr
;
3169 cast_type
= groktypename
3171 (build_tree_list (NULL_TREE
,
3172 xref_tag (RECORD_TYPE
,
3173 get_identifier (UTAG_CLASS
))),
3174 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3176 /* Filling the "isa" in with one allows the runtime system to
3177 detect that the version change...should remove before final release. */
3179 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3180 TREE_TYPE (expr
) = cast_type
;
3181 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3182 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3183 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3185 if (!instance_methods
)
3186 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3189 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3190 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3194 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3197 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3198 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3201 return objc_build_constructor (type
, nreverse (initlist
));
3204 /* struct objc_category {
3205 char *category_name;
3207 struct objc_method_list *instance_methods;
3208 struct objc_method_list *class_methods;
3209 struct objc_protocol_list *protocols;
3213 build_category_template ()
3215 tree decl_specs
, field_decl
, field_decl_chain
;
3217 objc_category_template
= start_struct (RECORD_TYPE
,
3218 get_identifier (UTAG_CATEGORY
));
3219 /* char *category_name; */
3221 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3223 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3224 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3225 field_decl_chain
= field_decl
;
3227 /* char *class_name; */
3229 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3230 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3231 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3232 chainon (field_decl_chain
, field_decl
);
3234 /* struct objc_method_list *instance_methods; */
3236 decl_specs
= build_tree_list (NULL_TREE
,
3237 xref_tag (RECORD_TYPE
,
3238 get_identifier (UTAG_METHOD_LIST
)));
3240 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3241 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3242 chainon (field_decl_chain
, field_decl
);
3244 /* struct objc_method_list *class_methods; */
3246 decl_specs
= build_tree_list (NULL_TREE
,
3247 xref_tag (RECORD_TYPE
,
3248 get_identifier (UTAG_METHOD_LIST
)));
3250 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3251 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3252 chainon (field_decl_chain
, field_decl
);
3254 /* struct objc_protocol **protocol_list; */
3256 decl_specs
= build_tree_list (NULL_TREE
,
3257 xref_tag (RECORD_TYPE
,
3258 get_identifier (UTAG_PROTOCOL
)));
3260 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3261 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3262 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3263 chainon (field_decl_chain
, field_decl
);
3265 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3268 /* struct objc_selector {
3274 build_selector_template ()
3277 tree decl_specs
, field_decl
, field_decl_chain
;
3279 objc_selector_template
3280 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3284 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3285 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3286 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3287 field_decl_chain
= field_decl
;
3289 /* char *sel_type; */
3291 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3292 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3293 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3294 chainon (field_decl_chain
, field_decl
);
3296 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3299 /* struct objc_class {
3300 struct objc_class *isa;
3301 struct objc_class *super_class;
3306 struct objc_ivar_list *ivars;
3307 struct objc_method_list *methods;
3308 if (flag_next_runtime)
3309 struct objc_cache *cache;
3311 struct sarray *dtable;
3312 struct objc_class *subclass_list;
3313 struct objc_class *sibling_class;
3315 struct objc_protocol_list *protocols;
3316 void *gc_object_type;
3320 build_class_template ()
3322 tree decl_specs
, field_decl
, field_decl_chain
;
3325 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3327 /* struct objc_class *isa; */
3329 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3330 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3331 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3332 field_decl_chain
= field_decl
;
3334 /* struct objc_class *super_class; */
3336 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3338 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3339 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3340 chainon (field_decl_chain
, field_decl
);
3344 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3345 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3346 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3347 chainon (field_decl_chain
, field_decl
);
3351 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3352 field_decl
= get_identifier ("version");
3353 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3354 chainon (field_decl_chain
, field_decl
);
3358 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3359 field_decl
= get_identifier ("info");
3360 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3361 chainon (field_decl_chain
, field_decl
);
3363 /* long instance_size; */
3365 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3366 field_decl
= get_identifier ("instance_size");
3367 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3368 chainon (field_decl_chain
, field_decl
);
3370 /* struct objc_ivar_list *ivars; */
3372 decl_specs
= build_tree_list (NULL_TREE
,
3373 xref_tag (RECORD_TYPE
,
3374 get_identifier (UTAG_IVAR_LIST
)));
3375 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3376 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3377 chainon (field_decl_chain
, field_decl
);
3379 /* struct objc_method_list *methods; */
3381 decl_specs
= build_tree_list (NULL_TREE
,
3382 xref_tag (RECORD_TYPE
,
3383 get_identifier (UTAG_METHOD_LIST
)));
3384 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3385 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3386 chainon (field_decl_chain
, field_decl
);
3388 if (flag_next_runtime
)
3390 /* struct objc_cache *cache; */
3392 decl_specs
= build_tree_list (NULL_TREE
,
3393 xref_tag (RECORD_TYPE
,
3394 get_identifier ("objc_cache")));
3395 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3396 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3397 chainon (field_decl_chain
, field_decl
);
3401 /* struct sarray *dtable; */
3403 decl_specs
= build_tree_list (NULL_TREE
,
3404 xref_tag (RECORD_TYPE
,
3405 get_identifier ("sarray")));
3406 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3407 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3408 chainon (field_decl_chain
, field_decl
);
3410 /* struct objc_class *subclass_list; */
3412 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3414 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3415 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3416 chainon (field_decl_chain
, field_decl
);
3418 /* struct objc_class *sibling_class; */
3420 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3422 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3423 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3424 chainon (field_decl_chain
, field_decl
);
3427 /* struct objc_protocol **protocol_list; */
3429 decl_specs
= build_tree_list (NULL_TREE
,
3430 xref_tag (RECORD_TYPE
,
3431 get_identifier (UTAG_PROTOCOL
)));
3433 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3435 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3436 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3437 chainon (field_decl_chain
, field_decl
);
3441 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3442 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3443 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3444 chainon (field_decl_chain
, field_decl
);
3446 /* void *gc_object_type; */
3448 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3449 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3450 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3451 chainon (field_decl_chain
, field_decl
);
3453 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3456 /* Generate appropriate forward declarations for an implementation. */
3459 synth_forward_declarations ()
3461 tree sc_spec
, decl_specs
, an_id
;
3463 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3465 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context
);
3467 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3468 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3469 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3470 TREE_USED (UOBJC_CLASS_decl
) = 1;
3471 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3473 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3475 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3476 objc_implementation_context
);
3478 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3479 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3480 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3482 /* Pre-build the following entities - for speed/convenience. */
3484 an_id
= get_identifier ("super_class");
3485 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3486 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3490 error_with_ivar (message
, decl
, rawdecl
)
3491 const char *message
;
3495 error ("%H%s `%s'", &DECL_SOURCE_LOCATION (decl
),
3496 message
, gen_declaration (rawdecl
, errbuf
));
3501 check_ivars (inter
, imp
)
3505 tree intdecls
= CLASS_IVARS (inter
);
3506 tree impdecls
= CLASS_IVARS (imp
);
3507 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3508 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3514 if (intdecls
== 0 && impdecls
== 0)
3516 if (intdecls
== 0 || impdecls
== 0)
3518 error ("inconsistent instance variable specification");
3522 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3524 if (!comptypes (t1
, t2
))
3526 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3528 error_with_ivar ("conflicting instance variable type",
3529 impdecls
, rawimpdecls
);
3530 error_with_ivar ("previous declaration of",
3531 intdecls
, rawintdecls
);
3533 else /* both the type and the name don't match */
3535 error ("inconsistent instance variable specification");
3540 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3542 error_with_ivar ("conflicting instance variable name",
3543 impdecls
, rawimpdecls
);
3544 error_with_ivar ("previous declaration of",
3545 intdecls
, rawintdecls
);
3548 intdecls
= TREE_CHAIN (intdecls
);
3549 impdecls
= TREE_CHAIN (impdecls
);
3550 rawintdecls
= TREE_CHAIN (rawintdecls
);
3551 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3555 /* Set super_type to the data type node for struct objc_super *,
3556 first defining struct objc_super itself.
3557 This needs to be done just once per compilation. */
3560 build_super_template ()
3562 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3564 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3566 /* struct objc_object *self; */
3568 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3569 field_decl
= get_identifier ("self");
3570 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3571 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3572 field_decl_chain
= field_decl
;
3574 /* struct objc_class *class; */
3576 decl_specs
= get_identifier (UTAG_CLASS
);
3577 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3578 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3580 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3581 chainon (field_decl_chain
, field_decl
);
3583 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3585 /* `struct objc_super *' */
3586 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3588 build1 (INDIRECT_REF
,
3589 NULL_TREE
, NULL_TREE
)));
3593 /* struct objc_ivar {
3600 build_ivar_template ()
3602 tree objc_ivar_id
, objc_ivar_record
;
3603 tree decl_specs
, field_decl
, field_decl_chain
;
3605 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3606 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3608 /* char *ivar_name; */
3610 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3611 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3613 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3614 field_decl_chain
= field_decl
;
3616 /* char *ivar_type; */
3618 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3619 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3621 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3622 chainon (field_decl_chain
, field_decl
);
3624 /* int ivar_offset; */
3626 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3627 field_decl
= get_identifier ("ivar_offset");
3629 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3630 chainon (field_decl_chain
, field_decl
);
3632 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3634 return objc_ivar_record
;
3639 struct objc_ivar ivar_list[ivar_count];
3643 build_ivar_list_template (list_type
, size
)
3647 tree objc_ivar_list_record
;
3648 tree decl_specs
, field_decl
, field_decl_chain
;
3650 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3652 /* int ivar_count; */
3654 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3655 field_decl
= get_identifier ("ivar_count");
3657 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3658 field_decl_chain
= field_decl
;
3660 /* struct objc_ivar ivar_list[]; */
3662 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3663 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3664 build_int_2 (size
, 0));
3666 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3667 chainon (field_decl_chain
, field_decl
);
3669 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3671 return objc_ivar_list_record
;
3677 struct objc_method method_list[method_count];
3681 build_method_list_template (list_type
, size
)
3685 tree objc_ivar_list_record
;
3686 tree decl_specs
, field_decl
, field_decl_chain
;
3688 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3690 /* int method_next; */
3695 xref_tag (RECORD_TYPE
,
3696 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3698 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3699 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3700 field_decl_chain
= field_decl
;
3702 /* int method_count; */
3704 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3705 field_decl
= get_identifier ("method_count");
3707 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3708 chainon (field_decl_chain
, field_decl
);
3710 /* struct objc_method method_list[]; */
3712 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3713 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3714 build_int_2 (size
, 0));
3716 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3717 chainon (field_decl_chain
, field_decl
);
3719 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3721 return objc_ivar_list_record
;
3725 build_ivar_list_initializer (type
, field_decl
)
3729 tree initlist
= NULL_TREE
;
3733 tree ivar
= NULL_TREE
;
3736 if (DECL_NAME (field_decl
))
3737 ivar
= tree_cons (NULL_TREE
,
3738 add_objc_string (DECL_NAME (field_decl
),
3742 /* Unnamed bit-field ivar (yuck). */
3743 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3746 encode_field_decl (field_decl
,
3747 obstack_object_size (&util_obstack
),
3748 OBJC_ENCODE_DONT_INLINE_DEFS
);
3750 /* Null terminate string. */
3751 obstack_1grow (&util_obstack
, 0);
3755 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3758 obstack_free (&util_obstack
, util_firstobj
);
3761 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3762 initlist
= tree_cons (NULL_TREE
,
3763 objc_build_constructor (type
, nreverse (ivar
)),
3766 field_decl
= TREE_CHAIN (field_decl
);
3770 return objc_build_constructor (build_array_type (type
, 0),
3771 nreverse (initlist
));
3775 generate_ivars_list (type
, name
, size
, list
)
3781 tree sc_spec
, decl_specs
, decl
, initlist
;
3783 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3784 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3786 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3787 decl_specs
, 1, NULL_TREE
);
3789 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3790 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3793 objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3800 generate_ivar_lists ()
3802 tree initlist
, ivar_list_template
, chain
;
3803 tree cast
, variable_length_type
;
3806 generating_instance_variables
= 1;
3808 if (!objc_ivar_template
)
3809 objc_ivar_template
= build_ivar_template ();
3813 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3814 get_identifier (UTAG_IVAR_LIST
))),
3816 variable_length_type
= groktypename (cast
);
3818 /* Only generate class variables for the root of the inheritance
3819 hierarchy since these will be the same for every class. */
3821 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3822 && (chain
= TYPE_FIELDS (objc_class_template
)))
3824 size
= list_length (chain
);
3826 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3827 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3829 UOBJC_CLASS_VARIABLES_decl
3830 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3832 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3835 UOBJC_CLASS_VARIABLES_decl
= 0;
3837 chain
= CLASS_IVARS (implementation_template
);
3840 size
= list_length (chain
);
3841 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3842 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3844 UOBJC_INSTANCE_VARIABLES_decl
3845 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3847 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3850 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3852 generating_instance_variables
= 0;
3856 build_dispatch_table_initializer (type
, entries
)
3860 tree initlist
= NULL_TREE
;
3864 tree elemlist
= NULL_TREE
;
3866 elemlist
= tree_cons (NULL_TREE
,
3867 build_selector (METHOD_SEL_NAME (entries
)),
3870 /* Generate the method encoding if we don't have one already. */
3871 if (! METHOD_ENCODING (entries
))
3872 METHOD_ENCODING (entries
) =
3873 encode_method_def (METHOD_DEFINITION (entries
));
3875 elemlist
= tree_cons (NULL_TREE
,
3876 add_objc_string (METHOD_ENCODING (entries
),
3880 elemlist
= tree_cons (NULL_TREE
,
3881 build_unary_op (ADDR_EXPR
,
3882 METHOD_DEFINITION (entries
), 1),
3885 initlist
= tree_cons (NULL_TREE
,
3886 objc_build_constructor (type
, nreverse (elemlist
)),
3889 entries
= TREE_CHAIN (entries
);
3893 return objc_build_constructor (build_array_type (type
, 0),
3894 nreverse (initlist
));
3897 /* To accomplish method prototyping without generating all kinds of
3898 inane warnings, the definition of the dispatch table entries were
3901 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3903 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3906 build_method_template ()
3909 tree decl_specs
, field_decl
, field_decl_chain
;
3911 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3913 /* struct objc_selector *_cmd; */
3914 decl_specs
= tree_cons (NULL_TREE
,
3915 xref_tag (RECORD_TYPE
,
3916 get_identifier (TAG_SELECTOR
)),
3918 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3920 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3921 field_decl_chain
= field_decl
;
3923 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3924 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3925 get_identifier ("method_types"));
3926 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3927 chainon (field_decl_chain
, field_decl
);
3931 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
3932 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
3933 field_decl
= grokfield (field_decl
, decl_specs
, NULL_TREE
);
3934 chainon (field_decl_chain
, field_decl
);
3936 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
3943 generate_dispatch_table (type
, name
, size
, list
)
3949 tree sc_spec
, decl_specs
, decl
, initlist
;
3951 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3952 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3954 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3955 decl_specs
, 1, NULL_TREE
);
3957 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
3958 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
3959 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3962 objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3969 mark_referenced_methods ()
3971 struct imp_entry
*impent
;
3974 for (impent
= imp_list
; impent
; impent
= impent
->next
)
3976 chain
= CLASS_CLS_METHODS (impent
->imp_context
);
3979 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)), 1);
3980 chain
= TREE_CHAIN (chain
);
3982 chain
= CLASS_NST_METHODS (impent
->imp_context
);
3985 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)), 1);
3986 chain
= TREE_CHAIN (chain
);
3992 generate_dispatch_tables ()
3994 tree initlist
, chain
, method_list_template
;
3995 tree cast
, variable_length_type
;
3998 if (!objc_method_template
)
3999 objc_method_template
= build_method_template ();
4003 (build_tree_list (NULL_TREE
,
4004 xref_tag (RECORD_TYPE
,
4005 get_identifier (UTAG_METHOD_LIST
))),
4008 variable_length_type
= groktypename (cast
);
4010 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
4013 size
= list_length (chain
);
4015 method_list_template
4016 = build_method_list_template (objc_method_template
, size
);
4018 = build_dispatch_table_initializer (objc_method_template
, chain
);
4020 UOBJC_CLASS_METHODS_decl
4021 = generate_dispatch_table (method_list_template
,
4022 ((TREE_CODE (objc_implementation_context
)
4023 == CLASS_IMPLEMENTATION_TYPE
)
4024 ? "_OBJC_CLASS_METHODS"
4025 : "_OBJC_CATEGORY_CLASS_METHODS"),
4027 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4030 UOBJC_CLASS_METHODS_decl
= 0;
4032 chain
= CLASS_NST_METHODS (objc_implementation_context
);
4035 size
= list_length (chain
);
4037 method_list_template
4038 = build_method_list_template (objc_method_template
, size
);
4040 = build_dispatch_table_initializer (objc_method_template
, chain
);
4042 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4043 UOBJC_INSTANCE_METHODS_decl
4044 = generate_dispatch_table (method_list_template
,
4045 "_OBJC_INSTANCE_METHODS",
4048 /* We have a category. */
4049 UOBJC_INSTANCE_METHODS_decl
4050 = generate_dispatch_table (method_list_template
,
4051 "_OBJC_CATEGORY_INSTANCE_METHODS",
4053 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4056 UOBJC_INSTANCE_METHODS_decl
= 0;
4060 generate_protocol_list (i_or_p
)
4063 tree initlist
, decl_specs
, sc_spec
;
4064 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4068 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4069 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4070 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4071 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4072 plist
= PROTOCOL_LIST (i_or_p
);
4076 cast_type
= groktypename
4078 (build_tree_list (NULL_TREE
,
4079 xref_tag (RECORD_TYPE
,
4080 get_identifier (UTAG_PROTOCOL
))),
4081 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4084 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4085 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4086 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4089 /* Build initializer. */
4090 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4092 e
= build_int_2 (size
, 0);
4093 TREE_TYPE (e
) = cast_type
;
4094 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4096 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4098 tree pval
= TREE_VALUE (lproto
);
4100 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4101 && PROTOCOL_FORWARD_DECL (pval
))
4103 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4104 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4108 /* static struct objc_protocol *refs[n]; */
4110 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4111 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4112 get_identifier (UTAG_PROTOCOL
)),
4115 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4116 expr_decl
= build_nt (ARRAY_REF
,
4117 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4119 build_int_2 (size
+ 2, 0));
4120 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4121 expr_decl
= build_nt (ARRAY_REF
,
4122 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4124 build_int_2 (size
+ 2, 0));
4125 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4127 = build_nt (ARRAY_REF
,
4128 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4130 build_int_2 (size
+ 2, 0));
4134 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4136 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4137 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4139 finish_decl (refs_decl
, objc_build_constructor (TREE_TYPE (refs_decl
),
4140 nreverse (initlist
)),
4147 build_category_initializer (type
, cat_name
, class_name
,
4148 instance_methods
, class_methods
, protocol_list
)
4152 tree instance_methods
;
4156 tree initlist
= NULL_TREE
, expr
;
4158 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4159 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4161 if (!instance_methods
)
4162 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4165 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4166 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4169 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4172 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4173 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4176 /* protocol_list = */
4178 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4181 tree cast_type2
= groktypename
4183 (build_tree_list (NULL_TREE
,
4184 xref_tag (RECORD_TYPE
,
4185 get_identifier (UTAG_PROTOCOL
))),
4186 build1 (INDIRECT_REF
, NULL_TREE
,
4187 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4189 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4190 TREE_TYPE (expr
) = cast_type2
;
4191 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4194 return objc_build_constructor (type
, nreverse (initlist
));
4197 /* struct objc_class {
4198 struct objc_class *isa;
4199 struct objc_class *super_class;
4204 struct objc_ivar_list *ivars;
4205 struct objc_method_list *methods;
4206 if (flag_next_runtime)
4207 struct objc_cache *cache;
4209 struct sarray *dtable;
4210 struct objc_class *subclass_list;
4211 struct objc_class *sibling_class;
4213 struct objc_protocol_list *protocols;
4214 void *gc_object_type;
4218 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4219 dispatch_table
, ivar_list
, protocol_list
)
4226 tree dispatch_table
;
4230 tree initlist
= NULL_TREE
, expr
;
4233 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4236 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4239 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4242 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4245 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4247 /* instance_size = */
4248 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4250 /* objc_ivar_list = */
4252 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4255 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4256 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4259 /* objc_method_list = */
4260 if (!dispatch_table
)
4261 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4264 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4265 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4268 if (flag_next_runtime
)
4269 /* method_cache = */
4270 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4274 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4276 /* subclass_list = */
4277 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4279 /* sibling_class = */
4280 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4283 /* protocol_list = */
4284 if (! protocol_list
)
4285 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4291 (build_tree_list (NULL_TREE
,
4292 xref_tag (RECORD_TYPE
,
4293 get_identifier (UTAG_PROTOCOL
))),
4294 build1 (INDIRECT_REF
, NULL_TREE
,
4295 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4297 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4298 TREE_TYPE (expr
) = cast_type2
;
4299 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4302 /* gc_object_type = NULL */
4303 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4305 return objc_build_constructor (type
, nreverse (initlist
));
4308 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4311 generate_category (cat
)
4314 tree sc_spec
, decl_specs
, decl
;
4315 tree initlist
, cat_name_expr
, class_name_expr
;
4316 tree protocol_decl
, category
;
4318 add_class_reference (CLASS_NAME (cat
));
4319 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4321 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4323 category
= CLASS_CATEGORY_LIST (implementation_template
);
4325 /* find the category interface from the class it is associated with */
4328 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4330 category
= CLASS_CATEGORY_LIST (category
);
4333 if (category
&& CLASS_PROTOCOL_LIST (category
))
4335 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4336 protocol_decl
= generate_protocol_list (category
);
4341 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4342 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4344 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4345 objc_implementation_context
),
4346 decl_specs
, 1, NULL_TREE
);
4348 initlist
= build_category_initializer (TREE_TYPE (decl
),
4349 cat_name_expr
, class_name_expr
,
4350 UOBJC_INSTANCE_METHODS_decl
,
4351 UOBJC_CLASS_METHODS_decl
,
4354 TREE_USED (decl
) = 1;
4355 finish_decl (decl
, initlist
, NULL_TREE
);
4358 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4359 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4362 generate_shared_structures ()
4364 tree sc_spec
, decl_specs
, decl
;
4365 tree name_expr
, super_expr
, root_expr
;
4366 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4367 tree cast_type
, initlist
, protocol_decl
;
4369 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4372 add_class_reference (my_super_id
);
4374 /* Compute "my_root_id" - this is required for code generation.
4375 the "isa" for all meta class structures points to the root of
4376 the inheritance hierarchy (e.g. "__Object")... */
4377 my_root_id
= my_super_id
;
4380 tree my_root_int
= lookup_interface (my_root_id
);
4382 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4383 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4390 /* No super class. */
4391 my_root_id
= CLASS_NAME (implementation_template
);
4394 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4395 objc_class_template
),
4396 build1 (INDIRECT_REF
,
4397 NULL_TREE
, NULL_TREE
)));
4399 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4402 /* Install class `isa' and `super' pointers at runtime. */
4405 super_expr
= add_objc_string (my_super_id
, class_names
);
4406 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4409 super_expr
= build_int_2 (0, 0);
4411 root_expr
= add_objc_string (my_root_id
, class_names
);
4412 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4414 if (CLASS_PROTOCOL_LIST (implementation_template
))
4416 generate_protocol_references
4417 (CLASS_PROTOCOL_LIST (implementation_template
));
4418 protocol_decl
= generate_protocol_list (implementation_template
);
4423 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4425 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4426 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4428 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4432 = build_shared_structure_initializer
4434 root_expr
, super_expr
, name_expr
,
4435 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4437 UOBJC_CLASS_METHODS_decl
,
4438 UOBJC_CLASS_VARIABLES_decl
,
4441 finish_decl (decl
, initlist
, NULL_TREE
);
4443 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4445 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4449 = build_shared_structure_initializer
4451 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4452 super_expr
, name_expr
,
4453 convert (integer_type_node
,
4454 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4455 (implementation_template
))),
4457 UOBJC_INSTANCE_METHODS_decl
,
4458 UOBJC_INSTANCE_VARIABLES_decl
,
4461 finish_decl (decl
, initlist
, NULL_TREE
);
4465 synth_id_with_class_suffix (preamble
, ctxt
)
4466 const char *preamble
;
4470 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4471 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4473 const char *const class_name
4474 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4475 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4476 sprintf (string
, "%s_%s", preamble
,
4477 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4479 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4480 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4482 /* We have a category. */
4483 const char *const class_name
4484 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4485 const char *const class_super_name
4486 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
4487 string
= (char *) alloca (strlen (preamble
)
4488 + strlen (class_name
)
4489 + strlen (class_super_name
)
4491 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4493 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4495 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4497 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4498 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4503 return get_identifier (string
);
4507 is_objc_type_qualifier (node
)
4510 return (TREE_CODE (node
) == IDENTIFIER_NODE
4511 && (node
== ridpointers
[(int) RID_CONST
]
4512 || node
== ridpointers
[(int) RID_VOLATILE
]
4513 || node
== ridpointers
[(int) RID_IN
]
4514 || node
== ridpointers
[(int) RID_OUT
]
4515 || node
== ridpointers
[(int) RID_INOUT
]
4516 || node
== ridpointers
[(int) RID_BYCOPY
]
4517 || node
== ridpointers
[(int) RID_BYREF
]
4518 || node
== ridpointers
[(int) RID_ONEWAY
]));
4521 /* If type is empty or only type qualifiers are present, add default
4522 type of id (otherwise grokdeclarator will default to int). */
4525 adjust_type_for_id_default (type
)
4528 tree declspecs
, chain
;
4531 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4532 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4534 declspecs
= TREE_PURPOSE (type
);
4536 /* Determine if a typespec is present. */
4537 for (chain
= declspecs
;
4539 chain
= TREE_CHAIN (chain
))
4541 if (TYPED_OBJECT (TREE_VALUE (chain
))
4542 && !(TREE_VALUE (type
)
4543 && TREE_CODE (TREE_VALUE (type
)) == INDIRECT_REF
))
4544 error ("can not use an object as parameter to a method\n");
4545 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4549 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4551 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4556 selector ':' '(' typename ')' identifier
4559 Transform an Objective-C keyword argument into
4560 the C equivalent parameter declarator.
4562 In: key_name, an "identifier_node" (optional).
4563 arg_type, a "tree_list" (optional).
4564 arg_name, an "identifier_node".
4566 Note: It would be really nice to strongly type the preceding
4567 arguments in the function prototype; however, then I
4568 could not use the "accessor" macros defined in "tree.h".
4570 Out: an instance of "keyword_decl". */
4573 build_keyword_decl (key_name
, arg_type
, arg_name
)
4580 /* If no type is specified, default to "id". */
4581 arg_type
= adjust_type_for_id_default (arg_type
);
4583 keyword_decl
= make_node (KEYWORD_DECL
);
4585 TREE_TYPE (keyword_decl
) = arg_type
;
4586 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4587 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4589 return keyword_decl
;
4592 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4595 build_keyword_selector (selector
)
4599 tree key_chain
, key_name
;
4602 /* Scan the selector to see how much space we'll need. */
4603 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4605 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4606 key_name
= KEYWORD_KEY_NAME (key_chain
);
4607 else if (TREE_CODE (selector
) == TREE_LIST
)
4608 key_name
= TREE_PURPOSE (key_chain
);
4613 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4615 /* Just a ':' arg. */
4619 buf
= (char *) alloca (len
+ 1);
4620 /* Start the buffer out as an empty string. */
4623 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4625 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4626 key_name
= KEYWORD_KEY_NAME (key_chain
);
4627 else if (TREE_CODE (selector
) == TREE_LIST
)
4628 key_name
= TREE_PURPOSE (key_chain
);
4633 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4637 return get_identifier (buf
);
4640 /* Used for declarations and definitions. */
4643 build_method_decl (code
, ret_type
, selector
, add_args
)
4644 enum tree_code code
;
4651 /* If no type is specified, default to "id". */
4652 ret_type
= adjust_type_for_id_default (ret_type
);
4654 method_decl
= make_node (code
);
4655 TREE_TYPE (method_decl
) = ret_type
;
4657 /* If we have a keyword selector, create an identifier_node that
4658 represents the full selector name (`:' included)... */
4659 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4661 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4662 METHOD_SEL_ARGS (method_decl
) = selector
;
4663 METHOD_ADD_ARGS (method_decl
) = add_args
;
4667 METHOD_SEL_NAME (method_decl
) = selector
;
4668 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4669 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4675 #define METHOD_DEF 0
4676 #define METHOD_REF 1
4678 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4679 an argument list for method METH. CONTEXT is either METHOD_DEF or
4680 METHOD_REF, saying whether we are trying to define a method or call
4681 one. SUPERFLAG says this is for a send to super; this makes a
4682 difference for the NeXT calling sequence in which the lookup and
4683 the method call are done together. */
4686 get_arg_type_list (meth
, context
, superflag
)
4693 /* Receiver type. */
4694 if (flag_next_runtime
&& superflag
)
4695 arglist
= build_tree_list (NULL_TREE
, super_type
);
4696 else if (context
== METHOD_DEF
)
4697 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4699 arglist
= build_tree_list (NULL_TREE
, id_type
);
4701 /* Selector type - will eventually change to `int'. */
4702 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4704 /* Build a list of argument types. */
4705 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4707 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4708 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4711 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4712 /* We have a `, ...' immediately following the selector,
4713 finalize the arglist...simulate get_parm_info (0). */
4715 else if (METHOD_ADD_ARGS (meth
))
4717 /* we have a variable length selector */
4718 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4719 chainon (arglist
, add_arg_list
);
4722 /* finalize the arglist...simulate get_parm_info (1) */
4723 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4729 check_duplicates (hsh
)
4732 tree meth
= NULL_TREE
;
4740 /* We have two methods with the same name and different types. */
4742 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4744 warning ("multiple declarations for method `%s'",
4745 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4747 warn_with_method ("using", type
, meth
);
4748 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4749 warn_with_method ("also found", type
, loop
->value
);
4755 /* If RECEIVER is a class reference, return the identifier node for
4756 the referenced class. RECEIVER is created by get_class_reference,
4757 so we check the exact form created depending on which runtimes are
4761 receiver_is_class_object (receiver
)
4764 tree chain
, exp
, arg
;
4766 /* The receiver is 'self' in the context of a class method. */
4767 if (objc_method_context
4768 && receiver
== self_decl
4769 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4771 return CLASS_NAME (objc_implementation_context
);
4774 if (flag_next_runtime
)
4776 /* The receiver is a variable created by
4777 build_class_reference_decl. */
4778 if (TREE_CODE (receiver
) == VAR_DECL
4779 && TREE_TYPE (receiver
) == objc_class_type
)
4780 /* Look up the identifier. */
4781 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4782 if (TREE_PURPOSE (chain
) == receiver
)
4783 return TREE_VALUE (chain
);
4787 /* The receiver is a function call that returns an id. Check if
4788 it is a call to objc_getClass, if so, pick up the class name. */
4789 if (TREE_CODE (receiver
) == CALL_EXPR
4790 && (exp
= TREE_OPERAND (receiver
, 0))
4791 && TREE_CODE (exp
) == ADDR_EXPR
4792 && (exp
= TREE_OPERAND (exp
, 0))
4793 && TREE_CODE (exp
) == FUNCTION_DECL
4794 && exp
== objc_get_class_decl
4795 /* We have a call to objc_getClass! */
4796 && (arg
= TREE_OPERAND (receiver
, 1))
4797 && TREE_CODE (arg
) == TREE_LIST
4798 && (arg
= TREE_VALUE (arg
)))
4801 if (TREE_CODE (arg
) == ADDR_EXPR
4802 && (arg
= TREE_OPERAND (arg
, 0))
4803 && TREE_CODE (arg
) == STRING_CST
)
4804 /* Finally, we have the class name. */
4805 return get_identifier (TREE_STRING_POINTER (arg
));
4811 /* If we are currently building a message expr, this holds
4812 the identifier of the selector of the message. This is
4813 used when printing warnings about argument mismatches. */
4815 static tree current_objc_message_selector
= 0;
4818 objc_message_selector ()
4820 return current_objc_message_selector
;
4823 /* Construct an expression for sending a message.
4824 MESS has the object to send to in TREE_PURPOSE
4825 and the argument list (including selector) in TREE_VALUE.
4827 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4828 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4831 build_message_expr (mess
)
4834 tree receiver
= TREE_PURPOSE (mess
);
4836 tree args
= TREE_VALUE (mess
);
4837 tree method_params
= NULL_TREE
;
4839 if (TREE_CODE (receiver
) == ERROR_MARK
)
4840 return error_mark_node
;
4842 /* Obtain the full selector name. */
4843 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4844 /* A unary selector. */
4846 else if (TREE_CODE (args
) == TREE_LIST
)
4847 sel_name
= build_keyword_selector (args
);
4851 /* Build the parameter list to give to the method. */
4852 if (TREE_CODE (args
) == TREE_LIST
)
4854 tree chain
= args
, prev
= NULL_TREE
;
4856 /* We have a keyword selector--check for comma expressions. */
4859 tree element
= TREE_VALUE (chain
);
4861 /* We have a comma expression, must collapse... */
4862 if (TREE_CODE (element
) == TREE_LIST
)
4865 TREE_CHAIN (prev
) = element
;
4870 chain
= TREE_CHAIN (chain
);
4872 method_params
= args
;
4875 return finish_message_expr (receiver
, sel_name
, method_params
);
4878 /* The 'finish_message_expr' routine is called from within
4879 'build_message_expr' for non-template functions. In the case of
4880 C++ template functions, it is called from 'build_expr_from_tree'
4881 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4884 finish_message_expr (receiver
, sel_name
, method_params
)
4885 tree receiver
, sel_name
, method_params
;
4887 tree method_prototype
= NULL_TREE
, class_ident
= NULL_TREE
;
4888 tree selector
, self_object
, retval
;
4889 int statically_typed
= 0, statically_allocated
= 0;
4891 /* Determine receiver type. */
4892 tree rtype
= TREE_TYPE (receiver
);
4893 int super
= IS_SUPER (rtype
);
4897 if (TREE_STATIC_TEMPLATE (rtype
))
4898 statically_allocated
= 1;
4899 else if (TREE_CODE (rtype
) == POINTER_TYPE
4900 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4901 statically_typed
= 1;
4902 else if ((flag_next_runtime
4904 && (class_ident
= receiver_is_class_object (receiver
)))
4906 else if (! IS_ID (rtype
)
4907 /* Allow any type that matches objc_class_type. */
4908 && ! comptypes (rtype
, objc_class_type
))
4910 warning ("invalid receiver type `%s'",
4911 gen_declaration (rtype
, errbuf
));
4913 if (statically_allocated
)
4914 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4916 /* Don't evaluate the receiver twice. */
4917 receiver
= save_expr (receiver
);
4918 self_object
= receiver
;
4921 /* If sending to `super', use current self as the object. */
4922 self_object
= self_decl
;
4924 /* Determine operation return type. */
4930 if (CLASS_SUPER_NAME (implementation_template
))
4933 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4935 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
4936 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4938 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4940 if (iface
&& !method_prototype
)
4941 warning ("`%s' does not respond to `%s'",
4942 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4943 IDENTIFIER_POINTER (sel_name
));
4947 error ("no super class declared in interface for `%s'",
4948 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4949 return error_mark_node
;
4953 else if (statically_allocated
)
4955 tree ctype
= TREE_TYPE (rtype
);
4956 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4959 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4961 if (! method_prototype
&& ctype
&& TYPE_PROTOCOL_LIST (ctype
))
4963 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4966 if (!method_prototype
)
4967 warning ("`%s' does not respond to `%s'",
4968 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
4969 IDENTIFIER_POINTER (sel_name
));
4971 else if (statically_typed
)
4973 tree ctype
= TREE_TYPE (rtype
);
4975 /* `self' is now statically_typed. All methods should be visible
4976 within the context of the implementation. */
4977 if (objc_implementation_context
4978 && CLASS_NAME (objc_implementation_context
) == TYPE_NAME (ctype
))
4981 = lookup_instance_method_static (implementation_template
,
4984 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4986 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4989 if (! method_prototype
4990 && implementation_template
!= objc_implementation_context
)
4991 /* The method is not published in the interface. Check
4994 = lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
5001 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5002 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5004 if (! method_prototype
)
5006 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5009 = lookup_method_in_protocol_list (protocol_list
,
5014 if (!method_prototype
)
5015 warning ("`%s' does not respond to `%s'",
5016 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5017 IDENTIFIER_POINTER (sel_name
));
5019 else if (class_ident
)
5021 if (objc_implementation_context
5022 && CLASS_NAME (objc_implementation_context
) == class_ident
)
5025 = lookup_class_method_static (implementation_template
, sel_name
);
5027 if (!method_prototype
5028 && implementation_template
!= objc_implementation_context
)
5029 /* The method is not published in the interface. Check
5032 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context
),
5039 if ((iface
= lookup_interface (class_ident
)))
5040 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5043 if (!method_prototype
)
5045 warning ("cannot find class (factory) method");
5046 warning ("return type for `%s' defaults to id",
5047 IDENTIFIER_POINTER (sel_name
));
5050 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5052 /* An anonymous object that has been qualified with a protocol. */
5054 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5056 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5059 if (!method_prototype
)
5063 warning ("method `%s' not implemented by protocol",
5064 IDENTIFIER_POINTER (sel_name
));
5066 /* Try and find the method signature in the global pools. */
5068 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5069 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5071 if (!(method_prototype
= check_duplicates (hsh
)))
5072 warning ("return type defaults to id");
5079 /* We think we have an instance...loophole: extern id Object; */
5080 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5083 /* For various loopholes */
5084 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5086 method_prototype
= check_duplicates (hsh
);
5087 if (!method_prototype
)
5089 warning ("cannot find method");
5090 warning ("return type for `%s' defaults to id",
5091 IDENTIFIER_POINTER (sel_name
));
5095 /* Save the selector name for printing error messages. */
5096 current_objc_message_selector
= sel_name
;
5098 /* Build the parameters list for looking up the method.
5099 These are the object itself and the selector. */
5101 if (flag_typed_selectors
)
5102 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5104 selector
= build_selector_reference (sel_name
);
5106 retval
= build_objc_method_call (super
, method_prototype
,
5107 receiver
, self_object
,
5108 selector
, method_params
);
5110 current_objc_message_selector
= 0;
5115 /* Build a tree expression to send OBJECT the operation SELECTOR,
5116 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5117 assuming the method has prototype METHOD_PROTOTYPE.
5118 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5119 Use METHOD_PARAMS as list of args to pass to the method.
5120 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5123 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5124 selector
, method_params
)
5126 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5128 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5129 tree rcv_p
= (super_flag
5130 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5131 get_identifier (TAG_SUPER
)))
5134 if (flag_next_runtime
)
5136 if (! method_prototype
)
5138 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5139 tree_cons (NULL_TREE
, selector
,
5141 assemble_external (sender
);
5142 return build_function_call (sender
, method_params
);
5146 /* This is a real kludge, but it is used only for the Next.
5147 Clobber the data type of SENDER temporarily to accept
5148 all the arguments for this operation, and to return
5149 whatever this operation returns. */
5150 tree arglist
= NULL_TREE
, retval
, savarg
, savret
;
5151 tree ret_type
= groktypename (TREE_TYPE (method_prototype
));
5153 /* Save the proper contents of SENDER's data type. */
5154 savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5155 savret
= TREE_TYPE (TREE_TYPE (sender
));
5157 /* Install this method's argument types. */
5158 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5160 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5162 /* Install this method's return type. */
5163 TREE_TYPE (TREE_TYPE (sender
)) = ret_type
;
5165 /* Call SENDER with all the parameters. This will do type
5166 checking using the arg types for this method. */
5167 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5168 tree_cons (NULL_TREE
, selector
,
5170 assemble_external (sender
);
5171 retval
= build_function_call (sender
, method_params
);
5173 /* Restore SENDER's return/argument types. */
5174 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5175 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5181 /* This is the portable way.
5182 First call the lookup function to get a pointer to the method,
5183 then cast the pointer, then call it with the method arguments. */
5186 /* Avoid trouble since we may evaluate each of these twice. */
5187 object
= save_expr (object
);
5188 selector
= save_expr (selector
);
5190 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5192 assemble_external (sender
);
5194 = build_function_call (sender
,
5195 tree_cons (NULL_TREE
, lookup_object
,
5196 tree_cons (NULL_TREE
, selector
,
5199 /* If we have a method prototype, construct the data type this
5200 method needs, and cast what we got from SENDER into a pointer
5202 if (method_prototype
)
5204 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5206 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5207 tree fake_function_type
= build_function_type (valtype
, arglist
);
5208 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5212 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5214 /* Pass the object to the method. */
5215 assemble_external (method
);
5216 return build_function_call (method
,
5217 tree_cons (NULL_TREE
, object
,
5218 tree_cons (NULL_TREE
, selector
,
5224 build_protocol_reference (p
)
5227 tree decl
, ident
, ptype
;
5229 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5231 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5233 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5234 objc_protocol_template
),
5237 if (identifier_global_value (ident
))
5238 decl
= identifier_global_value (ident
); /* Set by pushdecl. */
5241 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5242 DECL_EXTERNAL (decl
) = 1;
5243 TREE_PUBLIC (decl
) = 1;
5244 TREE_USED (decl
) = 1;
5245 DECL_ARTIFICIAL (decl
) = 1;
5247 make_decl_rtl (decl
, 0);
5248 pushdecl_top_level (decl
);
5251 PROTOCOL_FORWARD_DECL (p
) = decl
;
5254 /* This function is called by the parser when (and only when) a
5255 @protocol() expression is found, in order to compile it. */
5257 build_protocol_expr (protoname
)
5261 tree p
= lookup_protocol (protoname
);
5265 error ("cannot find protocol declaration for `%s'",
5266 IDENTIFIER_POINTER (protoname
));
5267 return error_mark_node
;
5270 if (!PROTOCOL_FORWARD_DECL (p
))
5271 build_protocol_reference (p
);
5273 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5275 TREE_TYPE (expr
) = protocol_type
;
5277 /* The @protocol() expression is being compiled into a pointer to a
5278 statically allocated instance of the Protocol class. To become
5279 usable at runtime, the 'isa' pointer of the instance need to be
5280 fixed up at runtime by the runtime library, to point to the
5281 actual 'Protocol' class. */
5283 /* For the GNU runtime, put the static Protocol instance in the list
5284 of statically allocated instances, so that we make sure that its
5285 'isa' pointer is fixed up at runtime by the GNU runtime library
5286 to point to the Protocol class (at runtime, when loading the
5287 module, the GNU runtime library loops on the statically allocated
5288 instances (as found in the defs field in objc_symtab) and fixups
5289 all the 'isa' pointers of those objects). */
5290 if (! flag_next_runtime
)
5292 /* This type is a struct containing the fields of a Protocol
5293 object. (Cfr. protocol_type instead is the type of a pointer
5294 to such a struct). */
5295 tree protocol_struct_type
= xref_tag
5296 (RECORD_TYPE
, get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
5299 /* Look for the list of Protocol statically allocated instances
5300 to fixup at runtime. Create a new list to hold Protocol
5301 statically allocated instances, if the list is not found. At
5302 present there is only another list, holding NSConstantString
5303 static instances to be fixed up at runtime. */
5304 for (chain
= &objc_static_instances
;
5305 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
5306 chain
= &TREE_CHAIN (*chain
));
5309 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
5310 add_objc_string (TYPE_NAME (protocol_struct_type
),
5314 /* Add this statically allocated instance to the Protocol list. */
5315 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
5316 PROTOCOL_FORWARD_DECL (p
),
5317 TREE_PURPOSE (*chain
));
5324 /* This function is called by the parser when a @selector() expression
5325 is found, in order to compile it. It is only called by the parser
5326 and only to compile a @selector(). */
5328 build_selector_expr (selnamelist
)
5333 /* Obtain the full selector name. */
5334 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5335 /* A unary selector. */
5336 selname
= selnamelist
;
5337 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5338 selname
= build_keyword_selector (selnamelist
);
5342 /* If we are required to check @selector() expressions as they
5343 are found, check that the selector has been declared. */
5344 if (warn_undeclared_selector
)
5346 /* Look the selector up in the list of all known class and
5347 instance methods (up to this line) to check that the selector
5351 /* First try with instance methods. */
5352 hsh
= hash_lookup (nst_method_hash_list
, selname
);
5354 /* If not found, try with class methods. */
5357 hsh
= hash_lookup (cls_method_hash_list
, selname
);
5360 /* If still not found, print out a warning. */
5363 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname
));
5368 if (flag_typed_selectors
)
5369 return build_typed_selector_reference (selname
, 0);
5371 return build_selector_reference (selname
);
5375 build_encode_expr (type
)
5381 encode_type (type
, obstack_object_size (&util_obstack
),
5382 OBJC_ENCODE_INLINE_DEFS
);
5383 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5384 string
= obstack_finish (&util_obstack
);
5386 /* Synthesize a string that represents the encoded struct/union. */
5387 result
= my_build_string (strlen (string
) + 1, string
);
5388 obstack_free (&util_obstack
, util_firstobj
);
5393 build_ivar_reference (id
)
5396 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5398 /* Historically, a class method that produced objects (factory
5399 method) would assign `self' to the instance that it
5400 allocated. This would effectively turn the class method into
5401 an instance method. Following this assignment, the instance
5402 variables could be accessed. That practice, while safe,
5403 violates the simple rule that a class method should not refer
5404 to an instance variable. It's better to catch the cases
5405 where this is done unknowingly than to support the above
5407 warning ("instance variable `%s' accessed in class method",
5408 IDENTIFIER_POINTER (id
));
5409 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5412 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5415 /* Compute a hash value for a given method SEL_NAME. */
5418 hash_func (sel_name
)
5421 const unsigned char *s
5422 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
5426 h
= h
* 67 + *s
++ - 113;
5433 nst_method_hash_list
= (hash
*) ggc_calloc (SIZEHASHTABLE
, sizeof (hash
));
5434 cls_method_hash_list
= (hash
*) ggc_calloc (SIZEHASHTABLE
, sizeof (hash
));
5437 /* WARNING!!!! hash_enter is called with a method, and will peek
5438 inside to find its selector! But hash_lookup is given a selector
5439 directly, and looks for the selector that's inside the found
5440 entry's key (method) for comparison. */
5443 hash_enter (hashlist
, method
)
5448 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5450 obj
= (hash
) ggc_alloc (sizeof (struct hashed_entry
));
5452 obj
->next
= hashlist
[slot
];
5455 hashlist
[slot
] = obj
; /* append to front */
5459 hash_lookup (hashlist
, sel_name
)
5465 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
5469 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5472 target
= target
->next
;
5478 hash_add_attr (entry
, value
)
5484 obj
= (attr
) ggc_alloc (sizeof (struct hashed_attribute
));
5485 obj
->next
= entry
->list
;
5488 entry
->list
= obj
; /* append to front */
5492 lookup_method (mchain
, method
)
5498 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5501 key
= METHOD_SEL_NAME (method
);
5505 if (METHOD_SEL_NAME (mchain
) == key
)
5508 mchain
= TREE_CHAIN (mchain
);
5514 lookup_instance_method_static (interface
, ident
)
5518 tree inter
= interface
;
5519 tree chain
= CLASS_NST_METHODS (inter
);
5520 tree meth
= NULL_TREE
;
5524 if ((meth
= lookup_method (chain
, ident
)))
5527 if (CLASS_CATEGORY_LIST (inter
))
5529 tree category
= CLASS_CATEGORY_LIST (inter
);
5530 chain
= CLASS_NST_METHODS (category
);
5534 if ((meth
= lookup_method (chain
, ident
)))
5537 /* Check for instance methods in protocols in categories. */
5538 if (CLASS_PROTOCOL_LIST (category
))
5540 if ((meth
= (lookup_method_in_protocol_list
5541 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5545 if ((category
= CLASS_CATEGORY_LIST (category
)))
5546 chain
= CLASS_NST_METHODS (category
);
5551 if (CLASS_PROTOCOL_LIST (inter
))
5553 if ((meth
= (lookup_method_in_protocol_list
5554 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5558 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5559 chain
= CLASS_NST_METHODS (inter
);
5567 lookup_class_method_static (interface
, ident
)
5571 tree inter
= interface
;
5572 tree chain
= CLASS_CLS_METHODS (inter
);
5573 tree meth
= NULL_TREE
;
5574 tree root_inter
= NULL_TREE
;
5578 if ((meth
= lookup_method (chain
, ident
)))
5581 if (CLASS_CATEGORY_LIST (inter
))
5583 tree category
= CLASS_CATEGORY_LIST (inter
);
5584 chain
= CLASS_CLS_METHODS (category
);
5588 if ((meth
= lookup_method (chain
, ident
)))
5591 /* Check for class methods in protocols in categories. */
5592 if (CLASS_PROTOCOL_LIST (category
))
5594 if ((meth
= (lookup_method_in_protocol_list
5595 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5599 if ((category
= CLASS_CATEGORY_LIST (category
)))
5600 chain
= CLASS_CLS_METHODS (category
);
5605 /* Check for class methods in protocols. */
5606 if (CLASS_PROTOCOL_LIST (inter
))
5608 if ((meth
= (lookup_method_in_protocol_list
5609 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5614 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5615 chain
= CLASS_CLS_METHODS (inter
);
5619 /* If no class (factory) method was found, check if an _instance_
5620 method of the same name exists in the root class. This is what
5621 the Objective-C runtime will do. */
5622 return lookup_instance_method_static (root_inter
, ident
);
5626 add_class_method (class, method
)
5633 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5635 /* put method on list in reverse order */
5636 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5637 CLASS_CLS_METHODS (class) = method
;
5641 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5642 error ("duplicate definition of class method `%s'",
5643 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5646 /* Check types; if different, complain. */
5647 if (!comp_proto_with_proto (method
, mth
))
5648 error ("duplicate declaration of class method `%s'",
5649 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5653 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5655 /* Install on a global chain. */
5656 hash_enter (cls_method_hash_list
, method
);
5660 /* Check types; if different, add to a list. */
5661 if (!comp_proto_with_proto (method
, hsh
->key
))
5662 hash_add_attr (hsh
, method
);
5668 add_instance_method (class, method
)
5675 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5677 /* Put method on list in reverse order. */
5678 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5679 CLASS_NST_METHODS (class) = method
;
5683 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5684 error ("duplicate definition of instance method `%s'",
5685 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5688 /* Check types; if different, complain. */
5689 if (!comp_proto_with_proto (method
, mth
))
5690 error ("duplicate declaration of instance method `%s'",
5691 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5695 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5697 /* Install on a global chain. */
5698 hash_enter (nst_method_hash_list
, method
);
5702 /* Check types; if different, add to a list. */
5703 if (!comp_proto_with_proto (method
, hsh
->key
))
5704 hash_add_attr (hsh
, method
);
5713 /* Put interfaces on list in reverse order. */
5714 TREE_CHAIN (class) = interface_chain
;
5715 interface_chain
= class;
5716 return interface_chain
;
5720 add_category (class, category
)
5724 /* Put categories on list in reverse order. */
5725 tree cat
= CLASS_CATEGORY_LIST (class);
5729 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5730 warning ("duplicate interface declaration for category `%s(%s)'",
5731 IDENTIFIER_POINTER (CLASS_NAME (class)),
5732 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5733 cat
= CLASS_CATEGORY_LIST (cat
);
5736 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5737 CLASS_CATEGORY_LIST (class) = category
;
5740 /* Called after parsing each instance variable declaration. Necessary to
5741 preserve typedefs and implement public/private...
5743 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5746 add_instance_variable (class, public, declarator
, declspecs
, width
)
5753 tree field_decl
, raw_decl
;
5755 raw_decl
= build_tree_list (declspecs
, declarator
);
5757 if (CLASS_RAW_IVARS (class))
5758 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5760 CLASS_RAW_IVARS (class) = raw_decl
;
5762 field_decl
= grokfield (declarator
, declspecs
, width
);
5764 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5768 TREE_PUBLIC (field_decl
) = 0;
5769 TREE_PRIVATE (field_decl
) = 0;
5770 TREE_PROTECTED (field_decl
) = 1;
5774 TREE_PUBLIC (field_decl
) = 1;
5775 TREE_PRIVATE (field_decl
) = 0;
5776 TREE_PROTECTED (field_decl
) = 0;
5780 TREE_PUBLIC (field_decl
) = 0;
5781 TREE_PRIVATE (field_decl
) = 1;
5782 TREE_PROTECTED (field_decl
) = 0;
5787 if (CLASS_IVARS (class))
5788 chainon (CLASS_IVARS (class), field_decl
);
5790 CLASS_IVARS (class) = field_decl
;
5796 is_ivar (decl_chain
, ident
)
5800 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5801 if (DECL_NAME (decl_chain
) == ident
)
5806 /* True if the ivar is private and we are not in its implementation. */
5812 if (TREE_PRIVATE (decl
)
5813 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5815 error ("instance variable `%s' is declared private",
5816 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5823 /* We have an instance variable reference;, check to see if it is public. */
5826 is_public (expr
, identifier
)
5830 tree basetype
= TREE_TYPE (expr
);
5831 enum tree_code code
= TREE_CODE (basetype
);
5834 if (code
== RECORD_TYPE
)
5836 if (TREE_STATIC_TEMPLATE (basetype
))
5838 if (!lookup_interface (TYPE_NAME (basetype
)))
5840 error ("cannot find interface declaration for `%s'",
5841 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5845 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5847 if (TREE_PUBLIC (decl
))
5850 /* Important difference between the Stepstone translator:
5851 all instance variables should be public within the context
5852 of the implementation. */
5853 if (objc_implementation_context
5854 && (((TREE_CODE (objc_implementation_context
)
5855 == CLASS_IMPLEMENTATION_TYPE
)
5856 || (TREE_CODE (objc_implementation_context
)
5857 == CATEGORY_IMPLEMENTATION_TYPE
))
5858 && (CLASS_NAME (objc_implementation_context
)
5859 == TYPE_NAME (basetype
))))
5860 return ! is_private (decl
);
5862 error ("instance variable `%s' is declared %s",
5863 IDENTIFIER_POINTER (identifier
),
5864 TREE_PRIVATE (decl
) ? "private" : "protected");
5869 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
5871 TREE_TYPE (expr
) = uprivate_record
;
5872 warning ("static access to object of type `id'");
5879 /* Make sure all entries in CHAIN are also in LIST. */
5882 check_methods (chain
, list
, mtype
)
5891 if (!lookup_method (list
, chain
))
5895 if (TREE_CODE (objc_implementation_context
)
5896 == CLASS_IMPLEMENTATION_TYPE
)
5897 warning ("incomplete implementation of class `%s'",
5898 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
5899 else if (TREE_CODE (objc_implementation_context
)
5900 == CATEGORY_IMPLEMENTATION_TYPE
)
5901 warning ("incomplete implementation of category `%s'",
5902 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
5906 warning ("method definition for `%c%s' not found",
5907 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5910 chain
= TREE_CHAIN (chain
);
5916 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5919 conforms_to_protocol (class, protocol
)
5923 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
5925 tree p
= CLASS_PROTOCOL_LIST (class);
5926 while (p
&& TREE_VALUE (p
) != protocol
)
5931 tree super
= (CLASS_SUPER_NAME (class)
5932 ? lookup_interface (CLASS_SUPER_NAME (class))
5934 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5943 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5944 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5947 check_methods_accessible (chain
, context
, mtype
)
5954 tree base_context
= context
;
5958 context
= base_context
;
5962 list
= CLASS_CLS_METHODS (context
);
5964 list
= CLASS_NST_METHODS (context
);
5966 if (lookup_method (list
, chain
))
5969 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5970 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5971 context
= (CLASS_SUPER_NAME (context
)
5972 ? lookup_interface (CLASS_SUPER_NAME (context
))
5975 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5976 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5977 context
= (CLASS_NAME (context
)
5978 ? lookup_interface (CLASS_NAME (context
))
5984 if (context
== NULL_TREE
)
5988 if (TREE_CODE (objc_implementation_context
)
5989 == CLASS_IMPLEMENTATION_TYPE
)
5990 warning ("incomplete implementation of class `%s'",
5992 (CLASS_NAME (objc_implementation_context
)));
5993 else if (TREE_CODE (objc_implementation_context
)
5994 == CATEGORY_IMPLEMENTATION_TYPE
)
5995 warning ("incomplete implementation of category `%s'",
5997 (CLASS_SUPER_NAME (objc_implementation_context
)));
6000 warning ("method definition for `%c%s' not found",
6001 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6004 chain
= TREE_CHAIN (chain
); /* next method... */
6009 /* Check whether the current interface (accessible via
6010 'objc_implementation_context') actually implements protocol P, along
6011 with any protocols that P inherits. */
6014 check_protocol (p
, type
, name
)
6019 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6023 /* Ensure that all protocols have bodies! */
6026 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6027 CLASS_CLS_METHODS (objc_implementation_context
),
6029 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6030 CLASS_NST_METHODS (objc_implementation_context
),
6035 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6036 objc_implementation_context
,
6038 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6039 objc_implementation_context
,
6044 warning ("%s `%s' does not fully implement the `%s' protocol",
6045 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6048 /* Check protocols recursively. */
6049 if (PROTOCOL_LIST (p
))
6051 tree subs
= PROTOCOL_LIST (p
);
6053 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6057 tree sub
= TREE_VALUE (subs
);
6059 /* If the superclass does not conform to the protocols
6060 inherited by P, then we must! */
6061 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
6062 check_protocol (sub
, type
, name
);
6063 subs
= TREE_CHAIN (subs
);
6068 /* Check whether the current interface (accessible via
6069 'objc_implementation_context') actually implements the protocols listed
6073 check_protocols (proto_list
, type
, name
)
6078 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6080 tree p
= TREE_VALUE (proto_list
);
6082 check_protocol (p
, type
, name
);
6086 /* Make sure that the class CLASS_NAME is defined
6087 CODE says which kind of thing CLASS_NAME ought to be.
6088 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6089 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6092 start_class (code
, class_name
, super_name
, protocol_list
)
6093 enum tree_code code
;
6100 if (objc_implementation_context
)
6102 warning ("`@end' missing in implementation context");
6103 finish_class (objc_implementation_context
);
6104 objc_ivar_chain
= NULL_TREE
;
6105 objc_implementation_context
= NULL_TREE
;
6108 class = make_node (code
);
6109 TYPE_BINFO (class) = make_tree_vec (BINFO_ELTS
);
6111 CLASS_NAME (class) = class_name
;
6112 CLASS_SUPER_NAME (class) = super_name
;
6113 CLASS_CLS_METHODS (class) = NULL_TREE
;
6115 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6117 error ("`%s' redeclared as different kind of symbol",
6118 IDENTIFIER_POINTER (class_name
));
6119 error_with_decl (decl
, "previous declaration of `%s'");
6122 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6127 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6128 if (TREE_VALUE (chain
) == class_name
)
6130 error ("reimplementation of class `%s'",
6131 IDENTIFIER_POINTER (class_name
));
6132 return error_mark_node
;
6134 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6135 implemented_classes
);
6138 /* Pre-build the following entities - for speed/convenience. */
6140 self_id
= get_identifier ("self");
6142 ucmd_id
= get_identifier ("_cmd");
6145 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6146 if (!objc_super_template
)
6147 objc_super_template
= build_super_template ();
6149 /* Reset for multiple classes per file. */
6152 objc_implementation_context
= class;
6154 /* Lookup the interface for this implementation. */
6156 if (!(implementation_template
= lookup_interface (class_name
)))
6158 warning ("cannot find interface declaration for `%s'",
6159 IDENTIFIER_POINTER (class_name
));
6160 add_class (implementation_template
= objc_implementation_context
);
6163 /* If a super class has been specified in the implementation,
6164 insure it conforms to the one specified in the interface. */
6167 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6169 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6170 const char *const name
=
6171 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6172 error ("conflicting super class name `%s'",
6173 IDENTIFIER_POINTER (super_name
));
6174 error ("previous declaration of `%s'", name
);
6177 else if (! super_name
)
6179 CLASS_SUPER_NAME (objc_implementation_context
)
6180 = CLASS_SUPER_NAME (implementation_template
);
6184 else if (code
== CLASS_INTERFACE_TYPE
)
6186 if (lookup_interface (class_name
))
6187 warning ("duplicate interface declaration for class `%s'",
6188 IDENTIFIER_POINTER (class_name
));
6193 CLASS_PROTOCOL_LIST (class)
6194 = lookup_and_install_protocols (protocol_list
);
6197 else if (code
== CATEGORY_INTERFACE_TYPE
)
6199 tree class_category_is_assoc_with
;
6201 /* For a category, class_name is really the name of the class that
6202 the following set of methods will be associated with. We must
6203 find the interface so that can derive the objects template. */
6205 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6207 error ("cannot find interface declaration for `%s'",
6208 IDENTIFIER_POINTER (class_name
));
6209 exit (FATAL_EXIT_CODE
);
6212 add_category (class_category_is_assoc_with
, class);
6215 CLASS_PROTOCOL_LIST (class)
6216 = lookup_and_install_protocols (protocol_list
);
6219 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6221 /* Pre-build the following entities for speed/convenience. */
6223 self_id
= get_identifier ("self");
6225 ucmd_id
= get_identifier ("_cmd");
6228 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6229 if (!objc_super_template
)
6230 objc_super_template
= build_super_template ();
6232 /* Reset for multiple classes per file. */
6235 objc_implementation_context
= class;
6237 /* For a category, class_name is really the name of the class that
6238 the following set of methods will be associated with. We must
6239 find the interface so that can derive the objects template. */
6241 if (!(implementation_template
= lookup_interface (class_name
)))
6243 error ("cannot find interface declaration for `%s'",
6244 IDENTIFIER_POINTER (class_name
));
6245 exit (FATAL_EXIT_CODE
);
6252 continue_class (class)
6255 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6256 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6258 struct imp_entry
*imp_entry
;
6261 /* Check consistency of the instance variables. */
6263 if (CLASS_IVARS (class))
6264 check_ivars (implementation_template
, class);
6266 /* code generation */
6268 ivar_context
= build_private_template (implementation_template
);
6270 if (!objc_class_template
)
6271 build_class_template ();
6273 imp_entry
= (struct imp_entry
*) ggc_alloc (sizeof (struct imp_entry
));
6275 imp_entry
->next
= imp_list
;
6276 imp_entry
->imp_context
= class;
6277 imp_entry
->imp_template
= implementation_template
;
6279 synth_forward_declarations ();
6280 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6281 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6283 /* Append to front and increment count. */
6284 imp_list
= imp_entry
;
6285 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6290 return ivar_context
;
6293 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6295 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6297 if (!TYPE_FIELDS (record
))
6299 finish_struct (record
, get_class_ivars (class), NULL_TREE
);
6300 CLASS_STATIC_TEMPLATE (class) = record
;
6302 /* Mark this record as a class template for static typing. */
6303 TREE_STATIC_TEMPLATE (record
) = 1;
6310 return error_mark_node
;
6313 /* This is called once we see the "@end" in an interface/implementation. */
6316 finish_class (class)
6319 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6321 /* All code generation is done in finish_objc. */
6323 if (implementation_template
!= objc_implementation_context
)
6325 /* Ensure that all method listed in the interface contain bodies. */
6326 check_methods (CLASS_CLS_METHODS (implementation_template
),
6327 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6328 check_methods (CLASS_NST_METHODS (implementation_template
),
6329 CLASS_NST_METHODS (objc_implementation_context
), '-');
6331 if (CLASS_PROTOCOL_LIST (implementation_template
))
6332 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6334 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6338 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6340 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6342 /* Find the category interface from the class it is associated with. */
6345 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6347 category
= CLASS_CATEGORY_LIST (category
);
6352 /* Ensure all method listed in the interface contain bodies. */
6353 check_methods (CLASS_CLS_METHODS (category
),
6354 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6355 check_methods (CLASS_NST_METHODS (category
),
6356 CLASS_NST_METHODS (objc_implementation_context
), '-');
6358 if (CLASS_PROTOCOL_LIST (category
))
6359 check_protocols (CLASS_PROTOCOL_LIST (category
),
6361 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6365 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6368 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6369 char *string
= (char *) alloca (strlen (class_name
) + 3);
6371 /* extern struct objc_object *_<my_name>; */
6373 sprintf (string
, "_%s", class_name
);
6375 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6376 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6377 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6383 add_protocol (protocol
)
6386 /* Put protocol on list in reverse order. */
6387 TREE_CHAIN (protocol
) = protocol_chain
;
6388 protocol_chain
= protocol
;
6389 return protocol_chain
;
6393 lookup_protocol (ident
)
6398 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6399 if (ident
== PROTOCOL_NAME (chain
))
6405 /* This function forward declares the protocols named by NAMES. If
6406 they are already declared or defined, the function has no effect. */
6409 objc_declare_protocols (names
)
6414 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6416 tree name
= TREE_VALUE (list
);
6418 if (lookup_protocol (name
) == NULL_TREE
)
6420 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6422 TYPE_BINFO (protocol
) = make_tree_vec (2);
6423 PROTOCOL_NAME (protocol
) = name
;
6424 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6425 add_protocol (protocol
);
6426 PROTOCOL_DEFINED (protocol
) = 0;
6427 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6433 start_protocol (code
, name
, list
)
6434 enum tree_code code
;
6440 /* This is as good a place as any. Need to invoke
6441 push_tag_toplevel. */
6442 if (!objc_protocol_template
)
6443 objc_protocol_template
= build_protocol_template ();
6445 protocol
= lookup_protocol (name
);
6449 protocol
= make_node (code
);
6450 TYPE_BINFO (protocol
) = make_tree_vec (2);
6452 PROTOCOL_NAME (protocol
) = name
;
6453 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6454 add_protocol (protocol
);
6455 PROTOCOL_DEFINED (protocol
) = 1;
6456 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6458 check_protocol_recursively (protocol
, list
);
6460 else if (! PROTOCOL_DEFINED (protocol
))
6462 PROTOCOL_DEFINED (protocol
) = 1;
6463 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6465 check_protocol_recursively (protocol
, list
);
6469 warning ("duplicate declaration for protocol `%s'",
6470 IDENTIFIER_POINTER (name
));
6476 finish_protocol (protocol
)
6477 tree protocol ATTRIBUTE_UNUSED
;
6482 /* "Encode" a data type into a string, which grows in util_obstack.
6483 ??? What is the FORMAT? Someone please document this! */
6486 encode_type_qualifiers (declspecs
)
6491 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6493 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6494 obstack_1grow (&util_obstack
, 'r');
6495 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6496 obstack_1grow (&util_obstack
, 'n');
6497 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6498 obstack_1grow (&util_obstack
, 'N');
6499 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6500 obstack_1grow (&util_obstack
, 'o');
6501 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6502 obstack_1grow (&util_obstack
, 'O');
6503 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6504 obstack_1grow (&util_obstack
, 'R');
6505 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6506 obstack_1grow (&util_obstack
, 'V');
6510 /* Encode a pointer type. */
6513 encode_pointer (type
, curtype
, format
)
6518 tree pointer_to
= TREE_TYPE (type
);
6520 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6522 if (TYPE_NAME (pointer_to
)
6523 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6525 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6527 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6529 obstack_1grow (&util_obstack
, '@');
6532 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6534 if (generating_instance_variables
)
6536 obstack_1grow (&util_obstack
, '@');
6537 obstack_1grow (&util_obstack
, '"');
6538 obstack_grow (&util_obstack
, name
, strlen (name
));
6539 obstack_1grow (&util_obstack
, '"');
6544 obstack_1grow (&util_obstack
, '@');
6548 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6550 obstack_1grow (&util_obstack
, '#');
6553 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6555 obstack_1grow (&util_obstack
, ':');
6560 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6561 && TYPE_MODE (pointer_to
) == QImode
)
6563 obstack_1grow (&util_obstack
, '*');
6567 /* We have a type that does not get special treatment. */
6569 /* NeXT extension */
6570 obstack_1grow (&util_obstack
, '^');
6571 encode_type (pointer_to
, curtype
, format
);
6575 encode_array (type
, curtype
, format
)
6580 tree an_int_cst
= TYPE_SIZE (type
);
6581 tree array_of
= TREE_TYPE (type
);
6584 /* An incomplete array is treated like a pointer. */
6585 if (an_int_cst
== NULL
)
6587 encode_pointer (type
, curtype
, format
);
6591 sprintf (buffer
, "[%ld",
6592 (long) (TREE_INT_CST_LOW (an_int_cst
)
6593 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6595 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6596 encode_type (array_of
, curtype
, format
);
6597 obstack_1grow (&util_obstack
, ']');
6602 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6609 /* The RECORD_TYPE may in fact be a typedef! For purposes
6610 of encoding, we need the real underlying enchilada. */
6611 if (TYPE_MAIN_VARIANT (type
))
6612 type
= TYPE_MAIN_VARIANT (type
);
6614 if (obstack_object_size (&util_obstack
) > 0
6615 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6617 tree name
= TYPE_NAME (type
);
6619 /* we have a reference; this is a NeXT extension. */
6621 if (obstack_object_size (&util_obstack
) - curtype
== 1
6622 && format
== OBJC_ENCODE_INLINE_DEFS
)
6624 /* Output format of struct for first level only. */
6625 tree fields
= TYPE_FIELDS (type
);
6627 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6629 obstack_1grow (&util_obstack
, left
);
6630 obstack_grow (&util_obstack
,
6631 IDENTIFIER_POINTER (name
),
6632 strlen (IDENTIFIER_POINTER (name
)));
6633 obstack_1grow (&util_obstack
, '=');
6637 obstack_1grow (&util_obstack
, left
);
6638 obstack_grow (&util_obstack
, "?=", 2);
6641 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6642 encode_field_decl (fields
, curtype
, format
);
6644 obstack_1grow (&util_obstack
, right
);
6647 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6649 obstack_1grow (&util_obstack
, left
);
6650 obstack_grow (&util_obstack
,
6651 IDENTIFIER_POINTER (name
),
6652 strlen (IDENTIFIER_POINTER (name
)));
6653 obstack_1grow (&util_obstack
, right
);
6658 /* We have an untagged structure or a typedef. */
6659 obstack_1grow (&util_obstack
, left
);
6660 obstack_1grow (&util_obstack
, '?');
6661 obstack_1grow (&util_obstack
, right
);
6667 tree name
= TYPE_NAME (type
);
6668 tree fields
= TYPE_FIELDS (type
);
6670 if (format
== OBJC_ENCODE_INLINE_DEFS
6671 || generating_instance_variables
)
6673 obstack_1grow (&util_obstack
, left
);
6674 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6675 obstack_grow (&util_obstack
,
6676 IDENTIFIER_POINTER (name
),
6677 strlen (IDENTIFIER_POINTER (name
)));
6679 obstack_1grow (&util_obstack
, '?');
6681 obstack_1grow (&util_obstack
, '=');
6683 for (; fields
; fields
= TREE_CHAIN (fields
))
6685 if (generating_instance_variables
)
6687 tree fname
= DECL_NAME (fields
);
6689 obstack_1grow (&util_obstack
, '"');
6690 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6692 obstack_grow (&util_obstack
,
6693 IDENTIFIER_POINTER (fname
),
6694 strlen (IDENTIFIER_POINTER (fname
)));
6697 obstack_1grow (&util_obstack
, '"');
6700 encode_field_decl (fields
, curtype
, format
);
6703 obstack_1grow (&util_obstack
, right
);
6708 obstack_1grow (&util_obstack
, left
);
6709 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6710 obstack_grow (&util_obstack
,
6711 IDENTIFIER_POINTER (name
),
6712 strlen (IDENTIFIER_POINTER (name
)));
6714 /* We have an untagged structure or a typedef. */
6715 obstack_1grow (&util_obstack
, '?');
6717 obstack_1grow (&util_obstack
, right
);
6723 encode_aggregate (type
, curtype
, format
)
6728 enum tree_code code
= TREE_CODE (type
);
6734 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6739 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6744 obstack_1grow (&util_obstack
, 'i');
6752 /* Support bitfields. The current version of Objective-C does not support
6753 them. The string will consist of one or more "b:n"'s where n is an
6754 integer describing the width of the bitfield. Currently, classes in
6755 the kit implement a method "-(char *)describeBitfieldStruct:" that
6756 simulates this. If they do not implement this method, the archiver
6757 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6758 according to the GNU compiler. After looking at the "kit", it appears
6759 that all classes currently rely on this default behavior, rather than
6760 hand generating this string (which is tedious). */
6763 encode_bitfield (width
)
6767 sprintf (buffer
, "b%d", width
);
6768 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6771 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6774 encode_type (type
, curtype
, format
)
6779 enum tree_code code
= TREE_CODE (type
);
6781 if (code
== INTEGER_TYPE
)
6783 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6785 /* Unsigned integer types. */
6787 if (TYPE_MODE (type
) == QImode
)
6788 obstack_1grow (&util_obstack
, 'C');
6789 else if (TYPE_MODE (type
) == HImode
)
6790 obstack_1grow (&util_obstack
, 'S');
6791 else if (TYPE_MODE (type
) == SImode
)
6793 if (type
== long_unsigned_type_node
)
6794 obstack_1grow (&util_obstack
, 'L');
6796 obstack_1grow (&util_obstack
, 'I');
6798 else if (TYPE_MODE (type
) == DImode
)
6799 obstack_1grow (&util_obstack
, 'Q');
6803 /* Signed integer types. */
6805 if (TYPE_MODE (type
) == QImode
)
6806 obstack_1grow (&util_obstack
, 'c');
6807 else if (TYPE_MODE (type
) == HImode
)
6808 obstack_1grow (&util_obstack
, 's');
6809 else if (TYPE_MODE (type
) == SImode
)
6811 if (type
== long_integer_type_node
)
6812 obstack_1grow (&util_obstack
, 'l');
6814 obstack_1grow (&util_obstack
, 'i');
6817 else if (TYPE_MODE (type
) == DImode
)
6818 obstack_1grow (&util_obstack
, 'q');
6822 else if (code
== REAL_TYPE
)
6824 /* Floating point types. */
6826 if (TYPE_MODE (type
) == SFmode
)
6827 obstack_1grow (&util_obstack
, 'f');
6828 else if (TYPE_MODE (type
) == DFmode
6829 || TYPE_MODE (type
) == TFmode
)
6830 obstack_1grow (&util_obstack
, 'd');
6833 else if (code
== VOID_TYPE
)
6834 obstack_1grow (&util_obstack
, 'v');
6836 else if (code
== ARRAY_TYPE
)
6837 encode_array (type
, curtype
, format
);
6839 else if (code
== POINTER_TYPE
)
6840 encode_pointer (type
, curtype
, format
);
6842 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6843 encode_aggregate (type
, curtype
, format
);
6845 else if (code
== FUNCTION_TYPE
) /* '?' */
6846 obstack_1grow (&util_obstack
, '?');
6850 encode_complete_bitfield (position
, type
, size
)
6855 enum tree_code code
= TREE_CODE (type
);
6857 char charType
= '?';
6859 if (code
== INTEGER_TYPE
)
6861 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6863 /* Unsigned integer types. */
6865 if (TYPE_MODE (type
) == QImode
)
6867 else if (TYPE_MODE (type
) == HImode
)
6869 else if (TYPE_MODE (type
) == SImode
)
6871 if (type
== long_unsigned_type_node
)
6876 else if (TYPE_MODE (type
) == DImode
)
6881 /* Signed integer types. */
6883 if (TYPE_MODE (type
) == QImode
)
6885 else if (TYPE_MODE (type
) == HImode
)
6887 else if (TYPE_MODE (type
) == SImode
)
6889 if (type
== long_integer_type_node
)
6895 else if (TYPE_MODE (type
) == DImode
)
6899 else if (code
== ENUMERAL_TYPE
)
6904 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6905 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6909 encode_field_decl (field_decl
, curtype
, format
)
6916 type
= TREE_TYPE (field_decl
);
6918 /* If this field is obviously a bitfield, or is a bitfield that has been
6919 clobbered to look like a ordinary integer mode, go ahead and generate
6920 the bitfield typing information. */
6921 if (flag_next_runtime
)
6923 if (DECL_BIT_FIELD_TYPE (field_decl
))
6924 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6926 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6930 if (DECL_BIT_FIELD_TYPE (field_decl
))
6931 encode_complete_bitfield (int_bit_position (field_decl
),
6932 DECL_BIT_FIELD_TYPE (field_decl
),
6933 tree_low_cst (DECL_SIZE (field_decl
), 1));
6935 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6940 objc_expr_last (complex_expr
)
6946 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6947 complex_expr
= next
;
6949 return complex_expr
;
6952 /* Transform a method definition into a function definition as follows:
6953 - synthesize the first two arguments, "self" and "_cmd". */
6956 start_method_def (method
)
6961 /* Required to implement _msgSuper. */
6962 objc_method_context
= method
;
6963 UOBJC_SUPER_decl
= NULL_TREE
;
6965 /* Must be called BEFORE start_function. */
6968 /* Generate prototype declarations for arguments..."new-style". */
6970 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
6971 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6973 /* Really a `struct objc_class *'. However, we allow people to
6974 assign to self, which changes its type midstream. */
6975 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6977 push_parm_decl (build_tree_list
6978 (build_tree_list (decl_specs
,
6979 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6982 decl_specs
= build_tree_list (NULL_TREE
,
6983 xref_tag (RECORD_TYPE
,
6984 get_identifier (TAG_SELECTOR
)));
6985 push_parm_decl (build_tree_list
6986 (build_tree_list (decl_specs
,
6987 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6990 /* Generate argument declarations if a keyword_decl. */
6991 if (METHOD_SEL_ARGS (method
))
6993 tree arglist
= METHOD_SEL_ARGS (method
);
6996 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6997 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
7001 tree last_expr
= objc_expr_last (arg_decl
);
7003 /* Unite the abstract decl with its name. */
7004 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
7005 push_parm_decl (build_tree_list
7006 (build_tree_list (arg_spec
, arg_decl
),
7009 /* Unhook: restore the abstract declarator. */
7010 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
7014 push_parm_decl (build_tree_list
7015 (build_tree_list (arg_spec
,
7016 KEYWORD_ARG_NAME (arglist
)),
7019 arglist
= TREE_CHAIN (arglist
);
7024 if (METHOD_ADD_ARGS (method
) != NULL_TREE
7025 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
7027 /* We have a variable length selector - in "prototype" format. */
7028 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7031 /* This must be done prior to calling pushdecl. pushdecl is
7032 going to change our chain on us. */
7033 tree nextkey
= TREE_CHAIN (akey
);
7041 warn_with_method (message
, mtype
, method
)
7042 const char *message
;
7046 /* Add a readable method name to the warning. */
7047 warning ("%H%s `%c%s'", &DECL_SOURCE_LOCATION (method
),
7048 message
, mtype
, gen_method_decl (method
, errbuf
));
7051 /* Return 1 if METHOD is consistent with PROTO. */
7054 comp_method_with_proto (method
, proto
)
7057 /* Create a function template node at most once. */
7058 if (!function1_template
)
7059 function1_template
= make_node (FUNCTION_TYPE
);
7061 /* Install argument types - normally set by build_function_type. */
7062 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7064 /* install return type */
7065 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto
));
7067 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function1_template
);
7070 /* Return 1 if PROTO1 is consistent with PROTO2. */
7073 comp_proto_with_proto (proto0
, proto1
)
7074 tree proto0
, proto1
;
7076 /* Create a couple of function_template nodes at most once. */
7077 if (!function1_template
)
7078 function1_template
= make_node (FUNCTION_TYPE
);
7079 if (!function2_template
)
7080 function2_template
= make_node (FUNCTION_TYPE
);
7082 /* Install argument types; normally set by build_function_type. */
7083 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto0
, METHOD_REF
, 0);
7084 TYPE_ARG_TYPES (function2_template
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7086 /* Install return type. */
7087 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto0
));
7088 TREE_TYPE (function2_template
) = groktypename (TREE_TYPE (proto1
));
7090 return comptypes (function1_template
, function2_template
);
7093 /* - Generate an identifier for the function. the format is "_n_cls",
7094 where 1 <= n <= nMethods, and cls is the name the implementation we
7096 - Install the return type from the method declaration.
7097 - If we have a prototype, check for type consistency. */
7100 really_start_method (method
, parmlist
)
7101 tree method
, parmlist
;
7103 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7104 tree method_decl
, method_id
;
7105 const char *sel_name
, *class_name
, *cat_name
;
7108 /* Synth the storage class & assemble the return type. */
7109 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7110 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7111 decl_specs
= chainon (sc_spec
, ret_spec
);
7113 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7114 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
7115 cat_name
= ((TREE_CODE (objc_implementation_context
)
7116 == CLASS_IMPLEMENTATION_TYPE
)
7118 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7121 /* Make sure this is big enough for any plausible method label. */
7122 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7123 + (cat_name
? strlen (cat_name
) : 0));
7125 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7126 class_name
, cat_name
, sel_name
, method_slot
);
7128 method_id
= get_identifier (buf
);
7130 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7132 /* Check the declarator portion of the return type for the method. */
7133 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7135 /* Unite the complex decl (specified in the abstract decl) with the
7136 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7137 tree save_expr
= objc_expr_last (ret_decl
);
7139 TREE_OPERAND (save_expr
, 0) = method_decl
;
7140 method_decl
= ret_decl
;
7142 /* Fool the parser into thinking it is starting a function. */
7143 start_function (decl_specs
, method_decl
, NULL_TREE
);
7145 /* Unhook: this has the effect of restoring the abstract declarator. */
7146 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7151 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7153 /* Fool the parser into thinking it is starting a function. */
7154 start_function (decl_specs
, method_decl
, NULL_TREE
);
7156 /* Unhook: this has the effect of restoring the abstract declarator. */
7157 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7160 METHOD_DEFINITION (method
) = current_function_decl
;
7162 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7164 if (implementation_template
!= objc_implementation_context
)
7168 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7169 proto
= lookup_instance_method_static (implementation_template
,
7170 METHOD_SEL_NAME (method
));
7172 proto
= lookup_class_method_static (implementation_template
,
7173 METHOD_SEL_NAME (method
));
7175 if (proto
&& ! comp_method_with_proto (method
, proto
))
7177 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7179 warn_with_method ("conflicting types for", type
, method
);
7180 warn_with_method ("previous declaration of", type
, proto
);
7185 /* The following routine is always called...this "architecture" is to
7186 accommodate "old-style" variable length selectors.
7188 - a:a b:b // prototype ; id c; id d; // old-style. */
7191 continue_method_def ()
7195 if (METHOD_ADD_ARGS (objc_method_context
) == objc_ellipsis_node
)
7196 /* We have a `, ...' immediately following the selector. */
7197 parmlist
= get_parm_info (0);
7199 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7201 /* Set self_decl from the first argument...this global is used by
7202 build_ivar_reference calling build_indirect_ref. */
7203 self_decl
= TREE_PURPOSE (parmlist
);
7206 really_start_method (objc_method_context
, parmlist
);
7207 store_parm_decls ();
7210 /* Called by the parser, from the `pushlevel' production. */
7215 if (!UOBJC_SUPER_decl
)
7217 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7218 build_tree_list (NULL_TREE
,
7219 objc_super_template
),
7222 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7224 /* This prevents `unused variable' warnings when compiling with -Wall. */
7225 TREE_USED (UOBJC_SUPER_decl
) = 1;
7226 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7230 /* _n_Method (id self, SEL sel, ...)
7232 struct objc_super _S;
7233 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7237 get_super_receiver ()
7239 if (objc_method_context
)
7241 tree super_expr
, super_expr_list
;
7243 /* Set receiver to self. */
7244 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7245 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7246 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7248 /* Set class to begin searching. */
7249 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7250 get_identifier ("class"));
7252 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7254 /* [_cls, __cls]Super are "pre-built" in
7255 synth_forward_declarations. */
7257 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7258 ((TREE_CODE (objc_method_context
)
7259 == INSTANCE_METHOD_DECL
)
7261 : uucls_super_ref
));
7265 /* We have a category. */
7267 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7270 /* Barf if super used in a category of Object. */
7273 error ("no super class declared in interface for `%s'",
7274 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7275 return error_mark_node
;
7278 if (flag_next_runtime
)
7280 super_class
= get_class_reference (super_name
);
7281 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7282 /* Cast the super class to 'id', since the user may not have
7283 included <objc/objc-class.h>, leaving 'struct objc_class'
7284 an incomplete type. */
7286 = build_component_ref (build_indirect_ref
7287 (build_c_cast (id_type
, super_class
), "->"),
7288 get_identifier ("isa"));
7292 add_class_reference (super_name
);
7293 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7294 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7295 assemble_external (super_class
);
7297 = build_function_call
7301 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7302 IDENTIFIER_POINTER (super_name
))));
7305 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7306 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7309 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7311 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7312 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7314 return build_compound_expr (super_expr_list
);
7318 error ("[super ...] must appear in a method context");
7319 return error_mark_node
;
7324 encode_method_def (func_decl
)
7329 HOST_WIDE_INT max_parm_end
= 0;
7334 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7335 obstack_object_size (&util_obstack
),
7336 OBJC_ENCODE_INLINE_DEFS
);
7339 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7340 parms
= TREE_CHAIN (parms
))
7342 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7343 + int_size_in_bytes (TREE_TYPE (parms
)));
7345 if (! offset_is_register
&& parm_end
> max_parm_end
)
7346 max_parm_end
= parm_end
;
7349 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7351 sprintf (buffer
, "%d", stack_size
);
7352 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7354 /* Argument types. */
7355 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7356 parms
= TREE_CHAIN (parms
))
7359 encode_type (TREE_TYPE (parms
),
7360 obstack_object_size (&util_obstack
),
7361 OBJC_ENCODE_INLINE_DEFS
);
7363 /* Compute offset. */
7364 sprintf (buffer
, "%d", forwarding_offset (parms
));
7366 /* Indicate register. */
7367 if (offset_is_register
)
7368 obstack_1grow (&util_obstack
, '+');
7370 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7373 /* Null terminate string. */
7374 obstack_1grow (&util_obstack
, 0);
7375 result
= get_identifier (obstack_finish (&util_obstack
));
7376 obstack_free (&util_obstack
, util_firstobj
);
7381 objc_expand_function_end ()
7383 METHOD_ENCODING (objc_method_context
) = encode_method_def (current_function_decl
);
7387 finish_method_def ()
7389 lang_expand_function_end
= objc_expand_function_end
;
7390 finish_function (0, 1);
7391 lang_expand_function_end
= NULL
;
7393 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7394 since the optimizer may find "may be used before set" errors. */
7395 objc_method_context
= NULL_TREE
;
7400 lang_report_error_function (decl
)
7403 if (objc_method_context
)
7405 fprintf (stderr
, "In method `%s'\n",
7406 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7416 is_complex_decl (type
)
7419 return (TREE_CODE (type
) == ARRAY_TYPE
7420 || TREE_CODE (type
) == FUNCTION_TYPE
7421 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7425 /* Code to convert a decl node into text for a declaration in C. */
7427 static char tmpbuf
[256];
7430 adorn_decl (decl
, str
)
7434 enum tree_code code
= TREE_CODE (decl
);
7436 if (code
== ARRAY_REF
)
7438 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7440 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7441 sprintf (str
+ strlen (str
), "[%ld]",
7442 (long) TREE_INT_CST_LOW (an_int_cst
));
7447 else if (code
== ARRAY_TYPE
)
7449 tree an_int_cst
= TYPE_SIZE (decl
);
7450 tree array_of
= TREE_TYPE (decl
);
7452 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7453 sprintf (str
+ strlen (str
), "[%ld]",
7454 (long) (TREE_INT_CST_LOW (an_int_cst
)
7455 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7460 else if (code
== CALL_EXPR
)
7462 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7467 gen_declaration_1 (chain
, str
);
7468 chain
= TREE_CHAIN (chain
);
7475 else if (code
== FUNCTION_TYPE
)
7477 tree chain
= TYPE_ARG_TYPES (decl
);
7480 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7482 gen_declaration_1 (TREE_VALUE (chain
), str
);
7483 chain
= TREE_CHAIN (chain
);
7484 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7490 else if (code
== INDIRECT_REF
)
7492 strcpy (tmpbuf
, "*");
7493 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7497 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7499 chain
= TREE_CHAIN (chain
))
7501 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7503 strcat (tmpbuf
, " ");
7504 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7508 strcat (tmpbuf
, " ");
7510 strcat (tmpbuf
, str
);
7511 strcpy (str
, tmpbuf
);
7514 else if (code
== POINTER_TYPE
)
7516 strcpy (tmpbuf
, "*");
7517 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7519 if (TREE_READONLY (decl
))
7520 strcat (tmpbuf
, " const");
7521 if (TYPE_VOLATILE (decl
))
7522 strcat (tmpbuf
, " volatile");
7524 strcat (tmpbuf
, " ");
7526 strcat (tmpbuf
, str
);
7527 strcpy (str
, tmpbuf
);
7532 gen_declarator (decl
, buf
, name
)
7539 enum tree_code code
= TREE_CODE (decl
);
7549 op
= TREE_OPERAND (decl
, 0);
7551 /* We have a pointer to a function or array...(*)(), (*)[] */
7552 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7553 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7556 str
= gen_declarator (op
, buf
, name
);
7560 strcpy (tmpbuf
, "(");
7561 strcat (tmpbuf
, str
);
7562 strcat (tmpbuf
, ")");
7563 strcpy (str
, tmpbuf
);
7566 adorn_decl (decl
, str
);
7575 /* This clause is done iteratively rather than recursively. */
7578 op
= (is_complex_decl (TREE_TYPE (decl
))
7579 ? TREE_TYPE (decl
) : NULL_TREE
);
7581 adorn_decl (decl
, str
);
7583 /* We have a pointer to a function or array...(*)(), (*)[] */
7584 if (code
== POINTER_TYPE
7585 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7586 || TREE_CODE (op
) == ARRAY_TYPE
))
7588 strcpy (tmpbuf
, "(");
7589 strcat (tmpbuf
, str
);
7590 strcat (tmpbuf
, ")");
7591 strcpy (str
, tmpbuf
);
7594 decl
= (is_complex_decl (TREE_TYPE (decl
))
7595 ? TREE_TYPE (decl
) : NULL_TREE
);
7598 while (decl
&& (code
= TREE_CODE (decl
)))
7603 case IDENTIFIER_NODE
:
7604 /* Will only happen if we are processing a "raw" expr-decl. */
7605 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7616 /* We have an abstract declarator or a _DECL node. */
7624 gen_declspecs (declspecs
, buf
, raw
)
7633 for (chain
= nreverse (copy_list (declspecs
));
7634 chain
; chain
= TREE_CHAIN (chain
))
7636 tree aspec
= TREE_VALUE (chain
);
7638 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7639 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7640 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7642 if (TYPE_NAME (aspec
))
7644 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7646 if (! TREE_STATIC_TEMPLATE (aspec
))
7647 strcat (buf
, "struct ");
7648 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7653 tree chain
= protocol_list
;
7660 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7661 chain
= TREE_CHAIN (chain
);
7670 strcat (buf
, "untagged struct");
7673 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7675 if (TYPE_NAME (aspec
))
7677 if (! TREE_STATIC_TEMPLATE (aspec
))
7678 strcat (buf
, "union ");
7679 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7682 strcat (buf
, "untagged union");
7685 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7687 if (TYPE_NAME (aspec
))
7689 if (! TREE_STATIC_TEMPLATE (aspec
))
7690 strcat (buf
, "enum ");
7691 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7694 strcat (buf
, "untagged enum");
7697 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7698 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7700 else if (IS_ID (aspec
))
7702 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7707 tree chain
= protocol_list
;
7714 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7715 chain
= TREE_CHAIN (chain
);
7722 if (TREE_CHAIN (chain
))
7728 /* Type qualifiers. */
7729 if (TREE_READONLY (declspecs
))
7730 strcat (buf
, "const ");
7731 if (TYPE_VOLATILE (declspecs
))
7732 strcat (buf
, "volatile ");
7734 switch (TREE_CODE (declspecs
))
7736 /* Type specifiers. */
7739 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7741 /* Signed integer types. */
7743 if (declspecs
== short_integer_type_node
)
7744 strcat (buf
, "short int ");
7745 else if (declspecs
== integer_type_node
)
7746 strcat (buf
, "int ");
7747 else if (declspecs
== long_integer_type_node
)
7748 strcat (buf
, "long int ");
7749 else if (declspecs
== long_long_integer_type_node
)
7750 strcat (buf
, "long long int ");
7751 else if (declspecs
== signed_char_type_node
7752 || declspecs
== char_type_node
)
7753 strcat (buf
, "char ");
7755 /* Unsigned integer types. */
7757 else if (declspecs
== short_unsigned_type_node
)
7758 strcat (buf
, "unsigned short ");
7759 else if (declspecs
== unsigned_type_node
)
7760 strcat (buf
, "unsigned int ");
7761 else if (declspecs
== long_unsigned_type_node
)
7762 strcat (buf
, "unsigned long ");
7763 else if (declspecs
== long_long_unsigned_type_node
)
7764 strcat (buf
, "unsigned long long ");
7765 else if (declspecs
== unsigned_char_type_node
)
7766 strcat (buf
, "unsigned char ");
7770 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7772 if (declspecs
== float_type_node
)
7773 strcat (buf
, "float ");
7774 else if (declspecs
== double_type_node
)
7775 strcat (buf
, "double ");
7776 else if (declspecs
== long_double_type_node
)
7777 strcat (buf
, "long double ");
7781 if (TYPE_NAME (declspecs
)
7782 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7784 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7786 if (! TREE_STATIC_TEMPLATE (declspecs
))
7787 strcat (buf
, "struct ");
7788 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7792 tree chain
= protocol_list
;
7799 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7800 chain
= TREE_CHAIN (chain
);
7809 strcat (buf
, "untagged struct");
7815 if (TYPE_NAME (declspecs
)
7816 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7818 strcat (buf
, "union ");
7819 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7824 strcat (buf
, "untagged union ");
7828 if (TYPE_NAME (declspecs
)
7829 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7831 strcat (buf
, "enum ");
7832 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7837 strcat (buf
, "untagged enum ");
7841 strcat (buf
, "void ");
7846 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7851 tree chain
= protocol_list
;
7858 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7859 chain
= TREE_CHAIN (chain
);
7875 /* Given a tree node, produce a printable description of it in the given
7876 buffer, overwriting the buffer. */
7879 gen_declaration (atype_or_adecl
, buf
)
7880 tree atype_or_adecl
;
7884 gen_declaration_1 (atype_or_adecl
, buf
);
7888 /* Given a tree node, append a printable description to the end of the
7892 gen_declaration_1 (atype_or_adecl
, buf
)
7893 tree atype_or_adecl
;
7898 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7900 tree declspecs
; /* "identifier_node", "record_type" */
7901 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7903 /* We have a "raw", abstract declarator (typename). */
7904 declarator
= TREE_VALUE (atype_or_adecl
);
7905 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7907 gen_declspecs (declspecs
, buf
, 1);
7911 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7918 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7919 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7921 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7922 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7923 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7924 atype
= TREE_TYPE (atype_or_adecl
);
7926 /* Assume we have a *_type node. */
7927 atype
= atype_or_adecl
;
7929 if (is_complex_decl (atype
))
7933 /* Get the declaration specifier; it is at the end of the list. */
7934 declarator
= chain
= atype
;
7936 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7937 while (is_complex_decl (chain
));
7944 declarator
= NULL_TREE
;
7947 gen_declspecs (declspecs
, buf
, 0);
7949 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7950 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7951 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7953 const char *const decl_name
=
7954 (DECL_NAME (atype_or_adecl
)
7955 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7960 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7963 else if (decl_name
[0])
7966 strcat (buf
, decl_name
);
7969 else if (declarator
)
7972 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7977 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7979 /* Given a method tree, put a printable description into the given
7980 buffer (overwriting) and return a pointer to the buffer. */
7983 gen_method_decl (method
, buf
)
7990 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7993 gen_declaration_1 (TREE_TYPE (method
), buf
);
7997 chain
= METHOD_SEL_ARGS (method
);
8000 /* We have a chain of keyword_decls. */
8003 if (KEYWORD_KEY_NAME (chain
))
8004 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
8007 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
8010 gen_declaration_1 (TREE_TYPE (chain
), buf
);
8014 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
8015 if ((chain
= TREE_CHAIN (chain
)))
8020 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
8021 strcat (buf
, ", ...");
8022 else if (METHOD_ADD_ARGS (method
))
8024 /* We have a tree list node as generate by get_parm_info. */
8025 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
8027 /* Know we have a chain of parm_decls. */
8031 gen_declaration_1 (chain
, buf
);
8032 chain
= TREE_CHAIN (chain
);
8038 /* We have a unary selector. */
8039 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8047 /* Dump an @interface declaration of the supplied class CHAIN to the
8048 supplied file FP. Used to implement the -gen-decls option (which
8049 prints out an @interface declaration of all classes compiled in
8050 this run); potentially useful for debugging the compiler too. */
8052 dump_interface (fp
, chain
)
8056 /* FIXME: A heap overflow here whenever a method (or ivar)
8057 declaration is so long that it doesn't fit in the buffer. The
8058 code and all the related functions should be rewritten to avoid
8059 using fixed size buffers. */
8060 char *buf
= (char *) xmalloc (1024 * 10);
8061 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8062 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8063 tree nst_methods
= CLASS_NST_METHODS (chain
);
8064 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8066 fprintf (fp
, "\n@interface %s", my_name
);
8068 /* CLASS_SUPER_NAME is used to store the superclass name for
8069 classes, and the category name for categories. */
8070 if (CLASS_SUPER_NAME (chain
))
8072 const char *name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8074 if (TREE_CODE (chain
) == CATEGORY_IMPLEMENTATION_TYPE
8075 || TREE_CODE (chain
) == CATEGORY_INTERFACE_TYPE
)
8077 fprintf (fp
, " (%s)\n", name
);
8081 fprintf (fp
, " : %s\n", name
);
8087 /* FIXME - the following doesn't seem to work at the moment. */
8090 fprintf (fp
, "{\n");
8093 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8094 ivar_decls
= TREE_CHAIN (ivar_decls
);
8097 fprintf (fp
, "}\n");
8102 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8103 nst_methods
= TREE_CHAIN (nst_methods
);
8108 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8109 cls_methods
= TREE_CHAIN (cls_methods
);
8112 fprintf (fp
, "@end\n");
8115 /* Demangle function for Objective-C */
8117 objc_demangle (mangled
)
8118 const char *mangled
;
8120 char *demangled
, *cp
;
8122 if (mangled
[0] == '_' &&
8123 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8126 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8127 if (mangled
[1] == 'i')
8128 *cp
++ = '-'; /* for instance method */
8130 *cp
++ = '+'; /* for class method */
8131 *cp
++ = '['; /* opening left brace */
8132 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8133 while (*cp
&& *cp
== '_')
8134 cp
++; /* skip any initial underbars in class name */
8135 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8138 free(demangled
); /* not mangled name */
8141 if (cp
[1] == '_') /* easy case: no category name */
8143 *cp
++ = ' '; /* replace two '_' with one ' ' */
8144 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8148 *cp
++ = '('; /* less easy case: category name */
8149 cp
= strchr(cp
, '_');
8152 free(demangled
); /* not mangled name */
8156 *cp
++ = ' '; /* overwriting 1st char of method name... */
8157 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8159 while (*cp
&& *cp
== '_')
8160 cp
++; /* skip any initial underbars in method name */
8163 *cp
= ':'; /* replace remaining '_' with ':' */
8164 *cp
++ = ']'; /* closing right brace */
8165 *cp
++ = 0; /* string terminator */
8169 return mangled
; /* not an objc mangled name */
8173 objc_printable_name (decl
, kind
)
8175 int kind ATTRIBUTE_UNUSED
;
8177 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8183 gcc_obstack_init (&util_obstack
);
8184 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8186 errbuf
= (char *) xmalloc (BUFSIZE
);
8188 synth_module_prologue ();
8194 struct imp_entry
*impent
;
8196 /* The internally generated initializers appear to have missing braces.
8197 Don't warn about this. */
8198 int save_warn_missing_braces
= warn_missing_braces
;
8199 warn_missing_braces
= 0;
8201 /* A missing @end may not be detected by the parser. */
8202 if (objc_implementation_context
)
8204 warning ("`@end' missing in implementation context");
8205 finish_class (objc_implementation_context
);
8206 objc_ivar_chain
= NULL_TREE
;
8207 objc_implementation_context
= NULL_TREE
;
8210 generate_forward_declaration_to_string_table ();
8212 /* Process the static instances here because initialization of objc_symtab
8214 if (objc_static_instances
)
8215 generate_static_references ();
8217 if (imp_list
|| class_names_chain
8218 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8219 generate_objc_symtab_decl ();
8221 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8223 objc_implementation_context
= impent
->imp_context
;
8224 implementation_template
= impent
->imp_template
;
8226 UOBJC_CLASS_decl
= impent
->class_decl
;
8227 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8229 /* Dump the @interface of each class as we compile it, if the
8230 -gen-decls option is in use. TODO: Dump the classes in the
8231 order they were found, rather than in reverse order as we
8233 if (flag_gen_declaration
)
8235 dump_interface (gen_declaration_file
, objc_implementation_context
);
8238 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8240 /* all of the following reference the string pool... */
8241 generate_ivar_lists ();
8242 generate_dispatch_tables ();
8243 generate_shared_structures ();
8247 generate_dispatch_tables ();
8248 generate_category (objc_implementation_context
);
8252 /* If we are using an array of selectors, we must always
8253 finish up the array decl even if no selectors were used. */
8254 if (! flag_next_runtime
|| sel_ref_chain
)
8255 build_selector_translation_table ();
8258 generate_protocols ();
8260 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8261 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8263 /* Arrange for ObjC data structures to be initialized at run time. */
8264 rtx init_sym
= build_module_descriptor ();
8265 if (init_sym
&& targetm
.have_ctors_dtors
)
8266 (* targetm
.asm_out
.constructor
) (init_sym
, DEFAULT_INIT_PRIORITY
);
8269 /* Dump the class references. This forces the appropriate classes
8270 to be linked into the executable image, preserving unix archive
8271 semantics. This can be removed when we move to a more dynamically
8272 linked environment. */
8274 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8276 handle_class_ref (chain
);
8277 if (TREE_PURPOSE (chain
))
8278 generate_classref_translation_entry (chain
);
8281 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8282 handle_impent (impent
);
8284 /* Dump the string table last. */
8286 generate_strings ();
8293 /* Run through the selector hash tables and print a warning for any
8294 selector which has multiple methods. */
8296 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8297 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8300 tree meth
= hsh
->key
;
8301 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8305 warning ("potential selector conflict for method `%s'",
8306 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8307 warn_with_method ("found", type
, meth
);
8308 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8309 warn_with_method ("found", type
, loop
->value
);
8312 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8313 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8316 tree meth
= hsh
->key
;
8317 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8321 warning ("potential selector conflict for method `%s'",
8322 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8323 warn_with_method ("found", type
, meth
);
8324 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8325 warn_with_method ("found", type
, loop
->value
);
8329 warn_missing_braces
= save_warn_missing_braces
;
8332 /* Subroutines of finish_objc. */
8335 generate_classref_translation_entry (chain
)
8338 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8341 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8343 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8344 expr
= build_c_cast (type
, expr
); /* cast! */
8346 name
= DECL_NAME (TREE_PURPOSE (chain
));
8348 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8350 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8351 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8353 /* The decl that is returned from start_decl is the one that we
8354 forward declared in build_class_reference. */
8355 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
);
8356 DECL_CONTEXT (decl
) = NULL_TREE
;
8357 finish_decl (decl
, expr
, NULL_TREE
);
8362 handle_class_ref (chain
)
8365 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8366 char *string
= (char *) alloca (strlen (name
) + 30);
8370 sprintf (string
, "%sobjc_class_name_%s",
8371 (flag_next_runtime
? "." : "__"), name
);
8373 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8374 if (flag_next_runtime
)
8376 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8381 /* Make a decl for this name, so we can use its address in a tree. */
8382 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8383 DECL_EXTERNAL (decl
) = 1;
8384 TREE_PUBLIC (decl
) = 1;
8387 rest_of_decl_compilation (decl
, 0, 0, 0);
8389 /* Make a decl for the address. */
8390 sprintf (string
, "%sobjc_class_ref_%s",
8391 (flag_next_runtime
? "." : "__"), name
);
8392 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8393 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8394 DECL_INITIAL (decl
) = exp
;
8395 TREE_STATIC (decl
) = 1;
8396 TREE_USED (decl
) = 1;
8399 rest_of_decl_compilation (decl
, 0, 0, 0);
8403 handle_impent (impent
)
8404 struct imp_entry
*impent
;
8408 objc_implementation_context
= impent
->imp_context
;
8409 implementation_template
= impent
->imp_template
;
8411 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8413 const char *const class_name
=
8414 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8416 string
= (char *) alloca (strlen (class_name
) + 30);
8418 sprintf (string
, "%sobjc_class_name_%s",
8419 (flag_next_runtime
? "." : "__"), class_name
);
8421 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8423 const char *const class_name
=
8424 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8425 const char *const class_super_name
=
8426 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8428 string
= (char *) alloca (strlen (class_name
)
8429 + strlen (class_super_name
) + 30);
8431 /* Do the same for categories. Even though no references to
8432 these symbols are generated automatically by the compiler, it
8433 gives you a handle to pull them into an archive by hand. */
8434 sprintf (string
, "*%sobjc_category_name_%s_%s",
8435 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8440 #ifdef ASM_DECLARE_CLASS_REFERENCE
8441 if (flag_next_runtime
)
8443 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8451 init
= build_int_2 (0, 0);
8452 TREE_TYPE (init
) = c_common_type_for_size (BITS_PER_WORD
, 1);
8453 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
8454 TREE_PUBLIC (decl
) = 1;
8455 TREE_READONLY (decl
) = 1;
8456 TREE_USED (decl
) = 1;
8457 TREE_CONSTANT (decl
) = 1;
8458 DECL_CONTEXT (decl
) = 0;
8459 DECL_ARTIFICIAL (decl
) = 1;
8460 DECL_INITIAL (decl
) = init
;
8461 assemble_variable (decl
, 1, 0, 0);
8465 /* Look up ID as an instance variable. */
8467 lookup_objc_ivar (id
)
8472 if (objc_method_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8473 /* We have a message to super. */
8474 return get_super_receiver ();
8475 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8477 if (is_private (decl
))
8478 return error_mark_node
;
8480 return build_ivar_reference (id
);
8486 #include "gt-objc-objc-act.h"
8487 #include "gtype-objc.h"