1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Steve Naroff.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
36 #include "c-family/c-common.h"
37 #include "c-family/c-pragma.h"
39 #include "langhooks.h"
48 #include "diagnostic-core.h"
51 #include "tree-iterator.h"
53 #include "langhooks-def.h"
55 /* For default_tree_printer (). */
56 #include "tree-pretty-print.h"
58 /* For enum gimplify_status */
61 #define OBJC_VOID_AT_END void_list_node
63 static unsigned int should_call_super_dealloc
= 0;
65 /* When building Objective-C++, we need in_late_binary_op. */
67 bool in_late_binary_op
= false;
70 /* When building Objective-C++, we are not linking against the C front-end
71 and so need to replicate the C tree-construction functions in some way. */
73 #define OBJCP_REMAP_FUNCTIONS
74 #include "objcp-decl.h"
77 /* This is the default way of generating a method name. */
78 /* I am not sure it is really correct.
79 Perhaps there's a danger that it will make name conflicts
80 if method names contain underscores. -- rms. */
81 #ifndef OBJC_GEN_METHOD_LABEL
82 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
85 sprintf ((BUF), "_%s_%s_%s_%s", \
86 ((IS_INST) ? "i" : "c"), \
88 ((CAT_NAME)? (CAT_NAME) : ""), \
90 for (temp = (BUF); *temp; temp++) \
91 if (*temp == ':') *temp = '_'; \
95 /* These need specifying. */
96 #ifndef OBJC_FORWARDING_STACK_OFFSET
97 #define OBJC_FORWARDING_STACK_OFFSET 0
100 #ifndef OBJC_FORWARDING_MIN_OFFSET
101 #define OBJC_FORWARDING_MIN_OFFSET 0
104 /* Set up for use of obstacks. */
108 /* This obstack is used to accumulate the encoding of a data type. */
109 static struct obstack util_obstack
;
111 /* This points to the beginning of obstack contents, so we can free
112 the whole contents. */
115 /* The version identifies which language generation and runtime
116 the module (file) was compiled for, and is recorded in the
117 module descriptor. */
119 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
120 #define PROTOCOL_VERSION 2
122 /* (Decide if these can ever be validly changed.) */
123 #define OBJC_ENCODE_INLINE_DEFS 0
124 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
126 /*** Private Interface (procedures) ***/
128 /* Used by compile_file. */
130 static void init_objc (void);
131 static void finish_objc (void);
133 /* Code generation. */
135 static tree
objc_build_constructor (tree
, VEC(constructor_elt
,gc
) *);
136 static tree
build_objc_method_call (location_t
, int, tree
, tree
, tree
, tree
);
137 static tree
get_proto_encoding (tree
);
138 static tree
lookup_interface (tree
);
139 static tree
objc_add_static_instance (tree
, tree
);
141 static tree
start_class (enum tree_code
, tree
, tree
, tree
);
142 static tree
continue_class (tree
);
143 static void finish_class (tree
);
144 static void start_method_def (tree
);
146 static void objc_start_function (tree
, tree
, tree
, tree
);
148 static void objc_start_function (tree
, tree
, tree
, struct c_arg_info
*);
150 static tree
start_protocol (enum tree_code
, tree
, tree
);
151 static tree
build_method_decl (enum tree_code
, tree
, tree
, tree
, bool);
152 static tree
objc_add_method (tree
, tree
, int, bool);
153 static tree
add_instance_variable (tree
, objc_ivar_visibility_kind
, tree
);
154 static tree
build_ivar_reference (tree
);
155 static tree
is_ivar (tree
, tree
);
157 static void build_objc_exception_stuff (void);
158 static void build_next_objc_exception_stuff (void);
160 /* We only need the following for ObjC; ObjC++ will use C++'s definition
161 of DERIVED_FROM_P. */
163 static bool objc_derived_from_p (tree
, tree
);
164 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
168 static void objc_gen_one_property_datum (tree
, tree
, tree
, bool*);
169 static void objc_gen_property_data (tree
, tree
);
170 static void objc_synthesize_getter (tree
, tree
, tree
);
171 static void objc_process_getter_setter (tree
, tree
, bool);
172 static void objc_synthesize_setter (tree
, tree
, tree
);
173 static char *objc_build_property_ivar_name (tree
);
174 static char *objc_build_property_setter_name (tree
, bool);
175 static int match_proto_with_proto (tree
, tree
, int);
176 static tree
lookup_property (tree
, tree
);
177 static tree
lookup_property_in_list (tree
, tree
);
178 static tree
lookup_property_in_protocol_list (tree
, tree
);
179 static tree
objc_setter_func_call (tree
, tree
, tree
);
180 static tree
build_property_reference (tree
, tree
);
181 static tree
is_property (tree
, tree
);
182 /* Set on a CALL_EXPR if it is for call to a getter function represented by an
183 objective-c property declaration. */
184 #define CALL_EXPR_OBJC_PROPERTY_GETTER(NODE) \
185 (CALL_EXPR_CHECK(NODE)->base.deprecated_flag)
187 static void objc_xref_basetypes (tree
, tree
);
189 static void build_class_template (void);
190 static void build_selector_template (void);
191 static void build_category_template (void);
192 static void build_super_template (void);
193 static tree
build_protocol_initializer (tree
, tree
, tree
, tree
, tree
);
194 static tree
get_class_ivars (tree
, bool);
195 static tree
generate_protocol_list (tree
);
196 static void build_protocol_reference (tree
);
198 static void build_fast_enumeration_state_template (void);
201 static void objc_generate_cxx_cdtors (void);
205 static void objc_decl_method_attributes (tree
*, tree
, int);
206 static tree
build_keyword_selector (tree
);
207 static const char *synth_id_with_class_suffix (const char *, tree
);
209 /* Hash tables to manage the global pool of method prototypes. */
211 hash
*nst_method_hash_list
= 0;
212 hash
*cls_method_hash_list
= 0;
214 static hash
hash_lookup (hash
*, tree
);
215 static tree
lookup_method (tree
, tree
);
216 static tree
lookup_method_static (tree
, tree
, int);
218 static tree
add_class (tree
, tree
);
219 static void add_category (tree
, tree
);
220 static inline tree
lookup_category (tree
, tree
);
224 class_names
, /* class, category, protocol, module names */
225 meth_var_names
, /* method and variable names */
226 meth_var_types
/* method and variable type descriptors */
229 static tree
add_objc_string (tree
, enum string_section
);
230 static void build_selector_table_decl (void);
232 /* Protocol additions. */
234 static tree
lookup_protocol (tree
);
235 static tree
lookup_and_install_protocols (tree
);
239 static void encode_type_qualifiers (tree
);
240 static void encode_type (tree
, int, int);
241 static void encode_field_decl (tree
, int, int);
244 static void really_start_method (tree
, tree
);
246 static void really_start_method (tree
, struct c_arg_info
*);
248 static int comp_proto_with_proto (tree
, tree
, int);
249 static tree
get_arg_type_list (tree
, int, int);
250 static tree
objc_decay_parm_type (tree
);
251 static void objc_push_parm (tree
);
253 static tree
objc_get_parm_info (int);
255 static struct c_arg_info
*objc_get_parm_info (int);
258 /* Utilities for debugging and error diagnostics. */
260 static char *gen_type_name (tree
);
261 static char *gen_type_name_0 (tree
);
262 static char *gen_method_decl (tree
);
263 static char *gen_declaration (tree
);
265 /* Everything else. */
267 static tree
create_field_decl (tree
, const char *);
268 static void add_class_reference (tree
);
269 static void build_protocol_template (void);
270 static tree
encode_method_prototype (tree
);
271 static void generate_classref_translation_entry (tree
);
272 static void handle_class_ref (tree
);
273 static void generate_struct_by_value_array (void)
275 static void mark_referenced_methods (void);
276 static void generate_objc_image_info (void);
277 static bool objc_type_valid_for_messaging (tree typ
);
279 /*** Private Interface (data) ***/
281 /* Reserved tag definitions. */
283 #define OBJECT_TYPEDEF_NAME "id"
284 #define CLASS_TYPEDEF_NAME "Class"
286 #define TAG_OBJECT "objc_object"
287 #define TAG_CLASS "objc_class"
288 #define TAG_SUPER "objc_super"
289 #define TAG_SELECTOR "objc_selector"
291 #define UTAG_CLASS "_objc_class"
292 #define UTAG_IVAR "_objc_ivar"
293 #define UTAG_IVAR_LIST "_objc_ivar_list"
294 #define UTAG_METHOD "_objc_method"
295 #define UTAG_METHOD_LIST "_objc_method_list"
296 #define UTAG_CATEGORY "_objc_category"
297 #define UTAG_MODULE "_objc_module"
298 #define UTAG_SYMTAB "_objc_symtab"
299 #define UTAG_SUPER "_objc_super"
300 #define UTAG_SELECTOR "_objc_selector"
302 #define UTAG_PROTOCOL "_objc_protocol"
303 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
304 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
306 /* Note that the string object global name is only needed for the
308 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
310 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
312 #define TAG_ENUMERATION_MUTATION "objc_enumerationMutation"
313 #define TAG_FAST_ENUMERATION_STATE "__objcFastEnumerationState"
315 static const char *TAG_GETCLASS
;
316 static const char *TAG_GETMETACLASS
;
317 static const char *TAG_MSGSEND
;
318 static const char *TAG_MSGSENDSUPER
;
319 /* The NeXT Objective-C messenger may have two extra entry points, for use
320 when returning a structure. */
321 static const char *TAG_MSGSEND_STRET
;
322 static const char *TAG_MSGSENDSUPER_STRET
;
323 static const char *default_constant_string_class_name
;
325 /* Runtime metadata flags. */
326 #define CLS_FACTORY 0x0001L
327 #define CLS_META 0x0002L
328 #define CLS_HAS_CXX_STRUCTORS 0x2000L
330 #define OBJC_MODIFIER_STATIC 0x00000001
331 #define OBJC_MODIFIER_FINAL 0x00000002
332 #define OBJC_MODIFIER_PUBLIC 0x00000004
333 #define OBJC_MODIFIER_PRIVATE 0x00000008
334 #define OBJC_MODIFIER_PROTECTED 0x00000010
335 #define OBJC_MODIFIER_NATIVE 0x00000020
336 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
337 #define OBJC_MODIFIER_ABSTRACT 0x00000080
338 #define OBJC_MODIFIER_VOLATILE 0x00000100
339 #define OBJC_MODIFIER_TRANSIENT 0x00000200
340 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
342 /* NeXT-specific tags. */
344 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
345 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
346 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
347 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
348 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
349 #define TAG_EXCEPTIONMATCH "objc_exception_match"
350 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
351 #define TAG_SYNCENTER "objc_sync_enter"
352 #define TAG_SYNCEXIT "objc_sync_exit"
353 #define TAG_SETJMP "_setjmp"
354 #define UTAG_EXCDATA "_objc_exception_data"
356 #define TAG_ASSIGNIVAR "objc_assign_ivar"
357 #define TAG_ASSIGNGLOBAL "objc_assign_global"
358 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
360 /* Branch entry points. All that matters here are the addresses;
361 functions with these names do not really exist in libobjc. */
363 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
364 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
366 #define TAG_CXX_CONSTRUCT ".cxx_construct"
367 #define TAG_CXX_DESTRUCT ".cxx_destruct"
369 /* GNU-specific tags. */
371 #define TAG_EXECCLASS "__objc_exec_class"
372 #define TAG_GNUINIT "__objc_gnu_init"
374 /* Flags for lookup_method_static(). */
375 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
376 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
378 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
379 tree objc_global_trees
[OCTI_MAX
];
381 static void handle_impent (struct imp_entry
*);
383 struct imp_entry
*imp_list
= 0;
384 int imp_count
= 0; /* `@implementation' */
385 int cat_count
= 0; /* `@category' */
387 enum tree_code objc_inherit_code
;
388 objc_ivar_visibility_kind objc_ivar_visibility
;
390 /* Use to generate method labels. */
391 static int method_slot
= 0;
393 /* Flag to say whether methods in a protocol are optional or
395 static bool objc_method_optional_flag
= false;
397 static bool property_readonly
;
398 static tree property_getter
;
399 static tree property_setter
;
400 static tree property_ivar
;
401 static bool property_copies
;
402 static bool in_objc_property_setter_name_context
= false;
404 static int objc_collecting_ivars
= 0;
408 static char *errbuf
; /* Buffer for error diagnostics */
410 /* Data imported from tree.c. */
412 extern enum debug_info_type write_symbols
;
414 /* Data imported from toplev.c. */
416 extern const char *dump_base_name
;
418 static int flag_typed_selectors
;
420 /* Store all constructed constant strings in a hash table so that
421 they get uniqued properly. */
423 struct GTY(()) string_descriptor
{
424 /* The literal argument . */
427 /* The resulting constant string. */
431 static GTY((param_is (struct string_descriptor
))) htab_t string_htab
;
433 FILE *gen_declaration_file
;
435 /* Tells "encode_pointer/encode_aggregate" whether we are generating
436 type descriptors for instance variables (as opposed to methods).
437 Type descriptors for instance variables contain more information
438 than methods (for static typing and embedded structures). */
440 static int generating_instance_variables
= 0;
442 /* For building an objc struct. These may not be used when this file
443 is compiled as part of obj-c++. */
445 static bool objc_building_struct
;
446 static struct c_struct_parse_info
*objc_struct_info ATTRIBUTE_UNUSED
;
448 /* Start building a struct for objc. */
451 objc_start_struct (tree name
)
453 gcc_assert (!objc_building_struct
);
454 objc_building_struct
= true;
455 return start_struct (input_location
, RECORD_TYPE
, name
, &objc_struct_info
);
458 /* Finish building a struct for objc. */
461 objc_finish_struct (tree type
, tree fieldlist
)
463 gcc_assert (objc_building_struct
);
464 objc_building_struct
= false;
465 return finish_struct (input_location
, type
, fieldlist
, NULL_TREE
,
470 build_sized_array_type (tree base_type
, int size
)
472 tree index_type
= build_index_type (build_int_cst (NULL_TREE
, size
- 1));
473 return build_array_type (base_type
, index_type
);
477 add_field_decl (tree type
, const char *name
, tree
**chain
)
479 tree field
= create_field_decl (type
, name
);
483 *chain
= &DECL_CHAIN (field
);
488 /* Some platforms pass small structures through registers versus
489 through an invisible pointer. Determine at what size structure is
490 the transition point between the two possibilities. */
493 generate_struct_by_value_array (void)
498 int aggregate_in_mem
[32];
501 /* Presumably no platform passes 32 byte structures in a register. */
502 for (i
= 1; i
< 32; i
++)
507 /* Create an unnamed struct that has `i' character components */
508 type
= objc_start_struct (NULL_TREE
);
510 strcpy (buffer
, "c1");
511 decls
= add_field_decl (char_type_node
, buffer
, &chain
);
513 for (j
= 1; j
< i
; j
++)
515 sprintf (buffer
, "c%d", j
+ 1);
516 add_field_decl (char_type_node
, buffer
, &chain
);
518 objc_finish_struct (type
, decls
);
520 aggregate_in_mem
[i
] = aggregate_value_p (type
, 0);
521 if (!aggregate_in_mem
[i
])
525 /* We found some structures that are returned in registers instead of memory
526 so output the necessary data. */
529 for (i
= 31; i
>= 0; i
--)
530 if (!aggregate_in_mem
[i
])
532 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
534 /* The first member of the structure is always 0 because we don't handle
535 structures with 0 members */
536 printf ("static int struct_forward_array[] = {\n 0");
538 for (j
= 1; j
<= i
; j
++)
539 printf (", %d", aggregate_in_mem
[j
]);
546 /* FIXME: We need to intercept calls to warn_deprecated_use, since that
547 ultimately calls warning () with a "qD" formatter for decls. The 'D'
548 formatter does not handle ObjC-specific decls (in ObjC++). For now, we
549 interpose a switch to the default handler which simply prints the decl
551 Eventually, we should handle this within the objc{,p}/ code. */
554 objc_warn_deprecated_use (tree depitem
, tree attr
)
556 if (DECL_P (depitem
))
558 static bool (*sav_printer
) (pretty_printer
*, text_info
*, const char *,
559 int, bool, bool, bool) = NULL
;
560 if (sav_printer
== NULL
)
561 sav_printer
= diagnostic_format_decoder (global_dc
) ;
562 diagnostic_format_decoder (global_dc
) = &default_tree_printer
;
563 warn_deprecated_use (depitem
, attr
);
564 diagnostic_format_decoder (global_dc
) = sav_printer
;
567 warn_deprecated_use (depitem
, attr
);
574 if (cxx_init () == false)
576 if (c_objc_common_init () == false)
580 /* If gen_declaration desired, open the output file. */
581 if (flag_gen_declaration
)
583 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
584 gen_declaration_file
= fopen (dumpname
, "w");
585 if (gen_declaration_file
== 0)
586 fatal_error ("can't open %s: %m", dumpname
);
590 if (flag_next_runtime
)
592 TAG_GETCLASS
= "objc_getClass";
593 TAG_GETMETACLASS
= "objc_getMetaClass";
594 TAG_MSGSEND
= "objc_msgSend";
595 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
596 TAG_MSGSEND_STRET
= "objc_msgSend_stret";
597 TAG_MSGSENDSUPER_STRET
= "objc_msgSendSuper_stret";
598 default_constant_string_class_name
= "NSConstantString";
602 TAG_GETCLASS
= "objc_get_class";
603 TAG_GETMETACLASS
= "objc_get_meta_class";
604 TAG_MSGSEND
= "objc_msg_lookup";
605 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
606 /* GNU runtime does not provide special functions to support
607 structure-returning methods. */
608 default_constant_string_class_name
= "NXConstantString";
609 flag_typed_selectors
= 1;
610 /* GNU runtime does not need the compiler to change code
611 in order to do GC. */
614 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
621 if (print_struct_values
&& !flag_compare_debug
)
622 generate_struct_by_value_array ();
627 /* This is called automatically (at the very end of compilation) by
628 c_write_global_declarations and cp_write_global_declarations. */
630 objc_write_global_declarations (void)
632 mark_referenced_methods ();
634 /* Finalize Objective-C runtime data. */
637 if (gen_declaration_file
)
638 fclose (gen_declaration_file
);
641 /* Return the first occurrence of a method declaration corresponding
642 to sel_name in rproto_list. Search rproto_list recursively.
643 If is_class is 0, search for instance methods, otherwise for class
646 lookup_method_in_protocol_list (tree rproto_list
, tree sel_name
,
652 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
654 p
= TREE_VALUE (rproto
);
656 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
658 if ((fnd
= lookup_method (is_class
659 ? PROTOCOL_CLS_METHODS (p
)
660 : PROTOCOL_NST_METHODS (p
), sel_name
)))
662 else if (PROTOCOL_LIST (p
))
663 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
668 ; /* An identifier...if we could not find a protocol. */
679 lookup_protocol_in_reflist (tree rproto_list
, tree lproto
)
683 /* Make sure the protocol is supported by the object on the rhs. */
684 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
687 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
689 p
= TREE_VALUE (rproto
);
691 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
696 else if (PROTOCOL_LIST (p
))
697 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
706 ; /* An identifier...if we could not find a protocol. */
713 objc_start_class_interface (tree klass
, tree super_class
,
714 tree protos
, tree attributes
)
717 warning_at (input_location
, OPT_Wattributes
,
718 "class attributes are not available in this version"
719 " of the compiler, (ignored)");
720 objc_interface_context
722 = start_class (CLASS_INTERFACE_TYPE
, klass
, super_class
, protos
);
723 objc_ivar_visibility
= OBJC_IVAR_VIS_PROTECTED
;
727 objc_start_category_interface (tree klass
, tree categ
,
728 tree protos
, tree attributes
)
731 warning_at (input_location
, OPT_Wattributes
,
732 "category attributes are not available in this version"
733 " of the compiler, (ignored)");
734 objc_interface_context
735 = start_class (CATEGORY_INTERFACE_TYPE
, klass
, categ
, protos
);
737 = continue_class (objc_interface_context
);
741 objc_start_protocol (tree name
, tree protos
, tree attributes
)
744 warning_at (input_location
, OPT_Wattributes
,
745 "protocol attributes are not available in this version"
746 " of the compiler, (ignored)");
747 objc_interface_context
748 = start_protocol (PROTOCOL_INTERFACE_TYPE
, name
, protos
);
749 objc_method_optional_flag
= false;
753 objc_continue_interface (void)
756 = continue_class (objc_interface_context
);
760 objc_finish_interface (void)
762 finish_class (objc_interface_context
);
763 objc_interface_context
= NULL_TREE
;
764 objc_method_optional_flag
= false;
768 objc_start_class_implementation (tree klass
, tree super_class
)
770 objc_implementation_context
772 = start_class (CLASS_IMPLEMENTATION_TYPE
, klass
, super_class
, NULL_TREE
);
773 objc_ivar_visibility
= OBJC_IVAR_VIS_PROTECTED
;
777 objc_start_category_implementation (tree klass
, tree categ
)
779 objc_implementation_context
780 = start_class (CATEGORY_IMPLEMENTATION_TYPE
, klass
, categ
, NULL_TREE
);
782 = continue_class (objc_implementation_context
);
786 objc_continue_implementation (void)
789 = continue_class (objc_implementation_context
);
793 objc_finish_implementation (void)
796 if (flag_objc_call_cxx_cdtors
)
797 objc_generate_cxx_cdtors ();
800 if (objc_implementation_context
)
802 finish_class (objc_implementation_context
);
803 objc_ivar_chain
= NULL_TREE
;
804 objc_implementation_context
= NULL_TREE
;
807 warning (0, "%<@end%> must appear in an @implementation context");
811 objc_set_visibility (objc_ivar_visibility_kind visibility
)
813 if (visibility
== OBJC_IVAR_VIS_PACKAGE
)
814 warning (0, "%<@package%> presently has the same effect as %<@public%>");
815 objc_ivar_visibility
= visibility
;
819 objc_set_method_opt (bool optional
)
821 objc_method_optional_flag
= optional
;
822 if (!objc_interface_context
823 || TREE_CODE (objc_interface_context
) != PROTOCOL_INTERFACE_TYPE
)
825 error ("@optional/@required is allowed in @protocol context only.");
826 objc_method_optional_flag
= false;
830 /* This routine gathers property attribute information from the attribute
831 portion of a property declaration. */
834 objc_set_property_attr (location_t loc
, objc_property_attribute_kind attr
,
837 static char string
[BUFSIZE
];
840 case OBJC_PATTR_INIT
: /* init */
841 property_readonly
= property_copies
= false;
842 property_setter
= property_getter
= property_ivar
= NULL_TREE
;
844 case OBJC_PATTR_READONLY
: /* readonly */
845 property_readonly
= true;
847 case OBJC_PATTR_GETTER
: /* getter = ident */
848 if (property_getter
!= NULL_TREE
)
849 error_at (loc
, "the %<getter%> attribute may only be specified once");
850 property_getter
= ident
;
852 case OBJC_PATTR_SETTER
: /* setter = ident */
853 if (property_setter
!= NULL_TREE
)
854 error_at (loc
, "the %<setter%> attribute may only be specified once");
855 /* setters always have a trailing ':' in their name. In fact, this is the
856 only syntax that parser recognizes for a setter name. Must add a trailing
857 ':' here so name matches that of the declaration of user instance method
859 sprintf (string
, "%s:", IDENTIFIER_POINTER (ident
));
860 property_setter
= get_identifier (string
);;
862 case OBJC_PATTR_IVAR
: /* ivar = ident */
863 if (property_ivar
!= NULL_TREE
)
864 error_at (loc
, "the %<ivar%> attribute may only be specified once");
865 else if (objc_interface_context
)
867 warning_at (loc
, 0, "the %<ivar%> attribute is ignored in an @interface");
868 property_ivar
= NULL_TREE
;
871 property_ivar
= ident
;
873 case OBJC_PATTR_COPIES
: /* copies */
874 property_copies
= true;
881 /* This routine builds a 'property_decl' tree node and adds it to the list
882 of such properties in the current class. It also checks for duplicates.
886 objc_add_property_variable (tree decl
)
890 tree interface
= NULL_TREE
;
892 if (objc_implementation_context
)
894 interface
= lookup_interface (CLASS_NAME (objc_implementation_context
));
897 error ("no class property can be implemented without an interface");
900 if (TREE_CODE (objc_implementation_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
902 interface
= lookup_category (interface
,
903 CLASS_SUPER_NAME (objc_implementation_context
));
906 error ("no category property can be implemented without an interface");
911 else if (!objc_interface_context
)
913 fatal_error ("property declaration not in @interface or @implementation context");
917 property_decl
= make_node (PROPERTY_DECL
);
918 TREE_TYPE (property_decl
) = TREE_TYPE (decl
);
920 PROPERTY_NAME (property_decl
) = DECL_NAME (decl
);
921 PROPERTY_GETTER_NAME (property_decl
) = property_getter
;
922 PROPERTY_SETTER_NAME (property_decl
) = property_setter
;
923 PROPERTY_IVAR_NAME (property_decl
) = property_ivar
;
924 PROPERTY_READONLY (property_decl
) = property_readonly
926 : boolean_false_node
;
927 PROPERTY_COPIES (property_decl
) = property_copies
929 : boolean_false_node
;
931 if (objc_interface_context
)
933 /* Doing the property in interface declaration. */
935 /* Issue error if property and an ivar name match. */
936 if (TREE_CODE (objc_interface_context
) == CLASS_INTERFACE_TYPE
937 && is_ivar (CLASS_IVARS (objc_interface_context
), DECL_NAME (decl
)))
938 error ("property %qD may not have the same name as an ivar in the class", decl
);
939 /* must check for duplicate property declarations. */
940 for (x
= CLASS_PROPERTY_DECL (objc_interface_context
); x
; x
= TREE_CHAIN (x
))
942 if (PROPERTY_NAME (x
) == DECL_NAME (decl
))
944 error ("duplicate property declaration %qD", decl
);
948 TREE_CHAIN (property_decl
) = CLASS_PROPERTY_DECL (objc_interface_context
);
949 CLASS_PROPERTY_DECL (objc_interface_context
) = property_decl
;
953 /* Doing the property in implementation context. */
954 /* If property is not declared in the interface issue error. */
955 for (x
= CLASS_PROPERTY_DECL (interface
); x
; x
= TREE_CHAIN (x
))
956 if (PROPERTY_NAME (x
) == DECL_NAME (decl
))
960 error ("no declaration of property %qD found in the interface", decl
);
963 /* readonlys must also match. */
964 if (PROPERTY_READONLY (x
) != PROPERTY_READONLY (property_decl
))
966 error ("property %qD %<readonly%> attribute conflicts with its"
967 " interface version", decl
);
969 /* copies must also match. */
970 if (PROPERTY_COPIES (x
) != PROPERTY_COPIES (property_decl
))
972 error ("property %qD %<copies%> attribute conflicts with its"
973 " interface version", decl
);
975 /* Cannot have readonly and setter attribute for the same property. */
976 if (PROPERTY_READONLY (property_decl
) == boolean_true_node
&&
977 PROPERTY_SETTER_NAME (property_decl
))
979 warning (0, "a %<readonly%> property cannot have a setter (ignored)");
980 PROPERTY_SETTER_NAME (property_decl
) = NULL_TREE
;
982 /* Add the property to the list of properties for current implementation. */
983 TREE_CHAIN (property_decl
) = IMPL_PROPERTY_DECL (objc_implementation_context
);
984 IMPL_PROPERTY_DECL (objc_implementation_context
) = property_decl
;
988 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
992 lookup_property_in_list (tree chain
, tree property
)
995 for (x
= CLASS_PROPERTY_DECL (chain
); x
; x
= TREE_CHAIN (x
))
996 if (PROPERTY_NAME (x
) == property
)
1001 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
1003 static tree
lookup_property_in_protocol_list (tree rproto_list
, tree property
)
1006 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
1008 tree p
= TREE_VALUE (rproto
);
1009 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
1011 if ((x
= lookup_property_in_list (p
, property
)))
1013 if (PROTOCOL_LIST (p
))
1014 return lookup_property_in_protocol_list (PROTOCOL_LIST (p
), property
);
1018 ; /* An identifier...if we could not find a protocol. */
1024 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
1025 chain of interface hierarchy.
1028 lookup_property (tree interface_type
, tree property
)
1030 tree inter
= interface_type
;
1034 if ((x
= lookup_property_in_list (inter
, property
)))
1036 /* Failing that, look for the property in each category of the class. */
1038 while ((category
= CLASS_CATEGORY_LIST (category
)))
1039 if ((x
= lookup_property_in_list (category
, property
)))
1042 /* Failing to find in categories, look for property in protocol list. */
1043 if (CLASS_PROTOCOL_LIST (inter
)
1044 && (x
= lookup_property_in_protocol_list (
1045 CLASS_PROTOCOL_LIST (inter
), property
)))
1048 /* Failing that, climb up the inheritance hierarchy. */
1049 inter
= lookup_interface (CLASS_SUPER_NAME (inter
));
1054 /* This routine recognizes a dot-notation for a propery reference and generates a call to
1055 the getter function for this property. In all other cases, it returns a NULL_TREE.
1059 objc_build_getter_call (tree receiver
, tree component
)
1064 if (receiver
== NULL_TREE
1065 || receiver
== error_mark_node
1066 || (rtype
= TREE_TYPE (receiver
)) == NULL_TREE
)
1069 if (component
== NULL_TREE
1070 || component
== error_mark_node
1071 || TREE_CODE (component
) != IDENTIFIER_NODE
)
1074 if (objc_is_id (rtype
))
1076 tree rprotos
= (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype
))
1077 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype
))
1080 x
= lookup_property_in_protocol_list (rprotos
, component
);
1084 tree basetype
= TYPE_MAIN_VARIANT (rtype
);
1086 if (basetype
!= NULL_TREE
&& TREE_CODE (basetype
) == POINTER_TYPE
)
1087 basetype
= TREE_TYPE (basetype
);
1091 while (basetype
!= NULL_TREE
1092 && TREE_CODE (basetype
) == RECORD_TYPE
1093 && OBJC_TYPE_NAME (basetype
)
1094 && TREE_CODE (OBJC_TYPE_NAME (basetype
)) == TYPE_DECL
1095 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype
)))
1096 basetype
= DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype
));
1098 if (basetype
!= NULL_TREE
&& TYPED_OBJECT (basetype
))
1100 tree interface_type
= TYPE_OBJC_INTERFACE (basetype
);
1101 if (!interface_type
)
1103 x
= lookup_property (interface_type
, component
);
1109 tree call_exp
, getter
;
1110 /* Get the getter name. */
1111 gcc_assert (PROPERTY_NAME (x
));
1112 getter
= objc_finish_message_expr (receiver
, PROPERTY_NAME (x
),
1116 /* In C++, a getter which returns an aggregate value results in a
1117 target_expr which initializes a temporary to the call expression. */
1118 if (TREE_CODE (getter
) == TARGET_EXPR
)
1120 gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter
)));
1121 gcc_assert (TREE_CODE (TREE_OPERAND (getter
,0)) == VAR_DECL
);
1122 call_exp
= TREE_OPERAND (getter
,1);
1125 gcc_assert (TREE_CODE (call_exp
) == CALL_EXPR
);
1127 CALL_EXPR_OBJC_PROPERTY_GETTER (call_exp
) = 1;
1133 /* This routine builds a call to property's 'setter' function. RECEIVER is the
1134 receiving object for 'setter'. PROPERTY_IDENT is name of the property and
1135 RHS is the argument passed to the 'setter' function. */
1138 objc_setter_func_call (tree receiver
, tree property_ident
, tree rhs
)
1140 tree setter_argument
= build_tree_list (NULL_TREE
, rhs
);
1141 char *setter_name
= objc_build_property_setter_name (property_ident
, true);
1143 in_objc_property_setter_name_context
= true;
1144 setter
= objc_finish_message_expr (receiver
, get_identifier (setter_name
),
1146 in_objc_property_setter_name_context
= false;
1150 /* Find the selector identifier from a reference. A somewhat tortuous way of
1151 obtaining the information to allow a setter to be written, given an
1155 get_selector_from_reference (tree selref
)
1159 if (flag_next_runtime
)
1161 /* Run through the selectors until we find the one we're looking for. */
1162 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1163 if (TREE_PURPOSE (chain
) == selref
)
1164 return TREE_VALUE (chain
);
1168 /* To find our way back to the selector for the GNU runtime is harder
1169 work, we need to decompose the representation of SELECTOR_TABLE[n]
1170 to find 'n'. This representation is in several forms. */
1171 if (TREE_CODE (selref
) == POINTER_PLUS_EXPR
)
1173 /* We need the element size to decode the array offset expression
1175 unsigned size
= (unsigned) TREE_INT_CST_LOW
1181 (TREE_OPERAND (selref
, 0), 0), 0)))));
1183 (unsigned) TREE_INT_CST_LOW (TREE_OPERAND (selref
, 1))
1185 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1187 return TREE_VALUE (chain
);
1189 else if (TREE_CODE (selref
) == NOP_EXPR
)
1191 /* Either we have a base an index, or we have just a base (when the
1193 if (TREE_CODE (TREE_OPERAND (selref
, 0)) == ADDR_EXPR
1196 (TREE_OPERAND (selref
, 0), 0)) == ARRAY_REF
)
1199 unsigned index
= (unsigned) TREE_INT_CST_LOW
1202 (TREE_OPERAND (selref
, 0), 0), 1));
1203 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1205 return TREE_VALUE (chain
);
1208 return TREE_VALUE (sel_ref_chain
);
1209 } /* Else we don't know how to figure this out - which will produce a
1210 parse error - saying that the LHS is not writeable. */
1215 /* This routine converts a previously synthesized 'getter' function call for
1216 a property and converts it to a 'setter' function call for the same
1220 objc_build_setter_call (tree lhs
, tree rhs
)
1223 && TREE_CODE (lhs
) == CALL_EXPR
1224 && CALL_EXPR_OBJC_PROPERTY_GETTER (lhs
))
1227 /* Get the Object. */
1228 tree receiver
= TREE_OPERAND (lhs
, 3);
1229 /* Get the selector reference. */
1230 tree selector_reference
= TREE_OPERAND (lhs
, 4);
1231 gcc_assert (receiver
&& selector_reference
);
1232 /* The style of the selector reference is different for GNU & NeXT. */
1233 selector
= get_selector_from_reference (selector_reference
);
1235 return objc_setter_func_call (receiver
, selector
, rhs
);
1240 /* This routine checks to see if ID is a property name. If so, it
1241 returns property declaration. */
1244 is_property (tree klass
, tree id
)
1248 for (x
= CLASS_PROPERTY_DECL (klass
); x
; x
= TREE_CHAIN (x
))
1249 if (PROPERTY_NAME (x
) == id
)
1254 /* This routine returns call to property's getter when a property is
1255 used stand-alone (without self. notation). */
1258 build_property_reference (tree property
, tree id
)
1261 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
1263 error ("property %qs accessed in class method",
1264 IDENTIFIER_POINTER (id
));
1265 return error_mark_node
;
1268 getter
= objc_finish_message_expr (self_decl
, PROPERTY_NAME (property
), NULL_TREE
);
1269 CALL_EXPR_OBJC_PROPERTY_GETTER (getter
) = 1;
1274 objc_set_method_type (enum tree_code type
)
1276 objc_inherit_code
= (type
== PLUS_EXPR
1278 : INSTANCE_METHOD_DECL
);
1282 objc_build_method_signature (tree rettype
, tree selector
,
1283 tree optparms
, bool ellipsis
)
1285 return build_method_decl (objc_inherit_code
, rettype
, selector
,
1286 optparms
, ellipsis
);
1290 objc_add_method_declaration (tree decl
, tree attributes
)
1292 if (!objc_interface_context
)
1294 /* PS: At the moment, due to how the parser works, it should be
1295 impossible to get here. But it's good to have the check in
1296 case the parser changes.
1298 fatal_error ("method declaration not in @interface context");
1301 objc_decl_method_attributes (&decl
, attributes
, 0);
1302 objc_add_method (objc_interface_context
,
1304 objc_inherit_code
== CLASS_METHOD_DECL
,
1305 objc_method_optional_flag
);
1308 /* Return 'true' if the method definition could be started, and
1309 'false' if not (because we are outside an @implementation context).
1312 objc_start_method_definition (tree decl
, tree attributes
)
1314 if (!objc_implementation_context
)
1316 error ("method definition not in @implementation context");
1320 if (decl
!= NULL_TREE
&& METHOD_SEL_NAME (decl
) == error_mark_node
)
1324 /* Indicate no valid break/continue context by setting these variables
1325 to some non-null, non-label value. We'll notice and emit the proper
1326 error message in c_finish_bc_stmt. */
1327 c_break_label
= c_cont_label
= size_zero_node
;
1330 objc_decl_method_attributes (&decl
, attributes
, 0);
1331 objc_add_method (objc_implementation_context
,
1333 objc_inherit_code
== CLASS_METHOD_DECL
,
1334 /* is optional */ false);
1335 start_method_def (decl
);
1340 objc_add_instance_variable (tree decl
)
1342 (void) add_instance_variable (objc_ivar_context
,
1343 objc_ivar_visibility
,
1347 /* Return true if TYPE is 'id'. */
1350 objc_is_object_id (tree type
)
1352 return OBJC_TYPE_NAME (type
) == objc_object_id
;
1356 objc_is_class_id (tree type
)
1358 return OBJC_TYPE_NAME (type
) == objc_class_id
;
1361 /* Construct a C struct with same name as KLASS, a base struct with tag
1362 SUPER_NAME (if any), and FIELDS indicated. */
1365 objc_build_struct (tree klass
, tree fields
, tree super_name
)
1367 tree name
= CLASS_NAME (klass
);
1368 tree s
= objc_start_struct (name
);
1369 tree super
= (super_name
? xref_tag (RECORD_TYPE
, super_name
) : NULL_TREE
);
1371 VEC(tree
,heap
) *objc_info
= NULL
;
1376 /* Prepend a packed variant of the base class into the layout. This
1377 is necessary to preserve ObjC ABI compatibility. */
1378 tree base
= build_decl (input_location
,
1379 FIELD_DECL
, NULL_TREE
, super
);
1380 tree field
= TYPE_FIELDS (super
);
1382 while (field
&& DECL_CHAIN (field
)
1383 && TREE_CODE (DECL_CHAIN (field
)) == FIELD_DECL
)
1384 field
= DECL_CHAIN (field
);
1386 /* For ObjC ABI purposes, the "packed" size of a base class is
1387 the sum of the offset and the size (in bits) of the last field
1390 = (field
&& TREE_CODE (field
) == FIELD_DECL
1391 ? size_binop (PLUS_EXPR
,
1392 size_binop (PLUS_EXPR
,
1395 convert (bitsizetype
,
1396 DECL_FIELD_OFFSET (field
)),
1397 bitsize_int (BITS_PER_UNIT
)),
1398 DECL_FIELD_BIT_OFFSET (field
)),
1400 : bitsize_zero_node
);
1401 DECL_SIZE_UNIT (base
)
1402 = size_binop (FLOOR_DIV_EXPR
, convert (sizetype
, DECL_SIZE (base
)),
1403 size_int (BITS_PER_UNIT
));
1404 DECL_ARTIFICIAL (base
) = 1;
1405 DECL_ALIGN (base
) = 1;
1406 DECL_FIELD_CONTEXT (base
) = s
;
1408 DECL_FIELD_IS_BASE (base
) = 1;
1411 TREE_NO_WARNING (fields
) = 1; /* Suppress C++ ABI warnings -- we */
1412 #endif /* are following the ObjC ABI here. */
1413 DECL_CHAIN (base
) = fields
;
1417 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
1418 in all variants of this RECORD_TYPE to be clobbered, but it is therein
1419 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
1420 Hence, we must squirrel away the ObjC-specific information before calling
1421 finish_struct(), and then reinstate it afterwards. */
1423 for (t
= TYPE_NEXT_VARIANT (s
); t
; t
= TYPE_NEXT_VARIANT (t
))
1425 if (!TYPE_HAS_OBJC_INFO (t
))
1427 INIT_TYPE_OBJC_INFO (t
);
1428 TYPE_OBJC_INTERFACE (t
) = klass
;
1430 VEC_safe_push (tree
, heap
, objc_info
, TYPE_OBJC_INFO (t
));
1433 /* Point the struct at its related Objective-C class. */
1434 INIT_TYPE_OBJC_INFO (s
);
1435 TYPE_OBJC_INTERFACE (s
) = klass
;
1437 s
= objc_finish_struct (s
, fields
);
1439 for (i
= 0, t
= TYPE_NEXT_VARIANT (s
); t
; t
= TYPE_NEXT_VARIANT (t
), i
++)
1441 TYPE_OBJC_INFO (t
) = VEC_index (tree
, objc_info
, i
);
1442 /* Replace the IDENTIFIER_NODE with an actual @interface. */
1443 TYPE_OBJC_INTERFACE (t
) = klass
;
1445 VEC_free (tree
, heap
, objc_info
);
1447 /* Use TYPE_BINFO structures to point at the super class, if any. */
1448 objc_xref_basetypes (s
, super
);
1450 /* Mark this struct as a class template. */
1451 CLASS_STATIC_TEMPLATE (klass
) = s
;
1456 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
1457 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
1460 objc_build_volatilized_type (tree type
)
1464 /* Check if we have not constructed the desired variant already. */
1465 for (t
= TYPE_MAIN_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
1467 /* The type qualifiers must (obviously) match up. */
1468 if (!TYPE_VOLATILE (t
)
1469 || (TYPE_READONLY (t
) != TYPE_READONLY (type
))
1470 || (TYPE_RESTRICT (t
) != TYPE_RESTRICT (type
)))
1473 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
1474 info, if any) must match up. */
1475 if (POINTER_TYPE_P (t
)
1476 && (TREE_TYPE (t
) != TREE_TYPE (type
)))
1479 /* Only match up the types which were previously volatilized in similar fashion and not
1480 because they were declared as such. */
1481 if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t
)))
1484 /* Everything matches up! */
1488 /* Ok, we could not re-use any of the pre-existing variants. Create
1490 t
= build_variant_type_copy (type
);
1491 TYPE_VOLATILE (t
) = 1;
1493 TYPE_ATTRIBUTES (t
) = merge_attributes (TYPE_ATTRIBUTES (type
),
1494 tree_cons (get_identifier ("objc_volatilized"),
1497 if (TREE_CODE (t
) == ARRAY_TYPE
)
1498 TREE_TYPE (t
) = objc_build_volatilized_type (TREE_TYPE (t
));
1500 /* Set up the canonical type information. */
1501 if (TYPE_STRUCTURAL_EQUALITY_P (type
))
1502 SET_TYPE_STRUCTURAL_EQUALITY (t
);
1503 else if (TYPE_CANONICAL (type
) != type
)
1504 TYPE_CANONICAL (t
) = objc_build_volatilized_type (TYPE_CANONICAL (type
));
1506 TYPE_CANONICAL (t
) = t
;
1511 /* Mark DECL as being 'volatile' for purposes of Darwin
1512 _setjmp()/_longjmp() exception handling. Called from
1513 objc_mark_locals_volatile(). */
1515 objc_volatilize_decl (tree decl
)
1517 /* Do not mess with variables that are 'static' or (already)
1519 if (!TREE_THIS_VOLATILE (decl
) && !TREE_STATIC (decl
)
1520 && (TREE_CODE (decl
) == VAR_DECL
1521 || TREE_CODE (decl
) == PARM_DECL
))
1523 tree t
= TREE_TYPE (decl
);
1525 t
= objc_build_volatilized_type (t
);
1527 TREE_TYPE (decl
) = t
;
1528 TREE_THIS_VOLATILE (decl
) = 1;
1529 TREE_SIDE_EFFECTS (decl
) = 1;
1530 DECL_REGISTER (decl
) = 0;
1532 C_DECL_REGISTER (decl
) = 0;
1537 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
1538 (including its categories and superclasses) or by object type TYP.
1539 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
1542 objc_lookup_protocol (tree proto
, tree cls
, tree typ
, bool warn
)
1544 bool class_type
= (cls
!= NULL_TREE
);
1550 /* Check protocols adopted by the class and its categories. */
1551 for (c
= cls
; c
; c
= CLASS_CATEGORY_LIST (c
))
1553 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c
), proto
))
1557 /* Repeat for superclasses. */
1558 cls
= lookup_interface (CLASS_SUPER_NAME (cls
));
1561 /* Check for any protocols attached directly to the object type. */
1562 if (TYPE_HAS_OBJC_INFO (typ
))
1564 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ
), proto
))
1571 gen_type_name_0 (class_type
? typ
: TYPE_POINTER_TO (typ
));
1572 /* NB: Types 'id' and 'Class' cannot reasonably be described as
1573 "implementing" a given protocol, since they do not have an
1576 warning (0, "class %qs does not implement the %qE protocol",
1577 identifier_to_locale (errbuf
), PROTOCOL_NAME (proto
));
1579 warning (0, "type %qs does not conform to the %qE protocol",
1580 identifier_to_locale (errbuf
), PROTOCOL_NAME (proto
));
1586 /* Check if class RCLS and instance struct type RTYP conform to at least the
1587 same protocols that LCLS and LTYP conform to. */
1590 objc_compare_protocols (tree lcls
, tree ltyp
, tree rcls
, tree rtyp
, bool warn
)
1593 bool have_lproto
= false;
1597 /* NB: We do _not_ look at categories defined for LCLS; these may or
1598 may not get loaded in, and therefore it is unreasonable to require
1599 that RCLS/RTYP must implement any of their protocols. */
1600 for (p
= CLASS_PROTOCOL_LIST (lcls
); p
; p
= TREE_CHAIN (p
))
1604 if (!objc_lookup_protocol (TREE_VALUE (p
), rcls
, rtyp
, warn
))
1608 /* Repeat for superclasses. */
1609 lcls
= lookup_interface (CLASS_SUPER_NAME (lcls
));
1612 /* Check for any protocols attached directly to the object type. */
1613 if (TYPE_HAS_OBJC_INFO (ltyp
))
1615 for (p
= TYPE_OBJC_PROTOCOL_LIST (ltyp
); p
; p
= TREE_CHAIN (p
))
1619 if (!objc_lookup_protocol (TREE_VALUE (p
), rcls
, rtyp
, warn
))
1624 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1625 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1626 away with simply checking for 'id' or 'Class' (!RCLS), since this
1627 routine will not get called in other cases. */
1628 return have_lproto
|| (rcls
!= NULL_TREE
);
1631 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
1632 Both TYPE1 and TYPE2 must be pointers, and already determined to be
1633 compatible by objc_compare_types() below. */
1636 objc_common_type (tree type1
, tree type2
)
1638 tree inner1
= TREE_TYPE (type1
), inner2
= TREE_TYPE (type2
);
1640 while (POINTER_TYPE_P (inner1
))
1642 inner1
= TREE_TYPE (inner1
);
1643 inner2
= TREE_TYPE (inner2
);
1646 /* If one type is derived from another, return the base type. */
1647 if (DERIVED_FROM_P (inner1
, inner2
))
1649 else if (DERIVED_FROM_P (inner2
, inner1
))
1652 /* If both types are 'Class', return 'Class'. */
1653 if (objc_is_class_id (inner1
) && objc_is_class_id (inner2
))
1654 return objc_class_type
;
1656 /* Otherwise, return 'id'. */
1657 return objc_object_type
;
1660 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1661 an instance of RTYP to an instance of LTYP or to compare the two
1662 (if ARGNO is equal to -3), per ObjC type system rules. Before
1663 returning 'true', this routine may issue warnings related to, e.g.,
1664 protocol conformance. When returning 'false', the routine must
1665 produce absolutely no warnings; the C or C++ front-end will do so
1666 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1667 the routine must return 'false'.
1669 The ARGNO parameter is encoded as follows:
1670 >= 1 Parameter number (CALLEE contains function being called);
1674 -3 Comparison (LTYP and RTYP may match in either direction);
1675 -4 Silent comparison (for C++ overload resolution).
1679 objc_compare_types (tree ltyp
, tree rtyp
, int argno
, tree callee
)
1681 tree lcls
, rcls
, lproto
, rproto
;
1682 bool pointers_compatible
;
1684 /* We must be dealing with pointer types */
1685 if (!POINTER_TYPE_P (ltyp
) || !POINTER_TYPE_P (rtyp
))
1690 ltyp
= TREE_TYPE (ltyp
); /* Remove indirections. */
1691 rtyp
= TREE_TYPE (rtyp
);
1693 while (POINTER_TYPE_P (ltyp
) && POINTER_TYPE_P (rtyp
));
1695 /* We must also handle function pointers, since ObjC is a bit more
1696 lenient than C or C++ on this. */
1697 if (TREE_CODE (ltyp
) == FUNCTION_TYPE
&& TREE_CODE (rtyp
) == FUNCTION_TYPE
)
1699 /* Return types must be covariant. */
1700 if (!comptypes (TREE_TYPE (ltyp
), TREE_TYPE (rtyp
))
1701 && !objc_compare_types (TREE_TYPE (ltyp
), TREE_TYPE (rtyp
),
1705 /* Argument types must be contravariant. */
1706 for (ltyp
= TYPE_ARG_TYPES (ltyp
), rtyp
= TYPE_ARG_TYPES (rtyp
);
1707 ltyp
&& rtyp
; ltyp
= TREE_CHAIN (ltyp
), rtyp
= TREE_CHAIN (rtyp
))
1709 if (!comptypes (TREE_VALUE (rtyp
), TREE_VALUE (ltyp
))
1710 && !objc_compare_types (TREE_VALUE (rtyp
), TREE_VALUE (ltyp
),
1715 return (ltyp
== rtyp
);
1718 /* Past this point, we are only interested in ObjC class instances,
1719 or 'id' or 'Class'. */
1720 if (TREE_CODE (ltyp
) != RECORD_TYPE
|| TREE_CODE (rtyp
) != RECORD_TYPE
)
1723 if (!objc_is_object_id (ltyp
) && !objc_is_class_id (ltyp
)
1724 && !TYPE_HAS_OBJC_INFO (ltyp
))
1727 if (!objc_is_object_id (rtyp
) && !objc_is_class_id (rtyp
)
1728 && !TYPE_HAS_OBJC_INFO (rtyp
))
1731 /* Past this point, we are committed to returning 'true' to the caller
1732 (unless performing a silent comparison; see below). However, we can
1733 still warn about type and/or protocol mismatches. */
1735 if (TYPE_HAS_OBJC_INFO (ltyp
))
1737 lcls
= TYPE_OBJC_INTERFACE (ltyp
);
1738 lproto
= TYPE_OBJC_PROTOCOL_LIST (ltyp
);
1741 lcls
= lproto
= NULL_TREE
;
1743 if (TYPE_HAS_OBJC_INFO (rtyp
))
1745 rcls
= TYPE_OBJC_INTERFACE (rtyp
);
1746 rproto
= TYPE_OBJC_PROTOCOL_LIST (rtyp
);
1749 rcls
= rproto
= NULL_TREE
;
1751 /* If we could not find an @interface declaration, we must have
1752 only seen a @class declaration; for purposes of type comparison,
1753 treat it as a stand-alone (root) class. */
1755 if (lcls
&& TREE_CODE (lcls
) == IDENTIFIER_NODE
)
1758 if (rcls
&& TREE_CODE (rcls
) == IDENTIFIER_NODE
)
1761 /* If either type is an unqualified 'id', we're done. */
1762 if ((!lproto
&& objc_is_object_id (ltyp
))
1763 || (!rproto
&& objc_is_object_id (rtyp
)))
1766 pointers_compatible
= (TYPE_MAIN_VARIANT (ltyp
) == TYPE_MAIN_VARIANT (rtyp
));
1768 /* If the underlying types are the same, and at most one of them has
1769 a protocol list, we do not need to issue any diagnostics. */
1770 if (pointers_compatible
&& (!lproto
|| !rproto
))
1773 /* If exactly one of the types is 'Class', issue a diagnostic; any
1774 exceptions of this rule have already been handled. */
1775 if (objc_is_class_id (ltyp
) ^ objc_is_class_id (rtyp
))
1776 pointers_compatible
= false;
1777 /* Otherwise, check for inheritance relations. */
1780 if (!pointers_compatible
)
1782 = (objc_is_object_id (ltyp
) || objc_is_object_id (rtyp
));
1784 if (!pointers_compatible
)
1785 pointers_compatible
= DERIVED_FROM_P (ltyp
, rtyp
);
1787 if (!pointers_compatible
&& argno
<= -3)
1788 pointers_compatible
= DERIVED_FROM_P (rtyp
, ltyp
);
1791 /* If the pointers match modulo protocols, check for protocol conformance
1793 if (pointers_compatible
)
1795 pointers_compatible
= objc_compare_protocols (lcls
, ltyp
, rcls
, rtyp
,
1798 if (!pointers_compatible
&& argno
== -3)
1799 pointers_compatible
= objc_compare_protocols (rcls
, rtyp
, lcls
, ltyp
,
1803 if (!pointers_compatible
)
1805 /* The two pointers are not exactly compatible. Issue a warning, unless
1806 we are performing a silent comparison, in which case return 'false'
1808 /* NB: For the time being, we shall make our warnings look like their
1809 C counterparts. In the future, we may wish to make them more
1817 warning (0, "comparison of distinct Objective-C types lacks a cast");
1821 warning (0, "initialization from distinct Objective-C type");
1825 warning (0, "assignment from distinct Objective-C type");
1829 warning (0, "distinct Objective-C type in return");
1833 warning (0, "passing argument %d of %qE from distinct "
1834 "Objective-C type", argno
, callee
);
1842 /* This routine is similar to objc_compare_types except that function-pointers are
1843 excluded. This is because, caller assumes that common types are of (id, Object*)
1844 variety and calls objc_common_type to obtain a common type. There is no commonolty
1845 between two function-pointers in this regard. */
1848 objc_have_common_type (tree ltyp
, tree rtyp
, int argno
, tree callee
)
1850 if (objc_compare_types (ltyp
, rtyp
, argno
, callee
))
1852 /* exclude function-pointer types. */
1855 ltyp
= TREE_TYPE (ltyp
); /* Remove indirections. */
1856 rtyp
= TREE_TYPE (rtyp
);
1858 while (POINTER_TYPE_P (ltyp
) && POINTER_TYPE_P (rtyp
));
1859 return !(TREE_CODE (ltyp
) == FUNCTION_TYPE
&& TREE_CODE (rtyp
) == FUNCTION_TYPE
);
1864 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1865 lives in the volatilized hash table, ignore the 'volatile' bit when
1866 making the comparison. */
1869 objc_type_quals_match (tree ltyp
, tree rtyp
)
1871 int lquals
= TYPE_QUALS (ltyp
), rquals
= TYPE_QUALS (rtyp
);
1873 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp
)))
1874 lquals
&= ~TYPE_QUAL_VOLATILE
;
1876 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp
)))
1877 rquals
&= ~TYPE_QUAL_VOLATILE
;
1879 return (lquals
== rquals
);
1883 /* Determine if CHILD is derived from PARENT. The routine assumes that
1884 both parameters are RECORD_TYPEs, and is non-reflexive. */
1887 objc_derived_from_p (tree parent
, tree child
)
1889 parent
= TYPE_MAIN_VARIANT (parent
);
1891 for (child
= TYPE_MAIN_VARIANT (child
);
1892 TYPE_BINFO (child
) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child
));)
1894 child
= TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1895 (TYPE_BINFO (child
),
1898 if (child
== parent
)
1907 objc_build_component_ref (tree datum
, tree component
)
1909 /* If COMPONENT is NULL, the caller is referring to the anonymous
1910 base class field. */
1913 tree base
= TYPE_FIELDS (TREE_TYPE (datum
));
1915 return build3 (COMPONENT_REF
, TREE_TYPE (base
), datum
, base
, NULL_TREE
);
1918 /* The 'build_component_ref' routine has been removed from the C++
1919 front-end, but 'finish_class_member_access_expr' seems to be
1920 a worthy substitute. */
1922 return finish_class_member_access_expr (datum
, component
, false,
1923 tf_warning_or_error
);
1925 return build_component_ref (input_location
, datum
, component
);
1929 /* Recursively copy inheritance information rooted at BINFO. To do this,
1930 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1933 objc_copy_binfo (tree binfo
)
1935 tree btype
= BINFO_TYPE (binfo
);
1936 tree binfo2
= make_tree_binfo (BINFO_N_BASE_BINFOS (binfo
));
1940 BINFO_TYPE (binfo2
) = btype
;
1941 BINFO_OFFSET (binfo2
) = BINFO_OFFSET (binfo
);
1942 BINFO_BASE_ACCESSES (binfo2
) = BINFO_BASE_ACCESSES (binfo
);
1944 /* Recursively copy base binfos of BINFO. */
1945 for (ix
= 0; BINFO_BASE_ITERATE (binfo
, ix
, base_binfo
); ix
++)
1947 tree base_binfo2
= objc_copy_binfo (base_binfo
);
1949 BINFO_INHERITANCE_CHAIN (base_binfo2
) = binfo2
;
1950 BINFO_BASE_APPEND (binfo2
, base_binfo2
);
1956 /* Record superclass information provided in BASETYPE for ObjC class REF.
1957 This is loosely based on cp/decl.c:xref_basetypes(). */
1960 objc_xref_basetypes (tree ref
, tree basetype
)
1962 tree binfo
= make_tree_binfo (basetype
? 1 : 0);
1964 TYPE_BINFO (ref
) = binfo
;
1965 BINFO_OFFSET (binfo
) = size_zero_node
;
1966 BINFO_TYPE (binfo
) = ref
;
1970 tree base_binfo
= objc_copy_binfo (TYPE_BINFO (basetype
));
1972 BINFO_INHERITANCE_CHAIN (base_binfo
) = binfo
;
1973 BINFO_BASE_ACCESSES (binfo
) = VEC_alloc (tree
, gc
, 1);
1974 BINFO_BASE_APPEND (binfo
, base_binfo
);
1975 BINFO_BASE_ACCESS_APPEND (binfo
, access_public_node
);
1979 /* Called from finish_decl. */
1982 objc_check_decl (tree decl
)
1984 tree type
= TREE_TYPE (decl
);
1986 if (TREE_CODE (type
) != RECORD_TYPE
)
1988 if (OBJC_TYPE_NAME (type
) && (type
= objc_is_class_name (OBJC_TYPE_NAME (type
))))
1989 error ("statically allocated instance of Objective-C class %qE",
1994 objc_check_global_decl (tree decl
)
1996 tree id
= DECL_NAME (decl
);
1997 if (objc_is_class_name (id
) && global_bindings_p())
1998 error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id
));
2001 /* Return a non-volatalized version of TYPE. */
2004 objc_non_volatilized_type (tree type
)
2006 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type
)))
2007 type
= build_qualified_type (type
, (TYPE_QUALS (type
) & ~TYPE_QUAL_VOLATILE
));
2011 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
2012 either name an Objective-C class, or refer to the special 'id' or 'Class'
2013 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
2016 objc_get_protocol_qualified_type (tree interface
, tree protocols
)
2018 /* If INTERFACE is not provided, default to 'id'. */
2019 tree type
= (interface
? objc_is_id (interface
) : objc_object_type
);
2020 bool is_ptr
= (type
!= NULL_TREE
);
2024 type
= objc_is_class_name (interface
);
2028 /* If looking at a typedef, retrieve the precise type it
2030 if (TREE_CODE (interface
) == IDENTIFIER_NODE
)
2031 interface
= identifier_global_value (interface
);
2033 type
= ((interface
&& TREE_CODE (interface
) == TYPE_DECL
2034 && DECL_ORIGINAL_TYPE (interface
))
2035 ? DECL_ORIGINAL_TYPE (interface
)
2036 : xref_tag (RECORD_TYPE
, type
));
2044 type
= build_variant_type_copy (type
);
2046 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
2050 tree orig_pointee_type
= TREE_TYPE (type
);
2051 TREE_TYPE (type
) = build_variant_type_copy (orig_pointee_type
);
2053 /* Set up the canonical type information. */
2054 TYPE_CANONICAL (type
)
2055 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type
));
2057 TYPE_POINTER_TO (TREE_TYPE (type
)) = type
;
2058 type
= TREE_TYPE (type
);
2061 /* Look up protocols and install in lang specific list. */
2062 DUP_TYPE_OBJC_INFO (type
, TYPE_MAIN_VARIANT (type
));
2063 TYPE_OBJC_PROTOCOL_LIST (type
) = lookup_and_install_protocols (protocols
);
2065 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
2066 return the pointer to the new pointee variant. */
2068 type
= TYPE_POINTER_TO (type
);
2070 TYPE_OBJC_INTERFACE (type
)
2071 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type
));
2077 /* Check for circular dependencies in protocols. The arguments are
2078 PROTO, the protocol to check, and LIST, a list of protocol it
2082 check_protocol_recursively (tree proto
, tree list
)
2086 for (p
= list
; p
; p
= TREE_CHAIN (p
))
2088 tree pp
= TREE_VALUE (p
);
2090 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
2091 pp
= lookup_protocol (pp
);
2094 fatal_error ("protocol %qE has circular dependency",
2095 PROTOCOL_NAME (pp
));
2097 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
2101 /* Look up PROTOCOLS, and return a list of those that are found.
2102 If none are found, return NULL. */
2105 lookup_and_install_protocols (tree protocols
)
2108 tree return_value
= NULL_TREE
;
2110 if (protocols
== error_mark_node
)
2113 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
2115 tree ident
= TREE_VALUE (proto
);
2116 tree p
= lookup_protocol (ident
);
2119 return_value
= chainon (return_value
,
2120 build_tree_list (NULL_TREE
, p
));
2121 else if (ident
!= error_mark_node
)
2122 error ("cannot find protocol declaration for %qE",
2126 return return_value
;
2129 /* Create a declaration for field NAME of a given TYPE. */
2132 create_field_decl (tree type
, const char *name
)
2134 return build_decl (input_location
,
2135 FIELD_DECL
, get_identifier (name
), type
);
2138 /* Create a global, static declaration for variable NAME of a given TYPE. The
2139 finish_var_decl() routine will need to be called on it afterwards. */
2142 start_var_decl (tree type
, const char *name
)
2144 tree var
= build_decl (input_location
,
2145 VAR_DECL
, get_identifier (name
), type
);
2147 TREE_STATIC (var
) = 1;
2148 DECL_INITIAL (var
) = error_mark_node
; /* A real initializer is coming... */
2149 DECL_IGNORED_P (var
) = 1;
2150 DECL_ARTIFICIAL (var
) = 1;
2151 DECL_CONTEXT (var
) = NULL_TREE
;
2153 DECL_THIS_STATIC (var
) = 1; /* squash redeclaration errors */
2159 /* Finish off the variable declaration created by start_var_decl(). */
2162 finish_var_decl (tree var
, tree initializer
)
2164 finish_decl (var
, input_location
, initializer
, NULL_TREE
, NULL_TREE
);
2167 /* Find the decl for the constant string class reference. This is only
2168 used for the NeXT runtime. */
2171 setup_string_decl (void)
2176 /* %s in format will provide room for terminating null */
2177 length
= strlen (STRING_OBJECT_GLOBAL_FORMAT
)
2178 + strlen (constant_string_class_name
);
2179 name
= XNEWVEC (char, length
);
2180 sprintf (name
, STRING_OBJECT_GLOBAL_FORMAT
,
2181 constant_string_class_name
);
2182 constant_string_global_id
= get_identifier (name
);
2183 string_class_decl
= lookup_name (constant_string_global_id
);
2185 return string_class_decl
;
2188 /* Purpose: "play" parser, creating/installing representations
2189 of the declarations that are required by Objective-C.
2193 type_spec--------->sc_spec
2194 (tree_list) (tree_list)
2197 identifier_node identifier_node */
2200 synth_module_prologue (void)
2203 enum debug_info_type save_write_symbols
= write_symbols
;
2204 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
2206 /* Suppress outputting debug symbols, because
2207 dbxout_init hasn't been called yet. */
2208 write_symbols
= NO_DEBUG
;
2209 debug_hooks
= &do_nothing_debug_hooks
;
2212 push_lang_context (lang_name_c
); /* extern "C" */
2215 /* The following are also defined in <objc/objc.h> and friends. */
2217 objc_object_id
= get_identifier (TAG_OBJECT
);
2218 objc_class_id
= get_identifier (TAG_CLASS
);
2220 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
2221 objc_class_reference
= xref_tag (RECORD_TYPE
, objc_class_id
);
2223 objc_object_type
= build_pointer_type (objc_object_reference
);
2224 objc_class_type
= build_pointer_type (objc_class_reference
);
2226 objc_object_name
= get_identifier (OBJECT_TYPEDEF_NAME
);
2227 objc_class_name
= get_identifier (CLASS_TYPEDEF_NAME
);
2229 /* Declare the 'id' and 'Class' typedefs. */
2231 type
= lang_hooks
.decls
.pushdecl (build_decl (input_location
,
2235 TREE_NO_WARNING (type
) = 1;
2236 type
= lang_hooks
.decls
.pushdecl (build_decl (input_location
,
2240 TREE_NO_WARNING (type
) = 1;
2242 /* Forward-declare '@interface Protocol'. */
2244 type
= get_identifier (PROTOCOL_OBJECT_CLASS_NAME
);
2245 objc_declare_class (tree_cons (NULL_TREE
, type
, NULL_TREE
));
2246 objc_protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
2249 /* Declare type of selector-objects that represent an operation name. */
2251 if (flag_next_runtime
)
2252 /* `struct objc_selector *' */
2254 = build_pointer_type (xref_tag (RECORD_TYPE
,
2255 get_identifier (TAG_SELECTOR
)));
2257 /* `const struct objc_selector *' */
2259 = build_pointer_type
2260 (build_qualified_type (xref_tag (RECORD_TYPE
,
2261 get_identifier (TAG_SELECTOR
)),
2264 /* Declare receiver type used for dispatching messages to 'super'. */
2266 /* `struct objc_super *' */
2267 objc_super_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
2268 get_identifier (TAG_SUPER
)));
2270 /* Declare pointers to method and ivar lists. */
2271 objc_method_list_ptr
= build_pointer_type
2272 (xref_tag (RECORD_TYPE
,
2273 get_identifier (UTAG_METHOD_LIST
)));
2274 objc_method_proto_list_ptr
2275 = build_pointer_type (xref_tag (RECORD_TYPE
,
2276 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2277 objc_ivar_list_ptr
= build_pointer_type
2278 (xref_tag (RECORD_TYPE
,
2279 get_identifier (UTAG_IVAR_LIST
)));
2281 /* TREE_NOTHROW is cleared for the message-sending functions,
2282 because the function that gets called can throw in Obj-C++, or
2283 could itself call something that can throw even in Obj-C. */
2285 if (flag_next_runtime
)
2287 /* NB: In order to call one of the ..._stret (struct-returning)
2288 functions, the function *MUST* first be cast to a signature that
2289 corresponds to the actual ObjC method being invoked. This is
2290 what is done by the build_objc_method_call() routine below. */
2292 /* id objc_msgSend (id, SEL, ...); */
2293 /* id objc_msgSendNonNil (id, SEL, ...); */
2294 /* id objc_msgSend_stret (id, SEL, ...); */
2295 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
2297 = build_varargs_function_type_list (objc_object_type
,
2301 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
2302 type
, 0, NOT_BUILT_IN
,
2304 umsg_nonnil_decl
= add_builtin_function (TAG_MSGSEND_NONNIL
,
2305 type
, 0, NOT_BUILT_IN
,
2307 umsg_stret_decl
= add_builtin_function (TAG_MSGSEND_STRET
,
2308 type
, 0, NOT_BUILT_IN
,
2310 umsg_nonnil_stret_decl
= add_builtin_function (TAG_MSGSEND_NONNIL_STRET
,
2311 type
, 0, NOT_BUILT_IN
,
2314 /* These can throw, because the function that gets called can throw
2315 in Obj-C++, or could itself call something that can throw even
2317 TREE_NOTHROW (umsg_decl
) = 0;
2318 TREE_NOTHROW (umsg_nonnil_decl
) = 0;
2319 TREE_NOTHROW (umsg_stret_decl
) = 0;
2320 TREE_NOTHROW (umsg_nonnil_stret_decl
) = 0;
2322 /* id objc_msgSend_Fast (id, SEL, ...)
2323 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
2324 #ifdef OFFS_MSGSEND_FAST
2325 umsg_fast_decl
= add_builtin_function (TAG_MSGSEND_FAST
,
2326 type
, 0, NOT_BUILT_IN
,
2328 TREE_NOTHROW (umsg_fast_decl
) = 0;
2329 DECL_ATTRIBUTES (umsg_fast_decl
)
2330 = tree_cons (get_identifier ("hard_coded_address"),
2331 build_int_cst (NULL_TREE
, OFFS_MSGSEND_FAST
),
2334 /* No direct dispatch available. */
2335 umsg_fast_decl
= umsg_decl
;
2338 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
2339 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
2341 = build_varargs_function_type_list (objc_object_type
,
2345 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
2346 type
, 0, NOT_BUILT_IN
,
2348 umsg_super_stret_decl
= add_builtin_function (TAG_MSGSENDSUPER_STRET
,
2349 type
, 0, NOT_BUILT_IN
, 0,
2351 TREE_NOTHROW (umsg_super_decl
) = 0;
2352 TREE_NOTHROW (umsg_super_stret_decl
) = 0;
2356 /* GNU runtime messenger entry points. */
2358 /* typedef id (*IMP)(id, SEL, ...); */
2360 build_varargs_function_type_list (objc_object_type
,
2364 tree IMP_type
= build_pointer_type (ftype
);
2366 /* IMP objc_msg_lookup (id, SEL); */
2367 type
= build_function_type_list (IMP_type
,
2371 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
2372 type
, 0, NOT_BUILT_IN
,
2374 TREE_NOTHROW (umsg_decl
) = 0;
2376 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
2378 = build_function_type_list (IMP_type
,
2382 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
2383 type
, 0, NOT_BUILT_IN
,
2385 TREE_NOTHROW (umsg_super_decl
) = 0;
2387 /* The following GNU runtime entry point is called to initialize
2390 __objc_exec_class (void *); */
2392 = build_function_type_list (void_type_node
,
2395 execclass_decl
= add_builtin_function (TAG_EXECCLASS
,
2396 type
, 0, NOT_BUILT_IN
,
2400 /* id objc_getClass (const char *); */
2402 type
= build_function_type_list (objc_object_type
,
2403 const_string_type_node
,
2407 = add_builtin_function (TAG_GETCLASS
, type
, 0, NOT_BUILT_IN
,
2410 /* id objc_getMetaClass (const char *); */
2412 objc_get_meta_class_decl
2413 = add_builtin_function (TAG_GETMETACLASS
, type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
2415 build_class_template ();
2416 build_super_template ();
2417 build_protocol_template ();
2418 build_category_template ();
2419 build_objc_exception_stuff ();
2421 if (flag_next_runtime
)
2422 build_next_objc_exception_stuff ();
2424 /* static SEL _OBJC_SELECTOR_TABLE[]; */
2426 if (! flag_next_runtime
)
2427 build_selector_table_decl ();
2429 /* Forward declare constant_string_id and constant_string_type. */
2430 if (!constant_string_class_name
)
2431 constant_string_class_name
= default_constant_string_class_name
;
2433 constant_string_id
= get_identifier (constant_string_class_name
);
2434 objc_declare_class (tree_cons (NULL_TREE
, constant_string_id
, NULL_TREE
));
2436 /* Pre-build the following entities - for speed/convenience. */
2437 self_id
= get_identifier ("self");
2438 ucmd_id
= get_identifier ("_cmd");
2440 /* Declare struct _objc_fast_enumeration_state { ... }; */
2441 build_fast_enumeration_state_template ();
2443 /* void objc_enumeration_mutation (id) */
2444 type
= build_function_type (void_type_node
,
2445 tree_cons (NULL_TREE
, objc_object_type
, NULL_TREE
));
2446 objc_enumeration_mutation_decl
2447 = add_builtin_function (TAG_ENUMERATION_MUTATION
, type
, 0, NOT_BUILT_IN
,
2449 TREE_NOTHROW (objc_enumeration_mutation_decl
) = 0;
2452 pop_lang_context ();
2455 write_symbols
= save_write_symbols
;
2456 debug_hooks
= save_hooks
;
2459 /* Ensure that the ivar list for NSConstantString/NXConstantString
2460 (or whatever was specified via `-fconstant-string-class')
2461 contains fields at least as large as the following three, so that
2462 the runtime can stomp on them with confidence:
2464 struct STRING_OBJECT_CLASS_NAME
2468 unsigned int length;
2472 check_string_class_template (void)
2474 tree field_decl
= objc_get_class_ivars (constant_string_id
);
2476 #define AT_LEAST_AS_LARGE_AS(F, T) \
2477 (F && TREE_CODE (F) == FIELD_DECL \
2478 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
2479 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
2481 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
2484 field_decl
= DECL_CHAIN (field_decl
);
2485 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
2488 field_decl
= DECL_CHAIN (field_decl
);
2489 return AT_LEAST_AS_LARGE_AS (field_decl
, unsigned_type_node
);
2491 #undef AT_LEAST_AS_LARGE_AS
2494 /* Avoid calling `check_string_class_template ()' more than once. */
2495 static GTY(()) int string_layout_checked
;
2497 /* Construct an internal string layout to be used as a template for
2498 creating NSConstantString/NXConstantString instances. */
2501 objc_build_internal_const_str_type (void)
2503 tree type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
2504 tree fields
= build_decl (input_location
,
2505 FIELD_DECL
, NULL_TREE
, ptr_type_node
);
2506 tree field
= build_decl (input_location
,
2507 FIELD_DECL
, NULL_TREE
, ptr_type_node
);
2509 DECL_CHAIN (field
) = fields
; fields
= field
;
2510 field
= build_decl (input_location
,
2511 FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
2512 DECL_CHAIN (field
) = fields
; fields
= field
;
2513 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
2515 finish_builtin_struct (type
, "__builtin_ObjCString",
2521 /* Custom build_string which sets TREE_TYPE! */
2524 my_build_string (int len
, const char *str
)
2526 return fix_string_type (build_string (len
, str
));
2529 /* Build a string with contents STR and length LEN and convert it to a
2533 my_build_string_pointer (int len
, const char *str
)
2535 tree string
= my_build_string (len
, str
);
2536 tree ptrtype
= build_pointer_type (TREE_TYPE (TREE_TYPE (string
)));
2537 return build1 (ADDR_EXPR
, ptrtype
, string
);
2541 string_hash (const void *ptr
)
2543 const_tree
const str
= ((const struct string_descriptor
*)ptr
)->literal
;
2544 const unsigned char *p
= (const unsigned char *) TREE_STRING_POINTER (str
);
2545 int i
, len
= TREE_STRING_LENGTH (str
);
2548 for (i
= 0; i
< len
; i
++)
2549 h
= ((h
* 613) + p
[i
]);
2555 string_eq (const void *ptr1
, const void *ptr2
)
2557 const_tree
const str1
= ((const struct string_descriptor
*)ptr1
)->literal
;
2558 const_tree
const str2
= ((const struct string_descriptor
*)ptr2
)->literal
;
2559 int len1
= TREE_STRING_LENGTH (str1
);
2561 return (len1
== TREE_STRING_LENGTH (str2
)
2562 && !memcmp (TREE_STRING_POINTER (str1
), TREE_STRING_POINTER (str2
),
2566 /* Given a chain of STRING_CST's, build a static instance of
2567 NXConstantString which points at the concatenation of those
2568 strings. We place the string object in the __string_objects
2569 section of the __OBJC segment. The Objective-C runtime will
2570 initialize the isa pointers of the string objects to point at the
2571 NXConstantString class object. */
2574 objc_build_string_object (tree string
)
2576 tree constructor
= NULL_TREE
, constant_string_class
;
2579 struct string_descriptor
*desc
, key
;
2582 /* Prep the string argument. */
2583 string
= fix_string_type (string
);
2584 TREE_SET_CODE (string
, STRING_CST
);
2585 length
= TREE_STRING_LENGTH (string
) - 1;
2587 /* Check whether the string class being used actually exists and has the
2588 correct ivar layout. */
2589 if (!string_layout_checked
)
2591 string_layout_checked
= -1;
2592 constant_string_class
= lookup_interface (constant_string_id
);
2593 internal_const_str_type
= objc_build_internal_const_str_type ();
2595 if (!constant_string_class
2596 || !(constant_string_type
2597 = CLASS_STATIC_TEMPLATE (constant_string_class
)))
2598 error ("cannot find interface declaration for %qE",
2599 constant_string_id
);
2600 /* The NSConstantString/NXConstantString ivar layout is now known. */
2601 else if (!check_string_class_template ())
2602 error ("interface %qE does not have valid constant string layout",
2603 constant_string_id
);
2604 /* For the NeXT runtime, we can generate a literal reference
2605 to the string class, don't need to run a constructor. */
2606 else if (flag_next_runtime
&& !setup_string_decl ())
2607 error ("cannot find reference tag for class %qE",
2608 constant_string_id
);
2611 string_layout_checked
= 1; /* Success! */
2612 add_class_reference (constant_string_id
);
2616 if (string_layout_checked
== -1)
2617 return error_mark_node
;
2619 /* Perhaps we already constructed a constant string just like this one? */
2620 key
.literal
= string
;
2621 loc
= htab_find_slot (string_htab
, &key
, INSERT
);
2622 desc
= (struct string_descriptor
*) *loc
;
2627 VEC(constructor_elt
,gc
) *v
= NULL
;
2628 *loc
= desc
= ggc_alloc_string_descriptor ();
2629 desc
->literal
= string
;
2631 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
2632 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
2633 fields
= TYPE_FIELDS (internal_const_str_type
);
2634 CONSTRUCTOR_APPEND_ELT (v
, fields
,
2636 ? build_unary_op (input_location
,
2637 ADDR_EXPR
, string_class_decl
, 0)
2638 : build_int_cst (NULL_TREE
, 0));
2639 fields
= DECL_CHAIN (fields
);
2640 CONSTRUCTOR_APPEND_ELT (v
, fields
,
2641 build_unary_op (input_location
,
2642 ADDR_EXPR
, string
, 1));
2643 fields
= DECL_CHAIN (fields
);
2644 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_int_cst (NULL_TREE
, length
));
2645 constructor
= objc_build_constructor (internal_const_str_type
, v
);
2647 if (!flag_next_runtime
)
2649 = objc_add_static_instance (constructor
, constant_string_type
);
2652 var
= build_decl (input_location
,
2653 CONST_DECL
, NULL
, TREE_TYPE (constructor
));
2654 DECL_INITIAL (var
) = constructor
;
2655 TREE_STATIC (var
) = 1;
2656 pushdecl_top_level (var
);
2659 desc
->constructor
= constructor
;
2662 addr
= convert (build_pointer_type (constant_string_type
),
2663 build_unary_op (input_location
,
2664 ADDR_EXPR
, desc
->constructor
, 1));
2669 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
2671 static GTY(()) int num_static_inst
;
2674 objc_add_static_instance (tree constructor
, tree class_decl
)
2679 /* Find the list of static instances for the CLASS_DECL. Create one if
2681 for (chain
= &objc_static_instances
;
2682 *chain
&& TREE_VALUE (*chain
) != class_decl
;
2683 chain
= &TREE_CHAIN (*chain
));
2686 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
2687 add_objc_string (OBJC_TYPE_NAME (class_decl
), class_names
);
2690 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
2691 decl
= build_decl (input_location
,
2692 VAR_DECL
, get_identifier (buf
), class_decl
);
2693 TREE_STATIC (decl
) = 1;
2694 DECL_ARTIFICIAL (decl
) = 1;
2695 TREE_USED (decl
) = 1;
2696 DECL_INITIAL (decl
) = constructor
;
2698 /* We may be writing something else just now.
2699 Postpone till end of input. */
2700 DECL_DEFER_OUTPUT (decl
) = 1;
2701 pushdecl_top_level (decl
);
2702 rest_of_decl_compilation (decl
, 1, 0);
2704 /* Add the DECL to the head of this CLASS' list. */
2705 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
2710 /* Build a static constant CONSTRUCTOR
2711 with type TYPE and elements ELTS. */
2714 objc_build_constructor (tree type
, VEC(constructor_elt
,gc
) *elts
)
2716 tree constructor
= build_constructor (type
, elts
);
2718 TREE_CONSTANT (constructor
) = 1;
2719 TREE_STATIC (constructor
) = 1;
2720 TREE_READONLY (constructor
) = 1;
2723 /* Adjust for impedance mismatch. We should figure out how to build
2724 CONSTRUCTORs that consistently please both the C and C++ gods. */
2725 if (!VEC_index (constructor_elt
, elts
, 0)->index
)
2726 TREE_TYPE (constructor
) = init_list_type_node
;
2732 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2734 /* Predefine the following data type:
2742 void *defs[cls_def_cnt + cat_def_cnt];
2746 build_objc_symtab_template (void)
2748 tree fields
, *chain
= NULL
;
2750 objc_symtab_template
= objc_start_struct (get_identifier (UTAG_SYMTAB
));
2752 /* long sel_ref_cnt; */
2753 fields
= add_field_decl (long_integer_type_node
, "sel_ref_cnt", &chain
);
2756 add_field_decl (build_pointer_type (objc_selector_type
), "refs", &chain
);
2758 /* short cls_def_cnt; */
2759 add_field_decl (short_integer_type_node
, "cls_def_cnt", &chain
);
2761 /* short cat_def_cnt; */
2762 add_field_decl (short_integer_type_node
, "cat_def_cnt", &chain
);
2764 if (imp_count
|| cat_count
|| !flag_next_runtime
)
2766 /* void *defs[imp_count + cat_count (+ 1)]; */
2767 /* NB: The index is one less than the size of the array. */
2768 int index
= imp_count
+ cat_count
+ (flag_next_runtime
? -1: 0);
2769 tree array_type
= build_sized_array_type (ptr_type_node
, index
+ 1);
2770 add_field_decl (array_type
, "defs", &chain
);
2773 objc_finish_struct (objc_symtab_template
, fields
);
2776 /* Create the initial value for the `defs' field of _objc_symtab.
2777 This is a CONSTRUCTOR. */
2780 init_def_list (tree type
)
2783 struct imp_entry
*impent
;
2784 VEC(constructor_elt
,gc
) *v
= NULL
;
2787 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2789 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
2791 expr
= build_unary_op (input_location
,
2792 ADDR_EXPR
, impent
->class_decl
, 0);
2793 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2798 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2800 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
2802 expr
= build_unary_op (input_location
,
2803 ADDR_EXPR
, impent
->class_decl
, 0);
2804 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2808 if (!flag_next_runtime
)
2810 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2811 if (static_instances_decl
)
2812 expr
= build_unary_op (input_location
,
2813 ADDR_EXPR
, static_instances_decl
, 0);
2815 expr
= integer_zero_node
;
2817 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2820 return objc_build_constructor (type
, v
);
2823 /* Construct the initial value for all of _objc_symtab. */
2826 init_objc_symtab (tree type
)
2828 VEC(constructor_elt
,gc
) *v
= NULL
;
2830 /* sel_ref_cnt = { ..., 5, ... } */
2832 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2833 build_int_cst (long_integer_type_node
, 0));
2835 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2837 if (flag_next_runtime
|| ! sel_ref_chain
)
2838 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, convert (
2839 build_pointer_type (objc_selector_type
),
2840 integer_zero_node
));
2843 tree expr
= build_unary_op (input_location
, ADDR_EXPR
,
2844 UOBJC_SELECTOR_TABLE_decl
, 1);
2846 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2847 convert (build_pointer_type (objc_selector_type
),
2851 /* cls_def_cnt = { ..., 5, ... } */
2853 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2854 build_int_cst (short_integer_type_node
, imp_count
));
2856 /* cat_def_cnt = { ..., 5, ... } */
2858 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2859 build_int_cst (short_integer_type_node
, cat_count
));
2861 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2863 if (imp_count
|| cat_count
|| !flag_next_runtime
)
2866 tree field
= TYPE_FIELDS (type
);
2867 field
= DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field
))));
2869 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, init_def_list (TREE_TYPE (field
)));
2872 return objc_build_constructor (type
, v
);
2875 /* Generate forward declarations for metadata such as
2876 'OBJC_CLASS_...'. */
2879 build_metadata_decl (const char *name
, tree type
)
2883 /* struct TYPE NAME_<name>; */
2884 decl
= start_var_decl (type
, synth_id_with_class_suffix
2886 objc_implementation_context
));
2891 /* Push forward-declarations of all the categories so that
2892 init_def_list can use them in a CONSTRUCTOR. */
2895 forward_declare_categories (void)
2897 struct imp_entry
*impent
;
2898 tree sav
= objc_implementation_context
;
2900 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2902 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
2904 /* Set an invisible arg to synth_id_with_class_suffix. */
2905 objc_implementation_context
= impent
->imp_context
;
2906 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2907 impent
->class_decl
= build_metadata_decl ("_OBJC_CATEGORY",
2908 objc_category_template
);
2911 objc_implementation_context
= sav
;
2914 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2915 and initialized appropriately. */
2918 generate_objc_symtab_decl (void)
2921 build_objc_symtab_template ();
2922 UOBJC_SYMBOLS_decl
= start_var_decl (objc_symtab_template
, "_OBJC_SYMBOLS");
2923 finish_var_decl (UOBJC_SYMBOLS_decl
,
2924 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)));
2928 init_module_descriptor (tree type
)
2931 VEC(constructor_elt
,gc
) *v
= NULL
;
2933 /* version = { 1, ... } */
2935 expr
= build_int_cst (long_integer_type_node
, OBJC_VERSION
);
2936 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2938 /* size = { ..., sizeof (struct _objc_module), ... } */
2940 expr
= convert (long_integer_type_node
,
2941 size_in_bytes (objc_module_template
));
2942 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2944 /* Don't provide any file name for security reasons. */
2945 /* name = { ..., "", ... } */
2947 expr
= add_objc_string (get_identifier (""), class_names
);
2948 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2950 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2952 if (UOBJC_SYMBOLS_decl
)
2953 expr
= build_unary_op (input_location
,
2954 ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
2956 expr
= null_pointer_node
;
2957 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2959 return objc_build_constructor (type
, v
);
2962 /* Write out the data structures to describe Objective C classes defined.
2964 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2967 build_module_descriptor (void)
2969 tree decls
, *chain
= NULL
;
2972 push_lang_context (lang_name_c
); /* extern "C" */
2975 objc_module_template
= objc_start_struct (get_identifier (UTAG_MODULE
));
2978 decls
= add_field_decl (long_integer_type_node
, "version", &chain
);
2981 add_field_decl (long_integer_type_node
, "size", &chain
);
2984 add_field_decl (string_type_node
, "name", &chain
);
2986 /* struct _objc_symtab *symtab; */
2987 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE
,
2988 get_identifier (UTAG_SYMTAB
))),
2991 objc_finish_struct (objc_module_template
, decls
);
2993 /* Create an instance of "_objc_module". */
2994 UOBJC_MODULES_decl
= start_var_decl (objc_module_template
, "_OBJC_MODULES");
2995 /* This is the root of the metadata for defined classes and categories, it
2996 is referenced by the runtime and, therefore, needed. */
2997 DECL_PRESERVE_P (UOBJC_MODULES_decl
) = 1;
2998 finish_var_decl (UOBJC_MODULES_decl
,
2999 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)));
3002 pop_lang_context ();
3006 /* The GNU runtime requires us to provide a static initializer function
3009 static void __objc_gnu_init (void) {
3010 __objc_exec_class (&L_OBJC_MODULES);
3014 build_module_initializer_routine (void)
3019 push_lang_context (lang_name_c
); /* extern "C" */
3022 objc_push_parm (build_decl (input_location
,
3023 PARM_DECL
, NULL_TREE
, void_type_node
));
3025 objc_start_function (get_identifier (TAG_GNUINIT
),
3026 build_function_type_list (void_type_node
, NULL_TREE
),
3027 NULL_TREE
, NULL_TREE
);
3029 objc_start_function (get_identifier (TAG_GNUINIT
),
3030 build_function_type_list (void_type_node
, NULL_TREE
),
3031 NULL_TREE
, objc_get_parm_info (0));
3033 body
= c_begin_compound_stmt (true);
3034 add_stmt (build_function_call
3039 build_unary_op (input_location
, ADDR_EXPR
,
3040 UOBJC_MODULES_decl
, 0))));
3041 add_stmt (c_end_compound_stmt (input_location
, body
, true));
3043 TREE_PUBLIC (current_function_decl
) = 0;
3046 /* For Objective-C++, we will need to call __objc_gnu_init
3047 from objc_generate_static_init_call() below. */
3048 DECL_STATIC_CONSTRUCTOR (current_function_decl
) = 1;
3051 GNU_INIT_decl
= current_function_decl
;
3055 pop_lang_context ();
3060 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
3061 to be called by the module initializer routine. */
3064 objc_static_init_needed_p (void)
3066 return (GNU_INIT_decl
!= NULL_TREE
);
3069 /* Generate a call to the __objc_gnu_init initializer function. */
3072 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED
)
3074 add_stmt (build_stmt (input_location
, EXPR_STMT
,
3075 build_function_call (input_location
,
3076 GNU_INIT_decl
, NULL_TREE
)));
3080 #endif /* OBJCPLUS */
3082 /* Return the DECL of the string IDENT in the SECTION. */
3085 get_objc_string_decl (tree ident
, enum string_section section
)
3089 if (section
== class_names
)
3090 chain
= class_names_chain
;
3091 else if (section
== meth_var_names
)
3092 chain
= meth_var_names_chain
;
3093 else if (section
== meth_var_types
)
3094 chain
= meth_var_types_chain
;
3098 for (; chain
!= 0; chain
= TREE_CHAIN (chain
))
3099 if (TREE_VALUE (chain
) == ident
)
3100 return (TREE_PURPOSE (chain
));
3106 /* Output references to all statically allocated objects. Return the DECL
3107 for the array built. */
3110 generate_static_references (void)
3112 tree expr
= NULL_TREE
;
3113 tree class_name
, klass
, decl
;
3114 tree cl_chain
, in_chain
, type
3115 = build_array_type (build_pointer_type (void_type_node
), NULL_TREE
);
3116 int num_inst
, num_class
;
3118 VEC(constructor_elt
,gc
) *decls
= NULL
;
3120 if (flag_next_runtime
)
3123 for (cl_chain
= objc_static_instances
, num_class
= 0;
3124 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
3126 VEC(constructor_elt
,gc
) *v
= NULL
;
3128 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
3129 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
3131 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
3132 decl
= start_var_decl (type
, buf
);
3134 /* Output {class_name, ...}. */
3135 klass
= TREE_VALUE (cl_chain
);
3136 class_name
= get_objc_string_decl (OBJC_TYPE_NAME (klass
), class_names
);
3137 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
3138 build_unary_op (input_location
,
3139 ADDR_EXPR
, class_name
, 1));
3141 /* Output {..., instance, ...}. */
3142 for (in_chain
= TREE_PURPOSE (cl_chain
);
3143 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
3145 expr
= build_unary_op (input_location
,
3146 ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
3147 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
3150 /* Output {..., NULL}. */
3151 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
3153 expr
= objc_build_constructor (TREE_TYPE (decl
), v
);
3154 finish_var_decl (decl
, expr
);
3155 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
,
3156 build_unary_op (input_location
,
3157 ADDR_EXPR
, decl
, 1));
3160 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
3161 expr
= objc_build_constructor (type
, decls
);
3162 static_instances_decl
= start_var_decl (type
, "_OBJC_STATIC_INSTANCES");
3163 finish_var_decl (static_instances_decl
, expr
);
3166 static GTY(()) int selector_reference_idx
;
3169 build_selector_reference_decl (void)
3174 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx
++);
3175 decl
= start_var_decl (objc_selector_type
, buf
);
3181 build_selector_table_decl (void)
3185 if (flag_typed_selectors
)
3187 build_selector_template ();
3188 temp
= build_array_type (objc_selector_template
, NULL_TREE
);
3191 temp
= build_array_type (objc_selector_type
, NULL_TREE
);
3193 UOBJC_SELECTOR_TABLE_decl
= start_var_decl (temp
, "_OBJC_SELECTOR_TABLE");
3196 /* Just a handy wrapper for add_objc_string. */
3199 build_selector (tree ident
)
3201 return convert (objc_selector_type
,
3202 add_objc_string (ident
, meth_var_names
));
3205 /* Used only by build_*_selector_translation_table (). */
3207 diagnose_missing_method (tree meth
, location_t here
)
3211 for (method_chain
= meth_var_names_chain
;
3213 method_chain
= TREE_CHAIN (method_chain
))
3215 if (TREE_VALUE (method_chain
) == meth
)
3223 warning_at (here
, 0, "creating selector for nonexistent method %qE",
3228 build_next_selector_translation_table (void)
3231 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
3234 tree decl
= TREE_PURPOSE (chain
);
3235 if (warn_selector
&& objc_implementation_context
)
3239 loc
= DECL_SOURCE_LOCATION (decl
);
3241 loc
= input_location
;
3242 diagnose_missing_method (TREE_VALUE (chain
), loc
);
3245 expr
= build_selector (TREE_VALUE (chain
));
3249 /* Entries of this form are used for references to methods.
3250 The runtime re-writes these on start-up, but the compiler can't see
3251 that and optimizes it away unless we force it. */
3252 DECL_PRESERVE_P (decl
) = 1;
3253 finish_var_decl (decl
, expr
);
3259 build_gnu_selector_translation_table (void)
3263 tree decl = NULL_TREE;*/
3264 VEC(constructor_elt
,gc
) *inits
= NULL
;
3266 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
3270 if (warn_selector
&& objc_implementation_context
)
3271 diagnose_missing_method (TREE_VALUE (chain
), input_location
);
3273 expr
= build_selector (TREE_VALUE (chain
));
3274 /* add one for the '\0' character
3275 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
3278 if (flag_typed_selectors
)
3280 VEC(constructor_elt
,gc
) *v
= NULL
;
3281 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
3282 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
3283 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, encoding
);
3284 expr
= objc_build_constructor (objc_selector_template
, v
);
3287 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
3289 } /* each element in the chain */
3292 /* Cause the selector table (previously forward-declared)
3293 to be actually output. */
3296 if (flag_typed_selectors
)
3298 VEC(constructor_elt
,gc
) *v
= NULL
;
3299 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
3300 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
3301 expr
= objc_build_constructor (objc_selector_template
, v
);
3304 expr
= integer_zero_node
;
3306 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
3307 expr
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
3309 finish_var_decl (UOBJC_SELECTOR_TABLE_decl
, expr
);
3314 get_proto_encoding (tree proto
)
3319 if (! METHOD_ENCODING (proto
))
3321 encoding
= encode_method_prototype (proto
);
3322 METHOD_ENCODING (proto
) = encoding
;
3325 encoding
= METHOD_ENCODING (proto
);
3327 return add_objc_string (encoding
, meth_var_types
);
3330 return build_int_cst (NULL_TREE
, 0);
3333 /* sel_ref_chain is a list whose "value" fields will be instances of
3334 identifier_node that represent the selector. LOC is the location of
3338 build_typed_selector_reference (location_t loc
, tree ident
, tree prototype
)
3340 tree
*chain
= &sel_ref_chain
;
3346 if (TREE_PURPOSE (*chain
) == prototype
&& TREE_VALUE (*chain
) == ident
)
3347 goto return_at_index
;
3350 chain
= &TREE_CHAIN (*chain
);
3353 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
3356 expr
= build_unary_op (loc
, ADDR_EXPR
,
3357 build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
3358 build_int_cst (NULL_TREE
, index
)),
3360 return convert (objc_selector_type
, expr
);
3364 build_selector_reference (location_t loc
, tree ident
)
3366 tree
*chain
= &sel_ref_chain
;
3372 if (TREE_VALUE (*chain
) == ident
)
3373 return (flag_next_runtime
3374 ? TREE_PURPOSE (*chain
)
3375 : build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
3376 build_int_cst (NULL_TREE
, index
)));
3379 chain
= &TREE_CHAIN (*chain
);
3382 expr
= (flag_next_runtime
? build_selector_reference_decl (): NULL_TREE
);
3384 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
3386 return (flag_next_runtime
3388 : build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
3389 build_int_cst (NULL_TREE
, index
)));
3392 static GTY(()) int class_reference_idx
;
3395 build_class_reference_decl (void)
3400 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx
++);
3401 decl
= start_var_decl (objc_class_type
, buf
);
3406 /* Create a class reference, but don't create a variable to reference
3410 add_class_reference (tree ident
)
3414 if ((chain
= cls_ref_chain
))
3419 if (ident
== TREE_VALUE (chain
))
3423 chain
= TREE_CHAIN (chain
);
3427 /* Append to the end of the list */
3428 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
3431 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
3434 /* Get a class reference, creating it if necessary. Also create the
3435 reference variable. */
3438 objc_get_class_reference (tree ident
)
3440 tree orig_ident
= (DECL_P (ident
)
3443 ? OBJC_TYPE_NAME (ident
)
3445 bool local_scope
= false;
3448 if (processing_template_decl
)
3449 /* Must wait until template instantiation time. */
3450 return build_min_nt (CLASS_REFERENCE_EXPR
, ident
);
3453 if (TREE_CODE (ident
) == TYPE_DECL
)
3454 ident
= (DECL_ORIGINAL_TYPE (ident
)
3455 ? DECL_ORIGINAL_TYPE (ident
)
3456 : TREE_TYPE (ident
));
3460 && CP_TYPE_CONTEXT (ident
) != global_namespace
)
3464 if (local_scope
|| !(ident
= objc_is_class_name (ident
)))
3466 error ("%qE is not an Objective-C class name or alias",
3468 return error_mark_node
;
3471 if (flag_next_runtime
&& !flag_zero_link
)
3476 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
3477 if (TREE_VALUE (*chain
) == ident
)
3479 if (! TREE_PURPOSE (*chain
))
3480 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
3482 return TREE_PURPOSE (*chain
);
3485 decl
= build_class_reference_decl ();
3486 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
3493 add_class_reference (ident
);
3495 params
= build_tree_list (NULL_TREE
,
3496 my_build_string_pointer
3497 (IDENTIFIER_LENGTH (ident
) + 1,
3498 IDENTIFIER_POINTER (ident
)));
3500 assemble_external (objc_get_class_decl
);
3501 return build_function_call (input_location
, objc_get_class_decl
, params
);
3505 /* For each string section we have a chain which maps identifier nodes
3506 to decls for the strings. */
3508 static GTY(()) int class_names_idx
;
3509 static GTY(()) int meth_var_names_idx
;
3510 static GTY(()) int meth_var_types_idx
;
3513 add_objc_string (tree ident
, enum string_section section
)
3515 tree
*chain
, decl
, type
, string_expr
;
3519 if (section
== class_names
)
3521 chain
= &class_names_chain
;
3522 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
3524 else if (section
== meth_var_names
)
3526 chain
= &meth_var_names_chain
;
3527 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
3529 else if (section
== meth_var_types
)
3531 chain
= &meth_var_types_chain
;
3532 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
3539 if (TREE_VALUE (*chain
) == ident
)
3540 return convert (string_type_node
,
3541 build_unary_op (input_location
,
3542 ADDR_EXPR
, TREE_PURPOSE (*chain
), 1));
3544 chain
= &TREE_CHAIN (*chain
);
3547 type
= build_sized_array_type (char_type_node
, IDENTIFIER_LENGTH (ident
) + 1);
3548 decl
= start_var_decl (type
, buf
);
3549 string_expr
= my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
3550 IDENTIFIER_POINTER (ident
));
3551 TREE_CONSTANT (decl
) = 1;
3552 finish_var_decl (decl
, string_expr
);
3554 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
3556 return convert (string_type_node
, build_unary_op (input_location
,
3557 ADDR_EXPR
, decl
, 1));
3561 objc_declare_alias (tree alias_ident
, tree class_ident
)
3563 tree underlying_class
;
3566 if (current_namespace
!= global_namespace
) {
3567 error ("Objective-C declarations may only appear in global scope");
3569 #endif /* OBJCPLUS */
3571 if (!(underlying_class
= objc_is_class_name (class_ident
)))
3572 warning (0, "cannot find class %qE", class_ident
);
3573 else if (objc_is_class_name (alias_ident
))
3574 warning (0, "class %qE already exists", alias_ident
);
3577 /* Implement @compatibility_alias as a typedef. */
3579 push_lang_context (lang_name_c
); /* extern "C" */
3581 lang_hooks
.decls
.pushdecl (build_decl
3585 xref_tag (RECORD_TYPE
, underlying_class
)));
3587 pop_lang_context ();
3589 alias_chain
= tree_cons (underlying_class
, alias_ident
, alias_chain
);
3594 objc_declare_class (tree ident_list
)
3598 if (current_namespace
!= global_namespace
) {
3599 error ("Objective-C declarations may only appear in global scope");
3601 #endif /* OBJCPLUS */
3603 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
3605 tree ident
= TREE_VALUE (list
);
3607 if (! objc_is_class_name (ident
))
3609 tree record
= lookup_name (ident
), type
= record
;
3613 if (TREE_CODE (record
) == TYPE_DECL
)
3614 type
= DECL_ORIGINAL_TYPE (record
) ?
3615 DECL_ORIGINAL_TYPE (record
) :
3618 if (!TYPE_HAS_OBJC_INFO (type
)
3619 || !TYPE_OBJC_INTERFACE (type
))
3621 error ("%qE redeclared as different kind of symbol",
3623 error ("previous declaration of %q+D",
3628 record
= xref_tag (RECORD_TYPE
, ident
);
3629 INIT_TYPE_OBJC_INFO (record
);
3630 TYPE_OBJC_INTERFACE (record
) = ident
;
3631 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
3637 objc_is_class_name (tree ident
)
3641 if (ident
&& TREE_CODE (ident
) == IDENTIFIER_NODE
3642 && identifier_global_value (ident
))
3643 ident
= identifier_global_value (ident
);
3644 while (ident
&& TREE_CODE (ident
) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (ident
))
3645 ident
= OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident
));
3647 if (ident
&& TREE_CODE (ident
) == RECORD_TYPE
)
3648 ident
= OBJC_TYPE_NAME (ident
);
3650 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
3652 tree type
= TREE_TYPE (ident
);
3653 if (type
&& TREE_CODE (type
) == TEMPLATE_TYPE_PARM
)
3655 ident
= DECL_NAME (ident
);
3658 if (!ident
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
3661 if (lookup_interface (ident
))
3664 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
3666 if (ident
== TREE_VALUE (chain
))
3670 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
3672 if (ident
== TREE_VALUE (chain
))
3673 return TREE_PURPOSE (chain
);
3679 /* Check whether TYPE is either 'id' or 'Class'. */
3682 objc_is_id (tree type
)
3684 if (type
&& TREE_CODE (type
) == IDENTIFIER_NODE
3685 && identifier_global_value (type
))
3686 type
= identifier_global_value (type
);
3688 if (type
&& TREE_CODE (type
) == TYPE_DECL
)
3689 type
= TREE_TYPE (type
);
3691 /* NB: This function may be called before the ObjC front-end has
3692 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3693 return (objc_object_type
&& type
3694 && (IS_ID (type
) || IS_CLASS (type
) || IS_SUPER (type
))
3699 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3700 class instance. This is needed by other parts of the compiler to
3701 handle ObjC types gracefully. */
3704 objc_is_object_ptr (tree type
)
3708 type
= TYPE_MAIN_VARIANT (type
);
3709 if (!POINTER_TYPE_P (type
))
3712 ret
= objc_is_id (type
);
3714 ret
= objc_is_class_name (TREE_TYPE (type
));
3720 objc_is_gcable_type (tree type
, int or_strong_p
)
3726 if (objc_is_id (TYPE_MAIN_VARIANT (type
)))
3728 if (or_strong_p
&& lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type
)))
3730 if (TREE_CODE (type
) != POINTER_TYPE
&& TREE_CODE (type
) != INDIRECT_REF
)
3732 type
= TREE_TYPE (type
);
3733 if (TREE_CODE (type
) != RECORD_TYPE
)
3735 name
= TYPE_NAME (type
);
3736 return (objc_is_class_name (name
) != NULL_TREE
);
3740 objc_substitute_decl (tree expr
, tree oldexpr
, tree newexpr
)
3742 if (expr
== oldexpr
)
3745 switch (TREE_CODE (expr
))
3748 return objc_build_component_ref
3749 (objc_substitute_decl (TREE_OPERAND (expr
, 0),
3752 DECL_NAME (TREE_OPERAND (expr
, 1)));
3754 return build_array_ref (input_location
,
3755 objc_substitute_decl (TREE_OPERAND (expr
, 0),
3758 TREE_OPERAND (expr
, 1));
3760 return build_indirect_ref (input_location
,
3761 objc_substitute_decl (TREE_OPERAND (expr
, 0),
3763 newexpr
), RO_ARROW
);
3770 objc_build_ivar_assignment (tree outervar
, tree lhs
, tree rhs
)
3773 /* The LHS parameter contains the expression 'outervar->memberspec';
3774 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3775 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3778 = objc_substitute_decl
3779 (lhs
, outervar
, convert (TREE_TYPE (outervar
), integer_zero_node
));
3781 = (flag_objc_direct_dispatch
3782 ? objc_assign_ivar_fast_decl
3783 : objc_assign_ivar_decl
);
3785 offs
= convert (integer_type_node
, build_unary_op (input_location
,
3786 ADDR_EXPR
, offs
, 0));
3788 func_params
= tree_cons (NULL_TREE
,
3789 convert (objc_object_type
, rhs
),
3790 tree_cons (NULL_TREE
, convert (objc_object_type
, outervar
),
3791 tree_cons (NULL_TREE
, offs
,
3794 assemble_external (func
);
3795 return build_function_call (input_location
, func
, func_params
);
3799 objc_build_global_assignment (tree lhs
, tree rhs
)
3801 tree func_params
= tree_cons (NULL_TREE
,
3802 convert (objc_object_type
, rhs
),
3803 tree_cons (NULL_TREE
, convert (build_pointer_type (objc_object_type
),
3804 build_unary_op (input_location
, ADDR_EXPR
, lhs
, 0)),
3807 assemble_external (objc_assign_global_decl
);
3808 return build_function_call (input_location
,
3809 objc_assign_global_decl
, func_params
);
3813 objc_build_strong_cast_assignment (tree lhs
, tree rhs
)
3815 tree func_params
= tree_cons (NULL_TREE
,
3816 convert (objc_object_type
, rhs
),
3817 tree_cons (NULL_TREE
, convert (build_pointer_type (objc_object_type
),
3818 build_unary_op (input_location
, ADDR_EXPR
, lhs
, 0)),
3821 assemble_external (objc_assign_strong_cast_decl
);
3822 return build_function_call (input_location
,
3823 objc_assign_strong_cast_decl
, func_params
);
3827 objc_is_gcable_p (tree expr
)
3829 return (TREE_CODE (expr
) == COMPONENT_REF
3830 ? objc_is_gcable_p (TREE_OPERAND (expr
, 1))
3831 : TREE_CODE (expr
) == ARRAY_REF
3832 ? (objc_is_gcable_p (TREE_TYPE (expr
))
3833 || objc_is_gcable_p (TREE_OPERAND (expr
, 0)))
3834 : TREE_CODE (expr
) == ARRAY_TYPE
3835 ? objc_is_gcable_p (TREE_TYPE (expr
))
3837 ? objc_is_gcable_type (expr
, 1)
3838 : (objc_is_gcable_p (TREE_TYPE (expr
))
3840 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr
)))));
3844 objc_is_ivar_reference_p (tree expr
)
3846 return (TREE_CODE (expr
) == ARRAY_REF
3847 ? objc_is_ivar_reference_p (TREE_OPERAND (expr
, 0))
3848 : TREE_CODE (expr
) == COMPONENT_REF
3849 ? TREE_CODE (TREE_OPERAND (expr
, 1)) == FIELD_DECL
3854 objc_is_global_reference_p (tree expr
)
3856 return (TREE_CODE (expr
) == INDIRECT_REF
|| TREE_CODE (expr
) == PLUS_EXPR
3857 ? objc_is_global_reference_p (TREE_OPERAND (expr
, 0))
3859 ? (DECL_FILE_SCOPE_P (expr
) || TREE_STATIC (expr
))
3864 objc_generate_write_barrier (tree lhs
, enum tree_code modifycode
, tree rhs
)
3866 tree result
= NULL_TREE
, outer
;
3867 int strong_cast_p
= 0, outer_gc_p
= 0, indirect_p
= 0;
3869 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3870 will have been transformed to the form '*(type *)&expr'. */
3871 if (TREE_CODE (lhs
) == INDIRECT_REF
)
3873 outer
= TREE_OPERAND (lhs
, 0);
3875 while (!strong_cast_p
3876 && (CONVERT_EXPR_P (outer
)
3877 || TREE_CODE (outer
) == NON_LVALUE_EXPR
))
3879 tree lhstype
= TREE_TYPE (outer
);
3881 /* Descend down the cast chain, and record the first objc_gc
3883 if (POINTER_TYPE_P (lhstype
))
3886 = lookup_attribute ("objc_gc",
3887 TYPE_ATTRIBUTES (TREE_TYPE (lhstype
)));
3893 outer
= TREE_OPERAND (outer
, 0);
3897 /* If we have a __strong cast, it trumps all else. */
3900 if (modifycode
!= NOP_EXPR
)
3901 goto invalid_pointer_arithmetic
;
3903 if (warn_assign_intercept
)
3904 warning (0, "strong-cast assignment has been intercepted");
3906 result
= objc_build_strong_cast_assignment (lhs
, rhs
);
3911 /* the lhs must be of a suitable type, regardless of its underlying
3913 if (!objc_is_gcable_p (lhs
))
3919 && (TREE_CODE (outer
) == COMPONENT_REF
3920 || TREE_CODE (outer
) == ARRAY_REF
))
3921 outer
= TREE_OPERAND (outer
, 0);
3923 if (TREE_CODE (outer
) == INDIRECT_REF
)
3925 outer
= TREE_OPERAND (outer
, 0);
3929 outer_gc_p
= objc_is_gcable_p (outer
);
3931 /* Handle ivar assignments. */
3932 if (objc_is_ivar_reference_p (lhs
))
3934 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3935 doesn't cut it here), the best we can do here is suggest a cast. */
3936 if (!objc_is_gcable_type (TREE_TYPE (outer
), 0))
3938 /* We may still be able to use the global write barrier... */
3939 if (!indirect_p
&& objc_is_global_reference_p (outer
))
3940 goto global_reference
;
3943 if (modifycode
== NOP_EXPR
)
3945 if (warn_assign_intercept
)
3946 warning (0, "strong-cast may possibly be needed");
3952 if (modifycode
!= NOP_EXPR
)
3953 goto invalid_pointer_arithmetic
;
3955 if (warn_assign_intercept
)
3956 warning (0, "instance variable assignment has been intercepted");
3958 result
= objc_build_ivar_assignment (outer
, lhs
, rhs
);
3963 /* Likewise, intercept assignment to global/static variables if their type is
3965 if (objc_is_global_reference_p (outer
))
3971 if (modifycode
!= NOP_EXPR
)
3973 invalid_pointer_arithmetic
:
3975 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3980 if (warn_assign_intercept
)
3981 warning (0, "global/static variable assignment has been intercepted");
3983 result
= objc_build_global_assignment (lhs
, rhs
);
3986 /* In all other cases, fall back to the normal mechanism. */
3991 struct GTY(()) interface_tuple
{
3996 static GTY ((param_is (struct interface_tuple
))) htab_t interface_htab
;
3999 hash_interface (const void *p
)
4001 const struct interface_tuple
*d
= (const struct interface_tuple
*) p
;
4002 return IDENTIFIER_HASH_VALUE (d
->id
);
4006 eq_interface (const void *p1
, const void *p2
)
4008 const struct interface_tuple
*d
= (const struct interface_tuple
*) p1
;
4013 lookup_interface (tree ident
)
4016 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
4017 ident
= DECL_NAME (ident
);
4020 if (ident
== NULL_TREE
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
4024 struct interface_tuple
**slot
;
4029 slot
= (struct interface_tuple
**)
4030 htab_find_slot_with_hash (interface_htab
, ident
,
4031 IDENTIFIER_HASH_VALUE (ident
),
4034 i
= (*slot
)->class_name
;
4040 /* Implement @defs (<classname>) within struct bodies. */
4043 objc_get_class_ivars (tree class_name
)
4045 tree interface
= lookup_interface (class_name
);
4048 return get_class_ivars (interface
, true);
4050 error ("cannot find interface declaration for %qE",
4053 return error_mark_node
;
4056 /* Called when checking the variables in a struct. If we are not
4057 doing the ivars list inside an @interface context, then returns
4058 fieldlist unchanged. Else, returns the list of class ivars.
4061 objc_get_interface_ivars (tree fieldlist
)
4063 if (!objc_collecting_ivars
|| !objc_interface_context
4064 || TREE_CODE (objc_interface_context
) != CLASS_INTERFACE_TYPE
4065 || CLASS_SUPER_NAME (objc_interface_context
) == NULL_TREE
)
4068 return get_class_ivars (objc_interface_context
, true);
4071 /* Used by: build_private_template, continue_class,
4072 and for @defs constructs. */
4075 get_class_ivars (tree interface
, bool inherited
)
4077 tree ivar_chain
= copy_list (CLASS_RAW_IVARS (interface
));
4079 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
4080 by the current class (i.e., they do not include super-class ivars).
4081 However, the CLASS_IVARS list will be side-effected by a call to
4082 finish_struct(), which will fill in field offsets. */
4083 if (!CLASS_IVARS (interface
))
4084 CLASS_IVARS (interface
) = ivar_chain
;
4089 while (CLASS_SUPER_NAME (interface
))
4091 /* Prepend super-class ivars. */
4092 interface
= lookup_interface (CLASS_SUPER_NAME (interface
));
4093 ivar_chain
= chainon (copy_list (CLASS_RAW_IVARS (interface
)),
4100 /* Create a temporary variable of type 'type'. If 'name' is set, uses
4101 the specified name, else use no name. Returns the declaration of
4102 the type. The 'name' is mostly useful for debugging.
4105 objc_create_temporary_var (tree type
, const char *name
)
4111 decl
= build_decl (input_location
,
4112 VAR_DECL
, get_identifier (name
), type
);
4116 decl
= build_decl (input_location
,
4117 VAR_DECL
, NULL_TREE
, type
);
4119 TREE_USED (decl
) = 1;
4120 DECL_ARTIFICIAL (decl
) = 1;
4121 DECL_IGNORED_P (decl
) = 1;
4122 DECL_CONTEXT (decl
) = current_function_decl
;
4127 /* Exception handling constructs. We begin by having the parser do most
4128 of the work and passing us blocks. What we do next depends on whether
4129 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
4130 We abstract all of this in a handful of appropriately named routines. */
4132 /* Stack of open try blocks. */
4134 struct objc_try_context
4136 struct objc_try_context
*outer
;
4138 /* Statements (or statement lists) as processed by the parser. */
4142 /* Some file position locations. */
4143 location_t try_locus
;
4144 location_t end_try_locus
;
4145 location_t end_catch_locus
;
4146 location_t finally_locus
;
4147 location_t end_finally_locus
;
4149 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
4150 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
4153 /* The CATCH_EXPR of an open @catch clause. */
4156 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
4162 static struct objc_try_context
*cur_try_context
;
4164 static GTY(()) tree objc_eh_personality_decl
;
4166 /* This hook, called via lang_eh_runtime_type, generates a runtime object
4167 that represents TYPE. For Objective-C, this is just the class name. */
4168 /* ??? Isn't there a class object or some such? Is it easy to get? */
4172 objc_eh_runtime_type (tree type
)
4174 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type
)), class_names
);
4178 objc_eh_personality (void)
4180 if (!flag_objc_sjlj_exceptions
&& !objc_eh_personality_decl
)
4181 objc_eh_personality_decl
= build_personality_function ("gnu_objc");
4182 return objc_eh_personality_decl
;
4186 /* Build __builtin_eh_pointer, or the moral equivalent. In the case
4187 of Darwin, we'll arrange for it to be initialized (and associated
4188 with a binding) later. */
4191 objc_build_exc_ptr (void)
4193 if (flag_objc_sjlj_exceptions
)
4195 tree var
= cur_try_context
->caught_decl
;
4198 var
= objc_create_temporary_var (objc_object_type
, NULL
);
4199 cur_try_context
->caught_decl
= var
;
4206 t
= built_in_decls
[BUILT_IN_EH_POINTER
];
4207 t
= build_call_expr (t
, 1, integer_zero_node
);
4208 return fold_convert (objc_object_type
, t
);
4212 /* Build "objc_exception_try_exit(&_stack)". */
4215 next_sjlj_build_try_exit (void)
4218 t
= build_fold_addr_expr_loc (input_location
, cur_try_context
->stack_decl
);
4219 t
= tree_cons (NULL
, t
, NULL
);
4220 t
= build_function_call (input_location
,
4221 objc_exception_try_exit_decl
, t
);
4226 objc_exception_try_enter (&_stack);
4227 if (_setjmp(&_stack.buf))
4231 Return the COND_EXPR. Note that the THEN and ELSE fields are left
4232 empty, ready for the caller to fill them in. */
4235 next_sjlj_build_enter_and_setjmp (void)
4237 tree t
, enter
, sj
, cond
;
4239 t
= build_fold_addr_expr_loc (input_location
, cur_try_context
->stack_decl
);
4240 t
= tree_cons (NULL
, t
, NULL
);
4241 enter
= build_function_call (input_location
,
4242 objc_exception_try_enter_decl
, t
);
4244 t
= objc_build_component_ref (cur_try_context
->stack_decl
,
4245 get_identifier ("buf"));
4246 t
= build_fold_addr_expr_loc (input_location
, t
);
4248 /* Convert _setjmp argument to type that is expected. */
4249 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl
)))
4250 t
= convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl
))), t
);
4252 t
= convert (ptr_type_node
, t
);
4254 t
= convert (ptr_type_node
, t
);
4256 t
= tree_cons (NULL
, t
, NULL
);
4257 sj
= build_function_call (input_location
,
4258 objc_setjmp_decl
, t
);
4260 cond
= build2 (COMPOUND_EXPR
, TREE_TYPE (sj
), enter
, sj
);
4261 cond
= c_common_truthvalue_conversion (input_location
, cond
);
4263 return build3 (COND_EXPR
, void_type_node
, cond
, NULL
, NULL
);
4268 DECL = objc_exception_extract(&_stack); */
4271 next_sjlj_build_exc_extract (tree decl
)
4275 t
= build_fold_addr_expr_loc (input_location
, cur_try_context
->stack_decl
);
4276 t
= tree_cons (NULL
, t
, NULL
);
4277 t
= build_function_call (input_location
,
4278 objc_exception_extract_decl
, t
);
4279 t
= convert (TREE_TYPE (decl
), t
);
4280 t
= build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
4286 if (objc_exception_match(obj_get_class(TYPE), _caught)
4293 objc_exception_try_exit(&_stack);
4295 from the sequence of CATCH_EXPRs in the current try context. */
4298 next_sjlj_build_catch_list (void)
4300 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
4302 tree
*last
= &catch_seq
;
4303 bool saw_id
= false;
4305 for (; !tsi_end_p (i
); tsi_next (&i
))
4307 tree stmt
= tsi_stmt (i
);
4308 tree type
= CATCH_TYPES (stmt
);
4309 tree body
= CATCH_BODY (stmt
);
4321 if (type
== error_mark_node
)
4322 cond
= error_mark_node
;
4325 args
= tree_cons (NULL
, cur_try_context
->caught_decl
, NULL
);
4326 t
= objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type
)));
4327 args
= tree_cons (NULL
, t
, args
);
4328 t
= build_function_call (input_location
,
4329 objc_exception_match_decl
, args
);
4330 cond
= c_common_truthvalue_conversion (input_location
, t
);
4332 t
= build3 (COND_EXPR
, void_type_node
, cond
, body
, NULL
);
4333 SET_EXPR_LOCATION (t
, EXPR_LOCATION (stmt
));
4336 last
= &COND_EXPR_ELSE (t
);
4342 t
= build2 (MODIFY_EXPR
, void_type_node
, cur_try_context
->rethrow_decl
,
4343 cur_try_context
->caught_decl
);
4344 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
4345 append_to_statement_list (t
, last
);
4347 t
= next_sjlj_build_try_exit ();
4348 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
4349 append_to_statement_list (t
, last
);
4355 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
4356 exception handling. We aim to build:
4359 struct _objc_exception_data _stack;
4363 objc_exception_try_enter (&_stack);
4364 if (_setjmp(&_stack.buf))
4366 id _caught = objc_exception_extract(&_stack);
4367 objc_exception_try_enter (&_stack);
4368 if (_setjmp(&_stack.buf))
4369 _rethrow = objc_exception_extract(&_stack);
4379 objc_exception_try_exit(&_stack);
4382 objc_exception_throw(_rethrow);
4386 If CATCH-LIST is empty, we can omit all of the block containing
4387 "_caught" except for the setting of _rethrow. Note the use of
4388 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
4389 but handles goto and other exits from the block. */
4392 next_sjlj_build_try_catch_finally (void)
4394 tree rethrow_decl
, stack_decl
, t
;
4395 tree catch_seq
, try_fin
, bind
;
4397 /* Create the declarations involved. */
4398 t
= xref_tag (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
4399 stack_decl
= objc_create_temporary_var (t
, NULL
);
4400 cur_try_context
->stack_decl
= stack_decl
;
4402 rethrow_decl
= objc_create_temporary_var (objc_object_type
, NULL
);
4403 cur_try_context
->rethrow_decl
= rethrow_decl
;
4404 TREE_CHAIN (rethrow_decl
) = stack_decl
;
4406 /* Build the outermost variable binding level. */
4407 bind
= build3 (BIND_EXPR
, void_type_node
, rethrow_decl
, NULL
, NULL
);
4408 SET_EXPR_LOCATION (bind
, cur_try_context
->try_locus
);
4409 TREE_SIDE_EFFECTS (bind
) = 1;
4411 /* Initialize rethrow_decl. */
4412 t
= build2 (MODIFY_EXPR
, void_type_node
, rethrow_decl
,
4413 convert (objc_object_type
, null_pointer_node
));
4414 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
4415 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
4417 /* Build the outermost TRY_FINALLY_EXPR. */
4418 try_fin
= build2 (TRY_FINALLY_EXPR
, void_type_node
, NULL
, NULL
);
4419 SET_EXPR_LOCATION (try_fin
, cur_try_context
->try_locus
);
4420 TREE_SIDE_EFFECTS (try_fin
) = 1;
4421 append_to_statement_list (try_fin
, &BIND_EXPR_BODY (bind
));
4423 /* Create the complete catch sequence. */
4424 if (cur_try_context
->catch_list
)
4426 tree caught_decl
= objc_build_exc_ptr ();
4427 catch_seq
= build_stmt (input_location
, BIND_EXPR
, caught_decl
, NULL
, NULL
);
4428 TREE_SIDE_EFFECTS (catch_seq
) = 1;
4430 t
= next_sjlj_build_exc_extract (caught_decl
);
4431 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
4433 t
= next_sjlj_build_enter_and_setjmp ();
4434 COND_EXPR_THEN (t
) = next_sjlj_build_exc_extract (rethrow_decl
);
4435 COND_EXPR_ELSE (t
) = next_sjlj_build_catch_list ();
4436 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
4439 catch_seq
= next_sjlj_build_exc_extract (rethrow_decl
);
4440 SET_EXPR_LOCATION (catch_seq
, cur_try_context
->end_try_locus
);
4442 /* Build the main register-and-try if statement. */
4443 t
= next_sjlj_build_enter_and_setjmp ();
4444 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
4445 COND_EXPR_THEN (t
) = catch_seq
;
4446 COND_EXPR_ELSE (t
) = cur_try_context
->try_body
;
4447 TREE_OPERAND (try_fin
, 0) = t
;
4449 /* Build the complete FINALLY statement list. */
4450 t
= next_sjlj_build_try_exit ();
4451 t
= build_stmt (input_location
, COND_EXPR
,
4452 c_common_truthvalue_conversion
4453 (input_location
, rethrow_decl
),
4455 SET_EXPR_LOCATION (t
, cur_try_context
->finally_locus
);
4456 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
4458 append_to_statement_list (cur_try_context
->finally_body
,
4459 &TREE_OPERAND (try_fin
, 1));
4461 t
= tree_cons (NULL
, rethrow_decl
, NULL
);
4462 t
= build_function_call (input_location
,
4463 objc_exception_throw_decl
, t
);
4464 t
= build_stmt (input_location
, COND_EXPR
,
4465 c_common_truthvalue_conversion (input_location
,
4468 SET_EXPR_LOCATION (t
, cur_try_context
->end_finally_locus
);
4469 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
4474 /* Called just after parsing the @try and its associated BODY. We now
4475 must prepare for the tricky bits -- handling the catches and finally. */
4478 objc_begin_try_stmt (location_t try_locus
, tree body
)
4480 struct objc_try_context
*c
= XCNEW (struct objc_try_context
);
4481 c
->outer
= cur_try_context
;
4483 c
->try_locus
= try_locus
;
4484 c
->end_try_locus
= input_location
;
4485 cur_try_context
= c
;
4487 /* -fobjc-exceptions is required to enable Objective-C exceptions.
4488 For example, on Darwin, ObjC exceptions require a sufficiently
4489 recent version of the runtime, so the user must ask for them
4490 explicitly. On other platforms, at the moment -fobjc-exceptions
4491 triggers -fexceptions which again is required for exceptions to
4494 if (!flag_objc_exceptions
)
4496 error_at (try_locus
, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4499 if (flag_objc_sjlj_exceptions
)
4500 objc_mark_locals_volatile (NULL
);
4503 /* Called just after parsing "@catch (parm)". Open a binding level,
4504 enter DECL into the binding level, and initialize it. Leave the
4505 binding level open while the body of the compound statement is parsed. */
4508 objc_begin_catch_clause (tree decl
)
4510 tree compound
, type
, t
;
4512 /* Begin a new scope that the entire catch clause will live in. */
4513 compound
= c_begin_compound_stmt (true);
4515 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
4516 decl
= build_decl (input_location
,
4517 VAR_DECL
, DECL_NAME (decl
), TREE_TYPE (decl
));
4518 lang_hooks
.decls
.pushdecl (decl
);
4520 /* Since a decl is required here by syntax, don't warn if its unused. */
4521 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
4522 be what the previous objc implementation did. */
4523 TREE_USED (decl
) = 1;
4524 DECL_READ_P (decl
) = 1;
4526 /* Verify that the type of the catch is valid. It must be a pointer
4527 to an Objective-C class, or "id" (which is catch-all). */
4528 type
= TREE_TYPE (decl
);
4530 if (POINTER_TYPE_P (type
) && objc_is_object_id (TREE_TYPE (type
)))
4532 else if (!POINTER_TYPE_P (type
) || !TYPED_OBJECT (TREE_TYPE (type
)))
4534 error ("@catch parameter is not a known Objective-C class type");
4535 type
= error_mark_node
;
4537 else if (cur_try_context
->catch_list
)
4539 /* Examine previous @catch clauses and see if we've already
4540 caught the type in question. */
4541 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
4542 for (; !tsi_end_p (i
); tsi_next (&i
))
4544 tree stmt
= tsi_stmt (i
);
4545 t
= CATCH_TYPES (stmt
);
4546 if (t
== error_mark_node
)
4548 if (!t
|| DERIVED_FROM_P (TREE_TYPE (t
), TREE_TYPE (type
)))
4550 warning (0, "exception of type %<%T%> will be caught",
4552 warning_at (EXPR_LOCATION (stmt
), 0, " by earlier handler for %<%T%>",
4553 TREE_TYPE (t
? t
: objc_object_type
));
4559 /* Record the data for the catch in the try context so that we can
4560 finalize it later. */
4561 t
= build_stmt (input_location
, CATCH_EXPR
, type
, compound
);
4562 cur_try_context
->current_catch
= t
;
4564 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
4565 t
= objc_build_exc_ptr ();
4566 t
= convert (TREE_TYPE (decl
), t
);
4567 t
= build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
4571 /* Called just after parsing the closing brace of a @catch clause. Close
4572 the open binding level, and record a CATCH_EXPR for it. */
4575 objc_finish_catch_clause (void)
4577 tree c
= cur_try_context
->current_catch
;
4578 cur_try_context
->current_catch
= NULL
;
4579 cur_try_context
->end_catch_locus
= input_location
;
4581 CATCH_BODY (c
) = c_end_compound_stmt (input_location
, CATCH_BODY (c
), 1);
4582 append_to_statement_list (c
, &cur_try_context
->catch_list
);
4585 /* Called after parsing a @finally clause and its associated BODY.
4586 Record the body for later placement. */
4589 objc_build_finally_clause (location_t finally_locus
, tree body
)
4591 cur_try_context
->finally_body
= body
;
4592 cur_try_context
->finally_locus
= finally_locus
;
4593 cur_try_context
->end_finally_locus
= input_location
;
4596 /* Called to finalize a @try construct. */
4599 objc_finish_try_stmt (void)
4601 struct objc_try_context
*c
= cur_try_context
;
4604 if (c
->catch_list
== NULL
&& c
->finally_body
== NULL
)
4605 error ("%<@try%> without %<@catch%> or %<@finally%>");
4607 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
4608 if (flag_objc_sjlj_exceptions
)
4610 bool save
= in_late_binary_op
;
4611 in_late_binary_op
= true;
4612 if (!cur_try_context
->finally_body
)
4614 cur_try_context
->finally_locus
= input_location
;
4615 cur_try_context
->end_finally_locus
= input_location
;
4617 stmt
= next_sjlj_build_try_catch_finally ();
4618 in_late_binary_op
= save
;
4622 /* Otherwise, nest the CATCH inside a FINALLY. */
4626 stmt
= build_stmt (input_location
, TRY_CATCH_EXPR
, stmt
, c
->catch_list
);
4627 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
4629 if (c
->finally_body
)
4631 stmt
= build_stmt (input_location
, TRY_FINALLY_EXPR
, stmt
, c
->finally_body
);
4632 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
4637 cur_try_context
= c
->outer
;
4643 objc_build_throw_stmt (location_t loc
, tree throw_expr
)
4647 if (!flag_objc_exceptions
)
4649 error_at (loc
, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4652 if (throw_expr
== NULL
)
4654 /* If we're not inside a @catch block, there is no "current
4655 exception" to be rethrown. */
4656 if (cur_try_context
== NULL
4657 || cur_try_context
->current_catch
== NULL
)
4659 error_at (loc
, "%<@throw%> (rethrow) used outside of a @catch block");
4663 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
4664 value that we get from the runtime. */
4665 throw_expr
= objc_build_exc_ptr ();
4668 /* A throw is just a call to the runtime throw function with the
4669 object as a parameter. */
4670 args
= tree_cons (NULL
, throw_expr
, NULL
);
4671 return add_stmt (build_function_call (loc
,
4672 objc_exception_throw_decl
, args
));
4676 objc_build_synchronized (location_t start_locus
, tree mutex
, tree body
)
4680 /* First lock the mutex. */
4681 mutex
= save_expr (mutex
);
4682 args
= tree_cons (NULL
, mutex
, NULL
);
4683 call
= build_function_call (input_location
,
4684 objc_sync_enter_decl
, args
);
4685 SET_EXPR_LOCATION (call
, start_locus
);
4688 /* Build the mutex unlock. */
4689 args
= tree_cons (NULL
, mutex
, NULL
);
4690 call
= build_function_call (input_location
,
4691 objc_sync_exit_decl
, args
);
4692 SET_EXPR_LOCATION (call
, input_location
);
4694 /* Put the that and the body in a TRY_FINALLY. */
4695 objc_begin_try_stmt (start_locus
, body
);
4696 objc_build_finally_clause (input_location
, call
);
4697 return objc_finish_try_stmt ();
4701 /* Predefine the following data type:
4703 struct _objc_exception_data
4705 int buf[OBJC_JBLEN];
4709 /* The following yuckiness should prevent users from having to #include
4710 <setjmp.h> in their code... */
4712 /* Define to a harmless positive value so the below code doesn't die. */
4714 #define OBJC_JBLEN 18
4718 build_next_objc_exception_stuff (void)
4720 tree decls
, temp_type
, *chain
= NULL
;
4722 objc_exception_data_template
4723 = objc_start_struct (get_identifier (UTAG_EXCDATA
));
4725 /* int buf[OBJC_JBLEN]; */
4727 temp_type
= build_sized_array_type (integer_type_node
, OBJC_JBLEN
);
4728 decls
= add_field_decl (temp_type
, "buf", &chain
);
4730 /* void *pointers[4]; */
4732 temp_type
= build_sized_array_type (ptr_type_node
, 4);
4733 add_field_decl (temp_type
, "pointers", &chain
);
4735 objc_finish_struct (objc_exception_data_template
, decls
);
4737 /* int _setjmp(...); */
4738 /* If the user includes <setjmp.h>, this shall be superseded by
4739 'int _setjmp(jmp_buf);' */
4740 temp_type
= build_varargs_function_type_list (integer_type_node
, NULL_TREE
);
4742 = add_builtin_function (TAG_SETJMP
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
4744 /* id objc_exception_extract(struct _objc_exception_data *); */
4746 = build_function_type_list (objc_object_type
,
4747 build_pointer_type (objc_exception_data_template
),
4749 objc_exception_extract_decl
4750 = add_builtin_function (TAG_EXCEPTIONEXTRACT
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4752 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4753 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4755 = build_function_type_list (void_type_node
,
4756 build_pointer_type (objc_exception_data_template
),
4758 objc_exception_try_enter_decl
4759 = add_builtin_function (TAG_EXCEPTIONTRYENTER
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4761 objc_exception_try_exit_decl
4762 = add_builtin_function (TAG_EXCEPTIONTRYEXIT
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4765 /* int objc_exception_match(id, id); */
4767 = build_function_type_list (integer_type_node
,
4768 objc_object_type
, objc_object_type
, NULL_TREE
);
4769 objc_exception_match_decl
4770 = add_builtin_function (TAG_EXCEPTIONMATCH
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4773 /* id objc_assign_ivar (id, id, unsigned int); */
4774 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4775 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4777 = build_function_type_list (objc_object_type
,
4782 objc_assign_ivar_decl
4783 = add_builtin_function (TAG_ASSIGNIVAR
, temp_type
, 0, NOT_BUILT_IN
,
4785 #ifdef OFFS_ASSIGNIVAR_FAST
4786 objc_assign_ivar_fast_decl
4787 = add_builtin_function (TAG_ASSIGNIVAR_FAST
, temp_type
, 0,
4788 NOT_BUILT_IN
, NULL
, NULL_TREE
);
4789 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl
)
4790 = tree_cons (get_identifier ("hard_coded_address"),
4791 build_int_cst (NULL_TREE
, OFFS_ASSIGNIVAR_FAST
),
4794 /* Default to slower ivar method. */
4795 objc_assign_ivar_fast_decl
= objc_assign_ivar_decl
;
4798 /* id objc_assign_global (id, id *); */
4799 /* id objc_assign_strongCast (id, id *); */
4800 temp_type
= build_function_type_list (objc_object_type
,
4802 build_pointer_type (objc_object_type
),
4804 objc_assign_global_decl
4805 = add_builtin_function (TAG_ASSIGNGLOBAL
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4807 objc_assign_strong_cast_decl
4808 = add_builtin_function (TAG_ASSIGNSTRONGCAST
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4813 build_objc_exception_stuff (void)
4815 tree noreturn_list
, nothrow_list
, temp_type
;
4817 noreturn_list
= tree_cons (get_identifier ("noreturn"), NULL
, NULL
);
4818 nothrow_list
= tree_cons (get_identifier ("nothrow"), NULL
, NULL
);
4820 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4821 /* void objc_sync_enter(id); */
4822 /* void objc_sync_exit(id); */
4823 temp_type
= build_function_type_list (void_type_node
,
4826 objc_exception_throw_decl
4827 = add_builtin_function (TAG_EXCEPTIONTHROW
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4829 objc_sync_enter_decl
4830 = add_builtin_function (TAG_SYNCENTER
, temp_type
, 0, NOT_BUILT_IN
,
4831 NULL
, nothrow_list
);
4833 = add_builtin_function (TAG_SYNCEXIT
, temp_type
, 0, NOT_BUILT_IN
,
4834 NULL
, nothrow_list
);
4837 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4840 struct <classname> {
4841 struct _objc_class *isa;
4846 build_private_template (tree klass
)
4848 if (!CLASS_STATIC_TEMPLATE (klass
))
4850 tree record
= objc_build_struct (klass
,
4851 get_class_ivars (klass
, false),
4852 CLASS_SUPER_NAME (klass
));
4854 /* Set the TREE_USED bit for this struct, so that stab generator
4855 can emit stabs for this struct type. */
4856 if (flag_debug_only_used_symbols
&& TYPE_STUB_DECL (record
))
4857 TREE_USED (TYPE_STUB_DECL (record
)) = 1;
4861 /* Begin code generation for protocols... */
4863 /* struct _objc_protocol {
4864 struct _objc_class *isa;
4865 char *protocol_name;
4866 struct _objc_protocol **protocol_list;
4867 struct _objc__method_prototype_list *instance_methods;
4868 struct _objc__method_prototype_list *class_methods;
4872 build_protocol_template (void)
4874 tree ptype
, decls
, *chain
= NULL
;
4876 objc_protocol_template
= objc_start_struct (get_identifier (UTAG_PROTOCOL
));
4878 /* struct _objc_class *isa; */
4879 ptype
= build_pointer_type (xref_tag (RECORD_TYPE
,
4880 get_identifier (UTAG_CLASS
)));
4881 decls
= add_field_decl (ptype
, "isa", &chain
);
4883 /* char *protocol_name; */
4884 add_field_decl (string_type_node
, "protocol_name", &chain
);
4886 /* struct _objc_protocol **protocol_list; */
4887 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
4888 add_field_decl (ptype
, "protocol_list", &chain
);
4890 /* struct _objc__method_prototype_list *instance_methods; */
4891 add_field_decl (objc_method_proto_list_ptr
, "instance_methods", &chain
);
4893 /* struct _objc__method_prototype_list *class_methods; */
4894 add_field_decl (objc_method_proto_list_ptr
, "class_methods", &chain
);
4896 objc_finish_struct (objc_protocol_template
, decls
);
4900 build_descriptor_table_initializer (tree type
, tree entries
)
4902 VEC(constructor_elt
,gc
) *inits
= NULL
;
4906 VEC(constructor_elt
,gc
) *elts
= NULL
;
4908 CONSTRUCTOR_APPEND_ELT (elts
, NULL_TREE
,
4909 build_selector (METHOD_SEL_NAME (entries
)));
4910 CONSTRUCTOR_APPEND_ELT (elts
, NULL_TREE
,
4911 add_objc_string (METHOD_ENCODING (entries
),
4914 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
,
4915 objc_build_constructor (type
, elts
));
4917 entries
= DECL_CHAIN (entries
);
4921 return objc_build_constructor (build_array_type (type
, 0), inits
);
4924 /* struct objc_method_prototype_list {
4926 struct objc_method_prototype {
4933 build_method_prototype_list_template (tree list_type
, int size
)
4935 tree objc_ivar_list_record
;
4936 tree array_type
, decls
, *chain
= NULL
;
4938 /* Generate an unnamed struct definition. */
4940 objc_ivar_list_record
= objc_start_struct (NULL_TREE
);
4942 /* int method_count; */
4943 decls
= add_field_decl (integer_type_node
, "method_count", &chain
);
4945 /* struct objc_method method_list[]; */
4946 array_type
= build_sized_array_type (list_type
, size
);
4947 add_field_decl (array_type
, "method_list", &chain
);
4949 objc_finish_struct (objc_ivar_list_record
, decls
);
4951 return objc_ivar_list_record
;
4955 build_method_prototype_template (void)
4958 tree decls
, *chain
= NULL
;
4960 proto_record
= objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE
));
4963 decls
= add_field_decl (objc_selector_type
, "_cmd", &chain
);
4965 /* char *method_types; */
4966 add_field_decl (string_type_node
, "method_types", &chain
);
4968 objc_finish_struct (proto_record
, decls
);
4970 return proto_record
;
4974 objc_method_parm_type (tree type
)
4976 type
= TREE_VALUE (TREE_TYPE (type
));
4977 if (TREE_CODE (type
) == TYPE_DECL
)
4978 type
= TREE_TYPE (type
);
4983 objc_encoded_type_size (tree type
)
4985 int sz
= int_size_in_bytes (type
);
4987 /* Make all integer and enum types at least as large
4989 if (sz
> 0 && INTEGRAL_TYPE_P (type
))
4990 sz
= MAX (sz
, int_size_in_bytes (integer_type_node
));
4991 /* Treat arrays as pointers, since that's how they're
4993 else if (TREE_CODE (type
) == ARRAY_TYPE
)
4994 sz
= int_size_in_bytes (ptr_type_node
);
4998 /* Encode a method prototype.
5000 The format is described in gcc/doc/objc.texi, section 'Method
5004 encode_method_prototype (tree method_decl
)
5011 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
5012 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
5014 /* Encode return type. */
5015 encode_type (objc_method_parm_type (method_decl
),
5016 obstack_object_size (&util_obstack
),
5017 OBJC_ENCODE_INLINE_DEFS
);
5020 /* The first two arguments (self and _cmd) are pointers; account for
5022 i
= int_size_in_bytes (ptr_type_node
);
5023 parm_offset
= 2 * i
;
5024 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
5025 parms
= DECL_CHAIN (parms
))
5027 tree type
= objc_method_parm_type (parms
);
5028 int sz
= objc_encoded_type_size (type
);
5030 /* If a type size is not known, bail out. */
5033 error ("type %q+D does not have a known size",
5035 /* Pretend that the encoding succeeded; the compilation will
5036 fail nevertheless. */
5037 goto finish_encoding
;
5042 sprintf (buf
, "%d@0:%d", parm_offset
, i
);
5043 obstack_grow (&util_obstack
, buf
, strlen (buf
));
5045 /* Argument types. */
5046 parm_offset
= 2 * i
;
5047 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
5048 parms
= DECL_CHAIN (parms
))
5050 tree type
= objc_method_parm_type (parms
);
5052 /* Process argument qualifiers for user supplied arguments. */
5053 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms
)));
5056 encode_type (type
, obstack_object_size (&util_obstack
),
5057 OBJC_ENCODE_INLINE_DEFS
);
5059 /* Compute offset. */
5060 sprintf (buf
, "%d", parm_offset
);
5061 parm_offset
+= objc_encoded_type_size (type
);
5063 obstack_grow (&util_obstack
, buf
, strlen (buf
));
5067 obstack_1grow (&util_obstack
, '\0');
5068 result
= get_identifier (XOBFINISH (&util_obstack
, char *));
5069 obstack_free (&util_obstack
, util_firstobj
);
5074 generate_descriptor_table (tree type
, const char *name
, int size
, tree list
,
5078 VEC(constructor_elt
,gc
) *v
= NULL
;
5080 decl
= start_var_decl (type
, synth_id_with_class_suffix (name
, proto
));
5082 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
5083 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, list
);
5085 finish_var_decl (decl
, objc_build_constructor (type
, v
));
5091 generate_method_descriptors (tree protocol
)
5093 tree initlist
, chain
, method_list_template
;
5096 if (!objc_method_prototype_template
)
5097 objc_method_prototype_template
= build_method_prototype_template ();
5099 chain
= PROTOCOL_CLS_METHODS (protocol
);
5102 size
= list_length (chain
);
5104 method_list_template
5105 = build_method_prototype_list_template (objc_method_prototype_template
,
5109 = build_descriptor_table_initializer (objc_method_prototype_template
,
5112 UOBJC_CLASS_METHODS_decl
5113 = generate_descriptor_table (method_list_template
,
5114 "_OBJC_PROTOCOL_CLASS_METHODS",
5115 size
, initlist
, protocol
);
5118 UOBJC_CLASS_METHODS_decl
= 0;
5120 chain
= PROTOCOL_NST_METHODS (protocol
);
5123 size
= list_length (chain
);
5125 method_list_template
5126 = build_method_prototype_list_template (objc_method_prototype_template
,
5129 = build_descriptor_table_initializer (objc_method_prototype_template
,
5132 UOBJC_INSTANCE_METHODS_decl
5133 = generate_descriptor_table (method_list_template
,
5134 "_OBJC_PROTOCOL_INSTANCE_METHODS",
5135 size
, initlist
, protocol
);
5138 UOBJC_INSTANCE_METHODS_decl
= 0;
5142 generate_protocol_references (tree plist
)
5146 /* Forward declare protocols referenced. */
5147 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
5149 tree proto
= TREE_VALUE (lproto
);
5151 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
5152 && PROTOCOL_NAME (proto
))
5154 if (! PROTOCOL_FORWARD_DECL (proto
))
5155 build_protocol_reference (proto
);
5157 if (PROTOCOL_LIST (proto
))
5158 generate_protocol_references (PROTOCOL_LIST (proto
));
5163 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
5167 objc_generate_cxx_ctor_or_dtor (bool dtor
)
5169 tree fn
, body
, compound_stmt
, ivar
;
5171 /* - (id) .cxx_construct { ... return self; } */
5172 /* - (void) .cxx_construct { ... } */
5174 objc_set_method_type (MINUS_EXPR
);
5175 objc_start_method_definition
5176 (objc_build_method_signature (build_tree_list (NULL_TREE
,
5179 : objc_object_type
),
5180 get_identifier (dtor
5182 : TAG_CXX_CONSTRUCT
),
5183 make_node (TREE_LIST
),
5185 body
= begin_function_body ();
5186 compound_stmt
= begin_compound_stmt (0);
5188 ivar
= CLASS_IVARS (implementation_template
);
5189 /* Destroy ivars in reverse order. */
5191 ivar
= nreverse (copy_list (ivar
));
5193 for (; ivar
; ivar
= TREE_CHAIN (ivar
))
5195 if (TREE_CODE (ivar
) == FIELD_DECL
)
5197 tree type
= TREE_TYPE (ivar
);
5199 /* Call the ivar's default constructor or destructor. Do not
5200 call the destructor unless a corresponding constructor call
5201 has also been made (or is not needed). */
5202 if (MAYBE_CLASS_TYPE_P (type
)
5204 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type
)
5205 && (!TYPE_NEEDS_CONSTRUCTING (type
)
5206 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type
)))
5207 : (TYPE_NEEDS_CONSTRUCTING (type
)
5208 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type
))))
5210 (build_special_member_call
5211 (build_ivar_reference (DECL_NAME (ivar
)),
5212 dtor
? complete_dtor_identifier
: complete_ctor_identifier
,
5213 NULL
, type
, LOOKUP_NORMAL
, tf_warning_or_error
));
5217 /* The constructor returns 'self'. */
5219 finish_return_stmt (self_decl
);
5221 finish_compound_stmt (compound_stmt
);
5222 finish_function_body (body
);
5223 fn
= current_function_decl
;
5225 objc_finish_method_definition (fn
);
5228 /* The following routine will examine the current @interface for any
5229 non-POD C++ ivars requiring non-trivial construction and/or
5230 destruction, and then synthesize special '- .cxx_construct' and/or
5231 '- .cxx_destruct' methods which will run the appropriate
5232 construction or destruction code. Note that ivars inherited from
5233 super-classes are _not_ considered. */
5235 objc_generate_cxx_cdtors (void)
5237 bool need_ctor
= false, need_dtor
= false;
5240 /* Error case, due to possibly an extra @end. */
5241 if (!objc_implementation_context
)
5244 /* We do not want to do this for categories, since they do not have
5247 if (TREE_CODE (objc_implementation_context
) != CLASS_IMPLEMENTATION_TYPE
)
5250 /* First, determine if we even need a constructor and/or destructor. */
5252 for (ivar
= CLASS_IVARS (implementation_template
); ivar
;
5253 ivar
= TREE_CHAIN (ivar
))
5255 if (TREE_CODE (ivar
) == FIELD_DECL
)
5257 tree type
= TREE_TYPE (ivar
);
5259 if (MAYBE_CLASS_TYPE_P (type
))
5261 if (TYPE_NEEDS_CONSTRUCTING (type
)
5262 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type
))
5263 /* NB: If a default constructor is not available, we will not
5264 be able to initialize this ivar; the add_instance_variable()
5265 routine will already have warned about this. */
5268 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type
)
5269 && (!TYPE_NEEDS_CONSTRUCTING (type
)
5270 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type
)))
5271 /* NB: If a default constructor is not available, we will not
5272 call the destructor either, for symmetry. */
5278 /* Generate '- .cxx_construct' if needed. */
5281 objc_generate_cxx_ctor_or_dtor (false);
5283 /* Generate '- .cxx_destruct' if needed. */
5286 objc_generate_cxx_ctor_or_dtor (true);
5288 /* The 'imp_list' variable points at an imp_entry record for the current
5289 @implementation. Record the existence of '- .cxx_construct' and/or
5290 '- .cxx_destruct' methods therein; it will be included in the
5291 metadata for the class. */
5292 if (flag_next_runtime
)
5293 imp_list
->has_cxx_cdtors
= (need_ctor
|| need_dtor
);
5297 /* For each protocol which was referenced either from a @protocol()
5298 expression, or because a class/category implements it (then a
5299 pointer to the protocol is stored in the struct describing the
5300 class/category), we create a statically allocated instance of the
5301 Protocol class. The code is written in such a way as to generate
5302 as few Protocol objects as possible; we generate a unique Protocol
5303 instance for each protocol, and we don't generate a Protocol
5304 instance if the protocol is never referenced (either from a
5305 @protocol() or from a class/category implementation). These
5306 statically allocated objects can be referred to via the static
5307 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
5309 The statically allocated Protocol objects that we generate here
5310 need to be fixed up at runtime in order to be used: the 'isa'
5311 pointer of the objects need to be set up to point to the 'Protocol'
5312 class, as known at runtime.
5314 The NeXT runtime fixes up all protocols at program startup time,
5315 before main() is entered. It uses a low-level trick to look up all
5316 those symbols, then loops on them and fixes them up.
5318 The GNU runtime as well fixes up all protocols before user code
5319 from the module is executed; it requires pointers to those symbols
5320 to be put in the objc_symtab (which is then passed as argument to
5321 the function __objc_exec_class() which the compiler sets up to be
5322 executed automatically when the module is loaded); setup of those
5323 Protocol objects happen in two ways in the GNU runtime: all
5324 Protocol objects referred to by a class or category implementation
5325 are fixed up when the class/category is loaded; all Protocol
5326 objects referred to by a @protocol() expression are added by the
5327 compiler to the list of statically allocated instances to fixup
5328 (the same list holding the statically allocated constant string
5329 objects). Because, as explained above, the compiler generates as
5330 few Protocol objects as possible, some Protocol object might end up
5331 being referenced multiple times when compiled with the GNU runtime,
5332 and end up being fixed up multiple times at runtime initialization.
5333 But that doesn't hurt, it's just a little inefficient. */
5336 generate_protocols (void)
5340 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
5342 /* If a protocol was directly referenced, pull in indirect references. */
5343 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
5344 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
5345 generate_protocol_references (PROTOCOL_LIST (p
));
5347 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
5349 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
5350 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
5352 /* If protocol wasn't referenced, don't generate any code. */
5353 decl
= PROTOCOL_FORWARD_DECL (p
);
5358 /* Make sure we link in the Protocol class. */
5359 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
5363 if (! METHOD_ENCODING (nst_methods
))
5365 encoding
= encode_method_prototype (nst_methods
);
5366 METHOD_ENCODING (nst_methods
) = encoding
;
5368 nst_methods
= DECL_CHAIN (nst_methods
);
5373 if (! METHOD_ENCODING (cls_methods
))
5375 encoding
= encode_method_prototype (cls_methods
);
5376 METHOD_ENCODING (cls_methods
) = encoding
;
5379 cls_methods
= DECL_CHAIN (cls_methods
);
5381 generate_method_descriptors (p
);
5383 if (PROTOCOL_LIST (p
))
5384 refs_decl
= generate_protocol_list (p
);
5388 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5389 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
5392 refs_expr
= convert (build_pointer_type (build_pointer_type
5393 (objc_protocol_template
)),
5394 build_unary_op (input_location
,
5395 ADDR_EXPR
, refs_decl
, 0));
5397 refs_expr
= build_int_cst (NULL_TREE
, 0);
5399 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
5400 by generate_method_descriptors, which is called above. */
5401 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
5402 protocol_name_expr
, refs_expr
,
5403 UOBJC_INSTANCE_METHODS_decl
,
5404 UOBJC_CLASS_METHODS_decl
);
5405 finish_var_decl (decl
, initlist
);
5410 build_protocol_initializer (tree type
, tree protocol_name
,
5411 tree protocol_list
, tree instance_methods
,
5415 tree cast_type
= build_pointer_type
5416 (xref_tag (RECORD_TYPE
,
5417 get_identifier (UTAG_CLASS
)));
5418 VEC(constructor_elt
,gc
) *inits
= NULL
;
5420 /* Filling the "isa" in with one allows the runtime system to
5421 detect that the version change...should remove before final release. */
5423 expr
= build_int_cst (cast_type
, PROTOCOL_VERSION
);
5424 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
5425 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_name
);
5426 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_list
);
5428 if (!instance_methods
)
5429 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
5432 expr
= convert (objc_method_proto_list_ptr
,
5433 build_unary_op (input_location
,
5434 ADDR_EXPR
, instance_methods
, 0));
5435 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
5439 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
5442 expr
= convert (objc_method_proto_list_ptr
,
5443 build_unary_op (input_location
,
5444 ADDR_EXPR
, class_methods
, 0));
5445 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
5448 return objc_build_constructor (type
, inits
);
5451 /* struct _objc_category {
5452 char *category_name;
5454 struct _objc_method_list *instance_methods;
5455 struct _objc_method_list *class_methods;
5456 struct _objc_protocol_list *protocols;
5460 build_category_template (void)
5462 tree ptype
, decls
, *chain
= NULL
;
5464 objc_category_template
= objc_start_struct (get_identifier (UTAG_CATEGORY
));
5466 /* char *category_name; */
5467 decls
= add_field_decl (string_type_node
, "category_name", &chain
);
5469 /* char *class_name; */
5470 add_field_decl (string_type_node
, "class_name", &chain
);
5472 /* struct _objc_method_list *instance_methods; */
5473 add_field_decl (objc_method_list_ptr
, "instance_methods", &chain
);
5475 /* struct _objc_method_list *class_methods; */
5476 add_field_decl (objc_method_list_ptr
, "class_methods", &chain
);
5478 /* struct _objc_protocol **protocol_list; */
5479 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
5480 add_field_decl (ptype
, "protocol_list", &chain
);
5482 objc_finish_struct (objc_category_template
, decls
);
5485 /* struct _objc_selector {
5491 build_selector_template (void)
5493 tree decls
, *chain
= NULL
;
5495 objc_selector_template
= objc_start_struct (get_identifier (UTAG_SELECTOR
));
5498 decls
= add_field_decl (objc_selector_type
, "sel_id", &chain
);
5500 /* char *sel_type; */
5501 add_field_decl (string_type_node
, "sel_type", &chain
);
5503 objc_finish_struct (objc_selector_template
, decls
);
5506 /* struct _objc_class {
5507 struct _objc_class *isa;
5508 struct _objc_class *super_class;
5513 struct _objc_ivar_list *ivars;
5514 struct _objc_method_list *methods;
5515 #ifdef __NEXT_RUNTIME__
5516 struct objc_cache *cache;
5518 struct sarray *dtable;
5519 struct _objc_class *subclass_list;
5520 struct _objc_class *sibling_class;
5522 struct _objc_protocol_list *protocols;
5523 #ifdef __NEXT_RUNTIME__
5526 void *gc_object_type;
5529 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
5530 the NeXT/Apple runtime; still, the compiler must generate them to
5531 maintain backward binary compatibility (and to allow for future
5535 build_class_template (void)
5537 tree ptype
, decls
, *chain
= NULL
;
5539 objc_class_template
= objc_start_struct (get_identifier (UTAG_CLASS
));
5541 /* struct _objc_class *isa; */
5542 decls
= add_field_decl (build_pointer_type (objc_class_template
),
5545 /* struct _objc_class *super_class; */
5546 add_field_decl (build_pointer_type (objc_class_template
),
5547 "super_class", &chain
);
5550 add_field_decl (string_type_node
, "name", &chain
);
5553 add_field_decl (long_integer_type_node
, "version", &chain
);
5556 add_field_decl (long_integer_type_node
, "info", &chain
);
5558 /* long instance_size; */
5559 add_field_decl (long_integer_type_node
, "instance_size", &chain
);
5561 /* struct _objc_ivar_list *ivars; */
5562 add_field_decl (objc_ivar_list_ptr
,"ivars", &chain
);
5564 /* struct _objc_method_list *methods; */
5565 add_field_decl (objc_method_list_ptr
, "methods", &chain
);
5567 if (flag_next_runtime
)
5569 /* struct objc_cache *cache; */
5570 ptype
= build_pointer_type (xref_tag (RECORD_TYPE
,
5571 get_identifier ("objc_cache")));
5572 add_field_decl (ptype
, "cache", &chain
);
5576 /* struct sarray *dtable; */
5577 ptype
= build_pointer_type(xref_tag (RECORD_TYPE
,
5578 get_identifier ("sarray")));
5579 add_field_decl (ptype
, "dtable", &chain
);
5581 /* struct objc_class *subclass_list; */
5582 ptype
= build_pointer_type (objc_class_template
);
5583 add_field_decl (ptype
, "subclass_list", &chain
);
5585 /* struct objc_class *sibling_class; */
5586 ptype
= build_pointer_type (objc_class_template
);
5587 add_field_decl (ptype
, "sibling_class", &chain
);
5590 /* struct _objc_protocol **protocol_list; */
5591 ptype
= build_pointer_type (build_pointer_type
5592 (xref_tag (RECORD_TYPE
,
5593 get_identifier (UTAG_PROTOCOL
))));
5594 add_field_decl (ptype
, "protocol_list", &chain
);
5596 if (flag_next_runtime
)
5599 add_field_decl (build_pointer_type (void_type_node
), "sel_id", &chain
);
5602 /* void *gc_object_type; */
5603 add_field_decl (build_pointer_type (void_type_node
),
5604 "gc_object_type", &chain
);
5606 objc_finish_struct (objc_class_template
, decls
);
5609 /* Generate appropriate forward declarations for an implementation. */
5612 synth_forward_declarations (void)
5616 /* static struct objc_class _OBJC_CLASS_<my_name>; */
5617 UOBJC_CLASS_decl
= build_metadata_decl ("_OBJC_CLASS",
5618 objc_class_template
);
5620 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
5621 UOBJC_METACLASS_decl
= build_metadata_decl ("_OBJC_METACLASS",
5622 objc_class_template
);
5624 /* Pre-build the following entities - for speed/convenience. */
5626 an_id
= get_identifier ("super_class");
5627 ucls_super_ref
= objc_build_component_ref (UOBJC_CLASS_decl
, an_id
);
5628 uucls_super_ref
= objc_build_component_ref (UOBJC_METACLASS_decl
, an_id
);
5632 error_with_ivar (const char *message
, tree decl
)
5634 error_at (DECL_SOURCE_LOCATION (decl
), "%s %qs",
5635 message
, identifier_to_locale (gen_declaration (decl
)));
5640 check_ivars (tree inter
, tree imp
)
5642 tree intdecls
= CLASS_RAW_IVARS (inter
);
5643 tree impdecls
= CLASS_RAW_IVARS (imp
);
5650 if (intdecls
&& TREE_CODE (intdecls
) == TYPE_DECL
)
5651 intdecls
= TREE_CHAIN (intdecls
);
5653 if (intdecls
== 0 && impdecls
== 0)
5655 if (intdecls
== 0 || impdecls
== 0)
5657 error ("inconsistent instance variable specification");
5661 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
5663 if (!comptypes (t1
, t2
)
5664 || !tree_int_cst_equal (DECL_INITIAL (intdecls
),
5665 DECL_INITIAL (impdecls
)))
5667 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
5669 error_with_ivar ("conflicting instance variable type",
5671 error_with_ivar ("previous declaration of",
5674 else /* both the type and the name don't match */
5676 error ("inconsistent instance variable specification");
5681 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
5683 error_with_ivar ("conflicting instance variable name",
5685 error_with_ivar ("previous declaration of",
5689 intdecls
= DECL_CHAIN (intdecls
);
5690 impdecls
= DECL_CHAIN (impdecls
);
5694 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5695 This needs to be done just once per compilation. */
5697 /* struct _objc_super {
5698 struct _objc_object *self;
5699 struct _objc_class *super_class;
5703 build_super_template (void)
5705 tree decls
, *chain
= NULL
;
5707 objc_super_template
= objc_start_struct (get_identifier (UTAG_SUPER
));
5709 /* struct _objc_object *self; */
5710 decls
= add_field_decl (objc_object_type
, "self", &chain
);
5712 /* struct _objc_class *super_class; */
5713 add_field_decl (build_pointer_type (objc_class_template
),
5714 "super_class", &chain
);
5716 objc_finish_struct (objc_super_template
, decls
);
5719 /* struct _objc_ivar {
5726 build_ivar_template (void)
5728 tree objc_ivar_id
, objc_ivar_record
;
5729 tree decls
, *chain
= NULL
;
5731 objc_ivar_id
= get_identifier (UTAG_IVAR
);
5732 objc_ivar_record
= objc_start_struct (objc_ivar_id
);
5734 /* char *ivar_name; */
5735 decls
= add_field_decl (string_type_node
, "ivar_name", &chain
);
5737 /* char *ivar_type; */
5738 add_field_decl (string_type_node
, "ivar_type", &chain
);
5740 /* int ivar_offset; */
5741 add_field_decl (integer_type_node
, "ivar_offset", &chain
);
5743 objc_finish_struct (objc_ivar_record
, decls
);
5745 return objc_ivar_record
;
5750 struct objc_ivar ivar_list[ivar_count];
5754 build_ivar_list_template (tree list_type
, int size
)
5756 tree objc_ivar_list_record
;
5757 tree array_type
, decls
, *chain
= NULL
;
5759 objc_ivar_list_record
= objc_start_struct (NULL_TREE
);
5761 /* int ivar_count; */
5762 decls
= add_field_decl (integer_type_node
, "ivar_count", &chain
);
5764 /* struct objc_ivar ivar_list[]; */
5765 array_type
= build_sized_array_type (list_type
, size
);
5766 add_field_decl (array_type
, "ivar_list", &chain
);
5768 objc_finish_struct (objc_ivar_list_record
, decls
);
5770 return objc_ivar_list_record
;
5774 struct _objc__method_prototype_list *method_next;
5776 struct objc_method method_list[method_count];
5780 build_method_list_template (tree list_type
, int size
)
5782 tree objc_ivar_list_record
;
5783 tree array_type
, decls
, *chain
= NULL
;
5785 objc_ivar_list_record
= objc_start_struct (NULL_TREE
);
5787 /* struct _objc__method_prototype_list *method_next; */
5788 decls
= add_field_decl (objc_method_proto_list_ptr
, "method_next", &chain
);
5790 /* int method_count; */
5791 add_field_decl (integer_type_node
, "method_count", &chain
);
5793 /* struct objc_method method_list[]; */
5794 array_type
= build_sized_array_type (list_type
, size
);
5795 add_field_decl (array_type
, "method_list", &chain
);
5797 objc_finish_struct (objc_ivar_list_record
, decls
);
5799 return objc_ivar_list_record
;
5803 build_ivar_list_initializer (tree type
, tree field_decl
)
5805 VEC(constructor_elt
,gc
) *inits
= NULL
;
5809 VEC(constructor_elt
,gc
) *ivar
= NULL
;
5813 if (DECL_NAME (field_decl
))
5814 CONSTRUCTOR_APPEND_ELT (ivar
, NULL_TREE
,
5815 add_objc_string (DECL_NAME (field_decl
),
5818 /* Unnamed bit-field ivar (yuck). */
5819 CONSTRUCTOR_APPEND_ELT (ivar
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
5822 encode_field_decl (field_decl
,
5823 obstack_object_size (&util_obstack
),
5824 OBJC_ENCODE_DONT_INLINE_DEFS
);
5826 /* Null terminate string. */
5827 obstack_1grow (&util_obstack
, 0);
5828 id
= add_objc_string (get_identifier (XOBFINISH (&util_obstack
, char *)),
5830 CONSTRUCTOR_APPEND_ELT (ivar
, NULL_TREE
, id
);
5831 obstack_free (&util_obstack
, util_firstobj
);
5834 CONSTRUCTOR_APPEND_ELT (ivar
, NULL_TREE
, byte_position (field_decl
));
5835 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
,
5836 objc_build_constructor (type
, ivar
));
5838 field_decl
= DECL_CHAIN (field_decl
);
5839 while (field_decl
&& TREE_CODE (field_decl
) != FIELD_DECL
);
5843 return objc_build_constructor (build_array_type (type
, 0), inits
);
5847 generate_ivars_list (tree type
, const char *name
, int size
, tree list
)
5850 VEC(constructor_elt
,gc
) *inits
= NULL
;
5852 decl
= start_var_decl (type
, synth_id_with_class_suffix
5853 (name
, objc_implementation_context
));
5855 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
5856 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, list
);
5858 finish_var_decl (decl
,
5859 objc_build_constructor (TREE_TYPE (decl
), inits
));
5864 /* Count only the fields occurring in T. */
5867 ivar_list_length (tree t
)
5871 for (; t
; t
= DECL_CHAIN (t
))
5872 if (TREE_CODE (t
) == FIELD_DECL
)
5879 generate_ivar_lists (void)
5881 tree initlist
, ivar_list_template
, chain
;
5884 generating_instance_variables
= 1;
5886 if (!objc_ivar_template
)
5887 objc_ivar_template
= build_ivar_template ();
5889 /* Only generate class variables for the root of the inheritance
5890 hierarchy since these will be the same for every class. */
5892 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
5893 && (chain
= TYPE_FIELDS (objc_class_template
)))
5895 size
= ivar_list_length (chain
);
5897 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
5898 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
5900 UOBJC_CLASS_VARIABLES_decl
5901 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
5905 UOBJC_CLASS_VARIABLES_decl
= 0;
5907 chain
= CLASS_IVARS (implementation_template
);
5910 size
= ivar_list_length (chain
);
5911 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
5912 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
5914 UOBJC_INSTANCE_VARIABLES_decl
5915 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
5919 UOBJC_INSTANCE_VARIABLES_decl
= 0;
5921 generating_instance_variables
= 0;
5925 build_dispatch_table_initializer (tree type
, tree entries
)
5927 VEC(constructor_elt
,gc
) *inits
= NULL
;
5931 VEC(constructor_elt
,gc
) *elems
= NULL
;
5934 CONSTRUCTOR_APPEND_ELT (elems
, NULL_TREE
,
5935 build_selector (METHOD_SEL_NAME (entries
)));
5937 /* Generate the method encoding if we don't have one already. */
5938 if (! METHOD_ENCODING (entries
))
5939 METHOD_ENCODING (entries
) =
5940 encode_method_prototype (entries
);
5942 CONSTRUCTOR_APPEND_ELT (elems
, NULL_TREE
,
5943 add_objc_string (METHOD_ENCODING (entries
),
5946 expr
= convert (ptr_type_node
,
5947 build_unary_op (input_location
, ADDR_EXPR
,
5948 METHOD_DEFINITION (entries
), 1));
5949 CONSTRUCTOR_APPEND_ELT (elems
, NULL_TREE
, expr
);
5951 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
,
5952 objc_build_constructor (type
, elems
));
5954 entries
= DECL_CHAIN (entries
);
5958 return objc_build_constructor (build_array_type (type
, 0), inits
);
5961 /* To accomplish method prototyping without generating all kinds of
5962 inane warnings, the definition of the dispatch table entries were
5965 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5967 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5970 build_method_template (void)
5973 tree decls
, *chain
= NULL
;
5975 _SLT_record
= objc_start_struct (get_identifier (UTAG_METHOD
));
5978 decls
= add_field_decl (objc_selector_type
, "_cmd", &chain
);
5980 /* char *method_types; */
5981 add_field_decl (string_type_node
, "method_types", &chain
);
5984 add_field_decl (build_pointer_type (void_type_node
), "_imp", &chain
);
5986 objc_finish_struct (_SLT_record
, decls
);
5993 generate_dispatch_table (tree type
, const char *name
, int size
, tree list
)
5996 VEC(constructor_elt
,gc
) *v
= NULL
;
5998 decl
= start_var_decl (type
, synth_id_with_class_suffix
5999 (name
, objc_implementation_context
));
6001 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
6002 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (integer_type_node
, size
));
6003 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, list
);
6005 finish_var_decl (decl
,
6006 objc_build_constructor (TREE_TYPE (decl
), v
));
6012 mark_referenced_methods (void)
6014 struct imp_entry
*impent
;
6017 for (impent
= imp_list
; impent
; impent
= impent
->next
)
6019 chain
= CLASS_CLS_METHODS (impent
->imp_context
);
6022 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
6023 chain
= DECL_CHAIN (chain
);
6026 chain
= CLASS_NST_METHODS (impent
->imp_context
);
6029 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
6030 chain
= DECL_CHAIN (chain
);
6036 generate_dispatch_tables (void)
6038 tree initlist
, chain
, method_list_template
;
6041 if (!objc_method_template
)
6042 objc_method_template
= build_method_template ();
6044 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
6047 size
= list_length (chain
);
6049 method_list_template
6050 = build_method_list_template (objc_method_template
, size
);
6052 = build_dispatch_table_initializer (objc_method_template
, chain
);
6054 UOBJC_CLASS_METHODS_decl
6055 = generate_dispatch_table (method_list_template
,
6056 ((TREE_CODE (objc_implementation_context
)
6057 == CLASS_IMPLEMENTATION_TYPE
)
6058 ? "_OBJC_CLASS_METHODS"
6059 : "_OBJC_CATEGORY_CLASS_METHODS"),
6063 UOBJC_CLASS_METHODS_decl
= 0;
6065 chain
= CLASS_NST_METHODS (objc_implementation_context
);
6068 size
= list_length (chain
);
6070 method_list_template
6071 = build_method_list_template (objc_method_template
, size
);
6073 = build_dispatch_table_initializer (objc_method_template
, chain
);
6075 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
6076 UOBJC_INSTANCE_METHODS_decl
6077 = generate_dispatch_table (method_list_template
,
6078 "_OBJC_INSTANCE_METHODS",
6081 /* We have a category. */
6082 UOBJC_INSTANCE_METHODS_decl
6083 = generate_dispatch_table (method_list_template
,
6084 "_OBJC_CATEGORY_INSTANCE_METHODS",
6088 UOBJC_INSTANCE_METHODS_decl
= 0;
6092 generate_protocol_list (tree i_or_p
)
6094 tree array_type
, ptype
, refs_decl
, lproto
, e
, plist
;
6096 const char *ref_name
;
6097 VEC(constructor_elt
,gc
) *v
= NULL
;
6099 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
6100 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
6101 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
6102 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
6103 plist
= PROTOCOL_LIST (i_or_p
);
6108 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
6109 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
6110 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
6113 /* Build initializer. */
6114 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6115 e
= build_int_cst (build_pointer_type (objc_protocol_template
), size
);
6116 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
6118 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
6120 tree pval
= TREE_VALUE (lproto
);
6122 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
6123 && PROTOCOL_FORWARD_DECL (pval
))
6125 e
= build_unary_op (input_location
, ADDR_EXPR
,
6126 PROTOCOL_FORWARD_DECL (pval
), 0);
6127 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
6131 /* static struct objc_protocol *refs[n]; */
6133 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
6134 ref_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p
);
6135 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
6136 ref_name
= synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p
);
6137 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
6138 ref_name
= synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p
);
6142 ptype
= build_pointer_type (objc_protocol_template
);
6143 array_type
= build_sized_array_type (ptype
, size
+ 3);
6144 refs_decl
= start_var_decl (array_type
, ref_name
);
6146 finish_var_decl (refs_decl
,
6147 objc_build_constructor (TREE_TYPE (refs_decl
), v
));
6153 build_category_initializer (tree type
, tree cat_name
, tree class_name
,
6154 tree instance_methods
, tree class_methods
,
6158 VEC(constructor_elt
,gc
) *v
= NULL
;
6160 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, cat_name
);
6161 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, class_name
);
6163 if (!instance_methods
)
6164 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6167 expr
= convert (objc_method_list_ptr
,
6168 build_unary_op (input_location
, ADDR_EXPR
,
6169 instance_methods
, 0));
6170 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6173 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6176 expr
= convert (objc_method_list_ptr
,
6177 build_unary_op (input_location
, ADDR_EXPR
,
6179 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6182 /* protocol_list = */
6184 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6187 expr
= convert (build_pointer_type
6189 (objc_protocol_template
)),
6190 build_unary_op (input_location
, ADDR_EXPR
,
6192 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6195 return objc_build_constructor (type
, v
);
6198 /* struct _objc_class {
6199 struct objc_class *isa;
6200 struct objc_class *super_class;
6205 struct objc_ivar_list *ivars;
6206 struct objc_method_list *methods;
6207 if (flag_next_runtime)
6208 struct objc_cache *cache;
6210 struct sarray *dtable;
6211 struct objc_class *subclass_list;
6212 struct objc_class *sibling_class;
6214 struct objc_protocol_list *protocols;
6215 if (flag_next_runtime)
6217 void *gc_object_type;
6221 build_shared_structure_initializer (tree type
, tree isa
, tree super
,
6222 tree name
, tree size
, int status
,
6223 tree dispatch_table
, tree ivar_list
,
6227 VEC(constructor_elt
,gc
) *v
= NULL
;
6230 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, isa
);
6233 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, super
);
6236 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, default_conversion (name
));
6239 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
6240 build_int_cst (long_integer_type_node
, 0));
6243 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
6244 build_int_cst (long_integer_type_node
, status
));
6246 /* instance_size = */
6247 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
6248 convert (long_integer_type_node
, size
));
6250 /* objc_ivar_list = */
6252 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6255 expr
= convert (objc_ivar_list_ptr
,
6256 build_unary_op (input_location
, ADDR_EXPR
,
6258 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6261 /* objc_method_list = */
6262 if (!dispatch_table
)
6263 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6266 expr
= convert (objc_method_list_ptr
,
6267 build_unary_op (input_location
, ADDR_EXPR
,
6268 dispatch_table
, 0));
6269 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6272 if (flag_next_runtime
)
6273 /* method_cache = */
6274 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6278 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6280 /* subclass_list = */
6281 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6283 /* sibling_class = */
6284 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6287 /* protocol_list = */
6288 if (! protocol_list
)
6289 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6292 expr
= convert (build_pointer_type
6294 (objc_protocol_template
)),
6295 build_unary_op (input_location
, ADDR_EXPR
,
6297 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6300 if (flag_next_runtime
)
6302 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6304 /* gc_object_type = NULL */
6305 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6307 return objc_build_constructor (type
, v
);
6310 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
6313 lookup_category (tree klass
, tree cat_name
)
6315 tree category
= CLASS_CATEGORY_LIST (klass
);
6317 while (category
&& CLASS_SUPER_NAME (category
) != cat_name
)
6318 category
= CLASS_CATEGORY_LIST (category
);
6322 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
6325 generate_category (struct imp_entry
*impent
)
6327 tree initlist
, cat_name_expr
, class_name_expr
;
6328 tree protocol_decl
, category
;
6329 tree cat
= impent
->imp_context
;
6331 implementation_template
= impent
->imp_template
;
6332 UOBJC_CLASS_decl
= impent
->class_decl
;
6333 UOBJC_METACLASS_decl
= impent
->meta_decl
;
6335 add_class_reference (CLASS_NAME (cat
));
6336 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
6338 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
6340 category
= lookup_category (implementation_template
,
6341 CLASS_SUPER_NAME (cat
));
6343 if (category
&& CLASS_PROTOCOL_LIST (category
))
6345 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
6346 protocol_decl
= generate_protocol_list (category
);
6351 initlist
= build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl
),
6352 cat_name_expr
, class_name_expr
,
6353 UOBJC_INSTANCE_METHODS_decl
,
6354 UOBJC_CLASS_METHODS_decl
,
6356 /* Finish and initialize the forward decl. */
6357 finish_var_decl (UOBJC_CLASS_decl
, initlist
);
6360 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
6361 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6364 generate_shared_structures (struct imp_entry
*impent
)
6366 tree name_expr
, super_expr
, root_expr
;
6367 tree my_root_id
, my_super_id
;
6368 tree cast_type
, initlist
, protocol_decl
;
6371 objc_implementation_context
= impent
->imp_context
;
6372 implementation_template
= impent
->imp_template
;
6373 UOBJC_CLASS_decl
= impent
->class_decl
;
6374 UOBJC_METACLASS_decl
= impent
->meta_decl
;
6375 cls_flags
= impent
->has_cxx_cdtors
? CLS_HAS_CXX_STRUCTORS
: 0 ;
6377 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
6380 add_class_reference (my_super_id
);
6382 /* Compute "my_root_id" - this is required for code generation.
6383 the "isa" for all meta class structures points to the root of
6384 the inheritance hierarchy (e.g. "__Object")... */
6385 my_root_id
= my_super_id
;
6388 tree my_root_int
= lookup_interface (my_root_id
);
6390 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
6391 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
6398 /* No super class. */
6399 my_root_id
= CLASS_NAME (implementation_template
);
6401 cast_type
= build_pointer_type (objc_class_template
);
6402 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
6405 /* Install class `isa' and `super' pointers at runtime. */
6407 super_expr
= add_objc_string (my_super_id
, class_names
);
6409 super_expr
= integer_zero_node
;
6411 super_expr
= build_c_cast (input_location
,
6412 cast_type
, super_expr
); /* cast! */
6414 root_expr
= add_objc_string (my_root_id
, class_names
);
6415 root_expr
= build_c_cast (input_location
, cast_type
, root_expr
); /* cast! */
6417 if (CLASS_PROTOCOL_LIST (implementation_template
))
6419 generate_protocol_references
6420 (CLASS_PROTOCOL_LIST (implementation_template
));
6421 protocol_decl
= generate_protocol_list (implementation_template
);
6426 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
6429 = build_shared_structure_initializer
6430 (TREE_TYPE (UOBJC_METACLASS_decl
),
6431 root_expr
, super_expr
, name_expr
,
6432 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
6434 UOBJC_CLASS_METHODS_decl
,
6435 UOBJC_CLASS_VARIABLES_decl
,
6438 finish_var_decl (UOBJC_METACLASS_decl
, initlist
);
6440 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6443 = build_shared_structure_initializer
6444 (TREE_TYPE (UOBJC_CLASS_decl
),
6445 build_unary_op (input_location
, ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
6446 super_expr
, name_expr
,
6447 convert (integer_type_node
,
6448 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
6449 (implementation_template
))),
6450 1 /*CLS_FACTORY*/ | cls_flags
,
6451 UOBJC_INSTANCE_METHODS_decl
,
6452 UOBJC_INSTANCE_VARIABLES_decl
,
6455 finish_var_decl (UOBJC_CLASS_decl
, initlist
);
6460 synth_id_with_class_suffix (const char *preamble
, tree ctxt
)
6462 static char string
[BUFSIZE
];
6464 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
6465 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
6467 sprintf (string
, "%s_%s", preamble
,
6468 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
6470 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
6471 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
6473 /* We have a category. */
6474 const char *const class_name
6475 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
6476 const char *const class_super_name
6477 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
6478 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
6480 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
6482 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
6483 sprintf (string
, "%s_%s", preamble
, protocol_name
);
6491 /* If type is empty or only type qualifiers are present, add default
6492 type of id (otherwise grokdeclarator will default to int). */
6495 adjust_type_for_id_default (tree type
)
6498 type
= make_node (TREE_LIST
);
6500 if (!TREE_VALUE (type
))
6501 TREE_VALUE (type
) = objc_object_type
;
6502 else if (TREE_CODE (TREE_VALUE (type
)) == RECORD_TYPE
6503 && TYPED_OBJECT (TREE_VALUE (type
)))
6504 error ("can not use an object as parameter to a method");
6511 selector ':' '(' typename ')' identifier
6514 Transform an Objective-C keyword argument into
6515 the C equivalent parameter declarator.
6517 In: key_name, an "identifier_node" (optional).
6518 arg_type, a "tree_list" (optional).
6519 arg_name, an "identifier_node".
6520 attributes, a optional tree containing param attributes.
6522 Note: It would be really nice to strongly type the preceding
6523 arguments in the function prototype; however, then I
6524 could not use the "accessor" macros defined in "tree.h".
6526 Out: an instance of "keyword_decl". */
6529 objc_build_keyword_decl (tree key_name
, tree arg_type
,
6530 tree arg_name
, tree attributes
)
6535 warning_at (input_location
, OPT_Wattributes
,
6536 "method parameter attributes are not available in this "
6537 "version of the compiler, (ignored)");
6539 /* If no type is specified, default to "id". */
6540 arg_type
= adjust_type_for_id_default (arg_type
);
6542 keyword_decl
= make_node (KEYWORD_DECL
);
6544 TREE_TYPE (keyword_decl
) = arg_type
;
6545 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
6546 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
6548 return keyword_decl
;
6551 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
6554 build_keyword_selector (tree selector
)
6557 tree key_chain
, key_name
;
6560 /* Scan the selector to see how much space we'll need. */
6561 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
6563 if (TREE_CODE (selector
) == KEYWORD_DECL
)
6564 key_name
= KEYWORD_KEY_NAME (key_chain
);
6565 else if (TREE_CODE (selector
) == TREE_LIST
)
6566 key_name
= TREE_PURPOSE (key_chain
);
6571 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
6573 /* Just a ':' arg. */
6577 buf
= (char *) alloca (len
+ 1);
6578 /* Start the buffer out as an empty string. */
6581 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
6583 if (TREE_CODE (selector
) == KEYWORD_DECL
)
6584 key_name
= KEYWORD_KEY_NAME (key_chain
);
6585 else if (TREE_CODE (selector
) == TREE_LIST
)
6587 key_name
= TREE_PURPOSE (key_chain
);
6588 /* The keyword decl chain will later be used as a function argument
6589 chain. Unhook the selector itself so as to not confuse other
6590 parts of the compiler. */
6591 TREE_PURPOSE (key_chain
) = NULL_TREE
;
6597 strcat (buf
, IDENTIFIER_POINTER (key_name
));
6601 return get_identifier (buf
);
6604 /* Used for declarations and definitions. */
6607 build_method_decl (enum tree_code code
, tree ret_type
, tree selector
,
6608 tree add_args
, bool ellipsis
)
6612 /* If no type is specified, default to "id". */
6613 ret_type
= adjust_type_for_id_default (ret_type
);
6615 method_decl
= make_node (code
);
6616 TREE_TYPE (method_decl
) = ret_type
;
6618 /* If we have a keyword selector, create an identifier_node that
6619 represents the full selector name (`:' included)... */
6620 if (TREE_CODE (selector
) == KEYWORD_DECL
)
6622 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
6623 METHOD_SEL_ARGS (method_decl
) = selector
;
6624 METHOD_ADD_ARGS (method_decl
) = add_args
;
6625 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl
) = ellipsis
;
6629 METHOD_SEL_NAME (method_decl
) = selector
;
6630 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
6631 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
6637 #define METHOD_DEF 0
6638 #define METHOD_REF 1
6640 /* This routine processes objective-c method attributes. */
6643 objc_decl_method_attributes (tree
*node
, tree attributes
, int flags
)
6645 tree sentinel_attr
= lookup_attribute ("sentinel", attributes
);
6648 /* hackery to make an obj method look like a function type. */
6649 tree rettype
= TREE_TYPE (*node
);
6650 TREE_TYPE (*node
) = build_function_type (TREE_VALUE (rettype
),
6651 get_arg_type_list (*node
, METHOD_REF
, 0));
6652 decl_attributes (node
, attributes
, flags
);
6653 METHOD_TYPE_ATTRIBUTES (*node
) = TYPE_ATTRIBUTES (TREE_TYPE (*node
));
6654 TREE_TYPE (*node
) = rettype
;
6657 decl_attributes (node
, attributes
, flags
);
6661 objc_method_decl (enum tree_code opcode
)
6663 return opcode
== INSTANCE_METHOD_DECL
|| opcode
== CLASS_METHOD_DECL
;
6666 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6667 an argument list for method METH. CONTEXT is either METHOD_DEF or
6668 METHOD_REF, saying whether we are trying to define a method or call
6669 one. SUPERFLAG says this is for a send to super; this makes a
6670 difference for the NeXT calling sequence in which the lookup and
6671 the method call are done together. If METH is null, user-defined
6672 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6675 get_arg_type_list (tree meth
, int context
, int superflag
)
6679 /* Receiver type. */
6680 if (flag_next_runtime
&& superflag
)
6681 arglist
= build_tree_list (NULL_TREE
, objc_super_type
);
6682 else if (context
== METHOD_DEF
&& TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
6683 arglist
= build_tree_list (NULL_TREE
, objc_instance_type
);
6685 arglist
= build_tree_list (NULL_TREE
, objc_object_type
);
6687 /* Selector type - will eventually change to `int'. */
6688 chainon (arglist
, build_tree_list (NULL_TREE
, objc_selector_type
));
6690 /* No actual method prototype given -- assume that remaining arguments
6695 /* Build a list of argument types. */
6696 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= DECL_CHAIN (akey
))
6698 tree arg_type
= TREE_VALUE (TREE_TYPE (akey
));
6700 /* Decay argument types for the underlying C function as appropriate. */
6701 arg_type
= objc_decay_parm_type (arg_type
);
6703 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
6706 if (METHOD_ADD_ARGS (meth
))
6708 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
6709 akey
; akey
= TREE_CHAIN (akey
))
6711 tree arg_type
= TREE_TYPE (TREE_VALUE (akey
));
6713 arg_type
= objc_decay_parm_type (arg_type
);
6715 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
6718 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth
))
6719 goto lack_of_ellipsis
;
6724 chainon (arglist
, OBJC_VOID_AT_END
);
6731 check_duplicates (hash hsh
, int methods
, int is_class
)
6733 tree meth
= NULL_TREE
;
6741 /* We have two or more methods with the same name but
6745 /* But just how different are those types? If
6746 -Wno-strict-selector-match is specified, we shall not
6747 complain if the differences are solely among types with
6748 identical size and alignment. */
6749 if (!warn_strict_selector_match
)
6751 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
6752 if (!comp_proto_with_proto (meth
, loop
->value
, 0))
6761 bool type
= TREE_CODE (meth
) == INSTANCE_METHOD_DECL
;
6763 warning_at (input_location
, 0,
6764 "multiple methods named %<%c%E%> found",
6765 (is_class
? '+' : '-'),
6766 METHOD_SEL_NAME (meth
));
6767 inform (DECL_SOURCE_LOCATION (meth
), "using %<%c%s%>",
6769 identifier_to_locale (gen_method_decl (meth
)));
6773 bool type
= TREE_CODE (meth
) == INSTANCE_METHOD_DECL
;
6775 warning_at (input_location
, 0,
6776 "multiple selectors named %<%c%E%> found",
6777 (is_class
? '+' : '-'),
6778 METHOD_SEL_NAME (meth
));
6779 inform (DECL_SOURCE_LOCATION (meth
), "found %<%c%s%>",
6781 identifier_to_locale (gen_method_decl (meth
)));
6784 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
6786 bool type
= TREE_CODE (loop
->value
) == INSTANCE_METHOD_DECL
;
6788 inform (DECL_SOURCE_LOCATION (loop
->value
), "also found %<%c%s%>",
6790 identifier_to_locale (gen_method_decl (loop
->value
)));
6797 /* If RECEIVER is a class reference, return the identifier node for
6798 the referenced class. RECEIVER is created by objc_get_class_reference,
6799 so we check the exact form created depending on which runtimes are
6803 receiver_is_class_object (tree receiver
, int self
, int super
)
6805 tree chain
, exp
, arg
;
6807 /* The receiver is 'self' or 'super' in the context of a class method. */
6808 if (objc_method_context
6809 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
6812 ? CLASS_SUPER_NAME (implementation_template
)
6813 : CLASS_NAME (implementation_template
));
6815 if (flag_next_runtime
)
6817 /* The receiver is a variable created by
6818 build_class_reference_decl. */
6819 if (TREE_CODE (receiver
) == VAR_DECL
&& IS_CLASS (TREE_TYPE (receiver
)))
6820 /* Look up the identifier. */
6821 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
6822 if (TREE_PURPOSE (chain
) == receiver
)
6823 return TREE_VALUE (chain
);
6826 /* The receiver is a function call that returns an id. Check if
6827 it is a call to objc_getClass, if so, pick up the class name. */
6828 if (TREE_CODE (receiver
) == CALL_EXPR
6829 && (exp
= CALL_EXPR_FN (receiver
))
6830 && TREE_CODE (exp
) == ADDR_EXPR
6831 && (exp
= TREE_OPERAND (exp
, 0))
6832 && TREE_CODE (exp
) == FUNCTION_DECL
6833 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6834 prototypes for objc_get_class(). Thankfully, they seem to share the
6835 same function type. */
6836 && TREE_TYPE (exp
) == TREE_TYPE (objc_get_class_decl
)
6837 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp
)), TAG_GETCLASS
)
6838 /* We have a call to objc_get_class/objc_getClass! */
6839 && (arg
= CALL_EXPR_ARG (receiver
, 0)))
6842 if (TREE_CODE (arg
) == ADDR_EXPR
6843 && (arg
= TREE_OPERAND (arg
, 0))
6844 && TREE_CODE (arg
) == STRING_CST
)
6845 /* Finally, we have the class name. */
6846 return get_identifier (TREE_STRING_POINTER (arg
));
6851 /* If we are currently building a message expr, this holds
6852 the identifier of the selector of the message. This is
6853 used when printing warnings about argument mismatches. */
6855 static tree current_objc_message_selector
= 0;
6858 objc_message_selector (void)
6860 return current_objc_message_selector
;
6863 /* Construct an expression for sending a message.
6864 MESS has the object to send to in TREE_PURPOSE
6865 and the argument list (including selector) in TREE_VALUE.
6867 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6868 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6871 objc_build_message_expr (tree mess
)
6873 tree receiver
= TREE_PURPOSE (mess
);
6876 tree args
= TREE_PURPOSE (TREE_VALUE (mess
));
6878 tree args
= TREE_VALUE (mess
);
6880 tree method_params
= NULL_TREE
;
6882 if (TREE_CODE (receiver
) == ERROR_MARK
|| TREE_CODE (args
) == ERROR_MARK
)
6883 return error_mark_node
;
6885 /* Obtain the full selector name. */
6886 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
6887 /* A unary selector. */
6889 else if (TREE_CODE (args
) == TREE_LIST
)
6890 sel_name
= build_keyword_selector (args
);
6894 /* Build the parameter list to give to the method. */
6895 if (TREE_CODE (args
) == TREE_LIST
)
6897 method_params
= chainon (args
, TREE_VALUE (TREE_VALUE (mess
)));
6900 tree chain
= args
, prev
= NULL_TREE
;
6902 /* We have a keyword selector--check for comma expressions. */
6905 tree element
= TREE_VALUE (chain
);
6907 /* We have a comma expression, must collapse... */
6908 if (TREE_CODE (element
) == TREE_LIST
)
6911 TREE_CHAIN (prev
) = element
;
6916 chain
= TREE_CHAIN (chain
);
6918 method_params
= args
;
6923 if (processing_template_decl
)
6924 /* Must wait until template instantiation time. */
6925 return build_min_nt (MESSAGE_SEND_EXPR
, receiver
, sel_name
,
6929 return objc_finish_message_expr (receiver
, sel_name
, method_params
);
6932 /* Look up method SEL_NAME that would be suitable for receiver
6933 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6934 nonzero), and report on any duplicates. */
6937 lookup_method_in_hash_lists (tree sel_name
, int is_class
)
6939 hash method_prototype
= NULL
;
6942 method_prototype
= hash_lookup (nst_method_hash_list
,
6945 if (!method_prototype
)
6947 method_prototype
= hash_lookup (cls_method_hash_list
,
6952 return check_duplicates (method_prototype
, 1, is_class
);
6955 /* The 'objc_finish_message_expr' routine is called from within
6956 'objc_build_message_expr' for non-template functions. In the case of
6957 C++ template functions, it is called from 'build_expr_from_tree'
6958 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6961 objc_finish_message_expr (tree receiver
, tree sel_name
, tree method_params
)
6963 tree method_prototype
= NULL_TREE
, rprotos
= NULL_TREE
, rtype
;
6964 tree selector
, retval
, class_tree
;
6965 int self
, super
, have_cast
;
6967 /* We have used the receiver, so mark it as read. */
6968 mark_exp_read (receiver
);
6970 /* Extract the receiver of the message, as well as its type
6971 (where the latter may take the form of a cast or be inferred
6972 from the implementation context). */
6974 while (TREE_CODE (rtype
) == COMPOUND_EXPR
6975 || TREE_CODE (rtype
) == MODIFY_EXPR
6976 || CONVERT_EXPR_P (rtype
)
6977 || TREE_CODE (rtype
) == COMPONENT_REF
)
6978 rtype
= TREE_OPERAND (rtype
, 0);
6980 self
= (rtype
== self_decl
);
6981 super
= (rtype
== UOBJC_SUPER_decl
);
6982 rtype
= TREE_TYPE (receiver
);
6984 have_cast
= (TREE_CODE (receiver
) == NOP_EXPR
6985 || (TREE_CODE (receiver
) == COMPOUND_EXPR
6986 && !IS_SUPER (rtype
)));
6988 /* If we are calling [super dealloc], reset our warning flag. */
6989 if (super
&& !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name
)))
6990 should_call_super_dealloc
= 0;
6992 /* If the receiver is a class object, retrieve the corresponding
6993 @interface, if one exists. */
6994 class_tree
= receiver_is_class_object (receiver
, self
, super
);
6996 /* Now determine the receiver type (if an explicit cast has not been
7001 rtype
= lookup_interface (class_tree
);
7002 /* Handle `self' and `super'. */
7005 if (!CLASS_SUPER_NAME (implementation_template
))
7007 error ("no super class declared in @interface for %qE",
7008 CLASS_NAME (implementation_template
));
7009 return error_mark_node
;
7011 rtype
= lookup_interface (CLASS_SUPER_NAME (implementation_template
));
7014 rtype
= lookup_interface (CLASS_NAME (implementation_template
));
7017 /* If receiver is of type `id' or `Class' (or if the @interface for a
7018 class is not visible), we shall be satisfied with the existence of
7019 any instance or class method. */
7020 if (objc_is_id (rtype
))
7022 class_tree
= (IS_CLASS (rtype
) ? objc_class_name
: NULL_TREE
);
7023 rprotos
= (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype
))
7024 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype
))
7030 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
7031 in protocols themselves for the method prototype. */
7033 = lookup_method_in_protocol_list (rprotos
, sel_name
,
7034 class_tree
!= NULL_TREE
);
7036 /* If messaging 'Class <Proto>' but did not find a class method
7037 prototype, search for an instance method instead, and warn
7038 about having done so. */
7039 if (!method_prototype
&& !rtype
&& class_tree
!= NULL_TREE
)
7042 = lookup_method_in_protocol_list (rprotos
, sel_name
, 0);
7044 if (method_prototype
)
7045 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
7046 sel_name
, sel_name
);
7052 tree orig_rtype
= rtype
;
7054 if (TREE_CODE (rtype
) == POINTER_TYPE
)
7055 rtype
= TREE_TYPE (rtype
);
7056 /* Traverse typedef aliases */
7057 while (TREE_CODE (rtype
) == RECORD_TYPE
&& OBJC_TYPE_NAME (rtype
)
7058 && TREE_CODE (OBJC_TYPE_NAME (rtype
)) == TYPE_DECL
7059 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
)))
7060 rtype
= DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
));
7061 if (TYPED_OBJECT (rtype
))
7063 rprotos
= TYPE_OBJC_PROTOCOL_LIST (rtype
);
7064 rtype
= TYPE_OBJC_INTERFACE (rtype
);
7066 /* If we could not find an @interface declaration, we must have
7067 only seen a @class declaration; so, we cannot say anything
7068 more intelligent about which methods the receiver will
7070 if (!rtype
|| TREE_CODE (rtype
) == IDENTIFIER_NODE
)
7073 /* We could not find an @interface declaration, yet Message maybe in a
7074 @class's protocol. */
7075 if (!method_prototype
&& rprotos
)
7077 = lookup_method_in_protocol_list (rprotos
, sel_name
, 0);
7079 else if (TREE_CODE (rtype
) == CLASS_INTERFACE_TYPE
7080 || TREE_CODE (rtype
) == CLASS_IMPLEMENTATION_TYPE
)
7082 /* We have a valid ObjC class name. Look up the method name
7083 in the published @interface for the class (and its
7086 = lookup_method_static (rtype
, sel_name
, class_tree
!= NULL_TREE
);
7088 /* If the method was not found in the @interface, it may still
7089 exist locally as part of the @implementation. */
7090 if (!method_prototype
&& objc_implementation_context
7091 && CLASS_NAME (objc_implementation_context
)
7092 == OBJC_TYPE_NAME (rtype
))
7096 ? CLASS_CLS_METHODS (objc_implementation_context
)
7097 : CLASS_NST_METHODS (objc_implementation_context
)),
7100 /* If we haven't found a candidate method by now, try looking for
7101 it in the protocol list. */
7102 if (!method_prototype
&& rprotos
)
7104 = lookup_method_in_protocol_list (rprotos
, sel_name
,
7105 class_tree
!= NULL_TREE
);
7109 warning (0, "invalid receiver type %qs",
7110 identifier_to_locale (gen_type_name (orig_rtype
)));
7111 /* After issuing the "invalid receiver" warning, perform method
7112 lookup as if we were messaging 'id'. */
7113 rtype
= rprotos
= NULL_TREE
;
7118 /* For 'id' or 'Class' receivers, search in the global hash table
7119 as a last resort. For all receivers, warn if protocol searches
7121 if (!method_prototype
)
7124 warning (0, "%<%c%E%> not found in protocol(s)",
7125 (class_tree
? '+' : '-'),
7130 = lookup_method_in_hash_lists (sel_name
, class_tree
!= NULL_TREE
);
7133 if (!method_prototype
&& in_objc_property_setter_name_context
)
7134 error ("readonly property can not be set");
7135 else if (!method_prototype
)
7137 static bool warn_missing_methods
= false;
7140 warning (0, "%qE may not respond to %<%c%E%>",
7141 OBJC_TYPE_NAME (rtype
),
7142 (class_tree
? '+' : '-'),
7144 /* If we are messaging an 'id' or 'Class' object and made it here,
7145 then we have failed to find _any_ instance or class method,
7148 warning (0, "no %<%c%E%> method found",
7149 (class_tree
? '+' : '-'),
7152 if (!warn_missing_methods
)
7154 warning_at (input_location
,
7155 0, "(Messages without a matching method signature");
7156 warning_at (input_location
,
7157 0, "will be assumed to return %<id%> and accept");
7158 warning_at (input_location
,
7159 0, "%<...%> as arguments.)");
7160 warn_missing_methods
= true;
7164 /* Save the selector name for printing error messages. */
7165 current_objc_message_selector
= sel_name
;
7167 /* Build the parameters list for looking up the method.
7168 These are the object itself and the selector. */
7170 if (flag_typed_selectors
)
7171 selector
= build_typed_selector_reference (input_location
,
7172 sel_name
, method_prototype
);
7174 selector
= build_selector_reference (input_location
, sel_name
);
7176 retval
= build_objc_method_call (input_location
, super
, method_prototype
,
7178 selector
, method_params
);
7180 current_objc_message_selector
= 0;
7185 /* Build a tree expression to send OBJECT the operation SELECTOR,
7186 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
7187 assuming the method has prototype METHOD_PROTOTYPE.
7188 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
7189 LOC is the location of the expression to build.
7190 Use METHOD_PARAMS as list of args to pass to the method.
7191 If SUPER_FLAG is nonzero, we look up the superclass's method. */
7194 build_objc_method_call (location_t loc
, int super_flag
, tree method_prototype
,
7195 tree lookup_object
, tree selector
,
7198 tree sender
= (super_flag
? umsg_super_decl
:
7199 (!flag_next_runtime
|| flag_nil_receivers
7200 ? (flag_objc_direct_dispatch
7203 : umsg_nonnil_decl
));
7204 tree rcv_p
= (super_flag
? objc_super_type
: objc_object_type
);
7205 VEC(tree
, gc
) *parms
= NULL
;
7206 unsigned nparm
= (method_params
? list_length (method_params
) : 0);
7208 /* If a prototype for the method to be called exists, then cast
7209 the sender's return type and arguments to match that of the method.
7210 Otherwise, leave sender as is. */
7213 ? TREE_VALUE (TREE_TYPE (method_prototype
))
7214 : objc_object_type
);
7216 tree method_param_types
=
7217 get_arg_type_list (method_prototype
, METHOD_REF
, super_flag
);
7218 tree ftype
= build_function_type (ret_type
, method_param_types
);
7222 if (method_prototype
&& METHOD_TYPE_ATTRIBUTES (method_prototype
))
7223 ftype
= build_type_attribute_variant (
7224 ftype
, METHOD_TYPE_ATTRIBUTES (method_prototype
));
7226 sender_cast
= build_pointer_type (ftype
);
7228 if (method_prototype
&& TREE_DEPRECATED (method_prototype
))
7229 objc_warn_deprecated_use (method_prototype
, NULL_TREE
);
7231 lookup_object
= build_c_cast (loc
, rcv_p
, lookup_object
);
7233 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
7234 lookup_object
= save_expr (lookup_object
);
7236 /* Param list + 2 slots for object and selector. */
7237 parms
= VEC_alloc (tree
, gc
, nparm
+ 2);
7239 if (flag_next_runtime
)
7241 /* If we are returning a struct in memory, and the address
7242 of that memory location is passed as a hidden first
7243 argument, then change which messenger entry point this
7244 expr will call. NB: Note that sender_cast remains
7245 unchanged (it already has a struct return type). */
7246 if (!targetm
.calls
.struct_value_rtx (0, 0)
7247 && (TREE_CODE (ret_type
) == RECORD_TYPE
7248 || TREE_CODE (ret_type
) == UNION_TYPE
)
7249 && targetm
.calls
.return_in_memory (ret_type
, 0))
7250 sender
= (super_flag
? umsg_super_stret_decl
:
7251 flag_nil_receivers
? umsg_stret_decl
: umsg_nonnil_stret_decl
);
7253 method
= build_fold_addr_expr_loc (input_location
, sender
);
7254 /* Pass the object to the method. */
7255 VEC_quick_push (tree
, parms
, lookup_object
);
7259 /* This is the portable (GNU) way. */
7260 /* First, call the lookup function to get a pointer to the method,
7261 then cast the pointer, then call it with the method arguments. */
7262 VEC(tree
, gc
) *tv
= VEC_alloc (tree
, gc
, 2);
7263 VEC_quick_push (tree
, tv
, lookup_object
);
7264 VEC_quick_push (tree
, tv
, selector
);
7265 method
= build_function_call_vec (loc
, sender
, tv
, NULL
);
7266 VEC_free (tree
, gc
, tv
);
7268 /* Pass the appropriate object to the method. */
7269 VEC_quick_push (tree
, parms
, (super_flag
? self_decl
: lookup_object
));
7272 /* Pass the selector to the method. */
7273 VEC_quick_push (tree
, parms
, selector
);
7274 /* Now append the remainder of the parms. */
7276 for (; method_params
; method_params
= TREE_CHAIN (method_params
))
7277 VEC_quick_push (tree
, parms
, TREE_VALUE (method_params
));
7279 /* Build an obj_type_ref, with the correct cast for the method call. */
7280 t
= build3 (OBJ_TYPE_REF
, sender_cast
, method
,
7281 lookup_object
, size_zero_node
);
7282 t
= build_function_call_vec (loc
, t
, parms
, NULL
);\
7283 VEC_free (tree
, gc
, parms
);
7288 build_protocol_reference (tree p
)
7291 const char *proto_name
;
7293 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
7295 proto_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
7296 decl
= start_var_decl (objc_protocol_template
, proto_name
);
7298 PROTOCOL_FORWARD_DECL (p
) = decl
;
7301 /* This function is called by the parser when (and only when) a
7302 @protocol() expression is found, in order to compile it. */
7304 objc_build_protocol_expr (tree protoname
)
7307 tree p
= lookup_protocol (protoname
);
7311 error ("cannot find protocol declaration for %qE",
7313 return error_mark_node
;
7316 if (!PROTOCOL_FORWARD_DECL (p
))
7317 build_protocol_reference (p
);
7319 expr
= build_unary_op (input_location
,
7320 ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
7322 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
7323 if we have it, rather than converting it here. */
7324 expr
= convert (objc_protocol_type
, expr
);
7326 /* The @protocol() expression is being compiled into a pointer to a
7327 statically allocated instance of the Protocol class. To become
7328 usable at runtime, the 'isa' pointer of the instance need to be
7329 fixed up at runtime by the runtime library, to point to the
7330 actual 'Protocol' class. */
7332 /* For the GNU runtime, put the static Protocol instance in the list
7333 of statically allocated instances, so that we make sure that its
7334 'isa' pointer is fixed up at runtime by the GNU runtime library
7335 to point to the Protocol class (at runtime, when loading the
7336 module, the GNU runtime library loops on the statically allocated
7337 instances (as found in the defs field in objc_symtab) and fixups
7338 all the 'isa' pointers of those objects). */
7339 if (! flag_next_runtime
)
7341 /* This type is a struct containing the fields of a Protocol
7342 object. (Cfr. objc_protocol_type instead is the type of a pointer
7343 to such a struct). */
7344 tree protocol_struct_type
= xref_tag
7345 (RECORD_TYPE
, get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
7348 /* Look for the list of Protocol statically allocated instances
7349 to fixup at runtime. Create a new list to hold Protocol
7350 statically allocated instances, if the list is not found. At
7351 present there is only another list, holding NSConstantString
7352 static instances to be fixed up at runtime. */
7353 for (chain
= &objc_static_instances
;
7354 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
7355 chain
= &TREE_CHAIN (*chain
));
7358 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
7359 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type
),
7363 /* Add this statically allocated instance to the Protocol list. */
7364 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
7365 PROTOCOL_FORWARD_DECL (p
),
7366 TREE_PURPOSE (*chain
));
7373 /* This function is called by the parser when a @selector() expression
7374 is found, in order to compile it. It is only called by the parser
7375 and only to compile a @selector(). LOC is the location of the
7378 objc_build_selector_expr (location_t loc
, tree selnamelist
)
7382 /* Obtain the full selector name. */
7383 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
7384 /* A unary selector. */
7385 selname
= selnamelist
;
7386 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
7387 selname
= build_keyword_selector (selnamelist
);
7391 /* If we are required to check @selector() expressions as they
7392 are found, check that the selector has been declared. */
7393 if (warn_undeclared_selector
)
7395 /* Look the selector up in the list of all known class and
7396 instance methods (up to this line) to check that the selector
7400 /* First try with instance methods. */
7401 hsh
= hash_lookup (nst_method_hash_list
, selname
);
7403 /* If not found, try with class methods. */
7406 hsh
= hash_lookup (cls_method_hash_list
, selname
);
7409 /* If still not found, print out a warning. */
7412 warning (0, "undeclared selector %qE", selname
);
7417 if (flag_typed_selectors
)
7418 return build_typed_selector_reference (loc
, selname
, 0);
7420 return build_selector_reference (loc
, selname
);
7423 /* This is used to implement @encode(). See gcc/doc/objc.texi,
7424 section '@encode'. */
7426 objc_build_encode_expr (tree type
)
7431 encode_type (type
, obstack_object_size (&util_obstack
),
7432 OBJC_ENCODE_INLINE_DEFS
);
7433 obstack_1grow (&util_obstack
, 0); /* null terminate string */
7434 string
= XOBFINISH (&util_obstack
, const char *);
7436 /* Synthesize a string that represents the encoded struct/union. */
7437 result
= my_build_string (strlen (string
) + 1, string
);
7438 obstack_free (&util_obstack
, util_firstobj
);
7443 build_ivar_reference (tree id
)
7445 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7447 /* Historically, a class method that produced objects (factory
7448 method) would assign `self' to the instance that it
7449 allocated. This would effectively turn the class method into
7450 an instance method. Following this assignment, the instance
7451 variables could be accessed. That practice, while safe,
7452 violates the simple rule that a class method should not refer
7453 to an instance variable. It's better to catch the cases
7454 where this is done unknowingly than to support the above
7456 warning (0, "instance variable %qE accessed in class method",
7458 self_decl
= convert (objc_instance_type
, self_decl
); /* cast */
7461 return objc_build_component_ref (build_indirect_ref (input_location
,
7462 self_decl
, RO_ARROW
),
7466 /* Compute a hash value for a given method SEL_NAME. */
7469 hash_func (tree sel_name
)
7471 const unsigned char *s
7472 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
7476 h
= h
* 67 + *s
++ - 113;
7483 nst_method_hash_list
= ggc_alloc_cleared_vec_hash (SIZEHASHTABLE
);
7484 cls_method_hash_list
= ggc_alloc_cleared_vec_hash (SIZEHASHTABLE
);
7486 /* Initialize the hash table used to hold the constant string objects. */
7487 string_htab
= htab_create_ggc (31, string_hash
,
7491 /* WARNING!!!! hash_enter is called with a method, and will peek
7492 inside to find its selector! But hash_lookup is given a selector
7493 directly, and looks for the selector that's inside the found
7494 entry's key (method) for comparison. */
7497 hash_enter (hash
*hashlist
, tree method
)
7500 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
7502 obj
= ggc_alloc_hashed_entry ();
7504 obj
->next
= hashlist
[slot
];
7507 hashlist
[slot
] = obj
; /* append to front */
7511 hash_lookup (hash
*hashlist
, tree sel_name
)
7515 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
7519 if (sel_name
== METHOD_SEL_NAME (target
->key
))
7522 target
= target
->next
;
7528 hash_add_attr (hash entry
, tree value
)
7532 obj
= ggc_alloc_hashed_attribute ();
7533 obj
->next
= entry
->list
;
7536 entry
->list
= obj
; /* append to front */
7540 lookup_method (tree mchain
, tree method
)
7544 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
7547 key
= METHOD_SEL_NAME (method
);
7551 if (METHOD_SEL_NAME (mchain
) == key
)
7554 mchain
= DECL_CHAIN (mchain
);
7559 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
7560 in INTERFACE, along with any categories and protocols attached thereto.
7561 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
7562 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
7563 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
7564 be found in INTERFACE or any of its superclasses, look for an _instance_
7565 method of the same name in the root class as a last resort.
7567 If a suitable method cannot be found, return NULL_TREE. */
7570 lookup_method_static (tree interface
, tree ident
, int flags
)
7572 tree meth
= NULL_TREE
, root_inter
= NULL_TREE
;
7573 tree inter
= interface
;
7574 int is_class
= (flags
& OBJC_LOOKUP_CLASS
);
7575 int no_superclasses
= (flags
& OBJC_LOOKUP_NO_SUPER
);
7579 tree chain
= is_class
? CLASS_CLS_METHODS (inter
) : CLASS_NST_METHODS (inter
);
7580 tree category
= inter
;
7582 /* First, look up the method in the class itself. */
7583 if ((meth
= lookup_method (chain
, ident
)))
7586 /* Failing that, look for the method in each category of the class. */
7587 while ((category
= CLASS_CATEGORY_LIST (category
)))
7589 chain
= is_class
? CLASS_CLS_METHODS (category
) : CLASS_NST_METHODS (category
);
7591 /* Check directly in each category. */
7592 if ((meth
= lookup_method (chain
, ident
)))
7595 /* Failing that, check in each category's protocols. */
7596 if (CLASS_PROTOCOL_LIST (category
))
7598 if ((meth
= (lookup_method_in_protocol_list
7599 (CLASS_PROTOCOL_LIST (category
), ident
, is_class
))))
7604 /* If not found in categories, check in protocols of the main class. */
7605 if (CLASS_PROTOCOL_LIST (inter
))
7607 if ((meth
= (lookup_method_in_protocol_list
7608 (CLASS_PROTOCOL_LIST (inter
), ident
, is_class
))))
7612 /* If we were instructed not to look in superclasses, don't. */
7613 if (no_superclasses
)
7616 /* Failing that, climb up the inheritance hierarchy. */
7618 inter
= lookup_interface (CLASS_SUPER_NAME (inter
));
7622 /* If no class (factory) method was found, check if an _instance_
7623 method of the same name exists in the root class. This is what
7624 the Objective-C runtime will do. If an instance method was not
7626 return is_class
? lookup_method_static (root_inter
, ident
, 0): NULL_TREE
;
7629 /* Add the method to the hash list if it doesn't contain an identical
7633 add_method_to_hash_list (hash
*hash_list
, tree method
)
7637 if (!(hsh
= hash_lookup (hash_list
, METHOD_SEL_NAME (method
))))
7639 /* Install on a global chain. */
7640 hash_enter (hash_list
, method
);
7644 /* Check types against those; if different, add to a list. */
7646 int already_there
= comp_proto_with_proto (method
, hsh
->key
, 1);
7647 for (loop
= hsh
->list
; !already_there
&& loop
; loop
= loop
->next
)
7648 already_there
|= comp_proto_with_proto (method
, loop
->value
, 1);
7650 hash_add_attr (hsh
, method
);
7655 objc_add_method (tree klass
, tree method
, int is_class
, bool is_optional
)
7659 /* @optional methods are added to protocol's OPTIONAL list */
7662 gcc_assert (TREE_CODE (klass
) == PROTOCOL_INTERFACE_TYPE
);
7663 if (!(mth
= lookup_method (is_class
7664 ? PROTOCOL_OPTIONAL_CLS_METHODS (klass
)
7665 : PROTOCOL_OPTIONAL_NST_METHODS (klass
),
7670 TREE_CHAIN (method
) = PROTOCOL_OPTIONAL_CLS_METHODS (klass
);
7671 PROTOCOL_OPTIONAL_CLS_METHODS (klass
) = method
;
7675 TREE_CHAIN (method
) = PROTOCOL_OPTIONAL_NST_METHODS (klass
);
7676 PROTOCOL_OPTIONAL_NST_METHODS (klass
) = method
;
7680 else if (!(mth
= lookup_method (is_class
7681 ? CLASS_CLS_METHODS (klass
)
7682 : CLASS_NST_METHODS (klass
), method
)))
7684 /* put method on list in reverse order */
7687 DECL_CHAIN (method
) = CLASS_CLS_METHODS (klass
);
7688 CLASS_CLS_METHODS (klass
) = method
;
7692 DECL_CHAIN (method
) = CLASS_NST_METHODS (klass
);
7693 CLASS_NST_METHODS (klass
) = method
;
7698 /* When processing an @interface for a class or category, give hard
7699 errors on methods with identical selectors but differing argument
7700 and/or return types. We do not do this for @implementations, because
7701 C/C++ will do it for us (i.e., there will be duplicate function
7702 definition errors). */
7703 if ((TREE_CODE (klass
) == CLASS_INTERFACE_TYPE
7704 || TREE_CODE (klass
) == CATEGORY_INTERFACE_TYPE
)
7705 && !comp_proto_with_proto (method
, mth
, 1))
7706 error ("duplicate declaration of method %<%c%E%>",
7707 is_class
? '+' : '-',
7708 METHOD_SEL_NAME (mth
));
7712 add_method_to_hash_list (cls_method_hash_list
, method
);
7715 add_method_to_hash_list (nst_method_hash_list
, method
);
7717 /* Instance methods in root classes (and categories thereof)
7718 may act as class methods as a last resort. We also add
7719 instance methods listed in @protocol declarations to
7720 the class hash table, on the assumption that @protocols
7721 may be adopted by root classes or categories. */
7722 if (TREE_CODE (klass
) == CATEGORY_INTERFACE_TYPE
7723 || TREE_CODE (klass
) == CATEGORY_IMPLEMENTATION_TYPE
)
7724 klass
= lookup_interface (CLASS_NAME (klass
));
7726 if (TREE_CODE (klass
) == PROTOCOL_INTERFACE_TYPE
7727 || !CLASS_SUPER_NAME (klass
))
7728 add_method_to_hash_list (cls_method_hash_list
, method
);
7735 add_class (tree class_name
, tree name
)
7737 struct interface_tuple
**slot
;
7739 /* Put interfaces on list in reverse order. */
7740 TREE_CHAIN (class_name
) = interface_chain
;
7741 interface_chain
= class_name
;
7743 if (interface_htab
== NULL
)
7744 interface_htab
= htab_create_ggc (31, hash_interface
, eq_interface
, NULL
);
7745 slot
= (struct interface_tuple
**)
7746 htab_find_slot_with_hash (interface_htab
, name
,
7747 IDENTIFIER_HASH_VALUE (name
),
7751 *slot
= ggc_alloc_cleared_interface_tuple ();
7754 (*slot
)->class_name
= class_name
;
7756 return interface_chain
;
7760 add_category (tree klass
, tree category
)
7762 /* Put categories on list in reverse order. */
7763 tree cat
= lookup_category (klass
, CLASS_SUPER_NAME (category
));
7767 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
7769 CLASS_SUPER_NAME (category
));
7773 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (klass
);
7774 CLASS_CATEGORY_LIST (klass
) = category
;
7778 /* Called after parsing each instance variable declaration. Necessary to
7779 preserve typedefs and implement public/private...
7781 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7784 add_instance_variable (tree klass
, objc_ivar_visibility_kind visibility
,
7787 tree field_type
= TREE_TYPE (field_decl
);
7788 const char *ivar_name
= DECL_NAME (field_decl
)
7789 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl
)))
7793 if (TREE_CODE (field_type
) == REFERENCE_TYPE
)
7795 error ("illegal reference type specified for instance variable %qs",
7797 /* Return class as is without adding this ivar. */
7802 if (field_type
== error_mark_node
|| !TYPE_SIZE (field_type
)
7803 || TYPE_SIZE (field_type
) == error_mark_node
)
7804 /* 'type[0]' is allowed, but 'type[]' is not! */
7806 error ("instance variable %qs has unknown size", ivar_name
);
7807 /* Return class as is without adding this ivar. */
7812 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7813 need to either (1) warn the user about it or (2) generate suitable
7814 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7815 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7816 if (MAYBE_CLASS_TYPE_P (field_type
)
7817 && (TYPE_NEEDS_CONSTRUCTING (field_type
)
7818 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
)
7819 || TYPE_POLYMORPHIC_P (field_type
)))
7821 tree type_name
= OBJC_TYPE_NAME (field_type
);
7823 if (flag_objc_call_cxx_cdtors
)
7825 /* Since the ObjC runtime will be calling the constructors and
7826 destructors for us, the only thing we can't handle is the lack
7827 of a default constructor. */
7828 if (TYPE_NEEDS_CONSTRUCTING (field_type
)
7829 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type
))
7831 warning (0, "type %qE has no default constructor to call",
7834 /* If we cannot call a constructor, we should also avoid
7835 calling the destructor, for symmetry. */
7836 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
7837 warning (0, "destructor for %qE shall not be run either",
7843 static bool warn_cxx_ivars
= false;
7845 if (TYPE_POLYMORPHIC_P (field_type
))
7847 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7849 error ("type %qE has virtual member functions", type_name
);
7850 error ("illegal aggregate type %qE specified "
7851 "for instance variable %qs",
7852 type_name
, ivar_name
);
7853 /* Return class as is without adding this ivar. */
7857 /* User-defined constructors and destructors are not known to Obj-C
7858 and hence will not be called. This may or may not be a problem. */
7859 if (TYPE_NEEDS_CONSTRUCTING (field_type
))
7860 warning (0, "type %qE has a user-defined constructor", type_name
);
7861 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
7862 warning (0, "type %qE has a user-defined destructor", type_name
);
7864 if (!warn_cxx_ivars
)
7866 warning (0, "C++ constructors and destructors will not "
7867 "be invoked for Objective-C fields");
7868 warn_cxx_ivars
= true;
7874 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7877 case OBJC_IVAR_VIS_PROTECTED
:
7878 TREE_PUBLIC (field_decl
) = 0;
7879 TREE_PRIVATE (field_decl
) = 0;
7880 TREE_PROTECTED (field_decl
) = 1;
7883 case OBJC_IVAR_VIS_PACKAGE
:
7884 /* TODO: Implement the package variant. */
7885 case OBJC_IVAR_VIS_PUBLIC
:
7886 TREE_PUBLIC (field_decl
) = 1;
7887 TREE_PRIVATE (field_decl
) = 0;
7888 TREE_PROTECTED (field_decl
) = 0;
7891 case OBJC_IVAR_VIS_PRIVATE
:
7892 TREE_PUBLIC (field_decl
) = 0;
7893 TREE_PRIVATE (field_decl
) = 1;
7894 TREE_PROTECTED (field_decl
) = 0;
7899 CLASS_RAW_IVARS (klass
) = chainon (CLASS_RAW_IVARS (klass
), field_decl
);
7905 is_ivar (tree decl_chain
, tree ident
)
7907 for ( ; decl_chain
; decl_chain
= DECL_CHAIN (decl_chain
))
7908 if (DECL_NAME (decl_chain
) == ident
)
7913 /* True if the ivar is private and we are not in its implementation. */
7916 is_private (tree decl
)
7918 return (TREE_PRIVATE (decl
)
7919 && ! is_ivar (CLASS_IVARS (implementation_template
),
7923 /* We have an instance variable reference;, check to see if it is public. */
7926 objc_is_public (tree expr
, tree identifier
)
7928 tree basetype
, decl
;
7931 if (processing_template_decl
)
7935 if (TREE_TYPE (expr
) == error_mark_node
)
7938 basetype
= TYPE_MAIN_VARIANT (TREE_TYPE (expr
));
7940 if (basetype
&& TREE_CODE (basetype
) == RECORD_TYPE
)
7942 if (TYPE_HAS_OBJC_INFO (basetype
) && TYPE_OBJC_INTERFACE (basetype
))
7944 tree klass
= lookup_interface (OBJC_TYPE_NAME (basetype
));
7948 error ("cannot find interface declaration for %qE",
7949 OBJC_TYPE_NAME (basetype
));
7953 if ((decl
= is_ivar (get_class_ivars (klass
, true), identifier
)))
7955 if (TREE_PUBLIC (decl
))
7958 /* Important difference between the Stepstone translator:
7959 all instance variables should be public within the context
7960 of the implementation. */
7961 if (objc_implementation_context
7962 && ((TREE_CODE (objc_implementation_context
)
7963 == CLASS_IMPLEMENTATION_TYPE
)
7964 || (TREE_CODE (objc_implementation_context
)
7965 == CATEGORY_IMPLEMENTATION_TYPE
)))
7967 tree curtype
= TYPE_MAIN_VARIANT
7968 (CLASS_STATIC_TEMPLATE
7969 (implementation_template
));
7971 if (basetype
== curtype
7972 || DERIVED_FROM_P (basetype
, curtype
))
7974 int priv
= is_private (decl
);
7977 error ("instance variable %qE is declared private",
7984 /* The 2.95.2 compiler sometimes allowed C functions to access
7985 non-@public ivars. We will let this slide for now... */
7986 if (!objc_method_context
)
7988 warning (0, "instance variable %qE is %s; "
7989 "this will be a hard error in the future",
7991 TREE_PRIVATE (decl
) ? "@private" : "@protected");
7995 error ("instance variable %qE is declared %s",
7997 TREE_PRIVATE (decl
) ? "private" : "protected");
8006 /* Make sure all entries in CHAIN are also in LIST. */
8009 check_methods (tree chain
, tree list
, int mtype
)
8015 if (!lookup_method (list
, chain
))
8019 if (TREE_CODE (objc_implementation_context
)
8020 == CLASS_IMPLEMENTATION_TYPE
)
8021 warning (0, "incomplete implementation of class %qE",
8022 CLASS_NAME (objc_implementation_context
));
8023 else if (TREE_CODE (objc_implementation_context
)
8024 == CATEGORY_IMPLEMENTATION_TYPE
)
8025 warning (0, "incomplete implementation of category %qE",
8026 CLASS_SUPER_NAME (objc_implementation_context
));
8030 warning (0, "method definition for %<%c%E%> not found",
8031 mtype
, METHOD_SEL_NAME (chain
));
8034 chain
= DECL_CHAIN (chain
);
8040 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
8043 conforms_to_protocol (tree klass
, tree protocol
)
8045 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
8047 tree p
= CLASS_PROTOCOL_LIST (klass
);
8048 while (p
&& TREE_VALUE (p
) != protocol
)
8053 tree super
= (CLASS_SUPER_NAME (klass
)
8054 ? lookup_interface (CLASS_SUPER_NAME (klass
))
8056 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
8065 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
8066 CONTEXT. This is one of two mechanisms to check protocol integrity. */
8069 check_methods_accessible (tree chain
, tree context
, int mtype
)
8073 tree base_context
= context
;
8077 context
= base_context
;
8081 list
= CLASS_CLS_METHODS (context
);
8083 list
= CLASS_NST_METHODS (context
);
8085 if (lookup_method (list
, chain
))
8088 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
8089 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
8090 context
= (CLASS_SUPER_NAME (context
)
8091 ? lookup_interface (CLASS_SUPER_NAME (context
))
8094 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
8095 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
8096 context
= (CLASS_NAME (context
)
8097 ? lookup_interface (CLASS_NAME (context
))
8103 if (context
== NULL_TREE
)
8107 if (TREE_CODE (objc_implementation_context
)
8108 == CLASS_IMPLEMENTATION_TYPE
)
8109 warning (0, "incomplete implementation of class %qE",
8110 CLASS_NAME (objc_implementation_context
));
8111 else if (TREE_CODE (objc_implementation_context
)
8112 == CATEGORY_IMPLEMENTATION_TYPE
)
8113 warning (0, "incomplete implementation of category %qE",
8114 CLASS_SUPER_NAME (objc_implementation_context
));
8117 warning (0, "method definition for %<%c%E%> not found",
8118 mtype
, METHOD_SEL_NAME (chain
));
8121 chain
= TREE_CHAIN (chain
); /* next method... */
8126 /* Check whether the current interface (accessible via
8127 'objc_implementation_context') actually implements protocol P, along
8128 with any protocols that P inherits. */
8131 check_protocol (tree p
, const char *type
, tree name
)
8133 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
8137 /* Ensure that all protocols have bodies! */
8140 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
8141 CLASS_CLS_METHODS (objc_implementation_context
),
8143 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
8144 CLASS_NST_METHODS (objc_implementation_context
),
8149 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
8150 objc_implementation_context
,
8152 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
8153 objc_implementation_context
,
8158 warning (0, "%s %qE does not fully implement the %qE protocol",
8159 type
, name
, PROTOCOL_NAME (p
));
8162 /* Check protocols recursively. */
8163 if (PROTOCOL_LIST (p
))
8165 tree subs
= PROTOCOL_LIST (p
);
8167 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
8171 tree sub
= TREE_VALUE (subs
);
8173 /* If the superclass does not conform to the protocols
8174 inherited by P, then we must! */
8175 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
8176 check_protocol (sub
, type
, name
);
8177 subs
= TREE_CHAIN (subs
);
8182 /* Check whether the current interface (accessible via
8183 'objc_implementation_context') actually implements the protocols listed
8187 check_protocols (tree proto_list
, const char *type
, tree name
)
8189 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
8191 tree p
= TREE_VALUE (proto_list
);
8193 check_protocol (p
, type
, name
);
8197 /* Make sure that the class CLASS_NAME is defined
8198 CODE says which kind of thing CLASS_NAME ought to be.
8199 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
8200 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
8203 start_class (enum tree_code code
, tree class_name
, tree super_name
,
8209 if (current_namespace
!= global_namespace
) {
8210 error ("Objective-C declarations may only appear in global scope");
8212 #endif /* OBJCPLUS */
8214 if (objc_implementation_context
)
8216 warning (0, "%<@end%> missing in implementation context");
8217 finish_class (objc_implementation_context
);
8218 objc_ivar_chain
= NULL_TREE
;
8219 objc_implementation_context
= NULL_TREE
;
8222 klass
= make_node (code
);
8223 TYPE_LANG_SLOT_1 (klass
) = make_tree_vec (CLASS_LANG_SLOT_ELTS
);
8225 /* Check for existence of the super class, if one was specified. Note
8226 that we must have seen an @interface, not just a @class. If we
8227 are looking at a @compatibility_alias, traverse it first. */
8228 if ((code
== CLASS_INTERFACE_TYPE
|| code
== CLASS_IMPLEMENTATION_TYPE
)
8231 tree super
= objc_is_class_name (super_name
);
8233 if (!super
|| !lookup_interface (super
))
8235 error ("cannot find interface declaration for %qE, superclass of %qE",
8236 super
? super
: super_name
,
8238 super_name
= NULL_TREE
;
8244 CLASS_NAME (klass
) = class_name
;
8245 CLASS_SUPER_NAME (klass
) = super_name
;
8246 CLASS_CLS_METHODS (klass
) = NULL_TREE
;
8248 if (! objc_is_class_name (class_name
)
8249 && (decl
= lookup_name (class_name
)))
8251 error ("%qE redeclared as different kind of symbol",
8253 error ("previous declaration of %q+D",
8257 if (code
== CLASS_IMPLEMENTATION_TYPE
)
8262 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
8263 if (TREE_VALUE (chain
) == class_name
)
8265 error ("reimplementation of class %qE",
8267 return error_mark_node
;
8269 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
8270 implemented_classes
);
8273 /* Reset for multiple classes per file. */
8276 objc_implementation_context
= klass
;
8278 /* Lookup the interface for this implementation. */
8280 if (!(implementation_template
= lookup_interface (class_name
)))
8282 warning (0, "cannot find interface declaration for %qE",
8284 add_class (implementation_template
= objc_implementation_context
,
8288 /* If a super class has been specified in the implementation,
8289 insure it conforms to the one specified in the interface. */
8292 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
8294 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
8295 error ("conflicting super class name %qE",
8298 error ("previous declaration of %qE", previous_name
);
8300 error ("previous declaration");
8303 else if (! super_name
)
8305 CLASS_SUPER_NAME (objc_implementation_context
)
8306 = CLASS_SUPER_NAME (implementation_template
);
8310 else if (code
== CLASS_INTERFACE_TYPE
)
8312 if (lookup_interface (class_name
))
8314 error ("duplicate interface declaration for class %qE",
8316 warning (0, "duplicate interface declaration for class %qE",
8320 add_class (klass
, class_name
);
8323 CLASS_PROTOCOL_LIST (klass
)
8324 = lookup_and_install_protocols (protocol_list
);
8327 else if (code
== CATEGORY_INTERFACE_TYPE
)
8329 tree class_category_is_assoc_with
;
8331 /* For a category, class_name is really the name of the class that
8332 the following set of methods will be associated with. We must
8333 find the interface so that can derive the objects template. */
8335 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
8337 error ("cannot find interface declaration for %qE",
8339 exit (FATAL_EXIT_CODE
);
8342 add_category (class_category_is_assoc_with
, klass
);
8345 CLASS_PROTOCOL_LIST (klass
)
8346 = lookup_and_install_protocols (protocol_list
);
8349 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
8351 /* Reset for multiple classes per file. */
8354 objc_implementation_context
= klass
;
8356 /* For a category, class_name is really the name of the class that
8357 the following set of methods will be associated with. We must
8358 find the interface so that can derive the objects template. */
8360 if (!(implementation_template
= lookup_interface (class_name
)))
8362 error ("cannot find interface declaration for %qE",
8364 exit (FATAL_EXIT_CODE
);
8371 continue_class (tree klass
)
8373 if (TREE_CODE (klass
) == CLASS_IMPLEMENTATION_TYPE
8374 || TREE_CODE (klass
) == CATEGORY_IMPLEMENTATION_TYPE
)
8376 struct imp_entry
*imp_entry
;
8378 /* Check consistency of the instance variables. */
8380 if (CLASS_RAW_IVARS (klass
))
8381 check_ivars (implementation_template
, klass
);
8383 /* code generation */
8386 push_lang_context (lang_name_c
);
8389 build_private_template (implementation_template
);
8390 uprivate_record
= CLASS_STATIC_TEMPLATE (implementation_template
);
8391 objc_instance_type
= build_pointer_type (uprivate_record
);
8393 imp_entry
= ggc_alloc_imp_entry ();
8395 imp_entry
->next
= imp_list
;
8396 imp_entry
->imp_context
= klass
;
8397 imp_entry
->imp_template
= implementation_template
;
8399 synth_forward_declarations ();
8400 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
8401 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
8402 imp_entry
->has_cxx_cdtors
= 0;
8404 /* Append to front and increment count. */
8405 imp_list
= imp_entry
;
8406 if (TREE_CODE (klass
) == CLASS_IMPLEMENTATION_TYPE
)
8412 pop_lang_context ();
8413 #endif /* OBJCPLUS */
8415 return get_class_ivars (implementation_template
, true);
8418 else if (TREE_CODE (klass
) == CLASS_INTERFACE_TYPE
)
8421 push_lang_context (lang_name_c
);
8422 #endif /* OBJCPLUS */
8424 objc_collecting_ivars
= 1;
8425 build_private_template (klass
);
8426 objc_collecting_ivars
= 0;
8429 pop_lang_context ();
8430 #endif /* OBJCPLUS */
8436 return error_mark_node
;
8439 /* This routine builds a property ivar name. */
8442 objc_build_property_ivar_name (tree property_decl
)
8444 static char string
[BUFSIZE
];
8445 sprintf (string
, "_%s", IDENTIFIER_POINTER (PROPERTY_NAME (property_decl
)));
8449 /* This routine builds name of the setter synthesized function. */
8452 objc_build_property_setter_name (tree ident
, bool delimit_colon
)
8454 static char string
[BUFSIZE
];
8456 sprintf (string
, "set%s:", IDENTIFIER_POINTER (ident
));
8458 sprintf (string
, "set%s", IDENTIFIER_POINTER (ident
));
8459 string
[3] = TOUPPER (string
[3]);
8463 /* This routine does all the work for generating data and code per each
8464 property declared in current implementation. */
8467 objc_gen_one_property_datum (tree klass
, tree property
, tree class_methods
, bool *ivar_added
)
8471 /* If getter, check that it is already declared in user code. */
8472 if (PROPERTY_GETTER_NAME (property
))
8474 mth
= lookup_method (CLASS_NST_METHODS (class_methods
),
8475 PROPERTY_GETTER_NAME (property
));
8477 error ("property getter %qs not declared in class %qs",
8478 IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property
)),
8479 IDENTIFIER_POINTER (CLASS_NAME (class_methods
)));
8481 /* If setter, check that it is already declared in user code. */
8482 if (PROPERTY_SETTER_NAME (property
))
8484 mth
= lookup_method (CLASS_NST_METHODS (class_methods
),
8485 PROPERTY_SETTER_NAME (property
));
8487 error ("property setter %qs not declared in class %qs",
8488 IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property
)),
8489 IDENTIFIER_POINTER (CLASS_NAME (class_methods
)));
8491 /* If ivar attribute specified, check that it is already declared. */
8492 if (PROPERTY_IVAR_NAME (property
))
8494 if (!is_ivar (CLASS_IVARS (klass
),
8495 PROPERTY_IVAR_NAME (property
)))
8496 error ("ivar %qs in property declaration must be an existing ivar",
8497 IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property
)));
8499 else if (!PROPERTY_GETTER_NAME (property
)
8500 || (PROPERTY_READONLY (property
) == boolean_false_node
8501 && !PROPERTY_SETTER_NAME (property
)))
8503 /* Setter and/or getter must be synthesize and there was no user-specified
8504 ivar. Must create an ivar and add to to current class's ivar list. */
8505 tree record
= CLASS_STATIC_TEMPLATE (klass
);
8506 tree type
= TREE_TYPE (property
);
8507 tree field_decl
, field
;
8508 field_decl
= create_field_decl (type
,
8509 objc_build_property_ivar_name (property
));
8510 DECL_CONTEXT (field_decl
) = record
;
8511 (void) add_instance_variable (klass
,
8512 OBJC_IVAR_VIS_PUBLIC
, field_decl
);
8513 /* Unfortunately, CLASS_IVARS is completed when interface is completed.
8514 Must add the new ivar by hand to its list here. */
8516 CLASS_IVARS (klass
) =
8517 chainon (CLASS_IVARS (klass
),
8518 copy_node (field_decl
));
8519 gcc_assert (record
);
8520 /* Must also add this ivar to the end of list of fields for this class. */
8521 field
= TYPE_FIELDS (record
);
8522 if (field
&& field
!= CLASS_IVARS (klass
))
8523 /* class has a hidden field, attach ivar list after the hiddent field. */
8524 TREE_CHAIN (field
) = CLASS_IVARS (klass
);
8526 TYPE_FIELDS (record
) = CLASS_IVARS (klass
);
8531 /* This routine processes an existing getter or setter attribute.
8532 It aliases internal property getter or setter to the user implemented
8537 objc_process_getter_setter (tree klass
, tree property
, bool getter
)
8540 tree prop_getter_mth_decl
;
8544 /* getter name is same as property name. */
8545 name_ident
= PROPERTY_NAME (property
);
8547 /* Must synthesize setter name from property name. */
8548 name_ident
= get_identifier (objc_build_property_setter_name (
8549 PROPERTY_NAME (property
), true));
8551 /* Find declaration of instance method for the property in its class. */
8552 prop_mth_decl
= lookup_method (CLASS_NST_METHODS (klass
), name_ident
);
8557 prop_getter_mth_decl
= lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
8558 getter
? PROPERTY_GETTER_NAME (property
)
8559 : PROPERTY_SETTER_NAME (property
));
8561 if (!prop_getter_mth_decl
)
8564 if (!match_proto_with_proto (prop_getter_mth_decl
, prop_mth_decl
, 1))
8566 error ("User %s %qs does not match property %qs type",
8567 getter
? "getter" : "setter",
8568 IDENTIFIER_POINTER (DECL_NAME (prop_getter_mth_decl
)),
8569 IDENTIFIER_POINTER (PROPERTY_NAME (property
)));
8572 /* We alias internal property getter to the user implemented getter by copying relevant
8573 entries from user's implementation to the internal one. */
8574 prop_mth_decl
= copy_node (prop_mth_decl
);
8575 METHOD_ENCODING (prop_mth_decl
) = METHOD_ENCODING (prop_getter_mth_decl
);
8576 METHOD_DEFINITION (prop_mth_decl
) = METHOD_DEFINITION (prop_getter_mth_decl
);
8577 objc_add_method (objc_implementation_context
, prop_mth_decl
, 0, 0);
8580 /* This routine synthesizes a 'getter' method. */
8583 objc_synthesize_getter (tree klass
, tree class_method
, tree property
)
8590 /* If user has implemented a getter with same name then do nothing. */
8591 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
8592 PROPERTY_NAME (property
)))
8595 /* Find declaration of the property in the interface. There must be one. */
8596 decl
= lookup_method (CLASS_NST_METHODS (class_method
),
8597 PROPERTY_NAME (property
));
8599 /* If one not declared in the interface, this condition has already been reported
8600 as user error (because property was not declared in the interface). */
8604 objc_inherit_code
= INSTANCE_METHOD_DECL
;
8605 /* For now no attributes. */
8606 objc_start_method_definition (copy_node (decl
), NULL_TREE
);
8608 body
= c_begin_compound_stmt (true);
8609 /* return self->_property_name; */
8610 /* If user specified an ivar, use it in generation of the getter. */
8611 ivar_ident
= PROPERTY_IVAR_NAME (property
)
8612 ? PROPERTY_IVAR_NAME (property
)
8613 : get_identifier (objc_build_property_ivar_name (property
));
8615 /* objc_ivar_chain might not be up to date in the case that property 'ivar'
8616 is added *after* user ivar is parsed and objc_continue_implementation
8617 has already been called. */
8618 objc_ivar_chain
= CLASS_IVARS (klass
);
8619 ret_val
= objc_lookup_ivar (NULL_TREE
, ivar_ident
);
8620 /* If ivar attribute is not a user declared attribute, this condition has
8621 already been repored as error. */
8622 gcc_assert (ret_val
|| PROPERTY_IVAR_NAME (property
));
8627 finish_return_stmt (ret_val
);
8629 (void)c_finish_return (input_location
, ret_val
, NULL
);
8632 add_stmt (c_end_compound_stmt (input_location
, body
, true));
8633 fn
= current_function_decl
;
8637 objc_finish_method_definition (fn
);
8640 /* This routine synthesizes a 'setter' method. */
8643 objc_synthesize_setter (tree klass
, tree class_method
, tree property
)
8645 tree fn
, decl
, ivar_ident
, lhs
, rhs
;
8647 char *setter_name
= objc_build_property_setter_name (
8648 PROPERTY_NAME (property
), true);
8649 tree setter_ident
= get_identifier (setter_name
);
8651 /* If user has implemented a setter with same name then do nothing. */
8652 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
8656 /* Find declaration of the property in the interface. There must be one. */
8657 decl
= lookup_method (CLASS_NST_METHODS (class_method
), setter_ident
);
8659 /* If one not declared in the inerface, this condition has already been reported
8660 as user error (because property was not declared in the interface. */
8664 objc_inherit_code
= INSTANCE_METHOD_DECL
;
8665 /* For now, no attributes. */
8666 objc_start_method_definition (copy_node (decl
), NULL_TREE
);
8668 body
= c_begin_compound_stmt (true);
8669 /* _property_name = _value; */
8670 /* If user specified an ivar, use it in generation of the setter. */
8671 ivar_ident
= PROPERTY_IVAR_NAME (property
)
8672 ? PROPERTY_IVAR_NAME (property
)
8673 : get_identifier (objc_build_property_ivar_name (property
));
8675 /* objc_ivar_chain might not be up to date in the case that property 'ivar'
8676 is added *after* user ivar is parsed and objc_continue_implementation
8677 has already been called. */
8678 objc_ivar_chain
= CLASS_IVARS (klass
);
8679 lhs
= objc_lookup_ivar (NULL_TREE
, ivar_ident
);
8680 /* If ivar attribute is not a user declared attribute, this condition has
8681 already been repored as error. */
8682 gcc_assert (lhs
|| PROPERTY_IVAR_NAME (property
));
8685 rhs
= lookup_name (get_identifier ("_value"));
8687 /* FIXME: NULL types to get compile. */
8688 add_stmt (build_modify_expr (input_location
,
8689 lhs
, NULL_TREE
, NOP_EXPR
,
8690 input_location
, rhs
, NULL_TREE
));
8692 add_stmt (c_end_compound_stmt (input_location
, body
, true));
8693 fn
= current_function_decl
;
8697 objc_finish_method_definition (fn
);
8700 /* This function is called by the parser after a @synthesize
8701 expression is parsed. 'start_locus' is the location of the
8702 @synthesize expression, and 'property_and_ivar_list' is a chained
8703 list of the property and ivar names.
8706 objc_add_synthesize_declaration (location_t start_locus ATTRIBUTE_UNUSED
, tree property_and_ivar_list ATTRIBUTE_UNUSED
)
8708 if (property_and_ivar_list
== error_mark_node
)
8711 if (!objc_implementation_context
)
8713 /* We can get here only in Objective-C; the Objective-C++ parser
8714 detects the problem while parsing, outputs the error
8715 "misplaced '@synthesize' Objective-C++ construct" and skips
8717 error ("%<@synthesize%> not in @implementation context");
8722 error ("%<@synthesize%> is not supported in this version of the compiler");
8725 /* This function is called by the parser after a @dynamic expression
8726 is parsed. 'start_locus' is the location of the @dynamic
8727 expression, and 'property_list' is a chained list of all the
8730 objc_add_dynamic_declaration (location_t start_locus ATTRIBUTE_UNUSED
, tree property_list ATTRIBUTE_UNUSED
)
8732 if (property_list
== error_mark_node
)
8735 if (!objc_implementation_context
)
8737 /* We can get here only in Objective-C; the Objective-C++ parser
8738 detects the problem while parsing, outputs the error
8739 "misplaced '@dynamic' Objective-C++ construct" and skips the
8741 error ("%<@dynamic%> not in @implementation context");
8746 error ("%<@dynamic%> is not supported in this version of the compiler");
8749 /* Main routine to generate code/data for all the property information for
8750 current implementation (class or category). CLASS is the interface where
8751 ivars are declared. CLASS_METHODS is where methods are found which
8752 could be a class or a category depending on whether we are implementing
8753 property of a class or a category. */
8756 objc_gen_property_data (tree klass
, tree class_methods
)
8759 bool ivar_added
= false;
8760 for (x
= IMPL_PROPERTY_DECL (objc_implementation_context
); x
; x
= TREE_CHAIN (x
))
8761 objc_gen_one_property_datum (klass
, x
, class_methods
, &ivar_added
);
8765 tree record
= CLASS_STATIC_TEMPLATE (klass
);
8766 /* Ugh, must recalculate struct layout since at least one ivar was added. */
8767 TYPE_SIZE (record
) = 0;
8768 layout_type (record
);
8771 /* Synthesize all getters for properties. */
8772 for (x
= IMPL_PROPERTY_DECL (objc_implementation_context
); x
; x
= TREE_CHAIN (x
))
8774 /* Property has a getter attribute, no need to synthesize one. */
8775 if (PROPERTY_GETTER_NAME (x
) == NULL_TREE
)
8776 objc_synthesize_getter (klass
, class_methods
, x
);
8778 objc_process_getter_setter (class_methods
, x
, true);
8780 if (PROPERTY_READONLY (x
) == boolean_false_node
)
8782 /* not a readonly property. */
8783 if (PROPERTY_SETTER_NAME (x
) == NULL_TREE
)
8784 objc_synthesize_setter (klass
, class_methods
, x
);
8786 objc_process_getter_setter (class_methods
, x
, false);
8791 /* This is called once we see the "@end" in an interface/implementation. */
8794 finish_class (tree klass
)
8796 if (TREE_CODE (klass
) == CLASS_IMPLEMENTATION_TYPE
)
8798 /* All code generation is done in finish_objc. */
8800 /* Generate what needed for property; setters, getters, etc. */
8801 objc_gen_property_data (implementation_template
, implementation_template
);
8803 if (implementation_template
!= objc_implementation_context
)
8805 /* Ensure that all method listed in the interface contain bodies. */
8806 check_methods (CLASS_CLS_METHODS (implementation_template
),
8807 CLASS_CLS_METHODS (objc_implementation_context
), '+');
8808 check_methods (CLASS_NST_METHODS (implementation_template
),
8809 CLASS_NST_METHODS (objc_implementation_context
), '-');
8811 if (CLASS_PROTOCOL_LIST (implementation_template
))
8812 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
8814 CLASS_NAME (objc_implementation_context
));
8818 else if (TREE_CODE (klass
) == CATEGORY_IMPLEMENTATION_TYPE
)
8820 tree category
= lookup_category (implementation_template
, CLASS_SUPER_NAME (klass
));
8824 /* Generate what needed for property; setters, getters, etc. */
8825 objc_gen_property_data (implementation_template
, category
);
8827 /* Ensure all method listed in the interface contain bodies. */
8828 check_methods (CLASS_CLS_METHODS (category
),
8829 CLASS_CLS_METHODS (objc_implementation_context
), '+');
8830 check_methods (CLASS_NST_METHODS (category
),
8831 CLASS_NST_METHODS (objc_implementation_context
), '-');
8833 if (CLASS_PROTOCOL_LIST (category
))
8834 check_protocols (CLASS_PROTOCOL_LIST (category
),
8836 CLASS_SUPER_NAME (objc_implementation_context
));
8841 /* Process properties of the class. */
8843 for (x
= CLASS_PROPERTY_DECL (objc_interface_context
); x
; x
= TREE_CHAIN (x
))
8845 tree type
= TREE_TYPE (x
);
8846 tree prop_name
= PROPERTY_NAME (x
);
8847 /* Build an instance method declaration: - (type) prop_name; */
8848 if (PROPERTY_GETTER_NAME (x
) == NULL_TREE
)
8850 /* No getter attribute specified. Generate an instance method for the
8852 tree rettype
= build_tree_list (NULL_TREE
, type
);
8853 tree getter_decl
= build_method_decl (INSTANCE_METHOD_DECL
,
8856 objc_add_method (objc_interface_context
, getter_decl
, false, false);
8857 METHOD_PROPERTY_CONTEXT (getter_decl
) = x
;
8860 warning (0, "getter = %qs may not be specified in an interface",
8861 IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (x
)));
8863 /* Build an instance method declaration: - (void) setName: (type)value; */
8864 if (PROPERTY_SETTER_NAME (x
) == NULL_TREE
8865 && PROPERTY_READONLY (x
) == boolean_false_node
)
8867 /* Declare a setter instance method in the interface. */
8868 tree key_name
, arg_type
, arg_name
;
8869 tree setter_decl
, selector
;
8870 tree ret_type
= build_tree_list (NULL_TREE
, void_type_node
);
8872 key_name
= get_identifier (objc_build_property_setter_name (
8873 PROPERTY_NAME (x
), false));
8874 arg_type
= build_tree_list (NULL_TREE
, type
);
8875 arg_name
= get_identifier ("_value");
8876 /* For now, no attributes. */
8877 selector
= objc_build_keyword_decl (key_name
, arg_type
, arg_name
, NULL
);
8878 setter_decl
= build_method_decl (INSTANCE_METHOD_DECL
,
8880 build_tree_list (NULL_TREE
, NULL_TREE
),
8882 objc_add_method (objc_interface_context
, setter_decl
, false, false);
8883 METHOD_PROPERTY_CONTEXT (setter_decl
) = x
;
8885 else if (PROPERTY_SETTER_NAME (x
))
8886 warning (0, "setter = %qs may not be specified in an interface",
8887 IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x
)));
8888 if (PROPERTY_IVAR_NAME (x
))
8889 warning (0, "ivar = %qs attribute may not be specified in an interface",
8890 IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (x
)));
8896 add_protocol (tree protocol
)
8898 /* Put protocol on list in reverse order. */
8899 TREE_CHAIN (protocol
) = protocol_chain
;
8900 protocol_chain
= protocol
;
8901 return protocol_chain
;
8905 lookup_protocol (tree ident
)
8909 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
8910 if (ident
== PROTOCOL_NAME (chain
))
8916 /* This function forward declares the protocols named by NAMES. If
8917 they are already declared or defined, the function has no effect. */
8920 objc_declare_protocols (tree names
)
8925 if (current_namespace
!= global_namespace
) {
8926 error ("Objective-C declarations may only appear in global scope");
8928 #endif /* OBJCPLUS */
8930 for (list
= names
; list
; list
= TREE_CHAIN (list
))
8932 tree name
= TREE_VALUE (list
);
8934 if (lookup_protocol (name
) == NULL_TREE
)
8936 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
8938 TYPE_LANG_SLOT_1 (protocol
)
8939 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
8940 PROTOCOL_NAME (protocol
) = name
;
8941 PROTOCOL_LIST (protocol
) = NULL_TREE
;
8942 add_protocol (protocol
);
8943 PROTOCOL_DEFINED (protocol
) = 0;
8944 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
8950 start_protocol (enum tree_code code
, tree name
, tree list
)
8955 if (current_namespace
!= global_namespace
) {
8956 error ("Objective-C declarations may only appear in global scope");
8958 #endif /* OBJCPLUS */
8960 protocol
= lookup_protocol (name
);
8964 protocol
= make_node (code
);
8965 TYPE_LANG_SLOT_1 (protocol
) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
8967 PROTOCOL_NAME (protocol
) = name
;
8968 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
8969 add_protocol (protocol
);
8970 PROTOCOL_DEFINED (protocol
) = 1;
8971 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
8973 check_protocol_recursively (protocol
, list
);
8975 else if (! PROTOCOL_DEFINED (protocol
))
8977 PROTOCOL_DEFINED (protocol
) = 1;
8978 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
8980 check_protocol_recursively (protocol
, list
);
8984 warning (0, "duplicate declaration for protocol %qE",
8991 /* "Encode" a data type into a string, which grows in util_obstack.
8993 The format is described in gcc/doc/objc.texi, section 'Type
8996 Most of the encode_xxx functions have a 'type' argument, which is
8997 the type to encode, and an integer 'curtype' argument, which is the
8998 index in the encoding string of the beginning of the encoding of
8999 the current type, and allows you to find what characters have
9000 already been written for the current type (they are the ones in the
9001 current encoding string starting from 'curtype').
9003 For example, if we are encoding a method which returns 'int' and
9004 takes a 'char **' argument, then when we get to the point of
9005 encoding the 'char **' argument, the encoded string already
9006 contains 'i12@0:4' (assuming a pointer size of 4 bytes). So,
9007 'curtype' will be set to 7 when starting to encode 'char **'.
9008 During the whole of the encoding of 'char **', 'curtype' will be
9009 fixed at 7, so the routine encoding the second pointer can find out
9010 that it's actually encoding a pointer to a pointer by looking
9011 backwards at what has already been encoded for the current type,
9012 and seeing there is a "^" (meaning a pointer) in there.
9016 /* Encode type qualifiers encodes one of the "PQ" Objective-C
9017 keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
9018 'const', instead, is encoded directly as part of the type.
9022 encode_type_qualifiers (tree declspecs
)
9026 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
9028 /* FIXME: Shouldn't we use token->keyword here ? */
9029 if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
9030 obstack_1grow (&util_obstack
, 'n');
9031 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
9032 obstack_1grow (&util_obstack
, 'N');
9033 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
9034 obstack_1grow (&util_obstack
, 'o');
9035 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
9036 obstack_1grow (&util_obstack
, 'O');
9037 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
9038 obstack_1grow (&util_obstack
, 'R');
9039 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
9040 obstack_1grow (&util_obstack
, 'V');
9044 /* Determine if a pointee is marked read-only. Only used by the NeXT
9045 runtime to be compatible with gcc-3.3. */
9048 pointee_is_readonly (tree pointee
)
9050 while (POINTER_TYPE_P (pointee
))
9051 pointee
= TREE_TYPE (pointee
);
9053 return TYPE_READONLY (pointee
);
9056 /* Encode a pointer type. */
9059 encode_pointer (tree type
, int curtype
, int format
)
9061 tree pointer_to
= TREE_TYPE (type
);
9063 if (flag_next_runtime
)
9065 /* This code is used to be compatible with gcc-3.3. */
9066 /* For historical/compatibility reasons, the read-only qualifier
9067 of the pointee gets emitted _before_ the '^'. The read-only
9068 qualifier of the pointer itself gets ignored, _unless_ we are
9069 looking at a typedef! Also, do not emit the 'r' for anything
9070 but the outermost type! */
9071 if (!generating_instance_variables
9072 && (obstack_object_size (&util_obstack
) - curtype
<= 1)
9073 && (TYPE_NAME (type
) && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
9074 ? TYPE_READONLY (type
)
9075 : pointee_is_readonly (pointer_to
)))
9076 obstack_1grow (&util_obstack
, 'r');
9079 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
9081 if (OBJC_TYPE_NAME (pointer_to
)
9082 && TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
9084 const char *name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to
));
9086 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
9088 obstack_1grow (&util_obstack
, '@');
9091 else if (TYPE_HAS_OBJC_INFO (pointer_to
)
9092 && TYPE_OBJC_INTERFACE (pointer_to
))
9094 if (generating_instance_variables
)
9096 obstack_1grow (&util_obstack
, '@');
9097 obstack_1grow (&util_obstack
, '"');
9098 obstack_grow (&util_obstack
, name
, strlen (name
));
9099 obstack_1grow (&util_obstack
, '"');
9104 obstack_1grow (&util_obstack
, '@');
9108 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
9110 obstack_1grow (&util_obstack
, '#');
9113 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
9115 obstack_1grow (&util_obstack
, ':');
9120 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
9121 && TYPE_MODE (pointer_to
) == QImode
)
9123 tree pname
= TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
9124 ? OBJC_TYPE_NAME (pointer_to
)
9125 : DECL_NAME (OBJC_TYPE_NAME (pointer_to
));
9127 /* (BOOL *) are an exception and are encoded as ^c, while all
9128 other pointers to char are encoded as *. */
9129 if (strcmp (IDENTIFIER_POINTER (pname
), "BOOL"))
9131 if (!flag_next_runtime
)
9133 /* The NeXT runtime adds the 'r' before getting here. */
9135 /* It appears that "r*" means "const char *" rather than
9136 "char *const". "char *const" is encoded as "*",
9137 which is identical to "char *", so the "const" is
9138 unfortunately lost. */
9139 if (TYPE_READONLY (pointer_to
))
9140 obstack_1grow (&util_obstack
, 'r');
9143 obstack_1grow (&util_obstack
, '*');
9148 /* We have a normal pointer type that does not get special treatment. */
9149 obstack_1grow (&util_obstack
, '^');
9150 encode_type (pointer_to
, curtype
, format
);
9154 encode_array (tree type
, int curtype
, int format
)
9156 tree an_int_cst
= TYPE_SIZE (type
);
9157 tree array_of
= TREE_TYPE (type
);
9160 if (an_int_cst
== NULL
)
9162 /* We are trying to encode an incomplete array. An incomplete
9163 array is forbidden as part of an instance variable. */
9164 if (generating_instance_variables
)
9166 /* TODO: Detect this error earlier. */
9167 error ("instance variable has unknown size");
9171 /* So the only case in which an incomplete array could occur is
9172 if we are encoding the arguments or return value of a method.
9173 In that case, an incomplete array argument or return value
9174 (eg, -(void)display: (char[])string) is treated like a
9175 pointer because that is how the compiler does the function
9176 call. A special, more complicated case, is when the
9177 incomplete array is the last member of a struct (eg, if we
9178 are encoding "struct { unsigned long int a;double b[];}"),
9179 which is again part of a method argument/return value. In
9180 that case, we really need to communicate to the runtime that
9181 there is an incomplete array (not a pointer!) there. So, we
9182 detect that special case and encode it as a zero-length
9185 Try to detect that we are part of a struct. We do this by
9186 searching for '=' in the type encoding for the current type.
9187 NB: This hack assumes that you can't use '=' as part of a C
9191 char *enc
= obstack_base (&util_obstack
) + curtype
;
9192 if (memchr (enc
, '=',
9193 obstack_object_size (&util_obstack
) - curtype
) == NULL
)
9195 /* We are not inside a struct. Encode the array as a
9197 encode_pointer (type
, curtype
, format
);
9202 /* Else, we are in a struct, and we encode it as a zero-length
9204 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
)0);
9206 else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of
)) == 0)
9207 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
)0);
9209 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
,
9210 TREE_INT_CST_LOW (an_int_cst
)
9211 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
)));
9213 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
9214 encode_type (array_of
, curtype
, format
);
9215 obstack_1grow (&util_obstack
, ']');
9219 /* Encode a vector. The vector type is a GCC extension to C. */
9221 encode_vector (tree type
, int curtype
, int format
)
9223 tree vector_of
= TREE_TYPE (type
);
9226 /* Vectors are like simple fixed-size arrays. */
9228 /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
9229 alignment of the vector, and <code> is the base type. Eg, int
9230 __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
9231 assuming that the alignment is 32 bytes. We include size and
9232 alignment in bytes so that the runtime does not have to have any
9233 knowledge of the actual types.
9235 sprintf (buffer
, "![" HOST_WIDE_INT_PRINT_DEC
",%d",
9236 /* We want to compute the equivalent of sizeof (<vector>).
9237 Code inspired by c_sizeof_or_alignof_type. */
9238 ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type
))
9239 / (TYPE_PRECISION (char_type_node
) / BITS_PER_UNIT
))),
9240 /* We want to compute the equivalent of __alignof__
9241 (<vector>). Code inspired by
9242 c_sizeof_or_alignof_type. */
9243 TYPE_ALIGN_UNIT (type
));
9244 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
9245 encode_type (vector_of
, curtype
, format
);
9246 obstack_1grow (&util_obstack
, ']');
9251 encode_aggregate_fields (tree type
, bool pointed_to
, int curtype
, int format
)
9253 tree field
= TYPE_FIELDS (type
);
9255 for (; field
; field
= DECL_CHAIN (field
))
9258 /* C++ static members, and things that are not field at all,
9259 should not appear in the encoding. */
9260 if (TREE_CODE (field
) != FIELD_DECL
|| TREE_STATIC (field
))
9264 /* Recursively encode fields of embedded base classes. */
9265 if (DECL_ARTIFICIAL (field
) && !DECL_NAME (field
)
9266 && TREE_CODE (TREE_TYPE (field
)) == RECORD_TYPE
)
9268 encode_aggregate_fields (TREE_TYPE (field
),
9269 pointed_to
, curtype
, format
);
9273 if (generating_instance_variables
&& !pointed_to
)
9275 tree fname
= DECL_NAME (field
);
9277 obstack_1grow (&util_obstack
, '"');
9279 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
9280 obstack_grow (&util_obstack
,
9281 IDENTIFIER_POINTER (fname
),
9282 strlen (IDENTIFIER_POINTER (fname
)));
9284 obstack_1grow (&util_obstack
, '"');
9287 encode_field_decl (field
, curtype
, format
);
9292 encode_aggregate_within (tree type
, int curtype
, int format
, int left
,
9296 /* NB: aggregates that are pointed to have slightly different encoding
9297 rules in that you never encode the names of instance variables. */
9298 int ob_size
= obstack_object_size (&util_obstack
);
9299 bool inline_contents
= false;
9300 bool pointed_to
= false;
9302 if (flag_next_runtime
)
9304 if (ob_size
> 0 && *(obstack_next_free (&util_obstack
) - 1) == '^')
9307 if ((format
== OBJC_ENCODE_INLINE_DEFS
|| generating_instance_variables
)
9308 && (!pointed_to
|| ob_size
- curtype
== 1
9309 || (ob_size
- curtype
== 2
9310 && *(obstack_next_free (&util_obstack
) - 2) == 'r')))
9311 inline_contents
= true;
9315 /* c0 and c1 are the last two characters in the encoding of the
9316 current type; if the last two characters were '^' or '^r',
9317 then we are encoding an aggregate that is "pointed to". The
9318 comment above applies: in that case we should avoid encoding
9319 the names of instance variables.
9321 char c1
= ob_size
> 1 ? *(obstack_next_free (&util_obstack
) - 2) : 0;
9322 char c0
= ob_size
> 0 ? *(obstack_next_free (&util_obstack
) - 1) : 0;
9324 if (c0
== '^' || (c1
== '^' && c0
== 'r'))
9327 if (format
== OBJC_ENCODE_INLINE_DEFS
|| generating_instance_variables
)
9330 inline_contents
= true;
9333 /* Note that the check (ob_size - curtype < 2) prevents
9334 infinite recursion when encoding a structure which is
9335 a linked list (eg, struct node { struct node *next;
9336 }). Each time we follow a pointer, we add one
9337 character to ob_size, and curtype is fixed, so after
9338 at most two pointers we stop inlining contents and
9341 The other case where we don't inline is "^r", which
9342 is a pointer to a constant struct.
9344 if ((ob_size
- curtype
<= 2) && !(c0
== 'r'))
9345 inline_contents
= true;
9350 /* Traverse struct aliases; it is important to get the
9351 original struct and its tag name (if any). */
9352 type
= TYPE_MAIN_VARIANT (type
);
9353 name
= OBJC_TYPE_NAME (type
);
9354 /* Open parenth/bracket. */
9355 obstack_1grow (&util_obstack
, left
);
9357 /* Encode the struct/union tag name, or '?' if a tag was
9358 not provided. Typedef aliases do not qualify. */
9360 /* For compatibility with the NeXT runtime, ObjC++ encodes template
9361 args as a composite struct tag name. */
9362 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
9363 /* Did this struct have a tag? */
9364 && !TYPE_WAS_ANONYMOUS (type
))
9365 obstack_grow (&util_obstack
,
9366 decl_as_string (type
, TFF_DECL_SPECIFIERS
| TFF_UNQUALIFIED_NAME
),
9367 strlen (decl_as_string (type
, TFF_DECL_SPECIFIERS
| TFF_UNQUALIFIED_NAME
)));
9369 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
9370 obstack_grow (&util_obstack
,
9371 IDENTIFIER_POINTER (name
),
9372 strlen (IDENTIFIER_POINTER (name
)));
9375 obstack_1grow (&util_obstack
, '?');
9377 /* Encode the types (and possibly names) of the inner fields,
9379 if (inline_contents
)
9381 obstack_1grow (&util_obstack
, '=');
9382 encode_aggregate_fields (type
, pointed_to
, curtype
, format
);
9384 /* Close parenth/bracket. */
9385 obstack_1grow (&util_obstack
, right
);
9388 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
9392 encode_next_bitfield (int width
)
9395 sprintf (buffer
, "b%d", width
);
9396 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
9400 /* Encodes 'type', ignoring type qualifiers (which you should encode
9401 beforehand if needed) with the exception of 'const', which is
9402 encoded by encode_type. See above for the explanation of
9403 'curtype'. 'format' can be OBJC_ENCODE_INLINE_DEFS or
9404 OBJC_ENCODE_DONT_INLINE_DEFS.
9407 encode_type (tree type
, int curtype
, int format
)
9409 enum tree_code code
= TREE_CODE (type
);
9411 /* Ignore type qualifiers other than 'const' when encoding a
9414 if (type
== error_mark_node
)
9417 if (!flag_next_runtime
)
9419 if (TYPE_READONLY (type
))
9420 obstack_1grow (&util_obstack
, 'r');
9426 if (flag_next_runtime
)
9428 /* Kludge for backwards-compatibility with gcc-3.3: enums
9429 are always encoded as 'i' no matter what type they
9430 actually are (!). */
9431 obstack_1grow (&util_obstack
, 'i');
9434 /* Else, they are encoded exactly like the integer type that is
9435 used by the compiler to store them. */
9439 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
9441 case 8: c
= TYPE_UNSIGNED (type
) ? 'C' : 'c'; break;
9442 case 16: c
= TYPE_UNSIGNED (type
) ? 'S' : 's'; break;
9444 if (flag_next_runtime
)
9447 /* Another legacy kludge for compatiblity with
9448 gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
9449 but not always. For typedefs, we need to use 'i'
9450 or 'I' instead if encoding a struct field, or a
9452 int_type
= ((!generating_instance_variables
9453 && (obstack_object_size (&util_obstack
)
9454 == (unsigned) curtype
))
9455 ? TYPE_MAIN_VARIANT (type
)
9458 if (int_type
== long_unsigned_type_node
9459 || int_type
== long_integer_type_node
)
9460 c
= TYPE_UNSIGNED (type
) ? 'L' : 'l';
9462 c
= TYPE_UNSIGNED (type
) ? 'I' : 'i';
9466 if (type
== long_unsigned_type_node
9467 || type
== long_integer_type_node
)
9468 c
= TYPE_UNSIGNED (type
) ? 'L' : 'l';
9470 c
= TYPE_UNSIGNED (type
) ? 'I' : 'i';
9473 case 64: c
= TYPE_UNSIGNED (type
) ? 'Q' : 'q'; break;
9474 case 128: c
= TYPE_UNSIGNED (type
) ? 'T' : 't'; break;
9477 obstack_1grow (&util_obstack
, c
);
9483 /* Floating point types. */
9484 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
9486 case 32: c
= 'f'; break;
9487 case 64: c
= 'd'; break;
9489 case 128: c
= 'D'; break;
9492 obstack_1grow (&util_obstack
, c
);
9496 obstack_1grow (&util_obstack
, 'v');
9500 obstack_1grow (&util_obstack
, 'B');
9504 encode_array (type
, curtype
, format
);
9509 case REFERENCE_TYPE
:
9511 encode_pointer (type
, curtype
, format
);
9515 encode_aggregate_within (type
, curtype
, format
, '{', '}');
9519 encode_aggregate_within (type
, curtype
, format
, '(', ')');
9522 case FUNCTION_TYPE
: /* '?' means an unknown type. */
9523 obstack_1grow (&util_obstack
, '?');
9527 /* A complex is encoded as 'j' followed by the inner type (eg,
9528 "_Complex int" is encoded as 'ji'). */
9529 obstack_1grow (&util_obstack
, 'j');
9530 encode_type (TREE_TYPE (type
), curtype
, format
);
9534 encode_vector (type
, curtype
, format
);
9538 warning (0, "unknown type %s found during Objective-C encoding",
9539 gen_type_name (type
));
9540 obstack_1grow (&util_obstack
, '?');
9544 if (flag_next_runtime
)
9546 /* Super-kludge. Some ObjC qualifier and type combinations need
9547 to be rearranged for compatibility with gcc-3.3. */
9548 if (code
== POINTER_TYPE
&& obstack_object_size (&util_obstack
) >= 3)
9550 char *enc
= obstack_base (&util_obstack
) + curtype
;
9552 /* Rewrite "in const" from "nr" to "rn". */
9553 if (curtype
>= 1 && !strncmp (enc
- 1, "nr", 2))
9554 strncpy (enc
- 1, "rn", 2);
9560 encode_gnu_bitfield (int position
, tree type
, int size
)
9562 enum tree_code code
= TREE_CODE (type
);
9564 char charType
= '?';
9566 /* This code is only executed for the GNU runtime, so we can ignore
9567 the NeXT runtime kludge of always encoding enums as 'i' no matter
9568 what integers they actually are. */
9569 if (code
== INTEGER_TYPE
|| code
== ENUMERAL_TYPE
)
9571 if (integer_zerop (TYPE_MIN_VALUE (type
)))
9572 /* Unsigned integer types. */
9574 if (TYPE_MODE (type
) == QImode
)
9576 else if (TYPE_MODE (type
) == HImode
)
9578 else if (TYPE_MODE (type
) == SImode
)
9580 if (type
== long_unsigned_type_node
)
9585 else if (TYPE_MODE (type
) == DImode
)
9589 /* Signed integer types. */
9591 if (TYPE_MODE (type
) == QImode
)
9593 else if (TYPE_MODE (type
) == HImode
)
9595 else if (TYPE_MODE (type
) == SImode
)
9597 if (type
== long_integer_type_node
)
9603 else if (TYPE_MODE (type
) == DImode
)
9609 /* Do not do any encoding, produce an error and keep going. */
9610 error ("trying to encode non-integer type as a bitfield");
9614 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
9615 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
9619 encode_field_decl (tree field_decl
, int curtype
, int format
)
9622 /* C++ static members, and things that are not fields at all,
9623 should not appear in the encoding. */
9624 if (TREE_CODE (field_decl
) != FIELD_DECL
|| TREE_STATIC (field_decl
))
9628 /* Generate the bitfield typing information, if needed. Note the difference
9629 between GNU and NeXT runtimes. */
9630 if (DECL_BIT_FIELD_TYPE (field_decl
))
9632 int size
= tree_low_cst (DECL_SIZE (field_decl
), 1);
9634 if (flag_next_runtime
)
9635 encode_next_bitfield (size
);
9637 encode_gnu_bitfield (int_bit_position (field_decl
),
9638 DECL_BIT_FIELD_TYPE (field_decl
), size
);
9641 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
9644 /* Decay array and function parameters into pointers. */
9647 objc_decay_parm_type (tree type
)
9649 if (TREE_CODE (type
) == ARRAY_TYPE
|| TREE_CODE (type
) == FUNCTION_TYPE
)
9650 type
= build_pointer_type (TREE_CODE (type
) == ARRAY_TYPE
9657 static GTY(()) tree objc_parmlist
= NULL_TREE
;
9659 /* Append PARM to a list of formal parameters of a method, making a necessary
9660 array-to-pointer adjustment along the way. */
9663 objc_push_parm (tree parm
)
9667 if (TREE_TYPE (parm
) == error_mark_node
)
9669 objc_parmlist
= chainon (objc_parmlist
, parm
);
9673 /* Decay arrays and functions into pointers. */
9674 type
= objc_decay_parm_type (TREE_TYPE (parm
));
9676 /* If the parameter type has been decayed, a new PARM_DECL needs to be
9678 if (type
!= TREE_TYPE (parm
))
9679 parm
= build_decl (input_location
, PARM_DECL
, DECL_NAME (parm
), type
);
9681 DECL_ARG_TYPE (parm
)
9682 = lang_hooks
.types
.type_promotes_to (TREE_TYPE (parm
));
9684 /* Record constancy and volatility. */
9685 c_apply_type_quals_to_decl
9686 ((TYPE_READONLY (TREE_TYPE (parm
)) ? TYPE_QUAL_CONST
: 0)
9687 | (TYPE_RESTRICT (TREE_TYPE (parm
)) ? TYPE_QUAL_RESTRICT
: 0)
9688 | (TYPE_VOLATILE (TREE_TYPE (parm
)) ? TYPE_QUAL_VOLATILE
: 0), parm
);
9690 objc_parmlist
= chainon (objc_parmlist
, parm
);
9693 /* Retrieve the formal parameter list constructed via preceding calls to
9694 objc_push_parm(). */
9698 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED
)
9700 static struct c_arg_info
*
9701 objc_get_parm_info (int have_ellipsis
)
9705 tree parm_info
= objc_parmlist
;
9706 objc_parmlist
= NULL_TREE
;
9710 tree parm_info
= objc_parmlist
;
9711 struct c_arg_info
*arg_info
;
9712 /* The C front-end requires an elaborate song and dance at
9715 declare_parm_level ();
9718 tree next
= DECL_CHAIN (parm_info
);
9720 DECL_CHAIN (parm_info
) = NULL_TREE
;
9721 parm_info
= pushdecl (parm_info
);
9722 finish_decl (parm_info
, input_location
, NULL_TREE
, NULL_TREE
, NULL_TREE
);
9725 arg_info
= get_parm_info (have_ellipsis
);
9727 objc_parmlist
= NULL_TREE
;
9732 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
9733 method definitions. In the case of instance methods, we can be more
9734 specific as to the type of 'self'. */
9737 synth_self_and_ucmd_args (void)
9741 if (objc_method_context
9742 && TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
9743 self_type
= objc_instance_type
;
9745 /* Really a `struct objc_class *'. However, we allow people to
9746 assign to self, which changes its type midstream. */
9747 self_type
= objc_object_type
;
9750 objc_push_parm (build_decl (input_location
,
9751 PARM_DECL
, self_id
, self_type
));
9754 objc_push_parm (build_decl (input_location
,
9755 PARM_DECL
, ucmd_id
, objc_selector_type
));
9758 /* Transform an Objective-C method definition into a static C function
9759 definition, synthesizing the first two arguments, "self" and "_cmd",
9763 start_method_def (tree method
)
9769 struct c_arg_info
*parm_info
;
9771 int have_ellipsis
= 0;
9773 /* If we are defining a "dealloc" method in a non-root class, we
9774 will need to check if a [super dealloc] is missing, and warn if
9776 if(CLASS_SUPER_NAME (objc_implementation_context
)
9777 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method
))))
9778 should_call_super_dealloc
= 1;
9780 should_call_super_dealloc
= 0;
9782 /* Required to implement _msgSuper. */
9783 objc_method_context
= method
;
9784 UOBJC_SUPER_decl
= NULL_TREE
;
9786 /* Generate prototype declarations for arguments..."new-style". */
9787 synth_self_and_ucmd_args ();
9789 /* Generate argument declarations if a keyword_decl. */
9790 parmlist
= METHOD_SEL_ARGS (method
);
9793 tree type
= TREE_VALUE (TREE_TYPE (parmlist
)), parm
;
9795 parm
= build_decl (input_location
,
9796 PARM_DECL
, KEYWORD_ARG_NAME (parmlist
), type
);
9797 objc_push_parm (parm
);
9798 parmlist
= DECL_CHAIN (parmlist
);
9801 if (METHOD_ADD_ARGS (method
))
9805 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
9806 akey
; akey
= TREE_CHAIN (akey
))
9808 objc_push_parm (TREE_VALUE (akey
));
9811 if (METHOD_ADD_ARGS_ELLIPSIS_P (method
))
9815 parm_info
= objc_get_parm_info (have_ellipsis
);
9817 really_start_method (objc_method_context
, parm_info
);
9820 /* Return 1 if TYPE1 is equivalent to TYPE2
9821 for purposes of method overloading. */
9824 objc_types_are_equivalent (tree type1
, tree type2
)
9829 /* Strip away indirections. */
9830 while ((TREE_CODE (type1
) == ARRAY_TYPE
|| TREE_CODE (type1
) == POINTER_TYPE
)
9831 && (TREE_CODE (type1
) == TREE_CODE (type2
)))
9832 type1
= TREE_TYPE (type1
), type2
= TREE_TYPE (type2
);
9833 if (TYPE_MAIN_VARIANT (type1
) != TYPE_MAIN_VARIANT (type2
))
9836 type1
= (TYPE_HAS_OBJC_INFO (type1
)
9837 ? TYPE_OBJC_PROTOCOL_LIST (type1
)
9839 type2
= (TYPE_HAS_OBJC_INFO (type2
)
9840 ? TYPE_OBJC_PROTOCOL_LIST (type2
)
9843 if (list_length (type1
) == list_length (type2
))
9845 for (; type2
; type2
= TREE_CHAIN (type2
))
9846 if (!lookup_protocol_in_reflist (type1
, TREE_VALUE (type2
)))
9853 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
9856 objc_types_share_size_and_alignment (tree type1
, tree type2
)
9858 return (simple_cst_equal (TYPE_SIZE (type1
), TYPE_SIZE (type2
))
9859 && TYPE_ALIGN (type1
) == TYPE_ALIGN (type2
));
9862 /* Return 1 if PROTO1 is equivalent to PROTO2
9863 for purposes of method overloading. Ordinarily, the type signatures
9864 should match up exactly, unless STRICT is zero, in which case we
9865 shall allow differences in which the size and alignment of a type
9869 comp_proto_with_proto (tree proto1
, tree proto2
, int strict
)
9871 /* The following test is needed in case there are hashing
9873 if (METHOD_SEL_NAME (proto1
) != METHOD_SEL_NAME (proto2
))
9876 return match_proto_with_proto (proto1
, proto2
, strict
);
9880 match_proto_with_proto (tree proto1
, tree proto2
, int strict
)
9884 /* Compare return types. */
9885 type1
= TREE_VALUE (TREE_TYPE (proto1
));
9886 type2
= TREE_VALUE (TREE_TYPE (proto2
));
9888 if (!objc_types_are_equivalent (type1
, type2
)
9889 && (strict
|| !objc_types_share_size_and_alignment (type1
, type2
)))
9892 /* Compare argument types. */
9893 for (type1
= get_arg_type_list (proto1
, METHOD_REF
, 0),
9894 type2
= get_arg_type_list (proto2
, METHOD_REF
, 0);
9896 type1
= TREE_CHAIN (type1
), type2
= TREE_CHAIN (type2
))
9898 if (!objc_types_are_equivalent (TREE_VALUE (type1
), TREE_VALUE (type2
))
9900 || !objc_types_share_size_and_alignment (TREE_VALUE (type1
),
9901 TREE_VALUE (type2
))))
9905 return (!type1
&& !type2
);
9908 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
9909 this occurs. ObjC method dispatches are _not_ like C++ virtual
9910 member function dispatches, and we account for the difference here. */
9913 objc_fold_obj_type_ref (tree ref
, tree known_type
)
9915 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED
,
9916 tree known_type ATTRIBUTE_UNUSED
)
9920 tree v
= BINFO_VIRTUALS (TYPE_BINFO (known_type
));
9922 /* If the receiver does not have virtual member functions, there
9923 is nothing we can (or need to) do here. */
9927 /* Let C++ handle C++ virtual functions. */
9928 return cp_fold_obj_type_ref (ref
, known_type
);
9930 /* For plain ObjC, we currently do not need to do anything. */
9936 objc_start_function (tree name
, tree type
, tree attrs
,
9940 struct c_arg_info
*params
9944 tree fndecl
= build_decl (input_location
,
9945 FUNCTION_DECL
, name
, type
);
9948 DECL_ARGUMENTS (fndecl
) = params
;
9949 DECL_INITIAL (fndecl
) = error_mark_node
;
9950 DECL_EXTERNAL (fndecl
) = 0;
9951 TREE_STATIC (fndecl
) = 1;
9952 retrofit_lang_decl (fndecl
);
9953 cplus_decl_attributes (&fndecl
, attrs
, 0);
9954 start_preparsed_function (fndecl
, attrs
, /*flags=*/SF_DEFAULT
);
9956 current_function_returns_value
= 0; /* Assume, until we see it does. */
9957 current_function_returns_null
= 0;
9959 decl_attributes (&fndecl
, attrs
, 0);
9960 announce_function (fndecl
);
9961 DECL_INITIAL (fndecl
) = error_mark_node
;
9962 DECL_EXTERNAL (fndecl
) = 0;
9963 TREE_STATIC (fndecl
) = 1;
9964 current_function_decl
= pushdecl (fndecl
);
9966 declare_parm_level ();
9967 DECL_RESULT (current_function_decl
)
9968 = build_decl (input_location
,
9969 RESULT_DECL
, NULL_TREE
,
9970 TREE_TYPE (TREE_TYPE (current_function_decl
)));
9971 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl
)) = 1;
9972 DECL_IGNORED_P (DECL_RESULT (current_function_decl
)) = 1;
9973 start_fname_decls ();
9974 store_parm_decls_from (params
);
9977 TREE_USED (current_function_decl
) = 1;
9980 /* - Generate an identifier for the function. the format is "_n_cls",
9981 where 1 <= n <= nMethods, and cls is the name the implementation we
9983 - Install the return type from the method declaration.
9984 - If we have a prototype, check for type consistency. */
9987 really_start_method (tree method
,
9991 struct c_arg_info
*parmlist
9995 tree ret_type
, meth_type
;
9997 const char *sel_name
, *class_name
, *cat_name
;
10000 /* Synth the storage class & assemble the return type. */
10001 ret_type
= TREE_VALUE (TREE_TYPE (method
));
10003 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
10004 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
10005 cat_name
= ((TREE_CODE (objc_implementation_context
)
10006 == CLASS_IMPLEMENTATION_TYPE
)
10008 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
10011 /* Make sure this is big enough for any plausible method label. */
10012 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
10013 + (cat_name
? strlen (cat_name
) : 0));
10015 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
10016 class_name
, cat_name
, sel_name
, method_slot
);
10018 method_id
= get_identifier (buf
);
10021 /* Objective-C methods cannot be overloaded, so we don't need
10022 the type encoding appended. It looks bad anyway... */
10023 push_lang_context (lang_name_c
);
10027 = build_function_type (ret_type
,
10028 get_arg_type_list (method
, METHOD_DEF
, 0));
10029 objc_start_function (method_id
, meth_type
, NULL_TREE
, parmlist
);
10031 /* Set self_decl from the first argument. */
10032 self_decl
= DECL_ARGUMENTS (current_function_decl
);
10034 /* Suppress unused warnings. */
10035 TREE_USED (self_decl
) = 1;
10036 DECL_READ_P (self_decl
) = 1;
10037 TREE_USED (DECL_CHAIN (self_decl
)) = 1;
10038 DECL_READ_P (DECL_CHAIN (self_decl
)) = 1;
10040 pop_lang_context ();
10043 METHOD_DEFINITION (method
) = current_function_decl
;
10045 /* Check consistency...start_function, pushdecl, duplicate_decls. */
10047 if (implementation_template
!= objc_implementation_context
)
10050 = lookup_method_static (implementation_template
,
10051 METHOD_SEL_NAME (method
),
10052 ((TREE_CODE (method
) == CLASS_METHOD_DECL
)
10053 | OBJC_LOOKUP_NO_SUPER
));
10057 if (!comp_proto_with_proto (method
, proto
, 1))
10059 bool type
= TREE_CODE (method
) == INSTANCE_METHOD_DECL
;
10061 warning_at (DECL_SOURCE_LOCATION (method
), 0,
10062 "conflicting types for %<%c%s%>",
10063 (type
? '-' : '+'),
10064 identifier_to_locale (gen_method_decl (method
)));
10065 inform (DECL_SOURCE_LOCATION (proto
),
10066 "previous declaration of %<%c%s%>",
10067 (type
? '-' : '+'),
10068 identifier_to_locale (gen_method_decl (proto
)));
10073 /* We have a method @implementation even though we did not
10074 see a corresponding @interface declaration (which is allowed
10075 by Objective-C rules). Go ahead and place the method in
10076 the @interface anyway, so that message dispatch lookups
10078 tree interface
= implementation_template
;
10080 if (TREE_CODE (objc_implementation_context
)
10081 == CATEGORY_IMPLEMENTATION_TYPE
)
10082 interface
= lookup_category
10084 CLASS_SUPER_NAME (objc_implementation_context
));
10087 objc_add_method (interface
, copy_node (method
),
10088 TREE_CODE (method
) == CLASS_METHOD_DECL
,
10089 /* is_optional= */ false);
10094 static void *UOBJC_SUPER_scope
= 0;
10096 /* _n_Method (id self, SEL sel, ...)
10098 struct objc_super _S;
10099 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
10103 get_super_receiver (void)
10105 if (objc_method_context
)
10107 tree super_expr
, super_expr_list
;
10109 if (!UOBJC_SUPER_decl
)
10111 UOBJC_SUPER_decl
= build_decl (input_location
,
10112 VAR_DECL
, get_identifier (TAG_SUPER
),
10113 objc_super_template
);
10114 /* This prevents `unused variable' warnings when compiling with -Wall. */
10115 TREE_USED (UOBJC_SUPER_decl
) = 1;
10116 DECL_READ_P (UOBJC_SUPER_decl
) = 1;
10117 lang_hooks
.decls
.pushdecl (UOBJC_SUPER_decl
);
10118 finish_decl (UOBJC_SUPER_decl
, input_location
, NULL_TREE
, NULL_TREE
,
10120 UOBJC_SUPER_scope
= objc_get_current_scope ();
10123 /* Set receiver to self. */
10124 super_expr
= objc_build_component_ref (UOBJC_SUPER_decl
, self_id
);
10125 super_expr
= build_modify_expr (input_location
, super_expr
, NULL_TREE
,
10126 NOP_EXPR
, input_location
, self_decl
,
10128 super_expr_list
= super_expr
;
10130 /* Set class to begin searching. */
10131 super_expr
= objc_build_component_ref (UOBJC_SUPER_decl
,
10132 get_identifier ("super_class"));
10134 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
10136 /* [_cls, __cls]Super are "pre-built" in
10137 synth_forward_declarations. */
10139 super_expr
= build_modify_expr (input_location
, super_expr
,
10140 NULL_TREE
, NOP_EXPR
,
10142 ((TREE_CODE (objc_method_context
)
10143 == INSTANCE_METHOD_DECL
)
10145 : uucls_super_ref
),
10150 /* We have a category. */
10152 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
10155 /* Barf if super used in a category of Object. */
10158 error ("no super class declared in interface for %qE",
10159 CLASS_NAME (implementation_template
));
10160 return error_mark_node
;
10163 if (flag_next_runtime
&& !flag_zero_link
)
10165 super_class
= objc_get_class_reference (super_name
);
10166 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
10167 /* If we are in a class method, we must retrieve the
10168 _metaclass_ for the current class, pointed at by
10169 the class's "isa" pointer. The following assumes that
10170 "isa" is the first ivar in a class (which it must be). */
10172 = build_indirect_ref
10174 build_c_cast (input_location
,
10175 build_pointer_type (objc_class_type
),
10176 super_class
), RO_UNARY_STAR
);
10180 add_class_reference (super_name
);
10181 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
10182 ? objc_get_class_decl
: objc_get_meta_class_decl
);
10183 assemble_external (super_class
);
10185 = build_function_call
10190 my_build_string_pointer
10191 (IDENTIFIER_LENGTH (super_name
) + 1,
10192 IDENTIFIER_POINTER (super_name
))));
10196 = build_modify_expr (input_location
, super_expr
, NULL_TREE
,
10199 build_c_cast (input_location
,
10200 TREE_TYPE (super_expr
),
10205 super_expr_list
= build_compound_expr (input_location
,
10206 super_expr_list
, super_expr
);
10208 super_expr
= build_unary_op (input_location
,
10209 ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
10210 super_expr_list
= build_compound_expr (input_location
,
10211 super_expr_list
, super_expr
);
10213 return super_expr_list
;
10217 error ("[super ...] must appear in a method context");
10218 return error_mark_node
;
10222 /* When exiting a scope, sever links to a 'super' declaration (if any)
10223 therein contained. */
10226 objc_clear_super_receiver (void)
10228 if (objc_method_context
10229 && UOBJC_SUPER_scope
== objc_get_current_scope ()) {
10230 UOBJC_SUPER_decl
= 0;
10231 UOBJC_SUPER_scope
= 0;
10236 objc_finish_method_definition (tree fndecl
)
10238 /* We cannot validly inline ObjC methods, at least not without a language
10239 extension to declare that a method need not be dynamically
10240 dispatched, so suppress all thoughts of doing so. */
10241 DECL_UNINLINABLE (fndecl
) = 1;
10244 /* The C++ front-end will have called finish_function() for us. */
10245 finish_function ();
10248 METHOD_ENCODING (objc_method_context
)
10249 = encode_method_prototype (objc_method_context
);
10251 /* Required to implement _msgSuper. This must be done AFTER finish_function,
10252 since the optimizer may find "may be used before set" errors. */
10253 objc_method_context
= NULL_TREE
;
10255 if (should_call_super_dealloc
)
10256 warning (0, "method possibly missing a [super dealloc] call");
10259 /* Given a tree DECL node, produce a printable description of it in the given
10260 buffer, overwriting the buffer. */
10263 gen_declaration (tree decl
)
10269 gen_type_name_0 (TREE_TYPE (decl
));
10271 if (DECL_NAME (decl
))
10273 if (!POINTER_TYPE_P (TREE_TYPE (decl
)))
10274 strcat (errbuf
, " ");
10276 strcat (errbuf
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
10279 if (DECL_INITIAL (decl
)
10280 && TREE_CODE (DECL_INITIAL (decl
)) == INTEGER_CST
)
10281 sprintf (errbuf
+ strlen (errbuf
), ": " HOST_WIDE_INT_PRINT_DEC
,
10282 TREE_INT_CST_LOW (DECL_INITIAL (decl
)));
10288 /* Given a tree TYPE node, produce a printable description of it in the given
10289 buffer, overwriting the buffer. */
10292 gen_type_name_0 (tree type
)
10294 tree orig
= type
, proto
;
10296 if (TYPE_P (type
) && TYPE_NAME (type
))
10297 type
= TYPE_NAME (type
);
10298 else if (POINTER_TYPE_P (type
) || TREE_CODE (type
) == ARRAY_TYPE
)
10300 tree inner
= TREE_TYPE (type
);
10302 while (TREE_CODE (inner
) == ARRAY_TYPE
)
10303 inner
= TREE_TYPE (inner
);
10305 gen_type_name_0 (inner
);
10307 if (!POINTER_TYPE_P (inner
))
10308 strcat (errbuf
, " ");
10310 if (POINTER_TYPE_P (type
))
10311 strcat (errbuf
, "*");
10313 while (type
!= inner
)
10315 strcat (errbuf
, "[");
10317 if (TYPE_DOMAIN (type
))
10321 sprintf (sz
, HOST_WIDE_INT_PRINT_DEC
,
10323 (TYPE_MAX_VALUE (TYPE_DOMAIN (type
))) + 1));
10324 strcat (errbuf
, sz
);
10327 strcat (errbuf
, "]");
10328 type
= TREE_TYPE (type
);
10331 goto exit_function
;
10334 if (TREE_CODE (type
) == TYPE_DECL
&& DECL_NAME (type
))
10335 type
= DECL_NAME (type
);
10337 strcat (errbuf
, TREE_CODE (type
) == IDENTIFIER_NODE
10338 ? IDENTIFIER_POINTER (type
)
10341 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
10342 if (objc_is_id (orig
))
10343 orig
= TREE_TYPE (orig
);
10345 proto
= TYPE_HAS_OBJC_INFO (orig
) ? TYPE_OBJC_PROTOCOL_LIST (orig
) : NULL_TREE
;
10349 strcat (errbuf
, " <");
10353 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto
))));
10354 proto
= TREE_CHAIN (proto
);
10355 strcat (errbuf
, proto
? ", " : ">");
10364 gen_type_name (tree type
)
10368 return gen_type_name_0 (type
);
10371 /* Given a method tree, put a printable description into the given
10372 buffer (overwriting) and return a pointer to the buffer. */
10375 gen_method_decl (tree method
)
10379 strcpy (errbuf
, "("); /* NB: Do _not_ call strcat() here. */
10380 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method
)));
10381 strcat (errbuf
, ")");
10382 chain
= METHOD_SEL_ARGS (method
);
10386 /* We have a chain of keyword_decls. */
10389 if (KEYWORD_KEY_NAME (chain
))
10390 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
10392 strcat (errbuf
, ":(");
10393 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain
)));
10394 strcat (errbuf
, ")");
10396 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
10397 if ((chain
= DECL_CHAIN (chain
)))
10398 strcat (errbuf
, " ");
10402 if (METHOD_ADD_ARGS (method
))
10404 chain
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
10406 /* Know we have a chain of parm_decls. */
10409 strcat (errbuf
, ", ");
10410 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain
)));
10411 chain
= TREE_CHAIN (chain
);
10414 if (METHOD_ADD_ARGS_ELLIPSIS_P (method
))
10415 strcat (errbuf
, ", ...");
10420 /* We have a unary selector. */
10421 strcat (errbuf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
10429 /* Dump an @interface declaration of the supplied class CHAIN to the
10430 supplied file FP. Used to implement the -gen-decls option (which
10431 prints out an @interface declaration of all classes compiled in
10432 this run); potentially useful for debugging the compiler too. */
10434 dump_interface (FILE *fp
, tree chain
)
10436 /* FIXME: A heap overflow here whenever a method (or ivar)
10437 declaration is so long that it doesn't fit in the buffer. The
10438 code and all the related functions should be rewritten to avoid
10439 using fixed size buffers. */
10440 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
10441 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
10442 tree nst_methods
= CLASS_NST_METHODS (chain
);
10443 tree cls_methods
= CLASS_CLS_METHODS (chain
);
10445 fprintf (fp
, "\n@interface %s", my_name
);
10447 /* CLASS_SUPER_NAME is used to store the superclass name for
10448 classes, and the category name for categories. */
10449 if (CLASS_SUPER_NAME (chain
))
10451 const char *name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
10453 if (TREE_CODE (chain
) == CATEGORY_IMPLEMENTATION_TYPE
10454 || TREE_CODE (chain
) == CATEGORY_INTERFACE_TYPE
)
10456 fprintf (fp
, " (%s)\n", name
);
10460 fprintf (fp
, " : %s\n", name
);
10464 fprintf (fp
, "\n");
10466 /* FIXME - the following doesn't seem to work at the moment. */
10469 fprintf (fp
, "{\n");
10472 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
));
10473 ivar_decls
= TREE_CHAIN (ivar_decls
);
10475 while (ivar_decls
);
10476 fprintf (fp
, "}\n");
10479 while (nst_methods
)
10481 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
));
10482 nst_methods
= TREE_CHAIN (nst_methods
);
10485 while (cls_methods
)
10487 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
));
10488 cls_methods
= TREE_CHAIN (cls_methods
);
10491 fprintf (fp
, "@end\n");
10494 /* Demangle function for Objective-C */
10495 static const char *
10496 objc_demangle (const char *mangled
)
10498 char *demangled
, *cp
;
10500 if (mangled
[0] == '_' &&
10501 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
10504 cp
= demangled
= XNEWVEC (char, strlen(mangled
) + 2);
10505 if (mangled
[1] == 'i')
10506 *cp
++ = '-'; /* for instance method */
10508 *cp
++ = '+'; /* for class method */
10509 *cp
++ = '['; /* opening left brace */
10510 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
10511 while (*cp
&& *cp
== '_')
10512 cp
++; /* skip any initial underbars in class name */
10513 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
10516 free(demangled
); /* not mangled name */
10519 if (cp
[1] == '_') /* easy case: no category name */
10521 *cp
++ = ' '; /* replace two '_' with one ' ' */
10522 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
10526 *cp
++ = '('; /* less easy case: category name */
10527 cp
= strchr(cp
, '_');
10530 free(demangled
); /* not mangled name */
10534 *cp
++ = ' '; /* overwriting 1st char of method name... */
10535 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
10537 while (*cp
&& *cp
== '_')
10538 cp
++; /* skip any initial underbars in method name */
10541 *cp
= ':'; /* replace remaining '_' with ':' */
10542 *cp
++ = ']'; /* closing right brace */
10543 *cp
++ = 0; /* string terminator */
10547 return mangled
; /* not an objc mangled name */
10551 objc_printable_name (tree decl
, int kind ATTRIBUTE_UNUSED
)
10553 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
10559 gcc_obstack_init (&util_obstack
);
10560 util_firstobj
= (char *) obstack_finish (&util_obstack
);
10562 errbuf
= XNEWVEC (char, 1024 * 10);
10564 synth_module_prologue ();
10570 struct imp_entry
*impent
;
10572 /* The internally generated initializers appear to have missing braces.
10573 Don't warn about this. */
10574 int save_warn_missing_braces
= warn_missing_braces
;
10575 warn_missing_braces
= 0;
10577 /* A missing @end may not be detected by the parser. */
10578 if (objc_implementation_context
)
10580 warning (0, "%<@end%> missing in implementation context");
10581 finish_class (objc_implementation_context
);
10582 objc_ivar_chain
= NULL_TREE
;
10583 objc_implementation_context
= NULL_TREE
;
10586 /* Process the static instances here because initialization of objc_symtab
10587 depends on them. */
10588 if (objc_static_instances
)
10589 generate_static_references ();
10591 /* forward declare categories */
10593 forward_declare_categories ();
10595 for (impent
= imp_list
; impent
; impent
= impent
->next
)
10597 objc_implementation_context
= impent
->imp_context
;
10598 implementation_template
= impent
->imp_template
;
10600 /* FIXME: This needs reworking to be more obvious. */
10602 UOBJC_CLASS_decl
= impent
->class_decl
;
10603 UOBJC_METACLASS_decl
= impent
->meta_decl
;
10605 /* Dump the @interface of each class as we compile it, if the
10606 -gen-decls option is in use. TODO: Dump the classes in the
10607 order they were found, rather than in reverse order as we
10609 if (flag_gen_declaration
)
10611 dump_interface (gen_declaration_file
, objc_implementation_context
);
10614 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
10616 /* all of the following reference the string pool... */
10617 generate_ivar_lists ();
10618 generate_dispatch_tables ();
10619 generate_shared_structures (impent
);
10623 generate_dispatch_tables ();
10624 generate_category (impent
);
10627 impent
->class_decl
= UOBJC_CLASS_decl
;
10628 impent
->meta_decl
= UOBJC_METACLASS_decl
;
10631 /* If we are using an array of selectors, we must always
10632 finish up the array decl even if no selectors were used. */
10633 if (flag_next_runtime
)
10634 build_next_selector_translation_table ();
10636 build_gnu_selector_translation_table ();
10638 if (protocol_chain
)
10639 generate_protocols ();
10641 if (flag_next_runtime
)
10642 generate_objc_image_info ();
10644 if (imp_list
|| class_names_chain
10645 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
10646 generate_objc_symtab_decl ();
10648 /* Arrange for ObjC data structures to be initialized at run time. */
10649 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
10650 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
10652 build_module_descriptor ();
10654 if (!flag_next_runtime
)
10655 build_module_initializer_routine ();
10658 /* Dump the class references. This forces the appropriate classes
10659 to be linked into the executable image, preserving unix archive
10660 semantics. This can be removed when we move to a more dynamically
10661 linked environment. */
10663 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
10665 handle_class_ref (chain
);
10666 if (TREE_PURPOSE (chain
))
10667 generate_classref_translation_entry (chain
);
10670 for (impent
= imp_list
; impent
; impent
= impent
->next
)
10671 handle_impent (impent
);
10678 /* Run through the selector hash tables and print a warning for any
10679 selector which has multiple methods. */
10681 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
10683 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
10684 check_duplicates (hsh
, 0, 1);
10685 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
10686 check_duplicates (hsh
, 0, 1);
10690 warn_missing_braces
= save_warn_missing_braces
;
10693 /* Subroutines of finish_objc. */
10696 generate_classref_translation_entry (tree chain
)
10698 tree expr
, decl
, type
;
10700 decl
= TREE_PURPOSE (chain
);
10701 type
= TREE_TYPE (decl
);
10703 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
10704 expr
= convert (type
, expr
); /* cast! */
10706 /* This is a class reference. It is re-written by the runtime,
10707 but will be optimized away unless we force it. */
10708 DECL_PRESERVE_P (decl
) = 1;
10709 finish_var_decl (decl
, expr
);
10714 handle_class_ref (tree chain
)
10716 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
10717 char *string
= (char *) alloca (strlen (name
) + 30);
10721 sprintf (string
, "%sobjc_class_name_%s",
10722 (flag_next_runtime
? "." : "__"), name
);
10724 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
10725 if (flag_next_runtime
)
10727 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
10732 /* Make a decl for this name, so we can use its address in a tree. */
10733 decl
= build_decl (input_location
,
10734 VAR_DECL
, get_identifier (string
), TREE_TYPE (integer_zero_node
));
10735 DECL_EXTERNAL (decl
) = 1;
10736 TREE_PUBLIC (decl
) = 1;
10738 finish_var_decl (decl
, 0);
10740 /* Make a decl for the address. */
10741 sprintf (string
, "%sobjc_class_ref_%s",
10742 (flag_next_runtime
? "." : "__"), name
);
10743 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
10744 decl
= build_decl (input_location
,
10745 VAR_DECL
, get_identifier (string
), string_type_node
);
10746 TREE_STATIC (decl
) = 1;
10747 TREE_USED (decl
) = 1;
10748 DECL_READ_P (decl
) = 1;
10749 DECL_ARTIFICIAL (decl
) = 1;
10750 DECL_INITIAL (decl
) = error_mark_node
;
10752 /* We must force the reference. */
10753 DECL_PRESERVE_P (decl
) = 1;
10756 finish_var_decl (decl
, exp
);
10760 handle_impent (struct imp_entry
*impent
)
10764 objc_implementation_context
= impent
->imp_context
;
10765 implementation_template
= impent
->imp_template
;
10767 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
10769 const char *const class_name
=
10770 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
10772 string
= (char *) alloca (strlen (class_name
) + 30);
10774 sprintf (string
, "%sobjc_class_name_%s",
10775 (flag_next_runtime
? "." : "__"), class_name
);
10777 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
10779 const char *const class_name
=
10780 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
10781 const char *const class_super_name
=
10782 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
10784 string
= (char *) alloca (strlen (class_name
)
10785 + strlen (class_super_name
) + 30);
10787 /* Do the same for categories. Even though no references to
10788 these symbols are generated automatically by the compiler, it
10789 gives you a handle to pull them into an archive by hand. */
10790 sprintf (string
, "*%sobjc_category_name_%s_%s",
10791 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
10796 #ifdef ASM_DECLARE_CLASS_REFERENCE
10797 if (flag_next_runtime
)
10799 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
10807 init
= integer_zero_node
;
10808 decl
= build_decl (input_location
,
10809 VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
10810 TREE_PUBLIC (decl
) = 1;
10811 TREE_READONLY (decl
) = 1;
10812 TREE_USED (decl
) = 1;
10813 TREE_CONSTANT (decl
) = 1;
10814 DECL_CONTEXT (decl
) = NULL_TREE
;
10815 DECL_ARTIFICIAL (decl
) = 1;
10816 TREE_STATIC (decl
) = 1;
10817 DECL_INITIAL (decl
) = error_mark_node
; /* A real initializer is coming... */
10818 /* We must force the reference. */
10819 DECL_PRESERVE_P (decl
) = 1;
10821 finish_var_decl(decl
, init
) ;
10825 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
10826 later requires that ObjC translation units participating in F&C be
10827 specially marked. The following routine accomplishes this. */
10829 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
10832 generate_objc_image_info (void)
10836 = ((flag_replace_objc_classes
&& imp_count
? 1 : 0)
10837 | (flag_objc_gc
? 2 : 0));
10838 VEC(constructor_elt
,gc
) *v
= NULL
;
10842 return; /* No need for an image_info entry. */
10844 array_type
= build_sized_array_type (integer_type_node
, 2);
10846 decl
= start_var_decl (array_type
, "_OBJC_IMAGE_INFO");
10848 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
10849 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (integer_type_node
, flags
));
10850 /* If we need this (determined above) it is because the runtime wants to
10851 refer to it in a manner hidden from the compiler. So we must force the
10853 DECL_PRESERVE_P (decl
) = 1;
10854 finish_var_decl (decl
, objc_build_constructor (TREE_TYPE (decl
), v
));
10857 /* Routine is called to issue diagnostic when reference to a private
10858 ivar is made and no other variable with same name is found in
10861 objc_diagnose_private_ivar (tree id
)
10864 if (!objc_method_context
)
10866 ivar
= is_ivar (objc_ivar_chain
, id
);
10867 if (ivar
&& is_private (ivar
))
10869 error ("instance variable %qs is declared private",
10870 IDENTIFIER_POINTER (id
));
10876 /* Look up ID as an instance variable. OTHER contains the result of
10877 the C or C++ lookup, which we may want to use instead. */
10878 /* Also handle use of property as setter/getter. */
10880 objc_lookup_ivar (tree other
, tree id
)
10882 tree ivar
, property
;
10884 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
10885 if (!objc_method_context
)
10888 if (!strcmp (IDENTIFIER_POINTER (id
), "super"))
10889 /* We have a message to super. */
10890 return get_super_receiver ();
10892 /* In a class method, look up an instance variable only as a last
10894 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
10895 && other
&& other
!= error_mark_node
)
10898 property
= NULL_TREE
;
10899 if (objc_implementation_context
)
10900 property
= is_property (objc_implementation_context
, id
);
10904 /* Look up the ivar, but do not use it if it is not accessible. */
10905 ivar
= is_ivar (objc_ivar_chain
, id
);
10907 if (!ivar
|| is_private (ivar
))
10911 /* In an instance method, a local variable (or parameter) may hide the
10912 instance variable. */
10913 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
10914 && other
&& other
!= error_mark_node
10916 && CP_DECL_CONTEXT (other
) != global_namespace
)
10918 && !DECL_FILE_SCOPE_P (other
))
10922 warning (0, "local declaration of %qE hides property", id
);
10924 warning (0, "local declaration of %qE hides instance variable", id
);
10930 return build_property_reference (property
, id
);
10932 /* At this point, we are either in an instance method with no obscuring
10933 local definitions, or in a class method with no alternate definitions
10935 return build_ivar_reference (id
);
10938 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
10939 needs to be done if we are calling a function through a cast. */
10942 objc_rewrite_function_call (tree function
, tree first_param
)
10944 if (TREE_CODE (function
) == NOP_EXPR
10945 && TREE_CODE (TREE_OPERAND (function
, 0)) == ADDR_EXPR
10946 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function
, 0), 0))
10949 function
= build3 (OBJ_TYPE_REF
, TREE_TYPE (function
),
10950 TREE_OPERAND (function
, 0),
10951 first_param
, size_zero_node
);
10957 /* Look for the special case of OBJC_TYPE_REF with the address of
10958 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
10959 of its cousins). */
10962 objc_gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
10964 enum gimplify_status r0
, r1
;
10965 if (TREE_CODE (*expr_p
) == OBJ_TYPE_REF
10966 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p
)) == ADDR_EXPR
10967 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p
), 0))
10970 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
10971 value of the OBJ_TYPE_REF, so force them to be emitted
10972 during subexpression evaluation rather than after the
10973 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
10974 C to use direct rather than indirect calls when the
10975 object expression has a postincrement. */
10976 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
, NULL
,
10977 is_gimple_val
, fb_rvalue
);
10978 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
, post_p
,
10979 is_gimple_val
, fb_rvalue
);
10981 return MIN (r0
, r1
);
10985 return (enum gimplify_status
) cp_gimplify_expr (expr_p
, pre_p
, post_p
);
10987 return (enum gimplify_status
) c_gimplify_expr (expr_p
, pre_p
, post_p
);
10991 /* This routine returns true if TYP is a valid objc object type,
10992 suitable for messaging; false otherwise.
10996 objc_type_valid_for_messaging (tree typ
)
10998 if (!POINTER_TYPE_P (typ
))
11002 typ
= TREE_TYPE (typ
); /* Remove indirections. */
11003 while (POINTER_TYPE_P (typ
));
11005 if (TREE_CODE (typ
) != RECORD_TYPE
)
11008 return objc_is_object_id (typ
) || TYPE_HAS_OBJC_INFO (typ
);
11011 /* Begin code generation for fast enumeration (foreach) ... */
11015 struct __objcFastEnumerationState
11017 unsigned long state;
11019 unsigned long *mutationsPtr;
11020 unsigned long extra[5];
11023 Confusingly enough, NSFastEnumeration is then defined by libraries
11024 to be the same structure.
11028 build_fast_enumeration_state_template (void)
11030 tree decls
, *chain
= NULL
;
11033 objc_fast_enumeration_state_template
= objc_start_struct (get_identifier
11034 (TAG_FAST_ENUMERATION_STATE
));
11036 /* unsigned long state; */
11037 decls
= add_field_decl (long_unsigned_type_node
, "state", &chain
);
11039 /* id *itemsPtr; */
11040 add_field_decl (build_pointer_type (objc_object_type
),
11041 "itemsPtr", &chain
);
11043 /* unsigned long *mutationsPtr; */
11044 add_field_decl (build_pointer_type (long_unsigned_type_node
),
11045 "mutationsPtr", &chain
);
11047 /* unsigned long extra[5]; */
11048 add_field_decl (build_sized_array_type (long_unsigned_type_node
, 5),
11052 objc_finish_struct (objc_fast_enumeration_state_template
, decls
);
11056 'objc_finish_foreach_loop()' generates the code for an Objective-C
11057 foreach loop. The 'location' argument is the location of the 'for'
11058 that starts the loop. The 'object_expression' is the expression of
11059 the 'object' that iterates; the 'collection_expression' is the
11060 expression of the collection that we iterate over (we need to make
11061 sure we evaluate this only once); the 'for_body' is the set of
11062 statements to be executed in each iteration; 'break_label' and
11063 'continue_label' are the break and continue labels which we need to
11064 emit since the <statements> may be jumping to 'break_label' (if they
11065 contain 'break') or to 'continue_label' (if they contain
11070 for (<object expression> in <collection expression>)
11073 which is compiled into the following blurb:
11076 id __objc_foreach_collection;
11077 __objc_fast_enumeration_state __objc_foreach_enum_state;
11078 unsigned long __objc_foreach_batchsize;
11079 id __objc_foreach_items[16];
11080 __objc_foreach_collection = <collection expression>;
11081 __objc_foreach_enum_state = { 0 };
11082 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
11084 if (__objc_foreach_batchsize == 0)
11085 <object expression> = nil;
11088 unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
11091 unsigned long __objc_foreach_index;
11092 __objc_foreach_index = 0;
11095 if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
11096 <object expression> = enumState.itemsPtr[__objc_foreach_index];
11097 <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
11100 __objc_foreach_index++;
11101 if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
11102 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
11104 if (__objc_foreach_batchsize != 0) goto next_batch;
11105 <object expression> = nil;
11110 'statements' may contain a 'continue' or 'break' instruction, which
11111 the user expects to 'continue' or 'break' the entire foreach loop.
11112 We are provided the labels that 'break' and 'continue' jump to, so
11113 we place them where we want them to jump to when they pick them.
11115 Optimization TODO: we could cache the IMP of
11116 countByEnumeratingWithState:objects:count:.
11119 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line. */
11120 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
11122 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
11123 #include "tree-pretty-print.h"
11127 objc_finish_foreach_loop (location_t location
, tree object_expression
, tree collection_expression
, tree for_body
,
11128 tree break_label
, tree continue_label
)
11130 /* A tree representing the __objcFastEnumerationState struct type,
11131 or NSFastEnumerationState struct, whatever we are using. */
11132 tree objc_fast_enumeration_state_type
;
11134 /* The trees representing the declarations of each of the local variables. */
11135 tree objc_foreach_collection_decl
;
11136 tree objc_foreach_enum_state_decl
;
11137 tree objc_foreach_items_decl
;
11138 tree objc_foreach_batchsize_decl
;
11139 tree objc_foreach_mutations_pointer_decl
;
11140 tree objc_foreach_index_decl
;
11142 /* A tree representing the selector countByEnumeratingWithState:objects:count:. */
11143 tree selector_name
;
11145 /* A tree representing the local bind. */
11148 /* A tree representing the external 'if (__objc_foreach_batchsize)' */
11151 /* A tree representing the 'else' part of 'first_if' */
11154 /* A tree representing the 'next_batch' label. */
11155 tree next_batch_label_decl
;
11157 /* A tree representing the binding after the 'next_batch' label. */
11158 tree next_batch_bind
;
11160 /* A tree representing the 'next_object' label. */
11161 tree next_object_label_decl
;
11163 /* Temporary variables. */
11167 if (object_expression
== error_mark_node
)
11170 if (collection_expression
== error_mark_node
)
11173 if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression
)))
11175 error ("iterating variable in fast enumeration is not an object");
11179 if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression
)))
11181 error ("collection in fast enumeration is not an object");
11185 /* TODO: Check that object_expression is either a variable
11186 declaration, or an lvalue. */
11188 /* This kludge is an idea from apple. We use the
11189 __objcFastEnumerationState struct implicitly defined by the
11190 compiler, unless a NSFastEnumerationState struct has been defined
11191 (by a Foundation library such as GNUstep Base) in which case, we
11194 objc_fast_enumeration_state_type
= objc_fast_enumeration_state_template
;
11196 tree objc_NSFastEnumeration_type
= lookup_name (get_identifier ("NSFastEnumerationState"));
11198 if (objc_NSFastEnumeration_type
)
11200 /* TODO: We really need to check that
11201 objc_NSFastEnumeration_type is the same as ours! */
11202 if (TREE_CODE (objc_NSFastEnumeration_type
) == TYPE_DECL
)
11204 /* If it's a typedef, use the original type. */
11205 if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type
))
11206 objc_fast_enumeration_state_type
= DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type
);
11208 objc_fast_enumeration_state_type
= TREE_TYPE (objc_NSFastEnumeration_type
);
11214 /* Done by c-parser.c. */
11217 /* Done by c-parser.c. */
11219 /* id __objc_foreach_collection */
11220 objc_foreach_collection_decl
= objc_create_temporary_var (objc_object_type
, "__objc_foreach_collection");
11222 /* __objcFastEnumerationState __objc_foreach_enum_state; */
11223 objc_foreach_enum_state_decl
= objc_create_temporary_var (objc_fast_enumeration_state_type
, "__objc_foreach_enum_state");
11224 TREE_CHAIN (objc_foreach_enum_state_decl
) = objc_foreach_collection_decl
;
11226 /* id __objc_foreach_items[16]; */
11227 objc_foreach_items_decl
= objc_create_temporary_var (build_sized_array_type (objc_object_type
, 16), "__objc_foreach_items");
11228 TREE_CHAIN (objc_foreach_items_decl
) = objc_foreach_enum_state_decl
;
11230 /* unsigned long __objc_foreach_batchsize; */
11231 objc_foreach_batchsize_decl
= objc_create_temporary_var (long_unsigned_type_node
, "__objc_foreach_batchsize");
11232 TREE_CHAIN (objc_foreach_batchsize_decl
) = objc_foreach_items_decl
;
11234 /* Generate the local variable binding. */
11235 bind
= build3 (BIND_EXPR
, void_type_node
, objc_foreach_batchsize_decl
, NULL
, NULL
);
11236 SET_EXPR_LOCATION (bind
, location
);
11237 TREE_SIDE_EFFECTS (bind
) = 1;
11239 /* __objc_foreach_collection = <collection expression>; */
11240 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_collection_decl
, collection_expression
);
11241 SET_EXPR_LOCATION (t
, location
);
11242 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11244 /* __objc_foreach_enum_state.state = 0; */
11245 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11246 get_identifier ("state")),
11247 build_int_cst (long_unsigned_type_node
, 0));
11248 SET_EXPR_LOCATION (t
, location
);
11249 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11251 /* __objc_foreach_enum_state.itemsPtr = NULL; */
11252 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11253 get_identifier ("itemsPtr")),
11254 null_pointer_node
);
11255 SET_EXPR_LOCATION (t
, location
);
11256 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11258 /* __objc_foreach_enum_state.mutationsPtr = NULL; */
11259 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11260 get_identifier ("mutationsPtr")),
11261 null_pointer_node
);
11262 SET_EXPR_LOCATION (t
, location
);
11263 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11265 /* __objc_foreach_enum_state.extra[0] = 0; */
11266 /* __objc_foreach_enum_state.extra[1] = 0; */
11267 /* __objc_foreach_enum_state.extra[2] = 0; */
11268 /* __objc_foreach_enum_state.extra[3] = 0; */
11269 /* __objc_foreach_enum_state.extra[4] = 0; */
11270 for (i
= 0; i
< 5 ; i
++)
11272 t
= build2 (MODIFY_EXPR
, void_type_node
,
11273 build_array_ref (location
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11274 get_identifier ("extra")),
11275 build_int_cst (NULL_TREE
, i
)),
11276 build_int_cst (long_unsigned_type_node
, 0));
11277 SET_EXPR_LOCATION (t
, location
);
11278 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11281 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
11282 selector_name
= get_identifier ("countByEnumeratingWithState:objects:count:");
11284 t
= objc_finish_message_expr (objc_foreach_collection_decl
, selector_name
,
11286 tree_cons
/* &__objc_foreach_enum_state */
11287 (NULL_TREE
, build_fold_addr_expr_loc (location
, objc_foreach_enum_state_decl
),
11288 tree_cons
/* __objc_foreach_items */
11289 (NULL_TREE
, objc_foreach_items_decl
,
11291 (NULL_TREE
, build_int_cst (NULL_TREE
, 16), NULL_TREE
))));
11293 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
11295 struct c_expr array
;
11296 array
.value
= objc_foreach_items_decl
;
11297 t
= objc_finish_message_expr (objc_foreach_collection_decl
, selector_name
,
11299 tree_cons
/* &__objc_foreach_enum_state */
11300 (NULL_TREE
, build_fold_addr_expr_loc (location
, objc_foreach_enum_state_decl
),
11301 tree_cons
/* __objc_foreach_items */
11302 (NULL_TREE
, default_function_array_conversion (location
, array
).value
,
11304 (NULL_TREE
, build_int_cst (NULL_TREE
, 16), NULL_TREE
))));
11307 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_batchsize_decl
,
11308 convert (long_unsigned_type_node
, t
));
11309 SET_EXPR_LOCATION (t
, location
);
11310 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11312 /* if (__objc_foreach_batchsize == 0) */
11313 first_if
= build3 (COND_EXPR
, void_type_node
,
11316 (c_common_truthvalue_conversion
11318 build_binary_op (location
,
11320 objc_foreach_batchsize_decl
,
11321 build_int_cst (long_unsigned_type_node
, 0), 1)),
11323 /* Then block (we fill it in later). */
11325 /* Else block (we fill it in later). */
11327 SET_EXPR_LOCATION (first_if
, location
);
11328 append_to_statement_list (first_if
, &BIND_EXPR_BODY (bind
));
11330 /* then <object expression> = nil; */
11331 t
= build2 (MODIFY_EXPR
, void_type_node
, object_expression
, convert (objc_object_type
, null_pointer_node
));
11332 SET_EXPR_LOCATION (t
, location
);
11333 COND_EXPR_THEN (first_if
) = t
;
11335 /* Now we build the 'else' part of the if; once we finish building
11336 it, we attach it to first_if as the 'else' part. */
11341 /* unsigned long __objc_foreach_mutations_pointer; */
11342 objc_foreach_mutations_pointer_decl
= objc_create_temporary_var (long_unsigned_type_node
, "__objc_foreach_mutations_pointer");
11344 /* Generate the local variable binding. */
11345 first_else
= build3 (BIND_EXPR
, void_type_node
, objc_foreach_mutations_pointer_decl
, NULL
, NULL
);
11346 SET_EXPR_LOCATION (first_else
, location
);
11347 TREE_SIDE_EFFECTS (first_else
) = 1;
11349 /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
11350 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_mutations_pointer_decl
,
11351 build_indirect_ref (location
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11352 get_identifier ("mutationsPtr")),
11354 SET_EXPR_LOCATION (t
, location
);
11355 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11358 next_batch_label_decl
= create_artificial_label (location
);
11359 t
= build1 (LABEL_EXPR
, void_type_node
, next_batch_label_decl
);
11360 SET_EXPR_LOCATION (t
, location
);
11361 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11365 /* unsigned long __objc_foreach_index; */
11366 objc_foreach_index_decl
= objc_create_temporary_var (long_unsigned_type_node
, "__objc_foreach_index");
11368 /* Generate the local variable binding. */
11369 next_batch_bind
= build3 (BIND_EXPR
, void_type_node
, objc_foreach_index_decl
, NULL
, NULL
);
11370 SET_EXPR_LOCATION (next_batch_bind
, location
);
11371 TREE_SIDE_EFFECTS (next_batch_bind
) = 1;
11372 append_to_statement_list (next_batch_bind
, &BIND_EXPR_BODY (first_else
));
11374 /* __objc_foreach_index = 0; */
11375 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_index_decl
,
11376 build_int_cst (long_unsigned_type_node
, 0));
11377 SET_EXPR_LOCATION (t
, location
);
11378 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11381 next_object_label_decl
= create_artificial_label (location
);
11382 t
= build1 (LABEL_EXPR
, void_type_node
, next_object_label_decl
);
11383 SET_EXPR_LOCATION (t
, location
);
11384 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11386 /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
11387 t
= build3 (COND_EXPR
, void_type_node
,
11390 (c_common_truthvalue_conversion
11395 objc_foreach_mutations_pointer_decl
,
11396 build_indirect_ref (location
,
11397 objc_build_component_ref (objc_foreach_enum_state_decl
,
11398 get_identifier ("mutationsPtr")),
11399 RO_UNARY_STAR
), 1)),
11402 build_function_call (input_location
,
11403 objc_enumeration_mutation_decl
,
11404 tree_cons (NULL
, collection_expression
, NULL
)),
11407 SET_EXPR_LOCATION (t
, location
);
11408 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11410 /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
11411 t
= build2 (MODIFY_EXPR
, void_type_node
, object_expression
,
11412 build_array_ref (location
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11413 get_identifier ("itemsPtr")),
11414 objc_foreach_index_decl
));
11415 SET_EXPR_LOCATION (t
, location
);
11416 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11418 /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
11419 append_to_statement_list (for_body
, &BIND_EXPR_BODY (next_batch_bind
));
11421 /* continue_label: */
11422 if (continue_label
)
11424 t
= build1 (LABEL_EXPR
, void_type_node
, continue_label
);
11425 SET_EXPR_LOCATION (t
, location
);
11426 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11429 /* __objc_foreach_index++; */
11430 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_index_decl
,
11431 build_binary_op (location
,
11433 objc_foreach_index_decl
,
11434 build_int_cst (long_unsigned_type_node
, 1), 1));
11435 SET_EXPR_LOCATION (t
, location
);
11436 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11438 /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
11439 t
= build3 (COND_EXPR
, void_type_node
,
11442 (c_common_truthvalue_conversion
11444 build_binary_op (location
,
11446 objc_foreach_index_decl
,
11447 objc_foreach_batchsize_decl
, 1)),
11450 build1 (GOTO_EXPR
, void_type_node
, next_object_label_decl
),
11453 SET_EXPR_LOCATION (t
, location
);
11454 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11456 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
11458 t
= objc_finish_message_expr (objc_foreach_collection_decl
, selector_name
,
11460 tree_cons
/* &__objc_foreach_enum_state */
11461 (NULL_TREE
, build_fold_addr_expr_loc (location
, objc_foreach_enum_state_decl
),
11462 tree_cons
/* __objc_foreach_items */
11463 (NULL_TREE
, objc_foreach_items_decl
,
11465 (NULL_TREE
, build_int_cst (NULL_TREE
, 16), NULL_TREE
))));
11467 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
11469 struct c_expr array
;
11470 array
.value
= objc_foreach_items_decl
;
11471 t
= objc_finish_message_expr (objc_foreach_collection_decl
, selector_name
,
11473 tree_cons
/* &__objc_foreach_enum_state */
11474 (NULL_TREE
, build_fold_addr_expr_loc (location
, objc_foreach_enum_state_decl
),
11475 tree_cons
/* __objc_foreach_items */
11476 (NULL_TREE
, default_function_array_conversion (location
, array
).value
,
11478 (NULL_TREE
, build_int_cst (NULL_TREE
, 16), NULL_TREE
))));
11481 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_batchsize_decl
,
11482 convert (long_unsigned_type_node
, t
));
11483 SET_EXPR_LOCATION (t
, location
);
11484 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11488 /* if (__objc_foreach_batchsize != 0) goto next_batch; */
11489 t
= build3 (COND_EXPR
, void_type_node
,
11492 (c_common_truthvalue_conversion
11494 build_binary_op (location
,
11496 objc_foreach_batchsize_decl
,
11497 build_int_cst (long_unsigned_type_node
, 0), 1)),
11500 build1 (GOTO_EXPR
, void_type_node
, next_batch_label_decl
),
11503 SET_EXPR_LOCATION (t
, location
);
11504 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11506 /* <object expression> = nil; */
11507 t
= build2 (MODIFY_EXPR
, void_type_node
, object_expression
, convert (objc_object_type
, null_pointer_node
));
11508 SET_EXPR_LOCATION (t
, location
);
11509 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11514 t
= build1 (LABEL_EXPR
, void_type_node
, break_label
);
11515 SET_EXPR_LOCATION (t
, location
);
11516 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11520 COND_EXPR_ELSE (first_if
) = first_else
;
11522 /* Do the whole thing. */
11525 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
11526 /* This will print to stderr the whole blurb generated by the
11527 compiler while compiling (assuming the compiler doesn't crash
11528 before getting here).
11530 debug_generic_stmt (bind
);
11534 /* Done by c-parser.c */
11537 #include "gt-objc-objc-act.h"