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 /* This has the problem that "test_method:argument:" and
79 "test:method_argument:" will generate the same name
80 ("_i_Test__test_method_argument_" for an instance method of the
81 class "Test"), so you can't have them both in the same class!
82 Moreover, the demangling (going from
83 "_i_Test__test_method_argument" back to the original name) is
84 undefined because there are two correct ways of demangling the
86 #ifndef OBJC_GEN_METHOD_LABEL
87 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
90 sprintf ((BUF), "_%s_%s_%s_%s", \
91 ((IS_INST) ? "i" : "c"), \
93 ((CAT_NAME)? (CAT_NAME) : ""), \
95 for (temp = (BUF); *temp; temp++) \
96 if (*temp == ':') *temp = '_'; \
100 /* These need specifying. */
101 #ifndef OBJC_FORWARDING_STACK_OFFSET
102 #define OBJC_FORWARDING_STACK_OFFSET 0
105 #ifndef OBJC_FORWARDING_MIN_OFFSET
106 #define OBJC_FORWARDING_MIN_OFFSET 0
109 /* Set up for use of obstacks. */
113 /* This obstack is used to accumulate the encoding of a data type. */
114 static struct obstack util_obstack
;
116 /* This points to the beginning of obstack contents, so we can free
117 the whole contents. */
120 /* The version identifies which language generation and runtime
121 the module (file) was compiled for, and is recorded in the
122 module descriptor. */
124 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
125 #define PROTOCOL_VERSION 2
127 /* (Decide if these can ever be validly changed.) */
128 #define OBJC_ENCODE_INLINE_DEFS 0
129 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
131 /*** Private Interface (procedures) ***/
133 /* Used by compile_file. */
135 static void init_objc (void);
136 static void finish_objc (void);
138 /* Code generation. */
140 static tree
objc_build_constructor (tree
, VEC(constructor_elt
,gc
) *);
141 static tree
build_objc_method_call (location_t
, int, tree
, tree
, tree
, tree
);
142 static tree
get_proto_encoding (tree
);
143 static tree
lookup_interface (tree
);
144 static tree
objc_add_static_instance (tree
, tree
);
146 static tree
start_class (enum tree_code
, tree
, tree
, tree
);
147 static tree
continue_class (tree
);
148 static void finish_class (tree
);
149 static void start_method_def (tree
);
151 static void objc_start_function (tree
, tree
, tree
, tree
);
153 static void objc_start_function (tree
, tree
, tree
, struct c_arg_info
*);
155 static tree
start_protocol (enum tree_code
, tree
, tree
);
156 static tree
build_method_decl (enum tree_code
, tree
, tree
, tree
, bool);
157 static tree
objc_add_method (tree
, tree
, int, bool);
158 static tree
add_instance_variable (tree
, objc_ivar_visibility_kind
, tree
);
159 static tree
build_ivar_reference (tree
);
160 static tree
is_ivar (tree
, tree
);
162 static void build_objc_exception_stuff (void);
163 static void build_next_objc_exception_stuff (void);
165 /* We only need the following for ObjC; ObjC++ will use C++'s definition
166 of DERIVED_FROM_P. */
168 static bool objc_derived_from_p (tree
, tree
);
169 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
173 static void objc_gen_one_property_datum (tree
, tree
, tree
, bool*);
174 static void objc_gen_property_data (tree
, tree
);
175 static void objc_synthesize_getter (tree
, tree
, tree
);
176 static void objc_process_getter_setter (tree
, tree
, bool);
177 static void objc_synthesize_setter (tree
, tree
, tree
);
178 static char *objc_build_property_ivar_name (tree
);
179 static char *objc_build_property_setter_name (tree
, bool);
180 static int match_proto_with_proto (tree
, tree
, int);
181 static tree
lookup_property (tree
, tree
);
182 static tree
lookup_property_in_list (tree
, tree
);
183 static tree
lookup_property_in_protocol_list (tree
, tree
);
184 static tree
objc_setter_func_call (tree
, tree
, tree
);
185 static tree
build_property_reference (tree
, tree
);
186 static tree
is_property (tree
, tree
);
187 /* Set on a CALL_EXPR if it is for call to a getter function represented by an
188 objective-c property declaration. */
189 #define CALL_EXPR_OBJC_PROPERTY_GETTER(NODE) \
190 (CALL_EXPR_CHECK(NODE)->base.deprecated_flag)
192 static void objc_xref_basetypes (tree
, tree
);
194 static void build_class_template (void);
195 static void build_selector_template (void);
196 static void build_category_template (void);
197 static void build_super_template (void);
198 static tree
build_protocol_initializer (tree
, tree
, tree
, tree
, tree
);
199 static tree
get_class_ivars (tree
, bool);
200 static tree
generate_protocol_list (tree
);
201 static void build_protocol_reference (tree
);
203 static void build_fast_enumeration_state_template (void);
206 static void objc_generate_cxx_cdtors (void);
210 static void objc_decl_method_attributes (tree
*, tree
, int);
211 static tree
build_keyword_selector (tree
);
212 static const char *synth_id_with_class_suffix (const char *, tree
);
214 /* Hash tables to manage the global pool of method prototypes. */
216 hash
*nst_method_hash_list
= 0;
217 hash
*cls_method_hash_list
= 0;
219 /* Hash tables to manage the global pool of class names. */
221 hash
*cls_name_hash_list
= 0;
222 hash
*als_name_hash_list
= 0;
224 static void hash_class_name_enter (hash
*, tree
, tree
);
225 static hash
hash_class_name_lookup (hash
*, tree
);
227 static hash
hash_lookup (hash
*, tree
);
228 static tree
lookup_method (tree
, tree
);
229 static tree
lookup_method_static (tree
, tree
, int);
231 static tree
add_class (tree
, tree
);
232 static void add_category (tree
, tree
);
233 static inline tree
lookup_category (tree
, tree
);
237 class_names
, /* class, category, protocol, module names */
238 meth_var_names
, /* method and variable names */
239 meth_var_types
/* method and variable type descriptors */
242 static tree
add_objc_string (tree
, enum string_section
);
243 static void build_selector_table_decl (void);
245 /* Protocol additions. */
247 static tree
lookup_protocol (tree
);
248 static tree
lookup_and_install_protocols (tree
);
252 static void encode_type_qualifiers (tree
);
253 static void encode_type (tree
, int, int);
254 static void encode_field_decl (tree
, int, int);
257 static void really_start_method (tree
, tree
);
259 static void really_start_method (tree
, struct c_arg_info
*);
261 static int comp_proto_with_proto (tree
, tree
, int);
262 static tree
get_arg_type_list (tree
, int, int);
263 static tree
objc_decay_parm_type (tree
);
264 static void objc_push_parm (tree
);
266 static tree
objc_get_parm_info (int);
268 static struct c_arg_info
*objc_get_parm_info (int);
271 /* Utilities for debugging and error diagnostics. */
273 static char *gen_type_name (tree
);
274 static char *gen_type_name_0 (tree
);
275 static char *gen_method_decl (tree
);
276 static char *gen_declaration (tree
);
278 /* Everything else. */
280 static tree
create_field_decl (tree
, const char *);
281 static void add_class_reference (tree
);
282 static void build_protocol_template (void);
283 static tree
encode_method_prototype (tree
);
284 static void generate_classref_translation_entry (tree
);
285 static void handle_class_ref (tree
);
286 static void generate_struct_by_value_array (void)
288 static void mark_referenced_methods (void);
289 static void generate_objc_image_info (void);
290 static bool objc_type_valid_for_messaging (tree typ
);
292 /*** Private Interface (data) ***/
294 /* Reserved tag definitions. */
296 #define OBJECT_TYPEDEF_NAME "id"
297 #define CLASS_TYPEDEF_NAME "Class"
299 #define TAG_OBJECT "objc_object"
300 #define TAG_CLASS "objc_class"
301 #define TAG_SUPER "objc_super"
302 #define TAG_SELECTOR "objc_selector"
304 #define UTAG_CLASS "_objc_class"
305 #define UTAG_IVAR "_objc_ivar"
306 #define UTAG_IVAR_LIST "_objc_ivar_list"
307 #define UTAG_METHOD "_objc_method"
308 #define UTAG_METHOD_LIST "_objc_method_list"
309 #define UTAG_CATEGORY "_objc_category"
310 #define UTAG_MODULE "_objc_module"
311 #define UTAG_SYMTAB "_objc_symtab"
312 #define UTAG_SUPER "_objc_super"
313 #define UTAG_SELECTOR "_objc_selector"
315 #define UTAG_PROTOCOL "_objc_protocol"
316 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
317 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
319 /* Note that the string object global name is only needed for the
321 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
323 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
325 #define TAG_ENUMERATION_MUTATION "objc_enumerationMutation"
326 #define TAG_FAST_ENUMERATION_STATE "__objcFastEnumerationState"
328 static const char *TAG_GETCLASS
;
329 static const char *TAG_GETMETACLASS
;
330 static const char *TAG_MSGSEND
;
331 static const char *TAG_MSGSENDSUPER
;
332 /* The NeXT Objective-C messenger may have two extra entry points, for use
333 when returning a structure. */
334 static const char *TAG_MSGSEND_STRET
;
335 static const char *TAG_MSGSENDSUPER_STRET
;
336 static const char *default_constant_string_class_name
;
338 /* Runtime metadata flags. */
339 #define CLS_FACTORY 0x0001L
340 #define CLS_META 0x0002L
341 #define CLS_HAS_CXX_STRUCTORS 0x2000L
343 #define OBJC_MODIFIER_STATIC 0x00000001
344 #define OBJC_MODIFIER_FINAL 0x00000002
345 #define OBJC_MODIFIER_PUBLIC 0x00000004
346 #define OBJC_MODIFIER_PRIVATE 0x00000008
347 #define OBJC_MODIFIER_PROTECTED 0x00000010
348 #define OBJC_MODIFIER_NATIVE 0x00000020
349 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
350 #define OBJC_MODIFIER_ABSTRACT 0x00000080
351 #define OBJC_MODIFIER_VOLATILE 0x00000100
352 #define OBJC_MODIFIER_TRANSIENT 0x00000200
353 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
355 /* NeXT-specific tags. */
357 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
358 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
359 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
360 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
361 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
362 #define TAG_EXCEPTIONMATCH "objc_exception_match"
363 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
364 #define TAG_SYNCENTER "objc_sync_enter"
365 #define TAG_SYNCEXIT "objc_sync_exit"
366 #define TAG_SETJMP "_setjmp"
367 #define UTAG_EXCDATA "_objc_exception_data"
369 #define TAG_ASSIGNIVAR "objc_assign_ivar"
370 #define TAG_ASSIGNGLOBAL "objc_assign_global"
371 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
373 /* Branch entry points. All that matters here are the addresses;
374 functions with these names do not really exist in libobjc. */
376 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
377 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
379 #define TAG_CXX_CONSTRUCT ".cxx_construct"
380 #define TAG_CXX_DESTRUCT ".cxx_destruct"
382 /* GNU-specific tags. */
384 #define TAG_EXECCLASS "__objc_exec_class"
385 #define TAG_GNUINIT "__objc_gnu_init"
387 /* Flags for lookup_method_static(). */
388 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
389 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
391 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
392 tree objc_global_trees
[OCTI_MAX
];
394 static void handle_impent (struct imp_entry
*);
396 struct imp_entry
*imp_list
= 0;
397 int imp_count
= 0; /* `@implementation' */
398 int cat_count
= 0; /* `@category' */
400 objc_ivar_visibility_kind objc_ivar_visibility
;
402 /* Use to generate method labels. */
403 static int method_slot
= 0;
405 /* Flag to say whether methods in a protocol are optional or
407 static bool objc_method_optional_flag
= false;
409 static bool property_readonly
;
410 static tree property_getter
;
411 static tree property_setter
;
412 static tree property_ivar
;
413 static bool property_copies
;
414 static bool in_objc_property_setter_name_context
= false;
416 static int objc_collecting_ivars
= 0;
420 static char *errbuf
; /* Buffer for error diagnostics */
422 /* Data imported from tree.c. */
424 extern enum debug_info_type write_symbols
;
426 /* Data imported from toplev.c. */
428 extern const char *dump_base_name
;
430 static int flag_typed_selectors
;
432 /* Store all constructed constant strings in a hash table so that
433 they get uniqued properly. */
435 struct GTY(()) string_descriptor
{
436 /* The literal argument . */
439 /* The resulting constant string. */
443 static GTY((param_is (struct string_descriptor
))) htab_t string_htab
;
445 FILE *gen_declaration_file
;
447 /* Tells "encode_pointer/encode_aggregate" whether we are generating
448 type descriptors for instance variables (as opposed to methods).
449 Type descriptors for instance variables contain more information
450 than methods (for static typing and embedded structures). */
452 static int generating_instance_variables
= 0;
454 /* For building an objc struct. These may not be used when this file
455 is compiled as part of obj-c++. */
457 static bool objc_building_struct
;
458 static struct c_struct_parse_info
*objc_struct_info ATTRIBUTE_UNUSED
;
460 /* Start building a struct for objc. */
463 objc_start_struct (tree name
)
465 gcc_assert (!objc_building_struct
);
466 objc_building_struct
= true;
467 return start_struct (input_location
, RECORD_TYPE
, name
, &objc_struct_info
);
470 /* Finish building a struct for objc. */
473 objc_finish_struct (tree type
, tree fieldlist
)
475 gcc_assert (objc_building_struct
);
476 objc_building_struct
= false;
477 return finish_struct (input_location
, type
, fieldlist
, NULL_TREE
,
482 build_sized_array_type (tree base_type
, int size
)
484 tree index_type
= build_index_type (build_int_cst (NULL_TREE
, size
- 1));
485 return build_array_type (base_type
, index_type
);
489 add_field_decl (tree type
, const char *name
, tree
**chain
)
491 tree field
= create_field_decl (type
, name
);
495 *chain
= &DECL_CHAIN (field
);
500 /* Some platforms pass small structures through registers versus
501 through an invisible pointer. Determine at what size structure is
502 the transition point between the two possibilities. */
505 generate_struct_by_value_array (void)
510 int aggregate_in_mem
[32];
513 /* Presumably no platform passes 32 byte structures in a register. */
514 for (i
= 1; i
< 32; i
++)
519 /* Create an unnamed struct that has `i' character components */
520 type
= objc_start_struct (NULL_TREE
);
522 strcpy (buffer
, "c1");
523 decls
= add_field_decl (char_type_node
, buffer
, &chain
);
525 for (j
= 1; j
< i
; j
++)
527 sprintf (buffer
, "c%d", j
+ 1);
528 add_field_decl (char_type_node
, buffer
, &chain
);
530 objc_finish_struct (type
, decls
);
532 aggregate_in_mem
[i
] = aggregate_value_p (type
, 0);
533 if (!aggregate_in_mem
[i
])
537 /* We found some structures that are returned in registers instead of memory
538 so output the necessary data. */
541 for (i
= 31; i
>= 0; i
--)
542 if (!aggregate_in_mem
[i
])
544 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
546 /* The first member of the structure is always 0 because we don't handle
547 structures with 0 members */
548 printf ("static int struct_forward_array[] = {\n 0");
550 for (j
= 1; j
<= i
; j
++)
551 printf (", %d", aggregate_in_mem
[j
]);
562 if (cxx_init () == false)
564 if (c_objc_common_init () == false)
568 /* If gen_declaration desired, open the output file. */
569 if (flag_gen_declaration
)
571 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
572 gen_declaration_file
= fopen (dumpname
, "w");
573 if (gen_declaration_file
== 0)
574 fatal_error ("can't open %s: %m", dumpname
);
578 if (flag_next_runtime
)
580 TAG_GETCLASS
= "objc_getClass";
581 TAG_GETMETACLASS
= "objc_getMetaClass";
582 TAG_MSGSEND
= "objc_msgSend";
583 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
584 TAG_MSGSEND_STRET
= "objc_msgSend_stret";
585 TAG_MSGSENDSUPER_STRET
= "objc_msgSendSuper_stret";
586 default_constant_string_class_name
= "NSConstantString";
590 TAG_GETCLASS
= "objc_get_class";
591 TAG_GETMETACLASS
= "objc_get_meta_class";
592 TAG_MSGSEND
= "objc_msg_lookup";
593 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
594 /* GNU runtime does not provide special functions to support
595 structure-returning methods. */
596 default_constant_string_class_name
= "NXConstantString";
597 flag_typed_selectors
= 1;
598 /* GNU runtime does not need the compiler to change code
599 in order to do GC. */
602 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
609 if (print_struct_values
&& !flag_compare_debug
)
610 generate_struct_by_value_array ();
615 /* This is called automatically (at the very end of compilation) by
616 c_write_global_declarations and cp_write_global_declarations. */
618 objc_write_global_declarations (void)
620 mark_referenced_methods ();
622 /* Finalize Objective-C runtime data. */
625 if (gen_declaration_file
)
626 fclose (gen_declaration_file
);
629 /* Return the first occurrence of a method declaration corresponding
630 to sel_name in rproto_list. Search rproto_list recursively.
631 If is_class is 0, search for instance methods, otherwise for class
634 lookup_method_in_protocol_list (tree rproto_list
, tree sel_name
,
640 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
642 p
= TREE_VALUE (rproto
);
644 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
646 if ((fnd
= lookup_method (is_class
647 ? PROTOCOL_CLS_METHODS (p
)
648 : PROTOCOL_NST_METHODS (p
), sel_name
)))
650 else if (PROTOCOL_LIST (p
))
651 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
656 ; /* An identifier...if we could not find a protocol. */
667 lookup_protocol_in_reflist (tree rproto_list
, tree lproto
)
671 /* Make sure the protocol is supported by the object on the rhs. */
672 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
675 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
677 p
= TREE_VALUE (rproto
);
679 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
684 else if (PROTOCOL_LIST (p
))
685 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
694 ; /* An identifier...if we could not find a protocol. */
701 objc_start_class_interface (tree klass
, tree super_class
,
702 tree protos
, tree attributes
)
705 warning_at (input_location
, OPT_Wattributes
,
706 "class attributes are not available in this version"
707 " of the compiler, (ignored)");
708 objc_interface_context
710 = start_class (CLASS_INTERFACE_TYPE
, klass
, super_class
, protos
);
711 objc_ivar_visibility
= OBJC_IVAR_VIS_PROTECTED
;
715 objc_start_category_interface (tree klass
, tree categ
,
716 tree protos
, tree attributes
)
719 warning_at (input_location
, OPT_Wattributes
,
720 "category attributes are not available in this version"
721 " of the compiler, (ignored)");
722 objc_interface_context
723 = start_class (CATEGORY_INTERFACE_TYPE
, klass
, categ
, protos
);
725 = continue_class (objc_interface_context
);
729 objc_start_protocol (tree name
, tree protos
, tree attributes
)
732 warning_at (input_location
, OPT_Wattributes
,
733 "protocol attributes are not available in this version"
734 " of the compiler, (ignored)");
735 objc_interface_context
736 = start_protocol (PROTOCOL_INTERFACE_TYPE
, name
, protos
);
737 objc_method_optional_flag
= false;
741 objc_continue_interface (void)
744 = continue_class (objc_interface_context
);
748 objc_finish_interface (void)
750 finish_class (objc_interface_context
);
751 objc_interface_context
= NULL_TREE
;
752 objc_method_optional_flag
= false;
756 objc_start_class_implementation (tree klass
, tree super_class
)
758 objc_implementation_context
760 = start_class (CLASS_IMPLEMENTATION_TYPE
, klass
, super_class
, NULL_TREE
);
761 objc_ivar_visibility
= OBJC_IVAR_VIS_PROTECTED
;
765 objc_start_category_implementation (tree klass
, tree categ
)
767 objc_implementation_context
768 = start_class (CATEGORY_IMPLEMENTATION_TYPE
, klass
, categ
, NULL_TREE
);
770 = continue_class (objc_implementation_context
);
774 objc_continue_implementation (void)
777 = continue_class (objc_implementation_context
);
781 objc_finish_implementation (void)
784 if (flag_objc_call_cxx_cdtors
)
785 objc_generate_cxx_cdtors ();
788 if (objc_implementation_context
)
790 finish_class (objc_implementation_context
);
791 objc_ivar_chain
= NULL_TREE
;
792 objc_implementation_context
= NULL_TREE
;
795 warning (0, "%<@end%> must appear in an @implementation context");
799 objc_set_visibility (objc_ivar_visibility_kind visibility
)
801 if (visibility
== OBJC_IVAR_VIS_PACKAGE
)
802 warning (0, "%<@package%> presently has the same effect as %<@public%>");
803 objc_ivar_visibility
= visibility
;
807 objc_set_method_opt (bool optional
)
809 objc_method_optional_flag
= optional
;
810 if (!objc_interface_context
811 || TREE_CODE (objc_interface_context
) != PROTOCOL_INTERFACE_TYPE
)
813 error ("@optional/@required is allowed in @protocol context only.");
814 objc_method_optional_flag
= false;
818 /* This routine gathers property attribute information from the attribute
819 portion of a property declaration. */
822 objc_set_property_attr (location_t loc
, objc_property_attribute_kind attr
,
825 static char string
[BUFSIZE
];
828 case OBJC_PATTR_INIT
: /* init */
829 property_readonly
= property_copies
= false;
830 property_setter
= property_getter
= property_ivar
= NULL_TREE
;
832 case OBJC_PATTR_READONLY
: /* readonly */
833 property_readonly
= true;
835 case OBJC_PATTR_GETTER
: /* getter = ident */
836 if (property_getter
!= NULL_TREE
)
837 error_at (loc
, "the %<getter%> attribute may only be specified once");
838 property_getter
= ident
;
840 case OBJC_PATTR_SETTER
: /* setter = ident */
841 if (property_setter
!= NULL_TREE
)
842 error_at (loc
, "the %<setter%> attribute may only be specified once");
843 /* setters always have a trailing ':' in their name. In fact, this is the
844 only syntax that parser recognizes for a setter name. Must add a trailing
845 ':' here so name matches that of the declaration of user instance method
847 sprintf (string
, "%s:", IDENTIFIER_POINTER (ident
));
848 property_setter
= get_identifier (string
);;
850 case OBJC_PATTR_IVAR
: /* ivar = ident */
851 if (property_ivar
!= NULL_TREE
)
852 error_at (loc
, "the %<ivar%> attribute may only be specified once");
853 else if (objc_interface_context
)
855 warning_at (loc
, 0, "the %<ivar%> attribute is ignored in an @interface");
856 property_ivar
= NULL_TREE
;
859 property_ivar
= ident
;
861 case OBJC_PATTR_COPIES
: /* copies */
862 property_copies
= true;
869 /* This routine builds a 'property_decl' tree node and adds it to the list
870 of such properties in the current class. It also checks for duplicates.
874 objc_add_property_variable (tree decl
)
878 tree interface
= NULL_TREE
;
880 if (objc_implementation_context
)
882 interface
= lookup_interface (CLASS_NAME (objc_implementation_context
));
885 error ("no class property can be implemented without an interface");
888 if (TREE_CODE (objc_implementation_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
890 interface
= lookup_category (interface
,
891 CLASS_SUPER_NAME (objc_implementation_context
));
894 error ("no category property can be implemented without an interface");
899 else if (!objc_interface_context
)
901 fatal_error ("property declaration not in @interface or @implementation context");
905 property_decl
= make_node (PROPERTY_DECL
);
906 TREE_TYPE (property_decl
) = TREE_TYPE (decl
);
908 PROPERTY_NAME (property_decl
) = DECL_NAME (decl
);
909 PROPERTY_GETTER_NAME (property_decl
) = property_getter
;
910 PROPERTY_SETTER_NAME (property_decl
) = property_setter
;
911 PROPERTY_IVAR_NAME (property_decl
) = property_ivar
;
912 PROPERTY_READONLY (property_decl
) = property_readonly
914 : boolean_false_node
;
915 PROPERTY_COPIES (property_decl
) = property_copies
917 : boolean_false_node
;
919 if (objc_interface_context
)
921 /* Doing the property in interface declaration. */
923 /* Issue error if property and an ivar name match. */
924 if (TREE_CODE (objc_interface_context
) == CLASS_INTERFACE_TYPE
925 && is_ivar (CLASS_IVARS (objc_interface_context
), DECL_NAME (decl
)))
926 error ("property %qD may not have the same name as an ivar in the class", decl
);
927 /* must check for duplicate property declarations. */
928 for (x
= CLASS_PROPERTY_DECL (objc_interface_context
); x
; x
= TREE_CHAIN (x
))
930 if (PROPERTY_NAME (x
) == DECL_NAME (decl
))
932 error ("duplicate property declaration %qD", decl
);
936 TREE_CHAIN (property_decl
) = CLASS_PROPERTY_DECL (objc_interface_context
);
937 CLASS_PROPERTY_DECL (objc_interface_context
) = property_decl
;
941 /* Doing the property in implementation context. */
942 /* If property is not declared in the interface issue error. */
943 for (x
= CLASS_PROPERTY_DECL (interface
); x
; x
= TREE_CHAIN (x
))
944 if (PROPERTY_NAME (x
) == DECL_NAME (decl
))
948 error ("no declaration of property %qD found in the interface", decl
);
951 /* readonlys must also match. */
952 if (PROPERTY_READONLY (x
) != PROPERTY_READONLY (property_decl
))
954 error ("property %qD %<readonly%> attribute conflicts with its"
955 " interface version", decl
);
957 /* copies must also match. */
958 if (PROPERTY_COPIES (x
) != PROPERTY_COPIES (property_decl
))
960 error ("property %qD %<copies%> attribute conflicts with its"
961 " interface version", decl
);
963 /* Cannot have readonly and setter attribute for the same property. */
964 if (PROPERTY_READONLY (property_decl
) == boolean_true_node
&&
965 PROPERTY_SETTER_NAME (property_decl
))
967 warning (0, "a %<readonly%> property cannot have a setter (ignored)");
968 PROPERTY_SETTER_NAME (property_decl
) = NULL_TREE
;
970 /* Add the property to the list of properties for current implementation. */
971 TREE_CHAIN (property_decl
) = IMPL_PROPERTY_DECL (objc_implementation_context
);
972 IMPL_PROPERTY_DECL (objc_implementation_context
) = property_decl
;
976 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
980 lookup_property_in_list (tree chain
, tree property
)
983 for (x
= CLASS_PROPERTY_DECL (chain
); x
; x
= TREE_CHAIN (x
))
984 if (PROPERTY_NAME (x
) == property
)
989 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
991 static tree
lookup_property_in_protocol_list (tree rproto_list
, tree property
)
994 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
996 tree p
= TREE_VALUE (rproto
);
997 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
999 if ((x
= lookup_property_in_list (p
, property
)))
1001 if (PROTOCOL_LIST (p
))
1002 return lookup_property_in_protocol_list (PROTOCOL_LIST (p
), property
);
1006 ; /* An identifier...if we could not find a protocol. */
1012 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
1013 chain of interface hierarchy.
1016 lookup_property (tree interface_type
, tree property
)
1018 tree inter
= interface_type
;
1022 if ((x
= lookup_property_in_list (inter
, property
)))
1024 /* Failing that, look for the property in each category of the class. */
1026 while ((category
= CLASS_CATEGORY_LIST (category
)))
1027 if ((x
= lookup_property_in_list (category
, property
)))
1030 /* Failing to find in categories, look for property in protocol list. */
1031 if (CLASS_PROTOCOL_LIST (inter
)
1032 && (x
= lookup_property_in_protocol_list (
1033 CLASS_PROTOCOL_LIST (inter
), property
)))
1036 /* Failing that, climb up the inheritance hierarchy. */
1037 inter
= lookup_interface (CLASS_SUPER_NAME (inter
));
1042 /* This routine recognizes a dot-notation for a propery reference and generates a call to
1043 the getter function for this property. In all other cases, it returns a NULL_TREE.
1047 objc_build_getter_call (tree receiver
, tree component
)
1052 if (receiver
== NULL_TREE
1053 || receiver
== error_mark_node
1054 || (rtype
= TREE_TYPE (receiver
)) == NULL_TREE
)
1057 if (component
== NULL_TREE
1058 || component
== error_mark_node
1059 || TREE_CODE (component
) != IDENTIFIER_NODE
)
1062 if (objc_is_id (rtype
))
1064 tree rprotos
= (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype
))
1065 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype
))
1068 x
= lookup_property_in_protocol_list (rprotos
, component
);
1072 tree basetype
= TYPE_MAIN_VARIANT (rtype
);
1074 if (basetype
!= NULL_TREE
&& TREE_CODE (basetype
) == POINTER_TYPE
)
1075 basetype
= TREE_TYPE (basetype
);
1079 while (basetype
!= NULL_TREE
1080 && TREE_CODE (basetype
) == RECORD_TYPE
1081 && OBJC_TYPE_NAME (basetype
)
1082 && TREE_CODE (OBJC_TYPE_NAME (basetype
)) == TYPE_DECL
1083 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype
)))
1084 basetype
= DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype
));
1086 if (basetype
!= NULL_TREE
&& TYPED_OBJECT (basetype
))
1088 tree interface_type
= TYPE_OBJC_INTERFACE (basetype
);
1089 if (!interface_type
)
1091 x
= lookup_property (interface_type
, component
);
1097 tree call_exp
, getter
;
1098 /* Get the getter name. */
1099 gcc_assert (PROPERTY_NAME (x
));
1100 getter
= objc_finish_message_expr (receiver
, PROPERTY_NAME (x
),
1104 /* In C++, a getter which returns an aggregate value results in a
1105 target_expr which initializes a temporary to the call expression. */
1106 if (TREE_CODE (getter
) == TARGET_EXPR
)
1108 gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter
)));
1109 gcc_assert (TREE_CODE (TREE_OPERAND (getter
,0)) == VAR_DECL
);
1110 call_exp
= TREE_OPERAND (getter
,1);
1113 gcc_assert (TREE_CODE (call_exp
) == CALL_EXPR
);
1115 CALL_EXPR_OBJC_PROPERTY_GETTER (call_exp
) = 1;
1121 /* This routine builds a call to property's 'setter' function. RECEIVER is the
1122 receiving object for 'setter'. PROPERTY_IDENT is name of the property and
1123 RHS is the argument passed to the 'setter' function. */
1126 objc_setter_func_call (tree receiver
, tree property_ident
, tree rhs
)
1128 tree setter_argument
= build_tree_list (NULL_TREE
, rhs
);
1129 char *setter_name
= objc_build_property_setter_name (property_ident
, true);
1131 in_objc_property_setter_name_context
= true;
1132 setter
= objc_finish_message_expr (receiver
, get_identifier (setter_name
),
1134 in_objc_property_setter_name_context
= false;
1138 /* Find the selector identifier from a reference. A somewhat tortuous way of
1139 obtaining the information to allow a setter to be written, given an
1143 get_selector_from_reference (tree selref
)
1147 if (flag_next_runtime
)
1149 /* Run through the selectors until we find the one we're looking for. */
1150 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1151 if (TREE_PURPOSE (chain
) == selref
)
1152 return TREE_VALUE (chain
);
1156 /* To find our way back to the selector for the GNU runtime is harder
1157 work, we need to decompose the representation of SELECTOR_TABLE[n]
1158 to find 'n'. This representation is in several forms. */
1159 if (TREE_CODE (selref
) == POINTER_PLUS_EXPR
)
1161 /* We need the element size to decode the array offset expression
1163 unsigned size
= (unsigned) TREE_INT_CST_LOW
1169 (TREE_OPERAND (selref
, 0), 0), 0)))));
1171 (unsigned) TREE_INT_CST_LOW (TREE_OPERAND (selref
, 1))
1173 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1175 return TREE_VALUE (chain
);
1177 else if (TREE_CODE (selref
) == NOP_EXPR
)
1179 /* Either we have a base an index, or we have just a base (when the
1181 if (TREE_CODE (TREE_OPERAND (selref
, 0)) == ADDR_EXPR
1184 (TREE_OPERAND (selref
, 0), 0)) == ARRAY_REF
)
1187 unsigned index
= (unsigned) TREE_INT_CST_LOW
1190 (TREE_OPERAND (selref
, 0), 0), 1));
1191 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1193 return TREE_VALUE (chain
);
1196 return TREE_VALUE (sel_ref_chain
);
1197 } /* Else we don't know how to figure this out - which will produce a
1198 parse error - saying that the LHS is not writeable. */
1203 /* This routine converts a previously synthesized 'getter' function call for
1204 a property and converts it to a 'setter' function call for the same
1208 objc_build_setter_call (tree lhs
, tree rhs
)
1211 && TREE_CODE (lhs
) == CALL_EXPR
1212 && CALL_EXPR_OBJC_PROPERTY_GETTER (lhs
))
1215 /* Get the Object. */
1216 tree receiver
= TREE_OPERAND (lhs
, 3);
1217 /* Get the selector reference. */
1218 tree selector_reference
= TREE_OPERAND (lhs
, 4);
1219 gcc_assert (receiver
&& selector_reference
);
1220 /* The style of the selector reference is different for GNU & NeXT. */
1221 selector
= get_selector_from_reference (selector_reference
);
1223 return objc_setter_func_call (receiver
, selector
, rhs
);
1228 /* This routine checks to see if ID is a property name. If so, it
1229 returns property declaration. */
1232 is_property (tree klass
, tree id
)
1236 for (x
= CLASS_PROPERTY_DECL (klass
); x
; x
= TREE_CHAIN (x
))
1237 if (PROPERTY_NAME (x
) == id
)
1242 /* This routine returns call to property's getter when a property is
1243 used stand-alone (without self. notation). */
1246 build_property_reference (tree property
, tree id
)
1249 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
1251 error ("property %qs accessed in class method",
1252 IDENTIFIER_POINTER (id
));
1253 return error_mark_node
;
1256 getter
= objc_finish_message_expr (self_decl
, PROPERTY_NAME (property
), NULL_TREE
);
1257 CALL_EXPR_OBJC_PROPERTY_GETTER (getter
) = 1;
1262 objc_build_method_signature (bool is_class_method
, tree rettype
, tree selector
,
1263 tree optparms
, bool ellipsis
)
1265 if (is_class_method
)
1266 return build_method_decl (CLASS_METHOD_DECL
, rettype
, selector
,
1267 optparms
, ellipsis
);
1269 return build_method_decl (INSTANCE_METHOD_DECL
, rettype
, selector
,
1270 optparms
, ellipsis
);
1274 objc_add_method_declaration (bool is_class_method
, tree decl
, tree attributes
)
1276 if (!objc_interface_context
)
1278 /* PS: At the moment, due to how the parser works, it should be
1279 impossible to get here. But it's good to have the check in
1280 case the parser changes.
1282 fatal_error ("method declaration not in @interface context");
1285 objc_decl_method_attributes (&decl
, attributes
, 0);
1286 objc_add_method (objc_interface_context
,
1289 objc_method_optional_flag
);
1292 /* Return 'true' if the method definition could be started, and
1293 'false' if not (because we are outside an @implementation context).
1296 objc_start_method_definition (bool is_class_method
, tree decl
, tree attributes
)
1298 if (!objc_implementation_context
)
1300 error ("method definition not in @implementation context");
1304 if (decl
!= NULL_TREE
&& METHOD_SEL_NAME (decl
) == error_mark_node
)
1308 /* Indicate no valid break/continue context by setting these variables
1309 to some non-null, non-label value. We'll notice and emit the proper
1310 error message in c_finish_bc_stmt. */
1311 c_break_label
= c_cont_label
= size_zero_node
;
1314 objc_decl_method_attributes (&decl
, attributes
, 0);
1315 objc_add_method (objc_implementation_context
,
1318 /* is optional */ false);
1319 start_method_def (decl
);
1324 objc_add_instance_variable (tree decl
)
1326 (void) add_instance_variable (objc_ivar_context
,
1327 objc_ivar_visibility
,
1331 /* Return true if TYPE is 'id'. */
1334 objc_is_object_id (tree type
)
1336 return OBJC_TYPE_NAME (type
) == objc_object_id
;
1340 objc_is_class_id (tree type
)
1342 return OBJC_TYPE_NAME (type
) == objc_class_id
;
1345 /* Construct a C struct with same name as KLASS, a base struct with tag
1346 SUPER_NAME (if any), and FIELDS indicated. */
1349 objc_build_struct (tree klass
, tree fields
, tree super_name
)
1351 tree name
= CLASS_NAME (klass
);
1352 tree s
= objc_start_struct (name
);
1353 tree super
= (super_name
? xref_tag (RECORD_TYPE
, super_name
) : NULL_TREE
);
1355 VEC(tree
,heap
) *objc_info
= NULL
;
1360 /* Prepend a packed variant of the base class into the layout. This
1361 is necessary to preserve ObjC ABI compatibility. */
1362 tree base
= build_decl (input_location
,
1363 FIELD_DECL
, NULL_TREE
, super
);
1364 tree field
= TYPE_FIELDS (super
);
1366 while (field
&& DECL_CHAIN (field
)
1367 && TREE_CODE (DECL_CHAIN (field
)) == FIELD_DECL
)
1368 field
= DECL_CHAIN (field
);
1370 /* For ObjC ABI purposes, the "packed" size of a base class is
1371 the sum of the offset and the size (in bits) of the last field
1374 = (field
&& TREE_CODE (field
) == FIELD_DECL
1375 ? size_binop (PLUS_EXPR
,
1376 size_binop (PLUS_EXPR
,
1379 convert (bitsizetype
,
1380 DECL_FIELD_OFFSET (field
)),
1381 bitsize_int (BITS_PER_UNIT
)),
1382 DECL_FIELD_BIT_OFFSET (field
)),
1384 : bitsize_zero_node
);
1385 DECL_SIZE_UNIT (base
)
1386 = size_binop (FLOOR_DIV_EXPR
, convert (sizetype
, DECL_SIZE (base
)),
1387 size_int (BITS_PER_UNIT
));
1388 DECL_ARTIFICIAL (base
) = 1;
1389 DECL_ALIGN (base
) = 1;
1390 DECL_FIELD_CONTEXT (base
) = s
;
1392 DECL_FIELD_IS_BASE (base
) = 1;
1395 TREE_NO_WARNING (fields
) = 1; /* Suppress C++ ABI warnings -- we */
1396 #endif /* are following the ObjC ABI here. */
1397 DECL_CHAIN (base
) = fields
;
1401 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
1402 in all variants of this RECORD_TYPE to be clobbered, but it is therein
1403 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
1404 Hence, we must squirrel away the ObjC-specific information before calling
1405 finish_struct(), and then reinstate it afterwards. */
1407 for (t
= TYPE_NEXT_VARIANT (s
); t
; t
= TYPE_NEXT_VARIANT (t
))
1409 if (!TYPE_HAS_OBJC_INFO (t
))
1411 INIT_TYPE_OBJC_INFO (t
);
1412 TYPE_OBJC_INTERFACE (t
) = klass
;
1414 VEC_safe_push (tree
, heap
, objc_info
, TYPE_OBJC_INFO (t
));
1417 /* Point the struct at its related Objective-C class. */
1418 INIT_TYPE_OBJC_INFO (s
);
1419 TYPE_OBJC_INTERFACE (s
) = klass
;
1421 s
= objc_finish_struct (s
, fields
);
1423 for (i
= 0, t
= TYPE_NEXT_VARIANT (s
); t
; t
= TYPE_NEXT_VARIANT (t
), i
++)
1425 TYPE_OBJC_INFO (t
) = VEC_index (tree
, objc_info
, i
);
1426 /* Replace the IDENTIFIER_NODE with an actual @interface. */
1427 TYPE_OBJC_INTERFACE (t
) = klass
;
1429 VEC_free (tree
, heap
, objc_info
);
1431 /* Use TYPE_BINFO structures to point at the super class, if any. */
1432 objc_xref_basetypes (s
, super
);
1434 /* Mark this struct as a class template. */
1435 CLASS_STATIC_TEMPLATE (klass
) = s
;
1440 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
1441 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
1444 objc_build_volatilized_type (tree type
)
1448 /* Check if we have not constructed the desired variant already. */
1449 for (t
= TYPE_MAIN_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
1451 /* The type qualifiers must (obviously) match up. */
1452 if (!TYPE_VOLATILE (t
)
1453 || (TYPE_READONLY (t
) != TYPE_READONLY (type
))
1454 || (TYPE_RESTRICT (t
) != TYPE_RESTRICT (type
)))
1457 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
1458 info, if any) must match up. */
1459 if (POINTER_TYPE_P (t
)
1460 && (TREE_TYPE (t
) != TREE_TYPE (type
)))
1463 /* Only match up the types which were previously volatilized in similar fashion and not
1464 because they were declared as such. */
1465 if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t
)))
1468 /* Everything matches up! */
1472 /* Ok, we could not re-use any of the pre-existing variants. Create
1474 t
= build_variant_type_copy (type
);
1475 TYPE_VOLATILE (t
) = 1;
1477 TYPE_ATTRIBUTES (t
) = merge_attributes (TYPE_ATTRIBUTES (type
),
1478 tree_cons (get_identifier ("objc_volatilized"),
1481 if (TREE_CODE (t
) == ARRAY_TYPE
)
1482 TREE_TYPE (t
) = objc_build_volatilized_type (TREE_TYPE (t
));
1484 /* Set up the canonical type information. */
1485 if (TYPE_STRUCTURAL_EQUALITY_P (type
))
1486 SET_TYPE_STRUCTURAL_EQUALITY (t
);
1487 else if (TYPE_CANONICAL (type
) != type
)
1488 TYPE_CANONICAL (t
) = objc_build_volatilized_type (TYPE_CANONICAL (type
));
1490 TYPE_CANONICAL (t
) = t
;
1495 /* Mark DECL as being 'volatile' for purposes of Darwin
1496 _setjmp()/_longjmp() exception handling. Called from
1497 objc_mark_locals_volatile(). */
1499 objc_volatilize_decl (tree decl
)
1501 /* Do not mess with variables that are 'static' or (already)
1503 if (!TREE_THIS_VOLATILE (decl
) && !TREE_STATIC (decl
)
1504 && (TREE_CODE (decl
) == VAR_DECL
1505 || TREE_CODE (decl
) == PARM_DECL
))
1507 tree t
= TREE_TYPE (decl
);
1509 t
= objc_build_volatilized_type (t
);
1511 TREE_TYPE (decl
) = t
;
1512 TREE_THIS_VOLATILE (decl
) = 1;
1513 TREE_SIDE_EFFECTS (decl
) = 1;
1514 DECL_REGISTER (decl
) = 0;
1516 C_DECL_REGISTER (decl
) = 0;
1521 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
1522 (including its categories and superclasses) or by object type TYP.
1523 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
1526 objc_lookup_protocol (tree proto
, tree cls
, tree typ
, bool warn
)
1528 bool class_type
= (cls
!= NULL_TREE
);
1534 /* Check protocols adopted by the class and its categories. */
1535 for (c
= cls
; c
; c
= CLASS_CATEGORY_LIST (c
))
1537 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c
), proto
))
1541 /* Repeat for superclasses. */
1542 cls
= lookup_interface (CLASS_SUPER_NAME (cls
));
1545 /* Check for any protocols attached directly to the object type. */
1546 if (TYPE_HAS_OBJC_INFO (typ
))
1548 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ
), proto
))
1555 gen_type_name_0 (class_type
? typ
: TYPE_POINTER_TO (typ
));
1556 /* NB: Types 'id' and 'Class' cannot reasonably be described as
1557 "implementing" a given protocol, since they do not have an
1560 warning (0, "class %qs does not implement the %qE protocol",
1561 identifier_to_locale (errbuf
), PROTOCOL_NAME (proto
));
1563 warning (0, "type %qs does not conform to the %qE protocol",
1564 identifier_to_locale (errbuf
), PROTOCOL_NAME (proto
));
1570 /* Check if class RCLS and instance struct type RTYP conform to at least the
1571 same protocols that LCLS and LTYP conform to. */
1574 objc_compare_protocols (tree lcls
, tree ltyp
, tree rcls
, tree rtyp
, bool warn
)
1577 bool have_lproto
= false;
1581 /* NB: We do _not_ look at categories defined for LCLS; these may or
1582 may not get loaded in, and therefore it is unreasonable to require
1583 that RCLS/RTYP must implement any of their protocols. */
1584 for (p
= CLASS_PROTOCOL_LIST (lcls
); p
; p
= TREE_CHAIN (p
))
1588 if (!objc_lookup_protocol (TREE_VALUE (p
), rcls
, rtyp
, warn
))
1592 /* Repeat for superclasses. */
1593 lcls
= lookup_interface (CLASS_SUPER_NAME (lcls
));
1596 /* Check for any protocols attached directly to the object type. */
1597 if (TYPE_HAS_OBJC_INFO (ltyp
))
1599 for (p
= TYPE_OBJC_PROTOCOL_LIST (ltyp
); p
; p
= TREE_CHAIN (p
))
1603 if (!objc_lookup_protocol (TREE_VALUE (p
), rcls
, rtyp
, warn
))
1608 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1609 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1610 away with simply checking for 'id' or 'Class' (!RCLS), since this
1611 routine will not get called in other cases. */
1612 return have_lproto
|| (rcls
!= NULL_TREE
);
1615 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
1616 Both TYPE1 and TYPE2 must be pointers, and already determined to be
1617 compatible by objc_compare_types() below. */
1620 objc_common_type (tree type1
, tree type2
)
1622 tree inner1
= TREE_TYPE (type1
), inner2
= TREE_TYPE (type2
);
1624 while (POINTER_TYPE_P (inner1
))
1626 inner1
= TREE_TYPE (inner1
);
1627 inner2
= TREE_TYPE (inner2
);
1630 /* If one type is derived from another, return the base type. */
1631 if (DERIVED_FROM_P (inner1
, inner2
))
1633 else if (DERIVED_FROM_P (inner2
, inner1
))
1636 /* If both types are 'Class', return 'Class'. */
1637 if (objc_is_class_id (inner1
) && objc_is_class_id (inner2
))
1638 return objc_class_type
;
1640 /* Otherwise, return 'id'. */
1641 return objc_object_type
;
1644 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1645 an instance of RTYP to an instance of LTYP or to compare the two
1646 (if ARGNO is equal to -3), per ObjC type system rules. Before
1647 returning 'true', this routine may issue warnings related to, e.g.,
1648 protocol conformance. When returning 'false', the routine must
1649 produce absolutely no warnings; the C or C++ front-end will do so
1650 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1651 the routine must return 'false'.
1653 The ARGNO parameter is encoded as follows:
1654 >= 1 Parameter number (CALLEE contains function being called);
1658 -3 Comparison (LTYP and RTYP may match in either direction);
1659 -4 Silent comparison (for C++ overload resolution).
1663 objc_compare_types (tree ltyp
, tree rtyp
, int argno
, tree callee
)
1665 tree lcls
, rcls
, lproto
, rproto
;
1666 bool pointers_compatible
;
1668 /* We must be dealing with pointer types */
1669 if (!POINTER_TYPE_P (ltyp
) || !POINTER_TYPE_P (rtyp
))
1674 ltyp
= TREE_TYPE (ltyp
); /* Remove indirections. */
1675 rtyp
= TREE_TYPE (rtyp
);
1677 while (POINTER_TYPE_P (ltyp
) && POINTER_TYPE_P (rtyp
));
1679 /* We must also handle function pointers, since ObjC is a bit more
1680 lenient than C or C++ on this. */
1681 if (TREE_CODE (ltyp
) == FUNCTION_TYPE
&& TREE_CODE (rtyp
) == FUNCTION_TYPE
)
1683 /* Return types must be covariant. */
1684 if (!comptypes (TREE_TYPE (ltyp
), TREE_TYPE (rtyp
))
1685 && !objc_compare_types (TREE_TYPE (ltyp
), TREE_TYPE (rtyp
),
1689 /* Argument types must be contravariant. */
1690 for (ltyp
= TYPE_ARG_TYPES (ltyp
), rtyp
= TYPE_ARG_TYPES (rtyp
);
1691 ltyp
&& rtyp
; ltyp
= TREE_CHAIN (ltyp
), rtyp
= TREE_CHAIN (rtyp
))
1693 if (!comptypes (TREE_VALUE (rtyp
), TREE_VALUE (ltyp
))
1694 && !objc_compare_types (TREE_VALUE (rtyp
), TREE_VALUE (ltyp
),
1699 return (ltyp
== rtyp
);
1702 /* Past this point, we are only interested in ObjC class instances,
1703 or 'id' or 'Class'. */
1704 if (TREE_CODE (ltyp
) != RECORD_TYPE
|| TREE_CODE (rtyp
) != RECORD_TYPE
)
1707 if (!objc_is_object_id (ltyp
) && !objc_is_class_id (ltyp
)
1708 && !TYPE_HAS_OBJC_INFO (ltyp
))
1711 if (!objc_is_object_id (rtyp
) && !objc_is_class_id (rtyp
)
1712 && !TYPE_HAS_OBJC_INFO (rtyp
))
1715 /* Past this point, we are committed to returning 'true' to the caller
1716 (unless performing a silent comparison; see below). However, we can
1717 still warn about type and/or protocol mismatches. */
1719 if (TYPE_HAS_OBJC_INFO (ltyp
))
1721 lcls
= TYPE_OBJC_INTERFACE (ltyp
);
1722 lproto
= TYPE_OBJC_PROTOCOL_LIST (ltyp
);
1725 lcls
= lproto
= NULL_TREE
;
1727 if (TYPE_HAS_OBJC_INFO (rtyp
))
1729 rcls
= TYPE_OBJC_INTERFACE (rtyp
);
1730 rproto
= TYPE_OBJC_PROTOCOL_LIST (rtyp
);
1733 rcls
= rproto
= NULL_TREE
;
1735 /* If we could not find an @interface declaration, we must have
1736 only seen a @class declaration; for purposes of type comparison,
1737 treat it as a stand-alone (root) class. */
1739 if (lcls
&& TREE_CODE (lcls
) == IDENTIFIER_NODE
)
1742 if (rcls
&& TREE_CODE (rcls
) == IDENTIFIER_NODE
)
1745 /* If either type is an unqualified 'id', we're done. */
1746 if ((!lproto
&& objc_is_object_id (ltyp
))
1747 || (!rproto
&& objc_is_object_id (rtyp
)))
1750 pointers_compatible
= (TYPE_MAIN_VARIANT (ltyp
) == TYPE_MAIN_VARIANT (rtyp
));
1752 /* If the underlying types are the same, and at most one of them has
1753 a protocol list, we do not need to issue any diagnostics. */
1754 if (pointers_compatible
&& (!lproto
|| !rproto
))
1757 /* If exactly one of the types is 'Class', issue a diagnostic; any
1758 exceptions of this rule have already been handled. */
1759 if (objc_is_class_id (ltyp
) ^ objc_is_class_id (rtyp
))
1760 pointers_compatible
= false;
1761 /* Otherwise, check for inheritance relations. */
1764 if (!pointers_compatible
)
1766 = (objc_is_object_id (ltyp
) || objc_is_object_id (rtyp
));
1768 if (!pointers_compatible
)
1769 pointers_compatible
= DERIVED_FROM_P (ltyp
, rtyp
);
1771 if (!pointers_compatible
&& argno
<= -3)
1772 pointers_compatible
= DERIVED_FROM_P (rtyp
, ltyp
);
1775 /* If the pointers match modulo protocols, check for protocol conformance
1777 if (pointers_compatible
)
1779 pointers_compatible
= objc_compare_protocols (lcls
, ltyp
, rcls
, rtyp
,
1782 if (!pointers_compatible
&& argno
== -3)
1783 pointers_compatible
= objc_compare_protocols (rcls
, rtyp
, lcls
, ltyp
,
1787 if (!pointers_compatible
)
1789 /* The two pointers are not exactly compatible. Issue a warning, unless
1790 we are performing a silent comparison, in which case return 'false'
1792 /* NB: For the time being, we shall make our warnings look like their
1793 C counterparts. In the future, we may wish to make them more
1801 warning (0, "comparison of distinct Objective-C types lacks a cast");
1805 warning (0, "initialization from distinct Objective-C type");
1809 warning (0, "assignment from distinct Objective-C type");
1813 warning (0, "distinct Objective-C type in return");
1817 warning (0, "passing argument %d of %qE from distinct "
1818 "Objective-C type", argno
, callee
);
1826 /* This routine is similar to objc_compare_types except that function-pointers are
1827 excluded. This is because, caller assumes that common types are of (id, Object*)
1828 variety and calls objc_common_type to obtain a common type. There is no commonolty
1829 between two function-pointers in this regard. */
1832 objc_have_common_type (tree ltyp
, tree rtyp
, int argno
, tree callee
)
1834 if (objc_compare_types (ltyp
, rtyp
, argno
, callee
))
1836 /* exclude function-pointer types. */
1839 ltyp
= TREE_TYPE (ltyp
); /* Remove indirections. */
1840 rtyp
= TREE_TYPE (rtyp
);
1842 while (POINTER_TYPE_P (ltyp
) && POINTER_TYPE_P (rtyp
));
1843 return !(TREE_CODE (ltyp
) == FUNCTION_TYPE
&& TREE_CODE (rtyp
) == FUNCTION_TYPE
);
1848 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1849 lives in the volatilized hash table, ignore the 'volatile' bit when
1850 making the comparison. */
1853 objc_type_quals_match (tree ltyp
, tree rtyp
)
1855 int lquals
= TYPE_QUALS (ltyp
), rquals
= TYPE_QUALS (rtyp
);
1857 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp
)))
1858 lquals
&= ~TYPE_QUAL_VOLATILE
;
1860 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp
)))
1861 rquals
&= ~TYPE_QUAL_VOLATILE
;
1863 return (lquals
== rquals
);
1867 /* Determine if CHILD is derived from PARENT. The routine assumes that
1868 both parameters are RECORD_TYPEs, and is non-reflexive. */
1871 objc_derived_from_p (tree parent
, tree child
)
1873 parent
= TYPE_MAIN_VARIANT (parent
);
1875 for (child
= TYPE_MAIN_VARIANT (child
);
1876 TYPE_BINFO (child
) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child
));)
1878 child
= TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1879 (TYPE_BINFO (child
),
1882 if (child
== parent
)
1891 objc_build_component_ref (tree datum
, tree component
)
1893 /* If COMPONENT is NULL, the caller is referring to the anonymous
1894 base class field. */
1897 tree base
= TYPE_FIELDS (TREE_TYPE (datum
));
1899 return build3 (COMPONENT_REF
, TREE_TYPE (base
), datum
, base
, NULL_TREE
);
1902 /* The 'build_component_ref' routine has been removed from the C++
1903 front-end, but 'finish_class_member_access_expr' seems to be
1904 a worthy substitute. */
1906 return finish_class_member_access_expr (datum
, component
, false,
1907 tf_warning_or_error
);
1909 return build_component_ref (input_location
, datum
, component
);
1913 /* Recursively copy inheritance information rooted at BINFO. To do this,
1914 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1917 objc_copy_binfo (tree binfo
)
1919 tree btype
= BINFO_TYPE (binfo
);
1920 tree binfo2
= make_tree_binfo (BINFO_N_BASE_BINFOS (binfo
));
1924 BINFO_TYPE (binfo2
) = btype
;
1925 BINFO_OFFSET (binfo2
) = BINFO_OFFSET (binfo
);
1926 BINFO_BASE_ACCESSES (binfo2
) = BINFO_BASE_ACCESSES (binfo
);
1928 /* Recursively copy base binfos of BINFO. */
1929 for (ix
= 0; BINFO_BASE_ITERATE (binfo
, ix
, base_binfo
); ix
++)
1931 tree base_binfo2
= objc_copy_binfo (base_binfo
);
1933 BINFO_INHERITANCE_CHAIN (base_binfo2
) = binfo2
;
1934 BINFO_BASE_APPEND (binfo2
, base_binfo2
);
1940 /* Record superclass information provided in BASETYPE for ObjC class REF.
1941 This is loosely based on cp/decl.c:xref_basetypes(). */
1944 objc_xref_basetypes (tree ref
, tree basetype
)
1946 tree binfo
= make_tree_binfo (basetype
? 1 : 0);
1948 TYPE_BINFO (ref
) = binfo
;
1949 BINFO_OFFSET (binfo
) = size_zero_node
;
1950 BINFO_TYPE (binfo
) = ref
;
1954 tree base_binfo
= objc_copy_binfo (TYPE_BINFO (basetype
));
1956 BINFO_INHERITANCE_CHAIN (base_binfo
) = binfo
;
1957 BINFO_BASE_ACCESSES (binfo
) = VEC_alloc (tree
, gc
, 1);
1958 BINFO_BASE_APPEND (binfo
, base_binfo
);
1959 BINFO_BASE_ACCESS_APPEND (binfo
, access_public_node
);
1963 /* Called from finish_decl. */
1966 objc_check_decl (tree decl
)
1968 tree type
= TREE_TYPE (decl
);
1970 if (TREE_CODE (type
) != RECORD_TYPE
)
1972 if (OBJC_TYPE_NAME (type
) && (type
= objc_is_class_name (OBJC_TYPE_NAME (type
))))
1973 error ("statically allocated instance of Objective-C class %qE",
1978 objc_check_global_decl (tree decl
)
1980 tree id
= DECL_NAME (decl
);
1981 if (objc_is_class_name (id
) && global_bindings_p())
1982 error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id
));
1985 /* Return a non-volatalized version of TYPE. */
1988 objc_non_volatilized_type (tree type
)
1990 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type
)))
1991 type
= build_qualified_type (type
, (TYPE_QUALS (type
) & ~TYPE_QUAL_VOLATILE
));
1995 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1996 either name an Objective-C class, or refer to the special 'id' or 'Class'
1997 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
2000 objc_get_protocol_qualified_type (tree interface
, tree protocols
)
2002 /* If INTERFACE is not provided, default to 'id'. */
2003 tree type
= (interface
? objc_is_id (interface
) : objc_object_type
);
2004 bool is_ptr
= (type
!= NULL_TREE
);
2008 type
= objc_is_class_name (interface
);
2012 /* If looking at a typedef, retrieve the precise type it
2014 if (TREE_CODE (interface
) == IDENTIFIER_NODE
)
2015 interface
= identifier_global_value (interface
);
2017 type
= ((interface
&& TREE_CODE (interface
) == TYPE_DECL
2018 && DECL_ORIGINAL_TYPE (interface
))
2019 ? DECL_ORIGINAL_TYPE (interface
)
2020 : xref_tag (RECORD_TYPE
, type
));
2028 type
= build_variant_type_copy (type
);
2030 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
2034 tree orig_pointee_type
= TREE_TYPE (type
);
2035 TREE_TYPE (type
) = build_variant_type_copy (orig_pointee_type
);
2037 /* Set up the canonical type information. */
2038 TYPE_CANONICAL (type
)
2039 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type
));
2041 TYPE_POINTER_TO (TREE_TYPE (type
)) = type
;
2042 type
= TREE_TYPE (type
);
2045 /* Look up protocols and install in lang specific list. */
2046 DUP_TYPE_OBJC_INFO (type
, TYPE_MAIN_VARIANT (type
));
2047 TYPE_OBJC_PROTOCOL_LIST (type
) = lookup_and_install_protocols (protocols
);
2049 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
2050 return the pointer to the new pointee variant. */
2052 type
= TYPE_POINTER_TO (type
);
2054 TYPE_OBJC_INTERFACE (type
)
2055 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type
));
2061 /* Check for circular dependencies in protocols. The arguments are
2062 PROTO, the protocol to check, and LIST, a list of protocol it
2066 check_protocol_recursively (tree proto
, tree list
)
2070 for (p
= list
; p
; p
= TREE_CHAIN (p
))
2072 tree pp
= TREE_VALUE (p
);
2074 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
2075 pp
= lookup_protocol (pp
);
2078 fatal_error ("protocol %qE has circular dependency",
2079 PROTOCOL_NAME (pp
));
2081 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
2085 /* Look up PROTOCOLS, and return a list of those that are found.
2086 If none are found, return NULL. */
2089 lookup_and_install_protocols (tree protocols
)
2092 tree return_value
= NULL_TREE
;
2094 if (protocols
== error_mark_node
)
2097 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
2099 tree ident
= TREE_VALUE (proto
);
2100 tree p
= lookup_protocol (ident
);
2103 return_value
= chainon (return_value
,
2104 build_tree_list (NULL_TREE
, p
));
2105 else if (ident
!= error_mark_node
)
2106 error ("cannot find protocol declaration for %qE",
2110 return return_value
;
2113 /* Create a declaration for field NAME of a given TYPE. */
2116 create_field_decl (tree type
, const char *name
)
2118 return build_decl (input_location
,
2119 FIELD_DECL
, get_identifier (name
), type
);
2122 /* Create a global, static declaration for variable NAME of a given TYPE. The
2123 finish_var_decl() routine will need to be called on it afterwards. */
2126 start_var_decl (tree type
, const char *name
)
2128 tree var
= build_decl (input_location
,
2129 VAR_DECL
, get_identifier (name
), type
);
2131 TREE_STATIC (var
) = 1;
2132 DECL_INITIAL (var
) = error_mark_node
; /* A real initializer is coming... */
2133 DECL_IGNORED_P (var
) = 1;
2134 DECL_ARTIFICIAL (var
) = 1;
2135 DECL_CONTEXT (var
) = NULL_TREE
;
2137 DECL_THIS_STATIC (var
) = 1; /* squash redeclaration errors */
2143 /* Finish off the variable declaration created by start_var_decl(). */
2146 finish_var_decl (tree var
, tree initializer
)
2148 finish_decl (var
, input_location
, initializer
, NULL_TREE
, NULL_TREE
);
2151 /* Find the decl for the constant string class reference. This is only
2152 used for the NeXT runtime. */
2155 setup_string_decl (void)
2160 /* %s in format will provide room for terminating null */
2161 length
= strlen (STRING_OBJECT_GLOBAL_FORMAT
)
2162 + strlen (constant_string_class_name
);
2163 name
= XNEWVEC (char, length
);
2164 sprintf (name
, STRING_OBJECT_GLOBAL_FORMAT
,
2165 constant_string_class_name
);
2166 constant_string_global_id
= get_identifier (name
);
2167 string_class_decl
= lookup_name (constant_string_global_id
);
2169 return string_class_decl
;
2172 /* Purpose: "play" parser, creating/installing representations
2173 of the declarations that are required by Objective-C.
2177 type_spec--------->sc_spec
2178 (tree_list) (tree_list)
2181 identifier_node identifier_node */
2184 synth_module_prologue (void)
2187 enum debug_info_type save_write_symbols
= write_symbols
;
2188 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
2190 /* Suppress outputting debug symbols, because
2191 dbxout_init hasn't been called yet. */
2192 write_symbols
= NO_DEBUG
;
2193 debug_hooks
= &do_nothing_debug_hooks
;
2196 push_lang_context (lang_name_c
); /* extern "C" */
2199 /* The following are also defined in <objc/objc.h> and friends. */
2201 objc_object_id
= get_identifier (TAG_OBJECT
);
2202 objc_class_id
= get_identifier (TAG_CLASS
);
2204 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
2205 objc_class_reference
= xref_tag (RECORD_TYPE
, objc_class_id
);
2207 objc_object_type
= build_pointer_type (objc_object_reference
);
2208 objc_class_type
= build_pointer_type (objc_class_reference
);
2210 objc_object_name
= get_identifier (OBJECT_TYPEDEF_NAME
);
2211 objc_class_name
= get_identifier (CLASS_TYPEDEF_NAME
);
2213 /* Declare the 'id' and 'Class' typedefs. */
2215 type
= lang_hooks
.decls
.pushdecl (build_decl (input_location
,
2219 TREE_NO_WARNING (type
) = 1;
2220 type
= lang_hooks
.decls
.pushdecl (build_decl (input_location
,
2224 TREE_NO_WARNING (type
) = 1;
2226 /* Forward-declare '@interface Protocol'. */
2228 type
= get_identifier (PROTOCOL_OBJECT_CLASS_NAME
);
2229 objc_declare_class (tree_cons (NULL_TREE
, type
, NULL_TREE
));
2230 objc_protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
2233 /* Declare type of selector-objects that represent an operation name. */
2235 if (flag_next_runtime
)
2236 /* `struct objc_selector *' */
2238 = build_pointer_type (xref_tag (RECORD_TYPE
,
2239 get_identifier (TAG_SELECTOR
)));
2241 /* `const struct objc_selector *' */
2243 = build_pointer_type
2244 (build_qualified_type (xref_tag (RECORD_TYPE
,
2245 get_identifier (TAG_SELECTOR
)),
2248 /* Declare receiver type used for dispatching messages to 'super'. */
2250 /* `struct objc_super *' */
2251 objc_super_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
2252 get_identifier (TAG_SUPER
)));
2254 /* Declare pointers to method and ivar lists. */
2255 objc_method_list_ptr
= build_pointer_type
2256 (xref_tag (RECORD_TYPE
,
2257 get_identifier (UTAG_METHOD_LIST
)));
2258 objc_method_proto_list_ptr
2259 = build_pointer_type (xref_tag (RECORD_TYPE
,
2260 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2261 objc_ivar_list_ptr
= build_pointer_type
2262 (xref_tag (RECORD_TYPE
,
2263 get_identifier (UTAG_IVAR_LIST
)));
2265 /* TREE_NOTHROW is cleared for the message-sending functions,
2266 because the function that gets called can throw in Obj-C++, or
2267 could itself call something that can throw even in Obj-C. */
2269 if (flag_next_runtime
)
2271 /* NB: In order to call one of the ..._stret (struct-returning)
2272 functions, the function *MUST* first be cast to a signature that
2273 corresponds to the actual ObjC method being invoked. This is
2274 what is done by the build_objc_method_call() routine below. */
2276 /* id objc_msgSend (id, SEL, ...); */
2277 /* id objc_msgSendNonNil (id, SEL, ...); */
2278 /* id objc_msgSend_stret (id, SEL, ...); */
2279 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
2281 = build_varargs_function_type_list (objc_object_type
,
2285 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
2286 type
, 0, NOT_BUILT_IN
,
2288 umsg_nonnil_decl
= add_builtin_function (TAG_MSGSEND_NONNIL
,
2289 type
, 0, NOT_BUILT_IN
,
2291 umsg_stret_decl
= add_builtin_function (TAG_MSGSEND_STRET
,
2292 type
, 0, NOT_BUILT_IN
,
2294 umsg_nonnil_stret_decl
= add_builtin_function (TAG_MSGSEND_NONNIL_STRET
,
2295 type
, 0, NOT_BUILT_IN
,
2298 /* These can throw, because the function that gets called can throw
2299 in Obj-C++, or could itself call something that can throw even
2301 TREE_NOTHROW (umsg_decl
) = 0;
2302 TREE_NOTHROW (umsg_nonnil_decl
) = 0;
2303 TREE_NOTHROW (umsg_stret_decl
) = 0;
2304 TREE_NOTHROW (umsg_nonnil_stret_decl
) = 0;
2306 /* id objc_msgSend_Fast (id, SEL, ...)
2307 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
2308 #ifdef OFFS_MSGSEND_FAST
2309 umsg_fast_decl
= add_builtin_function (TAG_MSGSEND_FAST
,
2310 type
, 0, NOT_BUILT_IN
,
2312 TREE_NOTHROW (umsg_fast_decl
) = 0;
2313 DECL_ATTRIBUTES (umsg_fast_decl
)
2314 = tree_cons (get_identifier ("hard_coded_address"),
2315 build_int_cst (NULL_TREE
, OFFS_MSGSEND_FAST
),
2318 /* No direct dispatch available. */
2319 umsg_fast_decl
= umsg_decl
;
2322 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
2323 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
2325 = build_varargs_function_type_list (objc_object_type
,
2329 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
2330 type
, 0, NOT_BUILT_IN
,
2332 umsg_super_stret_decl
= add_builtin_function (TAG_MSGSENDSUPER_STRET
,
2333 type
, 0, NOT_BUILT_IN
, 0,
2335 TREE_NOTHROW (umsg_super_decl
) = 0;
2336 TREE_NOTHROW (umsg_super_stret_decl
) = 0;
2340 /* GNU runtime messenger entry points. */
2342 /* typedef id (*IMP)(id, SEL, ...); */
2344 build_varargs_function_type_list (objc_object_type
,
2348 tree IMP_type
= build_pointer_type (ftype
);
2350 /* IMP objc_msg_lookup (id, SEL); */
2351 type
= build_function_type_list (IMP_type
,
2355 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
2356 type
, 0, NOT_BUILT_IN
,
2358 TREE_NOTHROW (umsg_decl
) = 0;
2360 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
2362 = build_function_type_list (IMP_type
,
2366 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
2367 type
, 0, NOT_BUILT_IN
,
2369 TREE_NOTHROW (umsg_super_decl
) = 0;
2371 /* The following GNU runtime entry point is called to initialize
2374 __objc_exec_class (void *); */
2376 = build_function_type_list (void_type_node
,
2379 execclass_decl
= add_builtin_function (TAG_EXECCLASS
,
2380 type
, 0, NOT_BUILT_IN
,
2384 /* id objc_getClass (const char *); */
2386 type
= build_function_type_list (objc_object_type
,
2387 const_string_type_node
,
2391 = add_builtin_function (TAG_GETCLASS
, type
, 0, NOT_BUILT_IN
,
2394 /* id objc_getMetaClass (const char *); */
2396 objc_get_meta_class_decl
2397 = add_builtin_function (TAG_GETMETACLASS
, type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
2399 build_class_template ();
2400 build_super_template ();
2401 build_protocol_template ();
2402 build_category_template ();
2403 build_objc_exception_stuff ();
2405 if (flag_next_runtime
)
2406 build_next_objc_exception_stuff ();
2408 /* static SEL _OBJC_SELECTOR_TABLE[]; */
2410 if (! flag_next_runtime
)
2411 build_selector_table_decl ();
2413 /* Forward declare constant_string_id and constant_string_type. */
2414 if (!constant_string_class_name
)
2415 constant_string_class_name
= default_constant_string_class_name
;
2417 constant_string_id
= get_identifier (constant_string_class_name
);
2418 objc_declare_class (tree_cons (NULL_TREE
, constant_string_id
, NULL_TREE
));
2420 /* Pre-build the following entities - for speed/convenience. */
2421 self_id
= get_identifier ("self");
2422 ucmd_id
= get_identifier ("_cmd");
2424 /* Declare struct _objc_fast_enumeration_state { ... }; */
2425 build_fast_enumeration_state_template ();
2427 /* void objc_enumeration_mutation (id) */
2428 type
= build_function_type (void_type_node
,
2429 tree_cons (NULL_TREE
, objc_object_type
, NULL_TREE
));
2430 objc_enumeration_mutation_decl
2431 = add_builtin_function (TAG_ENUMERATION_MUTATION
, type
, 0, NOT_BUILT_IN
,
2433 TREE_NOTHROW (objc_enumeration_mutation_decl
) = 0;
2436 pop_lang_context ();
2439 write_symbols
= save_write_symbols
;
2440 debug_hooks
= save_hooks
;
2443 /* Ensure that the ivar list for NSConstantString/NXConstantString
2444 (or whatever was specified via `-fconstant-string-class')
2445 contains fields at least as large as the following three, so that
2446 the runtime can stomp on them with confidence:
2448 struct STRING_OBJECT_CLASS_NAME
2452 unsigned int length;
2456 check_string_class_template (void)
2458 tree field_decl
= objc_get_class_ivars (constant_string_id
);
2460 #define AT_LEAST_AS_LARGE_AS(F, T) \
2461 (F && TREE_CODE (F) == FIELD_DECL \
2462 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
2463 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
2465 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
2468 field_decl
= DECL_CHAIN (field_decl
);
2469 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
2472 field_decl
= DECL_CHAIN (field_decl
);
2473 return AT_LEAST_AS_LARGE_AS (field_decl
, unsigned_type_node
);
2475 #undef AT_LEAST_AS_LARGE_AS
2478 /* Avoid calling `check_string_class_template ()' more than once. */
2479 static GTY(()) int string_layout_checked
;
2481 /* Construct an internal string layout to be used as a template for
2482 creating NSConstantString/NXConstantString instances. */
2485 objc_build_internal_const_str_type (void)
2487 tree type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
2488 tree fields
= build_decl (input_location
,
2489 FIELD_DECL
, NULL_TREE
, ptr_type_node
);
2490 tree field
= build_decl (input_location
,
2491 FIELD_DECL
, NULL_TREE
, ptr_type_node
);
2493 DECL_CHAIN (field
) = fields
; fields
= field
;
2494 field
= build_decl (input_location
,
2495 FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
2496 DECL_CHAIN (field
) = fields
; fields
= field
;
2497 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
2499 finish_builtin_struct (type
, "__builtin_ObjCString",
2505 /* Custom build_string which sets TREE_TYPE! */
2508 my_build_string (int len
, const char *str
)
2510 return fix_string_type (build_string (len
, str
));
2513 /* Build a string with contents STR and length LEN and convert it to a
2517 my_build_string_pointer (int len
, const char *str
)
2519 tree string
= my_build_string (len
, str
);
2520 tree ptrtype
= build_pointer_type (TREE_TYPE (TREE_TYPE (string
)));
2521 return build1 (ADDR_EXPR
, ptrtype
, string
);
2525 string_hash (const void *ptr
)
2527 const_tree
const str
= ((const struct string_descriptor
*)ptr
)->literal
;
2528 const unsigned char *p
= (const unsigned char *) TREE_STRING_POINTER (str
);
2529 int i
, len
= TREE_STRING_LENGTH (str
);
2532 for (i
= 0; i
< len
; i
++)
2533 h
= ((h
* 613) + p
[i
]);
2539 string_eq (const void *ptr1
, const void *ptr2
)
2541 const_tree
const str1
= ((const struct string_descriptor
*)ptr1
)->literal
;
2542 const_tree
const str2
= ((const struct string_descriptor
*)ptr2
)->literal
;
2543 int len1
= TREE_STRING_LENGTH (str1
);
2545 return (len1
== TREE_STRING_LENGTH (str2
)
2546 && !memcmp (TREE_STRING_POINTER (str1
), TREE_STRING_POINTER (str2
),
2550 /* Given a chain of STRING_CST's, build a static instance of
2551 NXConstantString which points at the concatenation of those
2552 strings. We place the string object in the __string_objects
2553 section of the __OBJC segment. The Objective-C runtime will
2554 initialize the isa pointers of the string objects to point at the
2555 NXConstantString class object. */
2558 objc_build_string_object (tree string
)
2560 tree constant_string_class
;
2563 struct string_descriptor
*desc
, key
;
2566 /* Prep the string argument. */
2567 string
= fix_string_type (string
);
2568 TREE_SET_CODE (string
, STRING_CST
);
2569 length
= TREE_STRING_LENGTH (string
) - 1;
2571 /* The target may have different ideas on how to construct an ObjC string
2572 literal. On Darwin (Mac OS X), for example, we may wish to obtain a
2573 constant CFString reference instead.
2574 At present, this is only supported for the NeXT runtime. */
2575 if (flag_next_runtime
&& targetcm
.objc_construct_string
)
2577 tree constructor
= (*targetcm
.objc_construct_string
) (string
);
2579 return build1 (NOP_EXPR
, objc_object_type
, constructor
);
2582 /* Check whether the string class being used actually exists and has the
2583 correct ivar layout. */
2584 if (!string_layout_checked
)
2586 string_layout_checked
= -1;
2587 constant_string_class
= lookup_interface (constant_string_id
);
2588 internal_const_str_type
= objc_build_internal_const_str_type ();
2590 if (!constant_string_class
2591 || !(constant_string_type
2592 = CLASS_STATIC_TEMPLATE (constant_string_class
)))
2593 error ("cannot find interface declaration for %qE",
2594 constant_string_id
);
2595 /* The NSConstantString/NXConstantString ivar layout is now known. */
2596 else if (!check_string_class_template ())
2597 error ("interface %qE does not have valid constant string layout",
2598 constant_string_id
);
2599 /* For the NeXT runtime, we can generate a literal reference
2600 to the string class, don't need to run a constructor. */
2601 else if (flag_next_runtime
&& !setup_string_decl ())
2602 error ("cannot find reference tag for class %qE",
2603 constant_string_id
);
2606 string_layout_checked
= 1; /* Success! */
2607 add_class_reference (constant_string_id
);
2611 if (string_layout_checked
== -1)
2612 return error_mark_node
;
2614 /* Perhaps we already constructed a constant string just like this one? */
2615 key
.literal
= string
;
2616 loc
= htab_find_slot (string_htab
, &key
, INSERT
);
2617 desc
= (struct string_descriptor
*) *loc
;
2621 tree var
, constructor
;
2622 VEC(constructor_elt
,gc
) *v
= NULL
;
2623 *loc
= desc
= ggc_alloc_string_descriptor ();
2624 desc
->literal
= string
;
2626 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
2627 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
2628 fields
= TYPE_FIELDS (internal_const_str_type
);
2629 CONSTRUCTOR_APPEND_ELT (v
, fields
,
2631 ? build_unary_op (input_location
,
2632 ADDR_EXPR
, string_class_decl
, 0)
2633 : build_int_cst (NULL_TREE
, 0));
2634 fields
= DECL_CHAIN (fields
);
2635 CONSTRUCTOR_APPEND_ELT (v
, fields
,
2636 build_unary_op (input_location
,
2637 ADDR_EXPR
, string
, 1));
2638 fields
= DECL_CHAIN (fields
);
2639 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_int_cst (NULL_TREE
, length
));
2640 constructor
= objc_build_constructor (internal_const_str_type
, v
);
2642 if (!flag_next_runtime
)
2644 = objc_add_static_instance (constructor
, constant_string_type
);
2647 var
= build_decl (input_location
,
2648 CONST_DECL
, NULL
, TREE_TYPE (constructor
));
2649 DECL_INITIAL (var
) = constructor
;
2650 TREE_STATIC (var
) = 1;
2651 pushdecl_top_level (var
);
2654 desc
->constructor
= constructor
;
2657 addr
= convert (build_pointer_type (constant_string_type
),
2658 build_unary_op (input_location
,
2659 ADDR_EXPR
, desc
->constructor
, 1));
2664 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
2666 static GTY(()) int num_static_inst
;
2669 objc_add_static_instance (tree constructor
, tree class_decl
)
2674 /* Find the list of static instances for the CLASS_DECL. Create one if
2676 for (chain
= &objc_static_instances
;
2677 *chain
&& TREE_VALUE (*chain
) != class_decl
;
2678 chain
= &TREE_CHAIN (*chain
));
2681 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
2682 add_objc_string (OBJC_TYPE_NAME (class_decl
), class_names
);
2685 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
2686 decl
= build_decl (input_location
,
2687 VAR_DECL
, get_identifier (buf
), class_decl
);
2688 TREE_STATIC (decl
) = 1;
2689 DECL_ARTIFICIAL (decl
) = 1;
2690 TREE_USED (decl
) = 1;
2691 DECL_INITIAL (decl
) = constructor
;
2693 /* We may be writing something else just now.
2694 Postpone till end of input. */
2695 DECL_DEFER_OUTPUT (decl
) = 1;
2696 pushdecl_top_level (decl
);
2697 rest_of_decl_compilation (decl
, 1, 0);
2699 /* Add the DECL to the head of this CLASS' list. */
2700 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
2705 /* Build a static constant CONSTRUCTOR
2706 with type TYPE and elements ELTS. */
2709 objc_build_constructor (tree type
, VEC(constructor_elt
,gc
) *elts
)
2711 tree constructor
= build_constructor (type
, elts
);
2713 TREE_CONSTANT (constructor
) = 1;
2714 TREE_STATIC (constructor
) = 1;
2715 TREE_READONLY (constructor
) = 1;
2718 /* Adjust for impedance mismatch. We should figure out how to build
2719 CONSTRUCTORs that consistently please both the C and C++ gods. */
2720 if (!VEC_index (constructor_elt
, elts
, 0)->index
)
2721 TREE_TYPE (constructor
) = init_list_type_node
;
2727 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2729 /* Predefine the following data type:
2737 void *defs[cls_def_cnt + cat_def_cnt];
2741 build_objc_symtab_template (void)
2743 tree fields
, *chain
= NULL
;
2745 objc_symtab_template
= objc_start_struct (get_identifier (UTAG_SYMTAB
));
2747 /* long sel_ref_cnt; */
2748 fields
= add_field_decl (long_integer_type_node
, "sel_ref_cnt", &chain
);
2751 add_field_decl (build_pointer_type (objc_selector_type
), "refs", &chain
);
2753 /* short cls_def_cnt; */
2754 add_field_decl (short_integer_type_node
, "cls_def_cnt", &chain
);
2756 /* short cat_def_cnt; */
2757 add_field_decl (short_integer_type_node
, "cat_def_cnt", &chain
);
2759 if (imp_count
|| cat_count
|| !flag_next_runtime
)
2761 /* void *defs[imp_count + cat_count (+ 1)]; */
2762 /* NB: The index is one less than the size of the array. */
2763 int index
= imp_count
+ cat_count
+ (flag_next_runtime
? -1: 0);
2764 tree array_type
= build_sized_array_type (ptr_type_node
, index
+ 1);
2765 add_field_decl (array_type
, "defs", &chain
);
2768 objc_finish_struct (objc_symtab_template
, fields
);
2771 /* Create the initial value for the `defs' field of _objc_symtab.
2772 This is a CONSTRUCTOR. */
2775 init_def_list (tree type
)
2778 struct imp_entry
*impent
;
2779 VEC(constructor_elt
,gc
) *v
= NULL
;
2782 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2784 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
2786 expr
= build_unary_op (input_location
,
2787 ADDR_EXPR
, impent
->class_decl
, 0);
2788 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2793 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2795 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
2797 expr
= build_unary_op (input_location
,
2798 ADDR_EXPR
, impent
->class_decl
, 0);
2799 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2803 if (!flag_next_runtime
)
2805 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2806 if (static_instances_decl
)
2807 expr
= build_unary_op (input_location
,
2808 ADDR_EXPR
, static_instances_decl
, 0);
2810 expr
= integer_zero_node
;
2812 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2815 return objc_build_constructor (type
, v
);
2818 /* Construct the initial value for all of _objc_symtab. */
2821 init_objc_symtab (tree type
)
2823 VEC(constructor_elt
,gc
) *v
= NULL
;
2825 /* sel_ref_cnt = { ..., 5, ... } */
2827 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2828 build_int_cst (long_integer_type_node
, 0));
2830 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2832 if (flag_next_runtime
|| ! sel_ref_chain
)
2833 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, convert (
2834 build_pointer_type (objc_selector_type
),
2835 integer_zero_node
));
2838 tree expr
= build_unary_op (input_location
, ADDR_EXPR
,
2839 UOBJC_SELECTOR_TABLE_decl
, 1);
2841 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2842 convert (build_pointer_type (objc_selector_type
),
2846 /* cls_def_cnt = { ..., 5, ... } */
2848 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2849 build_int_cst (short_integer_type_node
, imp_count
));
2851 /* cat_def_cnt = { ..., 5, ... } */
2853 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2854 build_int_cst (short_integer_type_node
, cat_count
));
2856 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2858 if (imp_count
|| cat_count
|| !flag_next_runtime
)
2861 tree field
= TYPE_FIELDS (type
);
2862 field
= DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field
))));
2864 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, init_def_list (TREE_TYPE (field
)));
2867 return objc_build_constructor (type
, v
);
2870 /* Generate forward declarations for metadata such as
2871 'OBJC_CLASS_...'. */
2874 build_metadata_decl (const char *name
, tree type
)
2878 /* struct TYPE NAME_<name>; */
2879 decl
= start_var_decl (type
, synth_id_with_class_suffix
2881 objc_implementation_context
));
2886 /* Push forward-declarations of all the categories so that
2887 init_def_list can use them in a CONSTRUCTOR. */
2890 forward_declare_categories (void)
2892 struct imp_entry
*impent
;
2893 tree sav
= objc_implementation_context
;
2895 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2897 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
2899 /* Set an invisible arg to synth_id_with_class_suffix. */
2900 objc_implementation_context
= impent
->imp_context
;
2901 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2902 impent
->class_decl
= build_metadata_decl ("_OBJC_CATEGORY",
2903 objc_category_template
);
2906 objc_implementation_context
= sav
;
2909 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2910 and initialized appropriately. */
2913 generate_objc_symtab_decl (void)
2916 build_objc_symtab_template ();
2917 UOBJC_SYMBOLS_decl
= start_var_decl (objc_symtab_template
, "_OBJC_SYMBOLS");
2918 finish_var_decl (UOBJC_SYMBOLS_decl
,
2919 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)));
2923 init_module_descriptor (tree type
)
2926 VEC(constructor_elt
,gc
) *v
= NULL
;
2928 /* version = { 1, ... } */
2930 expr
= build_int_cst (long_integer_type_node
, OBJC_VERSION
);
2931 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2933 /* size = { ..., sizeof (struct _objc_module), ... } */
2935 expr
= convert (long_integer_type_node
,
2936 size_in_bytes (objc_module_template
));
2937 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2939 /* Don't provide any file name for security reasons. */
2940 /* name = { ..., "", ... } */
2942 expr
= add_objc_string (get_identifier (""), class_names
);
2943 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2945 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2947 if (UOBJC_SYMBOLS_decl
)
2948 expr
= build_unary_op (input_location
,
2949 ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
2951 expr
= null_pointer_node
;
2952 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2954 return objc_build_constructor (type
, v
);
2957 /* Write out the data structures to describe Objective C classes defined.
2959 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2962 build_module_descriptor (void)
2964 tree decls
, *chain
= NULL
;
2967 push_lang_context (lang_name_c
); /* extern "C" */
2970 objc_module_template
= objc_start_struct (get_identifier (UTAG_MODULE
));
2973 decls
= add_field_decl (long_integer_type_node
, "version", &chain
);
2976 add_field_decl (long_integer_type_node
, "size", &chain
);
2979 add_field_decl (string_type_node
, "name", &chain
);
2981 /* struct _objc_symtab *symtab; */
2982 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE
,
2983 get_identifier (UTAG_SYMTAB
))),
2986 objc_finish_struct (objc_module_template
, decls
);
2988 /* Create an instance of "_objc_module". */
2989 UOBJC_MODULES_decl
= start_var_decl (objc_module_template
, "_OBJC_MODULES");
2990 /* This is the root of the metadata for defined classes and categories, it
2991 is referenced by the runtime and, therefore, needed. */
2992 DECL_PRESERVE_P (UOBJC_MODULES_decl
) = 1;
2993 finish_var_decl (UOBJC_MODULES_decl
,
2994 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)));
2997 pop_lang_context ();
3001 /* The GNU runtime requires us to provide a static initializer function
3004 static void __objc_gnu_init (void) {
3005 __objc_exec_class (&L_OBJC_MODULES);
3009 build_module_initializer_routine (void)
3014 push_lang_context (lang_name_c
); /* extern "C" */
3017 objc_push_parm (build_decl (input_location
,
3018 PARM_DECL
, NULL_TREE
, void_type_node
));
3020 objc_start_function (get_identifier (TAG_GNUINIT
),
3021 build_function_type_list (void_type_node
, NULL_TREE
),
3022 NULL_TREE
, NULL_TREE
);
3024 objc_start_function (get_identifier (TAG_GNUINIT
),
3025 build_function_type_list (void_type_node
, NULL_TREE
),
3026 NULL_TREE
, objc_get_parm_info (0));
3028 body
= c_begin_compound_stmt (true);
3029 add_stmt (build_function_call
3034 build_unary_op (input_location
, ADDR_EXPR
,
3035 UOBJC_MODULES_decl
, 0))));
3036 add_stmt (c_end_compound_stmt (input_location
, body
, true));
3038 TREE_PUBLIC (current_function_decl
) = 0;
3041 /* For Objective-C++, we will need to call __objc_gnu_init
3042 from objc_generate_static_init_call() below. */
3043 DECL_STATIC_CONSTRUCTOR (current_function_decl
) = 1;
3046 GNU_INIT_decl
= current_function_decl
;
3050 pop_lang_context ();
3055 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
3056 to be called by the module initializer routine. */
3059 objc_static_init_needed_p (void)
3061 return (GNU_INIT_decl
!= NULL_TREE
);
3064 /* Generate a call to the __objc_gnu_init initializer function. */
3067 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED
)
3069 add_stmt (build_stmt (input_location
, EXPR_STMT
,
3070 build_function_call (input_location
,
3071 GNU_INIT_decl
, NULL_TREE
)));
3075 #endif /* OBJCPLUS */
3077 /* Return the DECL of the string IDENT in the SECTION. */
3080 get_objc_string_decl (tree ident
, enum string_section section
)
3087 chain
= class_names_chain
;
3089 case meth_var_names
:
3090 chain
= meth_var_names_chain
;
3092 case meth_var_types
:
3093 chain
= meth_var_types_chain
;
3099 for (; chain
!= 0; chain
= TREE_CHAIN (chain
))
3100 if (TREE_VALUE (chain
) == ident
)
3101 return (TREE_PURPOSE (chain
));
3107 /* Output references to all statically allocated objects. Return the DECL
3108 for the array built. */
3111 generate_static_references (void)
3113 tree expr
= NULL_TREE
;
3114 tree class_name
, klass
, decl
;
3115 tree cl_chain
, in_chain
, type
3116 = build_array_type (build_pointer_type (void_type_node
), NULL_TREE
);
3117 int num_inst
, num_class
;
3119 VEC(constructor_elt
,gc
) *decls
= NULL
;
3121 if (flag_next_runtime
)
3124 for (cl_chain
= objc_static_instances
, num_class
= 0;
3125 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
3127 VEC(constructor_elt
,gc
) *v
= NULL
;
3129 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
3130 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
3132 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
3133 decl
= start_var_decl (type
, buf
);
3135 /* Output {class_name, ...}. */
3136 klass
= TREE_VALUE (cl_chain
);
3137 class_name
= get_objc_string_decl (OBJC_TYPE_NAME (klass
), class_names
);
3138 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
3139 build_unary_op (input_location
,
3140 ADDR_EXPR
, class_name
, 1));
3142 /* Output {..., instance, ...}. */
3143 for (in_chain
= TREE_PURPOSE (cl_chain
);
3144 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
3146 expr
= build_unary_op (input_location
,
3147 ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
3148 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
3151 /* Output {..., NULL}. */
3152 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
3154 expr
= objc_build_constructor (TREE_TYPE (decl
), v
);
3155 finish_var_decl (decl
, expr
);
3156 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
,
3157 build_unary_op (input_location
,
3158 ADDR_EXPR
, decl
, 1));
3161 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
3162 expr
= objc_build_constructor (type
, decls
);
3163 static_instances_decl
= start_var_decl (type
, "_OBJC_STATIC_INSTANCES");
3164 finish_var_decl (static_instances_decl
, expr
);
3167 static GTY(()) int selector_reference_idx
;
3170 build_selector_reference_decl (void)
3175 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx
++);
3176 decl
= start_var_decl (objc_selector_type
, buf
);
3182 build_selector_table_decl (void)
3186 if (flag_typed_selectors
)
3188 build_selector_template ();
3189 temp
= build_array_type (objc_selector_template
, NULL_TREE
);
3192 temp
= build_array_type (objc_selector_type
, NULL_TREE
);
3194 UOBJC_SELECTOR_TABLE_decl
= start_var_decl (temp
, "_OBJC_SELECTOR_TABLE");
3197 /* Just a handy wrapper for add_objc_string. */
3200 build_selector (tree ident
)
3202 return convert (objc_selector_type
,
3203 add_objc_string (ident
, meth_var_names
));
3206 /* Used only by build_*_selector_translation_table (). */
3208 diagnose_missing_method (tree meth
, location_t here
)
3212 for (method_chain
= meth_var_names_chain
;
3214 method_chain
= TREE_CHAIN (method_chain
))
3216 if (TREE_VALUE (method_chain
) == meth
)
3224 warning_at (here
, 0, "creating selector for nonexistent method %qE",
3229 build_next_selector_translation_table (void)
3232 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
3235 tree decl
= TREE_PURPOSE (chain
);
3236 if (warn_selector
&& objc_implementation_context
)
3240 loc
= DECL_SOURCE_LOCATION (decl
);
3242 loc
= input_location
;
3243 diagnose_missing_method (TREE_VALUE (chain
), loc
);
3246 expr
= build_selector (TREE_VALUE (chain
));
3250 /* Entries of this form are used for references to methods.
3251 The runtime re-writes these on start-up, but the compiler can't see
3252 that and optimizes it away unless we force it. */
3253 DECL_PRESERVE_P (decl
) = 1;
3254 finish_var_decl (decl
, expr
);
3260 build_gnu_selector_translation_table (void)
3264 tree decl = NULL_TREE;*/
3265 VEC(constructor_elt
,gc
) *inits
= NULL
;
3267 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
3271 if (warn_selector
&& objc_implementation_context
)
3272 diagnose_missing_method (TREE_VALUE (chain
), input_location
);
3274 expr
= build_selector (TREE_VALUE (chain
));
3275 /* add one for the '\0' character
3276 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
3279 if (flag_typed_selectors
)
3281 VEC(constructor_elt
,gc
) *v
= NULL
;
3282 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
3283 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
3284 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, encoding
);
3285 expr
= objc_build_constructor (objc_selector_template
, v
);
3288 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
3290 } /* each element in the chain */
3293 /* Cause the selector table (previously forward-declared)
3294 to be actually output. */
3297 if (flag_typed_selectors
)
3299 VEC(constructor_elt
,gc
) *v
= NULL
;
3300 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
3301 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
3302 expr
= objc_build_constructor (objc_selector_template
, v
);
3305 expr
= integer_zero_node
;
3307 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
3308 expr
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
3310 finish_var_decl (UOBJC_SELECTOR_TABLE_decl
, expr
);
3315 get_proto_encoding (tree proto
)
3320 if (! METHOD_ENCODING (proto
))
3322 encoding
= encode_method_prototype (proto
);
3323 METHOD_ENCODING (proto
) = encoding
;
3326 encoding
= METHOD_ENCODING (proto
);
3328 return add_objc_string (encoding
, meth_var_types
);
3331 return build_int_cst (NULL_TREE
, 0);
3334 /* sel_ref_chain is a list whose "value" fields will be instances of
3335 identifier_node that represent the selector. LOC is the location of
3339 build_typed_selector_reference (location_t loc
, tree ident
, tree prototype
)
3341 tree
*chain
= &sel_ref_chain
;
3347 if (TREE_PURPOSE (*chain
) == prototype
&& TREE_VALUE (*chain
) == ident
)
3348 goto return_at_index
;
3351 chain
= &TREE_CHAIN (*chain
);
3354 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
3357 expr
= build_unary_op (loc
, ADDR_EXPR
,
3358 build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
3359 build_int_cst (NULL_TREE
, index
)),
3361 return convert (objc_selector_type
, expr
);
3365 build_selector_reference (location_t loc
, tree ident
)
3367 tree
*chain
= &sel_ref_chain
;
3373 if (TREE_VALUE (*chain
) == ident
)
3374 return (flag_next_runtime
3375 ? TREE_PURPOSE (*chain
)
3376 : build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
3377 build_int_cst (NULL_TREE
, index
)));
3380 chain
= &TREE_CHAIN (*chain
);
3383 expr
= (flag_next_runtime
? build_selector_reference_decl (): NULL_TREE
);
3385 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
3387 return (flag_next_runtime
3389 : build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
3390 build_int_cst (NULL_TREE
, index
)));
3393 static GTY(()) int class_reference_idx
;
3396 build_class_reference_decl (void)
3401 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx
++);
3402 decl
= start_var_decl (objc_class_type
, buf
);
3407 /* Create a class reference, but don't create a variable to reference
3411 add_class_reference (tree ident
)
3415 if ((chain
= cls_ref_chain
))
3420 if (ident
== TREE_VALUE (chain
))
3424 chain
= TREE_CHAIN (chain
);
3428 /* Append to the end of the list */
3429 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
3432 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
3435 /* Get a class reference, creating it if necessary. Also create the
3436 reference variable. */
3439 objc_get_class_reference (tree ident
)
3441 tree orig_ident
= (DECL_P (ident
)
3444 ? OBJC_TYPE_NAME (ident
)
3446 bool local_scope
= false;
3449 if (processing_template_decl
)
3450 /* Must wait until template instantiation time. */
3451 return build_min_nt (CLASS_REFERENCE_EXPR
, ident
);
3454 if (TREE_CODE (ident
) == TYPE_DECL
)
3455 ident
= (DECL_ORIGINAL_TYPE (ident
)
3456 ? DECL_ORIGINAL_TYPE (ident
)
3457 : TREE_TYPE (ident
));
3461 && CP_TYPE_CONTEXT (ident
) != global_namespace
)
3465 if (local_scope
|| !(ident
= objc_is_class_name (ident
)))
3467 error ("%qE is not an Objective-C class name or alias",
3469 return error_mark_node
;
3472 if (flag_next_runtime
&& !flag_zero_link
)
3477 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
3478 if (TREE_VALUE (*chain
) == ident
)
3480 if (! TREE_PURPOSE (*chain
))
3481 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
3483 return TREE_PURPOSE (*chain
);
3486 decl
= build_class_reference_decl ();
3487 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
3494 add_class_reference (ident
);
3496 params
= build_tree_list (NULL_TREE
,
3497 my_build_string_pointer
3498 (IDENTIFIER_LENGTH (ident
) + 1,
3499 IDENTIFIER_POINTER (ident
)));
3501 assemble_external (objc_get_class_decl
);
3502 return build_function_call (input_location
, objc_get_class_decl
, params
);
3506 /* For each string section we have a chain which maps identifier nodes
3507 to decls for the strings. */
3509 static GTY(()) int class_names_idx
;
3510 static GTY(()) int meth_var_names_idx
;
3511 static GTY(()) int meth_var_types_idx
;
3514 add_objc_string (tree ident
, enum string_section section
)
3516 tree
*chain
, decl
, type
, string_expr
;
3523 chain
= &class_names_chain
;
3524 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
3526 case meth_var_names
:
3527 chain
= &meth_var_names_chain
;
3528 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
3530 case meth_var_types
:
3531 chain
= &meth_var_types_chain
;
3532 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
3540 if (TREE_VALUE (*chain
) == ident
)
3541 return convert (string_type_node
,
3542 build_unary_op (input_location
,
3543 ADDR_EXPR
, TREE_PURPOSE (*chain
), 1));
3545 chain
= &TREE_CHAIN (*chain
);
3548 type
= build_sized_array_type (char_type_node
, IDENTIFIER_LENGTH (ident
) + 1);
3549 decl
= start_var_decl (type
, buf
);
3550 string_expr
= my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
3551 IDENTIFIER_POINTER (ident
));
3552 TREE_CONSTANT (decl
) = 1;
3553 finish_var_decl (decl
, string_expr
);
3555 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
3557 return convert (string_type_node
, build_unary_op (input_location
,
3558 ADDR_EXPR
, decl
, 1));
3562 objc_declare_alias (tree alias_ident
, tree class_ident
)
3564 tree underlying_class
;
3567 if (current_namespace
!= global_namespace
) {
3568 error ("Objective-C declarations may only appear in global scope");
3570 #endif /* OBJCPLUS */
3572 if (!(underlying_class
= objc_is_class_name (class_ident
)))
3573 warning (0, "cannot find class %qE", class_ident
);
3574 else if (objc_is_class_name (alias_ident
))
3575 warning (0, "class %qE already exists", alias_ident
);
3578 /* Implement @compatibility_alias as a typedef. */
3580 push_lang_context (lang_name_c
); /* extern "C" */
3582 lang_hooks
.decls
.pushdecl (build_decl
3586 xref_tag (RECORD_TYPE
, underlying_class
)));
3588 pop_lang_context ();
3590 hash_class_name_enter (als_name_hash_list
, alias_ident
,
3596 objc_declare_class (tree ident_list
)
3600 if (current_namespace
!= global_namespace
) {
3601 error ("Objective-C declarations may only appear in global scope");
3603 #endif /* OBJCPLUS */
3605 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
3607 tree ident
= TREE_VALUE (list
);
3609 if (! objc_is_class_name (ident
))
3611 tree record
= lookup_name (ident
), type
= record
;
3615 if (TREE_CODE (record
) == TYPE_DECL
)
3616 type
= DECL_ORIGINAL_TYPE (record
) ?
3617 DECL_ORIGINAL_TYPE (record
) :
3620 if (!TYPE_HAS_OBJC_INFO (type
)
3621 || !TYPE_OBJC_INTERFACE (type
))
3623 error ("%qE redeclared as different kind of symbol",
3625 error ("previous declaration of %q+D",
3630 record
= xref_tag (RECORD_TYPE
, ident
);
3631 INIT_TYPE_OBJC_INFO (record
);
3632 TYPE_OBJC_INTERFACE (record
) = ident
;
3633 hash_class_name_enter (cls_name_hash_list
, ident
, NULL_TREE
);
3639 objc_is_class_name (tree ident
)
3643 if (ident
&& TREE_CODE (ident
) == IDENTIFIER_NODE
3644 && identifier_global_value (ident
))
3645 ident
= identifier_global_value (ident
);
3646 while (ident
&& TREE_CODE (ident
) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (ident
))
3647 ident
= OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident
));
3649 if (ident
&& TREE_CODE (ident
) == RECORD_TYPE
)
3650 ident
= OBJC_TYPE_NAME (ident
);
3652 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
3654 tree type
= TREE_TYPE (ident
);
3655 if (type
&& TREE_CODE (type
) == TEMPLATE_TYPE_PARM
)
3657 ident
= DECL_NAME (ident
);
3660 if (!ident
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
3663 if (lookup_interface (ident
))
3666 target
= hash_class_name_lookup (cls_name_hash_list
, ident
);
3670 target
= hash_class_name_lookup (als_name_hash_list
, ident
);
3673 gcc_assert (target
->list
&& target
->list
->value
);
3674 return target
->list
->value
;
3680 /* Check whether TYPE is either 'id' or 'Class'. */
3683 objc_is_id (tree type
)
3685 if (type
&& TREE_CODE (type
) == IDENTIFIER_NODE
3686 && identifier_global_value (type
))
3687 type
= identifier_global_value (type
);
3689 if (type
&& TREE_CODE (type
) == TYPE_DECL
)
3690 type
= TREE_TYPE (type
);
3692 /* NB: This function may be called before the ObjC front-end has
3693 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3694 return (objc_object_type
&& type
3695 && (IS_ID (type
) || IS_CLASS (type
) || IS_SUPER (type
))
3700 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3701 class instance. This is needed by other parts of the compiler to
3702 handle ObjC types gracefully. */
3705 objc_is_object_ptr (tree type
)
3709 type
= TYPE_MAIN_VARIANT (type
);
3710 if (!POINTER_TYPE_P (type
))
3713 ret
= objc_is_id (type
);
3715 ret
= objc_is_class_name (TREE_TYPE (type
));
3721 objc_is_gcable_type (tree type
, int or_strong_p
)
3727 if (objc_is_id (TYPE_MAIN_VARIANT (type
)))
3729 if (or_strong_p
&& lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type
)))
3731 if (TREE_CODE (type
) != POINTER_TYPE
&& TREE_CODE (type
) != INDIRECT_REF
)
3733 type
= TREE_TYPE (type
);
3734 if (TREE_CODE (type
) != RECORD_TYPE
)
3736 name
= TYPE_NAME (type
);
3737 return (objc_is_class_name (name
) != NULL_TREE
);
3741 objc_substitute_decl (tree expr
, tree oldexpr
, tree newexpr
)
3743 if (expr
== oldexpr
)
3746 switch (TREE_CODE (expr
))
3749 return objc_build_component_ref
3750 (objc_substitute_decl (TREE_OPERAND (expr
, 0),
3753 DECL_NAME (TREE_OPERAND (expr
, 1)));
3755 return build_array_ref (input_location
,
3756 objc_substitute_decl (TREE_OPERAND (expr
, 0),
3759 TREE_OPERAND (expr
, 1));
3761 return build_indirect_ref (input_location
,
3762 objc_substitute_decl (TREE_OPERAND (expr
, 0),
3764 newexpr
), RO_ARROW
);
3771 objc_build_ivar_assignment (tree outervar
, tree lhs
, tree rhs
)
3774 /* The LHS parameter contains the expression 'outervar->memberspec';
3775 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3776 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3779 = objc_substitute_decl
3780 (lhs
, outervar
, convert (TREE_TYPE (outervar
), integer_zero_node
));
3782 = (flag_objc_direct_dispatch
3783 ? objc_assign_ivar_fast_decl
3784 : objc_assign_ivar_decl
);
3786 offs
= convert (integer_type_node
, build_unary_op (input_location
,
3787 ADDR_EXPR
, offs
, 0));
3789 func_params
= tree_cons (NULL_TREE
,
3790 convert (objc_object_type
, rhs
),
3791 tree_cons (NULL_TREE
, convert (objc_object_type
, outervar
),
3792 tree_cons (NULL_TREE
, offs
,
3795 assemble_external (func
);
3796 return build_function_call (input_location
, func
, func_params
);
3800 objc_build_global_assignment (tree lhs
, tree rhs
)
3802 tree func_params
= tree_cons (NULL_TREE
,
3803 convert (objc_object_type
, rhs
),
3804 tree_cons (NULL_TREE
, convert (build_pointer_type (objc_object_type
),
3805 build_unary_op (input_location
, ADDR_EXPR
, lhs
, 0)),
3808 assemble_external (objc_assign_global_decl
);
3809 return build_function_call (input_location
,
3810 objc_assign_global_decl
, func_params
);
3814 objc_build_strong_cast_assignment (tree lhs
, tree rhs
)
3816 tree func_params
= tree_cons (NULL_TREE
,
3817 convert (objc_object_type
, rhs
),
3818 tree_cons (NULL_TREE
, convert (build_pointer_type (objc_object_type
),
3819 build_unary_op (input_location
, ADDR_EXPR
, lhs
, 0)),
3822 assemble_external (objc_assign_strong_cast_decl
);
3823 return build_function_call (input_location
,
3824 objc_assign_strong_cast_decl
, func_params
);
3828 objc_is_gcable_p (tree expr
)
3830 return (TREE_CODE (expr
) == COMPONENT_REF
3831 ? objc_is_gcable_p (TREE_OPERAND (expr
, 1))
3832 : TREE_CODE (expr
) == ARRAY_REF
3833 ? (objc_is_gcable_p (TREE_TYPE (expr
))
3834 || objc_is_gcable_p (TREE_OPERAND (expr
, 0)))
3835 : TREE_CODE (expr
) == ARRAY_TYPE
3836 ? objc_is_gcable_p (TREE_TYPE (expr
))
3838 ? objc_is_gcable_type (expr
, 1)
3839 : (objc_is_gcable_p (TREE_TYPE (expr
))
3841 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr
)))));
3845 objc_is_ivar_reference_p (tree expr
)
3847 return (TREE_CODE (expr
) == ARRAY_REF
3848 ? objc_is_ivar_reference_p (TREE_OPERAND (expr
, 0))
3849 : TREE_CODE (expr
) == COMPONENT_REF
3850 ? TREE_CODE (TREE_OPERAND (expr
, 1)) == FIELD_DECL
3855 objc_is_global_reference_p (tree expr
)
3857 return (TREE_CODE (expr
) == INDIRECT_REF
|| TREE_CODE (expr
) == PLUS_EXPR
3858 ? objc_is_global_reference_p (TREE_OPERAND (expr
, 0))
3860 ? (DECL_FILE_SCOPE_P (expr
) || TREE_STATIC (expr
))
3865 objc_generate_write_barrier (tree lhs
, enum tree_code modifycode
, tree rhs
)
3867 tree result
= NULL_TREE
, outer
;
3868 int strong_cast_p
= 0, outer_gc_p
= 0, indirect_p
= 0;
3870 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3871 will have been transformed to the form '*(type *)&expr'. */
3872 if (TREE_CODE (lhs
) == INDIRECT_REF
)
3874 outer
= TREE_OPERAND (lhs
, 0);
3876 while (!strong_cast_p
3877 && (CONVERT_EXPR_P (outer
)
3878 || TREE_CODE (outer
) == NON_LVALUE_EXPR
))
3880 tree lhstype
= TREE_TYPE (outer
);
3882 /* Descend down the cast chain, and record the first objc_gc
3884 if (POINTER_TYPE_P (lhstype
))
3887 = lookup_attribute ("objc_gc",
3888 TYPE_ATTRIBUTES (TREE_TYPE (lhstype
)));
3894 outer
= TREE_OPERAND (outer
, 0);
3898 /* If we have a __strong cast, it trumps all else. */
3901 if (modifycode
!= NOP_EXPR
)
3902 goto invalid_pointer_arithmetic
;
3904 if (warn_assign_intercept
)
3905 warning (0, "strong-cast assignment has been intercepted");
3907 result
= objc_build_strong_cast_assignment (lhs
, rhs
);
3912 /* the lhs must be of a suitable type, regardless of its underlying
3914 if (!objc_is_gcable_p (lhs
))
3920 && (TREE_CODE (outer
) == COMPONENT_REF
3921 || TREE_CODE (outer
) == ARRAY_REF
))
3922 outer
= TREE_OPERAND (outer
, 0);
3924 if (TREE_CODE (outer
) == INDIRECT_REF
)
3926 outer
= TREE_OPERAND (outer
, 0);
3930 outer_gc_p
= objc_is_gcable_p (outer
);
3932 /* Handle ivar assignments. */
3933 if (objc_is_ivar_reference_p (lhs
))
3935 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3936 doesn't cut it here), the best we can do here is suggest a cast. */
3937 if (!objc_is_gcable_type (TREE_TYPE (outer
), 0))
3939 /* We may still be able to use the global write barrier... */
3940 if (!indirect_p
&& objc_is_global_reference_p (outer
))
3941 goto global_reference
;
3944 if (modifycode
== NOP_EXPR
)
3946 if (warn_assign_intercept
)
3947 warning (0, "strong-cast may possibly be needed");
3953 if (modifycode
!= NOP_EXPR
)
3954 goto invalid_pointer_arithmetic
;
3956 if (warn_assign_intercept
)
3957 warning (0, "instance variable assignment has been intercepted");
3959 result
= objc_build_ivar_assignment (outer
, lhs
, rhs
);
3964 /* Likewise, intercept assignment to global/static variables if their type is
3966 if (objc_is_global_reference_p (outer
))
3972 if (modifycode
!= NOP_EXPR
)
3974 invalid_pointer_arithmetic
:
3976 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3981 if (warn_assign_intercept
)
3982 warning (0, "global/static variable assignment has been intercepted");
3984 result
= objc_build_global_assignment (lhs
, rhs
);
3987 /* In all other cases, fall back to the normal mechanism. */
3992 struct GTY(()) interface_tuple
{
3997 static GTY ((param_is (struct interface_tuple
))) htab_t interface_htab
;
4000 hash_interface (const void *p
)
4002 const struct interface_tuple
*d
= (const struct interface_tuple
*) p
;
4003 return IDENTIFIER_HASH_VALUE (d
->id
);
4007 eq_interface (const void *p1
, const void *p2
)
4009 const struct interface_tuple
*d
= (const struct interface_tuple
*) p1
;
4014 lookup_interface (tree ident
)
4017 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
4018 ident
= DECL_NAME (ident
);
4021 if (ident
== NULL_TREE
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
4025 struct interface_tuple
**slot
;
4030 slot
= (struct interface_tuple
**)
4031 htab_find_slot_with_hash (interface_htab
, ident
,
4032 IDENTIFIER_HASH_VALUE (ident
),
4035 i
= (*slot
)->class_name
;
4041 /* Implement @defs (<classname>) within struct bodies. */
4044 objc_get_class_ivars (tree class_name
)
4046 tree interface
= lookup_interface (class_name
);
4049 return get_class_ivars (interface
, true);
4051 error ("cannot find interface declaration for %qE",
4054 return error_mark_node
;
4057 /* Called when checking the variables in a struct. If we are not
4058 doing the ivars list inside an @interface context, then returns
4059 fieldlist unchanged. Else, returns the list of class ivars.
4062 objc_get_interface_ivars (tree fieldlist
)
4064 if (!objc_collecting_ivars
|| !objc_interface_context
4065 || TREE_CODE (objc_interface_context
) != CLASS_INTERFACE_TYPE
4066 || CLASS_SUPER_NAME (objc_interface_context
) == NULL_TREE
)
4069 return get_class_ivars (objc_interface_context
, true);
4072 /* Used by: build_private_template, continue_class,
4073 and for @defs constructs. */
4076 get_class_ivars (tree interface
, bool inherited
)
4078 tree ivar_chain
= copy_list (CLASS_RAW_IVARS (interface
));
4080 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
4081 by the current class (i.e., they do not include super-class ivars).
4082 However, the CLASS_IVARS list will be side-effected by a call to
4083 finish_struct(), which will fill in field offsets. */
4084 if (!CLASS_IVARS (interface
))
4085 CLASS_IVARS (interface
) = ivar_chain
;
4090 while (CLASS_SUPER_NAME (interface
))
4092 /* Prepend super-class ivars. */
4093 interface
= lookup_interface (CLASS_SUPER_NAME (interface
));
4094 ivar_chain
= chainon (copy_list (CLASS_RAW_IVARS (interface
)),
4101 /* Create a temporary variable of type 'type'. If 'name' is set, uses
4102 the specified name, else use no name. Returns the declaration of
4103 the type. The 'name' is mostly useful for debugging.
4106 objc_create_temporary_var (tree type
, const char *name
)
4112 decl
= build_decl (input_location
,
4113 VAR_DECL
, get_identifier (name
), type
);
4117 decl
= build_decl (input_location
,
4118 VAR_DECL
, NULL_TREE
, type
);
4120 TREE_USED (decl
) = 1;
4121 DECL_ARTIFICIAL (decl
) = 1;
4122 DECL_IGNORED_P (decl
) = 1;
4123 DECL_CONTEXT (decl
) = current_function_decl
;
4128 /* Exception handling constructs. We begin by having the parser do most
4129 of the work and passing us blocks. What we do next depends on whether
4130 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
4131 We abstract all of this in a handful of appropriately named routines. */
4133 /* Stack of open try blocks. */
4135 struct objc_try_context
4137 struct objc_try_context
*outer
;
4139 /* Statements (or statement lists) as processed by the parser. */
4143 /* Some file position locations. */
4144 location_t try_locus
;
4145 location_t end_try_locus
;
4146 location_t end_catch_locus
;
4147 location_t finally_locus
;
4148 location_t end_finally_locus
;
4150 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
4151 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
4154 /* The CATCH_EXPR of an open @catch clause. */
4157 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
4163 static struct objc_try_context
*cur_try_context
;
4165 static GTY(()) tree objc_eh_personality_decl
;
4167 /* This hook, called via lang_eh_runtime_type, generates a runtime object
4168 that represents TYPE. For Objective-C, this is just the class name. */
4169 /* ??? Isn't there a class object or some such? Is it easy to get? */
4173 objc_eh_runtime_type (tree type
)
4175 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type
)), class_names
);
4179 objc_eh_personality (void)
4181 if (!flag_objc_sjlj_exceptions
&& !objc_eh_personality_decl
)
4182 objc_eh_personality_decl
= build_personality_function ("gnu_objc");
4183 return objc_eh_personality_decl
;
4187 /* Build __builtin_eh_pointer, or the moral equivalent. In the case
4188 of Darwin, we'll arrange for it to be initialized (and associated
4189 with a binding) later. */
4192 objc_build_exc_ptr (void)
4194 if (flag_objc_sjlj_exceptions
)
4196 tree var
= cur_try_context
->caught_decl
;
4199 var
= objc_create_temporary_var (objc_object_type
, NULL
);
4200 cur_try_context
->caught_decl
= var
;
4207 t
= built_in_decls
[BUILT_IN_EH_POINTER
];
4208 t
= build_call_expr (t
, 1, integer_zero_node
);
4209 return fold_convert (objc_object_type
, t
);
4213 /* Build "objc_exception_try_exit(&_stack)". */
4216 next_sjlj_build_try_exit (void)
4219 t
= build_fold_addr_expr_loc (input_location
, cur_try_context
->stack_decl
);
4220 t
= tree_cons (NULL
, t
, NULL
);
4221 t
= build_function_call (input_location
,
4222 objc_exception_try_exit_decl
, t
);
4227 objc_exception_try_enter (&_stack);
4228 if (_setjmp(&_stack.buf))
4232 Return the COND_EXPR. Note that the THEN and ELSE fields are left
4233 empty, ready for the caller to fill them in. */
4236 next_sjlj_build_enter_and_setjmp (void)
4238 tree t
, enter
, sj
, cond
;
4240 t
= build_fold_addr_expr_loc (input_location
, cur_try_context
->stack_decl
);
4241 t
= tree_cons (NULL
, t
, NULL
);
4242 enter
= build_function_call (input_location
,
4243 objc_exception_try_enter_decl
, t
);
4245 t
= objc_build_component_ref (cur_try_context
->stack_decl
,
4246 get_identifier ("buf"));
4247 t
= build_fold_addr_expr_loc (input_location
, t
);
4249 /* Convert _setjmp argument to type that is expected. */
4250 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl
)))
4251 t
= convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl
))), t
);
4253 t
= convert (ptr_type_node
, t
);
4255 t
= convert (ptr_type_node
, t
);
4257 t
= tree_cons (NULL
, t
, NULL
);
4258 sj
= build_function_call (input_location
,
4259 objc_setjmp_decl
, t
);
4261 cond
= build2 (COMPOUND_EXPR
, TREE_TYPE (sj
), enter
, sj
);
4262 cond
= c_common_truthvalue_conversion (input_location
, cond
);
4264 return build3 (COND_EXPR
, void_type_node
, cond
, NULL
, NULL
);
4269 DECL = objc_exception_extract(&_stack); */
4272 next_sjlj_build_exc_extract (tree decl
)
4276 t
= build_fold_addr_expr_loc (input_location
, cur_try_context
->stack_decl
);
4277 t
= tree_cons (NULL
, t
, NULL
);
4278 t
= build_function_call (input_location
,
4279 objc_exception_extract_decl
, t
);
4280 t
= convert (TREE_TYPE (decl
), t
);
4281 t
= build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
4287 if (objc_exception_match(obj_get_class(TYPE), _caught)
4294 objc_exception_try_exit(&_stack);
4296 from the sequence of CATCH_EXPRs in the current try context. */
4299 next_sjlj_build_catch_list (void)
4301 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
4303 tree
*last
= &catch_seq
;
4304 bool saw_id
= false;
4306 for (; !tsi_end_p (i
); tsi_next (&i
))
4308 tree stmt
= tsi_stmt (i
);
4309 tree type
= CATCH_TYPES (stmt
);
4310 tree body
= CATCH_BODY (stmt
);
4322 if (type
== error_mark_node
)
4323 cond
= error_mark_node
;
4326 args
= tree_cons (NULL
, cur_try_context
->caught_decl
, NULL
);
4327 t
= objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type
)));
4328 args
= tree_cons (NULL
, t
, args
);
4329 t
= build_function_call (input_location
,
4330 objc_exception_match_decl
, args
);
4331 cond
= c_common_truthvalue_conversion (input_location
, t
);
4333 t
= build3 (COND_EXPR
, void_type_node
, cond
, body
, NULL
);
4334 SET_EXPR_LOCATION (t
, EXPR_LOCATION (stmt
));
4337 last
= &COND_EXPR_ELSE (t
);
4343 t
= build2 (MODIFY_EXPR
, void_type_node
, cur_try_context
->rethrow_decl
,
4344 cur_try_context
->caught_decl
);
4345 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
4346 append_to_statement_list (t
, last
);
4348 t
= next_sjlj_build_try_exit ();
4349 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
4350 append_to_statement_list (t
, last
);
4356 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
4357 exception handling. We aim to build:
4360 struct _objc_exception_data _stack;
4364 objc_exception_try_enter (&_stack);
4365 if (_setjmp(&_stack.buf))
4367 id _caught = objc_exception_extract(&_stack);
4368 objc_exception_try_enter (&_stack);
4369 if (_setjmp(&_stack.buf))
4370 _rethrow = objc_exception_extract(&_stack);
4380 objc_exception_try_exit(&_stack);
4383 objc_exception_throw(_rethrow);
4387 If CATCH-LIST is empty, we can omit all of the block containing
4388 "_caught" except for the setting of _rethrow. Note the use of
4389 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
4390 but handles goto and other exits from the block. */
4393 next_sjlj_build_try_catch_finally (void)
4395 tree rethrow_decl
, stack_decl
, t
;
4396 tree catch_seq
, try_fin
, bind
;
4398 /* Create the declarations involved. */
4399 t
= xref_tag (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
4400 stack_decl
= objc_create_temporary_var (t
, NULL
);
4401 cur_try_context
->stack_decl
= stack_decl
;
4403 rethrow_decl
= objc_create_temporary_var (objc_object_type
, NULL
);
4404 cur_try_context
->rethrow_decl
= rethrow_decl
;
4405 TREE_CHAIN (rethrow_decl
) = stack_decl
;
4407 /* Build the outermost variable binding level. */
4408 bind
= build3 (BIND_EXPR
, void_type_node
, rethrow_decl
, NULL
, NULL
);
4409 SET_EXPR_LOCATION (bind
, cur_try_context
->try_locus
);
4410 TREE_SIDE_EFFECTS (bind
) = 1;
4412 /* Initialize rethrow_decl. */
4413 t
= build2 (MODIFY_EXPR
, void_type_node
, rethrow_decl
,
4414 convert (objc_object_type
, null_pointer_node
));
4415 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
4416 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
4418 /* Build the outermost TRY_FINALLY_EXPR. */
4419 try_fin
= build2 (TRY_FINALLY_EXPR
, void_type_node
, NULL
, NULL
);
4420 SET_EXPR_LOCATION (try_fin
, cur_try_context
->try_locus
);
4421 TREE_SIDE_EFFECTS (try_fin
) = 1;
4422 append_to_statement_list (try_fin
, &BIND_EXPR_BODY (bind
));
4424 /* Create the complete catch sequence. */
4425 if (cur_try_context
->catch_list
)
4427 tree caught_decl
= objc_build_exc_ptr ();
4428 catch_seq
= build_stmt (input_location
, BIND_EXPR
, caught_decl
, NULL
, NULL
);
4429 TREE_SIDE_EFFECTS (catch_seq
) = 1;
4431 t
= next_sjlj_build_exc_extract (caught_decl
);
4432 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
4434 t
= next_sjlj_build_enter_and_setjmp ();
4435 COND_EXPR_THEN (t
) = next_sjlj_build_exc_extract (rethrow_decl
);
4436 COND_EXPR_ELSE (t
) = next_sjlj_build_catch_list ();
4437 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
4440 catch_seq
= next_sjlj_build_exc_extract (rethrow_decl
);
4441 SET_EXPR_LOCATION (catch_seq
, cur_try_context
->end_try_locus
);
4443 /* Build the main register-and-try if statement. */
4444 t
= next_sjlj_build_enter_and_setjmp ();
4445 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
4446 COND_EXPR_THEN (t
) = catch_seq
;
4447 COND_EXPR_ELSE (t
) = cur_try_context
->try_body
;
4448 TREE_OPERAND (try_fin
, 0) = t
;
4450 /* Build the complete FINALLY statement list. */
4451 t
= next_sjlj_build_try_exit ();
4452 t
= build_stmt (input_location
, COND_EXPR
,
4453 c_common_truthvalue_conversion
4454 (input_location
, rethrow_decl
),
4456 SET_EXPR_LOCATION (t
, cur_try_context
->finally_locus
);
4457 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
4459 append_to_statement_list (cur_try_context
->finally_body
,
4460 &TREE_OPERAND (try_fin
, 1));
4462 t
= tree_cons (NULL
, rethrow_decl
, NULL
);
4463 t
= build_function_call (input_location
,
4464 objc_exception_throw_decl
, t
);
4465 t
= build_stmt (input_location
, COND_EXPR
,
4466 c_common_truthvalue_conversion (input_location
,
4469 SET_EXPR_LOCATION (t
, cur_try_context
->end_finally_locus
);
4470 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
4475 /* Called just after parsing the @try and its associated BODY. We now
4476 must prepare for the tricky bits -- handling the catches and finally. */
4479 objc_begin_try_stmt (location_t try_locus
, tree body
)
4481 struct objc_try_context
*c
= XCNEW (struct objc_try_context
);
4482 c
->outer
= cur_try_context
;
4484 c
->try_locus
= try_locus
;
4485 c
->end_try_locus
= input_location
;
4486 cur_try_context
= c
;
4488 /* -fobjc-exceptions is required to enable Objective-C exceptions.
4489 For example, on Darwin, ObjC exceptions require a sufficiently
4490 recent version of the runtime, so the user must ask for them
4491 explicitly. On other platforms, at the moment -fobjc-exceptions
4492 triggers -fexceptions which again is required for exceptions to
4495 if (!flag_objc_exceptions
)
4497 error_at (try_locus
, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4500 if (flag_objc_sjlj_exceptions
)
4501 objc_mark_locals_volatile (NULL
);
4504 /* Called just after parsing "@catch (parm)". Open a binding level,
4505 enter DECL into the binding level, and initialize it. Leave the
4506 binding level open while the body of the compound statement is parsed. */
4509 objc_begin_catch_clause (tree decl
)
4511 tree compound
, type
, t
;
4513 /* Begin a new scope that the entire catch clause will live in. */
4514 compound
= c_begin_compound_stmt (true);
4516 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
4517 decl
= build_decl (input_location
,
4518 VAR_DECL
, DECL_NAME (decl
), TREE_TYPE (decl
));
4519 lang_hooks
.decls
.pushdecl (decl
);
4521 /* Since a decl is required here by syntax, don't warn if its unused. */
4522 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
4523 be what the previous objc implementation did. */
4524 TREE_USED (decl
) = 1;
4525 DECL_READ_P (decl
) = 1;
4527 /* Verify that the type of the catch is valid. It must be a pointer
4528 to an Objective-C class, or "id" (which is catch-all). */
4529 type
= TREE_TYPE (decl
);
4531 if (POINTER_TYPE_P (type
) && objc_is_object_id (TREE_TYPE (type
)))
4533 else if (!POINTER_TYPE_P (type
) || !TYPED_OBJECT (TREE_TYPE (type
)))
4535 error ("@catch parameter is not a known Objective-C class type");
4536 type
= error_mark_node
;
4538 else if (cur_try_context
->catch_list
)
4540 /* Examine previous @catch clauses and see if we've already
4541 caught the type in question. */
4542 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
4543 for (; !tsi_end_p (i
); tsi_next (&i
))
4545 tree stmt
= tsi_stmt (i
);
4546 t
= CATCH_TYPES (stmt
);
4547 if (t
== error_mark_node
)
4549 if (!t
|| DERIVED_FROM_P (TREE_TYPE (t
), TREE_TYPE (type
)))
4551 warning (0, "exception of type %<%T%> will be caught",
4553 warning_at (EXPR_LOCATION (stmt
), 0, " by earlier handler for %<%T%>",
4554 TREE_TYPE (t
? t
: objc_object_type
));
4560 /* Record the data for the catch in the try context so that we can
4561 finalize it later. */
4562 t
= build_stmt (input_location
, CATCH_EXPR
, type
, compound
);
4563 cur_try_context
->current_catch
= t
;
4565 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
4566 t
= objc_build_exc_ptr ();
4567 t
= convert (TREE_TYPE (decl
), t
);
4568 t
= build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
4572 /* Called just after parsing the closing brace of a @catch clause. Close
4573 the open binding level, and record a CATCH_EXPR for it. */
4576 objc_finish_catch_clause (void)
4578 tree c
= cur_try_context
->current_catch
;
4579 cur_try_context
->current_catch
= NULL
;
4580 cur_try_context
->end_catch_locus
= input_location
;
4582 CATCH_BODY (c
) = c_end_compound_stmt (input_location
, CATCH_BODY (c
), 1);
4583 append_to_statement_list (c
, &cur_try_context
->catch_list
);
4586 /* Called after parsing a @finally clause and its associated BODY.
4587 Record the body for later placement. */
4590 objc_build_finally_clause (location_t finally_locus
, tree body
)
4592 cur_try_context
->finally_body
= body
;
4593 cur_try_context
->finally_locus
= finally_locus
;
4594 cur_try_context
->end_finally_locus
= input_location
;
4597 /* Called to finalize a @try construct. */
4600 objc_finish_try_stmt (void)
4602 struct objc_try_context
*c
= cur_try_context
;
4605 if (c
->catch_list
== NULL
&& c
->finally_body
== NULL
)
4606 error ("%<@try%> without %<@catch%> or %<@finally%>");
4608 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
4609 if (flag_objc_sjlj_exceptions
)
4611 bool save
= in_late_binary_op
;
4612 in_late_binary_op
= true;
4613 if (!cur_try_context
->finally_body
)
4615 cur_try_context
->finally_locus
= input_location
;
4616 cur_try_context
->end_finally_locus
= input_location
;
4618 stmt
= next_sjlj_build_try_catch_finally ();
4619 in_late_binary_op
= save
;
4623 /* Otherwise, nest the CATCH inside a FINALLY. */
4627 stmt
= build_stmt (input_location
, TRY_CATCH_EXPR
, stmt
, c
->catch_list
);
4628 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
4630 if (c
->finally_body
)
4632 stmt
= build_stmt (input_location
, TRY_FINALLY_EXPR
, stmt
, c
->finally_body
);
4633 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
4638 cur_try_context
= c
->outer
;
4644 objc_build_throw_stmt (location_t loc
, tree throw_expr
)
4648 if (!flag_objc_exceptions
)
4650 error_at (loc
, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4653 if (throw_expr
== NULL
)
4655 /* If we're not inside a @catch block, there is no "current
4656 exception" to be rethrown. */
4657 if (cur_try_context
== NULL
4658 || cur_try_context
->current_catch
== NULL
)
4660 error_at (loc
, "%<@throw%> (rethrow) used outside of a @catch block");
4664 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
4665 value that we get from the runtime. */
4666 throw_expr
= objc_build_exc_ptr ();
4669 /* A throw is just a call to the runtime throw function with the
4670 object as a parameter. */
4671 args
= tree_cons (NULL
, throw_expr
, NULL
);
4672 return add_stmt (build_function_call (loc
,
4673 objc_exception_throw_decl
, args
));
4677 objc_build_synchronized (location_t start_locus
, tree mutex
, tree body
)
4681 /* First lock the mutex. */
4682 mutex
= save_expr (mutex
);
4683 args
= tree_cons (NULL
, mutex
, NULL
);
4684 call
= build_function_call (input_location
,
4685 objc_sync_enter_decl
, args
);
4686 SET_EXPR_LOCATION (call
, start_locus
);
4689 /* Build the mutex unlock. */
4690 args
= tree_cons (NULL
, mutex
, NULL
);
4691 call
= build_function_call (input_location
,
4692 objc_sync_exit_decl
, args
);
4693 SET_EXPR_LOCATION (call
, input_location
);
4695 /* Put the that and the body in a TRY_FINALLY. */
4696 objc_begin_try_stmt (start_locus
, body
);
4697 objc_build_finally_clause (input_location
, call
);
4698 return objc_finish_try_stmt ();
4702 /* Predefine the following data type:
4704 struct _objc_exception_data
4706 int buf[OBJC_JBLEN];
4710 /* The following yuckiness should prevent users from having to #include
4711 <setjmp.h> in their code... */
4713 /* Define to a harmless positive value so the below code doesn't die. */
4715 #define OBJC_JBLEN 18
4719 build_next_objc_exception_stuff (void)
4721 tree decls
, temp_type
, *chain
= NULL
;
4723 objc_exception_data_template
4724 = objc_start_struct (get_identifier (UTAG_EXCDATA
));
4726 /* int buf[OBJC_JBLEN]; */
4728 temp_type
= build_sized_array_type (integer_type_node
, OBJC_JBLEN
);
4729 decls
= add_field_decl (temp_type
, "buf", &chain
);
4731 /* void *pointers[4]; */
4733 temp_type
= build_sized_array_type (ptr_type_node
, 4);
4734 add_field_decl (temp_type
, "pointers", &chain
);
4736 objc_finish_struct (objc_exception_data_template
, decls
);
4738 /* int _setjmp(...); */
4739 /* If the user includes <setjmp.h>, this shall be superseded by
4740 'int _setjmp(jmp_buf);' */
4741 temp_type
= build_varargs_function_type_list (integer_type_node
, NULL_TREE
);
4743 = add_builtin_function (TAG_SETJMP
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
4745 /* id objc_exception_extract(struct _objc_exception_data *); */
4747 = build_function_type_list (objc_object_type
,
4748 build_pointer_type (objc_exception_data_template
),
4750 objc_exception_extract_decl
4751 = add_builtin_function (TAG_EXCEPTIONEXTRACT
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4753 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4754 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4756 = build_function_type_list (void_type_node
,
4757 build_pointer_type (objc_exception_data_template
),
4759 objc_exception_try_enter_decl
4760 = add_builtin_function (TAG_EXCEPTIONTRYENTER
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4762 objc_exception_try_exit_decl
4763 = add_builtin_function (TAG_EXCEPTIONTRYEXIT
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4766 /* int objc_exception_match(id, id); */
4768 = build_function_type_list (integer_type_node
,
4769 objc_object_type
, objc_object_type
, NULL_TREE
);
4770 objc_exception_match_decl
4771 = add_builtin_function (TAG_EXCEPTIONMATCH
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4774 /* id objc_assign_ivar (id, id, unsigned int); */
4775 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4776 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4778 = build_function_type_list (objc_object_type
,
4783 objc_assign_ivar_decl
4784 = add_builtin_function (TAG_ASSIGNIVAR
, temp_type
, 0, NOT_BUILT_IN
,
4786 #ifdef OFFS_ASSIGNIVAR_FAST
4787 objc_assign_ivar_fast_decl
4788 = add_builtin_function (TAG_ASSIGNIVAR_FAST
, temp_type
, 0,
4789 NOT_BUILT_IN
, NULL
, NULL_TREE
);
4790 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl
)
4791 = tree_cons (get_identifier ("hard_coded_address"),
4792 build_int_cst (NULL_TREE
, OFFS_ASSIGNIVAR_FAST
),
4795 /* Default to slower ivar method. */
4796 objc_assign_ivar_fast_decl
= objc_assign_ivar_decl
;
4799 /* id objc_assign_global (id, id *); */
4800 /* id objc_assign_strongCast (id, id *); */
4801 temp_type
= build_function_type_list (objc_object_type
,
4803 build_pointer_type (objc_object_type
),
4805 objc_assign_global_decl
4806 = add_builtin_function (TAG_ASSIGNGLOBAL
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4808 objc_assign_strong_cast_decl
4809 = add_builtin_function (TAG_ASSIGNSTRONGCAST
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4814 build_objc_exception_stuff (void)
4816 tree noreturn_list
, nothrow_list
, temp_type
;
4818 noreturn_list
= tree_cons (get_identifier ("noreturn"), NULL
, NULL
);
4819 nothrow_list
= tree_cons (get_identifier ("nothrow"), NULL
, NULL
);
4821 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4822 /* void objc_sync_enter(id); */
4823 /* void objc_sync_exit(id); */
4824 temp_type
= build_function_type_list (void_type_node
,
4827 objc_exception_throw_decl
4828 = add_builtin_function (TAG_EXCEPTIONTHROW
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4830 objc_sync_enter_decl
4831 = add_builtin_function (TAG_SYNCENTER
, temp_type
, 0, NOT_BUILT_IN
,
4832 NULL
, nothrow_list
);
4834 = add_builtin_function (TAG_SYNCEXIT
, temp_type
, 0, NOT_BUILT_IN
,
4835 NULL
, nothrow_list
);
4838 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4841 struct <classname> {
4842 struct _objc_class *isa;
4847 build_private_template (tree klass
)
4849 if (!CLASS_STATIC_TEMPLATE (klass
))
4851 tree record
= objc_build_struct (klass
,
4852 get_class_ivars (klass
, false),
4853 CLASS_SUPER_NAME (klass
));
4855 /* Set the TREE_USED bit for this struct, so that stab generator
4856 can emit stabs for this struct type. */
4857 if (flag_debug_only_used_symbols
&& TYPE_STUB_DECL (record
))
4858 TREE_USED (TYPE_STUB_DECL (record
)) = 1;
4862 /* Begin code generation for protocols... */
4864 /* struct _objc_protocol {
4865 struct _objc_class *isa;
4866 char *protocol_name;
4867 struct _objc_protocol **protocol_list;
4868 struct _objc__method_prototype_list *instance_methods;
4869 struct _objc__method_prototype_list *class_methods;
4873 build_protocol_template (void)
4875 tree ptype
, decls
, *chain
= NULL
;
4877 objc_protocol_template
= objc_start_struct (get_identifier (UTAG_PROTOCOL
));
4879 /* struct _objc_class *isa; */
4880 ptype
= build_pointer_type (xref_tag (RECORD_TYPE
,
4881 get_identifier (UTAG_CLASS
)));
4882 decls
= add_field_decl (ptype
, "isa", &chain
);
4884 /* char *protocol_name; */
4885 add_field_decl (string_type_node
, "protocol_name", &chain
);
4887 /* struct _objc_protocol **protocol_list; */
4888 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
4889 add_field_decl (ptype
, "protocol_list", &chain
);
4891 /* struct _objc__method_prototype_list *instance_methods; */
4892 add_field_decl (objc_method_proto_list_ptr
, "instance_methods", &chain
);
4894 /* struct _objc__method_prototype_list *class_methods; */
4895 add_field_decl (objc_method_proto_list_ptr
, "class_methods", &chain
);
4897 objc_finish_struct (objc_protocol_template
, decls
);
4901 build_descriptor_table_initializer (tree type
, tree entries
)
4903 VEC(constructor_elt
,gc
) *inits
= NULL
;
4907 VEC(constructor_elt
,gc
) *elts
= NULL
;
4909 CONSTRUCTOR_APPEND_ELT (elts
, NULL_TREE
,
4910 build_selector (METHOD_SEL_NAME (entries
)));
4911 CONSTRUCTOR_APPEND_ELT (elts
, NULL_TREE
,
4912 add_objc_string (METHOD_ENCODING (entries
),
4915 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
,
4916 objc_build_constructor (type
, elts
));
4918 entries
= DECL_CHAIN (entries
);
4922 return objc_build_constructor (build_array_type (type
, 0), inits
);
4925 /* struct objc_method_prototype_list {
4927 struct objc_method_prototype {
4934 build_method_prototype_list_template (tree list_type
, int size
)
4936 tree objc_ivar_list_record
;
4937 tree array_type
, decls
, *chain
= NULL
;
4939 /* Generate an unnamed struct definition. */
4941 objc_ivar_list_record
= objc_start_struct (NULL_TREE
);
4943 /* int method_count; */
4944 decls
= add_field_decl (integer_type_node
, "method_count", &chain
);
4946 /* struct objc_method method_list[]; */
4947 array_type
= build_sized_array_type (list_type
, size
);
4948 add_field_decl (array_type
, "method_list", &chain
);
4950 objc_finish_struct (objc_ivar_list_record
, decls
);
4952 return objc_ivar_list_record
;
4956 build_method_prototype_template (void)
4959 tree decls
, *chain
= NULL
;
4961 proto_record
= objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE
));
4964 decls
= add_field_decl (objc_selector_type
, "_cmd", &chain
);
4966 /* char *method_types; */
4967 add_field_decl (string_type_node
, "method_types", &chain
);
4969 objc_finish_struct (proto_record
, decls
);
4971 return proto_record
;
4975 objc_method_parm_type (tree type
)
4977 type
= TREE_VALUE (TREE_TYPE (type
));
4978 if (TREE_CODE (type
) == TYPE_DECL
)
4979 type
= TREE_TYPE (type
);
4984 objc_encoded_type_size (tree type
)
4986 int sz
= int_size_in_bytes (type
);
4988 /* Make all integer and enum types at least as large
4990 if (sz
> 0 && INTEGRAL_TYPE_P (type
))
4991 sz
= MAX (sz
, int_size_in_bytes (integer_type_node
));
4992 /* Treat arrays as pointers, since that's how they're
4994 else if (TREE_CODE (type
) == ARRAY_TYPE
)
4995 sz
= int_size_in_bytes (ptr_type_node
);
4999 /* Encode a method prototype.
5001 The format is described in gcc/doc/objc.texi, section 'Method
5005 encode_method_prototype (tree method_decl
)
5012 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
5013 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
5015 /* Encode return type. */
5016 encode_type (objc_method_parm_type (method_decl
),
5017 obstack_object_size (&util_obstack
),
5018 OBJC_ENCODE_INLINE_DEFS
);
5021 /* The first two arguments (self and _cmd) are pointers; account for
5023 i
= int_size_in_bytes (ptr_type_node
);
5024 parm_offset
= 2 * i
;
5025 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
5026 parms
= DECL_CHAIN (parms
))
5028 tree type
= objc_method_parm_type (parms
);
5029 int sz
= objc_encoded_type_size (type
);
5031 /* If a type size is not known, bail out. */
5034 error ("type %q+D does not have a known size",
5036 /* Pretend that the encoding succeeded; the compilation will
5037 fail nevertheless. */
5038 goto finish_encoding
;
5043 sprintf (buf
, "%d@0:%d", parm_offset
, i
);
5044 obstack_grow (&util_obstack
, buf
, strlen (buf
));
5046 /* Argument types. */
5047 parm_offset
= 2 * i
;
5048 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
5049 parms
= DECL_CHAIN (parms
))
5051 tree type
= objc_method_parm_type (parms
);
5053 /* Process argument qualifiers for user supplied arguments. */
5054 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms
)));
5057 encode_type (type
, obstack_object_size (&util_obstack
),
5058 OBJC_ENCODE_INLINE_DEFS
);
5060 /* Compute offset. */
5061 sprintf (buf
, "%d", parm_offset
);
5062 parm_offset
+= objc_encoded_type_size (type
);
5064 obstack_grow (&util_obstack
, buf
, strlen (buf
));
5068 obstack_1grow (&util_obstack
, '\0');
5069 result
= get_identifier (XOBFINISH (&util_obstack
, char *));
5070 obstack_free (&util_obstack
, util_firstobj
);
5075 generate_descriptor_table (tree type
, const char *name
, int size
, tree list
,
5079 VEC(constructor_elt
,gc
) *v
= NULL
;
5081 decl
= start_var_decl (type
, synth_id_with_class_suffix (name
, proto
));
5083 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
5084 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, list
);
5086 finish_var_decl (decl
, objc_build_constructor (type
, v
));
5092 generate_method_descriptors (tree protocol
)
5094 tree initlist
, chain
, method_list_template
;
5097 if (!objc_method_prototype_template
)
5098 objc_method_prototype_template
= build_method_prototype_template ();
5100 chain
= PROTOCOL_CLS_METHODS (protocol
);
5103 size
= list_length (chain
);
5105 method_list_template
5106 = build_method_prototype_list_template (objc_method_prototype_template
,
5110 = build_descriptor_table_initializer (objc_method_prototype_template
,
5113 UOBJC_CLASS_METHODS_decl
5114 = generate_descriptor_table (method_list_template
,
5115 "_OBJC_PROTOCOL_CLASS_METHODS",
5116 size
, initlist
, protocol
);
5119 UOBJC_CLASS_METHODS_decl
= 0;
5121 chain
= PROTOCOL_NST_METHODS (protocol
);
5124 size
= list_length (chain
);
5126 method_list_template
5127 = build_method_prototype_list_template (objc_method_prototype_template
,
5130 = build_descriptor_table_initializer (objc_method_prototype_template
,
5133 UOBJC_INSTANCE_METHODS_decl
5134 = generate_descriptor_table (method_list_template
,
5135 "_OBJC_PROTOCOL_INSTANCE_METHODS",
5136 size
, initlist
, protocol
);
5139 UOBJC_INSTANCE_METHODS_decl
= 0;
5143 generate_protocol_references (tree plist
)
5147 /* Forward declare protocols referenced. */
5148 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
5150 tree proto
= TREE_VALUE (lproto
);
5152 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
5153 && PROTOCOL_NAME (proto
))
5155 if (! PROTOCOL_FORWARD_DECL (proto
))
5156 build_protocol_reference (proto
);
5158 if (PROTOCOL_LIST (proto
))
5159 generate_protocol_references (PROTOCOL_LIST (proto
));
5164 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
5168 objc_generate_cxx_ctor_or_dtor (bool dtor
)
5170 tree fn
, body
, compound_stmt
, ivar
;
5172 /* - (id) .cxx_construct { ... return self; } */
5173 /* - (void) .cxx_construct { ... } */
5175 objc_start_method_definition
5176 (false /* is_class_method */,
5177 objc_build_method_signature (false /* is_class_method */,
5178 build_tree_list (NULL_TREE
,
5181 : objc_object_type
),
5182 get_identifier (dtor
5184 : TAG_CXX_CONSTRUCT
),
5185 make_node (TREE_LIST
),
5187 body
= begin_function_body ();
5188 compound_stmt
= begin_compound_stmt (0);
5190 ivar
= CLASS_IVARS (implementation_template
);
5191 /* Destroy ivars in reverse order. */
5193 ivar
= nreverse (copy_list (ivar
));
5195 for (; ivar
; ivar
= TREE_CHAIN (ivar
))
5197 if (TREE_CODE (ivar
) == FIELD_DECL
)
5199 tree type
= TREE_TYPE (ivar
);
5201 /* Call the ivar's default constructor or destructor. Do not
5202 call the destructor unless a corresponding constructor call
5203 has also been made (or is not needed). */
5204 if (MAYBE_CLASS_TYPE_P (type
)
5206 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type
)
5207 && (!TYPE_NEEDS_CONSTRUCTING (type
)
5208 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type
)))
5209 : (TYPE_NEEDS_CONSTRUCTING (type
)
5210 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type
))))
5212 (build_special_member_call
5213 (build_ivar_reference (DECL_NAME (ivar
)),
5214 dtor
? complete_dtor_identifier
: complete_ctor_identifier
,
5215 NULL
, type
, LOOKUP_NORMAL
, tf_warning_or_error
));
5219 /* The constructor returns 'self'. */
5221 finish_return_stmt (self_decl
);
5223 finish_compound_stmt (compound_stmt
);
5224 finish_function_body (body
);
5225 fn
= current_function_decl
;
5227 objc_finish_method_definition (fn
);
5230 /* The following routine will examine the current @interface for any
5231 non-POD C++ ivars requiring non-trivial construction and/or
5232 destruction, and then synthesize special '- .cxx_construct' and/or
5233 '- .cxx_destruct' methods which will run the appropriate
5234 construction or destruction code. Note that ivars inherited from
5235 super-classes are _not_ considered. */
5237 objc_generate_cxx_cdtors (void)
5239 bool need_ctor
= false, need_dtor
= false;
5242 /* Error case, due to possibly an extra @end. */
5243 if (!objc_implementation_context
)
5246 /* We do not want to do this for categories, since they do not have
5249 if (TREE_CODE (objc_implementation_context
) != CLASS_IMPLEMENTATION_TYPE
)
5252 /* First, determine if we even need a constructor and/or destructor. */
5254 for (ivar
= CLASS_IVARS (implementation_template
); ivar
;
5255 ivar
= TREE_CHAIN (ivar
))
5257 if (TREE_CODE (ivar
) == FIELD_DECL
)
5259 tree type
= TREE_TYPE (ivar
);
5261 if (MAYBE_CLASS_TYPE_P (type
))
5263 if (TYPE_NEEDS_CONSTRUCTING (type
)
5264 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type
))
5265 /* NB: If a default constructor is not available, we will not
5266 be able to initialize this ivar; the add_instance_variable()
5267 routine will already have warned about this. */
5270 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type
)
5271 && (!TYPE_NEEDS_CONSTRUCTING (type
)
5272 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type
)))
5273 /* NB: If a default constructor is not available, we will not
5274 call the destructor either, for symmetry. */
5280 /* Generate '- .cxx_construct' if needed. */
5283 objc_generate_cxx_ctor_or_dtor (false);
5285 /* Generate '- .cxx_destruct' if needed. */
5288 objc_generate_cxx_ctor_or_dtor (true);
5290 /* The 'imp_list' variable points at an imp_entry record for the current
5291 @implementation. Record the existence of '- .cxx_construct' and/or
5292 '- .cxx_destruct' methods therein; it will be included in the
5293 metadata for the class. */
5294 if (flag_next_runtime
)
5295 imp_list
->has_cxx_cdtors
= (need_ctor
|| need_dtor
);
5299 /* For each protocol which was referenced either from a @protocol()
5300 expression, or because a class/category implements it (then a
5301 pointer to the protocol is stored in the struct describing the
5302 class/category), we create a statically allocated instance of the
5303 Protocol class. The code is written in such a way as to generate
5304 as few Protocol objects as possible; we generate a unique Protocol
5305 instance for each protocol, and we don't generate a Protocol
5306 instance if the protocol is never referenced (either from a
5307 @protocol() or from a class/category implementation). These
5308 statically allocated objects can be referred to via the static
5309 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
5311 The statically allocated Protocol objects that we generate here
5312 need to be fixed up at runtime in order to be used: the 'isa'
5313 pointer of the objects need to be set up to point to the 'Protocol'
5314 class, as known at runtime.
5316 The NeXT runtime fixes up all protocols at program startup time,
5317 before main() is entered. It uses a low-level trick to look up all
5318 those symbols, then loops on them and fixes them up.
5320 The GNU runtime as well fixes up all protocols before user code
5321 from the module is executed; it requires pointers to those symbols
5322 to be put in the objc_symtab (which is then passed as argument to
5323 the function __objc_exec_class() which the compiler sets up to be
5324 executed automatically when the module is loaded); setup of those
5325 Protocol objects happen in two ways in the GNU runtime: all
5326 Protocol objects referred to by a class or category implementation
5327 are fixed up when the class/category is loaded; all Protocol
5328 objects referred to by a @protocol() expression are added by the
5329 compiler to the list of statically allocated instances to fixup
5330 (the same list holding the statically allocated constant string
5331 objects). Because, as explained above, the compiler generates as
5332 few Protocol objects as possible, some Protocol object might end up
5333 being referenced multiple times when compiled with the GNU runtime,
5334 and end up being fixed up multiple times at runtime initialization.
5335 But that doesn't hurt, it's just a little inefficient. */
5338 generate_protocols (void)
5342 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
5344 /* If a protocol was directly referenced, pull in indirect references. */
5345 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
5346 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
5347 generate_protocol_references (PROTOCOL_LIST (p
));
5349 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
5351 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
5352 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
5354 /* If protocol wasn't referenced, don't generate any code. */
5355 decl
= PROTOCOL_FORWARD_DECL (p
);
5360 /* Make sure we link in the Protocol class. */
5361 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
5365 if (! METHOD_ENCODING (nst_methods
))
5367 encoding
= encode_method_prototype (nst_methods
);
5368 METHOD_ENCODING (nst_methods
) = encoding
;
5370 nst_methods
= DECL_CHAIN (nst_methods
);
5375 if (! METHOD_ENCODING (cls_methods
))
5377 encoding
= encode_method_prototype (cls_methods
);
5378 METHOD_ENCODING (cls_methods
) = encoding
;
5381 cls_methods
= DECL_CHAIN (cls_methods
);
5383 generate_method_descriptors (p
);
5385 if (PROTOCOL_LIST (p
))
5386 refs_decl
= generate_protocol_list (p
);
5390 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5391 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
5394 refs_expr
= convert (build_pointer_type (build_pointer_type
5395 (objc_protocol_template
)),
5396 build_unary_op (input_location
,
5397 ADDR_EXPR
, refs_decl
, 0));
5399 refs_expr
= build_int_cst (NULL_TREE
, 0);
5401 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
5402 by generate_method_descriptors, which is called above. */
5403 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
5404 protocol_name_expr
, refs_expr
,
5405 UOBJC_INSTANCE_METHODS_decl
,
5406 UOBJC_CLASS_METHODS_decl
);
5407 finish_var_decl (decl
, initlist
);
5412 build_protocol_initializer (tree type
, tree protocol_name
,
5413 tree protocol_list
, tree instance_methods
,
5417 tree cast_type
= build_pointer_type
5418 (xref_tag (RECORD_TYPE
,
5419 get_identifier (UTAG_CLASS
)));
5420 VEC(constructor_elt
,gc
) *inits
= NULL
;
5422 /* Filling the "isa" in with one allows the runtime system to
5423 detect that the version change...should remove before final release. */
5425 expr
= build_int_cst (cast_type
, PROTOCOL_VERSION
);
5426 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
5427 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_name
);
5428 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_list
);
5430 if (!instance_methods
)
5431 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
5434 expr
= convert (objc_method_proto_list_ptr
,
5435 build_unary_op (input_location
,
5436 ADDR_EXPR
, instance_methods
, 0));
5437 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
5441 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
5444 expr
= convert (objc_method_proto_list_ptr
,
5445 build_unary_op (input_location
,
5446 ADDR_EXPR
, class_methods
, 0));
5447 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
5450 return objc_build_constructor (type
, inits
);
5453 /* struct _objc_category {
5454 char *category_name;
5456 struct _objc_method_list *instance_methods;
5457 struct _objc_method_list *class_methods;
5458 struct _objc_protocol_list *protocols;
5462 build_category_template (void)
5464 tree ptype
, decls
, *chain
= NULL
;
5466 objc_category_template
= objc_start_struct (get_identifier (UTAG_CATEGORY
));
5468 /* char *category_name; */
5469 decls
= add_field_decl (string_type_node
, "category_name", &chain
);
5471 /* char *class_name; */
5472 add_field_decl (string_type_node
, "class_name", &chain
);
5474 /* struct _objc_method_list *instance_methods; */
5475 add_field_decl (objc_method_list_ptr
, "instance_methods", &chain
);
5477 /* struct _objc_method_list *class_methods; */
5478 add_field_decl (objc_method_list_ptr
, "class_methods", &chain
);
5480 /* struct _objc_protocol **protocol_list; */
5481 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
5482 add_field_decl (ptype
, "protocol_list", &chain
);
5484 objc_finish_struct (objc_category_template
, decls
);
5487 /* struct _objc_selector {
5493 build_selector_template (void)
5495 tree decls
, *chain
= NULL
;
5497 objc_selector_template
= objc_start_struct (get_identifier (UTAG_SELECTOR
));
5500 decls
= add_field_decl (objc_selector_type
, "sel_id", &chain
);
5502 /* char *sel_type; */
5503 add_field_decl (string_type_node
, "sel_type", &chain
);
5505 objc_finish_struct (objc_selector_template
, decls
);
5508 /* struct _objc_class {
5509 struct _objc_class *isa;
5510 struct _objc_class *super_class;
5515 struct _objc_ivar_list *ivars;
5516 struct _objc_method_list *methods;
5517 #ifdef __NEXT_RUNTIME__
5518 struct objc_cache *cache;
5520 struct sarray *dtable;
5521 struct _objc_class *subclass_list;
5522 struct _objc_class *sibling_class;
5524 struct _objc_protocol_list *protocols;
5525 #ifdef __NEXT_RUNTIME__
5528 void *gc_object_type;
5531 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
5532 the NeXT/Apple runtime; still, the compiler must generate them to
5533 maintain backward binary compatibility (and to allow for future
5537 build_class_template (void)
5539 tree ptype
, decls
, *chain
= NULL
;
5541 objc_class_template
= objc_start_struct (get_identifier (UTAG_CLASS
));
5543 /* struct _objc_class *isa; */
5544 decls
= add_field_decl (build_pointer_type (objc_class_template
),
5547 /* struct _objc_class *super_class; */
5548 add_field_decl (build_pointer_type (objc_class_template
),
5549 "super_class", &chain
);
5552 add_field_decl (string_type_node
, "name", &chain
);
5555 add_field_decl (long_integer_type_node
, "version", &chain
);
5558 add_field_decl (long_integer_type_node
, "info", &chain
);
5560 /* long instance_size; */
5561 add_field_decl (long_integer_type_node
, "instance_size", &chain
);
5563 /* struct _objc_ivar_list *ivars; */
5564 add_field_decl (objc_ivar_list_ptr
,"ivars", &chain
);
5566 /* struct _objc_method_list *methods; */
5567 add_field_decl (objc_method_list_ptr
, "methods", &chain
);
5569 if (flag_next_runtime
)
5571 /* struct objc_cache *cache; */
5572 ptype
= build_pointer_type (xref_tag (RECORD_TYPE
,
5573 get_identifier ("objc_cache")));
5574 add_field_decl (ptype
, "cache", &chain
);
5578 /* struct sarray *dtable; */
5579 ptype
= build_pointer_type(xref_tag (RECORD_TYPE
,
5580 get_identifier ("sarray")));
5581 add_field_decl (ptype
, "dtable", &chain
);
5583 /* struct objc_class *subclass_list; */
5584 ptype
= build_pointer_type (objc_class_template
);
5585 add_field_decl (ptype
, "subclass_list", &chain
);
5587 /* struct objc_class *sibling_class; */
5588 ptype
= build_pointer_type (objc_class_template
);
5589 add_field_decl (ptype
, "sibling_class", &chain
);
5592 /* struct _objc_protocol **protocol_list; */
5593 ptype
= build_pointer_type (build_pointer_type
5594 (xref_tag (RECORD_TYPE
,
5595 get_identifier (UTAG_PROTOCOL
))));
5596 add_field_decl (ptype
, "protocol_list", &chain
);
5598 if (flag_next_runtime
)
5601 add_field_decl (build_pointer_type (void_type_node
), "sel_id", &chain
);
5604 /* void *gc_object_type; */
5605 add_field_decl (build_pointer_type (void_type_node
),
5606 "gc_object_type", &chain
);
5608 objc_finish_struct (objc_class_template
, decls
);
5611 /* Generate appropriate forward declarations for an implementation. */
5614 synth_forward_declarations (void)
5618 /* static struct objc_class _OBJC_CLASS_<my_name>; */
5619 UOBJC_CLASS_decl
= build_metadata_decl ("_OBJC_CLASS",
5620 objc_class_template
);
5622 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
5623 UOBJC_METACLASS_decl
= build_metadata_decl ("_OBJC_METACLASS",
5624 objc_class_template
);
5626 /* Pre-build the following entities - for speed/convenience. */
5628 an_id
= get_identifier ("super_class");
5629 ucls_super_ref
= objc_build_component_ref (UOBJC_CLASS_decl
, an_id
);
5630 uucls_super_ref
= objc_build_component_ref (UOBJC_METACLASS_decl
, an_id
);
5634 error_with_ivar (const char *message
, tree decl
)
5636 error_at (DECL_SOURCE_LOCATION (decl
), "%s %qs",
5637 message
, identifier_to_locale (gen_declaration (decl
)));
5642 check_ivars (tree inter
, tree imp
)
5644 tree intdecls
= CLASS_RAW_IVARS (inter
);
5645 tree impdecls
= CLASS_RAW_IVARS (imp
);
5652 if (intdecls
&& TREE_CODE (intdecls
) == TYPE_DECL
)
5653 intdecls
= TREE_CHAIN (intdecls
);
5655 if (intdecls
== 0 && impdecls
== 0)
5657 if (intdecls
== 0 || impdecls
== 0)
5659 error ("inconsistent instance variable specification");
5663 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
5665 if (!comptypes (t1
, t2
)
5666 || !tree_int_cst_equal (DECL_INITIAL (intdecls
),
5667 DECL_INITIAL (impdecls
)))
5669 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
5671 error_with_ivar ("conflicting instance variable type",
5673 error_with_ivar ("previous declaration of",
5676 else /* both the type and the name don't match */
5678 error ("inconsistent instance variable specification");
5683 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
5685 error_with_ivar ("conflicting instance variable name",
5687 error_with_ivar ("previous declaration of",
5691 intdecls
= DECL_CHAIN (intdecls
);
5692 impdecls
= DECL_CHAIN (impdecls
);
5696 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5697 This needs to be done just once per compilation. */
5699 /* struct _objc_super {
5700 struct _objc_object *self;
5701 struct _objc_class *super_class;
5705 build_super_template (void)
5707 tree decls
, *chain
= NULL
;
5709 objc_super_template
= objc_start_struct (get_identifier (UTAG_SUPER
));
5711 /* struct _objc_object *self; */
5712 decls
= add_field_decl (objc_object_type
, "self", &chain
);
5714 /* struct _objc_class *super_class; */
5715 add_field_decl (build_pointer_type (objc_class_template
),
5716 "super_class", &chain
);
5718 objc_finish_struct (objc_super_template
, decls
);
5721 /* struct _objc_ivar {
5728 build_ivar_template (void)
5730 tree objc_ivar_id
, objc_ivar_record
;
5731 tree decls
, *chain
= NULL
;
5733 objc_ivar_id
= get_identifier (UTAG_IVAR
);
5734 objc_ivar_record
= objc_start_struct (objc_ivar_id
);
5736 /* char *ivar_name; */
5737 decls
= add_field_decl (string_type_node
, "ivar_name", &chain
);
5739 /* char *ivar_type; */
5740 add_field_decl (string_type_node
, "ivar_type", &chain
);
5742 /* int ivar_offset; */
5743 add_field_decl (integer_type_node
, "ivar_offset", &chain
);
5745 objc_finish_struct (objc_ivar_record
, decls
);
5747 return objc_ivar_record
;
5752 struct objc_ivar ivar_list[ivar_count];
5756 build_ivar_list_template (tree list_type
, int size
)
5758 tree objc_ivar_list_record
;
5759 tree array_type
, decls
, *chain
= NULL
;
5761 objc_ivar_list_record
= objc_start_struct (NULL_TREE
);
5763 /* int ivar_count; */
5764 decls
= add_field_decl (integer_type_node
, "ivar_count", &chain
);
5766 /* struct objc_ivar ivar_list[]; */
5767 array_type
= build_sized_array_type (list_type
, size
);
5768 add_field_decl (array_type
, "ivar_list", &chain
);
5770 objc_finish_struct (objc_ivar_list_record
, decls
);
5772 return objc_ivar_list_record
;
5776 struct _objc__method_prototype_list *method_next;
5778 struct objc_method method_list[method_count];
5782 build_method_list_template (tree list_type
, int size
)
5784 tree objc_ivar_list_record
;
5785 tree array_type
, decls
, *chain
= NULL
;
5787 objc_ivar_list_record
= objc_start_struct (NULL_TREE
);
5789 /* struct _objc__method_prototype_list *method_next; */
5790 decls
= add_field_decl (objc_method_proto_list_ptr
, "method_next", &chain
);
5792 /* int method_count; */
5793 add_field_decl (integer_type_node
, "method_count", &chain
);
5795 /* struct objc_method method_list[]; */
5796 array_type
= build_sized_array_type (list_type
, size
);
5797 add_field_decl (array_type
, "method_list", &chain
);
5799 objc_finish_struct (objc_ivar_list_record
, decls
);
5801 return objc_ivar_list_record
;
5805 build_ivar_list_initializer (tree type
, tree field_decl
)
5807 VEC(constructor_elt
,gc
) *inits
= NULL
;
5811 VEC(constructor_elt
,gc
) *ivar
= NULL
;
5815 if (DECL_NAME (field_decl
))
5816 CONSTRUCTOR_APPEND_ELT (ivar
, NULL_TREE
,
5817 add_objc_string (DECL_NAME (field_decl
),
5820 /* Unnamed bit-field ivar (yuck). */
5821 CONSTRUCTOR_APPEND_ELT (ivar
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
5824 encode_field_decl (field_decl
,
5825 obstack_object_size (&util_obstack
),
5826 OBJC_ENCODE_DONT_INLINE_DEFS
);
5828 /* Null terminate string. */
5829 obstack_1grow (&util_obstack
, 0);
5830 id
= add_objc_string (get_identifier (XOBFINISH (&util_obstack
, char *)),
5832 CONSTRUCTOR_APPEND_ELT (ivar
, NULL_TREE
, id
);
5833 obstack_free (&util_obstack
, util_firstobj
);
5836 CONSTRUCTOR_APPEND_ELT (ivar
, NULL_TREE
, byte_position (field_decl
));
5837 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
,
5838 objc_build_constructor (type
, ivar
));
5840 field_decl
= DECL_CHAIN (field_decl
);
5841 while (field_decl
&& TREE_CODE (field_decl
) != FIELD_DECL
);
5845 return objc_build_constructor (build_array_type (type
, 0), inits
);
5849 generate_ivars_list (tree type
, const char *name
, int size
, tree list
)
5852 VEC(constructor_elt
,gc
) *inits
= NULL
;
5854 decl
= start_var_decl (type
, synth_id_with_class_suffix
5855 (name
, objc_implementation_context
));
5857 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
5858 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, list
);
5860 finish_var_decl (decl
,
5861 objc_build_constructor (TREE_TYPE (decl
), inits
));
5866 /* Count only the fields occurring in T. */
5869 ivar_list_length (tree t
)
5873 for (; t
; t
= DECL_CHAIN (t
))
5874 if (TREE_CODE (t
) == FIELD_DECL
)
5881 generate_ivar_lists (void)
5883 tree initlist
, ivar_list_template
, chain
;
5886 generating_instance_variables
= 1;
5888 if (!objc_ivar_template
)
5889 objc_ivar_template
= build_ivar_template ();
5891 /* Only generate class variables for the root of the inheritance
5892 hierarchy since these will be the same for every class. */
5894 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
5895 && (chain
= TYPE_FIELDS (objc_class_template
)))
5897 size
= ivar_list_length (chain
);
5899 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
5900 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
5902 UOBJC_CLASS_VARIABLES_decl
5903 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
5907 UOBJC_CLASS_VARIABLES_decl
= 0;
5909 chain
= CLASS_IVARS (implementation_template
);
5912 size
= ivar_list_length (chain
);
5913 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
5914 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
5916 UOBJC_INSTANCE_VARIABLES_decl
5917 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
5921 UOBJC_INSTANCE_VARIABLES_decl
= 0;
5923 generating_instance_variables
= 0;
5927 build_dispatch_table_initializer (tree type
, tree entries
)
5929 VEC(constructor_elt
,gc
) *inits
= NULL
;
5933 VEC(constructor_elt
,gc
) *elems
= NULL
;
5936 CONSTRUCTOR_APPEND_ELT (elems
, NULL_TREE
,
5937 build_selector (METHOD_SEL_NAME (entries
)));
5939 /* Generate the method encoding if we don't have one already. */
5940 if (! METHOD_ENCODING (entries
))
5941 METHOD_ENCODING (entries
) =
5942 encode_method_prototype (entries
);
5944 CONSTRUCTOR_APPEND_ELT (elems
, NULL_TREE
,
5945 add_objc_string (METHOD_ENCODING (entries
),
5948 expr
= convert (ptr_type_node
,
5949 build_unary_op (input_location
, ADDR_EXPR
,
5950 METHOD_DEFINITION (entries
), 1));
5951 CONSTRUCTOR_APPEND_ELT (elems
, NULL_TREE
, expr
);
5953 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
,
5954 objc_build_constructor (type
, elems
));
5956 entries
= DECL_CHAIN (entries
);
5960 return objc_build_constructor (build_array_type (type
, 0), inits
);
5963 /* To accomplish method prototyping without generating all kinds of
5964 inane warnings, the definition of the dispatch table entries were
5967 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5969 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5972 build_method_template (void)
5975 tree decls
, *chain
= NULL
;
5977 _SLT_record
= objc_start_struct (get_identifier (UTAG_METHOD
));
5980 decls
= add_field_decl (objc_selector_type
, "_cmd", &chain
);
5982 /* char *method_types; */
5983 add_field_decl (string_type_node
, "method_types", &chain
);
5986 add_field_decl (build_pointer_type (void_type_node
), "_imp", &chain
);
5988 objc_finish_struct (_SLT_record
, decls
);
5995 generate_dispatch_table (tree type
, const char *name
, int size
, tree list
)
5998 VEC(constructor_elt
,gc
) *v
= NULL
;
6000 decl
= start_var_decl (type
, synth_id_with_class_suffix
6001 (name
, objc_implementation_context
));
6003 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
6004 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (integer_type_node
, size
));
6005 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, list
);
6007 finish_var_decl (decl
,
6008 objc_build_constructor (TREE_TYPE (decl
), v
));
6014 mark_referenced_methods (void)
6016 struct imp_entry
*impent
;
6019 for (impent
= imp_list
; impent
; impent
= impent
->next
)
6021 chain
= CLASS_CLS_METHODS (impent
->imp_context
);
6024 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
6025 chain
= DECL_CHAIN (chain
);
6028 chain
= CLASS_NST_METHODS (impent
->imp_context
);
6031 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
6032 chain
= DECL_CHAIN (chain
);
6038 generate_dispatch_tables (void)
6040 tree initlist
, chain
, method_list_template
;
6043 if (!objc_method_template
)
6044 objc_method_template
= build_method_template ();
6046 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
6049 size
= list_length (chain
);
6051 method_list_template
6052 = build_method_list_template (objc_method_template
, size
);
6054 = build_dispatch_table_initializer (objc_method_template
, chain
);
6056 UOBJC_CLASS_METHODS_decl
6057 = generate_dispatch_table (method_list_template
,
6058 ((TREE_CODE (objc_implementation_context
)
6059 == CLASS_IMPLEMENTATION_TYPE
)
6060 ? "_OBJC_CLASS_METHODS"
6061 : "_OBJC_CATEGORY_CLASS_METHODS"),
6065 UOBJC_CLASS_METHODS_decl
= 0;
6067 chain
= CLASS_NST_METHODS (objc_implementation_context
);
6070 size
= list_length (chain
);
6072 method_list_template
6073 = build_method_list_template (objc_method_template
, size
);
6075 = build_dispatch_table_initializer (objc_method_template
, chain
);
6077 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
6078 UOBJC_INSTANCE_METHODS_decl
6079 = generate_dispatch_table (method_list_template
,
6080 "_OBJC_INSTANCE_METHODS",
6083 /* We have a category. */
6084 UOBJC_INSTANCE_METHODS_decl
6085 = generate_dispatch_table (method_list_template
,
6086 "_OBJC_CATEGORY_INSTANCE_METHODS",
6090 UOBJC_INSTANCE_METHODS_decl
= 0;
6094 generate_protocol_list (tree i_or_p
)
6096 tree array_type
, ptype
, refs_decl
, lproto
, e
, plist
;
6098 const char *ref_name
;
6099 VEC(constructor_elt
,gc
) *v
= NULL
;
6101 switch (TREE_CODE (i_or_p
))
6103 case CLASS_INTERFACE_TYPE
:
6104 case CATEGORY_INTERFACE_TYPE
:
6105 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
6107 case PROTOCOL_INTERFACE_TYPE
:
6108 plist
= PROTOCOL_LIST (i_or_p
);
6115 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
6116 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
6117 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
6120 /* Build initializer. */
6121 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6122 e
= build_int_cst (build_pointer_type (objc_protocol_template
), size
);
6123 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
6125 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
6127 tree pval
= TREE_VALUE (lproto
);
6129 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
6130 && PROTOCOL_FORWARD_DECL (pval
))
6132 e
= build_unary_op (input_location
, ADDR_EXPR
,
6133 PROTOCOL_FORWARD_DECL (pval
), 0);
6134 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
6138 /* static struct objc_protocol *refs[n]; */
6140 switch (TREE_CODE (i_or_p
))
6142 case PROTOCOL_INTERFACE_TYPE
:
6143 ref_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p
);
6145 case CLASS_INTERFACE_TYPE
:
6146 ref_name
= synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p
);
6148 case CATEGORY_INTERFACE_TYPE
:
6149 ref_name
= synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p
);
6155 ptype
= build_pointer_type (objc_protocol_template
);
6156 array_type
= build_sized_array_type (ptype
, size
+ 3);
6157 refs_decl
= start_var_decl (array_type
, ref_name
);
6159 finish_var_decl (refs_decl
,
6160 objc_build_constructor (TREE_TYPE (refs_decl
), v
));
6166 build_category_initializer (tree type
, tree cat_name
, tree class_name
,
6167 tree instance_methods
, tree class_methods
,
6171 VEC(constructor_elt
,gc
) *v
= NULL
;
6173 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, cat_name
);
6174 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, class_name
);
6176 if (!instance_methods
)
6177 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6180 expr
= convert (objc_method_list_ptr
,
6181 build_unary_op (input_location
, ADDR_EXPR
,
6182 instance_methods
, 0));
6183 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6186 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6189 expr
= convert (objc_method_list_ptr
,
6190 build_unary_op (input_location
, ADDR_EXPR
,
6192 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6195 /* protocol_list = */
6197 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6200 expr
= convert (build_pointer_type
6202 (objc_protocol_template
)),
6203 build_unary_op (input_location
, ADDR_EXPR
,
6205 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6208 return objc_build_constructor (type
, v
);
6211 /* struct _objc_class {
6212 struct objc_class *isa;
6213 struct objc_class *super_class;
6218 struct objc_ivar_list *ivars;
6219 struct objc_method_list *methods;
6220 if (flag_next_runtime)
6221 struct objc_cache *cache;
6223 struct sarray *dtable;
6224 struct objc_class *subclass_list;
6225 struct objc_class *sibling_class;
6227 struct objc_protocol_list *protocols;
6228 if (flag_next_runtime)
6230 void *gc_object_type;
6234 build_shared_structure_initializer (tree type
, tree isa
, tree super
,
6235 tree name
, tree size
, int status
,
6236 tree dispatch_table
, tree ivar_list
,
6240 VEC(constructor_elt
,gc
) *v
= NULL
;
6243 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, isa
);
6246 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, super
);
6249 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, default_conversion (name
));
6252 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
6253 build_int_cst (long_integer_type_node
, 0));
6256 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
6257 build_int_cst (long_integer_type_node
, status
));
6259 /* instance_size = */
6260 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
6261 convert (long_integer_type_node
, size
));
6263 /* objc_ivar_list = */
6265 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6268 expr
= convert (objc_ivar_list_ptr
,
6269 build_unary_op (input_location
, ADDR_EXPR
,
6271 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6274 /* objc_method_list = */
6275 if (!dispatch_table
)
6276 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6279 expr
= convert (objc_method_list_ptr
,
6280 build_unary_op (input_location
, ADDR_EXPR
,
6281 dispatch_table
, 0));
6282 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6285 if (flag_next_runtime
)
6286 /* method_cache = */
6287 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6291 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6293 /* subclass_list = */
6294 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6296 /* sibling_class = */
6297 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6300 /* protocol_list = */
6301 if (! protocol_list
)
6302 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6305 expr
= convert (build_pointer_type
6307 (objc_protocol_template
)),
6308 build_unary_op (input_location
, ADDR_EXPR
,
6310 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6313 if (flag_next_runtime
)
6315 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6317 /* gc_object_type = NULL */
6318 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6320 return objc_build_constructor (type
, v
);
6323 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
6326 lookup_category (tree klass
, tree cat_name
)
6328 tree category
= CLASS_CATEGORY_LIST (klass
);
6330 while (category
&& CLASS_SUPER_NAME (category
) != cat_name
)
6331 category
= CLASS_CATEGORY_LIST (category
);
6335 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
6338 generate_category (struct imp_entry
*impent
)
6340 tree initlist
, cat_name_expr
, class_name_expr
;
6341 tree protocol_decl
, category
;
6342 tree cat
= impent
->imp_context
;
6344 implementation_template
= impent
->imp_template
;
6345 UOBJC_CLASS_decl
= impent
->class_decl
;
6346 UOBJC_METACLASS_decl
= impent
->meta_decl
;
6348 add_class_reference (CLASS_NAME (cat
));
6349 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
6351 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
6353 category
= lookup_category (implementation_template
,
6354 CLASS_SUPER_NAME (cat
));
6356 if (category
&& CLASS_PROTOCOL_LIST (category
))
6358 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
6359 protocol_decl
= generate_protocol_list (category
);
6364 initlist
= build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl
),
6365 cat_name_expr
, class_name_expr
,
6366 UOBJC_INSTANCE_METHODS_decl
,
6367 UOBJC_CLASS_METHODS_decl
,
6369 /* Finish and initialize the forward decl. */
6370 finish_var_decl (UOBJC_CLASS_decl
, initlist
);
6373 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
6374 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6377 generate_shared_structures (struct imp_entry
*impent
)
6379 tree name_expr
, super_expr
, root_expr
;
6380 tree my_root_id
, my_super_id
;
6381 tree cast_type
, initlist
, protocol_decl
;
6384 objc_implementation_context
= impent
->imp_context
;
6385 implementation_template
= impent
->imp_template
;
6386 UOBJC_CLASS_decl
= impent
->class_decl
;
6387 UOBJC_METACLASS_decl
= impent
->meta_decl
;
6388 cls_flags
= impent
->has_cxx_cdtors
? CLS_HAS_CXX_STRUCTORS
: 0 ;
6390 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
6393 add_class_reference (my_super_id
);
6395 /* Compute "my_root_id" - this is required for code generation.
6396 the "isa" for all meta class structures points to the root of
6397 the inheritance hierarchy (e.g. "__Object")... */
6398 my_root_id
= my_super_id
;
6401 tree my_root_int
= lookup_interface (my_root_id
);
6403 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
6404 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
6411 /* No super class. */
6412 my_root_id
= CLASS_NAME (implementation_template
);
6414 cast_type
= build_pointer_type (objc_class_template
);
6415 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
6418 /* Install class `isa' and `super' pointers at runtime. */
6420 super_expr
= add_objc_string (my_super_id
, class_names
);
6422 super_expr
= integer_zero_node
;
6424 super_expr
= build_c_cast (input_location
,
6425 cast_type
, super_expr
); /* cast! */
6427 root_expr
= add_objc_string (my_root_id
, class_names
);
6428 root_expr
= build_c_cast (input_location
, cast_type
, root_expr
); /* cast! */
6430 if (CLASS_PROTOCOL_LIST (implementation_template
))
6432 generate_protocol_references
6433 (CLASS_PROTOCOL_LIST (implementation_template
));
6434 protocol_decl
= generate_protocol_list (implementation_template
);
6439 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
6442 = build_shared_structure_initializer
6443 (TREE_TYPE (UOBJC_METACLASS_decl
),
6444 root_expr
, super_expr
, name_expr
,
6445 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
6447 UOBJC_CLASS_METHODS_decl
,
6448 UOBJC_CLASS_VARIABLES_decl
,
6451 finish_var_decl (UOBJC_METACLASS_decl
, initlist
);
6453 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6456 = build_shared_structure_initializer
6457 (TREE_TYPE (UOBJC_CLASS_decl
),
6458 build_unary_op (input_location
, ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
6459 super_expr
, name_expr
,
6460 convert (integer_type_node
,
6461 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
6462 (implementation_template
))),
6463 1 /*CLS_FACTORY*/ | cls_flags
,
6464 UOBJC_INSTANCE_METHODS_decl
,
6465 UOBJC_INSTANCE_VARIABLES_decl
,
6468 finish_var_decl (UOBJC_CLASS_decl
, initlist
);
6473 synth_id_with_class_suffix (const char *preamble
, tree ctxt
)
6475 static char string
[BUFSIZE
];
6477 switch (TREE_CODE (ctxt
))
6479 case CLASS_IMPLEMENTATION_TYPE
:
6480 case CLASS_INTERFACE_TYPE
:
6481 sprintf (string
, "%s_%s", preamble
,
6482 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
6484 case CATEGORY_IMPLEMENTATION_TYPE
:
6485 case CATEGORY_INTERFACE_TYPE
:
6487 /* We have a category. */
6488 const char *const class_name
6489 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
6490 const char *const class_super_name
6491 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
6492 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
6495 case PROTOCOL_INTERFACE_TYPE
:
6497 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
6498 sprintf (string
, "%s_%s", preamble
, protocol_name
);
6508 /* If type is empty or only type qualifiers are present, add default
6509 type of id (otherwise grokdeclarator will default to int). */
6511 adjust_type_for_id_default (tree type
)
6514 type
= make_node (TREE_LIST
);
6516 if (!TREE_VALUE (type
))
6517 TREE_VALUE (type
) = objc_object_type
;
6518 else if (TREE_CODE (TREE_VALUE (type
)) == RECORD_TYPE
6519 && TYPED_OBJECT (TREE_VALUE (type
)))
6520 error ("can not use an object as parameter to a method");
6525 /* Return a KEYWORD_DECL built using the specified key_name, arg_type,
6526 arg_name and attributes. (TODO: Rename KEYWORD_DECL to
6527 OBJC_METHOD_PARM_DECL ?)
6529 A KEYWORD_DECL is a tree representing the declaration of a
6530 parameter of an Objective-C method. It is produced when parsing a
6531 fragment of Objective-C method declaration of the form
6534 selector ':' '(' typename ')' identifier
6536 For example, take the Objective-C method
6538 -(NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type;
6540 the two fragments "pathForResource:(NSString *)resource" and
6541 "ofType:(NSString *)type" will generate a KEYWORD_DECL each. The
6542 KEYWORD_DECL stores the 'key_name' (eg, identifier for
6543 "pathForResource"), the 'arg_type' (eg, tree representing a
6544 NSString *), the 'arg_name' (eg identifier for "resource") and
6545 potentially some attributes (for example, a tree representing
6546 __attribute__ ((unused)) if such an attribute was attached to a
6547 certain parameter). You can access this information using the
6548 TREE_TYPE (for arg_type), KEYWORD_ARG_NAME (for arg_name),
6549 KEYWORD_KEY_NAME (for key_name), DECL_ATTRIBUTES (for attributes).
6551 'key_name' is an identifier node (and is optional as you can omit
6552 it in Objective-C methods).
6553 'arg_type' is a tree list (and is optional too if no parameter type
6555 'arg_name' is an identifier node and is required.
6556 'attributes' is an optional tree containing parameter attributes. */
6558 objc_build_keyword_decl (tree key_name
, tree arg_type
,
6559 tree arg_name
, tree attributes
)
6563 /* If no type is specified, default to "id". */
6564 arg_type
= adjust_type_for_id_default (arg_type
);
6566 keyword_decl
= make_node (KEYWORD_DECL
);
6568 TREE_TYPE (keyword_decl
) = arg_type
;
6569 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
6570 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
6571 DECL_ATTRIBUTES (keyword_decl
) = attributes
;
6573 return keyword_decl
;
6576 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
6578 build_keyword_selector (tree selector
)
6581 tree key_chain
, key_name
;
6584 /* Scan the selector to see how much space we'll need. */
6585 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
6587 switch (TREE_CODE (selector
))
6590 key_name
= KEYWORD_KEY_NAME (key_chain
);
6593 key_name
= TREE_PURPOSE (key_chain
);
6600 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
6602 /* Just a ':' arg. */
6606 buf
= (char *) alloca (len
+ 1);
6607 /* Start the buffer out as an empty string. */
6610 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
6612 switch (TREE_CODE (selector
))
6615 key_name
= KEYWORD_KEY_NAME (key_chain
);
6618 key_name
= TREE_PURPOSE (key_chain
);
6619 /* The keyword decl chain will later be used as a function
6620 argument chain. Unhook the selector itself so as to not
6621 confuse other parts of the compiler. */
6622 TREE_PURPOSE (key_chain
) = NULL_TREE
;
6629 strcat (buf
, IDENTIFIER_POINTER (key_name
));
6633 return get_identifier (buf
);
6636 /* Used for declarations and definitions. */
6639 build_method_decl (enum tree_code code
, tree ret_type
, tree selector
,
6640 tree add_args
, bool ellipsis
)
6644 /* If no type is specified, default to "id". */
6645 ret_type
= adjust_type_for_id_default (ret_type
);
6647 method_decl
= make_node (code
);
6648 TREE_TYPE (method_decl
) = ret_type
;
6650 /* If we have a keyword selector, create an identifier_node that
6651 represents the full selector name (`:' included)... */
6652 if (TREE_CODE (selector
) == KEYWORD_DECL
)
6654 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
6655 METHOD_SEL_ARGS (method_decl
) = selector
;
6656 METHOD_ADD_ARGS (method_decl
) = add_args
;
6657 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl
) = ellipsis
;
6661 METHOD_SEL_NAME (method_decl
) = selector
;
6662 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
6663 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
6669 #define METHOD_DEF 0
6670 #define METHOD_REF 1
6672 /* This routine processes objective-c method attributes. */
6675 objc_decl_method_attributes (tree
*node
, tree attributes
, int flags
)
6677 tree sentinel_attr
= lookup_attribute ("sentinel", attributes
);
6680 /* hackery to make an obj method look like a function type. */
6681 tree rettype
= TREE_TYPE (*node
);
6682 TREE_TYPE (*node
) = build_function_type (TREE_VALUE (rettype
),
6683 get_arg_type_list (*node
, METHOD_REF
, 0));
6684 decl_attributes (node
, attributes
, flags
);
6685 METHOD_TYPE_ATTRIBUTES (*node
) = TYPE_ATTRIBUTES (TREE_TYPE (*node
));
6686 TREE_TYPE (*node
) = rettype
;
6689 decl_attributes (node
, attributes
, flags
);
6693 objc_method_decl (enum tree_code opcode
)
6695 return opcode
== INSTANCE_METHOD_DECL
|| opcode
== CLASS_METHOD_DECL
;
6698 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6699 an argument list for method METH. CONTEXT is either METHOD_DEF or
6700 METHOD_REF, saying whether we are trying to define a method or call
6701 one. SUPERFLAG says this is for a send to super; this makes a
6702 difference for the NeXT calling sequence in which the lookup and
6703 the method call are done together. If METH is null, user-defined
6704 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6707 get_arg_type_list (tree meth
, int context
, int superflag
)
6711 /* Receiver type. */
6712 if (flag_next_runtime
&& superflag
)
6713 arglist
= build_tree_list (NULL_TREE
, objc_super_type
);
6714 else if (context
== METHOD_DEF
&& TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
6715 arglist
= build_tree_list (NULL_TREE
, objc_instance_type
);
6717 arglist
= build_tree_list (NULL_TREE
, objc_object_type
);
6719 /* Selector type - will eventually change to `int'. */
6720 chainon (arglist
, build_tree_list (NULL_TREE
, objc_selector_type
));
6722 /* No actual method prototype given -- assume that remaining arguments
6727 /* Build a list of argument types. */
6728 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= DECL_CHAIN (akey
))
6730 tree arg_type
= TREE_VALUE (TREE_TYPE (akey
));
6732 /* Decay argument types for the underlying C function as appropriate. */
6733 arg_type
= objc_decay_parm_type (arg_type
);
6735 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
6738 if (METHOD_ADD_ARGS (meth
))
6740 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
6741 akey
; akey
= TREE_CHAIN (akey
))
6743 tree arg_type
= TREE_TYPE (TREE_VALUE (akey
));
6745 arg_type
= objc_decay_parm_type (arg_type
);
6747 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
6750 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth
))
6751 goto lack_of_ellipsis
;
6756 chainon (arglist
, OBJC_VOID_AT_END
);
6763 check_duplicates (hash hsh
, int methods
, int is_class
)
6765 tree meth
= NULL_TREE
;
6773 /* We have two or more methods with the same name but
6777 /* But just how different are those types? If
6778 -Wno-strict-selector-match is specified, we shall not
6779 complain if the differences are solely among types with
6780 identical size and alignment. */
6781 if (!warn_strict_selector_match
)
6783 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
6784 if (!comp_proto_with_proto (meth
, loop
->value
, 0))
6793 bool type
= TREE_CODE (meth
) == INSTANCE_METHOD_DECL
;
6795 warning_at (input_location
, 0,
6796 "multiple methods named %<%c%E%> found",
6797 (is_class
? '+' : '-'),
6798 METHOD_SEL_NAME (meth
));
6799 inform (DECL_SOURCE_LOCATION (meth
), "using %<%c%s%>",
6801 identifier_to_locale (gen_method_decl (meth
)));
6805 bool type
= TREE_CODE (meth
) == INSTANCE_METHOD_DECL
;
6807 warning_at (input_location
, 0,
6808 "multiple selectors named %<%c%E%> found",
6809 (is_class
? '+' : '-'),
6810 METHOD_SEL_NAME (meth
));
6811 inform (DECL_SOURCE_LOCATION (meth
), "found %<%c%s%>",
6813 identifier_to_locale (gen_method_decl (meth
)));
6816 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
6818 bool type
= TREE_CODE (loop
->value
) == INSTANCE_METHOD_DECL
;
6820 inform (DECL_SOURCE_LOCATION (loop
->value
), "also found %<%c%s%>",
6822 identifier_to_locale (gen_method_decl (loop
->value
)));
6829 /* If RECEIVER is a class reference, return the identifier node for
6830 the referenced class. RECEIVER is created by objc_get_class_reference,
6831 so we check the exact form created depending on which runtimes are
6835 receiver_is_class_object (tree receiver
, int self
, int super
)
6837 tree chain
, exp
, arg
;
6839 /* The receiver is 'self' or 'super' in the context of a class method. */
6840 if (objc_method_context
6841 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
6844 ? CLASS_SUPER_NAME (implementation_template
)
6845 : CLASS_NAME (implementation_template
));
6847 if (flag_next_runtime
)
6849 /* The receiver is a variable created by
6850 build_class_reference_decl. */
6851 if (TREE_CODE (receiver
) == VAR_DECL
&& IS_CLASS (TREE_TYPE (receiver
)))
6852 /* Look up the identifier. */
6853 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
6854 if (TREE_PURPOSE (chain
) == receiver
)
6855 return TREE_VALUE (chain
);
6858 /* The receiver is a function call that returns an id. Check if
6859 it is a call to objc_getClass, if so, pick up the class name. */
6860 if (TREE_CODE (receiver
) == CALL_EXPR
6861 && (exp
= CALL_EXPR_FN (receiver
))
6862 && TREE_CODE (exp
) == ADDR_EXPR
6863 && (exp
= TREE_OPERAND (exp
, 0))
6864 && TREE_CODE (exp
) == FUNCTION_DECL
6865 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6866 prototypes for objc_get_class(). Thankfully, they seem to share the
6867 same function type. */
6868 && TREE_TYPE (exp
) == TREE_TYPE (objc_get_class_decl
)
6869 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp
)), TAG_GETCLASS
)
6870 /* We have a call to objc_get_class/objc_getClass! */
6871 && (arg
= CALL_EXPR_ARG (receiver
, 0)))
6874 if (TREE_CODE (arg
) == ADDR_EXPR
6875 && (arg
= TREE_OPERAND (arg
, 0))
6876 && TREE_CODE (arg
) == STRING_CST
)
6877 /* Finally, we have the class name. */
6878 return get_identifier (TREE_STRING_POINTER (arg
));
6883 /* If we are currently building a message expr, this holds
6884 the identifier of the selector of the message. This is
6885 used when printing warnings about argument mismatches. */
6887 static tree current_objc_message_selector
= 0;
6890 objc_message_selector (void)
6892 return current_objc_message_selector
;
6895 /* Construct an expression for sending a message.
6896 MESS has the object to send to in TREE_PURPOSE
6897 and the argument list (including selector) in TREE_VALUE.
6899 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6900 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6903 objc_build_message_expr (tree mess
)
6905 tree receiver
= TREE_PURPOSE (mess
);
6908 tree args
= TREE_PURPOSE (TREE_VALUE (mess
));
6910 tree args
= TREE_VALUE (mess
);
6912 tree method_params
= NULL_TREE
;
6914 if (TREE_CODE (receiver
) == ERROR_MARK
|| TREE_CODE (args
) == ERROR_MARK
)
6915 return error_mark_node
;
6917 /* Obtain the full selector name. */
6918 switch (TREE_CODE (args
))
6920 case IDENTIFIER_NODE
:
6921 /* A unary selector. */
6925 sel_name
= build_keyword_selector (args
);
6931 /* Build the parameter list to give to the method. */
6932 if (TREE_CODE (args
) == TREE_LIST
)
6934 method_params
= chainon (args
, TREE_VALUE (TREE_VALUE (mess
)));
6937 tree chain
= args
, prev
= NULL_TREE
;
6939 /* We have a keyword selector--check for comma expressions. */
6942 tree element
= TREE_VALUE (chain
);
6944 /* We have a comma expression, must collapse... */
6945 if (TREE_CODE (element
) == TREE_LIST
)
6948 TREE_CHAIN (prev
) = element
;
6953 chain
= TREE_CHAIN (chain
);
6955 method_params
= args
;
6960 if (processing_template_decl
)
6961 /* Must wait until template instantiation time. */
6962 return build_min_nt (MESSAGE_SEND_EXPR
, receiver
, sel_name
,
6966 return objc_finish_message_expr (receiver
, sel_name
, method_params
);
6969 /* Look up method SEL_NAME that would be suitable for receiver
6970 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6971 nonzero), and report on any duplicates. */
6974 lookup_method_in_hash_lists (tree sel_name
, int is_class
)
6976 hash method_prototype
= NULL
;
6979 method_prototype
= hash_lookup (nst_method_hash_list
,
6982 if (!method_prototype
)
6984 method_prototype
= hash_lookup (cls_method_hash_list
,
6989 return check_duplicates (method_prototype
, 1, is_class
);
6992 /* The 'objc_finish_message_expr' routine is called from within
6993 'objc_build_message_expr' for non-template functions. In the case of
6994 C++ template functions, it is called from 'build_expr_from_tree'
6995 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6998 objc_finish_message_expr (tree receiver
, tree sel_name
, tree method_params
)
7000 tree method_prototype
= NULL_TREE
, rprotos
= NULL_TREE
, rtype
;
7001 tree selector
, retval
, class_tree
;
7002 int self
, super
, have_cast
;
7004 /* We have used the receiver, so mark it as read. */
7005 mark_exp_read (receiver
);
7007 /* Extract the receiver of the message, as well as its type
7008 (where the latter may take the form of a cast or be inferred
7009 from the implementation context). */
7011 while (TREE_CODE (rtype
) == COMPOUND_EXPR
7012 || TREE_CODE (rtype
) == MODIFY_EXPR
7013 || CONVERT_EXPR_P (rtype
)
7014 || TREE_CODE (rtype
) == COMPONENT_REF
)
7015 rtype
= TREE_OPERAND (rtype
, 0);
7017 self
= (rtype
== self_decl
);
7018 super
= (rtype
== UOBJC_SUPER_decl
);
7019 rtype
= TREE_TYPE (receiver
);
7021 have_cast
= (TREE_CODE (receiver
) == NOP_EXPR
7022 || (TREE_CODE (receiver
) == COMPOUND_EXPR
7023 && !IS_SUPER (rtype
)));
7025 /* If we are calling [super dealloc], reset our warning flag. */
7026 if (super
&& !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name
)))
7027 should_call_super_dealloc
= 0;
7029 /* If the receiver is a class object, retrieve the corresponding
7030 @interface, if one exists. */
7031 class_tree
= receiver_is_class_object (receiver
, self
, super
);
7033 /* Now determine the receiver type (if an explicit cast has not been
7038 rtype
= lookup_interface (class_tree
);
7039 /* Handle `self' and `super'. */
7042 if (!CLASS_SUPER_NAME (implementation_template
))
7044 error ("no super class declared in @interface for %qE",
7045 CLASS_NAME (implementation_template
));
7046 return error_mark_node
;
7048 rtype
= lookup_interface (CLASS_SUPER_NAME (implementation_template
));
7051 rtype
= lookup_interface (CLASS_NAME (implementation_template
));
7054 /* If receiver is of type `id' or `Class' (or if the @interface for a
7055 class is not visible), we shall be satisfied with the existence of
7056 any instance or class method. */
7057 if (objc_is_id (rtype
))
7059 class_tree
= (IS_CLASS (rtype
) ? objc_class_name
: NULL_TREE
);
7060 rprotos
= (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype
))
7061 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype
))
7067 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
7068 in protocols themselves for the method prototype. */
7070 = lookup_method_in_protocol_list (rprotos
, sel_name
,
7071 class_tree
!= NULL_TREE
);
7073 /* If messaging 'Class <Proto>' but did not find a class method
7074 prototype, search for an instance method instead, and warn
7075 about having done so. */
7076 if (!method_prototype
&& !rtype
&& class_tree
!= NULL_TREE
)
7079 = lookup_method_in_protocol_list (rprotos
, sel_name
, 0);
7081 if (method_prototype
)
7082 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
7083 sel_name
, sel_name
);
7089 tree orig_rtype
= rtype
;
7091 if (TREE_CODE (rtype
) == POINTER_TYPE
)
7092 rtype
= TREE_TYPE (rtype
);
7093 /* Traverse typedef aliases */
7094 while (TREE_CODE (rtype
) == RECORD_TYPE
&& OBJC_TYPE_NAME (rtype
)
7095 && TREE_CODE (OBJC_TYPE_NAME (rtype
)) == TYPE_DECL
7096 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
)))
7097 rtype
= DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
));
7098 if (TYPED_OBJECT (rtype
))
7100 rprotos
= TYPE_OBJC_PROTOCOL_LIST (rtype
);
7101 rtype
= TYPE_OBJC_INTERFACE (rtype
);
7103 /* If we could not find an @interface declaration, we must have
7104 only seen a @class declaration; so, we cannot say anything
7105 more intelligent about which methods the receiver will
7107 if (!rtype
|| TREE_CODE (rtype
) == IDENTIFIER_NODE
)
7110 /* We could not find an @interface declaration, yet Message maybe in a
7111 @class's protocol. */
7112 if (!method_prototype
&& rprotos
)
7114 = lookup_method_in_protocol_list (rprotos
, sel_name
, 0);
7116 else if (TREE_CODE (rtype
) == CLASS_INTERFACE_TYPE
7117 || TREE_CODE (rtype
) == CLASS_IMPLEMENTATION_TYPE
)
7119 /* We have a valid ObjC class name. Look up the method name
7120 in the published @interface for the class (and its
7123 = lookup_method_static (rtype
, sel_name
, class_tree
!= NULL_TREE
);
7125 /* If the method was not found in the @interface, it may still
7126 exist locally as part of the @implementation. */
7127 if (!method_prototype
&& objc_implementation_context
7128 && CLASS_NAME (objc_implementation_context
)
7129 == OBJC_TYPE_NAME (rtype
))
7133 ? CLASS_CLS_METHODS (objc_implementation_context
)
7134 : CLASS_NST_METHODS (objc_implementation_context
)),
7137 /* If we haven't found a candidate method by now, try looking for
7138 it in the protocol list. */
7139 if (!method_prototype
&& rprotos
)
7141 = lookup_method_in_protocol_list (rprotos
, sel_name
,
7142 class_tree
!= NULL_TREE
);
7146 warning (0, "invalid receiver type %qs",
7147 identifier_to_locale (gen_type_name (orig_rtype
)));
7148 /* After issuing the "invalid receiver" warning, perform method
7149 lookup as if we were messaging 'id'. */
7150 rtype
= rprotos
= NULL_TREE
;
7155 /* For 'id' or 'Class' receivers, search in the global hash table
7156 as a last resort. For all receivers, warn if protocol searches
7158 if (!method_prototype
)
7161 warning (0, "%<%c%E%> not found in protocol(s)",
7162 (class_tree
? '+' : '-'),
7167 = lookup_method_in_hash_lists (sel_name
, class_tree
!= NULL_TREE
);
7170 if (!method_prototype
&& in_objc_property_setter_name_context
)
7171 error ("readonly property can not be set");
7172 else if (!method_prototype
)
7174 static bool warn_missing_methods
= false;
7177 warning (0, "%qE may not respond to %<%c%E%>",
7178 OBJC_TYPE_NAME (rtype
),
7179 (class_tree
? '+' : '-'),
7181 /* If we are messaging an 'id' or 'Class' object and made it here,
7182 then we have failed to find _any_ instance or class method,
7185 warning (0, "no %<%c%E%> method found",
7186 (class_tree
? '+' : '-'),
7189 if (!warn_missing_methods
)
7191 warning_at (input_location
,
7192 0, "(Messages without a matching method signature");
7193 warning_at (input_location
,
7194 0, "will be assumed to return %<id%> and accept");
7195 warning_at (input_location
,
7196 0, "%<...%> as arguments.)");
7197 warn_missing_methods
= true;
7201 /* Save the selector name for printing error messages. */
7202 current_objc_message_selector
= sel_name
;
7204 /* Build the parameters list for looking up the method.
7205 These are the object itself and the selector. */
7207 if (flag_typed_selectors
)
7208 selector
= build_typed_selector_reference (input_location
,
7209 sel_name
, method_prototype
);
7211 selector
= build_selector_reference (input_location
, sel_name
);
7213 retval
= build_objc_method_call (input_location
, super
, method_prototype
,
7215 selector
, method_params
);
7217 current_objc_message_selector
= 0;
7222 /* Build a tree expression to send OBJECT the operation SELECTOR,
7223 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
7224 assuming the method has prototype METHOD_PROTOTYPE.
7225 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
7226 LOC is the location of the expression to build.
7227 Use METHOD_PARAMS as list of args to pass to the method.
7228 If SUPER_FLAG is nonzero, we look up the superclass's method. */
7231 build_objc_method_call (location_t loc
, int super_flag
, tree method_prototype
,
7232 tree lookup_object
, tree selector
,
7235 tree sender
= (super_flag
? umsg_super_decl
:
7236 (!flag_next_runtime
|| flag_nil_receivers
7237 ? (flag_objc_direct_dispatch
7240 : umsg_nonnil_decl
));
7241 tree rcv_p
= (super_flag
? objc_super_type
: objc_object_type
);
7242 VEC(tree
, gc
) *parms
= NULL
;
7243 unsigned nparm
= (method_params
? list_length (method_params
) : 0);
7245 /* If a prototype for the method to be called exists, then cast
7246 the sender's return type and arguments to match that of the method.
7247 Otherwise, leave sender as is. */
7250 ? TREE_VALUE (TREE_TYPE (method_prototype
))
7251 : objc_object_type
);
7253 tree method_param_types
=
7254 get_arg_type_list (method_prototype
, METHOD_REF
, super_flag
);
7255 tree ftype
= build_function_type (ret_type
, method_param_types
);
7259 if (method_prototype
&& METHOD_TYPE_ATTRIBUTES (method_prototype
))
7260 ftype
= build_type_attribute_variant (
7261 ftype
, METHOD_TYPE_ATTRIBUTES (method_prototype
));
7263 sender_cast
= build_pointer_type (ftype
);
7265 if (method_prototype
&& TREE_DEPRECATED (method_prototype
))
7266 warn_deprecated_use (method_prototype
, NULL_TREE
);
7268 lookup_object
= build_c_cast (loc
, rcv_p
, lookup_object
);
7270 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
7271 lookup_object
= save_expr (lookup_object
);
7273 /* Param list + 2 slots for object and selector. */
7274 parms
= VEC_alloc (tree
, gc
, nparm
+ 2);
7276 if (flag_next_runtime
)
7278 /* If we are returning a struct in memory, and the address
7279 of that memory location is passed as a hidden first
7280 argument, then change which messenger entry point this
7281 expr will call. NB: Note that sender_cast remains
7282 unchanged (it already has a struct return type). */
7283 if (!targetm
.calls
.struct_value_rtx (0, 0)
7284 && (TREE_CODE (ret_type
) == RECORD_TYPE
7285 || TREE_CODE (ret_type
) == UNION_TYPE
)
7286 && targetm
.calls
.return_in_memory (ret_type
, 0))
7287 sender
= (super_flag
? umsg_super_stret_decl
:
7288 flag_nil_receivers
? umsg_stret_decl
: umsg_nonnil_stret_decl
);
7290 method
= build_fold_addr_expr_loc (input_location
, sender
);
7291 /* Pass the object to the method. */
7292 VEC_quick_push (tree
, parms
, lookup_object
);
7296 /* This is the portable (GNU) way. */
7297 /* First, call the lookup function to get a pointer to the method,
7298 then cast the pointer, then call it with the method arguments. */
7299 VEC(tree
, gc
) *tv
= VEC_alloc (tree
, gc
, 2);
7300 VEC_quick_push (tree
, tv
, lookup_object
);
7301 VEC_quick_push (tree
, tv
, selector
);
7302 method
= build_function_call_vec (loc
, sender
, tv
, NULL
);
7303 VEC_free (tree
, gc
, tv
);
7305 /* Pass the appropriate object to the method. */
7306 VEC_quick_push (tree
, parms
, (super_flag
? self_decl
: lookup_object
));
7309 /* Pass the selector to the method. */
7310 VEC_quick_push (tree
, parms
, selector
);
7311 /* Now append the remainder of the parms. */
7313 for (; method_params
; method_params
= TREE_CHAIN (method_params
))
7314 VEC_quick_push (tree
, parms
, TREE_VALUE (method_params
));
7316 /* Build an obj_type_ref, with the correct cast for the method call. */
7317 t
= build3 (OBJ_TYPE_REF
, sender_cast
, method
,
7318 lookup_object
, size_zero_node
);
7319 t
= build_function_call_vec (loc
, t
, parms
, NULL
);\
7320 VEC_free (tree
, gc
, parms
);
7325 build_protocol_reference (tree p
)
7328 const char *proto_name
;
7330 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
7332 proto_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
7333 decl
= start_var_decl (objc_protocol_template
, proto_name
);
7335 PROTOCOL_FORWARD_DECL (p
) = decl
;
7338 /* This function is called by the parser when (and only when) a
7339 @protocol() expression is found, in order to compile it. */
7341 objc_build_protocol_expr (tree protoname
)
7344 tree p
= lookup_protocol (protoname
);
7348 error ("cannot find protocol declaration for %qE",
7350 return error_mark_node
;
7353 if (!PROTOCOL_FORWARD_DECL (p
))
7354 build_protocol_reference (p
);
7356 expr
= build_unary_op (input_location
,
7357 ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
7359 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
7360 if we have it, rather than converting it here. */
7361 expr
= convert (objc_protocol_type
, expr
);
7363 /* The @protocol() expression is being compiled into a pointer to a
7364 statically allocated instance of the Protocol class. To become
7365 usable at runtime, the 'isa' pointer of the instance need to be
7366 fixed up at runtime by the runtime library, to point to the
7367 actual 'Protocol' class. */
7369 /* For the GNU runtime, put the static Protocol instance in the list
7370 of statically allocated instances, so that we make sure that its
7371 'isa' pointer is fixed up at runtime by the GNU runtime library
7372 to point to the Protocol class (at runtime, when loading the
7373 module, the GNU runtime library loops on the statically allocated
7374 instances (as found in the defs field in objc_symtab) and fixups
7375 all the 'isa' pointers of those objects). */
7376 if (! flag_next_runtime
)
7378 /* This type is a struct containing the fields of a Protocol
7379 object. (Cfr. objc_protocol_type instead is the type of a pointer
7380 to such a struct). */
7381 tree protocol_struct_type
= xref_tag
7382 (RECORD_TYPE
, get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
7385 /* Look for the list of Protocol statically allocated instances
7386 to fixup at runtime. Create a new list to hold Protocol
7387 statically allocated instances, if the list is not found. At
7388 present there is only another list, holding NSConstantString
7389 static instances to be fixed up at runtime. */
7390 for (chain
= &objc_static_instances
;
7391 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
7392 chain
= &TREE_CHAIN (*chain
));
7395 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
7396 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type
),
7400 /* Add this statically allocated instance to the Protocol list. */
7401 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
7402 PROTOCOL_FORWARD_DECL (p
),
7403 TREE_PURPOSE (*chain
));
7410 /* This function is called by the parser when a @selector() expression
7411 is found, in order to compile it. It is only called by the parser
7412 and only to compile a @selector(). LOC is the location of the
7415 objc_build_selector_expr (location_t loc
, tree selnamelist
)
7419 /* Obtain the full selector name. */
7420 switch (TREE_CODE (selnamelist
))
7422 case IDENTIFIER_NODE
:
7423 /* A unary selector. */
7424 selname
= selnamelist
;
7427 selname
= build_keyword_selector (selnamelist
);
7433 /* If we are required to check @selector() expressions as they
7434 are found, check that the selector has been declared. */
7435 if (warn_undeclared_selector
)
7437 /* Look the selector up in the list of all known class and
7438 instance methods (up to this line) to check that the selector
7442 /* First try with instance methods. */
7443 hsh
= hash_lookup (nst_method_hash_list
, selname
);
7445 /* If not found, try with class methods. */
7448 hsh
= hash_lookup (cls_method_hash_list
, selname
);
7451 /* If still not found, print out a warning. */
7454 warning (0, "undeclared selector %qE", selname
);
7459 if (flag_typed_selectors
)
7460 return build_typed_selector_reference (loc
, selname
, 0);
7462 return build_selector_reference (loc
, selname
);
7465 /* This is used to implement @encode(). See gcc/doc/objc.texi,
7466 section '@encode'. */
7468 objc_build_encode_expr (tree type
)
7473 encode_type (type
, obstack_object_size (&util_obstack
),
7474 OBJC_ENCODE_INLINE_DEFS
);
7475 obstack_1grow (&util_obstack
, 0); /* null terminate string */
7476 string
= XOBFINISH (&util_obstack
, const char *);
7478 /* Synthesize a string that represents the encoded struct/union. */
7479 result
= my_build_string (strlen (string
) + 1, string
);
7480 obstack_free (&util_obstack
, util_firstobj
);
7485 build_ivar_reference (tree id
)
7487 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7489 /* Historically, a class method that produced objects (factory
7490 method) would assign `self' to the instance that it
7491 allocated. This would effectively turn the class method into
7492 an instance method. Following this assignment, the instance
7493 variables could be accessed. That practice, while safe,
7494 violates the simple rule that a class method should not refer
7495 to an instance variable. It's better to catch the cases
7496 where this is done unknowingly than to support the above
7498 warning (0, "instance variable %qE accessed in class method",
7500 self_decl
= convert (objc_instance_type
, self_decl
); /* cast */
7503 return objc_build_component_ref (build_indirect_ref (input_location
,
7504 self_decl
, RO_ARROW
),
7508 /* Compute a hash value for a given method SEL_NAME. */
7511 hash_func (tree sel_name
)
7513 const unsigned char *s
7514 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
7518 h
= h
* 67 + *s
++ - 113;
7525 nst_method_hash_list
= ggc_alloc_cleared_vec_hash (SIZEHASHTABLE
);
7526 cls_method_hash_list
= ggc_alloc_cleared_vec_hash (SIZEHASHTABLE
);
7528 cls_name_hash_list
= ggc_alloc_cleared_vec_hash (SIZEHASHTABLE
);
7529 als_name_hash_list
= ggc_alloc_cleared_vec_hash (SIZEHASHTABLE
);
7531 /* Initialize the hash table used to hold the constant string objects. */
7532 string_htab
= htab_create_ggc (31, string_hash
,
7536 /* This routine adds sel_name to the hash list. sel_name is a class or alias
7537 name for the class. If alias name, then value is its underlying class.
7538 If class, the value is NULL_TREE. */
7541 hash_class_name_enter (hash
*hashlist
, tree sel_name
, tree value
)
7544 int slot
= hash_func (sel_name
) % SIZEHASHTABLE
;
7546 obj
= ggc_alloc_hashed_entry ();
7547 if (value
!= NULL_TREE
)
7549 /* Save the underlying class for the 'alias' in the hash table */
7550 attr obj_attr
= ggc_alloc_hashed_attribute ();
7551 obj_attr
->value
= value
;
7552 obj
->list
= obj_attr
;
7556 obj
->next
= hashlist
[slot
];
7557 obj
->key
= sel_name
;
7559 hashlist
[slot
] = obj
; /* append to front */
7564 Searches in the hash table looking for a match for class or alias name.
7568 hash_class_name_lookup (hash
*hashlist
, tree sel_name
)
7572 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
7576 if (sel_name
== target
->key
)
7579 target
= target
->next
;
7584 /* WARNING!!!! hash_enter is called with a method, and will peek
7585 inside to find its selector! But hash_lookup is given a selector
7586 directly, and looks for the selector that's inside the found
7587 entry's key (method) for comparison. */
7590 hash_enter (hash
*hashlist
, tree method
)
7593 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
7595 obj
= ggc_alloc_hashed_entry ();
7597 obj
->next
= hashlist
[slot
];
7600 hashlist
[slot
] = obj
; /* append to front */
7604 hash_lookup (hash
*hashlist
, tree sel_name
)
7608 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
7612 if (sel_name
== METHOD_SEL_NAME (target
->key
))
7615 target
= target
->next
;
7621 hash_add_attr (hash entry
, tree value
)
7625 obj
= ggc_alloc_hashed_attribute ();
7626 obj
->next
= entry
->list
;
7629 entry
->list
= obj
; /* append to front */
7633 lookup_method (tree mchain
, tree method
)
7637 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
7640 key
= METHOD_SEL_NAME (method
);
7644 if (METHOD_SEL_NAME (mchain
) == key
)
7647 mchain
= DECL_CHAIN (mchain
);
7652 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
7653 in INTERFACE, along with any categories and protocols attached thereto.
7654 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
7655 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
7656 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
7657 be found in INTERFACE or any of its superclasses, look for an _instance_
7658 method of the same name in the root class as a last resort.
7660 If a suitable method cannot be found, return NULL_TREE. */
7663 lookup_method_static (tree interface
, tree ident
, int flags
)
7665 tree meth
= NULL_TREE
, root_inter
= NULL_TREE
;
7666 tree inter
= interface
;
7667 int is_class
= (flags
& OBJC_LOOKUP_CLASS
);
7668 int no_superclasses
= (flags
& OBJC_LOOKUP_NO_SUPER
);
7672 tree chain
= is_class
? CLASS_CLS_METHODS (inter
) : CLASS_NST_METHODS (inter
);
7673 tree category
= inter
;
7675 /* First, look up the method in the class itself. */
7676 if ((meth
= lookup_method (chain
, ident
)))
7679 /* Failing that, look for the method in each category of the class. */
7680 while ((category
= CLASS_CATEGORY_LIST (category
)))
7682 chain
= is_class
? CLASS_CLS_METHODS (category
) : CLASS_NST_METHODS (category
);
7684 /* Check directly in each category. */
7685 if ((meth
= lookup_method (chain
, ident
)))
7688 /* Failing that, check in each category's protocols. */
7689 if (CLASS_PROTOCOL_LIST (category
))
7691 if ((meth
= (lookup_method_in_protocol_list
7692 (CLASS_PROTOCOL_LIST (category
), ident
, is_class
))))
7697 /* If not found in categories, check in protocols of the main class. */
7698 if (CLASS_PROTOCOL_LIST (inter
))
7700 if ((meth
= (lookup_method_in_protocol_list
7701 (CLASS_PROTOCOL_LIST (inter
), ident
, is_class
))))
7705 /* If we were instructed not to look in superclasses, don't. */
7706 if (no_superclasses
)
7709 /* Failing that, climb up the inheritance hierarchy. */
7711 inter
= lookup_interface (CLASS_SUPER_NAME (inter
));
7715 /* If no class (factory) method was found, check if an _instance_
7716 method of the same name exists in the root class. This is what
7717 the Objective-C runtime will do. If an instance method was not
7719 return is_class
? lookup_method_static (root_inter
, ident
, 0): NULL_TREE
;
7722 /* Add the method to the hash list if it doesn't contain an identical
7726 add_method_to_hash_list (hash
*hash_list
, tree method
)
7730 if (!(hsh
= hash_lookup (hash_list
, METHOD_SEL_NAME (method
))))
7732 /* Install on a global chain. */
7733 hash_enter (hash_list
, method
);
7737 /* Check types against those; if different, add to a list. */
7739 int already_there
= comp_proto_with_proto (method
, hsh
->key
, 1);
7740 for (loop
= hsh
->list
; !already_there
&& loop
; loop
= loop
->next
)
7741 already_there
|= comp_proto_with_proto (method
, loop
->value
, 1);
7743 hash_add_attr (hsh
, method
);
7748 objc_add_method (tree klass
, tree method
, int is_class
, bool is_optional
)
7752 /* @optional methods are added to protocol's OPTIONAL list */
7755 gcc_assert (TREE_CODE (klass
) == PROTOCOL_INTERFACE_TYPE
);
7756 if (!(mth
= lookup_method (is_class
7757 ? PROTOCOL_OPTIONAL_CLS_METHODS (klass
)
7758 : PROTOCOL_OPTIONAL_NST_METHODS (klass
),
7763 TREE_CHAIN (method
) = PROTOCOL_OPTIONAL_CLS_METHODS (klass
);
7764 PROTOCOL_OPTIONAL_CLS_METHODS (klass
) = method
;
7768 TREE_CHAIN (method
) = PROTOCOL_OPTIONAL_NST_METHODS (klass
);
7769 PROTOCOL_OPTIONAL_NST_METHODS (klass
) = method
;
7773 else if (!(mth
= lookup_method (is_class
7774 ? CLASS_CLS_METHODS (klass
)
7775 : CLASS_NST_METHODS (klass
), method
)))
7777 /* put method on list in reverse order */
7780 DECL_CHAIN (method
) = CLASS_CLS_METHODS (klass
);
7781 CLASS_CLS_METHODS (klass
) = method
;
7785 DECL_CHAIN (method
) = CLASS_NST_METHODS (klass
);
7786 CLASS_NST_METHODS (klass
) = method
;
7791 /* When processing an @interface for a class or category, give hard
7792 errors on methods with identical selectors but differing argument
7793 and/or return types. We do not do this for @implementations, because
7794 C/C++ will do it for us (i.e., there will be duplicate function
7795 definition errors). */
7796 if ((TREE_CODE (klass
) == CLASS_INTERFACE_TYPE
7797 || TREE_CODE (klass
) == CATEGORY_INTERFACE_TYPE
)
7798 && !comp_proto_with_proto (method
, mth
, 1))
7799 error ("duplicate declaration of method %<%c%E%>",
7800 is_class
? '+' : '-',
7801 METHOD_SEL_NAME (mth
));
7805 add_method_to_hash_list (cls_method_hash_list
, method
);
7808 add_method_to_hash_list (nst_method_hash_list
, method
);
7810 /* Instance methods in root classes (and categories thereof)
7811 may act as class methods as a last resort. We also add
7812 instance methods listed in @protocol declarations to
7813 the class hash table, on the assumption that @protocols
7814 may be adopted by root classes or categories. */
7815 if (TREE_CODE (klass
) == CATEGORY_INTERFACE_TYPE
7816 || TREE_CODE (klass
) == CATEGORY_IMPLEMENTATION_TYPE
)
7817 klass
= lookup_interface (CLASS_NAME (klass
));
7819 if (TREE_CODE (klass
) == PROTOCOL_INTERFACE_TYPE
7820 || !CLASS_SUPER_NAME (klass
))
7821 add_method_to_hash_list (cls_method_hash_list
, method
);
7828 add_class (tree class_name
, tree name
)
7830 struct interface_tuple
**slot
;
7832 /* Put interfaces on list in reverse order. */
7833 TREE_CHAIN (class_name
) = interface_chain
;
7834 interface_chain
= class_name
;
7836 if (interface_htab
== NULL
)
7837 interface_htab
= htab_create_ggc (31, hash_interface
, eq_interface
, NULL
);
7838 slot
= (struct interface_tuple
**)
7839 htab_find_slot_with_hash (interface_htab
, name
,
7840 IDENTIFIER_HASH_VALUE (name
),
7844 *slot
= ggc_alloc_cleared_interface_tuple ();
7847 (*slot
)->class_name
= class_name
;
7849 return interface_chain
;
7853 add_category (tree klass
, tree category
)
7855 /* Put categories on list in reverse order. */
7856 tree cat
= lookup_category (klass
, CLASS_SUPER_NAME (category
));
7860 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
7862 CLASS_SUPER_NAME (category
));
7866 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (klass
);
7867 CLASS_CATEGORY_LIST (klass
) = category
;
7871 /* Called after parsing each instance variable declaration. Necessary to
7872 preserve typedefs and implement public/private...
7874 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7877 add_instance_variable (tree klass
, objc_ivar_visibility_kind visibility
,
7880 tree field_type
= TREE_TYPE (field_decl
);
7881 const char *ivar_name
= DECL_NAME (field_decl
)
7882 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl
)))
7886 if (TREE_CODE (field_type
) == REFERENCE_TYPE
)
7888 error ("illegal reference type specified for instance variable %qs",
7890 /* Return class as is without adding this ivar. */
7895 if (field_type
== error_mark_node
|| !TYPE_SIZE (field_type
)
7896 || TYPE_SIZE (field_type
) == error_mark_node
)
7897 /* 'type[0]' is allowed, but 'type[]' is not! */
7899 error ("instance variable %qs has unknown size", ivar_name
);
7900 /* Return class as is without adding this ivar. */
7905 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7906 need to either (1) warn the user about it or (2) generate suitable
7907 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7908 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7909 if (MAYBE_CLASS_TYPE_P (field_type
)
7910 && (TYPE_NEEDS_CONSTRUCTING (field_type
)
7911 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
)
7912 || TYPE_POLYMORPHIC_P (field_type
)))
7914 tree type_name
= OBJC_TYPE_NAME (field_type
);
7916 if (flag_objc_call_cxx_cdtors
)
7918 /* Since the ObjC runtime will be calling the constructors and
7919 destructors for us, the only thing we can't handle is the lack
7920 of a default constructor. */
7921 if (TYPE_NEEDS_CONSTRUCTING (field_type
)
7922 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type
))
7924 warning (0, "type %qE has no default constructor to call",
7927 /* If we cannot call a constructor, we should also avoid
7928 calling the destructor, for symmetry. */
7929 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
7930 warning (0, "destructor for %qE shall not be run either",
7936 static bool warn_cxx_ivars
= false;
7938 if (TYPE_POLYMORPHIC_P (field_type
))
7940 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7942 error ("type %qE has virtual member functions", type_name
);
7943 error ("illegal aggregate type %qE specified "
7944 "for instance variable %qs",
7945 type_name
, ivar_name
);
7946 /* Return class as is without adding this ivar. */
7950 /* User-defined constructors and destructors are not known to Obj-C
7951 and hence will not be called. This may or may not be a problem. */
7952 if (TYPE_NEEDS_CONSTRUCTING (field_type
))
7953 warning (0, "type %qE has a user-defined constructor", type_name
);
7954 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
7955 warning (0, "type %qE has a user-defined destructor", type_name
);
7957 if (!warn_cxx_ivars
)
7959 warning (0, "C++ constructors and destructors will not "
7960 "be invoked for Objective-C fields");
7961 warn_cxx_ivars
= true;
7967 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7970 case OBJC_IVAR_VIS_PROTECTED
:
7971 TREE_PUBLIC (field_decl
) = 0;
7972 TREE_PRIVATE (field_decl
) = 0;
7973 TREE_PROTECTED (field_decl
) = 1;
7976 case OBJC_IVAR_VIS_PACKAGE
:
7977 /* TODO: Implement the package variant. */
7978 case OBJC_IVAR_VIS_PUBLIC
:
7979 TREE_PUBLIC (field_decl
) = 1;
7980 TREE_PRIVATE (field_decl
) = 0;
7981 TREE_PROTECTED (field_decl
) = 0;
7984 case OBJC_IVAR_VIS_PRIVATE
:
7985 TREE_PUBLIC (field_decl
) = 0;
7986 TREE_PRIVATE (field_decl
) = 1;
7987 TREE_PROTECTED (field_decl
) = 0;
7992 CLASS_RAW_IVARS (klass
) = chainon (CLASS_RAW_IVARS (klass
), field_decl
);
7998 is_ivar (tree decl_chain
, tree ident
)
8000 for ( ; decl_chain
; decl_chain
= DECL_CHAIN (decl_chain
))
8001 if (DECL_NAME (decl_chain
) == ident
)
8006 /* True if the ivar is private and we are not in its implementation. */
8009 is_private (tree decl
)
8011 return (TREE_PRIVATE (decl
)
8012 && ! is_ivar (CLASS_IVARS (implementation_template
),
8016 /* We have an instance variable reference;, check to see if it is public. */
8019 objc_is_public (tree expr
, tree identifier
)
8021 tree basetype
, decl
;
8024 if (processing_template_decl
)
8028 if (TREE_TYPE (expr
) == error_mark_node
)
8031 basetype
= TYPE_MAIN_VARIANT (TREE_TYPE (expr
));
8033 if (basetype
&& TREE_CODE (basetype
) == RECORD_TYPE
)
8035 if (TYPE_HAS_OBJC_INFO (basetype
) && TYPE_OBJC_INTERFACE (basetype
))
8037 tree klass
= lookup_interface (OBJC_TYPE_NAME (basetype
));
8041 error ("cannot find interface declaration for %qE",
8042 OBJC_TYPE_NAME (basetype
));
8046 if ((decl
= is_ivar (get_class_ivars (klass
, true), identifier
)))
8048 if (TREE_PUBLIC (decl
))
8051 /* Important difference between the Stepstone translator:
8052 all instance variables should be public within the context
8053 of the implementation. */
8054 if (objc_implementation_context
8055 && ((TREE_CODE (objc_implementation_context
)
8056 == CLASS_IMPLEMENTATION_TYPE
)
8057 || (TREE_CODE (objc_implementation_context
)
8058 == CATEGORY_IMPLEMENTATION_TYPE
)))
8060 tree curtype
= TYPE_MAIN_VARIANT
8061 (CLASS_STATIC_TEMPLATE
8062 (implementation_template
));
8064 if (basetype
== curtype
8065 || DERIVED_FROM_P (basetype
, curtype
))
8067 int priv
= is_private (decl
);
8070 error ("instance variable %qE is declared private",
8077 /* The 2.95.2 compiler sometimes allowed C functions to access
8078 non-@public ivars. We will let this slide for now... */
8079 if (!objc_method_context
)
8081 warning (0, "instance variable %qE is %s; "
8082 "this will be a hard error in the future",
8084 TREE_PRIVATE (decl
) ? "@private" : "@protected");
8088 error ("instance variable %qE is declared %s",
8090 TREE_PRIVATE (decl
) ? "private" : "protected");
8099 /* Make sure all entries in CHAIN are also in LIST. */
8102 check_methods (tree chain
, tree list
, int mtype
)
8108 if (!lookup_method (list
, chain
))
8112 switch (TREE_CODE (objc_implementation_context
))
8114 case CLASS_IMPLEMENTATION_TYPE
:
8115 warning (0, "incomplete implementation of class %qE",
8116 CLASS_NAME (objc_implementation_context
));
8118 case CATEGORY_IMPLEMENTATION_TYPE
:
8119 warning (0, "incomplete implementation of category %qE",
8120 CLASS_SUPER_NAME (objc_implementation_context
));
8128 warning (0, "method definition for %<%c%E%> not found",
8129 mtype
, METHOD_SEL_NAME (chain
));
8132 chain
= DECL_CHAIN (chain
);
8138 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
8141 conforms_to_protocol (tree klass
, tree protocol
)
8143 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
8145 tree p
= CLASS_PROTOCOL_LIST (klass
);
8146 while (p
&& TREE_VALUE (p
) != protocol
)
8151 tree super
= (CLASS_SUPER_NAME (klass
)
8152 ? lookup_interface (CLASS_SUPER_NAME (klass
))
8154 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
8163 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
8164 CONTEXT. This is one of two mechanisms to check protocol integrity. */
8167 check_methods_accessible (tree chain
, tree context
, int mtype
)
8171 tree base_context
= context
;
8175 context
= base_context
;
8179 list
= CLASS_CLS_METHODS (context
);
8181 list
= CLASS_NST_METHODS (context
);
8183 if (lookup_method (list
, chain
))
8186 switch (TREE_CODE (context
))
8188 case CLASS_IMPLEMENTATION_TYPE
:
8189 case CLASS_INTERFACE_TYPE
:
8190 context
= (CLASS_SUPER_NAME (context
)
8191 ? lookup_interface (CLASS_SUPER_NAME (context
))
8194 case CATEGORY_IMPLEMENTATION_TYPE
:
8195 case CATEGORY_INTERFACE_TYPE
:
8196 context
= (CLASS_NAME (context
)
8197 ? lookup_interface (CLASS_NAME (context
))
8205 if (context
== NULL_TREE
)
8209 switch (TREE_CODE (objc_implementation_context
))
8211 case CLASS_IMPLEMENTATION_TYPE
:
8212 warning (0, "incomplete implementation of class %qE",
8213 CLASS_NAME (objc_implementation_context
));
8215 case CATEGORY_IMPLEMENTATION_TYPE
:
8216 warning (0, "incomplete implementation of category %qE",
8217 CLASS_SUPER_NAME (objc_implementation_context
));
8224 warning (0, "method definition for %<%c%E%> not found",
8225 mtype
, METHOD_SEL_NAME (chain
));
8228 chain
= TREE_CHAIN (chain
); /* next method... */
8233 /* Check whether the current interface (accessible via
8234 'objc_implementation_context') actually implements protocol P, along
8235 with any protocols that P inherits. */
8238 check_protocol (tree p
, const char *type
, tree name
)
8240 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
8244 /* Ensure that all protocols have bodies! */
8247 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
8248 CLASS_CLS_METHODS (objc_implementation_context
),
8250 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
8251 CLASS_NST_METHODS (objc_implementation_context
),
8256 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
8257 objc_implementation_context
,
8259 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
8260 objc_implementation_context
,
8265 warning (0, "%s %qE does not fully implement the %qE protocol",
8266 type
, name
, PROTOCOL_NAME (p
));
8269 /* Check protocols recursively. */
8270 if (PROTOCOL_LIST (p
))
8272 tree subs
= PROTOCOL_LIST (p
);
8274 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
8278 tree sub
= TREE_VALUE (subs
);
8280 /* If the superclass does not conform to the protocols
8281 inherited by P, then we must! */
8282 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
8283 check_protocol (sub
, type
, name
);
8284 subs
= TREE_CHAIN (subs
);
8289 /* Check whether the current interface (accessible via
8290 'objc_implementation_context') actually implements the protocols listed
8294 check_protocols (tree proto_list
, const char *type
, tree name
)
8296 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
8298 tree p
= TREE_VALUE (proto_list
);
8300 check_protocol (p
, type
, name
);
8304 /* Make sure that the class CLASS_NAME is defined
8305 CODE says which kind of thing CLASS_NAME ought to be.
8306 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
8307 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
8310 start_class (enum tree_code code
, tree class_name
, tree super_name
,
8316 if (current_namespace
!= global_namespace
) {
8317 error ("Objective-C declarations may only appear in global scope");
8319 #endif /* OBJCPLUS */
8321 if (objc_implementation_context
)
8323 warning (0, "%<@end%> missing in implementation context");
8324 finish_class (objc_implementation_context
);
8325 objc_ivar_chain
= NULL_TREE
;
8326 objc_implementation_context
= NULL_TREE
;
8329 klass
= make_node (code
);
8330 TYPE_LANG_SLOT_1 (klass
) = make_tree_vec (CLASS_LANG_SLOT_ELTS
);
8332 /* Check for existence of the super class, if one was specified. Note
8333 that we must have seen an @interface, not just a @class. If we
8334 are looking at a @compatibility_alias, traverse it first. */
8335 if ((code
== CLASS_INTERFACE_TYPE
|| code
== CLASS_IMPLEMENTATION_TYPE
)
8338 tree super
= objc_is_class_name (super_name
);
8340 if (!super
|| !lookup_interface (super
))
8342 error ("cannot find interface declaration for %qE, superclass of %qE",
8343 super
? super
: super_name
,
8345 super_name
= NULL_TREE
;
8351 CLASS_NAME (klass
) = class_name
;
8352 CLASS_SUPER_NAME (klass
) = super_name
;
8353 CLASS_CLS_METHODS (klass
) = NULL_TREE
;
8355 if (! objc_is_class_name (class_name
)
8356 && (decl
= lookup_name (class_name
)))
8358 error ("%qE redeclared as different kind of symbol",
8360 error ("previous declaration of %q+D",
8366 case CLASS_IMPLEMENTATION_TYPE
:
8370 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
8371 if (TREE_VALUE (chain
) == class_name
)
8373 error ("reimplementation of class %qE",
8375 return error_mark_node
;
8377 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
8378 implemented_classes
);
8381 /* Reset for multiple classes per file. */
8384 objc_implementation_context
= klass
;
8386 /* Lookup the interface for this implementation. */
8388 if (!(implementation_template
= lookup_interface (class_name
)))
8390 warning (0, "cannot find interface declaration for %qE",
8392 add_class (implementation_template
= objc_implementation_context
,
8396 /* If a super class has been specified in the implementation,
8397 insure it conforms to the one specified in the interface. */
8400 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
8402 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
8403 error ("conflicting super class name %qE",
8406 error ("previous declaration of %qE", previous_name
);
8408 error ("previous declaration");
8411 else if (! super_name
)
8413 CLASS_SUPER_NAME (objc_implementation_context
)
8414 = CLASS_SUPER_NAME (implementation_template
);
8418 case CLASS_INTERFACE_TYPE
:
8419 if (lookup_interface (class_name
))
8421 error ("duplicate interface declaration for class %qE", class_name
);
8423 warning (0, "duplicate interface declaration for class %qE", class_name
);
8426 add_class (klass
, class_name
);
8429 CLASS_PROTOCOL_LIST (klass
)
8430 = lookup_and_install_protocols (protocol_list
);
8433 case CATEGORY_INTERFACE_TYPE
:
8435 tree class_category_is_assoc_with
;
8437 /* For a category, class_name is really the name of the class that
8438 the following set of methods will be associated with. We must
8439 find the interface so that can derive the objects template. */
8440 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
8442 error ("cannot find interface declaration for %qE",
8444 exit (FATAL_EXIT_CODE
);
8447 add_category (class_category_is_assoc_with
, klass
);
8450 CLASS_PROTOCOL_LIST (klass
)
8451 = lookup_and_install_protocols (protocol_list
);
8455 case CATEGORY_IMPLEMENTATION_TYPE
:
8456 /* Reset for multiple classes per file. */
8459 objc_implementation_context
= klass
;
8461 /* For a category, class_name is really the name of the class that
8462 the following set of methods will be associated with. We must
8463 find the interface so that can derive the objects template. */
8465 if (!(implementation_template
= lookup_interface (class_name
)))
8467 error ("cannot find interface declaration for %qE",
8469 exit (FATAL_EXIT_CODE
);
8479 continue_class (tree klass
)
8481 switch (TREE_CODE (klass
))
8483 case CLASS_IMPLEMENTATION_TYPE
:
8484 case CATEGORY_IMPLEMENTATION_TYPE
:
8486 struct imp_entry
*imp_entry
;
8488 /* Check consistency of the instance variables. */
8490 if (CLASS_RAW_IVARS (klass
))
8491 check_ivars (implementation_template
, klass
);
8493 /* code generation */
8495 push_lang_context (lang_name_c
);
8497 build_private_template (implementation_template
);
8498 uprivate_record
= CLASS_STATIC_TEMPLATE (implementation_template
);
8499 objc_instance_type
= build_pointer_type (uprivate_record
);
8501 imp_entry
= ggc_alloc_imp_entry ();
8503 imp_entry
->next
= imp_list
;
8504 imp_entry
->imp_context
= klass
;
8505 imp_entry
->imp_template
= implementation_template
;
8507 synth_forward_declarations ();
8508 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
8509 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
8510 imp_entry
->has_cxx_cdtors
= 0;
8512 /* Append to front and increment count. */
8513 imp_list
= imp_entry
;
8514 if (TREE_CODE (klass
) == CLASS_IMPLEMENTATION_TYPE
)
8519 pop_lang_context ();
8520 #endif /* OBJCPLUS */
8522 return get_class_ivars (implementation_template
, true);
8525 case CLASS_INTERFACE_TYPE
:
8528 push_lang_context (lang_name_c
);
8529 #endif /* OBJCPLUS */
8530 objc_collecting_ivars
= 1;
8531 build_private_template (klass
);
8532 objc_collecting_ivars
= 0;
8534 pop_lang_context ();
8535 #endif /* OBJCPLUS */
8540 return error_mark_node
;
8544 /* This routine builds a property ivar name. */
8547 objc_build_property_ivar_name (tree property_decl
)
8549 static char string
[BUFSIZE
];
8550 sprintf (string
, "_%s", IDENTIFIER_POINTER (PROPERTY_NAME (property_decl
)));
8554 /* This routine builds name of the setter synthesized function. */
8557 objc_build_property_setter_name (tree ident
, bool delimit_colon
)
8559 static char string
[BUFSIZE
];
8561 sprintf (string
, "set%s:", IDENTIFIER_POINTER (ident
));
8563 sprintf (string
, "set%s", IDENTIFIER_POINTER (ident
));
8564 string
[3] = TOUPPER (string
[3]);
8568 /* This routine does all the work for generating data and code per each
8569 property declared in current implementation. */
8572 objc_gen_one_property_datum (tree klass
, tree property
, tree class_methods
, bool *ivar_added
)
8576 /* If getter, check that it is already declared in user code. */
8577 if (PROPERTY_GETTER_NAME (property
))
8579 mth
= lookup_method (CLASS_NST_METHODS (class_methods
),
8580 PROPERTY_GETTER_NAME (property
));
8582 error ("property getter %qs not declared in class %qs",
8583 IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property
)),
8584 IDENTIFIER_POINTER (CLASS_NAME (class_methods
)));
8586 /* If setter, check that it is already declared in user code. */
8587 if (PROPERTY_SETTER_NAME (property
))
8589 mth
= lookup_method (CLASS_NST_METHODS (class_methods
),
8590 PROPERTY_SETTER_NAME (property
));
8592 error ("property setter %qs not declared in class %qs",
8593 IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property
)),
8594 IDENTIFIER_POINTER (CLASS_NAME (class_methods
)));
8596 /* If ivar attribute specified, check that it is already declared. */
8597 if (PROPERTY_IVAR_NAME (property
))
8599 if (!is_ivar (CLASS_IVARS (klass
),
8600 PROPERTY_IVAR_NAME (property
)))
8601 error ("ivar %qs in property declaration must be an existing ivar",
8602 IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property
)));
8604 else if (!PROPERTY_GETTER_NAME (property
)
8605 || (PROPERTY_READONLY (property
) == boolean_false_node
8606 && !PROPERTY_SETTER_NAME (property
)))
8608 /* Setter and/or getter must be synthesize and there was no user-specified
8609 ivar. Must create an ivar and add to to current class's ivar list. */
8610 tree record
= CLASS_STATIC_TEMPLATE (klass
);
8611 tree type
= TREE_TYPE (property
);
8612 tree field_decl
, field
;
8613 field_decl
= create_field_decl (type
,
8614 objc_build_property_ivar_name (property
));
8615 DECL_CONTEXT (field_decl
) = record
;
8616 (void) add_instance_variable (klass
,
8617 OBJC_IVAR_VIS_PUBLIC
, field_decl
);
8618 /* Unfortunately, CLASS_IVARS is completed when interface is completed.
8619 Must add the new ivar by hand to its list here. */
8621 CLASS_IVARS (klass
) =
8622 chainon (CLASS_IVARS (klass
),
8623 copy_node (field_decl
));
8624 gcc_assert (record
);
8625 /* Must also add this ivar to the end of list of fields for this class. */
8626 field
= TYPE_FIELDS (record
);
8627 if (field
&& field
!= CLASS_IVARS (klass
))
8628 /* class has a hidden field, attach ivar list after the hiddent field. */
8629 TREE_CHAIN (field
) = CLASS_IVARS (klass
);
8631 TYPE_FIELDS (record
) = CLASS_IVARS (klass
);
8636 /* This routine processes an existing getter or setter attribute.
8637 It aliases internal property getter or setter to the user implemented
8642 objc_process_getter_setter (tree klass
, tree property
, bool getter
)
8645 tree prop_getter_mth_decl
;
8649 /* getter name is same as property name. */
8650 name_ident
= PROPERTY_NAME (property
);
8652 /* Must synthesize setter name from property name. */
8653 name_ident
= get_identifier (objc_build_property_setter_name (
8654 PROPERTY_NAME (property
), true));
8656 /* Find declaration of instance method for the property in its class. */
8657 prop_mth_decl
= lookup_method (CLASS_NST_METHODS (klass
), name_ident
);
8662 prop_getter_mth_decl
= lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
8663 getter
? PROPERTY_GETTER_NAME (property
)
8664 : PROPERTY_SETTER_NAME (property
));
8666 if (!prop_getter_mth_decl
)
8669 if (!match_proto_with_proto (prop_getter_mth_decl
, prop_mth_decl
, 1))
8671 error ("User %s %qs does not match property %qs type",
8672 getter
? "getter" : "setter",
8673 IDENTIFIER_POINTER (DECL_NAME (prop_getter_mth_decl
)),
8674 IDENTIFIER_POINTER (PROPERTY_NAME (property
)));
8677 /* We alias internal property getter to the user implemented getter by copying relevant
8678 entries from user's implementation to the internal one. */
8679 prop_mth_decl
= copy_node (prop_mth_decl
);
8680 METHOD_ENCODING (prop_mth_decl
) = METHOD_ENCODING (prop_getter_mth_decl
);
8681 METHOD_DEFINITION (prop_mth_decl
) = METHOD_DEFINITION (prop_getter_mth_decl
);
8682 objc_add_method (objc_implementation_context
, prop_mth_decl
, 0, 0);
8685 /* This routine synthesizes a 'getter' method. */
8688 objc_synthesize_getter (tree klass
, tree class_method
, tree property
)
8695 /* If user has implemented a getter with same name then do nothing. */
8696 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
8697 PROPERTY_NAME (property
)))
8700 /* Find declaration of the property in the interface. There must be one. */
8701 decl
= lookup_method (CLASS_NST_METHODS (class_method
),
8702 PROPERTY_NAME (property
));
8704 /* If one not declared in the interface, this condition has already been reported
8705 as user error (because property was not declared in the interface). */
8709 /* For now no attributes. */
8710 objc_start_method_definition (false /* is_class_method */, copy_node (decl
), NULL_TREE
);
8712 body
= c_begin_compound_stmt (true);
8713 /* return self->_property_name; */
8714 /* If user specified an ivar, use it in generation of the getter. */
8715 ivar_ident
= PROPERTY_IVAR_NAME (property
)
8716 ? PROPERTY_IVAR_NAME (property
)
8717 : get_identifier (objc_build_property_ivar_name (property
));
8719 /* objc_ivar_chain might not be up to date in the case that property 'ivar'
8720 is added *after* user ivar is parsed and objc_continue_implementation
8721 has already been called. */
8722 objc_ivar_chain
= CLASS_IVARS (klass
);
8723 ret_val
= objc_lookup_ivar (NULL_TREE
, ivar_ident
);
8724 /* If ivar attribute is not a user declared attribute, this condition has
8725 already been repored as error. */
8726 gcc_assert (ret_val
|| PROPERTY_IVAR_NAME (property
));
8731 finish_return_stmt (ret_val
);
8733 (void)c_finish_return (input_location
, ret_val
, NULL
);
8736 add_stmt (c_end_compound_stmt (input_location
, body
, true));
8737 fn
= current_function_decl
;
8741 objc_finish_method_definition (fn
);
8744 /* This routine synthesizes a 'setter' method. */
8747 objc_synthesize_setter (tree klass
, tree class_method
, tree property
)
8749 tree fn
, decl
, ivar_ident
, lhs
, rhs
;
8751 char *setter_name
= objc_build_property_setter_name (
8752 PROPERTY_NAME (property
), true);
8753 tree setter_ident
= get_identifier (setter_name
);
8755 /* If user has implemented a setter with same name then do nothing. */
8756 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
8760 /* Find declaration of the property in the interface. There must be one. */
8761 decl
= lookup_method (CLASS_NST_METHODS (class_method
), setter_ident
);
8763 /* If one not declared in the inerface, this condition has already been reported
8764 as user error (because property was not declared in the interface. */
8768 /* For now, no attributes. */
8769 objc_start_method_definition (false /* is_class_method */, copy_node (decl
), NULL_TREE
);
8771 body
= c_begin_compound_stmt (true);
8772 /* _property_name = _value; */
8773 /* If user specified an ivar, use it in generation of the setter. */
8774 ivar_ident
= PROPERTY_IVAR_NAME (property
)
8775 ? PROPERTY_IVAR_NAME (property
)
8776 : get_identifier (objc_build_property_ivar_name (property
));
8778 /* objc_ivar_chain might not be up to date in the case that property 'ivar'
8779 is added *after* user ivar is parsed and objc_continue_implementation
8780 has already been called. */
8781 objc_ivar_chain
= CLASS_IVARS (klass
);
8782 lhs
= objc_lookup_ivar (NULL_TREE
, ivar_ident
);
8783 /* If ivar attribute is not a user declared attribute, this condition has
8784 already been repored as error. */
8785 gcc_assert (lhs
|| PROPERTY_IVAR_NAME (property
));
8788 rhs
= lookup_name (get_identifier ("_value"));
8790 /* FIXME: NULL types to get compile. */
8791 add_stmt (build_modify_expr (input_location
,
8792 lhs
, NULL_TREE
, NOP_EXPR
,
8793 input_location
, rhs
, NULL_TREE
));
8795 add_stmt (c_end_compound_stmt (input_location
, body
, true));
8796 fn
= current_function_decl
;
8800 objc_finish_method_definition (fn
);
8803 /* This function is called by the parser after a @synthesize
8804 expression is parsed. 'start_locus' is the location of the
8805 @synthesize expression, and 'property_and_ivar_list' is a chained
8806 list of the property and ivar names.
8809 objc_add_synthesize_declaration (location_t start_locus ATTRIBUTE_UNUSED
, tree property_and_ivar_list ATTRIBUTE_UNUSED
)
8811 if (property_and_ivar_list
== error_mark_node
)
8814 if (!objc_implementation_context
)
8816 /* We can get here only in Objective-C; the Objective-C++ parser
8817 detects the problem while parsing, outputs the error
8818 "misplaced '@synthesize' Objective-C++ construct" and skips
8820 error ("%<@synthesize%> not in @implementation context");
8825 error ("%<@synthesize%> is not supported in this version of the compiler");
8828 /* This function is called by the parser after a @dynamic expression
8829 is parsed. 'start_locus' is the location of the @dynamic
8830 expression, and 'property_list' is a chained list of all the
8833 objc_add_dynamic_declaration (location_t start_locus ATTRIBUTE_UNUSED
, tree property_list ATTRIBUTE_UNUSED
)
8835 if (property_list
== error_mark_node
)
8838 if (!objc_implementation_context
)
8840 /* We can get here only in Objective-C; the Objective-C++ parser
8841 detects the problem while parsing, outputs the error
8842 "misplaced '@dynamic' Objective-C++ construct" and skips the
8844 error ("%<@dynamic%> not in @implementation context");
8849 error ("%<@dynamic%> is not supported in this version of the compiler");
8852 /* Main routine to generate code/data for all the property information for
8853 current implementation (class or category). CLASS is the interface where
8854 ivars are declared. CLASS_METHODS is where methods are found which
8855 could be a class or a category depending on whether we are implementing
8856 property of a class or a category. */
8859 objc_gen_property_data (tree klass
, tree class_methods
)
8862 bool ivar_added
= false;
8863 for (x
= IMPL_PROPERTY_DECL (objc_implementation_context
); x
; x
= TREE_CHAIN (x
))
8864 objc_gen_one_property_datum (klass
, x
, class_methods
, &ivar_added
);
8868 tree record
= CLASS_STATIC_TEMPLATE (klass
);
8869 /* Ugh, must recalculate struct layout since at least one ivar was added. */
8870 TYPE_SIZE (record
) = 0;
8871 layout_type (record
);
8874 /* Synthesize all getters for properties. */
8875 for (x
= IMPL_PROPERTY_DECL (objc_implementation_context
); x
; x
= TREE_CHAIN (x
))
8877 /* Property has a getter attribute, no need to synthesize one. */
8878 if (PROPERTY_GETTER_NAME (x
) == NULL_TREE
)
8879 objc_synthesize_getter (klass
, class_methods
, x
);
8881 objc_process_getter_setter (class_methods
, x
, true);
8883 if (PROPERTY_READONLY (x
) == boolean_false_node
)
8885 /* not a readonly property. */
8886 if (PROPERTY_SETTER_NAME (x
) == NULL_TREE
)
8887 objc_synthesize_setter (klass
, class_methods
, x
);
8889 objc_process_getter_setter (class_methods
, x
, false);
8894 /* This is called once we see the "@end" in an interface/implementation. */
8897 finish_class (tree klass
)
8899 switch (TREE_CODE (klass
))
8901 case CLASS_IMPLEMENTATION_TYPE
:
8903 /* All code generation is done in finish_objc. */
8905 /* Generate what needed for property; setters, getters, etc. */
8906 objc_gen_property_data (implementation_template
, implementation_template
);
8908 if (implementation_template
!= objc_implementation_context
)
8910 /* Ensure that all method listed in the interface contain bodies. */
8911 check_methods (CLASS_CLS_METHODS (implementation_template
),
8912 CLASS_CLS_METHODS (objc_implementation_context
), '+');
8913 check_methods (CLASS_NST_METHODS (implementation_template
),
8914 CLASS_NST_METHODS (objc_implementation_context
), '-');
8916 if (CLASS_PROTOCOL_LIST (implementation_template
))
8917 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
8919 CLASS_NAME (objc_implementation_context
));
8923 case CATEGORY_IMPLEMENTATION_TYPE
:
8925 tree category
= lookup_category (implementation_template
, CLASS_SUPER_NAME (klass
));
8929 /* Generate what needed for property; setters, getters, etc. */
8930 objc_gen_property_data (implementation_template
, category
);
8932 /* Ensure all method listed in the interface contain bodies. */
8933 check_methods (CLASS_CLS_METHODS (category
),
8934 CLASS_CLS_METHODS (objc_implementation_context
), '+');
8935 check_methods (CLASS_NST_METHODS (category
),
8936 CLASS_NST_METHODS (objc_implementation_context
), '-');
8938 if (CLASS_PROTOCOL_LIST (category
))
8939 check_protocols (CLASS_PROTOCOL_LIST (category
),
8941 CLASS_SUPER_NAME (objc_implementation_context
));
8947 /* Process properties of the class. */
8949 for (x
= CLASS_PROPERTY_DECL (objc_interface_context
); x
; x
= TREE_CHAIN (x
))
8951 tree type
= TREE_TYPE (x
);
8952 tree prop_name
= PROPERTY_NAME (x
);
8953 /* Build an instance method declaration: - (type) prop_name; */
8954 if (PROPERTY_GETTER_NAME (x
) == NULL_TREE
)
8956 /* No getter attribute specified. Generate an instance method for the
8958 tree rettype
= build_tree_list (NULL_TREE
, type
);
8959 tree getter_decl
= build_method_decl (INSTANCE_METHOD_DECL
,
8962 objc_add_method (objc_interface_context
, getter_decl
, false, false);
8963 METHOD_PROPERTY_CONTEXT (getter_decl
) = x
;
8966 warning (0, "getter = %qs may not be specified in an interface",
8967 IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (x
)));
8969 /* Build an instance method declaration: - (void) setName: (type)value; */
8970 if (PROPERTY_SETTER_NAME (x
) == NULL_TREE
8971 && PROPERTY_READONLY (x
) == boolean_false_node
)
8973 /* Declare a setter instance method in the interface. */
8974 tree key_name
, arg_type
, arg_name
;
8975 tree setter_decl
, selector
;
8976 tree ret_type
= build_tree_list (NULL_TREE
, void_type_node
);
8978 key_name
= get_identifier (objc_build_property_setter_name
8979 (PROPERTY_NAME (x
), false));
8980 arg_type
= build_tree_list (NULL_TREE
, type
);
8981 arg_name
= get_identifier ("_value");
8982 /* For now, no attributes. */
8983 selector
= objc_build_keyword_decl (key_name
, arg_type
, arg_name
, NULL
);
8984 setter_decl
= build_method_decl (INSTANCE_METHOD_DECL
,
8986 build_tree_list (NULL_TREE
, NULL_TREE
),
8988 objc_add_method (objc_interface_context
, setter_decl
, false, false);
8989 METHOD_PROPERTY_CONTEXT (setter_decl
) = x
;
8991 else if (PROPERTY_SETTER_NAME (x
))
8992 warning (0, "setter = %qs may not be specified in an interface",
8993 IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x
)));
8994 if (PROPERTY_IVAR_NAME (x
))
8995 warning (0, "ivar = %qs attribute may not be specified in an interface",
8996 IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (x
)));
9003 add_protocol (tree protocol
)
9005 /* Put protocol on list in reverse order. */
9006 TREE_CHAIN (protocol
) = protocol_chain
;
9007 protocol_chain
= protocol
;
9008 return protocol_chain
;
9012 lookup_protocol (tree ident
)
9016 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
9017 if (ident
== PROTOCOL_NAME (chain
))
9023 /* This function forward declares the protocols named by NAMES. If
9024 they are already declared or defined, the function has no effect. */
9027 objc_declare_protocols (tree names
)
9032 if (current_namespace
!= global_namespace
) {
9033 error ("Objective-C declarations may only appear in global scope");
9035 #endif /* OBJCPLUS */
9037 for (list
= names
; list
; list
= TREE_CHAIN (list
))
9039 tree name
= TREE_VALUE (list
);
9041 if (lookup_protocol (name
) == NULL_TREE
)
9043 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
9045 TYPE_LANG_SLOT_1 (protocol
)
9046 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
9047 PROTOCOL_NAME (protocol
) = name
;
9048 PROTOCOL_LIST (protocol
) = NULL_TREE
;
9049 add_protocol (protocol
);
9050 PROTOCOL_DEFINED (protocol
) = 0;
9051 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
9057 start_protocol (enum tree_code code
, tree name
, tree list
)
9062 if (current_namespace
!= global_namespace
) {
9063 error ("Objective-C declarations may only appear in global scope");
9065 #endif /* OBJCPLUS */
9067 protocol
= lookup_protocol (name
);
9071 protocol
= make_node (code
);
9072 TYPE_LANG_SLOT_1 (protocol
) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
9074 PROTOCOL_NAME (protocol
) = name
;
9075 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
9076 add_protocol (protocol
);
9077 PROTOCOL_DEFINED (protocol
) = 1;
9078 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
9080 check_protocol_recursively (protocol
, list
);
9082 else if (! PROTOCOL_DEFINED (protocol
))
9084 PROTOCOL_DEFINED (protocol
) = 1;
9085 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
9087 check_protocol_recursively (protocol
, list
);
9091 warning (0, "duplicate declaration for protocol %qE",
9098 /* "Encode" a data type into a string, which grows in util_obstack.
9100 The format is described in gcc/doc/objc.texi, section 'Type
9103 Most of the encode_xxx functions have a 'type' argument, which is
9104 the type to encode, and an integer 'curtype' argument, which is the
9105 index in the encoding string of the beginning of the encoding of
9106 the current type, and allows you to find what characters have
9107 already been written for the current type (they are the ones in the
9108 current encoding string starting from 'curtype').
9110 For example, if we are encoding a method which returns 'int' and
9111 takes a 'char **' argument, then when we get to the point of
9112 encoding the 'char **' argument, the encoded string already
9113 contains 'i12@0:4' (assuming a pointer size of 4 bytes). So,
9114 'curtype' will be set to 7 when starting to encode 'char **'.
9115 During the whole of the encoding of 'char **', 'curtype' will be
9116 fixed at 7, so the routine encoding the second pointer can find out
9117 that it's actually encoding a pointer to a pointer by looking
9118 backwards at what has already been encoded for the current type,
9119 and seeing there is a "^" (meaning a pointer) in there.
9123 /* Encode type qualifiers encodes one of the "PQ" Objective-C
9124 keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
9125 'const', instead, is encoded directly as part of the type.
9129 encode_type_qualifiers (tree declspecs
)
9133 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
9135 /* FIXME: Shouldn't we use token->keyword here ? */
9136 if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
9137 obstack_1grow (&util_obstack
, 'n');
9138 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
9139 obstack_1grow (&util_obstack
, 'N');
9140 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
9141 obstack_1grow (&util_obstack
, 'o');
9142 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
9143 obstack_1grow (&util_obstack
, 'O');
9144 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
9145 obstack_1grow (&util_obstack
, 'R');
9146 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
9147 obstack_1grow (&util_obstack
, 'V');
9153 /* Determine if a pointee is marked read-only. Only used by the NeXT
9154 runtime to be compatible with gcc-3.3. */
9157 pointee_is_readonly (tree pointee
)
9159 while (POINTER_TYPE_P (pointee
))
9160 pointee
= TREE_TYPE (pointee
);
9162 return TYPE_READONLY (pointee
);
9165 /* Encode a pointer type. */
9168 encode_pointer (tree type
, int curtype
, int format
)
9170 tree pointer_to
= TREE_TYPE (type
);
9172 if (flag_next_runtime
)
9174 /* This code is used to be compatible with gcc-3.3. */
9175 /* For historical/compatibility reasons, the read-only qualifier
9176 of the pointee gets emitted _before_ the '^'. The read-only
9177 qualifier of the pointer itself gets ignored, _unless_ we are
9178 looking at a typedef! Also, do not emit the 'r' for anything
9179 but the outermost type! */
9180 if (!generating_instance_variables
9181 && (obstack_object_size (&util_obstack
) - curtype
<= 1)
9182 && (TYPE_NAME (type
) && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
9183 ? TYPE_READONLY (type
)
9184 : pointee_is_readonly (pointer_to
)))
9185 obstack_1grow (&util_obstack
, 'r');
9188 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
9190 if (OBJC_TYPE_NAME (pointer_to
)
9191 && TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
9193 const char *name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to
));
9195 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
9197 obstack_1grow (&util_obstack
, '@');
9200 else if (TYPE_HAS_OBJC_INFO (pointer_to
)
9201 && TYPE_OBJC_INTERFACE (pointer_to
))
9203 if (generating_instance_variables
)
9205 obstack_1grow (&util_obstack
, '@');
9206 obstack_1grow (&util_obstack
, '"');
9207 obstack_grow (&util_obstack
, name
, strlen (name
));
9208 obstack_1grow (&util_obstack
, '"');
9213 obstack_1grow (&util_obstack
, '@');
9217 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
9219 obstack_1grow (&util_obstack
, '#');
9222 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
9224 obstack_1grow (&util_obstack
, ':');
9229 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
9230 && TYPE_MODE (pointer_to
) == QImode
)
9232 tree pname
= TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
9233 ? OBJC_TYPE_NAME (pointer_to
)
9234 : DECL_NAME (OBJC_TYPE_NAME (pointer_to
));
9236 /* (BOOL *) are an exception and are encoded as ^c, while all
9237 other pointers to char are encoded as *. */
9238 if (strcmp (IDENTIFIER_POINTER (pname
), "BOOL"))
9240 if (!flag_next_runtime
)
9242 /* The NeXT runtime adds the 'r' before getting here. */
9244 /* It appears that "r*" means "const char *" rather than
9245 "char *const". "char *const" is encoded as "*",
9246 which is identical to "char *", so the "const" is
9247 unfortunately lost. */
9248 if (TYPE_READONLY (pointer_to
))
9249 obstack_1grow (&util_obstack
, 'r');
9252 obstack_1grow (&util_obstack
, '*');
9257 /* We have a normal pointer type that does not get special treatment. */
9258 obstack_1grow (&util_obstack
, '^');
9259 encode_type (pointer_to
, curtype
, format
);
9263 encode_array (tree type
, int curtype
, int format
)
9265 tree an_int_cst
= TYPE_SIZE (type
);
9266 tree array_of
= TREE_TYPE (type
);
9269 if (an_int_cst
== NULL
)
9271 /* We are trying to encode an incomplete array. An incomplete
9272 array is forbidden as part of an instance variable. */
9273 if (generating_instance_variables
)
9275 /* TODO: Detect this error earlier. */
9276 error ("instance variable has unknown size");
9280 /* So the only case in which an incomplete array could occur is
9281 if we are encoding the arguments or return value of a method.
9282 In that case, an incomplete array argument or return value
9283 (eg, -(void)display: (char[])string) is treated like a
9284 pointer because that is how the compiler does the function
9285 call. A special, more complicated case, is when the
9286 incomplete array is the last member of a struct (eg, if we
9287 are encoding "struct { unsigned long int a;double b[];}"),
9288 which is again part of a method argument/return value. In
9289 that case, we really need to communicate to the runtime that
9290 there is an incomplete array (not a pointer!) there. So, we
9291 detect that special case and encode it as a zero-length
9294 Try to detect that we are part of a struct. We do this by
9295 searching for '=' in the type encoding for the current type.
9296 NB: This hack assumes that you can't use '=' as part of a C
9300 char *enc
= obstack_base (&util_obstack
) + curtype
;
9301 if (memchr (enc
, '=',
9302 obstack_object_size (&util_obstack
) - curtype
) == NULL
)
9304 /* We are not inside a struct. Encode the array as a
9306 encode_pointer (type
, curtype
, format
);
9311 /* Else, we are in a struct, and we encode it as a zero-length
9313 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
)0);
9315 else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of
)) == 0)
9316 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
)0);
9318 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
,
9319 TREE_INT_CST_LOW (an_int_cst
)
9320 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
)));
9322 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
9323 encode_type (array_of
, curtype
, format
);
9324 obstack_1grow (&util_obstack
, ']');
9328 /* Encode a vector. The vector type is a GCC extension to C. */
9330 encode_vector (tree type
, int curtype
, int format
)
9332 tree vector_of
= TREE_TYPE (type
);
9335 /* Vectors are like simple fixed-size arrays. */
9337 /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
9338 alignment of the vector, and <code> is the base type. Eg, int
9339 __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
9340 assuming that the alignment is 32 bytes. We include size and
9341 alignment in bytes so that the runtime does not have to have any
9342 knowledge of the actual types.
9344 sprintf (buffer
, "![" HOST_WIDE_INT_PRINT_DEC
",%d",
9345 /* We want to compute the equivalent of sizeof (<vector>).
9346 Code inspired by c_sizeof_or_alignof_type. */
9347 ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type
))
9348 / (TYPE_PRECISION (char_type_node
) / BITS_PER_UNIT
))),
9349 /* We want to compute the equivalent of __alignof__
9350 (<vector>). Code inspired by
9351 c_sizeof_or_alignof_type. */
9352 TYPE_ALIGN_UNIT (type
));
9353 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
9354 encode_type (vector_of
, curtype
, format
);
9355 obstack_1grow (&util_obstack
, ']');
9360 encode_aggregate_fields (tree type
, bool pointed_to
, int curtype
, int format
)
9362 tree field
= TYPE_FIELDS (type
);
9364 for (; field
; field
= DECL_CHAIN (field
))
9367 /* C++ static members, and things that are not field at all,
9368 should not appear in the encoding. */
9369 if (TREE_CODE (field
) != FIELD_DECL
|| TREE_STATIC (field
))
9373 /* Recursively encode fields of embedded base classes. */
9374 if (DECL_ARTIFICIAL (field
) && !DECL_NAME (field
)
9375 && TREE_CODE (TREE_TYPE (field
)) == RECORD_TYPE
)
9377 encode_aggregate_fields (TREE_TYPE (field
),
9378 pointed_to
, curtype
, format
);
9382 if (generating_instance_variables
&& !pointed_to
)
9384 tree fname
= DECL_NAME (field
);
9386 obstack_1grow (&util_obstack
, '"');
9388 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
9389 obstack_grow (&util_obstack
,
9390 IDENTIFIER_POINTER (fname
),
9391 strlen (IDENTIFIER_POINTER (fname
)));
9393 obstack_1grow (&util_obstack
, '"');
9396 encode_field_decl (field
, curtype
, format
);
9401 encode_aggregate_within (tree type
, int curtype
, int format
, int left
,
9405 /* NB: aggregates that are pointed to have slightly different encoding
9406 rules in that you never encode the names of instance variables. */
9407 int ob_size
= obstack_object_size (&util_obstack
);
9408 bool inline_contents
= false;
9409 bool pointed_to
= false;
9411 if (flag_next_runtime
)
9413 if (ob_size
> 0 && *(obstack_next_free (&util_obstack
) - 1) == '^')
9416 if ((format
== OBJC_ENCODE_INLINE_DEFS
|| generating_instance_variables
)
9417 && (!pointed_to
|| ob_size
- curtype
== 1
9418 || (ob_size
- curtype
== 2
9419 && *(obstack_next_free (&util_obstack
) - 2) == 'r')))
9420 inline_contents
= true;
9424 /* c0 and c1 are the last two characters in the encoding of the
9425 current type; if the last two characters were '^' or '^r',
9426 then we are encoding an aggregate that is "pointed to". The
9427 comment above applies: in that case we should avoid encoding
9428 the names of instance variables.
9430 char c1
= ob_size
> 1 ? *(obstack_next_free (&util_obstack
) - 2) : 0;
9431 char c0
= ob_size
> 0 ? *(obstack_next_free (&util_obstack
) - 1) : 0;
9433 if (c0
== '^' || (c1
== '^' && c0
== 'r'))
9436 if (format
== OBJC_ENCODE_INLINE_DEFS
|| generating_instance_variables
)
9439 inline_contents
= true;
9442 /* Note that the check (ob_size - curtype < 2) prevents
9443 infinite recursion when encoding a structure which is
9444 a linked list (eg, struct node { struct node *next;
9445 }). Each time we follow a pointer, we add one
9446 character to ob_size, and curtype is fixed, so after
9447 at most two pointers we stop inlining contents and
9450 The other case where we don't inline is "^r", which
9451 is a pointer to a constant struct.
9453 if ((ob_size
- curtype
<= 2) && !(c0
== 'r'))
9454 inline_contents
= true;
9459 /* Traverse struct aliases; it is important to get the
9460 original struct and its tag name (if any). */
9461 type
= TYPE_MAIN_VARIANT (type
);
9462 name
= OBJC_TYPE_NAME (type
);
9463 /* Open parenth/bracket. */
9464 obstack_1grow (&util_obstack
, left
);
9466 /* Encode the struct/union tag name, or '?' if a tag was
9467 not provided. Typedef aliases do not qualify. */
9469 /* For compatibility with the NeXT runtime, ObjC++ encodes template
9470 args as a composite struct tag name. */
9471 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
9472 /* Did this struct have a tag? */
9473 && !TYPE_WAS_ANONYMOUS (type
))
9474 obstack_grow (&util_obstack
,
9475 decl_as_string (type
, TFF_DECL_SPECIFIERS
| TFF_UNQUALIFIED_NAME
),
9476 strlen (decl_as_string (type
, TFF_DECL_SPECIFIERS
| TFF_UNQUALIFIED_NAME
)));
9478 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
9479 obstack_grow (&util_obstack
,
9480 IDENTIFIER_POINTER (name
),
9481 strlen (IDENTIFIER_POINTER (name
)));
9484 obstack_1grow (&util_obstack
, '?');
9486 /* Encode the types (and possibly names) of the inner fields,
9488 if (inline_contents
)
9490 obstack_1grow (&util_obstack
, '=');
9491 encode_aggregate_fields (type
, pointed_to
, curtype
, format
);
9493 /* Close parenth/bracket. */
9494 obstack_1grow (&util_obstack
, right
);
9497 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
9501 encode_next_bitfield (int width
)
9504 sprintf (buffer
, "b%d", width
);
9505 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
9509 /* Encodes 'type', ignoring type qualifiers (which you should encode
9510 beforehand if needed) with the exception of 'const', which is
9511 encoded by encode_type. See above for the explanation of
9512 'curtype'. 'format' can be OBJC_ENCODE_INLINE_DEFS or
9513 OBJC_ENCODE_DONT_INLINE_DEFS.
9516 encode_type (tree type
, int curtype
, int format
)
9518 enum tree_code code
= TREE_CODE (type
);
9520 /* Ignore type qualifiers other than 'const' when encoding a
9523 if (type
== error_mark_node
)
9526 if (!flag_next_runtime
)
9528 if (TYPE_READONLY (type
))
9529 obstack_1grow (&util_obstack
, 'r');
9535 if (flag_next_runtime
)
9537 /* Kludge for backwards-compatibility with gcc-3.3: enums
9538 are always encoded as 'i' no matter what type they
9539 actually are (!). */
9540 obstack_1grow (&util_obstack
, 'i');
9543 /* Else, they are encoded exactly like the integer type that is
9544 used by the compiler to store them. */
9548 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
9550 case 8: c
= TYPE_UNSIGNED (type
) ? 'C' : 'c'; break;
9551 case 16: c
= TYPE_UNSIGNED (type
) ? 'S' : 's'; break;
9554 tree int_type
= type
;
9555 if (flag_next_runtime
)
9557 /* Another legacy kludge for compatiblity with
9558 gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
9559 but not always. For typedefs, we need to use 'i'
9560 or 'I' instead if encoding a struct field, or a
9562 int_type
= ((!generating_instance_variables
9563 && (obstack_object_size (&util_obstack
)
9564 == (unsigned) curtype
))
9565 ? TYPE_MAIN_VARIANT (type
)
9568 if (int_type
== long_unsigned_type_node
9569 || int_type
== long_integer_type_node
)
9570 c
= TYPE_UNSIGNED (type
) ? 'L' : 'l';
9572 c
= TYPE_UNSIGNED (type
) ? 'I' : 'i';
9575 case 64: c
= TYPE_UNSIGNED (type
) ? 'Q' : 'q'; break;
9576 case 128: c
= TYPE_UNSIGNED (type
) ? 'T' : 't'; break;
9577 default: gcc_unreachable ();
9579 obstack_1grow (&util_obstack
, c
);
9585 /* Floating point types. */
9586 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
9588 case 32: c
= 'f'; break;
9589 case 64: c
= 'd'; break;
9591 case 128: c
= 'D'; break;
9592 default: gcc_unreachable ();
9594 obstack_1grow (&util_obstack
, c
);
9598 obstack_1grow (&util_obstack
, 'v');
9602 obstack_1grow (&util_obstack
, 'B');
9606 encode_array (type
, curtype
, format
);
9611 case REFERENCE_TYPE
:
9613 encode_pointer (type
, curtype
, format
);
9617 encode_aggregate_within (type
, curtype
, format
, '{', '}');
9621 encode_aggregate_within (type
, curtype
, format
, '(', ')');
9624 case FUNCTION_TYPE
: /* '?' means an unknown type. */
9625 obstack_1grow (&util_obstack
, '?');
9629 /* A complex is encoded as 'j' followed by the inner type (eg,
9630 "_Complex int" is encoded as 'ji'). */
9631 obstack_1grow (&util_obstack
, 'j');
9632 encode_type (TREE_TYPE (type
), curtype
, format
);
9636 encode_vector (type
, curtype
, format
);
9640 warning (0, "unknown type %s found during Objective-C encoding",
9641 gen_type_name (type
));
9642 obstack_1grow (&util_obstack
, '?');
9646 if (flag_next_runtime
)
9648 /* Super-kludge. Some ObjC qualifier and type combinations need
9649 to be rearranged for compatibility with gcc-3.3. */
9650 if (code
== POINTER_TYPE
&& obstack_object_size (&util_obstack
) >= 3)
9652 char *enc
= obstack_base (&util_obstack
) + curtype
;
9654 /* Rewrite "in const" from "nr" to "rn". */
9655 if (curtype
>= 1 && !strncmp (enc
- 1, "nr", 2))
9656 strncpy (enc
- 1, "rn", 2);
9662 encode_gnu_bitfield (int position
, tree type
, int size
)
9664 enum tree_code code
= TREE_CODE (type
);
9666 char charType
= '?';
9668 /* This code is only executed for the GNU runtime, so we can ignore
9669 the NeXT runtime kludge of always encoding enums as 'i' no matter
9670 what integers they actually are. */
9671 if (code
== INTEGER_TYPE
|| code
== ENUMERAL_TYPE
)
9673 if (integer_zerop (TYPE_MIN_VALUE (type
)))
9674 /* Unsigned integer types. */
9676 switch (TYPE_MODE (type
))
9679 charType
= 'C'; break;
9681 charType
= 'S'; break;
9684 if (type
== long_unsigned_type_node
)
9691 charType
= 'Q'; break;
9697 /* Signed integer types. */
9699 switch (TYPE_MODE (type
))
9702 charType
= 'c'; break;
9704 charType
= 's'; break;
9707 if (type
== long_integer_type_node
)
9714 charType
= 'q'; break;
9722 /* Do not do any encoding, produce an error and keep going. */
9723 error ("trying to encode non-integer type as a bitfield");
9727 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
9728 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
9732 encode_field_decl (tree field_decl
, int curtype
, int format
)
9735 /* C++ static members, and things that are not fields at all,
9736 should not appear in the encoding. */
9737 if (TREE_CODE (field_decl
) != FIELD_DECL
|| TREE_STATIC (field_decl
))
9741 /* Generate the bitfield typing information, if needed. Note the difference
9742 between GNU and NeXT runtimes. */
9743 if (DECL_BIT_FIELD_TYPE (field_decl
))
9745 int size
= tree_low_cst (DECL_SIZE (field_decl
), 1);
9747 if (flag_next_runtime
)
9748 encode_next_bitfield (size
);
9750 encode_gnu_bitfield (int_bit_position (field_decl
),
9751 DECL_BIT_FIELD_TYPE (field_decl
), size
);
9754 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
9757 /* Decay array and function parameters into pointers. */
9760 objc_decay_parm_type (tree type
)
9762 if (TREE_CODE (type
) == ARRAY_TYPE
|| TREE_CODE (type
) == FUNCTION_TYPE
)
9763 type
= build_pointer_type (TREE_CODE (type
) == ARRAY_TYPE
9770 static GTY(()) tree objc_parmlist
= NULL_TREE
;
9772 /* Append PARM to a list of formal parameters of a method, making a necessary
9773 array-to-pointer adjustment along the way. */
9776 objc_push_parm (tree parm
)
9780 if (TREE_TYPE (parm
) == error_mark_node
)
9782 objc_parmlist
= chainon (objc_parmlist
, parm
);
9786 /* Decay arrays and functions into pointers. */
9787 type
= objc_decay_parm_type (TREE_TYPE (parm
));
9789 /* If the parameter type has been decayed, a new PARM_DECL needs to be
9791 if (type
!= TREE_TYPE (parm
))
9792 parm
= build_decl (input_location
, PARM_DECL
, DECL_NAME (parm
), type
);
9794 DECL_ARG_TYPE (parm
)
9795 = lang_hooks
.types
.type_promotes_to (TREE_TYPE (parm
));
9797 /* Record constancy and volatility. */
9798 c_apply_type_quals_to_decl
9799 ((TYPE_READONLY (TREE_TYPE (parm
)) ? TYPE_QUAL_CONST
: 0)
9800 | (TYPE_RESTRICT (TREE_TYPE (parm
)) ? TYPE_QUAL_RESTRICT
: 0)
9801 | (TYPE_VOLATILE (TREE_TYPE (parm
)) ? TYPE_QUAL_VOLATILE
: 0), parm
);
9803 objc_parmlist
= chainon (objc_parmlist
, parm
);
9806 /* Retrieve the formal parameter list constructed via preceding calls to
9807 objc_push_parm(). */
9811 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED
)
9813 static struct c_arg_info
*
9814 objc_get_parm_info (int have_ellipsis
)
9818 tree parm_info
= objc_parmlist
;
9819 objc_parmlist
= NULL_TREE
;
9823 tree parm_info
= objc_parmlist
;
9824 struct c_arg_info
*arg_info
;
9825 /* The C front-end requires an elaborate song and dance at
9828 declare_parm_level ();
9831 tree next
= DECL_CHAIN (parm_info
);
9833 DECL_CHAIN (parm_info
) = NULL_TREE
;
9834 parm_info
= pushdecl (parm_info
);
9835 finish_decl (parm_info
, input_location
, NULL_TREE
, NULL_TREE
, NULL_TREE
);
9838 arg_info
= get_parm_info (have_ellipsis
);
9840 objc_parmlist
= NULL_TREE
;
9845 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
9846 method definitions. In the case of instance methods, we can be more
9847 specific as to the type of 'self'. */
9850 synth_self_and_ucmd_args (void)
9854 if (objc_method_context
9855 && TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
9856 self_type
= objc_instance_type
;
9858 /* Really a `struct objc_class *'. However, we allow people to
9859 assign to self, which changes its type midstream. */
9860 self_type
= objc_object_type
;
9863 objc_push_parm (build_decl (input_location
,
9864 PARM_DECL
, self_id
, self_type
));
9867 objc_push_parm (build_decl (input_location
,
9868 PARM_DECL
, ucmd_id
, objc_selector_type
));
9871 /* Transform an Objective-C method definition into a static C function
9872 definition, synthesizing the first two arguments, "self" and "_cmd",
9876 start_method_def (tree method
)
9882 struct c_arg_info
*parm_info
;
9884 int have_ellipsis
= 0;
9886 /* If we are defining a "dealloc" method in a non-root class, we
9887 will need to check if a [super dealloc] is missing, and warn if
9889 if(CLASS_SUPER_NAME (objc_implementation_context
)
9890 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method
))))
9891 should_call_super_dealloc
= 1;
9893 should_call_super_dealloc
= 0;
9895 /* Required to implement _msgSuper. */
9896 objc_method_context
= method
;
9897 UOBJC_SUPER_decl
= NULL_TREE
;
9899 /* Generate prototype declarations for arguments..."new-style". */
9900 synth_self_and_ucmd_args ();
9902 /* Generate argument declarations if a keyword_decl. */
9903 parmlist
= METHOD_SEL_ARGS (method
);
9906 /* parmlist is a KEYWORD_DECL. */
9907 tree type
= TREE_VALUE (TREE_TYPE (parmlist
));
9910 parm
= build_decl (input_location
,
9911 PARM_DECL
, KEYWORD_ARG_NAME (parmlist
), type
);
9912 decl_attributes (&parm
, DECL_ATTRIBUTES (parmlist
), 0);
9913 objc_push_parm (parm
);
9914 parmlist
= DECL_CHAIN (parmlist
);
9917 if (METHOD_ADD_ARGS (method
))
9921 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
9922 akey
; akey
= TREE_CHAIN (akey
))
9924 objc_push_parm (TREE_VALUE (akey
));
9927 if (METHOD_ADD_ARGS_ELLIPSIS_P (method
))
9931 parm_info
= objc_get_parm_info (have_ellipsis
);
9933 really_start_method (objc_method_context
, parm_info
);
9936 /* Return 1 if TYPE1 is equivalent to TYPE2
9937 for purposes of method overloading. */
9940 objc_types_are_equivalent (tree type1
, tree type2
)
9945 /* Strip away indirections. */
9946 while ((TREE_CODE (type1
) == ARRAY_TYPE
|| TREE_CODE (type1
) == POINTER_TYPE
)
9947 && (TREE_CODE (type1
) == TREE_CODE (type2
)))
9948 type1
= TREE_TYPE (type1
), type2
= TREE_TYPE (type2
);
9949 if (TYPE_MAIN_VARIANT (type1
) != TYPE_MAIN_VARIANT (type2
))
9952 type1
= (TYPE_HAS_OBJC_INFO (type1
)
9953 ? TYPE_OBJC_PROTOCOL_LIST (type1
)
9955 type2
= (TYPE_HAS_OBJC_INFO (type2
)
9956 ? TYPE_OBJC_PROTOCOL_LIST (type2
)
9959 if (list_length (type1
) == list_length (type2
))
9961 for (; type2
; type2
= TREE_CHAIN (type2
))
9962 if (!lookup_protocol_in_reflist (type1
, TREE_VALUE (type2
)))
9969 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
9972 objc_types_share_size_and_alignment (tree type1
, tree type2
)
9974 return (simple_cst_equal (TYPE_SIZE (type1
), TYPE_SIZE (type2
))
9975 && TYPE_ALIGN (type1
) == TYPE_ALIGN (type2
));
9978 /* Return 1 if PROTO1 is equivalent to PROTO2
9979 for purposes of method overloading. Ordinarily, the type signatures
9980 should match up exactly, unless STRICT is zero, in which case we
9981 shall allow differences in which the size and alignment of a type
9985 comp_proto_with_proto (tree proto1
, tree proto2
, int strict
)
9987 /* The following test is needed in case there are hashing
9989 if (METHOD_SEL_NAME (proto1
) != METHOD_SEL_NAME (proto2
))
9992 return match_proto_with_proto (proto1
, proto2
, strict
);
9996 match_proto_with_proto (tree proto1
, tree proto2
, int strict
)
10000 /* Compare return types. */
10001 type1
= TREE_VALUE (TREE_TYPE (proto1
));
10002 type2
= TREE_VALUE (TREE_TYPE (proto2
));
10004 if (!objc_types_are_equivalent (type1
, type2
)
10005 && (strict
|| !objc_types_share_size_and_alignment (type1
, type2
)))
10008 /* Compare argument types. */
10009 for (type1
= get_arg_type_list (proto1
, METHOD_REF
, 0),
10010 type2
= get_arg_type_list (proto2
, METHOD_REF
, 0);
10012 type1
= TREE_CHAIN (type1
), type2
= TREE_CHAIN (type2
))
10014 if (!objc_types_are_equivalent (TREE_VALUE (type1
), TREE_VALUE (type2
))
10016 || !objc_types_share_size_and_alignment (TREE_VALUE (type1
),
10017 TREE_VALUE (type2
))))
10021 return (!type1
&& !type2
);
10024 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
10025 this occurs. ObjC method dispatches are _not_ like C++ virtual
10026 member function dispatches, and we account for the difference here. */
10029 objc_fold_obj_type_ref (tree ref
, tree known_type
)
10031 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED
,
10032 tree known_type ATTRIBUTE_UNUSED
)
10036 tree v
= BINFO_VIRTUALS (TYPE_BINFO (known_type
));
10038 /* If the receiver does not have virtual member functions, there
10039 is nothing we can (or need to) do here. */
10043 /* Let C++ handle C++ virtual functions. */
10044 return cp_fold_obj_type_ref (ref
, known_type
);
10046 /* For plain ObjC, we currently do not need to do anything. */
10052 objc_start_function (tree name
, tree type
, tree attrs
,
10056 struct c_arg_info
*params
10060 tree fndecl
= build_decl (input_location
,
10061 FUNCTION_DECL
, name
, type
);
10064 DECL_ARGUMENTS (fndecl
) = params
;
10065 DECL_INITIAL (fndecl
) = error_mark_node
;
10066 DECL_EXTERNAL (fndecl
) = 0;
10067 TREE_STATIC (fndecl
) = 1;
10068 retrofit_lang_decl (fndecl
);
10069 cplus_decl_attributes (&fndecl
, attrs
, 0);
10070 start_preparsed_function (fndecl
, attrs
, /*flags=*/SF_DEFAULT
);
10072 current_function_returns_value
= 0; /* Assume, until we see it does. */
10073 current_function_returns_null
= 0;
10074 decl_attributes (&fndecl
, attrs
, 0);
10075 announce_function (fndecl
);
10076 DECL_INITIAL (fndecl
) = error_mark_node
;
10077 DECL_EXTERNAL (fndecl
) = 0;
10078 TREE_STATIC (fndecl
) = 1;
10079 current_function_decl
= pushdecl (fndecl
);
10081 declare_parm_level ();
10082 DECL_RESULT (current_function_decl
)
10083 = build_decl (input_location
,
10084 RESULT_DECL
, NULL_TREE
,
10085 TREE_TYPE (TREE_TYPE (current_function_decl
)));
10086 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl
)) = 1;
10087 DECL_IGNORED_P (DECL_RESULT (current_function_decl
)) = 1;
10088 start_fname_decls ();
10089 store_parm_decls_from (params
);
10092 TREE_USED (current_function_decl
) = 1;
10095 /* - Generate an identifier for the function. the format is "_n_cls",
10096 where 1 <= n <= nMethods, and cls is the name the implementation we
10098 - Install the return type from the method declaration.
10099 - If we have a prototype, check for type consistency. */
10102 really_start_method (tree method
,
10106 struct c_arg_info
*parmlist
10110 tree ret_type
, meth_type
;
10112 const char *sel_name
, *class_name
, *cat_name
;
10115 /* Synth the storage class & assemble the return type. */
10116 ret_type
= TREE_VALUE (TREE_TYPE (method
));
10118 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
10119 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
10120 cat_name
= ((TREE_CODE (objc_implementation_context
)
10121 == CLASS_IMPLEMENTATION_TYPE
)
10123 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
10126 /* Make sure this is big enough for any plausible method label. */
10127 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
10128 + (cat_name
? strlen (cat_name
) : 0));
10130 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
10131 class_name
, cat_name
, sel_name
, method_slot
);
10133 method_id
= get_identifier (buf
);
10136 /* Objective-C methods cannot be overloaded, so we don't need
10137 the type encoding appended. It looks bad anyway... */
10138 push_lang_context (lang_name_c
);
10142 = build_function_type (ret_type
,
10143 get_arg_type_list (method
, METHOD_DEF
, 0));
10144 objc_start_function (method_id
, meth_type
, NULL_TREE
, parmlist
);
10146 /* Set self_decl from the first argument. */
10147 self_decl
= DECL_ARGUMENTS (current_function_decl
);
10149 /* Suppress unused warnings. */
10150 TREE_USED (self_decl
) = 1;
10151 DECL_READ_P (self_decl
) = 1;
10152 TREE_USED (DECL_CHAIN (self_decl
)) = 1;
10153 DECL_READ_P (DECL_CHAIN (self_decl
)) = 1;
10155 pop_lang_context ();
10158 METHOD_DEFINITION (method
) = current_function_decl
;
10160 /* Check consistency...start_function, pushdecl, duplicate_decls. */
10162 if (implementation_template
!= objc_implementation_context
)
10165 = lookup_method_static (implementation_template
,
10166 METHOD_SEL_NAME (method
),
10167 ((TREE_CODE (method
) == CLASS_METHOD_DECL
)
10168 | OBJC_LOOKUP_NO_SUPER
));
10172 if (!comp_proto_with_proto (method
, proto
, 1))
10174 bool type
= TREE_CODE (method
) == INSTANCE_METHOD_DECL
;
10176 warning_at (DECL_SOURCE_LOCATION (method
), 0,
10177 "conflicting types for %<%c%s%>",
10178 (type
? '-' : '+'),
10179 identifier_to_locale (gen_method_decl (method
)));
10180 inform (DECL_SOURCE_LOCATION (proto
),
10181 "previous declaration of %<%c%s%>",
10182 (type
? '-' : '+'),
10183 identifier_to_locale (gen_method_decl (proto
)));
10188 /* We have a method @implementation even though we did not
10189 see a corresponding @interface declaration (which is allowed
10190 by Objective-C rules). Go ahead and place the method in
10191 the @interface anyway, so that message dispatch lookups
10193 tree interface
= implementation_template
;
10195 if (TREE_CODE (objc_implementation_context
)
10196 == CATEGORY_IMPLEMENTATION_TYPE
)
10197 interface
= lookup_category
10199 CLASS_SUPER_NAME (objc_implementation_context
));
10202 objc_add_method (interface
, copy_node (method
),
10203 TREE_CODE (method
) == CLASS_METHOD_DECL
,
10204 /* is_optional= */ false);
10209 static void *UOBJC_SUPER_scope
= 0;
10211 /* _n_Method (id self, SEL sel, ...)
10213 struct objc_super _S;
10214 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
10218 get_super_receiver (void)
10220 if (objc_method_context
)
10222 tree super_expr
, super_expr_list
;
10224 if (!UOBJC_SUPER_decl
)
10226 UOBJC_SUPER_decl
= build_decl (input_location
,
10227 VAR_DECL
, get_identifier (TAG_SUPER
),
10228 objc_super_template
);
10229 /* This prevents `unused variable' warnings when compiling with -Wall. */
10230 TREE_USED (UOBJC_SUPER_decl
) = 1;
10231 DECL_READ_P (UOBJC_SUPER_decl
) = 1;
10232 lang_hooks
.decls
.pushdecl (UOBJC_SUPER_decl
);
10233 finish_decl (UOBJC_SUPER_decl
, input_location
, NULL_TREE
, NULL_TREE
,
10235 UOBJC_SUPER_scope
= objc_get_current_scope ();
10238 /* Set receiver to self. */
10239 super_expr
= objc_build_component_ref (UOBJC_SUPER_decl
, self_id
);
10240 super_expr
= build_modify_expr (input_location
, super_expr
, NULL_TREE
,
10241 NOP_EXPR
, input_location
, self_decl
,
10243 super_expr_list
= super_expr
;
10245 /* Set class to begin searching. */
10246 super_expr
= objc_build_component_ref (UOBJC_SUPER_decl
,
10247 get_identifier ("super_class"));
10249 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
10251 /* [_cls, __cls]Super are "pre-built" in
10252 synth_forward_declarations. */
10254 super_expr
= build_modify_expr (input_location
, super_expr
,
10255 NULL_TREE
, NOP_EXPR
,
10257 ((TREE_CODE (objc_method_context
)
10258 == INSTANCE_METHOD_DECL
)
10260 : uucls_super_ref
),
10265 /* We have a category. */
10267 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
10270 /* Barf if super used in a category of Object. */
10273 error ("no super class declared in interface for %qE",
10274 CLASS_NAME (implementation_template
));
10275 return error_mark_node
;
10278 if (flag_next_runtime
&& !flag_zero_link
)
10280 super_class
= objc_get_class_reference (super_name
);
10281 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
10282 /* If we are in a class method, we must retrieve the
10283 _metaclass_ for the current class, pointed at by
10284 the class's "isa" pointer. The following assumes that
10285 "isa" is the first ivar in a class (which it must be). */
10287 = build_indirect_ref
10289 build_c_cast (input_location
,
10290 build_pointer_type (objc_class_type
),
10291 super_class
), RO_UNARY_STAR
);
10295 add_class_reference (super_name
);
10296 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
10297 ? objc_get_class_decl
: objc_get_meta_class_decl
);
10298 assemble_external (super_class
);
10300 = build_function_call
10305 my_build_string_pointer
10306 (IDENTIFIER_LENGTH (super_name
) + 1,
10307 IDENTIFIER_POINTER (super_name
))));
10311 = build_modify_expr (input_location
, super_expr
, NULL_TREE
,
10314 build_c_cast (input_location
,
10315 TREE_TYPE (super_expr
),
10320 super_expr_list
= build_compound_expr (input_location
,
10321 super_expr_list
, super_expr
);
10323 super_expr
= build_unary_op (input_location
,
10324 ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
10325 super_expr_list
= build_compound_expr (input_location
,
10326 super_expr_list
, super_expr
);
10328 return super_expr_list
;
10332 error ("[super ...] must appear in a method context");
10333 return error_mark_node
;
10337 /* When exiting a scope, sever links to a 'super' declaration (if any)
10338 therein contained. */
10341 objc_clear_super_receiver (void)
10343 if (objc_method_context
10344 && UOBJC_SUPER_scope
== objc_get_current_scope ()) {
10345 UOBJC_SUPER_decl
= 0;
10346 UOBJC_SUPER_scope
= 0;
10351 objc_finish_method_definition (tree fndecl
)
10353 /* We cannot validly inline ObjC methods, at least not without a language
10354 extension to declare that a method need not be dynamically
10355 dispatched, so suppress all thoughts of doing so. */
10356 DECL_UNINLINABLE (fndecl
) = 1;
10359 /* The C++ front-end will have called finish_function() for us. */
10360 finish_function ();
10363 METHOD_ENCODING (objc_method_context
)
10364 = encode_method_prototype (objc_method_context
);
10366 /* Required to implement _msgSuper. This must be done AFTER finish_function,
10367 since the optimizer may find "may be used before set" errors. */
10368 objc_method_context
= NULL_TREE
;
10370 if (should_call_super_dealloc
)
10371 warning (0, "method possibly missing a [super dealloc] call");
10374 /* Given a tree DECL node, produce a printable description of it in the given
10375 buffer, overwriting the buffer. */
10378 gen_declaration (tree decl
)
10384 gen_type_name_0 (TREE_TYPE (decl
));
10386 if (DECL_NAME (decl
))
10388 if (!POINTER_TYPE_P (TREE_TYPE (decl
)))
10389 strcat (errbuf
, " ");
10391 strcat (errbuf
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
10394 if (DECL_INITIAL (decl
)
10395 && TREE_CODE (DECL_INITIAL (decl
)) == INTEGER_CST
)
10396 sprintf (errbuf
+ strlen (errbuf
), ": " HOST_WIDE_INT_PRINT_DEC
,
10397 TREE_INT_CST_LOW (DECL_INITIAL (decl
)));
10403 /* Given a tree TYPE node, produce a printable description of it in the given
10404 buffer, overwriting the buffer. */
10407 gen_type_name_0 (tree type
)
10409 tree orig
= type
, proto
;
10411 if (TYPE_P (type
) && TYPE_NAME (type
))
10412 type
= TYPE_NAME (type
);
10413 else if (POINTER_TYPE_P (type
) || TREE_CODE (type
) == ARRAY_TYPE
)
10415 tree inner
= TREE_TYPE (type
);
10417 while (TREE_CODE (inner
) == ARRAY_TYPE
)
10418 inner
= TREE_TYPE (inner
);
10420 gen_type_name_0 (inner
);
10422 if (!POINTER_TYPE_P (inner
))
10423 strcat (errbuf
, " ");
10425 if (POINTER_TYPE_P (type
))
10426 strcat (errbuf
, "*");
10428 while (type
!= inner
)
10430 strcat (errbuf
, "[");
10432 if (TYPE_DOMAIN (type
))
10436 sprintf (sz
, HOST_WIDE_INT_PRINT_DEC
,
10438 (TYPE_MAX_VALUE (TYPE_DOMAIN (type
))) + 1));
10439 strcat (errbuf
, sz
);
10442 strcat (errbuf
, "]");
10443 type
= TREE_TYPE (type
);
10446 goto exit_function
;
10449 if (TREE_CODE (type
) == TYPE_DECL
&& DECL_NAME (type
))
10450 type
= DECL_NAME (type
);
10452 strcat (errbuf
, TREE_CODE (type
) == IDENTIFIER_NODE
10453 ? IDENTIFIER_POINTER (type
)
10456 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
10457 if (objc_is_id (orig
))
10458 orig
= TREE_TYPE (orig
);
10460 proto
= TYPE_HAS_OBJC_INFO (orig
) ? TYPE_OBJC_PROTOCOL_LIST (orig
) : NULL_TREE
;
10464 strcat (errbuf
, " <");
10468 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto
))));
10469 proto
= TREE_CHAIN (proto
);
10470 strcat (errbuf
, proto
? ", " : ">");
10479 gen_type_name (tree type
)
10483 return gen_type_name_0 (type
);
10486 /* Given a method tree, put a printable description into the given
10487 buffer (overwriting) and return a pointer to the buffer. */
10490 gen_method_decl (tree method
)
10494 strcpy (errbuf
, "("); /* NB: Do _not_ call strcat() here. */
10495 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method
)));
10496 strcat (errbuf
, ")");
10497 chain
= METHOD_SEL_ARGS (method
);
10501 /* We have a chain of keyword_decls. */
10504 if (KEYWORD_KEY_NAME (chain
))
10505 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
10507 strcat (errbuf
, ":(");
10508 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain
)));
10509 strcat (errbuf
, ")");
10511 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
10512 if ((chain
= DECL_CHAIN (chain
)))
10513 strcat (errbuf
, " ");
10517 if (METHOD_ADD_ARGS (method
))
10519 chain
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
10521 /* Know we have a chain of parm_decls. */
10524 strcat (errbuf
, ", ");
10525 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain
)));
10526 chain
= TREE_CHAIN (chain
);
10529 if (METHOD_ADD_ARGS_ELLIPSIS_P (method
))
10530 strcat (errbuf
, ", ...");
10535 /* We have a unary selector. */
10536 strcat (errbuf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
10544 /* Dump an @interface declaration of the supplied class CHAIN to the
10545 supplied file FP. Used to implement the -gen-decls option (which
10546 prints out an @interface declaration of all classes compiled in
10547 this run); potentially useful for debugging the compiler too. */
10549 dump_interface (FILE *fp
, tree chain
)
10551 /* FIXME: A heap overflow here whenever a method (or ivar)
10552 declaration is so long that it doesn't fit in the buffer. The
10553 code and all the related functions should be rewritten to avoid
10554 using fixed size buffers. */
10555 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
10556 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
10557 tree nst_methods
= CLASS_NST_METHODS (chain
);
10558 tree cls_methods
= CLASS_CLS_METHODS (chain
);
10560 fprintf (fp
, "\n@interface %s", my_name
);
10562 /* CLASS_SUPER_NAME is used to store the superclass name for
10563 classes, and the category name for categories. */
10564 if (CLASS_SUPER_NAME (chain
))
10566 const char *name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
10568 switch (TREE_CODE (chain
))
10570 case CATEGORY_IMPLEMENTATION_TYPE
:
10571 case CATEGORY_INTERFACE_TYPE
:
10572 fprintf (fp
, " (%s)\n", name
);
10575 fprintf (fp
, " : %s\n", name
);
10580 fprintf (fp
, "\n");
10582 /* FIXME - the following doesn't seem to work at the moment. */
10585 fprintf (fp
, "{\n");
10588 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
));
10589 ivar_decls
= TREE_CHAIN (ivar_decls
);
10591 while (ivar_decls
);
10592 fprintf (fp
, "}\n");
10595 while (nst_methods
)
10597 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
));
10598 nst_methods
= TREE_CHAIN (nst_methods
);
10601 while (cls_methods
)
10603 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
));
10604 cls_methods
= TREE_CHAIN (cls_methods
);
10607 fprintf (fp
, "@end\n");
10611 /* Produce the pretty printing for an Objective-C method. This is
10612 currently unused, but could be handy while reorganizing the pretty
10613 printing to be more robust. */
10614 static const char *
10615 objc_pretty_print_method (bool is_class_method
,
10616 const char *class_name
,
10617 const char *category_name
,
10618 const char *selector
)
10622 char *result
= XNEWVEC (char, strlen (class_name
) + strlen (category_name
)
10623 + strlen (selector
) + 7);
10625 if (is_class_method
)
10626 sprintf (result
, "+[%s(%s) %s]", class_name
, category_name
, selector
);
10628 sprintf (result
, "-[%s(%s) %s]", class_name
, category_name
, selector
);
10634 char *result
= XNEWVEC (char, strlen (class_name
)
10635 + strlen (selector
) + 5);
10637 if (is_class_method
)
10638 sprintf (result
, "+[%s %s]", class_name
, selector
);
10640 sprintf (result
, "-[%s %s]", class_name
, selector
);
10647 /* Demangle function for Objective-C. Attempt to demangle the
10648 function name associated with a method (eg, going from
10649 "_i_NSObject__class" to "-[NSObject class]"); usually for the
10650 purpose of pretty printing or error messages. Return the demangled
10651 name, or NULL if the string is not an Objective-C mangled method
10654 Because of how the mangling is done, any method that has a '_' in
10655 its original name is at risk of being demangled incorrectly. In
10656 some cases there are multiple valid ways to demangle a method name
10657 and there is no way we can decide.
10659 TODO: objc_demangle() can't always get it right; the right way to
10660 get this correct for all method names would be to store the
10661 Objective-C method name somewhere in the function decl. Then,
10662 there is no demangling to do; we'd just pull the method name out of
10663 the decl. As an additional bonus, when printing error messages we
10664 could check for such a method name, and if we find it, we know the
10665 function is actually an Objective-C method and we could print error
10666 messages saying "In method '+[NSObject class]" instead of "In
10667 function '+[NSObject class]" as we do now. */
10668 static const char *
10669 objc_demangle (const char *mangled
)
10671 char *demangled
, *cp
;
10673 if (mangled
[0] == '_' &&
10674 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
10677 cp
= demangled
= XNEWVEC (char, strlen(mangled
) + 2);
10678 if (mangled
[1] == 'i')
10679 *cp
++ = '-'; /* for instance method */
10681 *cp
++ = '+'; /* for class method */
10682 *cp
++ = '['; /* opening left brace */
10683 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
10684 while (*cp
&& *cp
== '_')
10685 cp
++; /* skip any initial underbars in class name */
10686 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
10689 free(demangled
); /* not mangled name */
10692 if (cp
[1] == '_') /* easy case: no category name */
10694 *cp
++ = ' '; /* replace two '_' with one ' ' */
10695 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
10699 *cp
++ = '('; /* less easy case: category name */
10700 cp
= strchr(cp
, '_');
10703 free(demangled
); /* not mangled name */
10707 *cp
++ = ' '; /* overwriting 1st char of method name... */
10708 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
10710 /* Now we have the method name. We need to generally replace
10711 '_' with ':' but trying to preserve '_' if it could only have
10712 been in the mangled string because it was already in the
10713 original name. In cases where it's ambiguous, we assume that
10714 any '_' originated from a ':'. */
10716 /* Initial '_'s in method name can't have been generating by
10717 converting ':'s. Skip them. */
10718 while (*cp
&& *cp
== '_')
10721 /* If the method name does not end with '_', then it has no
10722 arguments and there was no replacement of ':'s with '_'s
10723 during mangling. Check for that case, and skip any
10724 replacement if so. This at least guarantees that methods
10725 with no arguments are always demangled correctly (unless the
10726 original name ends with '_'). */
10727 if (*(mangled
+ strlen (mangled
) - 1) != '_')
10729 /* Skip to the end. */
10735 /* Replace remaining '_' with ':'. This may get it wrong if
10736 there were '_'s in the original name. In most cases it
10737 is impossible to disambiguate. */
10742 *cp
++ = ']'; /* closing right brace */
10743 *cp
++ = 0; /* string terminator */
10747 return NULL
; /* not an objc mangled name */
10750 /* Try to pretty-print a decl. If the 'decl' is an Objective-C
10751 specific decl, return the printable name for it. If not, return
10754 objc_maybe_printable_name (tree decl
, int v ATTRIBUTE_UNUSED
)
10756 switch (TREE_CODE (decl
))
10758 case FUNCTION_DECL
:
10759 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
10762 /* The following happens when we are printing a deprecation
10763 warning for a method. The warn_deprecation() will end up
10764 trying to print the decl for INSTANCE_METHOD_DECL or
10765 CLASS_METHOD_DECL. It would be nice to be able to print
10766 "-[NSObject autorelease] is deprecated", but to do that, we'd
10767 need to store the class and method name in the method decl,
10768 which we currently don't do. For now, just return the name
10769 of the method. We don't return NULL, because that may
10770 trigger further attempts to pretty-print the decl in C/C++,
10771 but they wouldn't know how to pretty-print it. */
10772 case INSTANCE_METHOD_DECL
:
10773 case CLASS_METHOD_DECL
:
10774 return IDENTIFIER_POINTER (DECL_NAME (decl
));
10782 /* Return a printable name for 'decl'. This first tries
10783 objc_maybe_printable_name(), and if that fails, it returns the name
10784 in the decl. This is used as LANG_HOOKS_DECL_PRINTABLE_NAME for
10785 Objective-C; in Objective-C++, setting the hook is not enough
10786 because lots of C++ Front-End code calls cxx_printable_name,
10787 dump_decl and other C++ functions directly. So instead we have
10788 modified dump_decl to call objc_maybe_printable_name directly. */
10790 objc_printable_name (tree decl
, int v
)
10792 const char *demangled_name
= objc_maybe_printable_name (decl
, v
);
10794 if (demangled_name
!= NULL
)
10795 return demangled_name
;
10797 return IDENTIFIER_POINTER (DECL_NAME (decl
));
10803 gcc_obstack_init (&util_obstack
);
10804 util_firstobj
= (char *) obstack_finish (&util_obstack
);
10806 errbuf
= XNEWVEC (char, 1024 * 10);
10808 synth_module_prologue ();
10814 struct imp_entry
*impent
;
10816 /* The internally generated initializers appear to have missing braces.
10817 Don't warn about this. */
10818 int save_warn_missing_braces
= warn_missing_braces
;
10819 warn_missing_braces
= 0;
10821 /* A missing @end may not be detected by the parser. */
10822 if (objc_implementation_context
)
10824 warning (0, "%<@end%> missing in implementation context");
10825 finish_class (objc_implementation_context
);
10826 objc_ivar_chain
= NULL_TREE
;
10827 objc_implementation_context
= NULL_TREE
;
10830 /* Process the static instances here because initialization of objc_symtab
10831 depends on them. */
10832 if (objc_static_instances
)
10833 generate_static_references ();
10835 /* forward declare categories */
10837 forward_declare_categories ();
10839 for (impent
= imp_list
; impent
; impent
= impent
->next
)
10841 objc_implementation_context
= impent
->imp_context
;
10842 implementation_template
= impent
->imp_template
;
10844 /* FIXME: This needs reworking to be more obvious. */
10846 UOBJC_CLASS_decl
= impent
->class_decl
;
10847 UOBJC_METACLASS_decl
= impent
->meta_decl
;
10849 /* Dump the @interface of each class as we compile it, if the
10850 -gen-decls option is in use. TODO: Dump the classes in the
10851 order they were found, rather than in reverse order as we
10853 if (flag_gen_declaration
)
10855 dump_interface (gen_declaration_file
, objc_implementation_context
);
10858 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
10860 /* all of the following reference the string pool... */
10861 generate_ivar_lists ();
10862 generate_dispatch_tables ();
10863 generate_shared_structures (impent
);
10867 generate_dispatch_tables ();
10868 generate_category (impent
);
10871 impent
->class_decl
= UOBJC_CLASS_decl
;
10872 impent
->meta_decl
= UOBJC_METACLASS_decl
;
10875 /* If we are using an array of selectors, we must always
10876 finish up the array decl even if no selectors were used. */
10877 if (flag_next_runtime
)
10878 build_next_selector_translation_table ();
10880 build_gnu_selector_translation_table ();
10882 if (protocol_chain
)
10883 generate_protocols ();
10885 if (flag_next_runtime
)
10886 generate_objc_image_info ();
10888 if (imp_list
|| class_names_chain
10889 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
10890 generate_objc_symtab_decl ();
10892 /* Arrange for ObjC data structures to be initialized at run time. */
10893 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
10894 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
10896 build_module_descriptor ();
10898 if (!flag_next_runtime
)
10899 build_module_initializer_routine ();
10902 /* Dump the class references. This forces the appropriate classes
10903 to be linked into the executable image, preserving unix archive
10904 semantics. This can be removed when we move to a more dynamically
10905 linked environment. */
10907 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
10909 handle_class_ref (chain
);
10910 if (TREE_PURPOSE (chain
))
10911 generate_classref_translation_entry (chain
);
10914 for (impent
= imp_list
; impent
; impent
= impent
->next
)
10915 handle_impent (impent
);
10922 /* Run through the selector hash tables and print a warning for any
10923 selector which has multiple methods. */
10925 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
10927 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
10928 check_duplicates (hsh
, 0, 1);
10929 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
10930 check_duplicates (hsh
, 0, 1);
10934 warn_missing_braces
= save_warn_missing_braces
;
10937 /* Subroutines of finish_objc. */
10940 generate_classref_translation_entry (tree chain
)
10942 tree expr
, decl
, type
;
10944 decl
= TREE_PURPOSE (chain
);
10945 type
= TREE_TYPE (decl
);
10947 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
10948 expr
= convert (type
, expr
); /* cast! */
10950 /* This is a class reference. It is re-written by the runtime,
10951 but will be optimized away unless we force it. */
10952 DECL_PRESERVE_P (decl
) = 1;
10953 finish_var_decl (decl
, expr
);
10958 handle_class_ref (tree chain
)
10960 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
10961 char *string
= (char *) alloca (strlen (name
) + 30);
10965 sprintf (string
, "%sobjc_class_name_%s",
10966 (flag_next_runtime
? "." : "__"), name
);
10968 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
10969 if (flag_next_runtime
)
10971 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
10976 /* Make a decl for this name, so we can use its address in a tree. */
10977 decl
= build_decl (input_location
,
10978 VAR_DECL
, get_identifier (string
), TREE_TYPE (integer_zero_node
));
10979 DECL_EXTERNAL (decl
) = 1;
10980 TREE_PUBLIC (decl
) = 1;
10982 finish_var_decl (decl
, 0);
10984 /* Make a decl for the address. */
10985 sprintf (string
, "%sobjc_class_ref_%s",
10986 (flag_next_runtime
? "." : "__"), name
);
10987 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
10988 decl
= build_decl (input_location
,
10989 VAR_DECL
, get_identifier (string
), string_type_node
);
10990 TREE_STATIC (decl
) = 1;
10991 TREE_USED (decl
) = 1;
10992 DECL_READ_P (decl
) = 1;
10993 DECL_ARTIFICIAL (decl
) = 1;
10994 DECL_INITIAL (decl
) = error_mark_node
;
10996 /* We must force the reference. */
10997 DECL_PRESERVE_P (decl
) = 1;
11000 finish_var_decl (decl
, exp
);
11004 handle_impent (struct imp_entry
*impent
)
11008 objc_implementation_context
= impent
->imp_context
;
11009 implementation_template
= impent
->imp_template
;
11011 switch (TREE_CODE (impent
->imp_context
))
11013 case CLASS_IMPLEMENTATION_TYPE
:
11015 const char *const class_name
=
11016 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
11018 string
= (char *) alloca (strlen (class_name
) + 30);
11020 sprintf (string
, "%sobjc_class_name_%s",
11021 (flag_next_runtime
? "." : "__"), class_name
);
11024 case CATEGORY_IMPLEMENTATION_TYPE
:
11026 const char *const class_name
=
11027 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
11028 const char *const class_super_name
=
11029 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
11031 string
= (char *) alloca (strlen (class_name
)
11032 + strlen (class_super_name
) + 30);
11034 /* Do the same for categories. Even though no references to
11035 these symbols are generated automatically by the compiler,
11036 it gives you a handle to pull them into an archive by
11038 sprintf (string
, "*%sobjc_category_name_%s_%s",
11039 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
11046 #ifdef ASM_DECLARE_CLASS_REFERENCE
11047 if (flag_next_runtime
)
11049 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
11057 init
= integer_zero_node
;
11058 decl
= build_decl (input_location
,
11059 VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
11060 TREE_PUBLIC (decl
) = 1;
11061 TREE_READONLY (decl
) = 1;
11062 TREE_USED (decl
) = 1;
11063 TREE_CONSTANT (decl
) = 1;
11064 DECL_CONTEXT (decl
) = NULL_TREE
;
11065 DECL_ARTIFICIAL (decl
) = 1;
11066 TREE_STATIC (decl
) = 1;
11067 DECL_INITIAL (decl
) = error_mark_node
; /* A real initializer is coming... */
11068 /* We must force the reference. */
11069 DECL_PRESERVE_P (decl
) = 1;
11071 finish_var_decl(decl
, init
) ;
11075 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
11076 later requires that ObjC translation units participating in F&C be
11077 specially marked. The following routine accomplishes this. */
11079 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
11082 generate_objc_image_info (void)
11086 = ((flag_replace_objc_classes
&& imp_count
? 1 : 0)
11087 | (flag_objc_gc
? 2 : 0));
11088 VEC(constructor_elt
,gc
) *v
= NULL
;
11092 return; /* No need for an image_info entry. */
11094 array_type
= build_sized_array_type (integer_type_node
, 2);
11096 decl
= start_var_decl (array_type
, "_OBJC_IMAGE_INFO");
11098 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
11099 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (integer_type_node
, flags
));
11100 /* If we need this (determined above) it is because the runtime wants to
11101 refer to it in a manner hidden from the compiler. So we must force the
11103 DECL_PRESERVE_P (decl
) = 1;
11104 finish_var_decl (decl
, objc_build_constructor (TREE_TYPE (decl
), v
));
11107 /* Routine is called to issue diagnostic when reference to a private
11108 ivar is made and no other variable with same name is found in
11111 objc_diagnose_private_ivar (tree id
)
11114 if (!objc_method_context
)
11116 ivar
= is_ivar (objc_ivar_chain
, id
);
11117 if (ivar
&& is_private (ivar
))
11119 error ("instance variable %qs is declared private",
11120 IDENTIFIER_POINTER (id
));
11126 /* Look up ID as an instance variable. OTHER contains the result of
11127 the C or C++ lookup, which we may want to use instead. */
11128 /* Also handle use of property as setter/getter. */
11130 objc_lookup_ivar (tree other
, tree id
)
11132 tree ivar
, property
;
11134 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
11135 if (!objc_method_context
)
11138 if (!strcmp (IDENTIFIER_POINTER (id
), "super"))
11139 /* We have a message to super. */
11140 return get_super_receiver ();
11142 /* In a class method, look up an instance variable only as a last
11144 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
11145 && other
&& other
!= error_mark_node
)
11148 property
= NULL_TREE
;
11149 if (objc_implementation_context
)
11150 property
= is_property (objc_implementation_context
, id
);
11154 /* Look up the ivar, but do not use it if it is not accessible. */
11155 ivar
= is_ivar (objc_ivar_chain
, id
);
11157 if (!ivar
|| is_private (ivar
))
11161 /* In an instance method, a local variable (or parameter) may hide the
11162 instance variable. */
11163 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
11164 && other
&& other
!= error_mark_node
11166 && CP_DECL_CONTEXT (other
) != global_namespace
)
11168 && !DECL_FILE_SCOPE_P (other
))
11172 warning (0, "local declaration of %qE hides property", id
);
11174 warning (0, "local declaration of %qE hides instance variable", id
);
11180 return build_property_reference (property
, id
);
11182 /* At this point, we are either in an instance method with no obscuring
11183 local definitions, or in a class method with no alternate definitions
11185 return build_ivar_reference (id
);
11188 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
11189 needs to be done if we are calling a function through a cast. */
11192 objc_rewrite_function_call (tree function
, tree first_param
)
11194 if (TREE_CODE (function
) == NOP_EXPR
11195 && TREE_CODE (TREE_OPERAND (function
, 0)) == ADDR_EXPR
11196 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function
, 0), 0))
11199 function
= build3 (OBJ_TYPE_REF
, TREE_TYPE (function
),
11200 TREE_OPERAND (function
, 0),
11201 first_param
, size_zero_node
);
11207 /* Look for the special case of OBJC_TYPE_REF with the address of
11208 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
11209 of its cousins). */
11212 objc_gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
11214 enum gimplify_status r0
, r1
;
11215 if (TREE_CODE (*expr_p
) == OBJ_TYPE_REF
11216 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p
)) == ADDR_EXPR
11217 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p
), 0))
11220 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
11221 value of the OBJ_TYPE_REF, so force them to be emitted
11222 during subexpression evaluation rather than after the
11223 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
11224 C to use direct rather than indirect calls when the
11225 object expression has a postincrement. */
11226 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
, NULL
,
11227 is_gimple_val
, fb_rvalue
);
11228 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
, post_p
,
11229 is_gimple_val
, fb_rvalue
);
11231 return MIN (r0
, r1
);
11235 return (enum gimplify_status
) cp_gimplify_expr (expr_p
, pre_p
, post_p
);
11237 return (enum gimplify_status
) c_gimplify_expr (expr_p
, pre_p
, post_p
);
11241 /* This routine returns true if TYP is a valid objc object type,
11242 suitable for messaging; false otherwise.
11246 objc_type_valid_for_messaging (tree typ
)
11248 if (!POINTER_TYPE_P (typ
))
11252 typ
= TREE_TYPE (typ
); /* Remove indirections. */
11253 while (POINTER_TYPE_P (typ
));
11255 if (TREE_CODE (typ
) != RECORD_TYPE
)
11258 return objc_is_object_id (typ
) || TYPE_HAS_OBJC_INFO (typ
);
11261 /* Begin code generation for fast enumeration (foreach) ... */
11265 struct __objcFastEnumerationState
11267 unsigned long state;
11269 unsigned long *mutationsPtr;
11270 unsigned long extra[5];
11273 Confusingly enough, NSFastEnumeration is then defined by libraries
11274 to be the same structure.
11278 build_fast_enumeration_state_template (void)
11280 tree decls
, *chain
= NULL
;
11283 objc_fast_enumeration_state_template
= objc_start_struct (get_identifier
11284 (TAG_FAST_ENUMERATION_STATE
));
11286 /* unsigned long state; */
11287 decls
= add_field_decl (long_unsigned_type_node
, "state", &chain
);
11289 /* id *itemsPtr; */
11290 add_field_decl (build_pointer_type (objc_object_type
),
11291 "itemsPtr", &chain
);
11293 /* unsigned long *mutationsPtr; */
11294 add_field_decl (build_pointer_type (long_unsigned_type_node
),
11295 "mutationsPtr", &chain
);
11297 /* unsigned long extra[5]; */
11298 add_field_decl (build_sized_array_type (long_unsigned_type_node
, 5),
11302 objc_finish_struct (objc_fast_enumeration_state_template
, decls
);
11306 'objc_finish_foreach_loop()' generates the code for an Objective-C
11307 foreach loop. The 'location' argument is the location of the 'for'
11308 that starts the loop. The 'object_expression' is the expression of
11309 the 'object' that iterates; the 'collection_expression' is the
11310 expression of the collection that we iterate over (we need to make
11311 sure we evaluate this only once); the 'for_body' is the set of
11312 statements to be executed in each iteration; 'break_label' and
11313 'continue_label' are the break and continue labels which we need to
11314 emit since the <statements> may be jumping to 'break_label' (if they
11315 contain 'break') or to 'continue_label' (if they contain
11320 for (<object expression> in <collection expression>)
11323 which is compiled into the following blurb:
11326 id __objc_foreach_collection;
11327 __objc_fast_enumeration_state __objc_foreach_enum_state;
11328 unsigned long __objc_foreach_batchsize;
11329 id __objc_foreach_items[16];
11330 __objc_foreach_collection = <collection expression>;
11331 __objc_foreach_enum_state = { 0 };
11332 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
11334 if (__objc_foreach_batchsize == 0)
11335 <object expression> = nil;
11338 unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
11341 unsigned long __objc_foreach_index;
11342 __objc_foreach_index = 0;
11345 if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
11346 <object expression> = enumState.itemsPtr[__objc_foreach_index];
11347 <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
11350 __objc_foreach_index++;
11351 if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
11352 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
11354 if (__objc_foreach_batchsize != 0) goto next_batch;
11355 <object expression> = nil;
11360 'statements' may contain a 'continue' or 'break' instruction, which
11361 the user expects to 'continue' or 'break' the entire foreach loop.
11362 We are provided the labels that 'break' and 'continue' jump to, so
11363 we place them where we want them to jump to when they pick them.
11365 Optimization TODO: we could cache the IMP of
11366 countByEnumeratingWithState:objects:count:.
11369 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line. */
11370 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
11372 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
11373 #include "tree-pretty-print.h"
11377 objc_finish_foreach_loop (location_t location
, tree object_expression
, tree collection_expression
, tree for_body
,
11378 tree break_label
, tree continue_label
)
11380 /* A tree representing the __objcFastEnumerationState struct type,
11381 or NSFastEnumerationState struct, whatever we are using. */
11382 tree objc_fast_enumeration_state_type
;
11384 /* The trees representing the declarations of each of the local variables. */
11385 tree objc_foreach_collection_decl
;
11386 tree objc_foreach_enum_state_decl
;
11387 tree objc_foreach_items_decl
;
11388 tree objc_foreach_batchsize_decl
;
11389 tree objc_foreach_mutations_pointer_decl
;
11390 tree objc_foreach_index_decl
;
11392 /* A tree representing the selector countByEnumeratingWithState:objects:count:. */
11393 tree selector_name
;
11395 /* A tree representing the local bind. */
11398 /* A tree representing the external 'if (__objc_foreach_batchsize)' */
11401 /* A tree representing the 'else' part of 'first_if' */
11404 /* A tree representing the 'next_batch' label. */
11405 tree next_batch_label_decl
;
11407 /* A tree representing the binding after the 'next_batch' label. */
11408 tree next_batch_bind
;
11410 /* A tree representing the 'next_object' label. */
11411 tree next_object_label_decl
;
11413 /* Temporary variables. */
11417 if (object_expression
== error_mark_node
)
11420 if (collection_expression
== error_mark_node
)
11423 if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression
)))
11425 error ("iterating variable in fast enumeration is not an object");
11429 if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression
)))
11431 error ("collection in fast enumeration is not an object");
11435 /* TODO: Check that object_expression is either a variable
11436 declaration, or an lvalue. */
11438 /* This kludge is an idea from apple. We use the
11439 __objcFastEnumerationState struct implicitly defined by the
11440 compiler, unless a NSFastEnumerationState struct has been defined
11441 (by a Foundation library such as GNUstep Base) in which case, we
11444 objc_fast_enumeration_state_type
= objc_fast_enumeration_state_template
;
11446 tree objc_NSFastEnumeration_type
= lookup_name (get_identifier ("NSFastEnumerationState"));
11448 if (objc_NSFastEnumeration_type
)
11450 /* TODO: We really need to check that
11451 objc_NSFastEnumeration_type is the same as ours! */
11452 if (TREE_CODE (objc_NSFastEnumeration_type
) == TYPE_DECL
)
11454 /* If it's a typedef, use the original type. */
11455 if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type
))
11456 objc_fast_enumeration_state_type
= DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type
);
11458 objc_fast_enumeration_state_type
= TREE_TYPE (objc_NSFastEnumeration_type
);
11464 /* Done by c-parser.c. */
11467 /* Done by c-parser.c. */
11469 /* id __objc_foreach_collection */
11470 objc_foreach_collection_decl
= objc_create_temporary_var (objc_object_type
, "__objc_foreach_collection");
11472 /* __objcFastEnumerationState __objc_foreach_enum_state; */
11473 objc_foreach_enum_state_decl
= objc_create_temporary_var (objc_fast_enumeration_state_type
, "__objc_foreach_enum_state");
11474 TREE_CHAIN (objc_foreach_enum_state_decl
) = objc_foreach_collection_decl
;
11476 /* id __objc_foreach_items[16]; */
11477 objc_foreach_items_decl
= objc_create_temporary_var (build_sized_array_type (objc_object_type
, 16), "__objc_foreach_items");
11478 TREE_CHAIN (objc_foreach_items_decl
) = objc_foreach_enum_state_decl
;
11480 /* unsigned long __objc_foreach_batchsize; */
11481 objc_foreach_batchsize_decl
= objc_create_temporary_var (long_unsigned_type_node
, "__objc_foreach_batchsize");
11482 TREE_CHAIN (objc_foreach_batchsize_decl
) = objc_foreach_items_decl
;
11484 /* Generate the local variable binding. */
11485 bind
= build3 (BIND_EXPR
, void_type_node
, objc_foreach_batchsize_decl
, NULL
, NULL
);
11486 SET_EXPR_LOCATION (bind
, location
);
11487 TREE_SIDE_EFFECTS (bind
) = 1;
11489 /* __objc_foreach_collection = <collection expression>; */
11490 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_collection_decl
, collection_expression
);
11491 SET_EXPR_LOCATION (t
, location
);
11492 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11494 /* __objc_foreach_enum_state.state = 0; */
11495 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11496 get_identifier ("state")),
11497 build_int_cst (long_unsigned_type_node
, 0));
11498 SET_EXPR_LOCATION (t
, location
);
11499 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11501 /* __objc_foreach_enum_state.itemsPtr = NULL; */
11502 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11503 get_identifier ("itemsPtr")),
11504 null_pointer_node
);
11505 SET_EXPR_LOCATION (t
, location
);
11506 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11508 /* __objc_foreach_enum_state.mutationsPtr = NULL; */
11509 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11510 get_identifier ("mutationsPtr")),
11511 null_pointer_node
);
11512 SET_EXPR_LOCATION (t
, location
);
11513 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11515 /* __objc_foreach_enum_state.extra[0] = 0; */
11516 /* __objc_foreach_enum_state.extra[1] = 0; */
11517 /* __objc_foreach_enum_state.extra[2] = 0; */
11518 /* __objc_foreach_enum_state.extra[3] = 0; */
11519 /* __objc_foreach_enum_state.extra[4] = 0; */
11520 for (i
= 0; i
< 5 ; i
++)
11522 t
= build2 (MODIFY_EXPR
, void_type_node
,
11523 build_array_ref (location
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11524 get_identifier ("extra")),
11525 build_int_cst (NULL_TREE
, i
)),
11526 build_int_cst (long_unsigned_type_node
, 0));
11527 SET_EXPR_LOCATION (t
, location
);
11528 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11531 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
11532 selector_name
= get_identifier ("countByEnumeratingWithState:objects:count:");
11534 t
= objc_finish_message_expr (objc_foreach_collection_decl
, selector_name
,
11536 tree_cons
/* &__objc_foreach_enum_state */
11537 (NULL_TREE
, build_fold_addr_expr_loc (location
, objc_foreach_enum_state_decl
),
11538 tree_cons
/* __objc_foreach_items */
11539 (NULL_TREE
, objc_foreach_items_decl
,
11541 (NULL_TREE
, build_int_cst (NULL_TREE
, 16), NULL_TREE
))));
11543 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
11545 struct c_expr array
;
11546 array
.value
= objc_foreach_items_decl
;
11547 t
= objc_finish_message_expr (objc_foreach_collection_decl
, selector_name
,
11549 tree_cons
/* &__objc_foreach_enum_state */
11550 (NULL_TREE
, build_fold_addr_expr_loc (location
, objc_foreach_enum_state_decl
),
11551 tree_cons
/* __objc_foreach_items */
11552 (NULL_TREE
, default_function_array_conversion (location
, array
).value
,
11554 (NULL_TREE
, build_int_cst (NULL_TREE
, 16), NULL_TREE
))));
11557 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_batchsize_decl
,
11558 convert (long_unsigned_type_node
, t
));
11559 SET_EXPR_LOCATION (t
, location
);
11560 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11562 /* if (__objc_foreach_batchsize == 0) */
11563 first_if
= build3 (COND_EXPR
, void_type_node
,
11566 (c_common_truthvalue_conversion
11568 build_binary_op (location
,
11570 objc_foreach_batchsize_decl
,
11571 build_int_cst (long_unsigned_type_node
, 0), 1)),
11573 /* Then block (we fill it in later). */
11575 /* Else block (we fill it in later). */
11577 SET_EXPR_LOCATION (first_if
, location
);
11578 append_to_statement_list (first_if
, &BIND_EXPR_BODY (bind
));
11580 /* then <object expression> = nil; */
11581 t
= build2 (MODIFY_EXPR
, void_type_node
, object_expression
, convert (objc_object_type
, null_pointer_node
));
11582 SET_EXPR_LOCATION (t
, location
);
11583 COND_EXPR_THEN (first_if
) = t
;
11585 /* Now we build the 'else' part of the if; once we finish building
11586 it, we attach it to first_if as the 'else' part. */
11591 /* unsigned long __objc_foreach_mutations_pointer; */
11592 objc_foreach_mutations_pointer_decl
= objc_create_temporary_var (long_unsigned_type_node
, "__objc_foreach_mutations_pointer");
11594 /* Generate the local variable binding. */
11595 first_else
= build3 (BIND_EXPR
, void_type_node
, objc_foreach_mutations_pointer_decl
, NULL
, NULL
);
11596 SET_EXPR_LOCATION (first_else
, location
);
11597 TREE_SIDE_EFFECTS (first_else
) = 1;
11599 /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
11600 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_mutations_pointer_decl
,
11601 build_indirect_ref (location
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11602 get_identifier ("mutationsPtr")),
11604 SET_EXPR_LOCATION (t
, location
);
11605 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11608 next_batch_label_decl
= create_artificial_label (location
);
11609 t
= build1 (LABEL_EXPR
, void_type_node
, next_batch_label_decl
);
11610 SET_EXPR_LOCATION (t
, location
);
11611 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11615 /* unsigned long __objc_foreach_index; */
11616 objc_foreach_index_decl
= objc_create_temporary_var (long_unsigned_type_node
, "__objc_foreach_index");
11618 /* Generate the local variable binding. */
11619 next_batch_bind
= build3 (BIND_EXPR
, void_type_node
, objc_foreach_index_decl
, NULL
, NULL
);
11620 SET_EXPR_LOCATION (next_batch_bind
, location
);
11621 TREE_SIDE_EFFECTS (next_batch_bind
) = 1;
11622 append_to_statement_list (next_batch_bind
, &BIND_EXPR_BODY (first_else
));
11624 /* __objc_foreach_index = 0; */
11625 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_index_decl
,
11626 build_int_cst (long_unsigned_type_node
, 0));
11627 SET_EXPR_LOCATION (t
, location
);
11628 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11631 next_object_label_decl
= create_artificial_label (location
);
11632 t
= build1 (LABEL_EXPR
, void_type_node
, next_object_label_decl
);
11633 SET_EXPR_LOCATION (t
, location
);
11634 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11636 /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
11637 t
= build3 (COND_EXPR
, void_type_node
,
11640 (c_common_truthvalue_conversion
11645 objc_foreach_mutations_pointer_decl
,
11646 build_indirect_ref (location
,
11647 objc_build_component_ref (objc_foreach_enum_state_decl
,
11648 get_identifier ("mutationsPtr")),
11649 RO_UNARY_STAR
), 1)),
11652 build_function_call (input_location
,
11653 objc_enumeration_mutation_decl
,
11654 tree_cons (NULL
, collection_expression
, NULL
)),
11657 SET_EXPR_LOCATION (t
, location
);
11658 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11660 /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
11661 t
= build2 (MODIFY_EXPR
, void_type_node
, object_expression
,
11662 build_array_ref (location
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11663 get_identifier ("itemsPtr")),
11664 objc_foreach_index_decl
));
11665 SET_EXPR_LOCATION (t
, location
);
11666 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11668 /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
11669 append_to_statement_list (for_body
, &BIND_EXPR_BODY (next_batch_bind
));
11671 /* continue_label: */
11672 if (continue_label
)
11674 t
= build1 (LABEL_EXPR
, void_type_node
, continue_label
);
11675 SET_EXPR_LOCATION (t
, location
);
11676 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11679 /* __objc_foreach_index++; */
11680 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_index_decl
,
11681 build_binary_op (location
,
11683 objc_foreach_index_decl
,
11684 build_int_cst (long_unsigned_type_node
, 1), 1));
11685 SET_EXPR_LOCATION (t
, location
);
11686 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11688 /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
11689 t
= build3 (COND_EXPR
, void_type_node
,
11692 (c_common_truthvalue_conversion
11694 build_binary_op (location
,
11696 objc_foreach_index_decl
,
11697 objc_foreach_batchsize_decl
, 1)),
11700 build1 (GOTO_EXPR
, void_type_node
, next_object_label_decl
),
11703 SET_EXPR_LOCATION (t
, location
);
11704 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11706 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
11708 t
= objc_finish_message_expr (objc_foreach_collection_decl
, selector_name
,
11710 tree_cons
/* &__objc_foreach_enum_state */
11711 (NULL_TREE
, build_fold_addr_expr_loc (location
, objc_foreach_enum_state_decl
),
11712 tree_cons
/* __objc_foreach_items */
11713 (NULL_TREE
, objc_foreach_items_decl
,
11715 (NULL_TREE
, build_int_cst (NULL_TREE
, 16), NULL_TREE
))));
11717 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
11719 struct c_expr array
;
11720 array
.value
= objc_foreach_items_decl
;
11721 t
= objc_finish_message_expr (objc_foreach_collection_decl
, selector_name
,
11723 tree_cons
/* &__objc_foreach_enum_state */
11724 (NULL_TREE
, build_fold_addr_expr_loc (location
, objc_foreach_enum_state_decl
),
11725 tree_cons
/* __objc_foreach_items */
11726 (NULL_TREE
, default_function_array_conversion (location
, array
).value
,
11728 (NULL_TREE
, build_int_cst (NULL_TREE
, 16), NULL_TREE
))));
11731 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_batchsize_decl
,
11732 convert (long_unsigned_type_node
, t
));
11733 SET_EXPR_LOCATION (t
, location
);
11734 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11738 /* if (__objc_foreach_batchsize != 0) goto next_batch; */
11739 t
= build3 (COND_EXPR
, void_type_node
,
11742 (c_common_truthvalue_conversion
11744 build_binary_op (location
,
11746 objc_foreach_batchsize_decl
,
11747 build_int_cst (long_unsigned_type_node
, 0), 1)),
11750 build1 (GOTO_EXPR
, void_type_node
, next_batch_label_decl
),
11753 SET_EXPR_LOCATION (t
, location
);
11754 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11756 /* <object expression> = nil; */
11757 t
= build2 (MODIFY_EXPR
, void_type_node
, object_expression
, convert (objc_object_type
, null_pointer_node
));
11758 SET_EXPR_LOCATION (t
, location
);
11759 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11764 t
= build1 (LABEL_EXPR
, void_type_node
, break_label
);
11765 SET_EXPR_LOCATION (t
, location
);
11766 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11770 COND_EXPR_ELSE (first_if
) = first_else
;
11772 /* Do the whole thing. */
11775 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
11776 /* This will print to stderr the whole blurb generated by the
11777 compiler while compiling (assuming the compiler doesn't crash
11778 before getting here).
11780 debug_generic_stmt (bind
);
11784 /* Done by c-parser.c */
11787 #include "gt-objc-objc-act.h"