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 in_objc_property_setter_name_context
= false;
411 static int objc_collecting_ivars
= 0;
415 static char *errbuf
; /* Buffer for error diagnostics */
417 /* Data imported from tree.c. */
419 extern enum debug_info_type write_symbols
;
421 /* Data imported from toplev.c. */
423 extern const char *dump_base_name
;
425 static int flag_typed_selectors
;
427 /* Store all constructed constant strings in a hash table so that
428 they get uniqued properly. */
430 struct GTY(()) string_descriptor
{
431 /* The literal argument . */
434 /* The resulting constant string. */
438 static GTY((param_is (struct string_descriptor
))) htab_t string_htab
;
440 FILE *gen_declaration_file
;
442 /* Tells "encode_pointer/encode_aggregate" whether we are generating
443 type descriptors for instance variables (as opposed to methods).
444 Type descriptors for instance variables contain more information
445 than methods (for static typing and embedded structures). */
447 static int generating_instance_variables
= 0;
449 /* For building an objc struct. These may not be used when this file
450 is compiled as part of obj-c++. */
452 static bool objc_building_struct
;
453 static struct c_struct_parse_info
*objc_struct_info ATTRIBUTE_UNUSED
;
455 /* Start building a struct for objc. */
458 objc_start_struct (tree name
)
460 gcc_assert (!objc_building_struct
);
461 objc_building_struct
= true;
462 return start_struct (input_location
, RECORD_TYPE
, name
, &objc_struct_info
);
465 /* Finish building a struct for objc. */
468 objc_finish_struct (tree type
, tree fieldlist
)
470 gcc_assert (objc_building_struct
);
471 objc_building_struct
= false;
472 return finish_struct (input_location
, type
, fieldlist
, NULL_TREE
,
477 build_sized_array_type (tree base_type
, int size
)
479 tree index_type
= build_index_type (build_int_cst (NULL_TREE
, size
- 1));
480 return build_array_type (base_type
, index_type
);
484 add_field_decl (tree type
, const char *name
, tree
**chain
)
486 tree field
= create_field_decl (type
, name
);
490 *chain
= &DECL_CHAIN (field
);
495 /* Some platforms pass small structures through registers versus
496 through an invisible pointer. Determine at what size structure is
497 the transition point between the two possibilities. */
500 generate_struct_by_value_array (void)
505 int aggregate_in_mem
[32];
508 /* Presumably no platform passes 32 byte structures in a register. */
509 for (i
= 1; i
< 32; i
++)
514 /* Create an unnamed struct that has `i' character components */
515 type
= objc_start_struct (NULL_TREE
);
517 strcpy (buffer
, "c1");
518 decls
= add_field_decl (char_type_node
, buffer
, &chain
);
520 for (j
= 1; j
< i
; j
++)
522 sprintf (buffer
, "c%d", j
+ 1);
523 add_field_decl (char_type_node
, buffer
, &chain
);
525 objc_finish_struct (type
, decls
);
527 aggregate_in_mem
[i
] = aggregate_value_p (type
, 0);
528 if (!aggregate_in_mem
[i
])
532 /* We found some structures that are returned in registers instead of memory
533 so output the necessary data. */
536 for (i
= 31; i
>= 0; i
--)
537 if (!aggregate_in_mem
[i
])
539 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
541 /* The first member of the structure is always 0 because we don't handle
542 structures with 0 members */
543 printf ("static int struct_forward_array[] = {\n 0");
545 for (j
= 1; j
<= i
; j
++)
546 printf (", %d", aggregate_in_mem
[j
]);
557 if (cxx_init () == false)
559 if (c_objc_common_init () == false)
563 /* If gen_declaration desired, open the output file. */
564 if (flag_gen_declaration
)
566 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
567 gen_declaration_file
= fopen (dumpname
, "w");
568 if (gen_declaration_file
== 0)
569 fatal_error ("can't open %s: %m", dumpname
);
573 if (flag_next_runtime
)
575 TAG_GETCLASS
= "objc_getClass";
576 TAG_GETMETACLASS
= "objc_getMetaClass";
577 TAG_MSGSEND
= "objc_msgSend";
578 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
579 TAG_MSGSEND_STRET
= "objc_msgSend_stret";
580 TAG_MSGSENDSUPER_STRET
= "objc_msgSendSuper_stret";
581 default_constant_string_class_name
= "NSConstantString";
585 TAG_GETCLASS
= "objc_get_class";
586 TAG_GETMETACLASS
= "objc_get_meta_class";
587 TAG_MSGSEND
= "objc_msg_lookup";
588 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
589 /* GNU runtime does not provide special functions to support
590 structure-returning methods. */
591 default_constant_string_class_name
= "NXConstantString";
592 flag_typed_selectors
= 1;
593 /* GNU runtime does not need the compiler to change code
594 in order to do GC. */
597 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
604 if (print_struct_values
&& !flag_compare_debug
)
605 generate_struct_by_value_array ();
610 /* This is called automatically (at the very end of compilation) by
611 c_write_global_declarations and cp_write_global_declarations. */
613 objc_write_global_declarations (void)
615 mark_referenced_methods ();
617 /* Finalize Objective-C runtime data. */
620 if (gen_declaration_file
)
621 fclose (gen_declaration_file
);
624 /* Return the first occurrence of a method declaration corresponding
625 to sel_name in rproto_list. Search rproto_list recursively.
626 If is_class is 0, search for instance methods, otherwise for class
629 lookup_method_in_protocol_list (tree rproto_list
, tree sel_name
,
635 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
637 p
= TREE_VALUE (rproto
);
639 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
641 if ((fnd
= lookup_method (is_class
642 ? PROTOCOL_CLS_METHODS (p
)
643 : PROTOCOL_NST_METHODS (p
), sel_name
)))
645 else if (PROTOCOL_LIST (p
))
646 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
651 ; /* An identifier...if we could not find a protocol. */
662 lookup_protocol_in_reflist (tree rproto_list
, tree lproto
)
666 /* Make sure the protocol is supported by the object on the rhs. */
667 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
670 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
672 p
= TREE_VALUE (rproto
);
674 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
679 else if (PROTOCOL_LIST (p
))
680 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
689 ; /* An identifier...if we could not find a protocol. */
696 objc_start_class_interface (tree klass
, tree super_class
,
697 tree protos
, tree attributes
)
700 warning_at (input_location
, OPT_Wattributes
,
701 "class attributes are not available in this version"
702 " of the compiler, (ignored)");
703 objc_interface_context
705 = start_class (CLASS_INTERFACE_TYPE
, klass
, super_class
, protos
);
706 objc_ivar_visibility
= OBJC_IVAR_VIS_PROTECTED
;
710 objc_start_category_interface (tree klass
, tree categ
,
711 tree protos
, tree attributes
)
714 warning_at (input_location
, OPT_Wattributes
,
715 "category attributes are not available in this version"
716 " of the compiler, (ignored)");
717 objc_interface_context
718 = start_class (CATEGORY_INTERFACE_TYPE
, klass
, categ
, protos
);
720 = continue_class (objc_interface_context
);
724 objc_start_protocol (tree name
, tree protos
, tree attributes
)
727 warning_at (input_location
, OPT_Wattributes
,
728 "protocol attributes are not available in this version"
729 " of the compiler, (ignored)");
730 objc_interface_context
731 = start_protocol (PROTOCOL_INTERFACE_TYPE
, name
, protos
);
732 objc_method_optional_flag
= false;
736 objc_continue_interface (void)
739 = continue_class (objc_interface_context
);
743 objc_finish_interface (void)
745 finish_class (objc_interface_context
);
746 objc_interface_context
= NULL_TREE
;
747 objc_method_optional_flag
= false;
751 objc_start_class_implementation (tree klass
, tree super_class
)
753 objc_implementation_context
755 = start_class (CLASS_IMPLEMENTATION_TYPE
, klass
, super_class
, NULL_TREE
);
756 objc_ivar_visibility
= OBJC_IVAR_VIS_PROTECTED
;
760 objc_start_category_implementation (tree klass
, tree categ
)
762 objc_implementation_context
763 = start_class (CATEGORY_IMPLEMENTATION_TYPE
, klass
, categ
, NULL_TREE
);
765 = continue_class (objc_implementation_context
);
769 objc_continue_implementation (void)
772 = continue_class (objc_implementation_context
);
776 objc_finish_implementation (void)
779 if (flag_objc_call_cxx_cdtors
)
780 objc_generate_cxx_cdtors ();
783 if (objc_implementation_context
)
785 finish_class (objc_implementation_context
);
786 objc_ivar_chain
= NULL_TREE
;
787 objc_implementation_context
= NULL_TREE
;
790 warning (0, "%<@end%> must appear in an @implementation context");
794 objc_set_visibility (objc_ivar_visibility_kind visibility
)
796 if (visibility
== OBJC_IVAR_VIS_PACKAGE
)
797 warning (0, "%<@package%> presently has the same effect as %<@public%>");
798 objc_ivar_visibility
= visibility
;
802 objc_set_method_opt (bool optional
)
804 objc_method_optional_flag
= optional
;
805 if (!objc_interface_context
806 || TREE_CODE (objc_interface_context
) != PROTOCOL_INTERFACE_TYPE
)
808 error ("@optional/@required is allowed in @protocol context only.");
809 objc_method_optional_flag
= false;
813 /* This routine is called by the parser when a
814 @property... declaration is found. 'decl' is the declaration of
815 the property (type/identifier), and the other arguments represent
816 property attributes that may have been specified in the Objective-C
817 declaration. 'parsed_property_readonly' is 'true' if the attribute
818 'readonly' was specified, and 'false' if not; similarly for the
819 other bool parameters. 'parsed_property_getter_ident' is NULL_TREE
820 if the attribute 'getter' was not specified, and is the identifier
821 corresponding to the specified getter if it was; similarly for
822 'parsed_property_setter_ident'. */
824 objc_add_property_declaration (location_t location
, tree decl
,
825 bool parsed_property_readonly
, bool parsed_property_readwrite
,
826 bool parsed_property_assign
, bool parsed_property_retain
,
827 bool parsed_property_copy
, bool parsed_property_nonatomic
,
828 tree parsed_property_getter_ident
, tree parsed_property_setter_ident
,
829 /* The following two will be removed. */
830 bool parsed_property_copies
, tree parsed_property_ivar_ident
)
834 tree interface
= NULL_TREE
;
835 /* 'property_readonly' is the final readonly/rewrite attribute of
836 the property declaration after all things have been
838 bool property_readonly
= false;
839 enum objc_property_assign_semantics property_assign_semantics
= OBJC_PROPERTY_ASSIGN
;
840 /* The following will be removed once @synthesize is implemented. */
841 bool property_copies
= false;
843 if (parsed_property_readonly
&& parsed_property_readwrite
)
845 error_at (location
, "%<readonly%> attribute conflicts with %<readwrite%> attribute");
846 /* In case of conflicting attributes (here and below), after
847 producing an error, we pick one of the attributes and keep
849 property_readonly
= false;
853 if (parsed_property_readonly
)
854 property_readonly
= true;
856 if (parsed_property_readwrite
)
857 property_readonly
= false;
860 if (parsed_property_readonly
&& parsed_property_setter_ident
)
862 /* Maybe this should be an error ? */
863 warning_at (location
, 0, "%<readonly%> attribute conflicts with %<setter%> attribute");
864 parsed_property_readonly
= false;
867 if (parsed_property_assign
&& parsed_property_retain
)
869 error_at (location
, "%<assign%> attribute conflicts with %<retain%> attribute");
870 property_assign_semantics
= OBJC_PROPERTY_RETAIN
;
872 else if (parsed_property_assign
&& parsed_property_copy
)
874 error_at (location
, "%<assign%> attribute conflicts with %<copy%> attribute");
875 property_assign_semantics
= OBJC_PROPERTY_COPY
;
877 else if (parsed_property_retain
&& parsed_property_copy
)
879 error_at (location
, "%<retain%> attribute conflicts with %<copy%> attribute");
880 property_assign_semantics
= OBJC_PROPERTY_COPY
;
884 if (parsed_property_assign
)
885 property_assign_semantics
= OBJC_PROPERTY_ASSIGN
;
887 if (parsed_property_retain
)
888 property_assign_semantics
= OBJC_PROPERTY_RETAIN
;
890 if (parsed_property_copy
)
891 property_assign_semantics
= OBJC_PROPERTY_COPY
;
894 /* This will be removed when @synthesize is implemented. */
895 if (parsed_property_copies
)
896 property_copies
= true;
898 /* This case will be removed when @synthesize is implemented; then
899 @property will only be allowed in an @interface context. */
900 if (objc_implementation_context
)
902 interface
= lookup_interface (CLASS_NAME (objc_implementation_context
));
905 error_at (location
, "no class property can be implemented without an interface");
908 if (TREE_CODE (objc_implementation_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
910 interface
= lookup_category (interface
,
911 CLASS_SUPER_NAME (objc_implementation_context
));
914 error_at (location
, "no category property can be implemented without an interface");
919 else if (objc_interface_context
)
921 /* This will be removed when ivar is removed. */
922 if (parsed_property_ivar_ident
)
924 warning_at (location
, 0, "the %<ivar%> attribute is ignored in an @interface");
925 parsed_property_ivar_ident
= NULL_TREE
;
928 else if (!objc_interface_context
)
930 error_at (location
, "property declaration not in @interface or @implementation context");
934 if (parsed_property_setter_ident
)
936 /* The setter should be terminated by ':', but the parser only
937 passes us an identifier without ':'. So, we need to add ':'
939 const char *parsed_setter
= IDENTIFIER_POINTER (parsed_property_setter_ident
);
940 size_t length
= strlen (parsed_setter
);
941 char *final_setter
= (char *)alloca (length
+ 2);
943 sprintf (final_setter
, "%s:", parsed_setter
);
944 parsed_property_setter_ident
= get_identifier (final_setter
);
947 property_decl
= make_node (PROPERTY_DECL
);
948 TREE_TYPE (property_decl
) = TREE_TYPE (decl
);
950 PROPERTY_NAME (property_decl
) = DECL_NAME (decl
);
951 PROPERTY_GETTER_NAME (property_decl
) = parsed_property_getter_ident
;
952 PROPERTY_SETTER_NAME (property_decl
) = parsed_property_setter_ident
;
953 PROPERTY_IVAR_NAME (property_decl
) = parsed_property_ivar_ident
;
954 PROPERTY_READONLY (property_decl
) = property_readonly
956 : boolean_false_node
;
957 PROPERTY_COPIES (property_decl
) = property_copies
959 : boolean_false_node
;
961 /* TODO: The following is temporary code that will be removed when
962 property_assign_semantics and property_nonatomic are
964 if (objc_implementation_context
&& objc_interface_context
)
966 /* This branch is impossible but the compiler can't know it. Do
967 something with property_assign_semantics and
968 parsed_property_nonatomic (not implemented yet) to convince
969 the compiler we're using them and prevent it from generating
970 warnings and breaking bootstrap. */
971 PROPERTY_COPIES (property_decl
) = property_assign_semantics
? boolean_true_node
: boolean_false_node
;
972 PROPERTY_READONLY (property_decl
) = parsed_property_nonatomic
? boolean_true_node
: boolean_false_node
;
975 if (objc_interface_context
)
977 /* Doing the property in interface declaration. */
979 /* Issue error if property and an ivar name match. */
980 if (TREE_CODE (objc_interface_context
) == CLASS_INTERFACE_TYPE
981 && is_ivar (CLASS_IVARS (objc_interface_context
), DECL_NAME (decl
)))
982 error_at (location
, "property %qD may not have the same name as an ivar in the class", decl
);
983 /* must check for duplicate property declarations. */
984 for (x
= CLASS_PROPERTY_DECL (objc_interface_context
); x
; x
= TREE_CHAIN (x
))
986 if (PROPERTY_NAME (x
) == DECL_NAME (decl
))
988 error_at (location
, "duplicate property declaration %qD", decl
);
992 TREE_CHAIN (property_decl
) = CLASS_PROPERTY_DECL (objc_interface_context
);
993 CLASS_PROPERTY_DECL (objc_interface_context
) = property_decl
;
997 /* This case will go away once @syhtensize is implemented. */
999 /* Doing the property in implementation context. */
1000 /* If property is not declared in the interface issue error. */
1001 for (x
= CLASS_PROPERTY_DECL (interface
); x
; x
= TREE_CHAIN (x
))
1002 if (PROPERTY_NAME (x
) == DECL_NAME (decl
))
1006 error_at (location
, "no declaration of property %qD found in the interface", decl
);
1009 /* readonlys must also match. */
1010 if (PROPERTY_READONLY (x
) != PROPERTY_READONLY (property_decl
))
1012 error_at (location
, "property %qD %<readonly%> attribute conflicts with its"
1013 " interface version", decl
);
1015 /* copies must also match. */
1016 if (PROPERTY_COPIES (x
) != PROPERTY_COPIES (property_decl
))
1018 error_at (location
, "property %qD %<copies%> attribute conflicts with its"
1019 " interface version", decl
);
1021 /* Cannot have readonly and setter attribute for the same property. */
1022 if (PROPERTY_READONLY (property_decl
) == boolean_true_node
&&
1023 PROPERTY_SETTER_NAME (property_decl
))
1025 /* This error is already reported up there. */
1026 /* warning_at (location, 0, "a %<readonly%> property cannot have a setter (ignored)"); */
1027 PROPERTY_SETTER_NAME (property_decl
) = NULL_TREE
;
1029 /* Add the property to the list of properties for current implementation. */
1030 TREE_CHAIN (property_decl
) = IMPL_PROPERTY_DECL (objc_implementation_context
);
1031 IMPL_PROPERTY_DECL (objc_implementation_context
) = property_decl
;
1035 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
1039 lookup_property_in_list (tree chain
, tree property
)
1042 for (x
= CLASS_PROPERTY_DECL (chain
); x
; x
= TREE_CHAIN (x
))
1043 if (PROPERTY_NAME (x
) == property
)
1048 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
1050 static tree
lookup_property_in_protocol_list (tree rproto_list
, tree property
)
1053 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
1055 tree p
= TREE_VALUE (rproto
);
1056 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
1058 if ((x
= lookup_property_in_list (p
, property
)))
1060 if (PROTOCOL_LIST (p
))
1061 return lookup_property_in_protocol_list (PROTOCOL_LIST (p
), property
);
1065 ; /* An identifier...if we could not find a protocol. */
1071 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
1072 chain of interface hierarchy.
1075 lookup_property (tree interface_type
, tree property
)
1077 tree inter
= interface_type
;
1081 if ((x
= lookup_property_in_list (inter
, property
)))
1083 /* Failing that, look for the property in each category of the class. */
1085 while ((category
= CLASS_CATEGORY_LIST (category
)))
1086 if ((x
= lookup_property_in_list (category
, property
)))
1089 /* Failing to find in categories, look for property in protocol list. */
1090 if (CLASS_PROTOCOL_LIST (inter
)
1091 && (x
= lookup_property_in_protocol_list (
1092 CLASS_PROTOCOL_LIST (inter
), property
)))
1095 /* Failing that, climb up the inheritance hierarchy. */
1096 inter
= lookup_interface (CLASS_SUPER_NAME (inter
));
1101 /* This routine recognizes a dot-notation for a property reference and generates a call to
1102 the getter function for this property. In all other cases, it returns a NULL_TREE.
1106 objc_build_getter_call (tree receiver
, tree component
)
1111 if (receiver
== NULL_TREE
1112 || receiver
== error_mark_node
1113 || (rtype
= TREE_TYPE (receiver
)) == NULL_TREE
)
1116 if (component
== NULL_TREE
1117 || component
== error_mark_node
1118 || TREE_CODE (component
) != IDENTIFIER_NODE
)
1121 if (objc_is_id (rtype
))
1123 tree rprotos
= (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype
))
1124 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype
))
1127 x
= lookup_property_in_protocol_list (rprotos
, component
);
1131 tree basetype
= TYPE_MAIN_VARIANT (rtype
);
1133 if (basetype
!= NULL_TREE
&& TREE_CODE (basetype
) == POINTER_TYPE
)
1134 basetype
= TREE_TYPE (basetype
);
1138 while (basetype
!= NULL_TREE
1139 && TREE_CODE (basetype
) == RECORD_TYPE
1140 && OBJC_TYPE_NAME (basetype
)
1141 && TREE_CODE (OBJC_TYPE_NAME (basetype
)) == TYPE_DECL
1142 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype
)))
1143 basetype
= DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype
));
1145 if (basetype
!= NULL_TREE
&& TYPED_OBJECT (basetype
))
1147 tree interface_type
= TYPE_OBJC_INTERFACE (basetype
);
1148 if (!interface_type
)
1150 x
= lookup_property (interface_type
, component
);
1156 tree call_exp
, getter
;
1157 /* Get the getter name. */
1158 gcc_assert (PROPERTY_NAME (x
));
1159 getter
= objc_finish_message_expr (receiver
, PROPERTY_NAME (x
),
1163 /* In C++, a getter which returns an aggregate value results in a
1164 target_expr which initializes a temporary to the call expression. */
1165 if (TREE_CODE (getter
) == TARGET_EXPR
)
1167 gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter
)));
1168 gcc_assert (TREE_CODE (TREE_OPERAND (getter
,0)) == VAR_DECL
);
1169 call_exp
= TREE_OPERAND (getter
,1);
1172 gcc_assert (TREE_CODE (call_exp
) == CALL_EXPR
);
1174 CALL_EXPR_OBJC_PROPERTY_GETTER (call_exp
) = 1;
1180 /* This routine builds a call to property's 'setter' function. RECEIVER is the
1181 receiving object for 'setter'. PROPERTY_IDENT is name of the property and
1182 RHS is the argument passed to the 'setter' function. */
1185 objc_setter_func_call (tree receiver
, tree property_ident
, tree rhs
)
1187 tree setter_argument
= build_tree_list (NULL_TREE
, rhs
);
1188 char *setter_name
= objc_build_property_setter_name (property_ident
, true);
1190 in_objc_property_setter_name_context
= true;
1191 setter
= objc_finish_message_expr (receiver
, get_identifier (setter_name
),
1193 in_objc_property_setter_name_context
= false;
1197 /* Find the selector identifier from a reference. A somewhat tortuous way of
1198 obtaining the information to allow a setter to be written, given an
1202 get_selector_from_reference (tree selref
)
1206 if (flag_next_runtime
)
1208 /* Run through the selectors until we find the one we're looking for. */
1209 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1210 if (TREE_PURPOSE (chain
) == selref
)
1211 return TREE_VALUE (chain
);
1215 /* To find our way back to the selector for the GNU runtime is harder
1216 work, we need to decompose the representation of SELECTOR_TABLE[n]
1217 to find 'n'. This representation is in several forms. */
1218 if (TREE_CODE (selref
) == POINTER_PLUS_EXPR
)
1220 /* We need the element size to decode the array offset expression
1222 unsigned size
= (unsigned) TREE_INT_CST_LOW
1228 (TREE_OPERAND (selref
, 0), 0), 0)))));
1230 (unsigned) TREE_INT_CST_LOW (TREE_OPERAND (selref
, 1))
1232 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1234 return TREE_VALUE (chain
);
1236 else if (TREE_CODE (selref
) == NOP_EXPR
)
1238 /* Either we have a base an index, or we have just a base (when the
1240 if (TREE_CODE (TREE_OPERAND (selref
, 0)) == ADDR_EXPR
1243 (TREE_OPERAND (selref
, 0), 0)) == ARRAY_REF
)
1246 unsigned index
= (unsigned) TREE_INT_CST_LOW
1249 (TREE_OPERAND (selref
, 0), 0), 1));
1250 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1252 return TREE_VALUE (chain
);
1255 return TREE_VALUE (sel_ref_chain
);
1256 } /* Else we don't know how to figure this out - which will produce a
1257 parse error - saying that the LHS is not writeable. */
1262 /* This routine converts a previously synthesized 'getter' function call for
1263 a property and converts it to a 'setter' function call for the same
1267 objc_build_setter_call (tree lhs
, tree rhs
)
1270 && TREE_CODE (lhs
) == CALL_EXPR
1271 && CALL_EXPR_OBJC_PROPERTY_GETTER (lhs
))
1274 /* Get the Object. */
1275 tree receiver
= TREE_OPERAND (lhs
, 3);
1276 /* Get the selector reference. */
1277 tree selector_reference
= TREE_OPERAND (lhs
, 4);
1278 gcc_assert (receiver
&& selector_reference
);
1279 /* The style of the selector reference is different for GNU & NeXT. */
1280 selector
= get_selector_from_reference (selector_reference
);
1282 return objc_setter_func_call (receiver
, selector
, rhs
);
1287 /* This routine checks to see if ID is a property name. If so, it
1288 returns property declaration. */
1291 is_property (tree klass
, tree id
)
1295 for (x
= CLASS_PROPERTY_DECL (klass
); x
; x
= TREE_CHAIN (x
))
1296 if (PROPERTY_NAME (x
) == id
)
1301 /* This routine returns call to property's getter when a property is
1302 used stand-alone (without self. notation). */
1305 build_property_reference (tree property
, tree id
)
1308 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
1310 error ("property %qs accessed in class method",
1311 IDENTIFIER_POINTER (id
));
1312 return error_mark_node
;
1315 getter
= objc_finish_message_expr (self_decl
, PROPERTY_NAME (property
), NULL_TREE
);
1316 CALL_EXPR_OBJC_PROPERTY_GETTER (getter
) = 1;
1321 objc_build_method_signature (bool is_class_method
, tree rettype
, tree selector
,
1322 tree optparms
, bool ellipsis
)
1324 if (is_class_method
)
1325 return build_method_decl (CLASS_METHOD_DECL
, rettype
, selector
,
1326 optparms
, ellipsis
);
1328 return build_method_decl (INSTANCE_METHOD_DECL
, rettype
, selector
,
1329 optparms
, ellipsis
);
1333 objc_add_method_declaration (bool is_class_method
, tree decl
, tree attributes
)
1335 if (!objc_interface_context
)
1337 /* PS: At the moment, due to how the parser works, it should be
1338 impossible to get here. But it's good to have the check in
1339 case the parser changes.
1341 fatal_error ("method declaration not in @interface context");
1344 objc_decl_method_attributes (&decl
, attributes
, 0);
1345 objc_add_method (objc_interface_context
,
1348 objc_method_optional_flag
);
1351 /* Return 'true' if the method definition could be started, and
1352 'false' if not (because we are outside an @implementation context).
1355 objc_start_method_definition (bool is_class_method
, tree decl
, tree attributes
)
1357 if (!objc_implementation_context
)
1359 error ("method definition not in @implementation context");
1363 if (decl
!= NULL_TREE
&& METHOD_SEL_NAME (decl
) == error_mark_node
)
1367 /* Indicate no valid break/continue context by setting these variables
1368 to some non-null, non-label value. We'll notice and emit the proper
1369 error message in c_finish_bc_stmt. */
1370 c_break_label
= c_cont_label
= size_zero_node
;
1373 objc_decl_method_attributes (&decl
, attributes
, 0);
1374 objc_add_method (objc_implementation_context
,
1377 /* is optional */ false);
1378 start_method_def (decl
);
1383 objc_add_instance_variable (tree decl
)
1385 (void) add_instance_variable (objc_ivar_context
,
1386 objc_ivar_visibility
,
1390 /* Return true if TYPE is 'id'. */
1393 objc_is_object_id (tree type
)
1395 return OBJC_TYPE_NAME (type
) == objc_object_id
;
1399 objc_is_class_id (tree type
)
1401 return OBJC_TYPE_NAME (type
) == objc_class_id
;
1404 /* Construct a C struct with same name as KLASS, a base struct with tag
1405 SUPER_NAME (if any), and FIELDS indicated. */
1408 objc_build_struct (tree klass
, tree fields
, tree super_name
)
1410 tree name
= CLASS_NAME (klass
);
1411 tree s
= objc_start_struct (name
);
1412 tree super
= (super_name
? xref_tag (RECORD_TYPE
, super_name
) : NULL_TREE
);
1414 VEC(tree
,heap
) *objc_info
= NULL
;
1419 /* Prepend a packed variant of the base class into the layout. This
1420 is necessary to preserve ObjC ABI compatibility. */
1421 tree base
= build_decl (input_location
,
1422 FIELD_DECL
, NULL_TREE
, super
);
1423 tree field
= TYPE_FIELDS (super
);
1425 while (field
&& DECL_CHAIN (field
)
1426 && TREE_CODE (DECL_CHAIN (field
)) == FIELD_DECL
)
1427 field
= DECL_CHAIN (field
);
1429 /* For ObjC ABI purposes, the "packed" size of a base class is
1430 the sum of the offset and the size (in bits) of the last field
1433 = (field
&& TREE_CODE (field
) == FIELD_DECL
1434 ? size_binop (PLUS_EXPR
,
1435 size_binop (PLUS_EXPR
,
1438 convert (bitsizetype
,
1439 DECL_FIELD_OFFSET (field
)),
1440 bitsize_int (BITS_PER_UNIT
)),
1441 DECL_FIELD_BIT_OFFSET (field
)),
1443 : bitsize_zero_node
);
1444 DECL_SIZE_UNIT (base
)
1445 = size_binop (FLOOR_DIV_EXPR
, convert (sizetype
, DECL_SIZE (base
)),
1446 size_int (BITS_PER_UNIT
));
1447 DECL_ARTIFICIAL (base
) = 1;
1448 DECL_ALIGN (base
) = 1;
1449 DECL_FIELD_CONTEXT (base
) = s
;
1451 DECL_FIELD_IS_BASE (base
) = 1;
1454 TREE_NO_WARNING (fields
) = 1; /* Suppress C++ ABI warnings -- we */
1455 #endif /* are following the ObjC ABI here. */
1456 DECL_CHAIN (base
) = fields
;
1460 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
1461 in all variants of this RECORD_TYPE to be clobbered, but it is therein
1462 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
1463 Hence, we must squirrel away the ObjC-specific information before calling
1464 finish_struct(), and then reinstate it afterwards. */
1466 for (t
= TYPE_NEXT_VARIANT (s
); t
; t
= TYPE_NEXT_VARIANT (t
))
1468 if (!TYPE_HAS_OBJC_INFO (t
))
1470 INIT_TYPE_OBJC_INFO (t
);
1471 TYPE_OBJC_INTERFACE (t
) = klass
;
1473 VEC_safe_push (tree
, heap
, objc_info
, TYPE_OBJC_INFO (t
));
1476 /* Point the struct at its related Objective-C class. */
1477 INIT_TYPE_OBJC_INFO (s
);
1478 TYPE_OBJC_INTERFACE (s
) = klass
;
1480 s
= objc_finish_struct (s
, fields
);
1482 for (i
= 0, t
= TYPE_NEXT_VARIANT (s
); t
; t
= TYPE_NEXT_VARIANT (t
), i
++)
1484 TYPE_OBJC_INFO (t
) = VEC_index (tree
, objc_info
, i
);
1485 /* Replace the IDENTIFIER_NODE with an actual @interface. */
1486 TYPE_OBJC_INTERFACE (t
) = klass
;
1488 VEC_free (tree
, heap
, objc_info
);
1490 /* Use TYPE_BINFO structures to point at the super class, if any. */
1491 objc_xref_basetypes (s
, super
);
1493 /* Mark this struct as a class template. */
1494 CLASS_STATIC_TEMPLATE (klass
) = s
;
1499 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
1500 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
1503 objc_build_volatilized_type (tree type
)
1507 /* Check if we have not constructed the desired variant already. */
1508 for (t
= TYPE_MAIN_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
1510 /* The type qualifiers must (obviously) match up. */
1511 if (!TYPE_VOLATILE (t
)
1512 || (TYPE_READONLY (t
) != TYPE_READONLY (type
))
1513 || (TYPE_RESTRICT (t
) != TYPE_RESTRICT (type
)))
1516 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
1517 info, if any) must match up. */
1518 if (POINTER_TYPE_P (t
)
1519 && (TREE_TYPE (t
) != TREE_TYPE (type
)))
1522 /* Only match up the types which were previously volatilized in similar fashion and not
1523 because they were declared as such. */
1524 if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t
)))
1527 /* Everything matches up! */
1531 /* Ok, we could not re-use any of the pre-existing variants. Create
1533 t
= build_variant_type_copy (type
);
1534 TYPE_VOLATILE (t
) = 1;
1536 TYPE_ATTRIBUTES (t
) = merge_attributes (TYPE_ATTRIBUTES (type
),
1537 tree_cons (get_identifier ("objc_volatilized"),
1540 if (TREE_CODE (t
) == ARRAY_TYPE
)
1541 TREE_TYPE (t
) = objc_build_volatilized_type (TREE_TYPE (t
));
1543 /* Set up the canonical type information. */
1544 if (TYPE_STRUCTURAL_EQUALITY_P (type
))
1545 SET_TYPE_STRUCTURAL_EQUALITY (t
);
1546 else if (TYPE_CANONICAL (type
) != type
)
1547 TYPE_CANONICAL (t
) = objc_build_volatilized_type (TYPE_CANONICAL (type
));
1549 TYPE_CANONICAL (t
) = t
;
1554 /* Mark DECL as being 'volatile' for purposes of Darwin
1555 _setjmp()/_longjmp() exception handling. Called from
1556 objc_mark_locals_volatile(). */
1558 objc_volatilize_decl (tree decl
)
1560 /* Do not mess with variables that are 'static' or (already)
1562 if (!TREE_THIS_VOLATILE (decl
) && !TREE_STATIC (decl
)
1563 && (TREE_CODE (decl
) == VAR_DECL
1564 || TREE_CODE (decl
) == PARM_DECL
))
1566 tree t
= TREE_TYPE (decl
);
1568 t
= objc_build_volatilized_type (t
);
1570 TREE_TYPE (decl
) = t
;
1571 TREE_THIS_VOLATILE (decl
) = 1;
1572 TREE_SIDE_EFFECTS (decl
) = 1;
1573 DECL_REGISTER (decl
) = 0;
1575 C_DECL_REGISTER (decl
) = 0;
1580 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
1581 (including its categories and superclasses) or by object type TYP.
1582 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
1585 objc_lookup_protocol (tree proto
, tree cls
, tree typ
, bool warn
)
1587 bool class_type
= (cls
!= NULL_TREE
);
1593 /* Check protocols adopted by the class and its categories. */
1594 for (c
= cls
; c
; c
= CLASS_CATEGORY_LIST (c
))
1596 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c
), proto
))
1600 /* Repeat for superclasses. */
1601 cls
= lookup_interface (CLASS_SUPER_NAME (cls
));
1604 /* Check for any protocols attached directly to the object type. */
1605 if (TYPE_HAS_OBJC_INFO (typ
))
1607 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ
), proto
))
1614 gen_type_name_0 (class_type
? typ
: TYPE_POINTER_TO (typ
));
1615 /* NB: Types 'id' and 'Class' cannot reasonably be described as
1616 "implementing" a given protocol, since they do not have an
1619 warning (0, "class %qs does not implement the %qE protocol",
1620 identifier_to_locale (errbuf
), PROTOCOL_NAME (proto
));
1622 warning (0, "type %qs does not conform to the %qE protocol",
1623 identifier_to_locale (errbuf
), PROTOCOL_NAME (proto
));
1629 /* Check if class RCLS and instance struct type RTYP conform to at least the
1630 same protocols that LCLS and LTYP conform to. */
1633 objc_compare_protocols (tree lcls
, tree ltyp
, tree rcls
, tree rtyp
, bool warn
)
1636 bool have_lproto
= false;
1640 /* NB: We do _not_ look at categories defined for LCLS; these may or
1641 may not get loaded in, and therefore it is unreasonable to require
1642 that RCLS/RTYP must implement any of their protocols. */
1643 for (p
= CLASS_PROTOCOL_LIST (lcls
); p
; p
= TREE_CHAIN (p
))
1647 if (!objc_lookup_protocol (TREE_VALUE (p
), rcls
, rtyp
, warn
))
1651 /* Repeat for superclasses. */
1652 lcls
= lookup_interface (CLASS_SUPER_NAME (lcls
));
1655 /* Check for any protocols attached directly to the object type. */
1656 if (TYPE_HAS_OBJC_INFO (ltyp
))
1658 for (p
= TYPE_OBJC_PROTOCOL_LIST (ltyp
); p
; p
= TREE_CHAIN (p
))
1662 if (!objc_lookup_protocol (TREE_VALUE (p
), rcls
, rtyp
, warn
))
1667 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1668 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1669 away with simply checking for 'id' or 'Class' (!RCLS), since this
1670 routine will not get called in other cases. */
1671 return have_lproto
|| (rcls
!= NULL_TREE
);
1674 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
1675 Both TYPE1 and TYPE2 must be pointers, and already determined to be
1676 compatible by objc_compare_types() below. */
1679 objc_common_type (tree type1
, tree type2
)
1681 tree inner1
= TREE_TYPE (type1
), inner2
= TREE_TYPE (type2
);
1683 while (POINTER_TYPE_P (inner1
))
1685 inner1
= TREE_TYPE (inner1
);
1686 inner2
= TREE_TYPE (inner2
);
1689 /* If one type is derived from another, return the base type. */
1690 if (DERIVED_FROM_P (inner1
, inner2
))
1692 else if (DERIVED_FROM_P (inner2
, inner1
))
1695 /* If both types are 'Class', return 'Class'. */
1696 if (objc_is_class_id (inner1
) && objc_is_class_id (inner2
))
1697 return objc_class_type
;
1699 /* Otherwise, return 'id'. */
1700 return objc_object_type
;
1703 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1704 an instance of RTYP to an instance of LTYP or to compare the two
1705 (if ARGNO is equal to -3), per ObjC type system rules. Before
1706 returning 'true', this routine may issue warnings related to, e.g.,
1707 protocol conformance. When returning 'false', the routine must
1708 produce absolutely no warnings; the C or C++ front-end will do so
1709 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1710 the routine must return 'false'.
1712 The ARGNO parameter is encoded as follows:
1713 >= 1 Parameter number (CALLEE contains function being called);
1717 -3 Comparison (LTYP and RTYP may match in either direction);
1718 -4 Silent comparison (for C++ overload resolution).
1722 objc_compare_types (tree ltyp
, tree rtyp
, int argno
, tree callee
)
1724 tree lcls
, rcls
, lproto
, rproto
;
1725 bool pointers_compatible
;
1727 /* We must be dealing with pointer types */
1728 if (!POINTER_TYPE_P (ltyp
) || !POINTER_TYPE_P (rtyp
))
1733 ltyp
= TREE_TYPE (ltyp
); /* Remove indirections. */
1734 rtyp
= TREE_TYPE (rtyp
);
1736 while (POINTER_TYPE_P (ltyp
) && POINTER_TYPE_P (rtyp
));
1738 /* We must also handle function pointers, since ObjC is a bit more
1739 lenient than C or C++ on this. */
1740 if (TREE_CODE (ltyp
) == FUNCTION_TYPE
&& TREE_CODE (rtyp
) == FUNCTION_TYPE
)
1742 /* Return types must be covariant. */
1743 if (!comptypes (TREE_TYPE (ltyp
), TREE_TYPE (rtyp
))
1744 && !objc_compare_types (TREE_TYPE (ltyp
), TREE_TYPE (rtyp
),
1748 /* Argument types must be contravariant. */
1749 for (ltyp
= TYPE_ARG_TYPES (ltyp
), rtyp
= TYPE_ARG_TYPES (rtyp
);
1750 ltyp
&& rtyp
; ltyp
= TREE_CHAIN (ltyp
), rtyp
= TREE_CHAIN (rtyp
))
1752 if (!comptypes (TREE_VALUE (rtyp
), TREE_VALUE (ltyp
))
1753 && !objc_compare_types (TREE_VALUE (rtyp
), TREE_VALUE (ltyp
),
1758 return (ltyp
== rtyp
);
1761 /* Past this point, we are only interested in ObjC class instances,
1762 or 'id' or 'Class'. */
1763 if (TREE_CODE (ltyp
) != RECORD_TYPE
|| TREE_CODE (rtyp
) != RECORD_TYPE
)
1766 if (!objc_is_object_id (ltyp
) && !objc_is_class_id (ltyp
)
1767 && !TYPE_HAS_OBJC_INFO (ltyp
))
1770 if (!objc_is_object_id (rtyp
) && !objc_is_class_id (rtyp
)
1771 && !TYPE_HAS_OBJC_INFO (rtyp
))
1774 /* Past this point, we are committed to returning 'true' to the caller
1775 (unless performing a silent comparison; see below). However, we can
1776 still warn about type and/or protocol mismatches. */
1778 if (TYPE_HAS_OBJC_INFO (ltyp
))
1780 lcls
= TYPE_OBJC_INTERFACE (ltyp
);
1781 lproto
= TYPE_OBJC_PROTOCOL_LIST (ltyp
);
1784 lcls
= lproto
= NULL_TREE
;
1786 if (TYPE_HAS_OBJC_INFO (rtyp
))
1788 rcls
= TYPE_OBJC_INTERFACE (rtyp
);
1789 rproto
= TYPE_OBJC_PROTOCOL_LIST (rtyp
);
1792 rcls
= rproto
= NULL_TREE
;
1794 /* If we could not find an @interface declaration, we must have
1795 only seen a @class declaration; for purposes of type comparison,
1796 treat it as a stand-alone (root) class. */
1798 if (lcls
&& TREE_CODE (lcls
) == IDENTIFIER_NODE
)
1801 if (rcls
&& TREE_CODE (rcls
) == IDENTIFIER_NODE
)
1804 /* If either type is an unqualified 'id', we're done. */
1805 if ((!lproto
&& objc_is_object_id (ltyp
))
1806 || (!rproto
&& objc_is_object_id (rtyp
)))
1809 pointers_compatible
= (TYPE_MAIN_VARIANT (ltyp
) == TYPE_MAIN_VARIANT (rtyp
));
1811 /* If the underlying types are the same, and at most one of them has
1812 a protocol list, we do not need to issue any diagnostics. */
1813 if (pointers_compatible
&& (!lproto
|| !rproto
))
1816 /* If exactly one of the types is 'Class', issue a diagnostic; any
1817 exceptions of this rule have already been handled. */
1818 if (objc_is_class_id (ltyp
) ^ objc_is_class_id (rtyp
))
1819 pointers_compatible
= false;
1820 /* Otherwise, check for inheritance relations. */
1823 if (!pointers_compatible
)
1825 = (objc_is_object_id (ltyp
) || objc_is_object_id (rtyp
));
1827 if (!pointers_compatible
)
1828 pointers_compatible
= DERIVED_FROM_P (ltyp
, rtyp
);
1830 if (!pointers_compatible
&& argno
<= -3)
1831 pointers_compatible
= DERIVED_FROM_P (rtyp
, ltyp
);
1834 /* If the pointers match modulo protocols, check for protocol conformance
1836 if (pointers_compatible
)
1838 pointers_compatible
= objc_compare_protocols (lcls
, ltyp
, rcls
, rtyp
,
1841 if (!pointers_compatible
&& argno
== -3)
1842 pointers_compatible
= objc_compare_protocols (rcls
, rtyp
, lcls
, ltyp
,
1846 if (!pointers_compatible
)
1848 /* The two pointers are not exactly compatible. Issue a warning, unless
1849 we are performing a silent comparison, in which case return 'false'
1851 /* NB: For the time being, we shall make our warnings look like their
1852 C counterparts. In the future, we may wish to make them more
1860 warning (0, "comparison of distinct Objective-C types lacks a cast");
1864 warning (0, "initialization from distinct Objective-C type");
1868 warning (0, "assignment from distinct Objective-C type");
1872 warning (0, "distinct Objective-C type in return");
1876 warning (0, "passing argument %d of %qE from distinct "
1877 "Objective-C type", argno
, callee
);
1885 /* This routine is similar to objc_compare_types except that function-pointers are
1886 excluded. This is because, caller assumes that common types are of (id, Object*)
1887 variety and calls objc_common_type to obtain a common type. There is no commonolty
1888 between two function-pointers in this regard. */
1891 objc_have_common_type (tree ltyp
, tree rtyp
, int argno
, tree callee
)
1893 if (objc_compare_types (ltyp
, rtyp
, argno
, callee
))
1895 /* exclude function-pointer types. */
1898 ltyp
= TREE_TYPE (ltyp
); /* Remove indirections. */
1899 rtyp
= TREE_TYPE (rtyp
);
1901 while (POINTER_TYPE_P (ltyp
) && POINTER_TYPE_P (rtyp
));
1902 return !(TREE_CODE (ltyp
) == FUNCTION_TYPE
&& TREE_CODE (rtyp
) == FUNCTION_TYPE
);
1907 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1908 lives in the volatilized hash table, ignore the 'volatile' bit when
1909 making the comparison. */
1912 objc_type_quals_match (tree ltyp
, tree rtyp
)
1914 int lquals
= TYPE_QUALS (ltyp
), rquals
= TYPE_QUALS (rtyp
);
1916 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp
)))
1917 lquals
&= ~TYPE_QUAL_VOLATILE
;
1919 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp
)))
1920 rquals
&= ~TYPE_QUAL_VOLATILE
;
1922 return (lquals
== rquals
);
1926 /* Determine if CHILD is derived from PARENT. The routine assumes that
1927 both parameters are RECORD_TYPEs, and is non-reflexive. */
1930 objc_derived_from_p (tree parent
, tree child
)
1932 parent
= TYPE_MAIN_VARIANT (parent
);
1934 for (child
= TYPE_MAIN_VARIANT (child
);
1935 TYPE_BINFO (child
) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child
));)
1937 child
= TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1938 (TYPE_BINFO (child
),
1941 if (child
== parent
)
1950 objc_build_component_ref (tree datum
, tree component
)
1952 /* If COMPONENT is NULL, the caller is referring to the anonymous
1953 base class field. */
1956 tree base
= TYPE_FIELDS (TREE_TYPE (datum
));
1958 return build3 (COMPONENT_REF
, TREE_TYPE (base
), datum
, base
, NULL_TREE
);
1961 /* The 'build_component_ref' routine has been removed from the C++
1962 front-end, but 'finish_class_member_access_expr' seems to be
1963 a worthy substitute. */
1965 return finish_class_member_access_expr (datum
, component
, false,
1966 tf_warning_or_error
);
1968 return build_component_ref (input_location
, datum
, component
);
1972 /* Recursively copy inheritance information rooted at BINFO. To do this,
1973 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1976 objc_copy_binfo (tree binfo
)
1978 tree btype
= BINFO_TYPE (binfo
);
1979 tree binfo2
= make_tree_binfo (BINFO_N_BASE_BINFOS (binfo
));
1983 BINFO_TYPE (binfo2
) = btype
;
1984 BINFO_OFFSET (binfo2
) = BINFO_OFFSET (binfo
);
1985 BINFO_BASE_ACCESSES (binfo2
) = BINFO_BASE_ACCESSES (binfo
);
1987 /* Recursively copy base binfos of BINFO. */
1988 for (ix
= 0; BINFO_BASE_ITERATE (binfo
, ix
, base_binfo
); ix
++)
1990 tree base_binfo2
= objc_copy_binfo (base_binfo
);
1992 BINFO_INHERITANCE_CHAIN (base_binfo2
) = binfo2
;
1993 BINFO_BASE_APPEND (binfo2
, base_binfo2
);
1999 /* Record superclass information provided in BASETYPE for ObjC class REF.
2000 This is loosely based on cp/decl.c:xref_basetypes(). */
2003 objc_xref_basetypes (tree ref
, tree basetype
)
2005 tree binfo
= make_tree_binfo (basetype
? 1 : 0);
2007 TYPE_BINFO (ref
) = binfo
;
2008 BINFO_OFFSET (binfo
) = size_zero_node
;
2009 BINFO_TYPE (binfo
) = ref
;
2013 tree base_binfo
= objc_copy_binfo (TYPE_BINFO (basetype
));
2015 BINFO_INHERITANCE_CHAIN (base_binfo
) = binfo
;
2016 BINFO_BASE_ACCESSES (binfo
) = VEC_alloc (tree
, gc
, 1);
2017 BINFO_BASE_APPEND (binfo
, base_binfo
);
2018 BINFO_BASE_ACCESS_APPEND (binfo
, access_public_node
);
2022 /* Called from finish_decl. */
2025 objc_check_decl (tree decl
)
2027 tree type
= TREE_TYPE (decl
);
2029 if (TREE_CODE (type
) != RECORD_TYPE
)
2031 if (OBJC_TYPE_NAME (type
) && (type
= objc_is_class_name (OBJC_TYPE_NAME (type
))))
2032 error ("statically allocated instance of Objective-C class %qE",
2037 objc_check_global_decl (tree decl
)
2039 tree id
= DECL_NAME (decl
);
2040 if (objc_is_class_name (id
) && global_bindings_p())
2041 error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id
));
2044 /* Return a non-volatalized version of TYPE. */
2047 objc_non_volatilized_type (tree type
)
2049 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type
)))
2050 type
= build_qualified_type (type
, (TYPE_QUALS (type
) & ~TYPE_QUAL_VOLATILE
));
2054 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
2055 either name an Objective-C class, or refer to the special 'id' or 'Class'
2056 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
2059 objc_get_protocol_qualified_type (tree interface
, tree protocols
)
2061 /* If INTERFACE is not provided, default to 'id'. */
2062 tree type
= (interface
? objc_is_id (interface
) : objc_object_type
);
2063 bool is_ptr
= (type
!= NULL_TREE
);
2067 type
= objc_is_class_name (interface
);
2071 /* If looking at a typedef, retrieve the precise type it
2073 if (TREE_CODE (interface
) == IDENTIFIER_NODE
)
2074 interface
= identifier_global_value (interface
);
2076 type
= ((interface
&& TREE_CODE (interface
) == TYPE_DECL
2077 && DECL_ORIGINAL_TYPE (interface
))
2078 ? DECL_ORIGINAL_TYPE (interface
)
2079 : xref_tag (RECORD_TYPE
, type
));
2087 type
= build_variant_type_copy (type
);
2089 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
2093 tree orig_pointee_type
= TREE_TYPE (type
);
2094 TREE_TYPE (type
) = build_variant_type_copy (orig_pointee_type
);
2096 /* Set up the canonical type information. */
2097 TYPE_CANONICAL (type
)
2098 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type
));
2100 TYPE_POINTER_TO (TREE_TYPE (type
)) = type
;
2101 type
= TREE_TYPE (type
);
2104 /* Look up protocols and install in lang specific list. */
2105 DUP_TYPE_OBJC_INFO (type
, TYPE_MAIN_VARIANT (type
));
2106 TYPE_OBJC_PROTOCOL_LIST (type
) = lookup_and_install_protocols (protocols
);
2108 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
2109 return the pointer to the new pointee variant. */
2111 type
= TYPE_POINTER_TO (type
);
2113 TYPE_OBJC_INTERFACE (type
)
2114 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type
));
2120 /* Check for circular dependencies in protocols. The arguments are
2121 PROTO, the protocol to check, and LIST, a list of protocol it
2125 check_protocol_recursively (tree proto
, tree list
)
2129 for (p
= list
; p
; p
= TREE_CHAIN (p
))
2131 tree pp
= TREE_VALUE (p
);
2133 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
2134 pp
= lookup_protocol (pp
);
2137 fatal_error ("protocol %qE has circular dependency",
2138 PROTOCOL_NAME (pp
));
2140 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
2144 /* Look up PROTOCOLS, and return a list of those that are found.
2145 If none are found, return NULL. */
2148 lookup_and_install_protocols (tree protocols
)
2151 tree return_value
= NULL_TREE
;
2153 if (protocols
== error_mark_node
)
2156 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
2158 tree ident
= TREE_VALUE (proto
);
2159 tree p
= lookup_protocol (ident
);
2162 return_value
= chainon (return_value
,
2163 build_tree_list (NULL_TREE
, p
));
2164 else if (ident
!= error_mark_node
)
2165 error ("cannot find protocol declaration for %qE",
2169 return return_value
;
2172 /* Create a declaration for field NAME of a given TYPE. */
2175 create_field_decl (tree type
, const char *name
)
2177 return build_decl (input_location
,
2178 FIELD_DECL
, get_identifier (name
), type
);
2181 /* Create a global, static declaration for variable NAME of a given TYPE. The
2182 finish_var_decl() routine will need to be called on it afterwards. */
2185 start_var_decl (tree type
, const char *name
)
2187 tree var
= build_decl (input_location
,
2188 VAR_DECL
, get_identifier (name
), type
);
2190 TREE_STATIC (var
) = 1;
2191 DECL_INITIAL (var
) = error_mark_node
; /* A real initializer is coming... */
2192 DECL_IGNORED_P (var
) = 1;
2193 DECL_ARTIFICIAL (var
) = 1;
2194 DECL_CONTEXT (var
) = NULL_TREE
;
2196 DECL_THIS_STATIC (var
) = 1; /* squash redeclaration errors */
2202 /* Finish off the variable declaration created by start_var_decl(). */
2205 finish_var_decl (tree var
, tree initializer
)
2207 finish_decl (var
, input_location
, initializer
, NULL_TREE
, NULL_TREE
);
2210 /* Find the decl for the constant string class reference. This is only
2211 used for the NeXT runtime. */
2214 setup_string_decl (void)
2219 /* %s in format will provide room for terminating null */
2220 length
= strlen (STRING_OBJECT_GLOBAL_FORMAT
)
2221 + strlen (constant_string_class_name
);
2222 name
= XNEWVEC (char, length
);
2223 sprintf (name
, STRING_OBJECT_GLOBAL_FORMAT
,
2224 constant_string_class_name
);
2225 constant_string_global_id
= get_identifier (name
);
2226 string_class_decl
= lookup_name (constant_string_global_id
);
2228 return string_class_decl
;
2231 /* Purpose: "play" parser, creating/installing representations
2232 of the declarations that are required by Objective-C.
2236 type_spec--------->sc_spec
2237 (tree_list) (tree_list)
2240 identifier_node identifier_node */
2243 synth_module_prologue (void)
2246 enum debug_info_type save_write_symbols
= write_symbols
;
2247 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
2249 /* Suppress outputting debug symbols, because
2250 dbxout_init hasn't been called yet. */
2251 write_symbols
= NO_DEBUG
;
2252 debug_hooks
= &do_nothing_debug_hooks
;
2255 push_lang_context (lang_name_c
); /* extern "C" */
2258 /* The following are also defined in <objc/objc.h> and friends. */
2260 objc_object_id
= get_identifier (TAG_OBJECT
);
2261 objc_class_id
= get_identifier (TAG_CLASS
);
2263 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
2264 objc_class_reference
= xref_tag (RECORD_TYPE
, objc_class_id
);
2266 objc_object_type
= build_pointer_type (objc_object_reference
);
2267 objc_class_type
= build_pointer_type (objc_class_reference
);
2269 objc_object_name
= get_identifier (OBJECT_TYPEDEF_NAME
);
2270 objc_class_name
= get_identifier (CLASS_TYPEDEF_NAME
);
2272 /* Declare the 'id' and 'Class' typedefs. */
2274 type
= lang_hooks
.decls
.pushdecl (build_decl (input_location
,
2278 TREE_NO_WARNING (type
) = 1;
2279 type
= lang_hooks
.decls
.pushdecl (build_decl (input_location
,
2283 TREE_NO_WARNING (type
) = 1;
2285 /* Forward-declare '@interface Protocol'. */
2287 type
= get_identifier (PROTOCOL_OBJECT_CLASS_NAME
);
2288 objc_declare_class (tree_cons (NULL_TREE
, type
, NULL_TREE
));
2289 objc_protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
2292 /* Declare type of selector-objects that represent an operation name. */
2294 if (flag_next_runtime
)
2295 /* `struct objc_selector *' */
2297 = build_pointer_type (xref_tag (RECORD_TYPE
,
2298 get_identifier (TAG_SELECTOR
)));
2300 /* `const struct objc_selector *' */
2302 = build_pointer_type
2303 (build_qualified_type (xref_tag (RECORD_TYPE
,
2304 get_identifier (TAG_SELECTOR
)),
2307 /* Declare receiver type used for dispatching messages to 'super'. */
2309 /* `struct objc_super *' */
2310 objc_super_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
2311 get_identifier (TAG_SUPER
)));
2313 /* Declare pointers to method and ivar lists. */
2314 objc_method_list_ptr
= build_pointer_type
2315 (xref_tag (RECORD_TYPE
,
2316 get_identifier (UTAG_METHOD_LIST
)));
2317 objc_method_proto_list_ptr
2318 = build_pointer_type (xref_tag (RECORD_TYPE
,
2319 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2320 objc_ivar_list_ptr
= build_pointer_type
2321 (xref_tag (RECORD_TYPE
,
2322 get_identifier (UTAG_IVAR_LIST
)));
2324 /* TREE_NOTHROW is cleared for the message-sending functions,
2325 because the function that gets called can throw in Obj-C++, or
2326 could itself call something that can throw even in Obj-C. */
2328 if (flag_next_runtime
)
2330 /* NB: In order to call one of the ..._stret (struct-returning)
2331 functions, the function *MUST* first be cast to a signature that
2332 corresponds to the actual ObjC method being invoked. This is
2333 what is done by the build_objc_method_call() routine below. */
2335 /* id objc_msgSend (id, SEL, ...); */
2336 /* id objc_msgSendNonNil (id, SEL, ...); */
2337 /* id objc_msgSend_stret (id, SEL, ...); */
2338 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
2340 = build_varargs_function_type_list (objc_object_type
,
2344 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
2345 type
, 0, NOT_BUILT_IN
,
2347 umsg_nonnil_decl
= add_builtin_function (TAG_MSGSEND_NONNIL
,
2348 type
, 0, NOT_BUILT_IN
,
2350 umsg_stret_decl
= add_builtin_function (TAG_MSGSEND_STRET
,
2351 type
, 0, NOT_BUILT_IN
,
2353 umsg_nonnil_stret_decl
= add_builtin_function (TAG_MSGSEND_NONNIL_STRET
,
2354 type
, 0, NOT_BUILT_IN
,
2357 /* These can throw, because the function that gets called can throw
2358 in Obj-C++, or could itself call something that can throw even
2360 TREE_NOTHROW (umsg_decl
) = 0;
2361 TREE_NOTHROW (umsg_nonnil_decl
) = 0;
2362 TREE_NOTHROW (umsg_stret_decl
) = 0;
2363 TREE_NOTHROW (umsg_nonnil_stret_decl
) = 0;
2365 /* id objc_msgSend_Fast (id, SEL, ...)
2366 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
2367 #ifdef OFFS_MSGSEND_FAST
2368 umsg_fast_decl
= add_builtin_function (TAG_MSGSEND_FAST
,
2369 type
, 0, NOT_BUILT_IN
,
2371 TREE_NOTHROW (umsg_fast_decl
) = 0;
2372 DECL_ATTRIBUTES (umsg_fast_decl
)
2373 = tree_cons (get_identifier ("hard_coded_address"),
2374 build_int_cst (NULL_TREE
, OFFS_MSGSEND_FAST
),
2377 /* No direct dispatch available. */
2378 umsg_fast_decl
= umsg_decl
;
2381 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
2382 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
2384 = build_varargs_function_type_list (objc_object_type
,
2388 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
2389 type
, 0, NOT_BUILT_IN
,
2391 umsg_super_stret_decl
= add_builtin_function (TAG_MSGSENDSUPER_STRET
,
2392 type
, 0, NOT_BUILT_IN
, 0,
2394 TREE_NOTHROW (umsg_super_decl
) = 0;
2395 TREE_NOTHROW (umsg_super_stret_decl
) = 0;
2399 /* GNU runtime messenger entry points. */
2401 /* typedef id (*IMP)(id, SEL, ...); */
2403 build_varargs_function_type_list (objc_object_type
,
2407 tree IMP_type
= build_pointer_type (ftype
);
2409 /* IMP objc_msg_lookup (id, SEL); */
2410 type
= build_function_type_list (IMP_type
,
2414 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
2415 type
, 0, NOT_BUILT_IN
,
2417 TREE_NOTHROW (umsg_decl
) = 0;
2419 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
2421 = build_function_type_list (IMP_type
,
2425 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
2426 type
, 0, NOT_BUILT_IN
,
2428 TREE_NOTHROW (umsg_super_decl
) = 0;
2430 /* The following GNU runtime entry point is called to initialize
2433 __objc_exec_class (void *); */
2435 = build_function_type_list (void_type_node
,
2438 execclass_decl
= add_builtin_function (TAG_EXECCLASS
,
2439 type
, 0, NOT_BUILT_IN
,
2443 /* id objc_getClass (const char *); */
2445 type
= build_function_type_list (objc_object_type
,
2446 const_string_type_node
,
2450 = add_builtin_function (TAG_GETCLASS
, type
, 0, NOT_BUILT_IN
,
2453 /* id objc_getMetaClass (const char *); */
2455 objc_get_meta_class_decl
2456 = add_builtin_function (TAG_GETMETACLASS
, type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
2458 build_class_template ();
2459 build_super_template ();
2460 build_protocol_template ();
2461 build_category_template ();
2462 build_objc_exception_stuff ();
2464 if (flag_next_runtime
)
2465 build_next_objc_exception_stuff ();
2467 /* static SEL _OBJC_SELECTOR_TABLE[]; */
2469 if (! flag_next_runtime
)
2470 build_selector_table_decl ();
2472 /* Forward declare constant_string_id and constant_string_type. */
2473 if (!constant_string_class_name
)
2474 constant_string_class_name
= default_constant_string_class_name
;
2476 constant_string_id
= get_identifier (constant_string_class_name
);
2477 objc_declare_class (tree_cons (NULL_TREE
, constant_string_id
, NULL_TREE
));
2479 /* Pre-build the following entities - for speed/convenience. */
2480 self_id
= get_identifier ("self");
2481 ucmd_id
= get_identifier ("_cmd");
2483 /* Declare struct _objc_fast_enumeration_state { ... }; */
2484 build_fast_enumeration_state_template ();
2486 /* void objc_enumeration_mutation (id) */
2487 type
= build_function_type (void_type_node
,
2488 tree_cons (NULL_TREE
, objc_object_type
, NULL_TREE
));
2489 objc_enumeration_mutation_decl
2490 = add_builtin_function (TAG_ENUMERATION_MUTATION
, type
, 0, NOT_BUILT_IN
,
2492 TREE_NOTHROW (objc_enumeration_mutation_decl
) = 0;
2495 pop_lang_context ();
2498 write_symbols
= save_write_symbols
;
2499 debug_hooks
= save_hooks
;
2502 /* Ensure that the ivar list for NSConstantString/NXConstantString
2503 (or whatever was specified via `-fconstant-string-class')
2504 contains fields at least as large as the following three, so that
2505 the runtime can stomp on them with confidence:
2507 struct STRING_OBJECT_CLASS_NAME
2511 unsigned int length;
2515 check_string_class_template (void)
2517 tree field_decl
= objc_get_class_ivars (constant_string_id
);
2519 #define AT_LEAST_AS_LARGE_AS(F, T) \
2520 (F && TREE_CODE (F) == FIELD_DECL \
2521 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
2522 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
2524 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
2527 field_decl
= DECL_CHAIN (field_decl
);
2528 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
2531 field_decl
= DECL_CHAIN (field_decl
);
2532 return AT_LEAST_AS_LARGE_AS (field_decl
, unsigned_type_node
);
2534 #undef AT_LEAST_AS_LARGE_AS
2537 /* Avoid calling `check_string_class_template ()' more than once. */
2538 static GTY(()) int string_layout_checked
;
2540 /* Construct an internal string layout to be used as a template for
2541 creating NSConstantString/NXConstantString instances. */
2544 objc_build_internal_const_str_type (void)
2546 tree type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
2547 tree fields
= build_decl (input_location
,
2548 FIELD_DECL
, NULL_TREE
, ptr_type_node
);
2549 tree field
= build_decl (input_location
,
2550 FIELD_DECL
, NULL_TREE
, ptr_type_node
);
2552 DECL_CHAIN (field
) = fields
; fields
= field
;
2553 field
= build_decl (input_location
,
2554 FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
2555 DECL_CHAIN (field
) = fields
; fields
= field
;
2556 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
2558 finish_builtin_struct (type
, "__builtin_ObjCString",
2564 /* Custom build_string which sets TREE_TYPE! */
2567 my_build_string (int len
, const char *str
)
2569 return fix_string_type (build_string (len
, str
));
2572 /* Build a string with contents STR and length LEN and convert it to a
2576 my_build_string_pointer (int len
, const char *str
)
2578 tree string
= my_build_string (len
, str
);
2579 tree ptrtype
= build_pointer_type (TREE_TYPE (TREE_TYPE (string
)));
2580 return build1 (ADDR_EXPR
, ptrtype
, string
);
2584 string_hash (const void *ptr
)
2586 const_tree
const str
= ((const struct string_descriptor
*)ptr
)->literal
;
2587 const unsigned char *p
= (const unsigned char *) TREE_STRING_POINTER (str
);
2588 int i
, len
= TREE_STRING_LENGTH (str
);
2591 for (i
= 0; i
< len
; i
++)
2592 h
= ((h
* 613) + p
[i
]);
2598 string_eq (const void *ptr1
, const void *ptr2
)
2600 const_tree
const str1
= ((const struct string_descriptor
*)ptr1
)->literal
;
2601 const_tree
const str2
= ((const struct string_descriptor
*)ptr2
)->literal
;
2602 int len1
= TREE_STRING_LENGTH (str1
);
2604 return (len1
== TREE_STRING_LENGTH (str2
)
2605 && !memcmp (TREE_STRING_POINTER (str1
), TREE_STRING_POINTER (str2
),
2609 /* Given a chain of STRING_CST's, build a static instance of
2610 NXConstantString which points at the concatenation of those
2611 strings. We place the string object in the __string_objects
2612 section of the __OBJC segment. The Objective-C runtime will
2613 initialize the isa pointers of the string objects to point at the
2614 NXConstantString class object. */
2617 objc_build_string_object (tree string
)
2619 tree constant_string_class
;
2622 struct string_descriptor
*desc
, key
;
2625 /* Prep the string argument. */
2626 string
= fix_string_type (string
);
2627 TREE_SET_CODE (string
, STRING_CST
);
2628 length
= TREE_STRING_LENGTH (string
) - 1;
2630 /* The target may have different ideas on how to construct an ObjC string
2631 literal. On Darwin (Mac OS X), for example, we may wish to obtain a
2632 constant CFString reference instead.
2633 At present, this is only supported for the NeXT runtime. */
2634 if (flag_next_runtime
&& targetcm
.objc_construct_string
)
2636 tree constructor
= (*targetcm
.objc_construct_string
) (string
);
2638 return build1 (NOP_EXPR
, objc_object_type
, constructor
);
2641 /* Check whether the string class being used actually exists and has the
2642 correct ivar layout. */
2643 if (!string_layout_checked
)
2645 string_layout_checked
= -1;
2646 constant_string_class
= lookup_interface (constant_string_id
);
2647 internal_const_str_type
= objc_build_internal_const_str_type ();
2649 if (!constant_string_class
2650 || !(constant_string_type
2651 = CLASS_STATIC_TEMPLATE (constant_string_class
)))
2652 error ("cannot find interface declaration for %qE",
2653 constant_string_id
);
2654 /* The NSConstantString/NXConstantString ivar layout is now known. */
2655 else if (!check_string_class_template ())
2656 error ("interface %qE does not have valid constant string layout",
2657 constant_string_id
);
2658 /* For the NeXT runtime, we can generate a literal reference
2659 to the string class, don't need to run a constructor. */
2660 else if (flag_next_runtime
&& !setup_string_decl ())
2661 error ("cannot find reference tag for class %qE",
2662 constant_string_id
);
2665 string_layout_checked
= 1; /* Success! */
2666 add_class_reference (constant_string_id
);
2670 if (string_layout_checked
== -1)
2671 return error_mark_node
;
2673 /* Perhaps we already constructed a constant string just like this one? */
2674 key
.literal
= string
;
2675 loc
= htab_find_slot (string_htab
, &key
, INSERT
);
2676 desc
= (struct string_descriptor
*) *loc
;
2680 tree var
, constructor
;
2681 VEC(constructor_elt
,gc
) *v
= NULL
;
2682 *loc
= desc
= ggc_alloc_string_descriptor ();
2683 desc
->literal
= string
;
2685 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
2686 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
2687 fields
= TYPE_FIELDS (internal_const_str_type
);
2688 CONSTRUCTOR_APPEND_ELT (v
, fields
,
2690 ? build_unary_op (input_location
,
2691 ADDR_EXPR
, string_class_decl
, 0)
2692 : build_int_cst (NULL_TREE
, 0));
2693 fields
= DECL_CHAIN (fields
);
2694 CONSTRUCTOR_APPEND_ELT (v
, fields
,
2695 build_unary_op (input_location
,
2696 ADDR_EXPR
, string
, 1));
2697 fields
= DECL_CHAIN (fields
);
2698 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_int_cst (NULL_TREE
, length
));
2699 constructor
= objc_build_constructor (internal_const_str_type
, v
);
2701 if (!flag_next_runtime
)
2703 = objc_add_static_instance (constructor
, constant_string_type
);
2706 var
= build_decl (input_location
,
2707 CONST_DECL
, NULL
, TREE_TYPE (constructor
));
2708 DECL_INITIAL (var
) = constructor
;
2709 TREE_STATIC (var
) = 1;
2710 pushdecl_top_level (var
);
2713 desc
->constructor
= constructor
;
2716 addr
= convert (build_pointer_type (constant_string_type
),
2717 build_unary_op (input_location
,
2718 ADDR_EXPR
, desc
->constructor
, 1));
2723 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
2725 static GTY(()) int num_static_inst
;
2728 objc_add_static_instance (tree constructor
, tree class_decl
)
2733 /* Find the list of static instances for the CLASS_DECL. Create one if
2735 for (chain
= &objc_static_instances
;
2736 *chain
&& TREE_VALUE (*chain
) != class_decl
;
2737 chain
= &TREE_CHAIN (*chain
));
2740 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
2741 add_objc_string (OBJC_TYPE_NAME (class_decl
), class_names
);
2744 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
2745 decl
= build_decl (input_location
,
2746 VAR_DECL
, get_identifier (buf
), class_decl
);
2747 TREE_STATIC (decl
) = 1;
2748 DECL_ARTIFICIAL (decl
) = 1;
2749 TREE_USED (decl
) = 1;
2750 DECL_INITIAL (decl
) = constructor
;
2752 /* We may be writing something else just now.
2753 Postpone till end of input. */
2754 DECL_DEFER_OUTPUT (decl
) = 1;
2755 pushdecl_top_level (decl
);
2756 rest_of_decl_compilation (decl
, 1, 0);
2758 /* Add the DECL to the head of this CLASS' list. */
2759 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
2764 /* Build a static constant CONSTRUCTOR
2765 with type TYPE and elements ELTS. */
2768 objc_build_constructor (tree type
, VEC(constructor_elt
,gc
) *elts
)
2770 tree constructor
= build_constructor (type
, elts
);
2772 TREE_CONSTANT (constructor
) = 1;
2773 TREE_STATIC (constructor
) = 1;
2774 TREE_READONLY (constructor
) = 1;
2777 /* Adjust for impedance mismatch. We should figure out how to build
2778 CONSTRUCTORs that consistently please both the C and C++ gods. */
2779 if (!VEC_index (constructor_elt
, elts
, 0)->index
)
2780 TREE_TYPE (constructor
) = init_list_type_node
;
2786 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2788 /* Predefine the following data type:
2796 void *defs[cls_def_cnt + cat_def_cnt];
2800 build_objc_symtab_template (void)
2802 tree fields
, *chain
= NULL
;
2804 objc_symtab_template
= objc_start_struct (get_identifier (UTAG_SYMTAB
));
2806 /* long sel_ref_cnt; */
2807 fields
= add_field_decl (long_integer_type_node
, "sel_ref_cnt", &chain
);
2810 add_field_decl (build_pointer_type (objc_selector_type
), "refs", &chain
);
2812 /* short cls_def_cnt; */
2813 add_field_decl (short_integer_type_node
, "cls_def_cnt", &chain
);
2815 /* short cat_def_cnt; */
2816 add_field_decl (short_integer_type_node
, "cat_def_cnt", &chain
);
2818 if (imp_count
|| cat_count
|| !flag_next_runtime
)
2820 /* void *defs[imp_count + cat_count (+ 1)]; */
2821 /* NB: The index is one less than the size of the array. */
2822 int index
= imp_count
+ cat_count
+ (flag_next_runtime
? -1: 0);
2823 tree array_type
= build_sized_array_type (ptr_type_node
, index
+ 1);
2824 add_field_decl (array_type
, "defs", &chain
);
2827 objc_finish_struct (objc_symtab_template
, fields
);
2830 /* Create the initial value for the `defs' field of _objc_symtab.
2831 This is a CONSTRUCTOR. */
2834 init_def_list (tree type
)
2837 struct imp_entry
*impent
;
2838 VEC(constructor_elt
,gc
) *v
= NULL
;
2841 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2843 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
2845 expr
= build_unary_op (input_location
,
2846 ADDR_EXPR
, impent
->class_decl
, 0);
2847 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2852 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2854 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
2856 expr
= build_unary_op (input_location
,
2857 ADDR_EXPR
, impent
->class_decl
, 0);
2858 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2862 if (!flag_next_runtime
)
2864 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2865 if (static_instances_decl
)
2866 expr
= build_unary_op (input_location
,
2867 ADDR_EXPR
, static_instances_decl
, 0);
2869 expr
= integer_zero_node
;
2871 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2874 return objc_build_constructor (type
, v
);
2877 /* Construct the initial value for all of _objc_symtab. */
2880 init_objc_symtab (tree type
)
2882 VEC(constructor_elt
,gc
) *v
= NULL
;
2884 /* sel_ref_cnt = { ..., 5, ... } */
2886 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2887 build_int_cst (long_integer_type_node
, 0));
2889 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2891 if (flag_next_runtime
|| ! sel_ref_chain
)
2892 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, convert (
2893 build_pointer_type (objc_selector_type
),
2894 integer_zero_node
));
2897 tree expr
= build_unary_op (input_location
, ADDR_EXPR
,
2898 UOBJC_SELECTOR_TABLE_decl
, 1);
2900 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2901 convert (build_pointer_type (objc_selector_type
),
2905 /* cls_def_cnt = { ..., 5, ... } */
2907 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2908 build_int_cst (short_integer_type_node
, imp_count
));
2910 /* cat_def_cnt = { ..., 5, ... } */
2912 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2913 build_int_cst (short_integer_type_node
, cat_count
));
2915 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2917 if (imp_count
|| cat_count
|| !flag_next_runtime
)
2920 tree field
= TYPE_FIELDS (type
);
2921 field
= DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field
))));
2923 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, init_def_list (TREE_TYPE (field
)));
2926 return objc_build_constructor (type
, v
);
2929 /* Generate forward declarations for metadata such as
2930 'OBJC_CLASS_...'. */
2933 build_metadata_decl (const char *name
, tree type
)
2937 /* struct TYPE NAME_<name>; */
2938 decl
= start_var_decl (type
, synth_id_with_class_suffix
2940 objc_implementation_context
));
2945 /* Push forward-declarations of all the categories so that
2946 init_def_list can use them in a CONSTRUCTOR. */
2949 forward_declare_categories (void)
2951 struct imp_entry
*impent
;
2952 tree sav
= objc_implementation_context
;
2954 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2956 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
2958 /* Set an invisible arg to synth_id_with_class_suffix. */
2959 objc_implementation_context
= impent
->imp_context
;
2960 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2961 impent
->class_decl
= build_metadata_decl ("_OBJC_CATEGORY",
2962 objc_category_template
);
2965 objc_implementation_context
= sav
;
2968 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2969 and initialized appropriately. */
2972 generate_objc_symtab_decl (void)
2975 build_objc_symtab_template ();
2976 UOBJC_SYMBOLS_decl
= start_var_decl (objc_symtab_template
, "_OBJC_SYMBOLS");
2977 finish_var_decl (UOBJC_SYMBOLS_decl
,
2978 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)));
2982 init_module_descriptor (tree type
)
2985 VEC(constructor_elt
,gc
) *v
= NULL
;
2987 /* version = { 1, ... } */
2989 expr
= build_int_cst (long_integer_type_node
, OBJC_VERSION
);
2990 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2992 /* size = { ..., sizeof (struct _objc_module), ... } */
2994 expr
= convert (long_integer_type_node
,
2995 size_in_bytes (objc_module_template
));
2996 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2998 /* Don't provide any file name for security reasons. */
2999 /* name = { ..., "", ... } */
3001 expr
= add_objc_string (get_identifier (""), class_names
);
3002 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
3004 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
3006 if (UOBJC_SYMBOLS_decl
)
3007 expr
= build_unary_op (input_location
,
3008 ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
3010 expr
= null_pointer_node
;
3011 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
3013 return objc_build_constructor (type
, v
);
3016 /* Write out the data structures to describe Objective C classes defined.
3018 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
3021 build_module_descriptor (void)
3023 tree decls
, *chain
= NULL
;
3026 push_lang_context (lang_name_c
); /* extern "C" */
3029 objc_module_template
= objc_start_struct (get_identifier (UTAG_MODULE
));
3032 decls
= add_field_decl (long_integer_type_node
, "version", &chain
);
3035 add_field_decl (long_integer_type_node
, "size", &chain
);
3038 add_field_decl (string_type_node
, "name", &chain
);
3040 /* struct _objc_symtab *symtab; */
3041 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE
,
3042 get_identifier (UTAG_SYMTAB
))),
3045 objc_finish_struct (objc_module_template
, decls
);
3047 /* Create an instance of "_objc_module". */
3048 UOBJC_MODULES_decl
= start_var_decl (objc_module_template
, "_OBJC_MODULES");
3049 /* This is the root of the metadata for defined classes and categories, it
3050 is referenced by the runtime and, therefore, needed. */
3051 DECL_PRESERVE_P (UOBJC_MODULES_decl
) = 1;
3052 finish_var_decl (UOBJC_MODULES_decl
,
3053 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)));
3056 pop_lang_context ();
3060 /* The GNU runtime requires us to provide a static initializer function
3063 static void __objc_gnu_init (void) {
3064 __objc_exec_class (&L_OBJC_MODULES);
3068 build_module_initializer_routine (void)
3073 push_lang_context (lang_name_c
); /* extern "C" */
3076 objc_push_parm (build_decl (input_location
,
3077 PARM_DECL
, NULL_TREE
, void_type_node
));
3079 objc_start_function (get_identifier (TAG_GNUINIT
),
3080 build_function_type_list (void_type_node
, NULL_TREE
),
3081 NULL_TREE
, NULL_TREE
);
3083 objc_start_function (get_identifier (TAG_GNUINIT
),
3084 build_function_type_list (void_type_node
, NULL_TREE
),
3085 NULL_TREE
, objc_get_parm_info (0));
3087 body
= c_begin_compound_stmt (true);
3088 add_stmt (build_function_call
3093 build_unary_op (input_location
, ADDR_EXPR
,
3094 UOBJC_MODULES_decl
, 0))));
3095 add_stmt (c_end_compound_stmt (input_location
, body
, true));
3097 TREE_PUBLIC (current_function_decl
) = 0;
3100 /* For Objective-C++, we will need to call __objc_gnu_init
3101 from objc_generate_static_init_call() below. */
3102 DECL_STATIC_CONSTRUCTOR (current_function_decl
) = 1;
3105 GNU_INIT_decl
= current_function_decl
;
3109 pop_lang_context ();
3114 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
3115 to be called by the module initializer routine. */
3118 objc_static_init_needed_p (void)
3120 return (GNU_INIT_decl
!= NULL_TREE
);
3123 /* Generate a call to the __objc_gnu_init initializer function. */
3126 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED
)
3128 add_stmt (build_stmt (input_location
, EXPR_STMT
,
3129 build_function_call (input_location
,
3130 GNU_INIT_decl
, NULL_TREE
)));
3134 #endif /* OBJCPLUS */
3136 /* Return the DECL of the string IDENT in the SECTION. */
3139 get_objc_string_decl (tree ident
, enum string_section section
)
3146 chain
= class_names_chain
;
3148 case meth_var_names
:
3149 chain
= meth_var_names_chain
;
3151 case meth_var_types
:
3152 chain
= meth_var_types_chain
;
3158 for (; chain
!= 0; chain
= TREE_CHAIN (chain
))
3159 if (TREE_VALUE (chain
) == ident
)
3160 return (TREE_PURPOSE (chain
));
3166 /* Output references to all statically allocated objects. Return the DECL
3167 for the array built. */
3170 generate_static_references (void)
3172 tree expr
= NULL_TREE
;
3173 tree class_name
, klass
, decl
;
3174 tree cl_chain
, in_chain
, type
3175 = build_array_type (build_pointer_type (void_type_node
), NULL_TREE
);
3176 int num_inst
, num_class
;
3178 VEC(constructor_elt
,gc
) *decls
= NULL
;
3180 if (flag_next_runtime
)
3183 for (cl_chain
= objc_static_instances
, num_class
= 0;
3184 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
3186 VEC(constructor_elt
,gc
) *v
= NULL
;
3188 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
3189 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
3191 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
3192 decl
= start_var_decl (type
, buf
);
3194 /* Output {class_name, ...}. */
3195 klass
= TREE_VALUE (cl_chain
);
3196 class_name
= get_objc_string_decl (OBJC_TYPE_NAME (klass
), class_names
);
3197 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
3198 build_unary_op (input_location
,
3199 ADDR_EXPR
, class_name
, 1));
3201 /* Output {..., instance, ...}. */
3202 for (in_chain
= TREE_PURPOSE (cl_chain
);
3203 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
3205 expr
= build_unary_op (input_location
,
3206 ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
3207 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
3210 /* Output {..., NULL}. */
3211 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
3213 expr
= objc_build_constructor (TREE_TYPE (decl
), v
);
3214 finish_var_decl (decl
, expr
);
3215 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
,
3216 build_unary_op (input_location
,
3217 ADDR_EXPR
, decl
, 1));
3220 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
3221 expr
= objc_build_constructor (type
, decls
);
3222 static_instances_decl
= start_var_decl (type
, "_OBJC_STATIC_INSTANCES");
3223 finish_var_decl (static_instances_decl
, expr
);
3226 static GTY(()) int selector_reference_idx
;
3229 build_selector_reference_decl (void)
3234 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx
++);
3235 decl
= start_var_decl (objc_selector_type
, buf
);
3241 build_selector_table_decl (void)
3245 if (flag_typed_selectors
)
3247 build_selector_template ();
3248 temp
= build_array_type (objc_selector_template
, NULL_TREE
);
3251 temp
= build_array_type (objc_selector_type
, NULL_TREE
);
3253 UOBJC_SELECTOR_TABLE_decl
= start_var_decl (temp
, "_OBJC_SELECTOR_TABLE");
3256 /* Just a handy wrapper for add_objc_string. */
3259 build_selector (tree ident
)
3261 return convert (objc_selector_type
,
3262 add_objc_string (ident
, meth_var_names
));
3265 /* Used only by build_*_selector_translation_table (). */
3267 diagnose_missing_method (tree meth
, location_t here
)
3271 for (method_chain
= meth_var_names_chain
;
3273 method_chain
= TREE_CHAIN (method_chain
))
3275 if (TREE_VALUE (method_chain
) == meth
)
3283 warning_at (here
, 0, "creating selector for nonexistent method %qE",
3288 build_next_selector_translation_table (void)
3291 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
3294 tree decl
= TREE_PURPOSE (chain
);
3295 if (warn_selector
&& objc_implementation_context
)
3299 loc
= DECL_SOURCE_LOCATION (decl
);
3301 loc
= input_location
;
3302 diagnose_missing_method (TREE_VALUE (chain
), loc
);
3305 expr
= build_selector (TREE_VALUE (chain
));
3309 /* Entries of this form are used for references to methods.
3310 The runtime re-writes these on start-up, but the compiler can't see
3311 that and optimizes it away unless we force it. */
3312 DECL_PRESERVE_P (decl
) = 1;
3313 finish_var_decl (decl
, expr
);
3319 build_gnu_selector_translation_table (void)
3323 tree decl = NULL_TREE;*/
3324 VEC(constructor_elt
,gc
) *inits
= NULL
;
3326 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
3330 if (warn_selector
&& objc_implementation_context
)
3331 diagnose_missing_method (TREE_VALUE (chain
), input_location
);
3333 expr
= build_selector (TREE_VALUE (chain
));
3334 /* add one for the '\0' character
3335 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
3338 if (flag_typed_selectors
)
3340 VEC(constructor_elt
,gc
) *v
= NULL
;
3341 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
3342 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
3343 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, encoding
);
3344 expr
= objc_build_constructor (objc_selector_template
, v
);
3347 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
3349 } /* each element in the chain */
3352 /* Cause the selector table (previously forward-declared)
3353 to be actually output. */
3356 if (flag_typed_selectors
)
3358 VEC(constructor_elt
,gc
) *v
= NULL
;
3359 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
3360 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
3361 expr
= objc_build_constructor (objc_selector_template
, v
);
3364 expr
= integer_zero_node
;
3366 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
3367 expr
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
3369 finish_var_decl (UOBJC_SELECTOR_TABLE_decl
, expr
);
3374 get_proto_encoding (tree proto
)
3379 if (! METHOD_ENCODING (proto
))
3381 encoding
= encode_method_prototype (proto
);
3382 METHOD_ENCODING (proto
) = encoding
;
3385 encoding
= METHOD_ENCODING (proto
);
3387 return add_objc_string (encoding
, meth_var_types
);
3390 return build_int_cst (NULL_TREE
, 0);
3393 /* sel_ref_chain is a list whose "value" fields will be instances of
3394 identifier_node that represent the selector. LOC is the location of
3398 build_typed_selector_reference (location_t loc
, tree ident
, tree prototype
)
3400 tree
*chain
= &sel_ref_chain
;
3406 if (TREE_PURPOSE (*chain
) == prototype
&& TREE_VALUE (*chain
) == ident
)
3407 goto return_at_index
;
3410 chain
= &TREE_CHAIN (*chain
);
3413 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
3416 expr
= build_unary_op (loc
, ADDR_EXPR
,
3417 build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
3418 build_int_cst (NULL_TREE
, index
)),
3420 return convert (objc_selector_type
, expr
);
3424 build_selector_reference (location_t loc
, tree ident
)
3426 tree
*chain
= &sel_ref_chain
;
3432 if (TREE_VALUE (*chain
) == ident
)
3433 return (flag_next_runtime
3434 ? TREE_PURPOSE (*chain
)
3435 : build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
3436 build_int_cst (NULL_TREE
, index
)));
3439 chain
= &TREE_CHAIN (*chain
);
3442 expr
= (flag_next_runtime
? build_selector_reference_decl (): NULL_TREE
);
3444 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
3446 return (flag_next_runtime
3448 : build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
3449 build_int_cst (NULL_TREE
, index
)));
3452 static GTY(()) int class_reference_idx
;
3455 build_class_reference_decl (void)
3460 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx
++);
3461 decl
= start_var_decl (objc_class_type
, buf
);
3466 /* Create a class reference, but don't create a variable to reference
3470 add_class_reference (tree ident
)
3474 if ((chain
= cls_ref_chain
))
3479 if (ident
== TREE_VALUE (chain
))
3483 chain
= TREE_CHAIN (chain
);
3487 /* Append to the end of the list */
3488 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
3491 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
3494 /* Get a class reference, creating it if necessary. Also create the
3495 reference variable. */
3498 objc_get_class_reference (tree ident
)
3500 tree orig_ident
= (DECL_P (ident
)
3503 ? OBJC_TYPE_NAME (ident
)
3505 bool local_scope
= false;
3508 if (processing_template_decl
)
3509 /* Must wait until template instantiation time. */
3510 return build_min_nt (CLASS_REFERENCE_EXPR
, ident
);
3513 if (TREE_CODE (ident
) == TYPE_DECL
)
3514 ident
= (DECL_ORIGINAL_TYPE (ident
)
3515 ? DECL_ORIGINAL_TYPE (ident
)
3516 : TREE_TYPE (ident
));
3520 && CP_TYPE_CONTEXT (ident
) != global_namespace
)
3524 if (local_scope
|| !(ident
= objc_is_class_name (ident
)))
3526 error ("%qE is not an Objective-C class name or alias",
3528 return error_mark_node
;
3531 if (flag_next_runtime
&& !flag_zero_link
)
3536 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
3537 if (TREE_VALUE (*chain
) == ident
)
3539 if (! TREE_PURPOSE (*chain
))
3540 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
3542 return TREE_PURPOSE (*chain
);
3545 decl
= build_class_reference_decl ();
3546 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
3553 add_class_reference (ident
);
3555 params
= build_tree_list (NULL_TREE
,
3556 my_build_string_pointer
3557 (IDENTIFIER_LENGTH (ident
) + 1,
3558 IDENTIFIER_POINTER (ident
)));
3560 assemble_external (objc_get_class_decl
);
3561 return build_function_call (input_location
, objc_get_class_decl
, params
);
3565 /* For each string section we have a chain which maps identifier nodes
3566 to decls for the strings. */
3568 static GTY(()) int class_names_idx
;
3569 static GTY(()) int meth_var_names_idx
;
3570 static GTY(()) int meth_var_types_idx
;
3573 add_objc_string (tree ident
, enum string_section section
)
3575 tree
*chain
, decl
, type
, string_expr
;
3582 chain
= &class_names_chain
;
3583 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
3585 case meth_var_names
:
3586 chain
= &meth_var_names_chain
;
3587 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
3589 case meth_var_types
:
3590 chain
= &meth_var_types_chain
;
3591 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
3599 if (TREE_VALUE (*chain
) == ident
)
3600 return convert (string_type_node
,
3601 build_unary_op (input_location
,
3602 ADDR_EXPR
, TREE_PURPOSE (*chain
), 1));
3604 chain
= &TREE_CHAIN (*chain
);
3607 type
= build_sized_array_type (char_type_node
, IDENTIFIER_LENGTH (ident
) + 1);
3608 decl
= start_var_decl (type
, buf
);
3609 string_expr
= my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
3610 IDENTIFIER_POINTER (ident
));
3611 TREE_CONSTANT (decl
) = 1;
3612 finish_var_decl (decl
, string_expr
);
3614 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
3616 return convert (string_type_node
, build_unary_op (input_location
,
3617 ADDR_EXPR
, decl
, 1));
3621 objc_declare_alias (tree alias_ident
, tree class_ident
)
3623 tree underlying_class
;
3626 if (current_namespace
!= global_namespace
) {
3627 error ("Objective-C declarations may only appear in global scope");
3629 #endif /* OBJCPLUS */
3631 if (!(underlying_class
= objc_is_class_name (class_ident
)))
3632 warning (0, "cannot find class %qE", class_ident
);
3633 else if (objc_is_class_name (alias_ident
))
3634 warning (0, "class %qE already exists", alias_ident
);
3637 /* Implement @compatibility_alias as a typedef. */
3639 push_lang_context (lang_name_c
); /* extern "C" */
3641 lang_hooks
.decls
.pushdecl (build_decl
3645 xref_tag (RECORD_TYPE
, underlying_class
)));
3647 pop_lang_context ();
3649 hash_class_name_enter (als_name_hash_list
, alias_ident
,
3655 objc_declare_class (tree ident_list
)
3659 if (current_namespace
!= global_namespace
) {
3660 error ("Objective-C declarations may only appear in global scope");
3662 #endif /* OBJCPLUS */
3664 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
3666 tree ident
= TREE_VALUE (list
);
3668 if (! objc_is_class_name (ident
))
3670 tree record
= lookup_name (ident
), type
= record
;
3674 if (TREE_CODE (record
) == TYPE_DECL
)
3675 type
= DECL_ORIGINAL_TYPE (record
) ?
3676 DECL_ORIGINAL_TYPE (record
) :
3679 if (!TYPE_HAS_OBJC_INFO (type
)
3680 || !TYPE_OBJC_INTERFACE (type
))
3682 error ("%qE redeclared as different kind of symbol",
3684 error ("previous declaration of %q+D",
3689 record
= xref_tag (RECORD_TYPE
, ident
);
3690 INIT_TYPE_OBJC_INFO (record
);
3691 TYPE_OBJC_INTERFACE (record
) = ident
;
3692 hash_class_name_enter (cls_name_hash_list
, ident
, NULL_TREE
);
3698 objc_is_class_name (tree ident
)
3702 if (ident
&& TREE_CODE (ident
) == IDENTIFIER_NODE
3703 && identifier_global_value (ident
))
3704 ident
= identifier_global_value (ident
);
3705 while (ident
&& TREE_CODE (ident
) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (ident
))
3706 ident
= OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident
));
3708 if (ident
&& TREE_CODE (ident
) == RECORD_TYPE
)
3709 ident
= OBJC_TYPE_NAME (ident
);
3711 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
3713 tree type
= TREE_TYPE (ident
);
3714 if (type
&& TREE_CODE (type
) == TEMPLATE_TYPE_PARM
)
3716 ident
= DECL_NAME (ident
);
3719 if (!ident
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
3722 if (lookup_interface (ident
))
3725 target
= hash_class_name_lookup (cls_name_hash_list
, ident
);
3729 target
= hash_class_name_lookup (als_name_hash_list
, ident
);
3732 gcc_assert (target
->list
&& target
->list
->value
);
3733 return target
->list
->value
;
3739 /* Check whether TYPE is either 'id' or 'Class'. */
3742 objc_is_id (tree type
)
3744 if (type
&& TREE_CODE (type
) == IDENTIFIER_NODE
3745 && identifier_global_value (type
))
3746 type
= identifier_global_value (type
);
3748 if (type
&& TREE_CODE (type
) == TYPE_DECL
)
3749 type
= TREE_TYPE (type
);
3751 /* NB: This function may be called before the ObjC front-end has
3752 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3753 return (objc_object_type
&& type
3754 && (IS_ID (type
) || IS_CLASS (type
) || IS_SUPER (type
))
3759 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3760 class instance. This is needed by other parts of the compiler to
3761 handle ObjC types gracefully. */
3764 objc_is_object_ptr (tree type
)
3768 type
= TYPE_MAIN_VARIANT (type
);
3769 if (!POINTER_TYPE_P (type
))
3772 ret
= objc_is_id (type
);
3774 ret
= objc_is_class_name (TREE_TYPE (type
));
3780 objc_is_gcable_type (tree type
, int or_strong_p
)
3786 if (objc_is_id (TYPE_MAIN_VARIANT (type
)))
3788 if (or_strong_p
&& lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type
)))
3790 if (TREE_CODE (type
) != POINTER_TYPE
&& TREE_CODE (type
) != INDIRECT_REF
)
3792 type
= TREE_TYPE (type
);
3793 if (TREE_CODE (type
) != RECORD_TYPE
)
3795 name
= TYPE_NAME (type
);
3796 return (objc_is_class_name (name
) != NULL_TREE
);
3800 objc_substitute_decl (tree expr
, tree oldexpr
, tree newexpr
)
3802 if (expr
== oldexpr
)
3805 switch (TREE_CODE (expr
))
3808 return objc_build_component_ref
3809 (objc_substitute_decl (TREE_OPERAND (expr
, 0),
3812 DECL_NAME (TREE_OPERAND (expr
, 1)));
3814 return build_array_ref (input_location
,
3815 objc_substitute_decl (TREE_OPERAND (expr
, 0),
3818 TREE_OPERAND (expr
, 1));
3820 return build_indirect_ref (input_location
,
3821 objc_substitute_decl (TREE_OPERAND (expr
, 0),
3823 newexpr
), RO_ARROW
);
3830 objc_build_ivar_assignment (tree outervar
, tree lhs
, tree rhs
)
3833 /* The LHS parameter contains the expression 'outervar->memberspec';
3834 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3835 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3838 = objc_substitute_decl
3839 (lhs
, outervar
, convert (TREE_TYPE (outervar
), integer_zero_node
));
3841 = (flag_objc_direct_dispatch
3842 ? objc_assign_ivar_fast_decl
3843 : objc_assign_ivar_decl
);
3845 offs
= convert (integer_type_node
, build_unary_op (input_location
,
3846 ADDR_EXPR
, offs
, 0));
3848 func_params
= tree_cons (NULL_TREE
,
3849 convert (objc_object_type
, rhs
),
3850 tree_cons (NULL_TREE
, convert (objc_object_type
, outervar
),
3851 tree_cons (NULL_TREE
, offs
,
3854 assemble_external (func
);
3855 return build_function_call (input_location
, func
, func_params
);
3859 objc_build_global_assignment (tree lhs
, tree rhs
)
3861 tree func_params
= tree_cons (NULL_TREE
,
3862 convert (objc_object_type
, rhs
),
3863 tree_cons (NULL_TREE
, convert (build_pointer_type (objc_object_type
),
3864 build_unary_op (input_location
, ADDR_EXPR
, lhs
, 0)),
3867 assemble_external (objc_assign_global_decl
);
3868 return build_function_call (input_location
,
3869 objc_assign_global_decl
, func_params
);
3873 objc_build_strong_cast_assignment (tree lhs
, tree rhs
)
3875 tree func_params
= tree_cons (NULL_TREE
,
3876 convert (objc_object_type
, rhs
),
3877 tree_cons (NULL_TREE
, convert (build_pointer_type (objc_object_type
),
3878 build_unary_op (input_location
, ADDR_EXPR
, lhs
, 0)),
3881 assemble_external (objc_assign_strong_cast_decl
);
3882 return build_function_call (input_location
,
3883 objc_assign_strong_cast_decl
, func_params
);
3887 objc_is_gcable_p (tree expr
)
3889 return (TREE_CODE (expr
) == COMPONENT_REF
3890 ? objc_is_gcable_p (TREE_OPERAND (expr
, 1))
3891 : TREE_CODE (expr
) == ARRAY_REF
3892 ? (objc_is_gcable_p (TREE_TYPE (expr
))
3893 || objc_is_gcable_p (TREE_OPERAND (expr
, 0)))
3894 : TREE_CODE (expr
) == ARRAY_TYPE
3895 ? objc_is_gcable_p (TREE_TYPE (expr
))
3897 ? objc_is_gcable_type (expr
, 1)
3898 : (objc_is_gcable_p (TREE_TYPE (expr
))
3900 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr
)))));
3904 objc_is_ivar_reference_p (tree expr
)
3906 return (TREE_CODE (expr
) == ARRAY_REF
3907 ? objc_is_ivar_reference_p (TREE_OPERAND (expr
, 0))
3908 : TREE_CODE (expr
) == COMPONENT_REF
3909 ? TREE_CODE (TREE_OPERAND (expr
, 1)) == FIELD_DECL
3914 objc_is_global_reference_p (tree expr
)
3916 return (TREE_CODE (expr
) == INDIRECT_REF
|| TREE_CODE (expr
) == PLUS_EXPR
3917 ? objc_is_global_reference_p (TREE_OPERAND (expr
, 0))
3919 ? (DECL_FILE_SCOPE_P (expr
) || TREE_STATIC (expr
))
3924 objc_generate_write_barrier (tree lhs
, enum tree_code modifycode
, tree rhs
)
3926 tree result
= NULL_TREE
, outer
;
3927 int strong_cast_p
= 0, outer_gc_p
= 0, indirect_p
= 0;
3929 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3930 will have been transformed to the form '*(type *)&expr'. */
3931 if (TREE_CODE (lhs
) == INDIRECT_REF
)
3933 outer
= TREE_OPERAND (lhs
, 0);
3935 while (!strong_cast_p
3936 && (CONVERT_EXPR_P (outer
)
3937 || TREE_CODE (outer
) == NON_LVALUE_EXPR
))
3939 tree lhstype
= TREE_TYPE (outer
);
3941 /* Descend down the cast chain, and record the first objc_gc
3943 if (POINTER_TYPE_P (lhstype
))
3946 = lookup_attribute ("objc_gc",
3947 TYPE_ATTRIBUTES (TREE_TYPE (lhstype
)));
3953 outer
= TREE_OPERAND (outer
, 0);
3957 /* If we have a __strong cast, it trumps all else. */
3960 if (modifycode
!= NOP_EXPR
)
3961 goto invalid_pointer_arithmetic
;
3963 if (warn_assign_intercept
)
3964 warning (0, "strong-cast assignment has been intercepted");
3966 result
= objc_build_strong_cast_assignment (lhs
, rhs
);
3971 /* the lhs must be of a suitable type, regardless of its underlying
3973 if (!objc_is_gcable_p (lhs
))
3979 && (TREE_CODE (outer
) == COMPONENT_REF
3980 || TREE_CODE (outer
) == ARRAY_REF
))
3981 outer
= TREE_OPERAND (outer
, 0);
3983 if (TREE_CODE (outer
) == INDIRECT_REF
)
3985 outer
= TREE_OPERAND (outer
, 0);
3989 outer_gc_p
= objc_is_gcable_p (outer
);
3991 /* Handle ivar assignments. */
3992 if (objc_is_ivar_reference_p (lhs
))
3994 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3995 doesn't cut it here), the best we can do here is suggest a cast. */
3996 if (!objc_is_gcable_type (TREE_TYPE (outer
), 0))
3998 /* We may still be able to use the global write barrier... */
3999 if (!indirect_p
&& objc_is_global_reference_p (outer
))
4000 goto global_reference
;
4003 if (modifycode
== NOP_EXPR
)
4005 if (warn_assign_intercept
)
4006 warning (0, "strong-cast may possibly be needed");
4012 if (modifycode
!= NOP_EXPR
)
4013 goto invalid_pointer_arithmetic
;
4015 if (warn_assign_intercept
)
4016 warning (0, "instance variable assignment has been intercepted");
4018 result
= objc_build_ivar_assignment (outer
, lhs
, rhs
);
4023 /* Likewise, intercept assignment to global/static variables if their type is
4025 if (objc_is_global_reference_p (outer
))
4031 if (modifycode
!= NOP_EXPR
)
4033 invalid_pointer_arithmetic
:
4035 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
4040 if (warn_assign_intercept
)
4041 warning (0, "global/static variable assignment has been intercepted");
4043 result
= objc_build_global_assignment (lhs
, rhs
);
4046 /* In all other cases, fall back to the normal mechanism. */
4051 struct GTY(()) interface_tuple
{
4056 static GTY ((param_is (struct interface_tuple
))) htab_t interface_htab
;
4059 hash_interface (const void *p
)
4061 const struct interface_tuple
*d
= (const struct interface_tuple
*) p
;
4062 return IDENTIFIER_HASH_VALUE (d
->id
);
4066 eq_interface (const void *p1
, const void *p2
)
4068 const struct interface_tuple
*d
= (const struct interface_tuple
*) p1
;
4073 lookup_interface (tree ident
)
4076 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
4077 ident
= DECL_NAME (ident
);
4080 if (ident
== NULL_TREE
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
4084 struct interface_tuple
**slot
;
4089 slot
= (struct interface_tuple
**)
4090 htab_find_slot_with_hash (interface_htab
, ident
,
4091 IDENTIFIER_HASH_VALUE (ident
),
4094 i
= (*slot
)->class_name
;
4100 /* Implement @defs (<classname>) within struct bodies. */
4103 objc_get_class_ivars (tree class_name
)
4105 tree interface
= lookup_interface (class_name
);
4108 return get_class_ivars (interface
, true);
4110 error ("cannot find interface declaration for %qE",
4113 return error_mark_node
;
4116 /* Called when checking the variables in a struct. If we are not
4117 doing the ivars list inside an @interface context, then returns
4118 fieldlist unchanged. Else, returns the list of class ivars.
4121 objc_get_interface_ivars (tree fieldlist
)
4123 if (!objc_collecting_ivars
|| !objc_interface_context
4124 || TREE_CODE (objc_interface_context
) != CLASS_INTERFACE_TYPE
4125 || CLASS_SUPER_NAME (objc_interface_context
) == NULL_TREE
)
4128 return get_class_ivars (objc_interface_context
, true);
4131 /* Used by: build_private_template, continue_class,
4132 and for @defs constructs. */
4135 get_class_ivars (tree interface
, bool inherited
)
4137 tree ivar_chain
= copy_list (CLASS_RAW_IVARS (interface
));
4139 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
4140 by the current class (i.e., they do not include super-class ivars).
4141 However, the CLASS_IVARS list will be side-effected by a call to
4142 finish_struct(), which will fill in field offsets. */
4143 if (!CLASS_IVARS (interface
))
4144 CLASS_IVARS (interface
) = ivar_chain
;
4149 while (CLASS_SUPER_NAME (interface
))
4151 /* Prepend super-class ivars. */
4152 interface
= lookup_interface (CLASS_SUPER_NAME (interface
));
4153 ivar_chain
= chainon (copy_list (CLASS_RAW_IVARS (interface
)),
4160 /* Create a temporary variable of type 'type'. If 'name' is set, uses
4161 the specified name, else use no name. Returns the declaration of
4162 the type. The 'name' is mostly useful for debugging.
4165 objc_create_temporary_var (tree type
, const char *name
)
4171 decl
= build_decl (input_location
,
4172 VAR_DECL
, get_identifier (name
), type
);
4176 decl
= build_decl (input_location
,
4177 VAR_DECL
, NULL_TREE
, type
);
4179 TREE_USED (decl
) = 1;
4180 DECL_ARTIFICIAL (decl
) = 1;
4181 DECL_IGNORED_P (decl
) = 1;
4182 DECL_CONTEXT (decl
) = current_function_decl
;
4187 /* Exception handling constructs. We begin by having the parser do most
4188 of the work and passing us blocks. What we do next depends on whether
4189 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
4190 We abstract all of this in a handful of appropriately named routines. */
4192 /* Stack of open try blocks. */
4194 struct objc_try_context
4196 struct objc_try_context
*outer
;
4198 /* Statements (or statement lists) as processed by the parser. */
4202 /* Some file position locations. */
4203 location_t try_locus
;
4204 location_t end_try_locus
;
4205 location_t end_catch_locus
;
4206 location_t finally_locus
;
4207 location_t end_finally_locus
;
4209 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
4210 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
4213 /* The CATCH_EXPR of an open @catch clause. */
4216 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
4222 static struct objc_try_context
*cur_try_context
;
4224 static GTY(()) tree objc_eh_personality_decl
;
4226 /* This hook, called via lang_eh_runtime_type, generates a runtime object
4227 that represents TYPE. For Objective-C, this is just the class name. */
4228 /* ??? Isn't there a class object or some such? Is it easy to get? */
4232 objc_eh_runtime_type (tree type
)
4234 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type
)), class_names
);
4238 objc_eh_personality (void)
4240 if (!flag_objc_sjlj_exceptions
&& !objc_eh_personality_decl
)
4241 objc_eh_personality_decl
= build_personality_function ("gnu_objc");
4242 return objc_eh_personality_decl
;
4246 /* Build __builtin_eh_pointer, or the moral equivalent. In the case
4247 of Darwin, we'll arrange for it to be initialized (and associated
4248 with a binding) later. */
4251 objc_build_exc_ptr (void)
4253 if (flag_objc_sjlj_exceptions
)
4255 tree var
= cur_try_context
->caught_decl
;
4258 var
= objc_create_temporary_var (objc_object_type
, NULL
);
4259 cur_try_context
->caught_decl
= var
;
4266 t
= built_in_decls
[BUILT_IN_EH_POINTER
];
4267 t
= build_call_expr (t
, 1, integer_zero_node
);
4268 return fold_convert (objc_object_type
, t
);
4272 /* Build "objc_exception_try_exit(&_stack)". */
4275 next_sjlj_build_try_exit (void)
4278 t
= build_fold_addr_expr_loc (input_location
, cur_try_context
->stack_decl
);
4279 t
= tree_cons (NULL
, t
, NULL
);
4280 t
= build_function_call (input_location
,
4281 objc_exception_try_exit_decl
, t
);
4286 objc_exception_try_enter (&_stack);
4287 if (_setjmp(&_stack.buf))
4291 Return the COND_EXPR. Note that the THEN and ELSE fields are left
4292 empty, ready for the caller to fill them in. */
4295 next_sjlj_build_enter_and_setjmp (void)
4297 tree t
, enter
, sj
, cond
;
4299 t
= build_fold_addr_expr_loc (input_location
, cur_try_context
->stack_decl
);
4300 t
= tree_cons (NULL
, t
, NULL
);
4301 enter
= build_function_call (input_location
,
4302 objc_exception_try_enter_decl
, t
);
4304 t
= objc_build_component_ref (cur_try_context
->stack_decl
,
4305 get_identifier ("buf"));
4306 t
= build_fold_addr_expr_loc (input_location
, t
);
4308 /* Convert _setjmp argument to type that is expected. */
4309 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl
)))
4310 t
= convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl
))), t
);
4312 t
= convert (ptr_type_node
, t
);
4314 t
= convert (ptr_type_node
, t
);
4316 t
= tree_cons (NULL
, t
, NULL
);
4317 sj
= build_function_call (input_location
,
4318 objc_setjmp_decl
, t
);
4320 cond
= build2 (COMPOUND_EXPR
, TREE_TYPE (sj
), enter
, sj
);
4321 cond
= c_common_truthvalue_conversion (input_location
, cond
);
4323 return build3 (COND_EXPR
, void_type_node
, cond
, NULL
, NULL
);
4328 DECL = objc_exception_extract(&_stack); */
4331 next_sjlj_build_exc_extract (tree decl
)
4335 t
= build_fold_addr_expr_loc (input_location
, cur_try_context
->stack_decl
);
4336 t
= tree_cons (NULL
, t
, NULL
);
4337 t
= build_function_call (input_location
,
4338 objc_exception_extract_decl
, t
);
4339 t
= convert (TREE_TYPE (decl
), t
);
4340 t
= build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
4346 if (objc_exception_match(obj_get_class(TYPE), _caught)
4353 objc_exception_try_exit(&_stack);
4355 from the sequence of CATCH_EXPRs in the current try context. */
4358 next_sjlj_build_catch_list (void)
4360 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
4362 tree
*last
= &catch_seq
;
4363 bool saw_id
= false;
4365 for (; !tsi_end_p (i
); tsi_next (&i
))
4367 tree stmt
= tsi_stmt (i
);
4368 tree type
= CATCH_TYPES (stmt
);
4369 tree body
= CATCH_BODY (stmt
);
4381 if (type
== error_mark_node
)
4382 cond
= error_mark_node
;
4385 args
= tree_cons (NULL
, cur_try_context
->caught_decl
, NULL
);
4386 t
= objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type
)));
4387 args
= tree_cons (NULL
, t
, args
);
4388 t
= build_function_call (input_location
,
4389 objc_exception_match_decl
, args
);
4390 cond
= c_common_truthvalue_conversion (input_location
, t
);
4392 t
= build3 (COND_EXPR
, void_type_node
, cond
, body
, NULL
);
4393 SET_EXPR_LOCATION (t
, EXPR_LOCATION (stmt
));
4396 last
= &COND_EXPR_ELSE (t
);
4402 t
= build2 (MODIFY_EXPR
, void_type_node
, cur_try_context
->rethrow_decl
,
4403 cur_try_context
->caught_decl
);
4404 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
4405 append_to_statement_list (t
, last
);
4407 t
= next_sjlj_build_try_exit ();
4408 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
4409 append_to_statement_list (t
, last
);
4415 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
4416 exception handling. We aim to build:
4419 struct _objc_exception_data _stack;
4423 objc_exception_try_enter (&_stack);
4424 if (_setjmp(&_stack.buf))
4426 id _caught = objc_exception_extract(&_stack);
4427 objc_exception_try_enter (&_stack);
4428 if (_setjmp(&_stack.buf))
4429 _rethrow = objc_exception_extract(&_stack);
4439 objc_exception_try_exit(&_stack);
4442 objc_exception_throw(_rethrow);
4446 If CATCH-LIST is empty, we can omit all of the block containing
4447 "_caught" except for the setting of _rethrow. Note the use of
4448 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
4449 but handles goto and other exits from the block. */
4452 next_sjlj_build_try_catch_finally (void)
4454 tree rethrow_decl
, stack_decl
, t
;
4455 tree catch_seq
, try_fin
, bind
;
4457 /* Create the declarations involved. */
4458 t
= xref_tag (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
4459 stack_decl
= objc_create_temporary_var (t
, NULL
);
4460 cur_try_context
->stack_decl
= stack_decl
;
4462 rethrow_decl
= objc_create_temporary_var (objc_object_type
, NULL
);
4463 cur_try_context
->rethrow_decl
= rethrow_decl
;
4464 TREE_CHAIN (rethrow_decl
) = stack_decl
;
4466 /* Build the outermost variable binding level. */
4467 bind
= build3 (BIND_EXPR
, void_type_node
, rethrow_decl
, NULL
, NULL
);
4468 SET_EXPR_LOCATION (bind
, cur_try_context
->try_locus
);
4469 TREE_SIDE_EFFECTS (bind
) = 1;
4471 /* Initialize rethrow_decl. */
4472 t
= build2 (MODIFY_EXPR
, void_type_node
, rethrow_decl
,
4473 convert (objc_object_type
, null_pointer_node
));
4474 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
4475 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
4477 /* Build the outermost TRY_FINALLY_EXPR. */
4478 try_fin
= build2 (TRY_FINALLY_EXPR
, void_type_node
, NULL
, NULL
);
4479 SET_EXPR_LOCATION (try_fin
, cur_try_context
->try_locus
);
4480 TREE_SIDE_EFFECTS (try_fin
) = 1;
4481 append_to_statement_list (try_fin
, &BIND_EXPR_BODY (bind
));
4483 /* Create the complete catch sequence. */
4484 if (cur_try_context
->catch_list
)
4486 tree caught_decl
= objc_build_exc_ptr ();
4487 catch_seq
= build_stmt (input_location
, BIND_EXPR
, caught_decl
, NULL
, NULL
);
4488 TREE_SIDE_EFFECTS (catch_seq
) = 1;
4490 t
= next_sjlj_build_exc_extract (caught_decl
);
4491 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
4493 t
= next_sjlj_build_enter_and_setjmp ();
4494 COND_EXPR_THEN (t
) = next_sjlj_build_exc_extract (rethrow_decl
);
4495 COND_EXPR_ELSE (t
) = next_sjlj_build_catch_list ();
4496 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
4499 catch_seq
= next_sjlj_build_exc_extract (rethrow_decl
);
4500 SET_EXPR_LOCATION (catch_seq
, cur_try_context
->end_try_locus
);
4502 /* Build the main register-and-try if statement. */
4503 t
= next_sjlj_build_enter_and_setjmp ();
4504 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
4505 COND_EXPR_THEN (t
) = catch_seq
;
4506 COND_EXPR_ELSE (t
) = cur_try_context
->try_body
;
4507 TREE_OPERAND (try_fin
, 0) = t
;
4509 /* Build the complete FINALLY statement list. */
4510 t
= next_sjlj_build_try_exit ();
4511 t
= build_stmt (input_location
, COND_EXPR
,
4512 c_common_truthvalue_conversion
4513 (input_location
, rethrow_decl
),
4515 SET_EXPR_LOCATION (t
, cur_try_context
->finally_locus
);
4516 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
4518 append_to_statement_list (cur_try_context
->finally_body
,
4519 &TREE_OPERAND (try_fin
, 1));
4521 t
= tree_cons (NULL
, rethrow_decl
, NULL
);
4522 t
= build_function_call (input_location
,
4523 objc_exception_throw_decl
, t
);
4524 t
= build_stmt (input_location
, COND_EXPR
,
4525 c_common_truthvalue_conversion (input_location
,
4528 SET_EXPR_LOCATION (t
, cur_try_context
->end_finally_locus
);
4529 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
4534 /* Called just after parsing the @try and its associated BODY. We now
4535 must prepare for the tricky bits -- handling the catches and finally. */
4538 objc_begin_try_stmt (location_t try_locus
, tree body
)
4540 struct objc_try_context
*c
= XCNEW (struct objc_try_context
);
4541 c
->outer
= cur_try_context
;
4543 c
->try_locus
= try_locus
;
4544 c
->end_try_locus
= input_location
;
4545 cur_try_context
= c
;
4547 /* -fobjc-exceptions is required to enable Objective-C exceptions.
4548 For example, on Darwin, ObjC exceptions require a sufficiently
4549 recent version of the runtime, so the user must ask for them
4550 explicitly. On other platforms, at the moment -fobjc-exceptions
4551 triggers -fexceptions which again is required for exceptions to
4554 if (!flag_objc_exceptions
)
4556 error_at (try_locus
, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4559 if (flag_objc_sjlj_exceptions
)
4560 objc_mark_locals_volatile (NULL
);
4563 /* Called just after parsing "@catch (parm)". Open a binding level,
4564 enter DECL into the binding level, and initialize it. Leave the
4565 binding level open while the body of the compound statement is parsed. */
4568 objc_begin_catch_clause (tree decl
)
4570 tree compound
, type
, t
;
4572 /* Begin a new scope that the entire catch clause will live in. */
4573 compound
= c_begin_compound_stmt (true);
4575 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
4576 decl
= build_decl (input_location
,
4577 VAR_DECL
, DECL_NAME (decl
), TREE_TYPE (decl
));
4578 lang_hooks
.decls
.pushdecl (decl
);
4580 /* Since a decl is required here by syntax, don't warn if its unused. */
4581 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
4582 be what the previous objc implementation did. */
4583 TREE_USED (decl
) = 1;
4584 DECL_READ_P (decl
) = 1;
4586 /* Verify that the type of the catch is valid. It must be a pointer
4587 to an Objective-C class, or "id" (which is catch-all). */
4588 type
= TREE_TYPE (decl
);
4590 if (POINTER_TYPE_P (type
) && objc_is_object_id (TREE_TYPE (type
)))
4592 else if (!POINTER_TYPE_P (type
) || !TYPED_OBJECT (TREE_TYPE (type
)))
4594 error ("@catch parameter is not a known Objective-C class type");
4595 type
= error_mark_node
;
4597 else if (cur_try_context
->catch_list
)
4599 /* Examine previous @catch clauses and see if we've already
4600 caught the type in question. */
4601 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
4602 for (; !tsi_end_p (i
); tsi_next (&i
))
4604 tree stmt
= tsi_stmt (i
);
4605 t
= CATCH_TYPES (stmt
);
4606 if (t
== error_mark_node
)
4608 if (!t
|| DERIVED_FROM_P (TREE_TYPE (t
), TREE_TYPE (type
)))
4610 warning (0, "exception of type %<%T%> will be caught",
4612 warning_at (EXPR_LOCATION (stmt
), 0, " by earlier handler for %<%T%>",
4613 TREE_TYPE (t
? t
: objc_object_type
));
4619 /* Record the data for the catch in the try context so that we can
4620 finalize it later. */
4621 t
= build_stmt (input_location
, CATCH_EXPR
, type
, compound
);
4622 cur_try_context
->current_catch
= t
;
4624 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
4625 t
= objc_build_exc_ptr ();
4626 t
= convert (TREE_TYPE (decl
), t
);
4627 t
= build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
4631 /* Called just after parsing the closing brace of a @catch clause. Close
4632 the open binding level, and record a CATCH_EXPR for it. */
4635 objc_finish_catch_clause (void)
4637 tree c
= cur_try_context
->current_catch
;
4638 cur_try_context
->current_catch
= NULL
;
4639 cur_try_context
->end_catch_locus
= input_location
;
4641 CATCH_BODY (c
) = c_end_compound_stmt (input_location
, CATCH_BODY (c
), 1);
4642 append_to_statement_list (c
, &cur_try_context
->catch_list
);
4645 /* Called after parsing a @finally clause and its associated BODY.
4646 Record the body for later placement. */
4649 objc_build_finally_clause (location_t finally_locus
, tree body
)
4651 cur_try_context
->finally_body
= body
;
4652 cur_try_context
->finally_locus
= finally_locus
;
4653 cur_try_context
->end_finally_locus
= input_location
;
4656 /* Called to finalize a @try construct. */
4659 objc_finish_try_stmt (void)
4661 struct objc_try_context
*c
= cur_try_context
;
4664 if (c
->catch_list
== NULL
&& c
->finally_body
== NULL
)
4665 error ("%<@try%> without %<@catch%> or %<@finally%>");
4667 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
4668 if (flag_objc_sjlj_exceptions
)
4670 bool save
= in_late_binary_op
;
4671 in_late_binary_op
= true;
4672 if (!cur_try_context
->finally_body
)
4674 cur_try_context
->finally_locus
= input_location
;
4675 cur_try_context
->end_finally_locus
= input_location
;
4677 stmt
= next_sjlj_build_try_catch_finally ();
4678 in_late_binary_op
= save
;
4682 /* Otherwise, nest the CATCH inside a FINALLY. */
4686 stmt
= build_stmt (input_location
, TRY_CATCH_EXPR
, stmt
, c
->catch_list
);
4687 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
4689 if (c
->finally_body
)
4691 stmt
= build_stmt (input_location
, TRY_FINALLY_EXPR
, stmt
, c
->finally_body
);
4692 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
4697 cur_try_context
= c
->outer
;
4703 objc_build_throw_stmt (location_t loc
, tree throw_expr
)
4707 if (!flag_objc_exceptions
)
4709 error_at (loc
, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4712 if (throw_expr
== NULL
)
4714 /* If we're not inside a @catch block, there is no "current
4715 exception" to be rethrown. */
4716 if (cur_try_context
== NULL
4717 || cur_try_context
->current_catch
== NULL
)
4719 error_at (loc
, "%<@throw%> (rethrow) used outside of a @catch block");
4723 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
4724 value that we get from the runtime. */
4725 throw_expr
= objc_build_exc_ptr ();
4728 /* A throw is just a call to the runtime throw function with the
4729 object as a parameter. */
4730 args
= tree_cons (NULL
, throw_expr
, NULL
);
4731 return add_stmt (build_function_call (loc
,
4732 objc_exception_throw_decl
, args
));
4736 objc_build_synchronized (location_t start_locus
, tree mutex
, tree body
)
4740 /* First lock the mutex. */
4741 mutex
= save_expr (mutex
);
4742 args
= tree_cons (NULL
, mutex
, NULL
);
4743 call
= build_function_call (input_location
,
4744 objc_sync_enter_decl
, args
);
4745 SET_EXPR_LOCATION (call
, start_locus
);
4748 /* Build the mutex unlock. */
4749 args
= tree_cons (NULL
, mutex
, NULL
);
4750 call
= build_function_call (input_location
,
4751 objc_sync_exit_decl
, args
);
4752 SET_EXPR_LOCATION (call
, input_location
);
4754 /* Put the that and the body in a TRY_FINALLY. */
4755 objc_begin_try_stmt (start_locus
, body
);
4756 objc_build_finally_clause (input_location
, call
);
4757 return objc_finish_try_stmt ();
4761 /* Predefine the following data type:
4763 struct _objc_exception_data
4765 int buf[OBJC_JBLEN];
4769 /* The following yuckiness should prevent users from having to #include
4770 <setjmp.h> in their code... */
4772 /* Define to a harmless positive value so the below code doesn't die. */
4774 #define OBJC_JBLEN 18
4778 build_next_objc_exception_stuff (void)
4780 tree decls
, temp_type
, *chain
= NULL
;
4782 objc_exception_data_template
4783 = objc_start_struct (get_identifier (UTAG_EXCDATA
));
4785 /* int buf[OBJC_JBLEN]; */
4787 temp_type
= build_sized_array_type (integer_type_node
, OBJC_JBLEN
);
4788 decls
= add_field_decl (temp_type
, "buf", &chain
);
4790 /* void *pointers[4]; */
4792 temp_type
= build_sized_array_type (ptr_type_node
, 4);
4793 add_field_decl (temp_type
, "pointers", &chain
);
4795 objc_finish_struct (objc_exception_data_template
, decls
);
4797 /* int _setjmp(...); */
4798 /* If the user includes <setjmp.h>, this shall be superseded by
4799 'int _setjmp(jmp_buf);' */
4800 temp_type
= build_varargs_function_type_list (integer_type_node
, NULL_TREE
);
4802 = add_builtin_function (TAG_SETJMP
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
4804 /* id objc_exception_extract(struct _objc_exception_data *); */
4806 = build_function_type_list (objc_object_type
,
4807 build_pointer_type (objc_exception_data_template
),
4809 objc_exception_extract_decl
4810 = add_builtin_function (TAG_EXCEPTIONEXTRACT
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4812 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4813 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4815 = build_function_type_list (void_type_node
,
4816 build_pointer_type (objc_exception_data_template
),
4818 objc_exception_try_enter_decl
4819 = add_builtin_function (TAG_EXCEPTIONTRYENTER
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4821 objc_exception_try_exit_decl
4822 = add_builtin_function (TAG_EXCEPTIONTRYEXIT
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4825 /* int objc_exception_match(id, id); */
4827 = build_function_type_list (integer_type_node
,
4828 objc_object_type
, objc_object_type
, NULL_TREE
);
4829 objc_exception_match_decl
4830 = add_builtin_function (TAG_EXCEPTIONMATCH
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4833 /* id objc_assign_ivar (id, id, unsigned int); */
4834 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4835 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4837 = build_function_type_list (objc_object_type
,
4842 objc_assign_ivar_decl
4843 = add_builtin_function (TAG_ASSIGNIVAR
, temp_type
, 0, NOT_BUILT_IN
,
4845 #ifdef OFFS_ASSIGNIVAR_FAST
4846 objc_assign_ivar_fast_decl
4847 = add_builtin_function (TAG_ASSIGNIVAR_FAST
, temp_type
, 0,
4848 NOT_BUILT_IN
, NULL
, NULL_TREE
);
4849 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl
)
4850 = tree_cons (get_identifier ("hard_coded_address"),
4851 build_int_cst (NULL_TREE
, OFFS_ASSIGNIVAR_FAST
),
4854 /* Default to slower ivar method. */
4855 objc_assign_ivar_fast_decl
= objc_assign_ivar_decl
;
4858 /* id objc_assign_global (id, id *); */
4859 /* id objc_assign_strongCast (id, id *); */
4860 temp_type
= build_function_type_list (objc_object_type
,
4862 build_pointer_type (objc_object_type
),
4864 objc_assign_global_decl
4865 = add_builtin_function (TAG_ASSIGNGLOBAL
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4867 objc_assign_strong_cast_decl
4868 = add_builtin_function (TAG_ASSIGNSTRONGCAST
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4873 build_objc_exception_stuff (void)
4875 tree noreturn_list
, nothrow_list
, temp_type
;
4877 noreturn_list
= tree_cons (get_identifier ("noreturn"), NULL
, NULL
);
4878 nothrow_list
= tree_cons (get_identifier ("nothrow"), NULL
, NULL
);
4880 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4881 /* void objc_sync_enter(id); */
4882 /* void objc_sync_exit(id); */
4883 temp_type
= build_function_type_list (void_type_node
,
4886 objc_exception_throw_decl
4887 = add_builtin_function (TAG_EXCEPTIONTHROW
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4889 objc_sync_enter_decl
4890 = add_builtin_function (TAG_SYNCENTER
, temp_type
, 0, NOT_BUILT_IN
,
4891 NULL
, nothrow_list
);
4893 = add_builtin_function (TAG_SYNCEXIT
, temp_type
, 0, NOT_BUILT_IN
,
4894 NULL
, nothrow_list
);
4897 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4900 struct <classname> {
4901 struct _objc_class *isa;
4906 build_private_template (tree klass
)
4908 if (!CLASS_STATIC_TEMPLATE (klass
))
4910 tree record
= objc_build_struct (klass
,
4911 get_class_ivars (klass
, false),
4912 CLASS_SUPER_NAME (klass
));
4914 /* Set the TREE_USED bit for this struct, so that stab generator
4915 can emit stabs for this struct type. */
4916 if (flag_debug_only_used_symbols
&& TYPE_STUB_DECL (record
))
4917 TREE_USED (TYPE_STUB_DECL (record
)) = 1;
4921 /* Begin code generation for protocols... */
4923 /* struct _objc_protocol {
4924 struct _objc_class *isa;
4925 char *protocol_name;
4926 struct _objc_protocol **protocol_list;
4927 struct _objc__method_prototype_list *instance_methods;
4928 struct _objc__method_prototype_list *class_methods;
4932 build_protocol_template (void)
4934 tree ptype
, decls
, *chain
= NULL
;
4936 objc_protocol_template
= objc_start_struct (get_identifier (UTAG_PROTOCOL
));
4938 /* struct _objc_class *isa; */
4939 ptype
= build_pointer_type (xref_tag (RECORD_TYPE
,
4940 get_identifier (UTAG_CLASS
)));
4941 decls
= add_field_decl (ptype
, "isa", &chain
);
4943 /* char *protocol_name; */
4944 add_field_decl (string_type_node
, "protocol_name", &chain
);
4946 /* struct _objc_protocol **protocol_list; */
4947 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
4948 add_field_decl (ptype
, "protocol_list", &chain
);
4950 /* struct _objc__method_prototype_list *instance_methods; */
4951 add_field_decl (objc_method_proto_list_ptr
, "instance_methods", &chain
);
4953 /* struct _objc__method_prototype_list *class_methods; */
4954 add_field_decl (objc_method_proto_list_ptr
, "class_methods", &chain
);
4956 objc_finish_struct (objc_protocol_template
, decls
);
4960 build_descriptor_table_initializer (tree type
, tree entries
)
4962 VEC(constructor_elt
,gc
) *inits
= NULL
;
4966 VEC(constructor_elt
,gc
) *elts
= NULL
;
4968 CONSTRUCTOR_APPEND_ELT (elts
, NULL_TREE
,
4969 build_selector (METHOD_SEL_NAME (entries
)));
4970 CONSTRUCTOR_APPEND_ELT (elts
, NULL_TREE
,
4971 add_objc_string (METHOD_ENCODING (entries
),
4974 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
,
4975 objc_build_constructor (type
, elts
));
4977 entries
= DECL_CHAIN (entries
);
4981 return objc_build_constructor (build_array_type (type
, 0), inits
);
4984 /* struct objc_method_prototype_list {
4986 struct objc_method_prototype {
4993 build_method_prototype_list_template (tree list_type
, int size
)
4995 tree objc_ivar_list_record
;
4996 tree array_type
, decls
, *chain
= NULL
;
4998 /* Generate an unnamed struct definition. */
5000 objc_ivar_list_record
= objc_start_struct (NULL_TREE
);
5002 /* int method_count; */
5003 decls
= add_field_decl (integer_type_node
, "method_count", &chain
);
5005 /* struct objc_method method_list[]; */
5006 array_type
= build_sized_array_type (list_type
, size
);
5007 add_field_decl (array_type
, "method_list", &chain
);
5009 objc_finish_struct (objc_ivar_list_record
, decls
);
5011 return objc_ivar_list_record
;
5015 build_method_prototype_template (void)
5018 tree decls
, *chain
= NULL
;
5020 proto_record
= objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE
));
5023 decls
= add_field_decl (objc_selector_type
, "_cmd", &chain
);
5025 /* char *method_types; */
5026 add_field_decl (string_type_node
, "method_types", &chain
);
5028 objc_finish_struct (proto_record
, decls
);
5030 return proto_record
;
5034 objc_method_parm_type (tree type
)
5036 type
= TREE_VALUE (TREE_TYPE (type
));
5037 if (TREE_CODE (type
) == TYPE_DECL
)
5038 type
= TREE_TYPE (type
);
5043 objc_encoded_type_size (tree type
)
5045 int sz
= int_size_in_bytes (type
);
5047 /* Make all integer and enum types at least as large
5049 if (sz
> 0 && INTEGRAL_TYPE_P (type
))
5050 sz
= MAX (sz
, int_size_in_bytes (integer_type_node
));
5051 /* Treat arrays as pointers, since that's how they're
5053 else if (TREE_CODE (type
) == ARRAY_TYPE
)
5054 sz
= int_size_in_bytes (ptr_type_node
);
5058 /* Encode a method prototype.
5060 The format is described in gcc/doc/objc.texi, section 'Method
5064 encode_method_prototype (tree method_decl
)
5071 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
5072 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
5074 /* Encode return type. */
5075 encode_type (objc_method_parm_type (method_decl
),
5076 obstack_object_size (&util_obstack
),
5077 OBJC_ENCODE_INLINE_DEFS
);
5080 /* The first two arguments (self and _cmd) are pointers; account for
5082 i
= int_size_in_bytes (ptr_type_node
);
5083 parm_offset
= 2 * i
;
5084 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
5085 parms
= DECL_CHAIN (parms
))
5087 tree type
= objc_method_parm_type (parms
);
5088 int sz
= objc_encoded_type_size (type
);
5090 /* If a type size is not known, bail out. */
5093 error ("type %q+D does not have a known size",
5095 /* Pretend that the encoding succeeded; the compilation will
5096 fail nevertheless. */
5097 goto finish_encoding
;
5102 sprintf (buf
, "%d@0:%d", parm_offset
, i
);
5103 obstack_grow (&util_obstack
, buf
, strlen (buf
));
5105 /* Argument types. */
5106 parm_offset
= 2 * i
;
5107 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
5108 parms
= DECL_CHAIN (parms
))
5110 tree type
= objc_method_parm_type (parms
);
5112 /* Process argument qualifiers for user supplied arguments. */
5113 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms
)));
5116 encode_type (type
, obstack_object_size (&util_obstack
),
5117 OBJC_ENCODE_INLINE_DEFS
);
5119 /* Compute offset. */
5120 sprintf (buf
, "%d", parm_offset
);
5121 parm_offset
+= objc_encoded_type_size (type
);
5123 obstack_grow (&util_obstack
, buf
, strlen (buf
));
5127 obstack_1grow (&util_obstack
, '\0');
5128 result
= get_identifier (XOBFINISH (&util_obstack
, char *));
5129 obstack_free (&util_obstack
, util_firstobj
);
5134 generate_descriptor_table (tree type
, const char *name
, int size
, tree list
,
5138 VEC(constructor_elt
,gc
) *v
= NULL
;
5140 decl
= start_var_decl (type
, synth_id_with_class_suffix (name
, proto
));
5142 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
5143 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, list
);
5145 finish_var_decl (decl
, objc_build_constructor (type
, v
));
5151 generate_method_descriptors (tree protocol
)
5153 tree initlist
, chain
, method_list_template
;
5156 if (!objc_method_prototype_template
)
5157 objc_method_prototype_template
= build_method_prototype_template ();
5159 chain
= PROTOCOL_CLS_METHODS (protocol
);
5162 size
= list_length (chain
);
5164 method_list_template
5165 = build_method_prototype_list_template (objc_method_prototype_template
,
5169 = build_descriptor_table_initializer (objc_method_prototype_template
,
5172 UOBJC_CLASS_METHODS_decl
5173 = generate_descriptor_table (method_list_template
,
5174 "_OBJC_PROTOCOL_CLASS_METHODS",
5175 size
, initlist
, protocol
);
5178 UOBJC_CLASS_METHODS_decl
= 0;
5180 chain
= PROTOCOL_NST_METHODS (protocol
);
5183 size
= list_length (chain
);
5185 method_list_template
5186 = build_method_prototype_list_template (objc_method_prototype_template
,
5189 = build_descriptor_table_initializer (objc_method_prototype_template
,
5192 UOBJC_INSTANCE_METHODS_decl
5193 = generate_descriptor_table (method_list_template
,
5194 "_OBJC_PROTOCOL_INSTANCE_METHODS",
5195 size
, initlist
, protocol
);
5198 UOBJC_INSTANCE_METHODS_decl
= 0;
5202 generate_protocol_references (tree plist
)
5206 /* Forward declare protocols referenced. */
5207 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
5209 tree proto
= TREE_VALUE (lproto
);
5211 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
5212 && PROTOCOL_NAME (proto
))
5214 if (! PROTOCOL_FORWARD_DECL (proto
))
5215 build_protocol_reference (proto
);
5217 if (PROTOCOL_LIST (proto
))
5218 generate_protocol_references (PROTOCOL_LIST (proto
));
5223 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
5227 objc_generate_cxx_ctor_or_dtor (bool dtor
)
5229 tree fn
, body
, compound_stmt
, ivar
;
5231 /* - (id) .cxx_construct { ... return self; } */
5232 /* - (void) .cxx_construct { ... } */
5234 objc_start_method_definition
5235 (false /* is_class_method */,
5236 objc_build_method_signature (false /* is_class_method */,
5237 build_tree_list (NULL_TREE
,
5240 : objc_object_type
),
5241 get_identifier (dtor
5243 : TAG_CXX_CONSTRUCT
),
5244 make_node (TREE_LIST
),
5246 body
= begin_function_body ();
5247 compound_stmt
= begin_compound_stmt (0);
5249 ivar
= CLASS_IVARS (implementation_template
);
5250 /* Destroy ivars in reverse order. */
5252 ivar
= nreverse (copy_list (ivar
));
5254 for (; ivar
; ivar
= TREE_CHAIN (ivar
))
5256 if (TREE_CODE (ivar
) == FIELD_DECL
)
5258 tree type
= TREE_TYPE (ivar
);
5260 /* Call the ivar's default constructor or destructor. Do not
5261 call the destructor unless a corresponding constructor call
5262 has also been made (or is not needed). */
5263 if (MAYBE_CLASS_TYPE_P (type
)
5265 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type
)
5266 && (!TYPE_NEEDS_CONSTRUCTING (type
)
5267 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type
)))
5268 : (TYPE_NEEDS_CONSTRUCTING (type
)
5269 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type
))))
5271 (build_special_member_call
5272 (build_ivar_reference (DECL_NAME (ivar
)),
5273 dtor
? complete_dtor_identifier
: complete_ctor_identifier
,
5274 NULL
, type
, LOOKUP_NORMAL
, tf_warning_or_error
));
5278 /* The constructor returns 'self'. */
5280 finish_return_stmt (self_decl
);
5282 finish_compound_stmt (compound_stmt
);
5283 finish_function_body (body
);
5284 fn
= current_function_decl
;
5286 objc_finish_method_definition (fn
);
5289 /* The following routine will examine the current @interface for any
5290 non-POD C++ ivars requiring non-trivial construction and/or
5291 destruction, and then synthesize special '- .cxx_construct' and/or
5292 '- .cxx_destruct' methods which will run the appropriate
5293 construction or destruction code. Note that ivars inherited from
5294 super-classes are _not_ considered. */
5296 objc_generate_cxx_cdtors (void)
5298 bool need_ctor
= false, need_dtor
= false;
5301 /* Error case, due to possibly an extra @end. */
5302 if (!objc_implementation_context
)
5305 /* We do not want to do this for categories, since they do not have
5308 if (TREE_CODE (objc_implementation_context
) != CLASS_IMPLEMENTATION_TYPE
)
5311 /* First, determine if we even need a constructor and/or destructor. */
5313 for (ivar
= CLASS_IVARS (implementation_template
); ivar
;
5314 ivar
= TREE_CHAIN (ivar
))
5316 if (TREE_CODE (ivar
) == FIELD_DECL
)
5318 tree type
= TREE_TYPE (ivar
);
5320 if (MAYBE_CLASS_TYPE_P (type
))
5322 if (TYPE_NEEDS_CONSTRUCTING (type
)
5323 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type
))
5324 /* NB: If a default constructor is not available, we will not
5325 be able to initialize this ivar; the add_instance_variable()
5326 routine will already have warned about this. */
5329 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type
)
5330 && (!TYPE_NEEDS_CONSTRUCTING (type
)
5331 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type
)))
5332 /* NB: If a default constructor is not available, we will not
5333 call the destructor either, for symmetry. */
5339 /* Generate '- .cxx_construct' if needed. */
5342 objc_generate_cxx_ctor_or_dtor (false);
5344 /* Generate '- .cxx_destruct' if needed. */
5347 objc_generate_cxx_ctor_or_dtor (true);
5349 /* The 'imp_list' variable points at an imp_entry record for the current
5350 @implementation. Record the existence of '- .cxx_construct' and/or
5351 '- .cxx_destruct' methods therein; it will be included in the
5352 metadata for the class. */
5353 if (flag_next_runtime
)
5354 imp_list
->has_cxx_cdtors
= (need_ctor
|| need_dtor
);
5358 /* For each protocol which was referenced either from a @protocol()
5359 expression, or because a class/category implements it (then a
5360 pointer to the protocol is stored in the struct describing the
5361 class/category), we create a statically allocated instance of the
5362 Protocol class. The code is written in such a way as to generate
5363 as few Protocol objects as possible; we generate a unique Protocol
5364 instance for each protocol, and we don't generate a Protocol
5365 instance if the protocol is never referenced (either from a
5366 @protocol() or from a class/category implementation). These
5367 statically allocated objects can be referred to via the static
5368 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
5370 The statically allocated Protocol objects that we generate here
5371 need to be fixed up at runtime in order to be used: the 'isa'
5372 pointer of the objects need to be set up to point to the 'Protocol'
5373 class, as known at runtime.
5375 The NeXT runtime fixes up all protocols at program startup time,
5376 before main() is entered. It uses a low-level trick to look up all
5377 those symbols, then loops on them and fixes them up.
5379 The GNU runtime as well fixes up all protocols before user code
5380 from the module is executed; it requires pointers to those symbols
5381 to be put in the objc_symtab (which is then passed as argument to
5382 the function __objc_exec_class() which the compiler sets up to be
5383 executed automatically when the module is loaded); setup of those
5384 Protocol objects happen in two ways in the GNU runtime: all
5385 Protocol objects referred to by a class or category implementation
5386 are fixed up when the class/category is loaded; all Protocol
5387 objects referred to by a @protocol() expression are added by the
5388 compiler to the list of statically allocated instances to fixup
5389 (the same list holding the statically allocated constant string
5390 objects). Because, as explained above, the compiler generates as
5391 few Protocol objects as possible, some Protocol object might end up
5392 being referenced multiple times when compiled with the GNU runtime,
5393 and end up being fixed up multiple times at runtime initialization.
5394 But that doesn't hurt, it's just a little inefficient. */
5397 generate_protocols (void)
5401 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
5403 /* If a protocol was directly referenced, pull in indirect references. */
5404 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
5405 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
5406 generate_protocol_references (PROTOCOL_LIST (p
));
5408 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
5410 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
5411 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
5413 /* If protocol wasn't referenced, don't generate any code. */
5414 decl
= PROTOCOL_FORWARD_DECL (p
);
5419 /* Make sure we link in the Protocol class. */
5420 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
5424 if (! METHOD_ENCODING (nst_methods
))
5426 encoding
= encode_method_prototype (nst_methods
);
5427 METHOD_ENCODING (nst_methods
) = encoding
;
5429 nst_methods
= DECL_CHAIN (nst_methods
);
5434 if (! METHOD_ENCODING (cls_methods
))
5436 encoding
= encode_method_prototype (cls_methods
);
5437 METHOD_ENCODING (cls_methods
) = encoding
;
5440 cls_methods
= DECL_CHAIN (cls_methods
);
5442 generate_method_descriptors (p
);
5444 if (PROTOCOL_LIST (p
))
5445 refs_decl
= generate_protocol_list (p
);
5449 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5450 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
5453 refs_expr
= convert (build_pointer_type (build_pointer_type
5454 (objc_protocol_template
)),
5455 build_unary_op (input_location
,
5456 ADDR_EXPR
, refs_decl
, 0));
5458 refs_expr
= build_int_cst (NULL_TREE
, 0);
5460 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
5461 by generate_method_descriptors, which is called above. */
5462 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
5463 protocol_name_expr
, refs_expr
,
5464 UOBJC_INSTANCE_METHODS_decl
,
5465 UOBJC_CLASS_METHODS_decl
);
5466 finish_var_decl (decl
, initlist
);
5471 build_protocol_initializer (tree type
, tree protocol_name
,
5472 tree protocol_list
, tree instance_methods
,
5476 tree cast_type
= build_pointer_type
5477 (xref_tag (RECORD_TYPE
,
5478 get_identifier (UTAG_CLASS
)));
5479 VEC(constructor_elt
,gc
) *inits
= NULL
;
5481 /* Filling the "isa" in with one allows the runtime system to
5482 detect that the version change...should remove before final release. */
5484 expr
= build_int_cst (cast_type
, PROTOCOL_VERSION
);
5485 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
5486 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_name
);
5487 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_list
);
5489 if (!instance_methods
)
5490 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
5493 expr
= convert (objc_method_proto_list_ptr
,
5494 build_unary_op (input_location
,
5495 ADDR_EXPR
, instance_methods
, 0));
5496 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
5500 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
5503 expr
= convert (objc_method_proto_list_ptr
,
5504 build_unary_op (input_location
,
5505 ADDR_EXPR
, class_methods
, 0));
5506 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
5509 return objc_build_constructor (type
, inits
);
5512 /* struct _objc_category {
5513 char *category_name;
5515 struct _objc_method_list *instance_methods;
5516 struct _objc_method_list *class_methods;
5517 struct _objc_protocol_list *protocols;
5521 build_category_template (void)
5523 tree ptype
, decls
, *chain
= NULL
;
5525 objc_category_template
= objc_start_struct (get_identifier (UTAG_CATEGORY
));
5527 /* char *category_name; */
5528 decls
= add_field_decl (string_type_node
, "category_name", &chain
);
5530 /* char *class_name; */
5531 add_field_decl (string_type_node
, "class_name", &chain
);
5533 /* struct _objc_method_list *instance_methods; */
5534 add_field_decl (objc_method_list_ptr
, "instance_methods", &chain
);
5536 /* struct _objc_method_list *class_methods; */
5537 add_field_decl (objc_method_list_ptr
, "class_methods", &chain
);
5539 /* struct _objc_protocol **protocol_list; */
5540 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
5541 add_field_decl (ptype
, "protocol_list", &chain
);
5543 objc_finish_struct (objc_category_template
, decls
);
5546 /* struct _objc_selector {
5552 build_selector_template (void)
5554 tree decls
, *chain
= NULL
;
5556 objc_selector_template
= objc_start_struct (get_identifier (UTAG_SELECTOR
));
5559 decls
= add_field_decl (objc_selector_type
, "sel_id", &chain
);
5561 /* char *sel_type; */
5562 add_field_decl (string_type_node
, "sel_type", &chain
);
5564 objc_finish_struct (objc_selector_template
, decls
);
5567 /* struct _objc_class {
5568 struct _objc_class *isa;
5569 struct _objc_class *super_class;
5574 struct _objc_ivar_list *ivars;
5575 struct _objc_method_list *methods;
5576 #ifdef __NEXT_RUNTIME__
5577 struct objc_cache *cache;
5579 struct sarray *dtable;
5580 struct _objc_class *subclass_list;
5581 struct _objc_class *sibling_class;
5583 struct _objc_protocol_list *protocols;
5584 #ifdef __NEXT_RUNTIME__
5587 void *gc_object_type;
5590 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
5591 the NeXT/Apple runtime; still, the compiler must generate them to
5592 maintain backward binary compatibility (and to allow for future
5596 build_class_template (void)
5598 tree ptype
, decls
, *chain
= NULL
;
5600 objc_class_template
= objc_start_struct (get_identifier (UTAG_CLASS
));
5602 /* struct _objc_class *isa; */
5603 decls
= add_field_decl (build_pointer_type (objc_class_template
),
5606 /* struct _objc_class *super_class; */
5607 add_field_decl (build_pointer_type (objc_class_template
),
5608 "super_class", &chain
);
5611 add_field_decl (string_type_node
, "name", &chain
);
5614 add_field_decl (long_integer_type_node
, "version", &chain
);
5617 add_field_decl (long_integer_type_node
, "info", &chain
);
5619 /* long instance_size; */
5620 add_field_decl (long_integer_type_node
, "instance_size", &chain
);
5622 /* struct _objc_ivar_list *ivars; */
5623 add_field_decl (objc_ivar_list_ptr
,"ivars", &chain
);
5625 /* struct _objc_method_list *methods; */
5626 add_field_decl (objc_method_list_ptr
, "methods", &chain
);
5628 if (flag_next_runtime
)
5630 /* struct objc_cache *cache; */
5631 ptype
= build_pointer_type (xref_tag (RECORD_TYPE
,
5632 get_identifier ("objc_cache")));
5633 add_field_decl (ptype
, "cache", &chain
);
5637 /* struct sarray *dtable; */
5638 ptype
= build_pointer_type(xref_tag (RECORD_TYPE
,
5639 get_identifier ("sarray")));
5640 add_field_decl (ptype
, "dtable", &chain
);
5642 /* struct objc_class *subclass_list; */
5643 ptype
= build_pointer_type (objc_class_template
);
5644 add_field_decl (ptype
, "subclass_list", &chain
);
5646 /* struct objc_class *sibling_class; */
5647 ptype
= build_pointer_type (objc_class_template
);
5648 add_field_decl (ptype
, "sibling_class", &chain
);
5651 /* struct _objc_protocol **protocol_list; */
5652 ptype
= build_pointer_type (build_pointer_type
5653 (xref_tag (RECORD_TYPE
,
5654 get_identifier (UTAG_PROTOCOL
))));
5655 add_field_decl (ptype
, "protocol_list", &chain
);
5657 if (flag_next_runtime
)
5660 add_field_decl (build_pointer_type (void_type_node
), "sel_id", &chain
);
5663 /* void *gc_object_type; */
5664 add_field_decl (build_pointer_type (void_type_node
),
5665 "gc_object_type", &chain
);
5667 objc_finish_struct (objc_class_template
, decls
);
5670 /* Generate appropriate forward declarations for an implementation. */
5673 synth_forward_declarations (void)
5677 /* static struct objc_class _OBJC_CLASS_<my_name>; */
5678 UOBJC_CLASS_decl
= build_metadata_decl ("_OBJC_CLASS",
5679 objc_class_template
);
5681 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
5682 UOBJC_METACLASS_decl
= build_metadata_decl ("_OBJC_METACLASS",
5683 objc_class_template
);
5685 /* Pre-build the following entities - for speed/convenience. */
5687 an_id
= get_identifier ("super_class");
5688 ucls_super_ref
= objc_build_component_ref (UOBJC_CLASS_decl
, an_id
);
5689 uucls_super_ref
= objc_build_component_ref (UOBJC_METACLASS_decl
, an_id
);
5693 error_with_ivar (const char *message
, tree decl
)
5695 error_at (DECL_SOURCE_LOCATION (decl
), "%s %qs",
5696 message
, identifier_to_locale (gen_declaration (decl
)));
5701 check_ivars (tree inter
, tree imp
)
5703 tree intdecls
= CLASS_RAW_IVARS (inter
);
5704 tree impdecls
= CLASS_RAW_IVARS (imp
);
5711 if (intdecls
&& TREE_CODE (intdecls
) == TYPE_DECL
)
5712 intdecls
= TREE_CHAIN (intdecls
);
5714 if (intdecls
== 0 && impdecls
== 0)
5716 if (intdecls
== 0 || impdecls
== 0)
5718 error ("inconsistent instance variable specification");
5722 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
5724 if (!comptypes (t1
, t2
)
5725 || !tree_int_cst_equal (DECL_INITIAL (intdecls
),
5726 DECL_INITIAL (impdecls
)))
5728 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
5730 error_with_ivar ("conflicting instance variable type",
5732 error_with_ivar ("previous declaration of",
5735 else /* both the type and the name don't match */
5737 error ("inconsistent instance variable specification");
5742 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
5744 error_with_ivar ("conflicting instance variable name",
5746 error_with_ivar ("previous declaration of",
5750 intdecls
= DECL_CHAIN (intdecls
);
5751 impdecls
= DECL_CHAIN (impdecls
);
5755 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5756 This needs to be done just once per compilation. */
5758 /* struct _objc_super {
5759 struct _objc_object *self;
5760 struct _objc_class *super_class;
5764 build_super_template (void)
5766 tree decls
, *chain
= NULL
;
5768 objc_super_template
= objc_start_struct (get_identifier (UTAG_SUPER
));
5770 /* struct _objc_object *self; */
5771 decls
= add_field_decl (objc_object_type
, "self", &chain
);
5773 /* struct _objc_class *super_class; */
5774 add_field_decl (build_pointer_type (objc_class_template
),
5775 "super_class", &chain
);
5777 objc_finish_struct (objc_super_template
, decls
);
5780 /* struct _objc_ivar {
5787 build_ivar_template (void)
5789 tree objc_ivar_id
, objc_ivar_record
;
5790 tree decls
, *chain
= NULL
;
5792 objc_ivar_id
= get_identifier (UTAG_IVAR
);
5793 objc_ivar_record
= objc_start_struct (objc_ivar_id
);
5795 /* char *ivar_name; */
5796 decls
= add_field_decl (string_type_node
, "ivar_name", &chain
);
5798 /* char *ivar_type; */
5799 add_field_decl (string_type_node
, "ivar_type", &chain
);
5801 /* int ivar_offset; */
5802 add_field_decl (integer_type_node
, "ivar_offset", &chain
);
5804 objc_finish_struct (objc_ivar_record
, decls
);
5806 return objc_ivar_record
;
5811 struct objc_ivar ivar_list[ivar_count];
5815 build_ivar_list_template (tree list_type
, int size
)
5817 tree objc_ivar_list_record
;
5818 tree array_type
, decls
, *chain
= NULL
;
5820 objc_ivar_list_record
= objc_start_struct (NULL_TREE
);
5822 /* int ivar_count; */
5823 decls
= add_field_decl (integer_type_node
, "ivar_count", &chain
);
5825 /* struct objc_ivar ivar_list[]; */
5826 array_type
= build_sized_array_type (list_type
, size
);
5827 add_field_decl (array_type
, "ivar_list", &chain
);
5829 objc_finish_struct (objc_ivar_list_record
, decls
);
5831 return objc_ivar_list_record
;
5835 struct _objc__method_prototype_list *method_next;
5837 struct objc_method method_list[method_count];
5841 build_method_list_template (tree list_type
, int size
)
5843 tree objc_ivar_list_record
;
5844 tree array_type
, decls
, *chain
= NULL
;
5846 objc_ivar_list_record
= objc_start_struct (NULL_TREE
);
5848 /* struct _objc__method_prototype_list *method_next; */
5849 decls
= add_field_decl (objc_method_proto_list_ptr
, "method_next", &chain
);
5851 /* int method_count; */
5852 add_field_decl (integer_type_node
, "method_count", &chain
);
5854 /* struct objc_method method_list[]; */
5855 array_type
= build_sized_array_type (list_type
, size
);
5856 add_field_decl (array_type
, "method_list", &chain
);
5858 objc_finish_struct (objc_ivar_list_record
, decls
);
5860 return objc_ivar_list_record
;
5864 build_ivar_list_initializer (tree type
, tree field_decl
)
5866 VEC(constructor_elt
,gc
) *inits
= NULL
;
5870 VEC(constructor_elt
,gc
) *ivar
= NULL
;
5874 if (DECL_NAME (field_decl
))
5875 CONSTRUCTOR_APPEND_ELT (ivar
, NULL_TREE
,
5876 add_objc_string (DECL_NAME (field_decl
),
5879 /* Unnamed bit-field ivar (yuck). */
5880 CONSTRUCTOR_APPEND_ELT (ivar
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
5883 encode_field_decl (field_decl
,
5884 obstack_object_size (&util_obstack
),
5885 OBJC_ENCODE_DONT_INLINE_DEFS
);
5887 /* Null terminate string. */
5888 obstack_1grow (&util_obstack
, 0);
5889 id
= add_objc_string (get_identifier (XOBFINISH (&util_obstack
, char *)),
5891 CONSTRUCTOR_APPEND_ELT (ivar
, NULL_TREE
, id
);
5892 obstack_free (&util_obstack
, util_firstobj
);
5895 CONSTRUCTOR_APPEND_ELT (ivar
, NULL_TREE
, byte_position (field_decl
));
5896 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
,
5897 objc_build_constructor (type
, ivar
));
5899 field_decl
= DECL_CHAIN (field_decl
);
5900 while (field_decl
&& TREE_CODE (field_decl
) != FIELD_DECL
);
5904 return objc_build_constructor (build_array_type (type
, 0), inits
);
5908 generate_ivars_list (tree type
, const char *name
, int size
, tree list
)
5911 VEC(constructor_elt
,gc
) *inits
= NULL
;
5913 decl
= start_var_decl (type
, synth_id_with_class_suffix
5914 (name
, objc_implementation_context
));
5916 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
5917 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, list
);
5919 finish_var_decl (decl
,
5920 objc_build_constructor (TREE_TYPE (decl
), inits
));
5925 /* Count only the fields occurring in T. */
5928 ivar_list_length (tree t
)
5932 for (; t
; t
= DECL_CHAIN (t
))
5933 if (TREE_CODE (t
) == FIELD_DECL
)
5940 generate_ivar_lists (void)
5942 tree initlist
, ivar_list_template
, chain
;
5945 generating_instance_variables
= 1;
5947 if (!objc_ivar_template
)
5948 objc_ivar_template
= build_ivar_template ();
5950 /* Only generate class variables for the root of the inheritance
5951 hierarchy since these will be the same for every class. */
5953 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
5954 && (chain
= TYPE_FIELDS (objc_class_template
)))
5956 size
= ivar_list_length (chain
);
5958 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
5959 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
5961 UOBJC_CLASS_VARIABLES_decl
5962 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
5966 UOBJC_CLASS_VARIABLES_decl
= 0;
5968 chain
= CLASS_IVARS (implementation_template
);
5971 size
= ivar_list_length (chain
);
5972 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
5973 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
5975 UOBJC_INSTANCE_VARIABLES_decl
5976 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
5980 UOBJC_INSTANCE_VARIABLES_decl
= 0;
5982 generating_instance_variables
= 0;
5986 build_dispatch_table_initializer (tree type
, tree entries
)
5988 VEC(constructor_elt
,gc
) *inits
= NULL
;
5992 VEC(constructor_elt
,gc
) *elems
= NULL
;
5995 CONSTRUCTOR_APPEND_ELT (elems
, NULL_TREE
,
5996 build_selector (METHOD_SEL_NAME (entries
)));
5998 /* Generate the method encoding if we don't have one already. */
5999 if (! METHOD_ENCODING (entries
))
6000 METHOD_ENCODING (entries
) =
6001 encode_method_prototype (entries
);
6003 CONSTRUCTOR_APPEND_ELT (elems
, NULL_TREE
,
6004 add_objc_string (METHOD_ENCODING (entries
),
6007 expr
= convert (ptr_type_node
,
6008 build_unary_op (input_location
, ADDR_EXPR
,
6009 METHOD_DEFINITION (entries
), 1));
6010 CONSTRUCTOR_APPEND_ELT (elems
, NULL_TREE
, expr
);
6012 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
,
6013 objc_build_constructor (type
, elems
));
6015 entries
= DECL_CHAIN (entries
);
6019 return objc_build_constructor (build_array_type (type
, 0), inits
);
6022 /* To accomplish method prototyping without generating all kinds of
6023 inane warnings, the definition of the dispatch table entries were
6026 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
6028 struct objc_method { SEL _cmd; ...; void *_imp; }; */
6031 build_method_template (void)
6034 tree decls
, *chain
= NULL
;
6036 _SLT_record
= objc_start_struct (get_identifier (UTAG_METHOD
));
6039 decls
= add_field_decl (objc_selector_type
, "_cmd", &chain
);
6041 /* char *method_types; */
6042 add_field_decl (string_type_node
, "method_types", &chain
);
6045 add_field_decl (build_pointer_type (void_type_node
), "_imp", &chain
);
6047 objc_finish_struct (_SLT_record
, decls
);
6054 generate_dispatch_table (tree type
, const char *name
, int size
, tree list
)
6057 VEC(constructor_elt
,gc
) *v
= NULL
;
6059 decl
= start_var_decl (type
, synth_id_with_class_suffix
6060 (name
, objc_implementation_context
));
6062 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
6063 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (integer_type_node
, size
));
6064 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, list
);
6066 finish_var_decl (decl
,
6067 objc_build_constructor (TREE_TYPE (decl
), v
));
6073 mark_referenced_methods (void)
6075 struct imp_entry
*impent
;
6078 for (impent
= imp_list
; impent
; impent
= impent
->next
)
6080 chain
= CLASS_CLS_METHODS (impent
->imp_context
);
6083 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
6084 chain
= DECL_CHAIN (chain
);
6087 chain
= CLASS_NST_METHODS (impent
->imp_context
);
6090 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
6091 chain
= DECL_CHAIN (chain
);
6097 generate_dispatch_tables (void)
6099 tree initlist
, chain
, method_list_template
;
6102 if (!objc_method_template
)
6103 objc_method_template
= build_method_template ();
6105 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
6108 size
= list_length (chain
);
6110 method_list_template
6111 = build_method_list_template (objc_method_template
, size
);
6113 = build_dispatch_table_initializer (objc_method_template
, chain
);
6115 UOBJC_CLASS_METHODS_decl
6116 = generate_dispatch_table (method_list_template
,
6117 ((TREE_CODE (objc_implementation_context
)
6118 == CLASS_IMPLEMENTATION_TYPE
)
6119 ? "_OBJC_CLASS_METHODS"
6120 : "_OBJC_CATEGORY_CLASS_METHODS"),
6124 UOBJC_CLASS_METHODS_decl
= 0;
6126 chain
= CLASS_NST_METHODS (objc_implementation_context
);
6129 size
= list_length (chain
);
6131 method_list_template
6132 = build_method_list_template (objc_method_template
, size
);
6134 = build_dispatch_table_initializer (objc_method_template
, chain
);
6136 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
6137 UOBJC_INSTANCE_METHODS_decl
6138 = generate_dispatch_table (method_list_template
,
6139 "_OBJC_INSTANCE_METHODS",
6142 /* We have a category. */
6143 UOBJC_INSTANCE_METHODS_decl
6144 = generate_dispatch_table (method_list_template
,
6145 "_OBJC_CATEGORY_INSTANCE_METHODS",
6149 UOBJC_INSTANCE_METHODS_decl
= 0;
6153 generate_protocol_list (tree i_or_p
)
6155 tree array_type
, ptype
, refs_decl
, lproto
, e
, plist
;
6157 const char *ref_name
;
6158 VEC(constructor_elt
,gc
) *v
= NULL
;
6160 switch (TREE_CODE (i_or_p
))
6162 case CLASS_INTERFACE_TYPE
:
6163 case CATEGORY_INTERFACE_TYPE
:
6164 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
6166 case PROTOCOL_INTERFACE_TYPE
:
6167 plist
= PROTOCOL_LIST (i_or_p
);
6174 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
6175 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
6176 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
6179 /* Build initializer. */
6180 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6181 e
= build_int_cst (build_pointer_type (objc_protocol_template
), size
);
6182 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
6184 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
6186 tree pval
= TREE_VALUE (lproto
);
6188 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
6189 && PROTOCOL_FORWARD_DECL (pval
))
6191 e
= build_unary_op (input_location
, ADDR_EXPR
,
6192 PROTOCOL_FORWARD_DECL (pval
), 0);
6193 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
6197 /* static struct objc_protocol *refs[n]; */
6199 switch (TREE_CODE (i_or_p
))
6201 case PROTOCOL_INTERFACE_TYPE
:
6202 ref_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p
);
6204 case CLASS_INTERFACE_TYPE
:
6205 ref_name
= synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p
);
6207 case CATEGORY_INTERFACE_TYPE
:
6208 ref_name
= synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p
);
6214 ptype
= build_pointer_type (objc_protocol_template
);
6215 array_type
= build_sized_array_type (ptype
, size
+ 3);
6216 refs_decl
= start_var_decl (array_type
, ref_name
);
6218 finish_var_decl (refs_decl
,
6219 objc_build_constructor (TREE_TYPE (refs_decl
), v
));
6225 build_category_initializer (tree type
, tree cat_name
, tree class_name
,
6226 tree instance_methods
, tree class_methods
,
6230 VEC(constructor_elt
,gc
) *v
= NULL
;
6232 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, cat_name
);
6233 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, class_name
);
6235 if (!instance_methods
)
6236 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6239 expr
= convert (objc_method_list_ptr
,
6240 build_unary_op (input_location
, ADDR_EXPR
,
6241 instance_methods
, 0));
6242 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6245 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6248 expr
= convert (objc_method_list_ptr
,
6249 build_unary_op (input_location
, ADDR_EXPR
,
6251 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6254 /* protocol_list = */
6256 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6259 expr
= convert (build_pointer_type
6261 (objc_protocol_template
)),
6262 build_unary_op (input_location
, ADDR_EXPR
,
6264 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6267 return objc_build_constructor (type
, v
);
6270 /* struct _objc_class {
6271 struct objc_class *isa;
6272 struct objc_class *super_class;
6277 struct objc_ivar_list *ivars;
6278 struct objc_method_list *methods;
6279 if (flag_next_runtime)
6280 struct objc_cache *cache;
6282 struct sarray *dtable;
6283 struct objc_class *subclass_list;
6284 struct objc_class *sibling_class;
6286 struct objc_protocol_list *protocols;
6287 if (flag_next_runtime)
6289 void *gc_object_type;
6293 build_shared_structure_initializer (tree type
, tree isa
, tree super
,
6294 tree name
, tree size
, int status
,
6295 tree dispatch_table
, tree ivar_list
,
6299 VEC(constructor_elt
,gc
) *v
= NULL
;
6302 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, isa
);
6305 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, super
);
6308 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, default_conversion (name
));
6311 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
6312 build_int_cst (long_integer_type_node
, 0));
6315 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
6316 build_int_cst (long_integer_type_node
, status
));
6318 /* instance_size = */
6319 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
6320 convert (long_integer_type_node
, size
));
6322 /* objc_ivar_list = */
6324 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6327 expr
= convert (objc_ivar_list_ptr
,
6328 build_unary_op (input_location
, ADDR_EXPR
,
6330 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6333 /* objc_method_list = */
6334 if (!dispatch_table
)
6335 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6338 expr
= convert (objc_method_list_ptr
,
6339 build_unary_op (input_location
, ADDR_EXPR
,
6340 dispatch_table
, 0));
6341 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6344 if (flag_next_runtime
)
6345 /* method_cache = */
6346 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6350 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6352 /* subclass_list = */
6353 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6355 /* sibling_class = */
6356 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6359 /* protocol_list = */
6360 if (! protocol_list
)
6361 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6364 expr
= convert (build_pointer_type
6366 (objc_protocol_template
)),
6367 build_unary_op (input_location
, ADDR_EXPR
,
6369 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
6372 if (flag_next_runtime
)
6374 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6376 /* gc_object_type = NULL */
6377 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
6379 return objc_build_constructor (type
, v
);
6382 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
6385 lookup_category (tree klass
, tree cat_name
)
6387 tree category
= CLASS_CATEGORY_LIST (klass
);
6389 while (category
&& CLASS_SUPER_NAME (category
) != cat_name
)
6390 category
= CLASS_CATEGORY_LIST (category
);
6394 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
6397 generate_category (struct imp_entry
*impent
)
6399 tree initlist
, cat_name_expr
, class_name_expr
;
6400 tree protocol_decl
, category
;
6401 tree cat
= impent
->imp_context
;
6403 implementation_template
= impent
->imp_template
;
6404 UOBJC_CLASS_decl
= impent
->class_decl
;
6405 UOBJC_METACLASS_decl
= impent
->meta_decl
;
6407 add_class_reference (CLASS_NAME (cat
));
6408 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
6410 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
6412 category
= lookup_category (implementation_template
,
6413 CLASS_SUPER_NAME (cat
));
6415 if (category
&& CLASS_PROTOCOL_LIST (category
))
6417 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
6418 protocol_decl
= generate_protocol_list (category
);
6423 initlist
= build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl
),
6424 cat_name_expr
, class_name_expr
,
6425 UOBJC_INSTANCE_METHODS_decl
,
6426 UOBJC_CLASS_METHODS_decl
,
6428 /* Finish and initialize the forward decl. */
6429 finish_var_decl (UOBJC_CLASS_decl
, initlist
);
6432 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
6433 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6436 generate_shared_structures (struct imp_entry
*impent
)
6438 tree name_expr
, super_expr
, root_expr
;
6439 tree my_root_id
, my_super_id
;
6440 tree cast_type
, initlist
, protocol_decl
;
6443 objc_implementation_context
= impent
->imp_context
;
6444 implementation_template
= impent
->imp_template
;
6445 UOBJC_CLASS_decl
= impent
->class_decl
;
6446 UOBJC_METACLASS_decl
= impent
->meta_decl
;
6447 cls_flags
= impent
->has_cxx_cdtors
? CLS_HAS_CXX_STRUCTORS
: 0 ;
6449 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
6452 add_class_reference (my_super_id
);
6454 /* Compute "my_root_id" - this is required for code generation.
6455 the "isa" for all meta class structures points to the root of
6456 the inheritance hierarchy (e.g. "__Object")... */
6457 my_root_id
= my_super_id
;
6460 tree my_root_int
= lookup_interface (my_root_id
);
6462 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
6463 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
6470 /* No super class. */
6471 my_root_id
= CLASS_NAME (implementation_template
);
6473 cast_type
= build_pointer_type (objc_class_template
);
6474 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
6477 /* Install class `isa' and `super' pointers at runtime. */
6479 super_expr
= add_objc_string (my_super_id
, class_names
);
6481 super_expr
= integer_zero_node
;
6483 super_expr
= build_c_cast (input_location
,
6484 cast_type
, super_expr
); /* cast! */
6486 root_expr
= add_objc_string (my_root_id
, class_names
);
6487 root_expr
= build_c_cast (input_location
, cast_type
, root_expr
); /* cast! */
6489 if (CLASS_PROTOCOL_LIST (implementation_template
))
6491 generate_protocol_references
6492 (CLASS_PROTOCOL_LIST (implementation_template
));
6493 protocol_decl
= generate_protocol_list (implementation_template
);
6498 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
6501 = build_shared_structure_initializer
6502 (TREE_TYPE (UOBJC_METACLASS_decl
),
6503 root_expr
, super_expr
, name_expr
,
6504 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
6506 UOBJC_CLASS_METHODS_decl
,
6507 UOBJC_CLASS_VARIABLES_decl
,
6510 finish_var_decl (UOBJC_METACLASS_decl
, initlist
);
6512 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6515 = build_shared_structure_initializer
6516 (TREE_TYPE (UOBJC_CLASS_decl
),
6517 build_unary_op (input_location
, ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
6518 super_expr
, name_expr
,
6519 convert (integer_type_node
,
6520 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
6521 (implementation_template
))),
6522 1 /*CLS_FACTORY*/ | cls_flags
,
6523 UOBJC_INSTANCE_METHODS_decl
,
6524 UOBJC_INSTANCE_VARIABLES_decl
,
6527 finish_var_decl (UOBJC_CLASS_decl
, initlist
);
6532 synth_id_with_class_suffix (const char *preamble
, tree ctxt
)
6534 static char string
[BUFSIZE
];
6536 switch (TREE_CODE (ctxt
))
6538 case CLASS_IMPLEMENTATION_TYPE
:
6539 case CLASS_INTERFACE_TYPE
:
6540 sprintf (string
, "%s_%s", preamble
,
6541 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
6543 case CATEGORY_IMPLEMENTATION_TYPE
:
6544 case CATEGORY_INTERFACE_TYPE
:
6546 /* We have a category. */
6547 const char *const class_name
6548 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
6549 const char *const class_super_name
6550 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
6551 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
6554 case PROTOCOL_INTERFACE_TYPE
:
6556 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
6557 sprintf (string
, "%s_%s", preamble
, protocol_name
);
6567 /* If type is empty or only type qualifiers are present, add default
6568 type of id (otherwise grokdeclarator will default to int). */
6570 adjust_type_for_id_default (tree type
)
6573 type
= make_node (TREE_LIST
);
6575 if (!TREE_VALUE (type
))
6576 TREE_VALUE (type
) = objc_object_type
;
6577 else if (TREE_CODE (TREE_VALUE (type
)) == RECORD_TYPE
6578 && TYPED_OBJECT (TREE_VALUE (type
)))
6579 error ("can not use an object as parameter to a method");
6584 /* Return a KEYWORD_DECL built using the specified key_name, arg_type,
6585 arg_name and attributes. (TODO: Rename KEYWORD_DECL to
6586 OBJC_METHOD_PARM_DECL ?)
6588 A KEYWORD_DECL is a tree representing the declaration of a
6589 parameter of an Objective-C method. It is produced when parsing a
6590 fragment of Objective-C method declaration of the form
6593 selector ':' '(' typename ')' identifier
6595 For example, take the Objective-C method
6597 -(NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type;
6599 the two fragments "pathForResource:(NSString *)resource" and
6600 "ofType:(NSString *)type" will generate a KEYWORD_DECL each. The
6601 KEYWORD_DECL stores the 'key_name' (eg, identifier for
6602 "pathForResource"), the 'arg_type' (eg, tree representing a
6603 NSString *), the 'arg_name' (eg identifier for "resource") and
6604 potentially some attributes (for example, a tree representing
6605 __attribute__ ((unused)) if such an attribute was attached to a
6606 certain parameter). You can access this information using the
6607 TREE_TYPE (for arg_type), KEYWORD_ARG_NAME (for arg_name),
6608 KEYWORD_KEY_NAME (for key_name), DECL_ATTRIBUTES (for attributes).
6610 'key_name' is an identifier node (and is optional as you can omit
6611 it in Objective-C methods).
6612 'arg_type' is a tree list (and is optional too if no parameter type
6614 'arg_name' is an identifier node and is required.
6615 'attributes' is an optional tree containing parameter attributes. */
6617 objc_build_keyword_decl (tree key_name
, tree arg_type
,
6618 tree arg_name
, tree attributes
)
6622 /* If no type is specified, default to "id". */
6623 arg_type
= adjust_type_for_id_default (arg_type
);
6625 keyword_decl
= make_node (KEYWORD_DECL
);
6627 TREE_TYPE (keyword_decl
) = arg_type
;
6628 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
6629 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
6630 DECL_ATTRIBUTES (keyword_decl
) = attributes
;
6632 return keyword_decl
;
6635 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
6637 build_keyword_selector (tree selector
)
6640 tree key_chain
, key_name
;
6643 /* Scan the selector to see how much space we'll need. */
6644 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
6646 switch (TREE_CODE (selector
))
6649 key_name
= KEYWORD_KEY_NAME (key_chain
);
6652 key_name
= TREE_PURPOSE (key_chain
);
6659 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
6661 /* Just a ':' arg. */
6665 buf
= (char *) alloca (len
+ 1);
6666 /* Start the buffer out as an empty string. */
6669 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
6671 switch (TREE_CODE (selector
))
6674 key_name
= KEYWORD_KEY_NAME (key_chain
);
6677 key_name
= TREE_PURPOSE (key_chain
);
6678 /* The keyword decl chain will later be used as a function
6679 argument chain. Unhook the selector itself so as to not
6680 confuse other parts of the compiler. */
6681 TREE_PURPOSE (key_chain
) = NULL_TREE
;
6688 strcat (buf
, IDENTIFIER_POINTER (key_name
));
6692 return get_identifier (buf
);
6695 /* Used for declarations and definitions. */
6698 build_method_decl (enum tree_code code
, tree ret_type
, tree selector
,
6699 tree add_args
, bool ellipsis
)
6703 /* If no type is specified, default to "id". */
6704 ret_type
= adjust_type_for_id_default (ret_type
);
6706 method_decl
= make_node (code
);
6707 TREE_TYPE (method_decl
) = ret_type
;
6709 /* If we have a keyword selector, create an identifier_node that
6710 represents the full selector name (`:' included)... */
6711 if (TREE_CODE (selector
) == KEYWORD_DECL
)
6713 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
6714 METHOD_SEL_ARGS (method_decl
) = selector
;
6715 METHOD_ADD_ARGS (method_decl
) = add_args
;
6716 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl
) = ellipsis
;
6720 METHOD_SEL_NAME (method_decl
) = selector
;
6721 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
6722 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
6728 #define METHOD_DEF 0
6729 #define METHOD_REF 1
6731 /* This routine processes objective-c method attributes. */
6734 objc_decl_method_attributes (tree
*node
, tree attributes
, int flags
)
6736 tree sentinel_attr
= lookup_attribute ("sentinel", attributes
);
6739 /* hackery to make an obj method look like a function type. */
6740 tree rettype
= TREE_TYPE (*node
);
6741 TREE_TYPE (*node
) = build_function_type (TREE_VALUE (rettype
),
6742 get_arg_type_list (*node
, METHOD_REF
, 0));
6743 decl_attributes (node
, attributes
, flags
);
6744 METHOD_TYPE_ATTRIBUTES (*node
) = TYPE_ATTRIBUTES (TREE_TYPE (*node
));
6745 TREE_TYPE (*node
) = rettype
;
6748 decl_attributes (node
, attributes
, flags
);
6752 objc_method_decl (enum tree_code opcode
)
6754 return opcode
== INSTANCE_METHOD_DECL
|| opcode
== CLASS_METHOD_DECL
;
6757 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6758 an argument list for method METH. CONTEXT is either METHOD_DEF or
6759 METHOD_REF, saying whether we are trying to define a method or call
6760 one. SUPERFLAG says this is for a send to super; this makes a
6761 difference for the NeXT calling sequence in which the lookup and
6762 the method call are done together. If METH is null, user-defined
6763 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6766 get_arg_type_list (tree meth
, int context
, int superflag
)
6770 /* Receiver type. */
6771 if (flag_next_runtime
&& superflag
)
6772 arglist
= build_tree_list (NULL_TREE
, objc_super_type
);
6773 else if (context
== METHOD_DEF
&& TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
6774 arglist
= build_tree_list (NULL_TREE
, objc_instance_type
);
6776 arglist
= build_tree_list (NULL_TREE
, objc_object_type
);
6778 /* Selector type - will eventually change to `int'. */
6779 chainon (arglist
, build_tree_list (NULL_TREE
, objc_selector_type
));
6781 /* No actual method prototype given -- assume that remaining arguments
6786 /* Build a list of argument types. */
6787 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= DECL_CHAIN (akey
))
6789 tree arg_type
= TREE_VALUE (TREE_TYPE (akey
));
6791 /* Decay argument types for the underlying C function as appropriate. */
6792 arg_type
= objc_decay_parm_type (arg_type
);
6794 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
6797 if (METHOD_ADD_ARGS (meth
))
6799 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
6800 akey
; akey
= TREE_CHAIN (akey
))
6802 tree arg_type
= TREE_TYPE (TREE_VALUE (akey
));
6804 arg_type
= objc_decay_parm_type (arg_type
);
6806 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
6809 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth
))
6810 goto lack_of_ellipsis
;
6815 chainon (arglist
, OBJC_VOID_AT_END
);
6822 check_duplicates (hash hsh
, int methods
, int is_class
)
6824 tree meth
= NULL_TREE
;
6832 /* We have two or more methods with the same name but
6836 /* But just how different are those types? If
6837 -Wno-strict-selector-match is specified, we shall not
6838 complain if the differences are solely among types with
6839 identical size and alignment. */
6840 if (!warn_strict_selector_match
)
6842 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
6843 if (!comp_proto_with_proto (meth
, loop
->value
, 0))
6852 bool type
= TREE_CODE (meth
) == INSTANCE_METHOD_DECL
;
6854 warning_at (input_location
, 0,
6855 "multiple methods named %<%c%E%> found",
6856 (is_class
? '+' : '-'),
6857 METHOD_SEL_NAME (meth
));
6858 inform (DECL_SOURCE_LOCATION (meth
), "using %<%c%s%>",
6860 identifier_to_locale (gen_method_decl (meth
)));
6864 bool type
= TREE_CODE (meth
) == INSTANCE_METHOD_DECL
;
6866 warning_at (input_location
, 0,
6867 "multiple selectors named %<%c%E%> found",
6868 (is_class
? '+' : '-'),
6869 METHOD_SEL_NAME (meth
));
6870 inform (DECL_SOURCE_LOCATION (meth
), "found %<%c%s%>",
6872 identifier_to_locale (gen_method_decl (meth
)));
6875 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
6877 bool type
= TREE_CODE (loop
->value
) == INSTANCE_METHOD_DECL
;
6879 inform (DECL_SOURCE_LOCATION (loop
->value
), "also found %<%c%s%>",
6881 identifier_to_locale (gen_method_decl (loop
->value
)));
6888 /* If RECEIVER is a class reference, return the identifier node for
6889 the referenced class. RECEIVER is created by objc_get_class_reference,
6890 so we check the exact form created depending on which runtimes are
6894 receiver_is_class_object (tree receiver
, int self
, int super
)
6896 tree chain
, exp
, arg
;
6898 /* The receiver is 'self' or 'super' in the context of a class method. */
6899 if (objc_method_context
6900 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
6903 ? CLASS_SUPER_NAME (implementation_template
)
6904 : CLASS_NAME (implementation_template
));
6906 if (flag_next_runtime
)
6908 /* The receiver is a variable created by
6909 build_class_reference_decl. */
6910 if (TREE_CODE (receiver
) == VAR_DECL
&& IS_CLASS (TREE_TYPE (receiver
)))
6911 /* Look up the identifier. */
6912 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
6913 if (TREE_PURPOSE (chain
) == receiver
)
6914 return TREE_VALUE (chain
);
6917 /* The receiver is a function call that returns an id. Check if
6918 it is a call to objc_getClass, if so, pick up the class name. */
6919 if (TREE_CODE (receiver
) == CALL_EXPR
6920 && (exp
= CALL_EXPR_FN (receiver
))
6921 && TREE_CODE (exp
) == ADDR_EXPR
6922 && (exp
= TREE_OPERAND (exp
, 0))
6923 && TREE_CODE (exp
) == FUNCTION_DECL
6924 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6925 prototypes for objc_get_class(). Thankfully, they seem to share the
6926 same function type. */
6927 && TREE_TYPE (exp
) == TREE_TYPE (objc_get_class_decl
)
6928 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp
)), TAG_GETCLASS
)
6929 /* We have a call to objc_get_class/objc_getClass! */
6930 && (arg
= CALL_EXPR_ARG (receiver
, 0)))
6933 if (TREE_CODE (arg
) == ADDR_EXPR
6934 && (arg
= TREE_OPERAND (arg
, 0))
6935 && TREE_CODE (arg
) == STRING_CST
)
6936 /* Finally, we have the class name. */
6937 return get_identifier (TREE_STRING_POINTER (arg
));
6942 /* If we are currently building a message expr, this holds
6943 the identifier of the selector of the message. This is
6944 used when printing warnings about argument mismatches. */
6946 static tree current_objc_message_selector
= 0;
6949 objc_message_selector (void)
6951 return current_objc_message_selector
;
6954 /* Construct an expression for sending a message.
6955 MESS has the object to send to in TREE_PURPOSE
6956 and the argument list (including selector) in TREE_VALUE.
6958 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6959 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6962 objc_build_message_expr (tree mess
)
6964 tree receiver
= TREE_PURPOSE (mess
);
6967 tree args
= TREE_PURPOSE (TREE_VALUE (mess
));
6969 tree args
= TREE_VALUE (mess
);
6971 tree method_params
= NULL_TREE
;
6973 if (TREE_CODE (receiver
) == ERROR_MARK
|| TREE_CODE (args
) == ERROR_MARK
)
6974 return error_mark_node
;
6976 /* Obtain the full selector name. */
6977 switch (TREE_CODE (args
))
6979 case IDENTIFIER_NODE
:
6980 /* A unary selector. */
6984 sel_name
= build_keyword_selector (args
);
6990 /* Build the parameter list to give to the method. */
6991 if (TREE_CODE (args
) == TREE_LIST
)
6993 method_params
= chainon (args
, TREE_VALUE (TREE_VALUE (mess
)));
6996 tree chain
= args
, prev
= NULL_TREE
;
6998 /* We have a keyword selector--check for comma expressions. */
7001 tree element
= TREE_VALUE (chain
);
7003 /* We have a comma expression, must collapse... */
7004 if (TREE_CODE (element
) == TREE_LIST
)
7007 TREE_CHAIN (prev
) = element
;
7012 chain
= TREE_CHAIN (chain
);
7014 method_params
= args
;
7019 if (processing_template_decl
)
7020 /* Must wait until template instantiation time. */
7021 return build_min_nt (MESSAGE_SEND_EXPR
, receiver
, sel_name
,
7025 return objc_finish_message_expr (receiver
, sel_name
, method_params
);
7028 /* Look up method SEL_NAME that would be suitable for receiver
7029 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
7030 nonzero), and report on any duplicates. */
7033 lookup_method_in_hash_lists (tree sel_name
, int is_class
)
7035 hash method_prototype
= NULL
;
7038 method_prototype
= hash_lookup (nst_method_hash_list
,
7041 if (!method_prototype
)
7043 method_prototype
= hash_lookup (cls_method_hash_list
,
7048 return check_duplicates (method_prototype
, 1, is_class
);
7051 /* The 'objc_finish_message_expr' routine is called from within
7052 'objc_build_message_expr' for non-template functions. In the case of
7053 C++ template functions, it is called from 'build_expr_from_tree'
7054 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
7057 objc_finish_message_expr (tree receiver
, tree sel_name
, tree method_params
)
7059 tree method_prototype
= NULL_TREE
, rprotos
= NULL_TREE
, rtype
;
7060 tree selector
, retval
, class_tree
;
7061 int self
, super
, have_cast
;
7063 /* We have used the receiver, so mark it as read. */
7064 mark_exp_read (receiver
);
7066 /* Extract the receiver of the message, as well as its type
7067 (where the latter may take the form of a cast or be inferred
7068 from the implementation context). */
7070 while (TREE_CODE (rtype
) == COMPOUND_EXPR
7071 || TREE_CODE (rtype
) == MODIFY_EXPR
7072 || CONVERT_EXPR_P (rtype
)
7073 || TREE_CODE (rtype
) == COMPONENT_REF
)
7074 rtype
= TREE_OPERAND (rtype
, 0);
7076 self
= (rtype
== self_decl
);
7077 super
= (rtype
== UOBJC_SUPER_decl
);
7078 rtype
= TREE_TYPE (receiver
);
7080 have_cast
= (TREE_CODE (receiver
) == NOP_EXPR
7081 || (TREE_CODE (receiver
) == COMPOUND_EXPR
7082 && !IS_SUPER (rtype
)));
7084 /* If we are calling [super dealloc], reset our warning flag. */
7085 if (super
&& !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name
)))
7086 should_call_super_dealloc
= 0;
7088 /* If the receiver is a class object, retrieve the corresponding
7089 @interface, if one exists. */
7090 class_tree
= receiver_is_class_object (receiver
, self
, super
);
7092 /* Now determine the receiver type (if an explicit cast has not been
7097 rtype
= lookup_interface (class_tree
);
7098 /* Handle `self' and `super'. */
7101 if (!CLASS_SUPER_NAME (implementation_template
))
7103 error ("no super class declared in @interface for %qE",
7104 CLASS_NAME (implementation_template
));
7105 return error_mark_node
;
7107 rtype
= lookup_interface (CLASS_SUPER_NAME (implementation_template
));
7110 rtype
= lookup_interface (CLASS_NAME (implementation_template
));
7113 /* If receiver is of type `id' or `Class' (or if the @interface for a
7114 class is not visible), we shall be satisfied with the existence of
7115 any instance or class method. */
7116 if (objc_is_id (rtype
))
7118 class_tree
= (IS_CLASS (rtype
) ? objc_class_name
: NULL_TREE
);
7119 rprotos
= (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype
))
7120 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype
))
7126 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
7127 in protocols themselves for the method prototype. */
7129 = lookup_method_in_protocol_list (rprotos
, sel_name
,
7130 class_tree
!= NULL_TREE
);
7132 /* If messaging 'Class <Proto>' but did not find a class method
7133 prototype, search for an instance method instead, and warn
7134 about having done so. */
7135 if (!method_prototype
&& !rtype
&& class_tree
!= NULL_TREE
)
7138 = lookup_method_in_protocol_list (rprotos
, sel_name
, 0);
7140 if (method_prototype
)
7141 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
7142 sel_name
, sel_name
);
7148 tree orig_rtype
= rtype
;
7150 if (TREE_CODE (rtype
) == POINTER_TYPE
)
7151 rtype
= TREE_TYPE (rtype
);
7152 /* Traverse typedef aliases */
7153 while (TREE_CODE (rtype
) == RECORD_TYPE
&& OBJC_TYPE_NAME (rtype
)
7154 && TREE_CODE (OBJC_TYPE_NAME (rtype
)) == TYPE_DECL
7155 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
)))
7156 rtype
= DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
));
7157 if (TYPED_OBJECT (rtype
))
7159 rprotos
= TYPE_OBJC_PROTOCOL_LIST (rtype
);
7160 rtype
= TYPE_OBJC_INTERFACE (rtype
);
7162 /* If we could not find an @interface declaration, we must have
7163 only seen a @class declaration; so, we cannot say anything
7164 more intelligent about which methods the receiver will
7166 if (!rtype
|| TREE_CODE (rtype
) == IDENTIFIER_NODE
)
7169 /* We could not find an @interface declaration, yet Message maybe in a
7170 @class's protocol. */
7171 if (!method_prototype
&& rprotos
)
7173 = lookup_method_in_protocol_list (rprotos
, sel_name
, 0);
7175 else if (TREE_CODE (rtype
) == CLASS_INTERFACE_TYPE
7176 || TREE_CODE (rtype
) == CLASS_IMPLEMENTATION_TYPE
)
7178 /* We have a valid ObjC class name. Look up the method name
7179 in the published @interface for the class (and its
7182 = lookup_method_static (rtype
, sel_name
, class_tree
!= NULL_TREE
);
7184 /* If the method was not found in the @interface, it may still
7185 exist locally as part of the @implementation. */
7186 if (!method_prototype
&& objc_implementation_context
7187 && CLASS_NAME (objc_implementation_context
)
7188 == OBJC_TYPE_NAME (rtype
))
7192 ? CLASS_CLS_METHODS (objc_implementation_context
)
7193 : CLASS_NST_METHODS (objc_implementation_context
)),
7196 /* If we haven't found a candidate method by now, try looking for
7197 it in the protocol list. */
7198 if (!method_prototype
&& rprotos
)
7200 = lookup_method_in_protocol_list (rprotos
, sel_name
,
7201 class_tree
!= NULL_TREE
);
7205 warning (0, "invalid receiver type %qs",
7206 identifier_to_locale (gen_type_name (orig_rtype
)));
7207 /* After issuing the "invalid receiver" warning, perform method
7208 lookup as if we were messaging 'id'. */
7209 rtype
= rprotos
= NULL_TREE
;
7214 /* For 'id' or 'Class' receivers, search in the global hash table
7215 as a last resort. For all receivers, warn if protocol searches
7217 if (!method_prototype
)
7220 warning (0, "%<%c%E%> not found in protocol(s)",
7221 (class_tree
? '+' : '-'),
7226 = lookup_method_in_hash_lists (sel_name
, class_tree
!= NULL_TREE
);
7229 if (!method_prototype
&& in_objc_property_setter_name_context
)
7230 error ("readonly property can not be set");
7231 else if (!method_prototype
)
7233 static bool warn_missing_methods
= false;
7236 warning (0, "%qE may not respond to %<%c%E%>",
7237 OBJC_TYPE_NAME (rtype
),
7238 (class_tree
? '+' : '-'),
7240 /* If we are messaging an 'id' or 'Class' object and made it here,
7241 then we have failed to find _any_ instance or class method,
7244 warning (0, "no %<%c%E%> method found",
7245 (class_tree
? '+' : '-'),
7248 if (!warn_missing_methods
)
7250 warning_at (input_location
,
7251 0, "(Messages without a matching method signature");
7252 warning_at (input_location
,
7253 0, "will be assumed to return %<id%> and accept");
7254 warning_at (input_location
,
7255 0, "%<...%> as arguments.)");
7256 warn_missing_methods
= true;
7260 /* Save the selector name for printing error messages. */
7261 current_objc_message_selector
= sel_name
;
7263 /* Build the parameters list for looking up the method.
7264 These are the object itself and the selector. */
7266 if (flag_typed_selectors
)
7267 selector
= build_typed_selector_reference (input_location
,
7268 sel_name
, method_prototype
);
7270 selector
= build_selector_reference (input_location
, sel_name
);
7272 retval
= build_objc_method_call (input_location
, super
, method_prototype
,
7274 selector
, method_params
);
7276 current_objc_message_selector
= 0;
7281 /* Build a tree expression to send OBJECT the operation SELECTOR,
7282 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
7283 assuming the method has prototype METHOD_PROTOTYPE.
7284 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
7285 LOC is the location of the expression to build.
7286 Use METHOD_PARAMS as list of args to pass to the method.
7287 If SUPER_FLAG is nonzero, we look up the superclass's method. */
7290 build_objc_method_call (location_t loc
, int super_flag
, tree method_prototype
,
7291 tree lookup_object
, tree selector
,
7294 tree sender
= (super_flag
? umsg_super_decl
:
7295 (!flag_next_runtime
|| flag_nil_receivers
7296 ? (flag_objc_direct_dispatch
7299 : umsg_nonnil_decl
));
7300 tree rcv_p
= (super_flag
? objc_super_type
: objc_object_type
);
7301 VEC(tree
, gc
) *parms
= NULL
;
7302 unsigned nparm
= (method_params
? list_length (method_params
) : 0);
7304 /* If a prototype for the method to be called exists, then cast
7305 the sender's return type and arguments to match that of the method.
7306 Otherwise, leave sender as is. */
7309 ? TREE_VALUE (TREE_TYPE (method_prototype
))
7310 : objc_object_type
);
7312 tree method_param_types
=
7313 get_arg_type_list (method_prototype
, METHOD_REF
, super_flag
);
7314 tree ftype
= build_function_type (ret_type
, method_param_types
);
7318 if (method_prototype
&& METHOD_TYPE_ATTRIBUTES (method_prototype
))
7319 ftype
= build_type_attribute_variant (
7320 ftype
, METHOD_TYPE_ATTRIBUTES (method_prototype
));
7322 sender_cast
= build_pointer_type (ftype
);
7324 if (method_prototype
&& TREE_DEPRECATED (method_prototype
))
7325 warn_deprecated_use (method_prototype
, NULL_TREE
);
7327 lookup_object
= build_c_cast (loc
, rcv_p
, lookup_object
);
7329 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
7330 lookup_object
= save_expr (lookup_object
);
7332 /* Param list + 2 slots for object and selector. */
7333 parms
= VEC_alloc (tree
, gc
, nparm
+ 2);
7335 if (flag_next_runtime
)
7337 /* If we are returning a struct in memory, and the address
7338 of that memory location is passed as a hidden first
7339 argument, then change which messenger entry point this
7340 expr will call. NB: Note that sender_cast remains
7341 unchanged (it already has a struct return type). */
7342 if (!targetm
.calls
.struct_value_rtx (0, 0)
7343 && (TREE_CODE (ret_type
) == RECORD_TYPE
7344 || TREE_CODE (ret_type
) == UNION_TYPE
)
7345 && targetm
.calls
.return_in_memory (ret_type
, 0))
7346 sender
= (super_flag
? umsg_super_stret_decl
:
7347 flag_nil_receivers
? umsg_stret_decl
: umsg_nonnil_stret_decl
);
7349 method
= build_fold_addr_expr_loc (input_location
, sender
);
7350 /* Pass the object to the method. */
7351 VEC_quick_push (tree
, parms
, lookup_object
);
7355 /* This is the portable (GNU) way. */
7356 /* First, call the lookup function to get a pointer to the method,
7357 then cast the pointer, then call it with the method arguments. */
7358 VEC(tree
, gc
) *tv
= VEC_alloc (tree
, gc
, 2);
7359 VEC_quick_push (tree
, tv
, lookup_object
);
7360 VEC_quick_push (tree
, tv
, selector
);
7361 method
= build_function_call_vec (loc
, sender
, tv
, NULL
);
7362 VEC_free (tree
, gc
, tv
);
7364 /* Pass the appropriate object to the method. */
7365 VEC_quick_push (tree
, parms
, (super_flag
? self_decl
: lookup_object
));
7368 /* Pass the selector to the method. */
7369 VEC_quick_push (tree
, parms
, selector
);
7370 /* Now append the remainder of the parms. */
7372 for (; method_params
; method_params
= TREE_CHAIN (method_params
))
7373 VEC_quick_push (tree
, parms
, TREE_VALUE (method_params
));
7375 /* Build an obj_type_ref, with the correct cast for the method call. */
7376 t
= build3 (OBJ_TYPE_REF
, sender_cast
, method
,
7377 lookup_object
, size_zero_node
);
7378 t
= build_function_call_vec (loc
, t
, parms
, NULL
);\
7379 VEC_free (tree
, gc
, parms
);
7384 build_protocol_reference (tree p
)
7387 const char *proto_name
;
7389 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
7391 proto_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
7392 decl
= start_var_decl (objc_protocol_template
, proto_name
);
7394 PROTOCOL_FORWARD_DECL (p
) = decl
;
7397 /* This function is called by the parser when (and only when) a
7398 @protocol() expression is found, in order to compile it. */
7400 objc_build_protocol_expr (tree protoname
)
7403 tree p
= lookup_protocol (protoname
);
7407 error ("cannot find protocol declaration for %qE",
7409 return error_mark_node
;
7412 if (!PROTOCOL_FORWARD_DECL (p
))
7413 build_protocol_reference (p
);
7415 expr
= build_unary_op (input_location
,
7416 ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
7418 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
7419 if we have it, rather than converting it here. */
7420 expr
= convert (objc_protocol_type
, expr
);
7422 /* The @protocol() expression is being compiled into a pointer to a
7423 statically allocated instance of the Protocol class. To become
7424 usable at runtime, the 'isa' pointer of the instance need to be
7425 fixed up at runtime by the runtime library, to point to the
7426 actual 'Protocol' class. */
7428 /* For the GNU runtime, put the static Protocol instance in the list
7429 of statically allocated instances, so that we make sure that its
7430 'isa' pointer is fixed up at runtime by the GNU runtime library
7431 to point to the Protocol class (at runtime, when loading the
7432 module, the GNU runtime library loops on the statically allocated
7433 instances (as found in the defs field in objc_symtab) and fixups
7434 all the 'isa' pointers of those objects). */
7435 if (! flag_next_runtime
)
7437 /* This type is a struct containing the fields of a Protocol
7438 object. (Cfr. objc_protocol_type instead is the type of a pointer
7439 to such a struct). */
7440 tree protocol_struct_type
= xref_tag
7441 (RECORD_TYPE
, get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
7444 /* Look for the list of Protocol statically allocated instances
7445 to fixup at runtime. Create a new list to hold Protocol
7446 statically allocated instances, if the list is not found. At
7447 present there is only another list, holding NSConstantString
7448 static instances to be fixed up at runtime. */
7449 for (chain
= &objc_static_instances
;
7450 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
7451 chain
= &TREE_CHAIN (*chain
));
7454 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
7455 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type
),
7459 /* Add this statically allocated instance to the Protocol list. */
7460 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
7461 PROTOCOL_FORWARD_DECL (p
),
7462 TREE_PURPOSE (*chain
));
7469 /* This function is called by the parser when a @selector() expression
7470 is found, in order to compile it. It is only called by the parser
7471 and only to compile a @selector(). LOC is the location of the
7474 objc_build_selector_expr (location_t loc
, tree selnamelist
)
7478 /* Obtain the full selector name. */
7479 switch (TREE_CODE (selnamelist
))
7481 case IDENTIFIER_NODE
:
7482 /* A unary selector. */
7483 selname
= selnamelist
;
7486 selname
= build_keyword_selector (selnamelist
);
7492 /* If we are required to check @selector() expressions as they
7493 are found, check that the selector has been declared. */
7494 if (warn_undeclared_selector
)
7496 /* Look the selector up in the list of all known class and
7497 instance methods (up to this line) to check that the selector
7501 /* First try with instance methods. */
7502 hsh
= hash_lookup (nst_method_hash_list
, selname
);
7504 /* If not found, try with class methods. */
7507 hsh
= hash_lookup (cls_method_hash_list
, selname
);
7510 /* If still not found, print out a warning. */
7513 warning (0, "undeclared selector %qE", selname
);
7518 if (flag_typed_selectors
)
7519 return build_typed_selector_reference (loc
, selname
, 0);
7521 return build_selector_reference (loc
, selname
);
7524 /* This is used to implement @encode(). See gcc/doc/objc.texi,
7525 section '@encode'. */
7527 objc_build_encode_expr (tree type
)
7532 encode_type (type
, obstack_object_size (&util_obstack
),
7533 OBJC_ENCODE_INLINE_DEFS
);
7534 obstack_1grow (&util_obstack
, 0); /* null terminate string */
7535 string
= XOBFINISH (&util_obstack
, const char *);
7537 /* Synthesize a string that represents the encoded struct/union. */
7538 result
= my_build_string (strlen (string
) + 1, string
);
7539 obstack_free (&util_obstack
, util_firstobj
);
7544 build_ivar_reference (tree id
)
7546 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7548 /* Historically, a class method that produced objects (factory
7549 method) would assign `self' to the instance that it
7550 allocated. This would effectively turn the class method into
7551 an instance method. Following this assignment, the instance
7552 variables could be accessed. That practice, while safe,
7553 violates the simple rule that a class method should not refer
7554 to an instance variable. It's better to catch the cases
7555 where this is done unknowingly than to support the above
7557 warning (0, "instance variable %qE accessed in class method",
7559 self_decl
= convert (objc_instance_type
, self_decl
); /* cast */
7562 return objc_build_component_ref (build_indirect_ref (input_location
,
7563 self_decl
, RO_ARROW
),
7567 /* Compute a hash value for a given method SEL_NAME. */
7570 hash_func (tree sel_name
)
7572 const unsigned char *s
7573 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
7577 h
= h
* 67 + *s
++ - 113;
7584 nst_method_hash_list
= ggc_alloc_cleared_vec_hash (SIZEHASHTABLE
);
7585 cls_method_hash_list
= ggc_alloc_cleared_vec_hash (SIZEHASHTABLE
);
7587 cls_name_hash_list
= ggc_alloc_cleared_vec_hash (SIZEHASHTABLE
);
7588 als_name_hash_list
= ggc_alloc_cleared_vec_hash (SIZEHASHTABLE
);
7590 /* Initialize the hash table used to hold the constant string objects. */
7591 string_htab
= htab_create_ggc (31, string_hash
,
7595 /* This routine adds sel_name to the hash list. sel_name is a class or alias
7596 name for the class. If alias name, then value is its underlying class.
7597 If class, the value is NULL_TREE. */
7600 hash_class_name_enter (hash
*hashlist
, tree sel_name
, tree value
)
7603 int slot
= hash_func (sel_name
) % SIZEHASHTABLE
;
7605 obj
= ggc_alloc_hashed_entry ();
7606 if (value
!= NULL_TREE
)
7608 /* Save the underlying class for the 'alias' in the hash table */
7609 attr obj_attr
= ggc_alloc_hashed_attribute ();
7610 obj_attr
->value
= value
;
7611 obj
->list
= obj_attr
;
7615 obj
->next
= hashlist
[slot
];
7616 obj
->key
= sel_name
;
7618 hashlist
[slot
] = obj
; /* append to front */
7623 Searches in the hash table looking for a match for class or alias name.
7627 hash_class_name_lookup (hash
*hashlist
, tree sel_name
)
7631 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
7635 if (sel_name
== target
->key
)
7638 target
= target
->next
;
7643 /* WARNING!!!! hash_enter is called with a method, and will peek
7644 inside to find its selector! But hash_lookup is given a selector
7645 directly, and looks for the selector that's inside the found
7646 entry's key (method) for comparison. */
7649 hash_enter (hash
*hashlist
, tree method
)
7652 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
7654 obj
= ggc_alloc_hashed_entry ();
7656 obj
->next
= hashlist
[slot
];
7659 hashlist
[slot
] = obj
; /* append to front */
7663 hash_lookup (hash
*hashlist
, tree sel_name
)
7667 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
7671 if (sel_name
== METHOD_SEL_NAME (target
->key
))
7674 target
= target
->next
;
7680 hash_add_attr (hash entry
, tree value
)
7684 obj
= ggc_alloc_hashed_attribute ();
7685 obj
->next
= entry
->list
;
7688 entry
->list
= obj
; /* append to front */
7692 lookup_method (tree mchain
, tree method
)
7696 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
7699 key
= METHOD_SEL_NAME (method
);
7703 if (METHOD_SEL_NAME (mchain
) == key
)
7706 mchain
= DECL_CHAIN (mchain
);
7711 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
7712 in INTERFACE, along with any categories and protocols attached thereto.
7713 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
7714 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
7715 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
7716 be found in INTERFACE or any of its superclasses, look for an _instance_
7717 method of the same name in the root class as a last resort.
7719 If a suitable method cannot be found, return NULL_TREE. */
7722 lookup_method_static (tree interface
, tree ident
, int flags
)
7724 tree meth
= NULL_TREE
, root_inter
= NULL_TREE
;
7725 tree inter
= interface
;
7726 int is_class
= (flags
& OBJC_LOOKUP_CLASS
);
7727 int no_superclasses
= (flags
& OBJC_LOOKUP_NO_SUPER
);
7731 tree chain
= is_class
? CLASS_CLS_METHODS (inter
) : CLASS_NST_METHODS (inter
);
7732 tree category
= inter
;
7734 /* First, look up the method in the class itself. */
7735 if ((meth
= lookup_method (chain
, ident
)))
7738 /* Failing that, look for the method in each category of the class. */
7739 while ((category
= CLASS_CATEGORY_LIST (category
)))
7741 chain
= is_class
? CLASS_CLS_METHODS (category
) : CLASS_NST_METHODS (category
);
7743 /* Check directly in each category. */
7744 if ((meth
= lookup_method (chain
, ident
)))
7747 /* Failing that, check in each category's protocols. */
7748 if (CLASS_PROTOCOL_LIST (category
))
7750 if ((meth
= (lookup_method_in_protocol_list
7751 (CLASS_PROTOCOL_LIST (category
), ident
, is_class
))))
7756 /* If not found in categories, check in protocols of the main class. */
7757 if (CLASS_PROTOCOL_LIST (inter
))
7759 if ((meth
= (lookup_method_in_protocol_list
7760 (CLASS_PROTOCOL_LIST (inter
), ident
, is_class
))))
7764 /* If we were instructed not to look in superclasses, don't. */
7765 if (no_superclasses
)
7768 /* Failing that, climb up the inheritance hierarchy. */
7770 inter
= lookup_interface (CLASS_SUPER_NAME (inter
));
7774 /* If no class (factory) method was found, check if an _instance_
7775 method of the same name exists in the root class. This is what
7776 the Objective-C runtime will do. If an instance method was not
7778 return is_class
? lookup_method_static (root_inter
, ident
, 0): NULL_TREE
;
7781 /* Add the method to the hash list if it doesn't contain an identical
7785 add_method_to_hash_list (hash
*hash_list
, tree method
)
7789 if (!(hsh
= hash_lookup (hash_list
, METHOD_SEL_NAME (method
))))
7791 /* Install on a global chain. */
7792 hash_enter (hash_list
, method
);
7796 /* Check types against those; if different, add to a list. */
7798 int already_there
= comp_proto_with_proto (method
, hsh
->key
, 1);
7799 for (loop
= hsh
->list
; !already_there
&& loop
; loop
= loop
->next
)
7800 already_there
|= comp_proto_with_proto (method
, loop
->value
, 1);
7802 hash_add_attr (hsh
, method
);
7807 objc_add_method (tree klass
, tree method
, int is_class
, bool is_optional
)
7811 /* @optional methods are added to protocol's OPTIONAL list */
7814 gcc_assert (TREE_CODE (klass
) == PROTOCOL_INTERFACE_TYPE
);
7815 if (!(mth
= lookup_method (is_class
7816 ? PROTOCOL_OPTIONAL_CLS_METHODS (klass
)
7817 : PROTOCOL_OPTIONAL_NST_METHODS (klass
),
7822 TREE_CHAIN (method
) = PROTOCOL_OPTIONAL_CLS_METHODS (klass
);
7823 PROTOCOL_OPTIONAL_CLS_METHODS (klass
) = method
;
7827 TREE_CHAIN (method
) = PROTOCOL_OPTIONAL_NST_METHODS (klass
);
7828 PROTOCOL_OPTIONAL_NST_METHODS (klass
) = method
;
7832 else if (!(mth
= lookup_method (is_class
7833 ? CLASS_CLS_METHODS (klass
)
7834 : CLASS_NST_METHODS (klass
), method
)))
7836 /* put method on list in reverse order */
7839 DECL_CHAIN (method
) = CLASS_CLS_METHODS (klass
);
7840 CLASS_CLS_METHODS (klass
) = method
;
7844 DECL_CHAIN (method
) = CLASS_NST_METHODS (klass
);
7845 CLASS_NST_METHODS (klass
) = method
;
7850 /* When processing an @interface for a class or category, give hard
7851 errors on methods with identical selectors but differing argument
7852 and/or return types. We do not do this for @implementations, because
7853 C/C++ will do it for us (i.e., there will be duplicate function
7854 definition errors). */
7855 if ((TREE_CODE (klass
) == CLASS_INTERFACE_TYPE
7856 || TREE_CODE (klass
) == CATEGORY_INTERFACE_TYPE
)
7857 && !comp_proto_with_proto (method
, mth
, 1))
7858 error ("duplicate declaration of method %<%c%E%>",
7859 is_class
? '+' : '-',
7860 METHOD_SEL_NAME (mth
));
7864 add_method_to_hash_list (cls_method_hash_list
, method
);
7867 add_method_to_hash_list (nst_method_hash_list
, method
);
7869 /* Instance methods in root classes (and categories thereof)
7870 may act as class methods as a last resort. We also add
7871 instance methods listed in @protocol declarations to
7872 the class hash table, on the assumption that @protocols
7873 may be adopted by root classes or categories. */
7874 if (TREE_CODE (klass
) == CATEGORY_INTERFACE_TYPE
7875 || TREE_CODE (klass
) == CATEGORY_IMPLEMENTATION_TYPE
)
7876 klass
= lookup_interface (CLASS_NAME (klass
));
7878 if (TREE_CODE (klass
) == PROTOCOL_INTERFACE_TYPE
7879 || !CLASS_SUPER_NAME (klass
))
7880 add_method_to_hash_list (cls_method_hash_list
, method
);
7887 add_class (tree class_name
, tree name
)
7889 struct interface_tuple
**slot
;
7891 /* Put interfaces on list in reverse order. */
7892 TREE_CHAIN (class_name
) = interface_chain
;
7893 interface_chain
= class_name
;
7895 if (interface_htab
== NULL
)
7896 interface_htab
= htab_create_ggc (31, hash_interface
, eq_interface
, NULL
);
7897 slot
= (struct interface_tuple
**)
7898 htab_find_slot_with_hash (interface_htab
, name
,
7899 IDENTIFIER_HASH_VALUE (name
),
7903 *slot
= ggc_alloc_cleared_interface_tuple ();
7906 (*slot
)->class_name
= class_name
;
7908 return interface_chain
;
7912 add_category (tree klass
, tree category
)
7914 /* Put categories on list in reverse order. */
7915 tree cat
= lookup_category (klass
, CLASS_SUPER_NAME (category
));
7919 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
7921 CLASS_SUPER_NAME (category
));
7925 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (klass
);
7926 CLASS_CATEGORY_LIST (klass
) = category
;
7930 /* Called after parsing each instance variable declaration. Necessary to
7931 preserve typedefs and implement public/private...
7933 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7936 add_instance_variable (tree klass
, objc_ivar_visibility_kind visibility
,
7939 tree field_type
= TREE_TYPE (field_decl
);
7940 const char *ivar_name
= DECL_NAME (field_decl
)
7941 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl
)))
7945 if (TREE_CODE (field_type
) == REFERENCE_TYPE
)
7947 error ("illegal reference type specified for instance variable %qs",
7949 /* Return class as is without adding this ivar. */
7954 if (field_type
== error_mark_node
|| !TYPE_SIZE (field_type
)
7955 || TYPE_SIZE (field_type
) == error_mark_node
)
7956 /* 'type[0]' is allowed, but 'type[]' is not! */
7958 error ("instance variable %qs has unknown size", ivar_name
);
7959 /* Return class as is without adding this ivar. */
7964 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7965 need to either (1) warn the user about it or (2) generate suitable
7966 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7967 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7968 if (MAYBE_CLASS_TYPE_P (field_type
)
7969 && (TYPE_NEEDS_CONSTRUCTING (field_type
)
7970 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
)
7971 || TYPE_POLYMORPHIC_P (field_type
)))
7973 tree type_name
= OBJC_TYPE_NAME (field_type
);
7975 if (flag_objc_call_cxx_cdtors
)
7977 /* Since the ObjC runtime will be calling the constructors and
7978 destructors for us, the only thing we can't handle is the lack
7979 of a default constructor. */
7980 if (TYPE_NEEDS_CONSTRUCTING (field_type
)
7981 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type
))
7983 warning (0, "type %qE has no default constructor to call",
7986 /* If we cannot call a constructor, we should also avoid
7987 calling the destructor, for symmetry. */
7988 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
7989 warning (0, "destructor for %qE shall not be run either",
7995 static bool warn_cxx_ivars
= false;
7997 if (TYPE_POLYMORPHIC_P (field_type
))
7999 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
8001 error ("type %qE has virtual member functions", type_name
);
8002 error ("illegal aggregate type %qE specified "
8003 "for instance variable %qs",
8004 type_name
, ivar_name
);
8005 /* Return class as is without adding this ivar. */
8009 /* User-defined constructors and destructors are not known to Obj-C
8010 and hence will not be called. This may or may not be a problem. */
8011 if (TYPE_NEEDS_CONSTRUCTING (field_type
))
8012 warning (0, "type %qE has a user-defined constructor", type_name
);
8013 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
8014 warning (0, "type %qE has a user-defined destructor", type_name
);
8016 if (!warn_cxx_ivars
)
8018 warning (0, "C++ constructors and destructors will not "
8019 "be invoked for Objective-C fields");
8020 warn_cxx_ivars
= true;
8026 /* Overload the public attribute, it is not used for FIELD_DECLs. */
8029 case OBJC_IVAR_VIS_PROTECTED
:
8030 TREE_PUBLIC (field_decl
) = 0;
8031 TREE_PRIVATE (field_decl
) = 0;
8032 TREE_PROTECTED (field_decl
) = 1;
8035 case OBJC_IVAR_VIS_PACKAGE
:
8036 /* TODO: Implement the package variant. */
8037 case OBJC_IVAR_VIS_PUBLIC
:
8038 TREE_PUBLIC (field_decl
) = 1;
8039 TREE_PRIVATE (field_decl
) = 0;
8040 TREE_PROTECTED (field_decl
) = 0;
8043 case OBJC_IVAR_VIS_PRIVATE
:
8044 TREE_PUBLIC (field_decl
) = 0;
8045 TREE_PRIVATE (field_decl
) = 1;
8046 TREE_PROTECTED (field_decl
) = 0;
8051 CLASS_RAW_IVARS (klass
) = chainon (CLASS_RAW_IVARS (klass
), field_decl
);
8057 is_ivar (tree decl_chain
, tree ident
)
8059 for ( ; decl_chain
; decl_chain
= DECL_CHAIN (decl_chain
))
8060 if (DECL_NAME (decl_chain
) == ident
)
8065 /* True if the ivar is private and we are not in its implementation. */
8068 is_private (tree decl
)
8070 return (TREE_PRIVATE (decl
)
8071 && ! is_ivar (CLASS_IVARS (implementation_template
),
8075 /* We have an instance variable reference;, check to see if it is public. */
8078 objc_is_public (tree expr
, tree identifier
)
8080 tree basetype
, decl
;
8083 if (processing_template_decl
)
8087 if (TREE_TYPE (expr
) == error_mark_node
)
8090 basetype
= TYPE_MAIN_VARIANT (TREE_TYPE (expr
));
8092 if (basetype
&& TREE_CODE (basetype
) == RECORD_TYPE
)
8094 if (TYPE_HAS_OBJC_INFO (basetype
) && TYPE_OBJC_INTERFACE (basetype
))
8096 tree klass
= lookup_interface (OBJC_TYPE_NAME (basetype
));
8100 error ("cannot find interface declaration for %qE",
8101 OBJC_TYPE_NAME (basetype
));
8105 if ((decl
= is_ivar (get_class_ivars (klass
, true), identifier
)))
8107 if (TREE_PUBLIC (decl
))
8110 /* Important difference between the Stepstone translator:
8111 all instance variables should be public within the context
8112 of the implementation. */
8113 if (objc_implementation_context
8114 && ((TREE_CODE (objc_implementation_context
)
8115 == CLASS_IMPLEMENTATION_TYPE
)
8116 || (TREE_CODE (objc_implementation_context
)
8117 == CATEGORY_IMPLEMENTATION_TYPE
)))
8119 tree curtype
= TYPE_MAIN_VARIANT
8120 (CLASS_STATIC_TEMPLATE
8121 (implementation_template
));
8123 if (basetype
== curtype
8124 || DERIVED_FROM_P (basetype
, curtype
))
8126 int priv
= is_private (decl
);
8129 error ("instance variable %qE is declared private",
8136 /* The 2.95.2 compiler sometimes allowed C functions to access
8137 non-@public ivars. We will let this slide for now... */
8138 if (!objc_method_context
)
8140 warning (0, "instance variable %qE is %s; "
8141 "this will be a hard error in the future",
8143 TREE_PRIVATE (decl
) ? "@private" : "@protected");
8147 error ("instance variable %qE is declared %s",
8149 TREE_PRIVATE (decl
) ? "private" : "protected");
8158 /* Make sure all entries in CHAIN are also in LIST. */
8161 check_methods (tree chain
, tree list
, int mtype
)
8167 if (!lookup_method (list
, chain
))
8171 switch (TREE_CODE (objc_implementation_context
))
8173 case CLASS_IMPLEMENTATION_TYPE
:
8174 warning (0, "incomplete implementation of class %qE",
8175 CLASS_NAME (objc_implementation_context
));
8177 case CATEGORY_IMPLEMENTATION_TYPE
:
8178 warning (0, "incomplete implementation of category %qE",
8179 CLASS_SUPER_NAME (objc_implementation_context
));
8187 warning (0, "method definition for %<%c%E%> not found",
8188 mtype
, METHOD_SEL_NAME (chain
));
8191 chain
= DECL_CHAIN (chain
);
8197 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
8200 conforms_to_protocol (tree klass
, tree protocol
)
8202 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
8204 tree p
= CLASS_PROTOCOL_LIST (klass
);
8205 while (p
&& TREE_VALUE (p
) != protocol
)
8210 tree super
= (CLASS_SUPER_NAME (klass
)
8211 ? lookup_interface (CLASS_SUPER_NAME (klass
))
8213 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
8222 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
8223 CONTEXT. This is one of two mechanisms to check protocol integrity. */
8226 check_methods_accessible (tree chain
, tree context
, int mtype
)
8230 tree base_context
= context
;
8234 context
= base_context
;
8238 list
= CLASS_CLS_METHODS (context
);
8240 list
= CLASS_NST_METHODS (context
);
8242 if (lookup_method (list
, chain
))
8245 switch (TREE_CODE (context
))
8247 case CLASS_IMPLEMENTATION_TYPE
:
8248 case CLASS_INTERFACE_TYPE
:
8249 context
= (CLASS_SUPER_NAME (context
)
8250 ? lookup_interface (CLASS_SUPER_NAME (context
))
8253 case CATEGORY_IMPLEMENTATION_TYPE
:
8254 case CATEGORY_INTERFACE_TYPE
:
8255 context
= (CLASS_NAME (context
)
8256 ? lookup_interface (CLASS_NAME (context
))
8264 if (context
== NULL_TREE
)
8268 switch (TREE_CODE (objc_implementation_context
))
8270 case CLASS_IMPLEMENTATION_TYPE
:
8271 warning (0, "incomplete implementation of class %qE",
8272 CLASS_NAME (objc_implementation_context
));
8274 case CATEGORY_IMPLEMENTATION_TYPE
:
8275 warning (0, "incomplete implementation of category %qE",
8276 CLASS_SUPER_NAME (objc_implementation_context
));
8283 warning (0, "method definition for %<%c%E%> not found",
8284 mtype
, METHOD_SEL_NAME (chain
));
8287 chain
= TREE_CHAIN (chain
); /* next method... */
8292 /* Check whether the current interface (accessible via
8293 'objc_implementation_context') actually implements protocol P, along
8294 with any protocols that P inherits. */
8297 check_protocol (tree p
, const char *type
, tree name
)
8299 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
8303 /* Ensure that all protocols have bodies! */
8306 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
8307 CLASS_CLS_METHODS (objc_implementation_context
),
8309 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
8310 CLASS_NST_METHODS (objc_implementation_context
),
8315 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
8316 objc_implementation_context
,
8318 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
8319 objc_implementation_context
,
8324 warning (0, "%s %qE does not fully implement the %qE protocol",
8325 type
, name
, PROTOCOL_NAME (p
));
8328 /* Check protocols recursively. */
8329 if (PROTOCOL_LIST (p
))
8331 tree subs
= PROTOCOL_LIST (p
);
8333 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
8337 tree sub
= TREE_VALUE (subs
);
8339 /* If the superclass does not conform to the protocols
8340 inherited by P, then we must! */
8341 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
8342 check_protocol (sub
, type
, name
);
8343 subs
= TREE_CHAIN (subs
);
8348 /* Check whether the current interface (accessible via
8349 'objc_implementation_context') actually implements the protocols listed
8353 check_protocols (tree proto_list
, const char *type
, tree name
)
8355 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
8357 tree p
= TREE_VALUE (proto_list
);
8359 check_protocol (p
, type
, name
);
8363 /* Make sure that the class CLASS_NAME is defined
8364 CODE says which kind of thing CLASS_NAME ought to be.
8365 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
8366 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
8369 start_class (enum tree_code code
, tree class_name
, tree super_name
,
8375 if (current_namespace
!= global_namespace
) {
8376 error ("Objective-C declarations may only appear in global scope");
8378 #endif /* OBJCPLUS */
8380 if (objc_implementation_context
)
8382 warning (0, "%<@end%> missing in implementation context");
8383 finish_class (objc_implementation_context
);
8384 objc_ivar_chain
= NULL_TREE
;
8385 objc_implementation_context
= NULL_TREE
;
8388 klass
= make_node (code
);
8389 TYPE_LANG_SLOT_1 (klass
) = make_tree_vec (CLASS_LANG_SLOT_ELTS
);
8391 /* Check for existence of the super class, if one was specified. Note
8392 that we must have seen an @interface, not just a @class. If we
8393 are looking at a @compatibility_alias, traverse it first. */
8394 if ((code
== CLASS_INTERFACE_TYPE
|| code
== CLASS_IMPLEMENTATION_TYPE
)
8397 tree super
= objc_is_class_name (super_name
);
8399 if (!super
|| !lookup_interface (super
))
8401 error ("cannot find interface declaration for %qE, superclass of %qE",
8402 super
? super
: super_name
,
8404 super_name
= NULL_TREE
;
8410 CLASS_NAME (klass
) = class_name
;
8411 CLASS_SUPER_NAME (klass
) = super_name
;
8412 CLASS_CLS_METHODS (klass
) = NULL_TREE
;
8414 if (! objc_is_class_name (class_name
)
8415 && (decl
= lookup_name (class_name
)))
8417 error ("%qE redeclared as different kind of symbol",
8419 error ("previous declaration of %q+D",
8425 case CLASS_IMPLEMENTATION_TYPE
:
8429 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
8430 if (TREE_VALUE (chain
) == class_name
)
8432 error ("reimplementation of class %qE",
8434 return error_mark_node
;
8436 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
8437 implemented_classes
);
8440 /* Reset for multiple classes per file. */
8443 objc_implementation_context
= klass
;
8445 /* Lookup the interface for this implementation. */
8447 if (!(implementation_template
= lookup_interface (class_name
)))
8449 warning (0, "cannot find interface declaration for %qE",
8451 add_class (implementation_template
= objc_implementation_context
,
8455 /* If a super class has been specified in the implementation,
8456 insure it conforms to the one specified in the interface. */
8459 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
8461 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
8462 error ("conflicting super class name %qE",
8465 error ("previous declaration of %qE", previous_name
);
8467 error ("previous declaration");
8470 else if (! super_name
)
8472 CLASS_SUPER_NAME (objc_implementation_context
)
8473 = CLASS_SUPER_NAME (implementation_template
);
8477 case CLASS_INTERFACE_TYPE
:
8478 if (lookup_interface (class_name
))
8480 error ("duplicate interface declaration for class %qE", class_name
);
8482 warning (0, "duplicate interface declaration for class %qE", class_name
);
8485 add_class (klass
, class_name
);
8488 CLASS_PROTOCOL_LIST (klass
)
8489 = lookup_and_install_protocols (protocol_list
);
8492 case CATEGORY_INTERFACE_TYPE
:
8494 tree class_category_is_assoc_with
;
8496 /* For a category, class_name is really the name of the class that
8497 the following set of methods will be associated with. We must
8498 find the interface so that can derive the objects template. */
8499 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
8501 error ("cannot find interface declaration for %qE",
8503 exit (FATAL_EXIT_CODE
);
8506 add_category (class_category_is_assoc_with
, klass
);
8509 CLASS_PROTOCOL_LIST (klass
)
8510 = lookup_and_install_protocols (protocol_list
);
8514 case CATEGORY_IMPLEMENTATION_TYPE
:
8515 /* Reset for multiple classes per file. */
8518 objc_implementation_context
= klass
;
8520 /* For a category, class_name is really the name of the class that
8521 the following set of methods will be associated with. We must
8522 find the interface so that can derive the objects template. */
8524 if (!(implementation_template
= lookup_interface (class_name
)))
8526 error ("cannot find interface declaration for %qE",
8528 exit (FATAL_EXIT_CODE
);
8538 continue_class (tree klass
)
8540 switch (TREE_CODE (klass
))
8542 case CLASS_IMPLEMENTATION_TYPE
:
8543 case CATEGORY_IMPLEMENTATION_TYPE
:
8545 struct imp_entry
*imp_entry
;
8547 /* Check consistency of the instance variables. */
8549 if (CLASS_RAW_IVARS (klass
))
8550 check_ivars (implementation_template
, klass
);
8552 /* code generation */
8554 push_lang_context (lang_name_c
);
8556 build_private_template (implementation_template
);
8557 uprivate_record
= CLASS_STATIC_TEMPLATE (implementation_template
);
8558 objc_instance_type
= build_pointer_type (uprivate_record
);
8560 imp_entry
= ggc_alloc_imp_entry ();
8562 imp_entry
->next
= imp_list
;
8563 imp_entry
->imp_context
= klass
;
8564 imp_entry
->imp_template
= implementation_template
;
8566 synth_forward_declarations ();
8567 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
8568 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
8569 imp_entry
->has_cxx_cdtors
= 0;
8571 /* Append to front and increment count. */
8572 imp_list
= imp_entry
;
8573 if (TREE_CODE (klass
) == CLASS_IMPLEMENTATION_TYPE
)
8578 pop_lang_context ();
8579 #endif /* OBJCPLUS */
8581 return get_class_ivars (implementation_template
, true);
8584 case CLASS_INTERFACE_TYPE
:
8587 push_lang_context (lang_name_c
);
8588 #endif /* OBJCPLUS */
8589 objc_collecting_ivars
= 1;
8590 build_private_template (klass
);
8591 objc_collecting_ivars
= 0;
8593 pop_lang_context ();
8594 #endif /* OBJCPLUS */
8599 return error_mark_node
;
8603 /* This routine builds a property ivar name. */
8606 objc_build_property_ivar_name (tree property_decl
)
8608 static char string
[BUFSIZE
];
8609 sprintf (string
, "_%s", IDENTIFIER_POINTER (PROPERTY_NAME (property_decl
)));
8613 /* This routine builds name of the setter synthesized function. */
8616 objc_build_property_setter_name (tree ident
, bool delimit_colon
)
8618 static char string
[BUFSIZE
];
8620 sprintf (string
, "set%s:", IDENTIFIER_POINTER (ident
));
8622 sprintf (string
, "set%s", IDENTIFIER_POINTER (ident
));
8623 string
[3] = TOUPPER (string
[3]);
8627 /* This routine does all the work for generating data and code per each
8628 property declared in current implementation. */
8631 objc_gen_one_property_datum (tree klass
, tree property
, tree class_methods
, bool *ivar_added
)
8635 /* If getter, check that it is already declared in user code. */
8636 if (PROPERTY_GETTER_NAME (property
))
8638 mth
= lookup_method (CLASS_NST_METHODS (class_methods
),
8639 PROPERTY_GETTER_NAME (property
));
8641 error ("property getter %qs not declared in class %qs",
8642 IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property
)),
8643 IDENTIFIER_POINTER (CLASS_NAME (class_methods
)));
8645 /* If setter, check that it is already declared in user code. */
8646 if (PROPERTY_SETTER_NAME (property
))
8648 mth
= lookup_method (CLASS_NST_METHODS (class_methods
),
8649 PROPERTY_SETTER_NAME (property
));
8651 error ("property setter %qs not declared in class %qs",
8652 IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property
)),
8653 IDENTIFIER_POINTER (CLASS_NAME (class_methods
)));
8655 /* If ivar attribute specified, check that it is already declared. */
8656 if (PROPERTY_IVAR_NAME (property
))
8658 if (!is_ivar (CLASS_IVARS (klass
),
8659 PROPERTY_IVAR_NAME (property
)))
8660 error ("ivar %qs in property declaration must be an existing ivar",
8661 IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property
)));
8663 else if (!PROPERTY_GETTER_NAME (property
)
8664 || (PROPERTY_READONLY (property
) == boolean_false_node
8665 && !PROPERTY_SETTER_NAME (property
)))
8667 /* Setter and/or getter must be synthesize and there was no user-specified
8668 ivar. Must create an ivar and add to to current class's ivar list. */
8669 tree record
= CLASS_STATIC_TEMPLATE (klass
);
8670 tree type
= TREE_TYPE (property
);
8671 tree field_decl
, field
;
8672 field_decl
= create_field_decl (type
,
8673 objc_build_property_ivar_name (property
));
8674 DECL_CONTEXT (field_decl
) = record
;
8675 (void) add_instance_variable (klass
,
8676 OBJC_IVAR_VIS_PUBLIC
, field_decl
);
8677 /* Unfortunately, CLASS_IVARS is completed when interface is completed.
8678 Must add the new ivar by hand to its list here. */
8680 CLASS_IVARS (klass
) =
8681 chainon (CLASS_IVARS (klass
),
8682 copy_node (field_decl
));
8683 gcc_assert (record
);
8684 /* Must also add this ivar to the end of list of fields for this class. */
8685 field
= TYPE_FIELDS (record
);
8686 if (field
&& field
!= CLASS_IVARS (klass
))
8687 /* class has a hidden field, attach ivar list after the hiddent field. */
8688 TREE_CHAIN (field
) = CLASS_IVARS (klass
);
8690 TYPE_FIELDS (record
) = CLASS_IVARS (klass
);
8695 /* This routine processes an existing getter or setter attribute.
8696 It aliases internal property getter or setter to the user implemented
8701 objc_process_getter_setter (tree klass
, tree property
, bool getter
)
8704 tree prop_getter_mth_decl
;
8708 /* getter name is same as property name. */
8709 name_ident
= PROPERTY_NAME (property
);
8711 /* Must synthesize setter name from property name. */
8712 name_ident
= get_identifier (objc_build_property_setter_name (
8713 PROPERTY_NAME (property
), true));
8715 /* Find declaration of instance method for the property in its class. */
8716 prop_mth_decl
= lookup_method (CLASS_NST_METHODS (klass
), name_ident
);
8721 prop_getter_mth_decl
= lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
8722 getter
? PROPERTY_GETTER_NAME (property
)
8723 : PROPERTY_SETTER_NAME (property
));
8725 if (!prop_getter_mth_decl
)
8728 if (!match_proto_with_proto (prop_getter_mth_decl
, prop_mth_decl
, 1))
8730 error ("User %s %qs does not match property %qs type",
8731 getter
? "getter" : "setter",
8732 IDENTIFIER_POINTER (DECL_NAME (prop_getter_mth_decl
)),
8733 IDENTIFIER_POINTER (PROPERTY_NAME (property
)));
8736 /* We alias internal property getter to the user implemented getter by copying relevant
8737 entries from user's implementation to the internal one. */
8738 prop_mth_decl
= copy_node (prop_mth_decl
);
8739 METHOD_ENCODING (prop_mth_decl
) = METHOD_ENCODING (prop_getter_mth_decl
);
8740 METHOD_DEFINITION (prop_mth_decl
) = METHOD_DEFINITION (prop_getter_mth_decl
);
8741 objc_add_method (objc_implementation_context
, prop_mth_decl
, 0, 0);
8744 /* This routine synthesizes a 'getter' method. */
8747 objc_synthesize_getter (tree klass
, tree class_method
, tree property
)
8754 /* If user has implemented a getter with same name then do nothing. */
8755 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
8756 PROPERTY_NAME (property
)))
8759 /* Find declaration of the property in the interface. There must be one. */
8760 decl
= lookup_method (CLASS_NST_METHODS (class_method
),
8761 PROPERTY_NAME (property
));
8763 /* If one not declared in the interface, 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 /* return self->_property_name; */
8773 /* If user specified an ivar, use it in generation of the getter. */
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 ret_val
= 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 (ret_val
|| PROPERTY_IVAR_NAME (property
));
8790 finish_return_stmt (ret_val
);
8792 (void)c_finish_return (input_location
, ret_val
, NULL
);
8795 add_stmt (c_end_compound_stmt (input_location
, body
, true));
8796 fn
= current_function_decl
;
8800 objc_finish_method_definition (fn
);
8803 /* This routine synthesizes a 'setter' method. */
8806 objc_synthesize_setter (tree klass
, tree class_method
, tree property
)
8808 tree fn
, decl
, ivar_ident
, lhs
, rhs
;
8810 char *setter_name
= objc_build_property_setter_name (
8811 PROPERTY_NAME (property
), true);
8812 tree setter_ident
= get_identifier (setter_name
);
8814 /* If user has implemented a setter with same name then do nothing. */
8815 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
8819 /* Find declaration of the property in the interface. There must be one. */
8820 decl
= lookup_method (CLASS_NST_METHODS (class_method
), setter_ident
);
8822 /* If one not declared in the inerface, this condition has already been reported
8823 as user error (because property was not declared in the interface. */
8827 /* For now, no attributes. */
8828 objc_start_method_definition (false /* is_class_method */, copy_node (decl
), NULL_TREE
);
8830 body
= c_begin_compound_stmt (true);
8831 /* _property_name = _value; */
8832 /* If user specified an ivar, use it in generation of the setter. */
8833 ivar_ident
= PROPERTY_IVAR_NAME (property
)
8834 ? PROPERTY_IVAR_NAME (property
)
8835 : get_identifier (objc_build_property_ivar_name (property
));
8837 /* objc_ivar_chain might not be up to date in the case that property 'ivar'
8838 is added *after* user ivar is parsed and objc_continue_implementation
8839 has already been called. */
8840 objc_ivar_chain
= CLASS_IVARS (klass
);
8841 lhs
= objc_lookup_ivar (NULL_TREE
, ivar_ident
);
8842 /* If ivar attribute is not a user declared attribute, this condition has
8843 already been repored as error. */
8844 gcc_assert (lhs
|| PROPERTY_IVAR_NAME (property
));
8847 rhs
= lookup_name (get_identifier ("_value"));
8849 /* FIXME: NULL types to get compile. */
8850 add_stmt (build_modify_expr (input_location
,
8851 lhs
, NULL_TREE
, NOP_EXPR
,
8852 input_location
, rhs
, NULL_TREE
));
8854 add_stmt (c_end_compound_stmt (input_location
, body
, true));
8855 fn
= current_function_decl
;
8859 objc_finish_method_definition (fn
);
8862 /* This function is called by the parser after a @synthesize
8863 expression is parsed. 'start_locus' is the location of the
8864 @synthesize expression, and 'property_and_ivar_list' is a chained
8865 list of the property and ivar names.
8868 objc_add_synthesize_declaration (location_t start_locus ATTRIBUTE_UNUSED
, tree property_and_ivar_list ATTRIBUTE_UNUSED
)
8870 if (property_and_ivar_list
== error_mark_node
)
8873 if (!objc_implementation_context
)
8875 /* We can get here only in Objective-C; the Objective-C++ parser
8876 detects the problem while parsing, outputs the error
8877 "misplaced '@synthesize' Objective-C++ construct" and skips
8879 error ("%<@synthesize%> not in @implementation context");
8884 error ("%<@synthesize%> is not supported in this version of the compiler");
8887 /* This function is called by the parser after a @dynamic expression
8888 is parsed. 'start_locus' is the location of the @dynamic
8889 expression, and 'property_list' is a chained list of all the
8892 objc_add_dynamic_declaration (location_t start_locus ATTRIBUTE_UNUSED
, tree property_list ATTRIBUTE_UNUSED
)
8894 if (property_list
== error_mark_node
)
8897 if (!objc_implementation_context
)
8899 /* We can get here only in Objective-C; the Objective-C++ parser
8900 detects the problem while parsing, outputs the error
8901 "misplaced '@dynamic' Objective-C++ construct" and skips the
8903 error ("%<@dynamic%> not in @implementation context");
8908 error ("%<@dynamic%> is not supported in this version of the compiler");
8911 /* Main routine to generate code/data for all the property information for
8912 current implementation (class or category). CLASS is the interface where
8913 ivars are declared. CLASS_METHODS is where methods are found which
8914 could be a class or a category depending on whether we are implementing
8915 property of a class or a category. */
8918 objc_gen_property_data (tree klass
, tree class_methods
)
8921 bool ivar_added
= false;
8922 for (x
= IMPL_PROPERTY_DECL (objc_implementation_context
); x
; x
= TREE_CHAIN (x
))
8923 objc_gen_one_property_datum (klass
, x
, class_methods
, &ivar_added
);
8927 tree record
= CLASS_STATIC_TEMPLATE (klass
);
8928 /* Ugh, must recalculate struct layout since at least one ivar was added. */
8929 TYPE_SIZE (record
) = 0;
8930 layout_type (record
);
8933 /* Synthesize all getters for properties. */
8934 for (x
= IMPL_PROPERTY_DECL (objc_implementation_context
); x
; x
= TREE_CHAIN (x
))
8936 /* Property has a getter attribute, no need to synthesize one. */
8937 if (PROPERTY_GETTER_NAME (x
) == NULL_TREE
)
8938 objc_synthesize_getter (klass
, class_methods
, x
);
8940 objc_process_getter_setter (class_methods
, x
, true);
8942 if (PROPERTY_READONLY (x
) == boolean_false_node
)
8944 /* not a readonly property. */
8945 if (PROPERTY_SETTER_NAME (x
) == NULL_TREE
)
8946 objc_synthesize_setter (klass
, class_methods
, x
);
8948 objc_process_getter_setter (class_methods
, x
, false);
8953 /* This is called once we see the "@end" in an interface/implementation. */
8956 finish_class (tree klass
)
8958 switch (TREE_CODE (klass
))
8960 case CLASS_IMPLEMENTATION_TYPE
:
8962 /* All code generation is done in finish_objc. */
8964 /* Generate what needed for property; setters, getters, etc. */
8965 objc_gen_property_data (implementation_template
, implementation_template
);
8967 if (implementation_template
!= objc_implementation_context
)
8969 /* Ensure that all method listed in the interface contain bodies. */
8970 check_methods (CLASS_CLS_METHODS (implementation_template
),
8971 CLASS_CLS_METHODS (objc_implementation_context
), '+');
8972 check_methods (CLASS_NST_METHODS (implementation_template
),
8973 CLASS_NST_METHODS (objc_implementation_context
), '-');
8975 if (CLASS_PROTOCOL_LIST (implementation_template
))
8976 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
8978 CLASS_NAME (objc_implementation_context
));
8982 case CATEGORY_IMPLEMENTATION_TYPE
:
8984 tree category
= lookup_category (implementation_template
, CLASS_SUPER_NAME (klass
));
8988 /* Generate what needed for property; setters, getters, etc. */
8989 objc_gen_property_data (implementation_template
, category
);
8991 /* Ensure all method listed in the interface contain bodies. */
8992 check_methods (CLASS_CLS_METHODS (category
),
8993 CLASS_CLS_METHODS (objc_implementation_context
), '+');
8994 check_methods (CLASS_NST_METHODS (category
),
8995 CLASS_NST_METHODS (objc_implementation_context
), '-');
8997 if (CLASS_PROTOCOL_LIST (category
))
8998 check_protocols (CLASS_PROTOCOL_LIST (category
),
9000 CLASS_SUPER_NAME (objc_implementation_context
));
9006 /* Process properties of the class. */
9008 for (x
= CLASS_PROPERTY_DECL (objc_interface_context
); x
; x
= TREE_CHAIN (x
))
9010 tree type
= TREE_TYPE (x
);
9011 tree prop_name
= PROPERTY_NAME (x
);
9012 /* Build an instance method declaration: - (type) prop_name; */
9013 if (PROPERTY_GETTER_NAME (x
) == NULL_TREE
)
9015 /* No getter attribute specified. Generate an instance method for the
9017 tree rettype
= build_tree_list (NULL_TREE
, type
);
9018 tree getter_decl
= build_method_decl (INSTANCE_METHOD_DECL
,
9021 objc_add_method (objc_interface_context
, getter_decl
, false, false);
9022 METHOD_PROPERTY_CONTEXT (getter_decl
) = x
;
9025 warning (0, "getter = %qs may not be specified in an interface",
9026 IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (x
)));
9028 /* Build an instance method declaration: - (void) setName: (type)value; */
9029 if (PROPERTY_SETTER_NAME (x
) == NULL_TREE
9030 && PROPERTY_READONLY (x
) == boolean_false_node
)
9032 /* Declare a setter instance method in the interface. */
9033 tree key_name
, arg_type
, arg_name
;
9034 tree setter_decl
, selector
;
9035 tree ret_type
= build_tree_list (NULL_TREE
, void_type_node
);
9037 key_name
= get_identifier (objc_build_property_setter_name
9038 (PROPERTY_NAME (x
), false));
9039 arg_type
= build_tree_list (NULL_TREE
, type
);
9040 arg_name
= get_identifier ("_value");
9041 /* For now, no attributes. */
9042 selector
= objc_build_keyword_decl (key_name
, arg_type
, arg_name
, NULL
);
9043 setter_decl
= build_method_decl (INSTANCE_METHOD_DECL
,
9045 build_tree_list (NULL_TREE
, NULL_TREE
),
9047 objc_add_method (objc_interface_context
, setter_decl
, false, false);
9048 METHOD_PROPERTY_CONTEXT (setter_decl
) = x
;
9050 else if (PROPERTY_SETTER_NAME (x
))
9051 warning (0, "setter = %qs may not be specified in an interface",
9052 IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x
)));
9053 if (PROPERTY_IVAR_NAME (x
))
9054 warning (0, "ivar = %qs attribute may not be specified in an interface",
9055 IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (x
)));
9062 add_protocol (tree protocol
)
9064 /* Put protocol on list in reverse order. */
9065 TREE_CHAIN (protocol
) = protocol_chain
;
9066 protocol_chain
= protocol
;
9067 return protocol_chain
;
9071 lookup_protocol (tree ident
)
9075 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
9076 if (ident
== PROTOCOL_NAME (chain
))
9082 /* This function forward declares the protocols named by NAMES. If
9083 they are already declared or defined, the function has no effect. */
9086 objc_declare_protocols (tree names
)
9091 if (current_namespace
!= global_namespace
) {
9092 error ("Objective-C declarations may only appear in global scope");
9094 #endif /* OBJCPLUS */
9096 for (list
= names
; list
; list
= TREE_CHAIN (list
))
9098 tree name
= TREE_VALUE (list
);
9100 if (lookup_protocol (name
) == NULL_TREE
)
9102 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
9104 TYPE_LANG_SLOT_1 (protocol
)
9105 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
9106 PROTOCOL_NAME (protocol
) = name
;
9107 PROTOCOL_LIST (protocol
) = NULL_TREE
;
9108 add_protocol (protocol
);
9109 PROTOCOL_DEFINED (protocol
) = 0;
9110 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
9116 start_protocol (enum tree_code code
, tree name
, tree list
)
9121 if (current_namespace
!= global_namespace
) {
9122 error ("Objective-C declarations may only appear in global scope");
9124 #endif /* OBJCPLUS */
9126 protocol
= lookup_protocol (name
);
9130 protocol
= make_node (code
);
9131 TYPE_LANG_SLOT_1 (protocol
) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
9133 PROTOCOL_NAME (protocol
) = name
;
9134 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
9135 add_protocol (protocol
);
9136 PROTOCOL_DEFINED (protocol
) = 1;
9137 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
9139 check_protocol_recursively (protocol
, list
);
9141 else if (! PROTOCOL_DEFINED (protocol
))
9143 PROTOCOL_DEFINED (protocol
) = 1;
9144 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
9146 check_protocol_recursively (protocol
, list
);
9150 warning (0, "duplicate declaration for protocol %qE",
9157 /* "Encode" a data type into a string, which grows in util_obstack.
9159 The format is described in gcc/doc/objc.texi, section 'Type
9162 Most of the encode_xxx functions have a 'type' argument, which is
9163 the type to encode, and an integer 'curtype' argument, which is the
9164 index in the encoding string of the beginning of the encoding of
9165 the current type, and allows you to find what characters have
9166 already been written for the current type (they are the ones in the
9167 current encoding string starting from 'curtype').
9169 For example, if we are encoding a method which returns 'int' and
9170 takes a 'char **' argument, then when we get to the point of
9171 encoding the 'char **' argument, the encoded string already
9172 contains 'i12@0:4' (assuming a pointer size of 4 bytes). So,
9173 'curtype' will be set to 7 when starting to encode 'char **'.
9174 During the whole of the encoding of 'char **', 'curtype' will be
9175 fixed at 7, so the routine encoding the second pointer can find out
9176 that it's actually encoding a pointer to a pointer by looking
9177 backwards at what has already been encoded for the current type,
9178 and seeing there is a "^" (meaning a pointer) in there.
9182 /* Encode type qualifiers encodes one of the "PQ" Objective-C
9183 keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
9184 'const', instead, is encoded directly as part of the type.
9188 encode_type_qualifiers (tree declspecs
)
9192 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
9194 /* FIXME: Shouldn't we use token->keyword here ? */
9195 if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
9196 obstack_1grow (&util_obstack
, 'n');
9197 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
9198 obstack_1grow (&util_obstack
, 'N');
9199 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
9200 obstack_1grow (&util_obstack
, 'o');
9201 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
9202 obstack_1grow (&util_obstack
, 'O');
9203 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
9204 obstack_1grow (&util_obstack
, 'R');
9205 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
9206 obstack_1grow (&util_obstack
, 'V');
9212 /* Determine if a pointee is marked read-only. Only used by the NeXT
9213 runtime to be compatible with gcc-3.3. */
9216 pointee_is_readonly (tree pointee
)
9218 while (POINTER_TYPE_P (pointee
))
9219 pointee
= TREE_TYPE (pointee
);
9221 return TYPE_READONLY (pointee
);
9224 /* Encode a pointer type. */
9227 encode_pointer (tree type
, int curtype
, int format
)
9229 tree pointer_to
= TREE_TYPE (type
);
9231 if (flag_next_runtime
)
9233 /* This code is used to be compatible with gcc-3.3. */
9234 /* For historical/compatibility reasons, the read-only qualifier
9235 of the pointee gets emitted _before_ the '^'. The read-only
9236 qualifier of the pointer itself gets ignored, _unless_ we are
9237 looking at a typedef! Also, do not emit the 'r' for anything
9238 but the outermost type! */
9239 if (!generating_instance_variables
9240 && (obstack_object_size (&util_obstack
) - curtype
<= 1)
9241 && (TYPE_NAME (type
) && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
9242 ? TYPE_READONLY (type
)
9243 : pointee_is_readonly (pointer_to
)))
9244 obstack_1grow (&util_obstack
, 'r');
9247 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
9249 if (OBJC_TYPE_NAME (pointer_to
)
9250 && TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
9252 const char *name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to
));
9254 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
9256 obstack_1grow (&util_obstack
, '@');
9259 else if (TYPE_HAS_OBJC_INFO (pointer_to
)
9260 && TYPE_OBJC_INTERFACE (pointer_to
))
9262 if (generating_instance_variables
)
9264 obstack_1grow (&util_obstack
, '@');
9265 obstack_1grow (&util_obstack
, '"');
9266 obstack_grow (&util_obstack
, name
, strlen (name
));
9267 obstack_1grow (&util_obstack
, '"');
9272 obstack_1grow (&util_obstack
, '@');
9276 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
9278 obstack_1grow (&util_obstack
, '#');
9281 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
9283 obstack_1grow (&util_obstack
, ':');
9288 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
9289 && TYPE_MODE (pointer_to
) == QImode
)
9291 tree pname
= TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
9292 ? OBJC_TYPE_NAME (pointer_to
)
9293 : DECL_NAME (OBJC_TYPE_NAME (pointer_to
));
9295 /* (BOOL *) are an exception and are encoded as ^c, while all
9296 other pointers to char are encoded as *. */
9297 if (strcmp (IDENTIFIER_POINTER (pname
), "BOOL"))
9299 if (!flag_next_runtime
)
9301 /* The NeXT runtime adds the 'r' before getting here. */
9303 /* It appears that "r*" means "const char *" rather than
9304 "char *const". "char *const" is encoded as "*",
9305 which is identical to "char *", so the "const" is
9306 unfortunately lost. */
9307 if (TYPE_READONLY (pointer_to
))
9308 obstack_1grow (&util_obstack
, 'r');
9311 obstack_1grow (&util_obstack
, '*');
9316 /* We have a normal pointer type that does not get special treatment. */
9317 obstack_1grow (&util_obstack
, '^');
9318 encode_type (pointer_to
, curtype
, format
);
9322 encode_array (tree type
, int curtype
, int format
)
9324 tree an_int_cst
= TYPE_SIZE (type
);
9325 tree array_of
= TREE_TYPE (type
);
9328 if (an_int_cst
== NULL
)
9330 /* We are trying to encode an incomplete array. An incomplete
9331 array is forbidden as part of an instance variable. */
9332 if (generating_instance_variables
)
9334 /* TODO: Detect this error earlier. */
9335 error ("instance variable has unknown size");
9339 /* So the only case in which an incomplete array could occur is
9340 if we are encoding the arguments or return value of a method.
9341 In that case, an incomplete array argument or return value
9342 (eg, -(void)display: (char[])string) is treated like a
9343 pointer because that is how the compiler does the function
9344 call. A special, more complicated case, is when the
9345 incomplete array is the last member of a struct (eg, if we
9346 are encoding "struct { unsigned long int a;double b[];}"),
9347 which is again part of a method argument/return value. In
9348 that case, we really need to communicate to the runtime that
9349 there is an incomplete array (not a pointer!) there. So, we
9350 detect that special case and encode it as a zero-length
9353 Try to detect that we are part of a struct. We do this by
9354 searching for '=' in the type encoding for the current type.
9355 NB: This hack assumes that you can't use '=' as part of a C
9359 char *enc
= obstack_base (&util_obstack
) + curtype
;
9360 if (memchr (enc
, '=',
9361 obstack_object_size (&util_obstack
) - curtype
) == NULL
)
9363 /* We are not inside a struct. Encode the array as a
9365 encode_pointer (type
, curtype
, format
);
9370 /* Else, we are in a struct, and we encode it as a zero-length
9372 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
)0);
9374 else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of
)) == 0)
9375 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
)0);
9377 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
,
9378 TREE_INT_CST_LOW (an_int_cst
)
9379 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
)));
9381 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
9382 encode_type (array_of
, curtype
, format
);
9383 obstack_1grow (&util_obstack
, ']');
9387 /* Encode a vector. The vector type is a GCC extension to C. */
9389 encode_vector (tree type
, int curtype
, int format
)
9391 tree vector_of
= TREE_TYPE (type
);
9394 /* Vectors are like simple fixed-size arrays. */
9396 /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
9397 alignment of the vector, and <code> is the base type. Eg, int
9398 __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
9399 assuming that the alignment is 32 bytes. We include size and
9400 alignment in bytes so that the runtime does not have to have any
9401 knowledge of the actual types.
9403 sprintf (buffer
, "![" HOST_WIDE_INT_PRINT_DEC
",%d",
9404 /* We want to compute the equivalent of sizeof (<vector>).
9405 Code inspired by c_sizeof_or_alignof_type. */
9406 ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type
))
9407 / (TYPE_PRECISION (char_type_node
) / BITS_PER_UNIT
))),
9408 /* We want to compute the equivalent of __alignof__
9409 (<vector>). Code inspired by
9410 c_sizeof_or_alignof_type. */
9411 TYPE_ALIGN_UNIT (type
));
9412 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
9413 encode_type (vector_of
, curtype
, format
);
9414 obstack_1grow (&util_obstack
, ']');
9419 encode_aggregate_fields (tree type
, bool pointed_to
, int curtype
, int format
)
9421 tree field
= TYPE_FIELDS (type
);
9423 for (; field
; field
= DECL_CHAIN (field
))
9426 /* C++ static members, and things that are not field at all,
9427 should not appear in the encoding. */
9428 if (TREE_CODE (field
) != FIELD_DECL
|| TREE_STATIC (field
))
9432 /* Recursively encode fields of embedded base classes. */
9433 if (DECL_ARTIFICIAL (field
) && !DECL_NAME (field
)
9434 && TREE_CODE (TREE_TYPE (field
)) == RECORD_TYPE
)
9436 encode_aggregate_fields (TREE_TYPE (field
),
9437 pointed_to
, curtype
, format
);
9441 if (generating_instance_variables
&& !pointed_to
)
9443 tree fname
= DECL_NAME (field
);
9445 obstack_1grow (&util_obstack
, '"');
9447 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
9448 obstack_grow (&util_obstack
,
9449 IDENTIFIER_POINTER (fname
),
9450 strlen (IDENTIFIER_POINTER (fname
)));
9452 obstack_1grow (&util_obstack
, '"');
9455 encode_field_decl (field
, curtype
, format
);
9460 encode_aggregate_within (tree type
, int curtype
, int format
, int left
,
9464 /* NB: aggregates that are pointed to have slightly different encoding
9465 rules in that you never encode the names of instance variables. */
9466 int ob_size
= obstack_object_size (&util_obstack
);
9467 bool inline_contents
= false;
9468 bool pointed_to
= false;
9470 if (flag_next_runtime
)
9472 if (ob_size
> 0 && *(obstack_next_free (&util_obstack
) - 1) == '^')
9475 if ((format
== OBJC_ENCODE_INLINE_DEFS
|| generating_instance_variables
)
9476 && (!pointed_to
|| ob_size
- curtype
== 1
9477 || (ob_size
- curtype
== 2
9478 && *(obstack_next_free (&util_obstack
) - 2) == 'r')))
9479 inline_contents
= true;
9483 /* c0 and c1 are the last two characters in the encoding of the
9484 current type; if the last two characters were '^' or '^r',
9485 then we are encoding an aggregate that is "pointed to". The
9486 comment above applies: in that case we should avoid encoding
9487 the names of instance variables.
9489 char c1
= ob_size
> 1 ? *(obstack_next_free (&util_obstack
) - 2) : 0;
9490 char c0
= ob_size
> 0 ? *(obstack_next_free (&util_obstack
) - 1) : 0;
9492 if (c0
== '^' || (c1
== '^' && c0
== 'r'))
9495 if (format
== OBJC_ENCODE_INLINE_DEFS
|| generating_instance_variables
)
9498 inline_contents
= true;
9501 /* Note that the check (ob_size - curtype < 2) prevents
9502 infinite recursion when encoding a structure which is
9503 a linked list (eg, struct node { struct node *next;
9504 }). Each time we follow a pointer, we add one
9505 character to ob_size, and curtype is fixed, so after
9506 at most two pointers we stop inlining contents and
9509 The other case where we don't inline is "^r", which
9510 is a pointer to a constant struct.
9512 if ((ob_size
- curtype
<= 2) && !(c0
== 'r'))
9513 inline_contents
= true;
9518 /* Traverse struct aliases; it is important to get the
9519 original struct and its tag name (if any). */
9520 type
= TYPE_MAIN_VARIANT (type
);
9521 name
= OBJC_TYPE_NAME (type
);
9522 /* Open parenth/bracket. */
9523 obstack_1grow (&util_obstack
, left
);
9525 /* Encode the struct/union tag name, or '?' if a tag was
9526 not provided. Typedef aliases do not qualify. */
9528 /* For compatibility with the NeXT runtime, ObjC++ encodes template
9529 args as a composite struct tag name. */
9530 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
9531 /* Did this struct have a tag? */
9532 && !TYPE_WAS_ANONYMOUS (type
))
9533 obstack_grow (&util_obstack
,
9534 decl_as_string (type
, TFF_DECL_SPECIFIERS
| TFF_UNQUALIFIED_NAME
),
9535 strlen (decl_as_string (type
, TFF_DECL_SPECIFIERS
| TFF_UNQUALIFIED_NAME
)));
9537 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
9538 obstack_grow (&util_obstack
,
9539 IDENTIFIER_POINTER (name
),
9540 strlen (IDENTIFIER_POINTER (name
)));
9543 obstack_1grow (&util_obstack
, '?');
9545 /* Encode the types (and possibly names) of the inner fields,
9547 if (inline_contents
)
9549 obstack_1grow (&util_obstack
, '=');
9550 encode_aggregate_fields (type
, pointed_to
, curtype
, format
);
9552 /* Close parenth/bracket. */
9553 obstack_1grow (&util_obstack
, right
);
9556 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
9560 encode_next_bitfield (int width
)
9563 sprintf (buffer
, "b%d", width
);
9564 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
9568 /* Encodes 'type', ignoring type qualifiers (which you should encode
9569 beforehand if needed) with the exception of 'const', which is
9570 encoded by encode_type. See above for the explanation of
9571 'curtype'. 'format' can be OBJC_ENCODE_INLINE_DEFS or
9572 OBJC_ENCODE_DONT_INLINE_DEFS.
9575 encode_type (tree type
, int curtype
, int format
)
9577 enum tree_code code
= TREE_CODE (type
);
9579 /* Ignore type qualifiers other than 'const' when encoding a
9582 if (type
== error_mark_node
)
9585 if (!flag_next_runtime
)
9587 if (TYPE_READONLY (type
))
9588 obstack_1grow (&util_obstack
, 'r');
9594 if (flag_next_runtime
)
9596 /* Kludge for backwards-compatibility with gcc-3.3: enums
9597 are always encoded as 'i' no matter what type they
9598 actually are (!). */
9599 obstack_1grow (&util_obstack
, 'i');
9602 /* Else, they are encoded exactly like the integer type that is
9603 used by the compiler to store them. */
9607 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
9609 case 8: c
= TYPE_UNSIGNED (type
) ? 'C' : 'c'; break;
9610 case 16: c
= TYPE_UNSIGNED (type
) ? 'S' : 's'; break;
9613 tree int_type
= type
;
9614 if (flag_next_runtime
)
9616 /* Another legacy kludge for compatiblity with
9617 gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
9618 but not always. For typedefs, we need to use 'i'
9619 or 'I' instead if encoding a struct field, or a
9621 int_type
= ((!generating_instance_variables
9622 && (obstack_object_size (&util_obstack
)
9623 == (unsigned) curtype
))
9624 ? TYPE_MAIN_VARIANT (type
)
9627 if (int_type
== long_unsigned_type_node
9628 || int_type
== long_integer_type_node
)
9629 c
= TYPE_UNSIGNED (type
) ? 'L' : 'l';
9631 c
= TYPE_UNSIGNED (type
) ? 'I' : 'i';
9634 case 64: c
= TYPE_UNSIGNED (type
) ? 'Q' : 'q'; break;
9635 case 128: c
= TYPE_UNSIGNED (type
) ? 'T' : 't'; break;
9636 default: gcc_unreachable ();
9638 obstack_1grow (&util_obstack
, c
);
9644 /* Floating point types. */
9645 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
9647 case 32: c
= 'f'; break;
9648 case 64: c
= 'd'; break;
9650 case 128: c
= 'D'; break;
9651 default: gcc_unreachable ();
9653 obstack_1grow (&util_obstack
, c
);
9657 obstack_1grow (&util_obstack
, 'v');
9661 obstack_1grow (&util_obstack
, 'B');
9665 encode_array (type
, curtype
, format
);
9670 case REFERENCE_TYPE
:
9672 encode_pointer (type
, curtype
, format
);
9676 encode_aggregate_within (type
, curtype
, format
, '{', '}');
9680 encode_aggregate_within (type
, curtype
, format
, '(', ')');
9683 case FUNCTION_TYPE
: /* '?' means an unknown type. */
9684 obstack_1grow (&util_obstack
, '?');
9688 /* A complex is encoded as 'j' followed by the inner type (eg,
9689 "_Complex int" is encoded as 'ji'). */
9690 obstack_1grow (&util_obstack
, 'j');
9691 encode_type (TREE_TYPE (type
), curtype
, format
);
9695 encode_vector (type
, curtype
, format
);
9699 warning (0, "unknown type %s found during Objective-C encoding",
9700 gen_type_name (type
));
9701 obstack_1grow (&util_obstack
, '?');
9705 if (flag_next_runtime
)
9707 /* Super-kludge. Some ObjC qualifier and type combinations need
9708 to be rearranged for compatibility with gcc-3.3. */
9709 if (code
== POINTER_TYPE
&& obstack_object_size (&util_obstack
) >= 3)
9711 char *enc
= obstack_base (&util_obstack
) + curtype
;
9713 /* Rewrite "in const" from "nr" to "rn". */
9714 if (curtype
>= 1 && !strncmp (enc
- 1, "nr", 2))
9715 strncpy (enc
- 1, "rn", 2);
9721 encode_gnu_bitfield (int position
, tree type
, int size
)
9723 enum tree_code code
= TREE_CODE (type
);
9725 char charType
= '?';
9727 /* This code is only executed for the GNU runtime, so we can ignore
9728 the NeXT runtime kludge of always encoding enums as 'i' no matter
9729 what integers they actually are. */
9730 if (code
== INTEGER_TYPE
|| code
== ENUMERAL_TYPE
)
9732 if (integer_zerop (TYPE_MIN_VALUE (type
)))
9733 /* Unsigned integer types. */
9735 switch (TYPE_MODE (type
))
9738 charType
= 'C'; break;
9740 charType
= 'S'; break;
9743 if (type
== long_unsigned_type_node
)
9750 charType
= 'Q'; break;
9756 /* Signed integer types. */
9758 switch (TYPE_MODE (type
))
9761 charType
= 'c'; break;
9763 charType
= 's'; break;
9766 if (type
== long_integer_type_node
)
9773 charType
= 'q'; break;
9781 /* Do not do any encoding, produce an error and keep going. */
9782 error ("trying to encode non-integer type as a bitfield");
9786 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
9787 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
9791 encode_field_decl (tree field_decl
, int curtype
, int format
)
9794 /* C++ static members, and things that are not fields at all,
9795 should not appear in the encoding. */
9796 if (TREE_CODE (field_decl
) != FIELD_DECL
|| TREE_STATIC (field_decl
))
9800 /* Generate the bitfield typing information, if needed. Note the difference
9801 between GNU and NeXT runtimes. */
9802 if (DECL_BIT_FIELD_TYPE (field_decl
))
9804 int size
= tree_low_cst (DECL_SIZE (field_decl
), 1);
9806 if (flag_next_runtime
)
9807 encode_next_bitfield (size
);
9809 encode_gnu_bitfield (int_bit_position (field_decl
),
9810 DECL_BIT_FIELD_TYPE (field_decl
), size
);
9813 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
9816 /* Decay array and function parameters into pointers. */
9819 objc_decay_parm_type (tree type
)
9821 if (TREE_CODE (type
) == ARRAY_TYPE
|| TREE_CODE (type
) == FUNCTION_TYPE
)
9822 type
= build_pointer_type (TREE_CODE (type
) == ARRAY_TYPE
9829 static GTY(()) tree objc_parmlist
= NULL_TREE
;
9831 /* Append PARM to a list of formal parameters of a method, making a necessary
9832 array-to-pointer adjustment along the way. */
9835 objc_push_parm (tree parm
)
9839 if (TREE_TYPE (parm
) == error_mark_node
)
9841 objc_parmlist
= chainon (objc_parmlist
, parm
);
9845 /* Decay arrays and functions into pointers. */
9846 type
= objc_decay_parm_type (TREE_TYPE (parm
));
9848 /* If the parameter type has been decayed, a new PARM_DECL needs to be
9850 if (type
!= TREE_TYPE (parm
))
9851 parm
= build_decl (input_location
, PARM_DECL
, DECL_NAME (parm
), type
);
9853 DECL_ARG_TYPE (parm
)
9854 = lang_hooks
.types
.type_promotes_to (TREE_TYPE (parm
));
9856 /* Record constancy and volatility. */
9857 c_apply_type_quals_to_decl
9858 ((TYPE_READONLY (TREE_TYPE (parm
)) ? TYPE_QUAL_CONST
: 0)
9859 | (TYPE_RESTRICT (TREE_TYPE (parm
)) ? TYPE_QUAL_RESTRICT
: 0)
9860 | (TYPE_VOLATILE (TREE_TYPE (parm
)) ? TYPE_QUAL_VOLATILE
: 0), parm
);
9862 objc_parmlist
= chainon (objc_parmlist
, parm
);
9865 /* Retrieve the formal parameter list constructed via preceding calls to
9866 objc_push_parm(). */
9870 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED
)
9872 static struct c_arg_info
*
9873 objc_get_parm_info (int have_ellipsis
)
9877 tree parm_info
= objc_parmlist
;
9878 objc_parmlist
= NULL_TREE
;
9882 tree parm_info
= objc_parmlist
;
9883 struct c_arg_info
*arg_info
;
9884 /* The C front-end requires an elaborate song and dance at
9887 declare_parm_level ();
9890 tree next
= DECL_CHAIN (parm_info
);
9892 DECL_CHAIN (parm_info
) = NULL_TREE
;
9893 parm_info
= pushdecl (parm_info
);
9894 finish_decl (parm_info
, input_location
, NULL_TREE
, NULL_TREE
, NULL_TREE
);
9897 arg_info
= get_parm_info (have_ellipsis
);
9899 objc_parmlist
= NULL_TREE
;
9904 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
9905 method definitions. In the case of instance methods, we can be more
9906 specific as to the type of 'self'. */
9909 synth_self_and_ucmd_args (void)
9913 if (objc_method_context
9914 && TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
9915 self_type
= objc_instance_type
;
9917 /* Really a `struct objc_class *'. However, we allow people to
9918 assign to self, which changes its type midstream. */
9919 self_type
= objc_object_type
;
9922 objc_push_parm (build_decl (input_location
,
9923 PARM_DECL
, self_id
, self_type
));
9926 objc_push_parm (build_decl (input_location
,
9927 PARM_DECL
, ucmd_id
, objc_selector_type
));
9930 /* Transform an Objective-C method definition into a static C function
9931 definition, synthesizing the first two arguments, "self" and "_cmd",
9935 start_method_def (tree method
)
9941 struct c_arg_info
*parm_info
;
9943 int have_ellipsis
= 0;
9945 /* If we are defining a "dealloc" method in a non-root class, we
9946 will need to check if a [super dealloc] is missing, and warn if
9948 if(CLASS_SUPER_NAME (objc_implementation_context
)
9949 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method
))))
9950 should_call_super_dealloc
= 1;
9952 should_call_super_dealloc
= 0;
9954 /* Required to implement _msgSuper. */
9955 objc_method_context
= method
;
9956 UOBJC_SUPER_decl
= NULL_TREE
;
9958 /* Generate prototype declarations for arguments..."new-style". */
9959 synth_self_and_ucmd_args ();
9961 /* Generate argument declarations if a keyword_decl. */
9962 parmlist
= METHOD_SEL_ARGS (method
);
9965 /* parmlist is a KEYWORD_DECL. */
9966 tree type
= TREE_VALUE (TREE_TYPE (parmlist
));
9969 parm
= build_decl (input_location
,
9970 PARM_DECL
, KEYWORD_ARG_NAME (parmlist
), type
);
9971 decl_attributes (&parm
, DECL_ATTRIBUTES (parmlist
), 0);
9972 objc_push_parm (parm
);
9973 parmlist
= DECL_CHAIN (parmlist
);
9976 if (METHOD_ADD_ARGS (method
))
9980 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
9981 akey
; akey
= TREE_CHAIN (akey
))
9983 objc_push_parm (TREE_VALUE (akey
));
9986 if (METHOD_ADD_ARGS_ELLIPSIS_P (method
))
9990 parm_info
= objc_get_parm_info (have_ellipsis
);
9992 really_start_method (objc_method_context
, parm_info
);
9995 /* Return 1 if TYPE1 is equivalent to TYPE2
9996 for purposes of method overloading. */
9999 objc_types_are_equivalent (tree type1
, tree type2
)
10001 if (type1
== type2
)
10004 /* Strip away indirections. */
10005 while ((TREE_CODE (type1
) == ARRAY_TYPE
|| TREE_CODE (type1
) == POINTER_TYPE
)
10006 && (TREE_CODE (type1
) == TREE_CODE (type2
)))
10007 type1
= TREE_TYPE (type1
), type2
= TREE_TYPE (type2
);
10008 if (TYPE_MAIN_VARIANT (type1
) != TYPE_MAIN_VARIANT (type2
))
10011 type1
= (TYPE_HAS_OBJC_INFO (type1
)
10012 ? TYPE_OBJC_PROTOCOL_LIST (type1
)
10014 type2
= (TYPE_HAS_OBJC_INFO (type2
)
10015 ? TYPE_OBJC_PROTOCOL_LIST (type2
)
10018 if (list_length (type1
) == list_length (type2
))
10020 for (; type2
; type2
= TREE_CHAIN (type2
))
10021 if (!lookup_protocol_in_reflist (type1
, TREE_VALUE (type2
)))
10028 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
10031 objc_types_share_size_and_alignment (tree type1
, tree type2
)
10033 return (simple_cst_equal (TYPE_SIZE (type1
), TYPE_SIZE (type2
))
10034 && TYPE_ALIGN (type1
) == TYPE_ALIGN (type2
));
10037 /* Return 1 if PROTO1 is equivalent to PROTO2
10038 for purposes of method overloading. Ordinarily, the type signatures
10039 should match up exactly, unless STRICT is zero, in which case we
10040 shall allow differences in which the size and alignment of a type
10044 comp_proto_with_proto (tree proto1
, tree proto2
, int strict
)
10046 /* The following test is needed in case there are hashing
10048 if (METHOD_SEL_NAME (proto1
) != METHOD_SEL_NAME (proto2
))
10051 return match_proto_with_proto (proto1
, proto2
, strict
);
10055 match_proto_with_proto (tree proto1
, tree proto2
, int strict
)
10059 /* Compare return types. */
10060 type1
= TREE_VALUE (TREE_TYPE (proto1
));
10061 type2
= TREE_VALUE (TREE_TYPE (proto2
));
10063 if (!objc_types_are_equivalent (type1
, type2
)
10064 && (strict
|| !objc_types_share_size_and_alignment (type1
, type2
)))
10067 /* Compare argument types. */
10068 for (type1
= get_arg_type_list (proto1
, METHOD_REF
, 0),
10069 type2
= get_arg_type_list (proto2
, METHOD_REF
, 0);
10071 type1
= TREE_CHAIN (type1
), type2
= TREE_CHAIN (type2
))
10073 if (!objc_types_are_equivalent (TREE_VALUE (type1
), TREE_VALUE (type2
))
10075 || !objc_types_share_size_and_alignment (TREE_VALUE (type1
),
10076 TREE_VALUE (type2
))))
10080 return (!type1
&& !type2
);
10083 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
10084 this occurs. ObjC method dispatches are _not_ like C++ virtual
10085 member function dispatches, and we account for the difference here. */
10088 objc_fold_obj_type_ref (tree ref
, tree known_type
)
10090 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED
,
10091 tree known_type ATTRIBUTE_UNUSED
)
10095 tree v
= BINFO_VIRTUALS (TYPE_BINFO (known_type
));
10097 /* If the receiver does not have virtual member functions, there
10098 is nothing we can (or need to) do here. */
10102 /* Let C++ handle C++ virtual functions. */
10103 return cp_fold_obj_type_ref (ref
, known_type
);
10105 /* For plain ObjC, we currently do not need to do anything. */
10111 objc_start_function (tree name
, tree type
, tree attrs
,
10115 struct c_arg_info
*params
10119 tree fndecl
= build_decl (input_location
,
10120 FUNCTION_DECL
, name
, type
);
10123 DECL_ARGUMENTS (fndecl
) = params
;
10124 DECL_INITIAL (fndecl
) = error_mark_node
;
10125 DECL_EXTERNAL (fndecl
) = 0;
10126 TREE_STATIC (fndecl
) = 1;
10127 retrofit_lang_decl (fndecl
);
10128 cplus_decl_attributes (&fndecl
, attrs
, 0);
10129 start_preparsed_function (fndecl
, attrs
, /*flags=*/SF_DEFAULT
);
10131 current_function_returns_value
= 0; /* Assume, until we see it does. */
10132 current_function_returns_null
= 0;
10133 decl_attributes (&fndecl
, attrs
, 0);
10134 announce_function (fndecl
);
10135 DECL_INITIAL (fndecl
) = error_mark_node
;
10136 DECL_EXTERNAL (fndecl
) = 0;
10137 TREE_STATIC (fndecl
) = 1;
10138 current_function_decl
= pushdecl (fndecl
);
10140 declare_parm_level ();
10141 DECL_RESULT (current_function_decl
)
10142 = build_decl (input_location
,
10143 RESULT_DECL
, NULL_TREE
,
10144 TREE_TYPE (TREE_TYPE (current_function_decl
)));
10145 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl
)) = 1;
10146 DECL_IGNORED_P (DECL_RESULT (current_function_decl
)) = 1;
10147 start_fname_decls ();
10148 store_parm_decls_from (params
);
10151 TREE_USED (current_function_decl
) = 1;
10154 /* - Generate an identifier for the function. the format is "_n_cls",
10155 where 1 <= n <= nMethods, and cls is the name the implementation we
10157 - Install the return type from the method declaration.
10158 - If we have a prototype, check for type consistency. */
10161 really_start_method (tree method
,
10165 struct c_arg_info
*parmlist
10169 tree ret_type
, meth_type
;
10171 const char *sel_name
, *class_name
, *cat_name
;
10174 /* Synth the storage class & assemble the return type. */
10175 ret_type
= TREE_VALUE (TREE_TYPE (method
));
10177 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
10178 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
10179 cat_name
= ((TREE_CODE (objc_implementation_context
)
10180 == CLASS_IMPLEMENTATION_TYPE
)
10182 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
10185 /* Make sure this is big enough for any plausible method label. */
10186 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
10187 + (cat_name
? strlen (cat_name
) : 0));
10189 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
10190 class_name
, cat_name
, sel_name
, method_slot
);
10192 method_id
= get_identifier (buf
);
10195 /* Objective-C methods cannot be overloaded, so we don't need
10196 the type encoding appended. It looks bad anyway... */
10197 push_lang_context (lang_name_c
);
10201 = build_function_type (ret_type
,
10202 get_arg_type_list (method
, METHOD_DEF
, 0));
10203 objc_start_function (method_id
, meth_type
, NULL_TREE
, parmlist
);
10205 /* Set self_decl from the first argument. */
10206 self_decl
= DECL_ARGUMENTS (current_function_decl
);
10208 /* Suppress unused warnings. */
10209 TREE_USED (self_decl
) = 1;
10210 DECL_READ_P (self_decl
) = 1;
10211 TREE_USED (DECL_CHAIN (self_decl
)) = 1;
10212 DECL_READ_P (DECL_CHAIN (self_decl
)) = 1;
10214 pop_lang_context ();
10217 METHOD_DEFINITION (method
) = current_function_decl
;
10219 /* Check consistency...start_function, pushdecl, duplicate_decls. */
10221 if (implementation_template
!= objc_implementation_context
)
10224 = lookup_method_static (implementation_template
,
10225 METHOD_SEL_NAME (method
),
10226 ((TREE_CODE (method
) == CLASS_METHOD_DECL
)
10227 | OBJC_LOOKUP_NO_SUPER
));
10231 if (!comp_proto_with_proto (method
, proto
, 1))
10233 bool type
= TREE_CODE (method
) == INSTANCE_METHOD_DECL
;
10235 warning_at (DECL_SOURCE_LOCATION (method
), 0,
10236 "conflicting types for %<%c%s%>",
10237 (type
? '-' : '+'),
10238 identifier_to_locale (gen_method_decl (method
)));
10239 inform (DECL_SOURCE_LOCATION (proto
),
10240 "previous declaration of %<%c%s%>",
10241 (type
? '-' : '+'),
10242 identifier_to_locale (gen_method_decl (proto
)));
10247 /* We have a method @implementation even though we did not
10248 see a corresponding @interface declaration (which is allowed
10249 by Objective-C rules). Go ahead and place the method in
10250 the @interface anyway, so that message dispatch lookups
10252 tree interface
= implementation_template
;
10254 if (TREE_CODE (objc_implementation_context
)
10255 == CATEGORY_IMPLEMENTATION_TYPE
)
10256 interface
= lookup_category
10258 CLASS_SUPER_NAME (objc_implementation_context
));
10261 objc_add_method (interface
, copy_node (method
),
10262 TREE_CODE (method
) == CLASS_METHOD_DECL
,
10263 /* is_optional= */ false);
10268 static void *UOBJC_SUPER_scope
= 0;
10270 /* _n_Method (id self, SEL sel, ...)
10272 struct objc_super _S;
10273 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
10277 get_super_receiver (void)
10279 if (objc_method_context
)
10281 tree super_expr
, super_expr_list
;
10283 if (!UOBJC_SUPER_decl
)
10285 UOBJC_SUPER_decl
= build_decl (input_location
,
10286 VAR_DECL
, get_identifier (TAG_SUPER
),
10287 objc_super_template
);
10288 /* This prevents `unused variable' warnings when compiling with -Wall. */
10289 TREE_USED (UOBJC_SUPER_decl
) = 1;
10290 DECL_READ_P (UOBJC_SUPER_decl
) = 1;
10291 lang_hooks
.decls
.pushdecl (UOBJC_SUPER_decl
);
10292 finish_decl (UOBJC_SUPER_decl
, input_location
, NULL_TREE
, NULL_TREE
,
10294 UOBJC_SUPER_scope
= objc_get_current_scope ();
10297 /* Set receiver to self. */
10298 super_expr
= objc_build_component_ref (UOBJC_SUPER_decl
, self_id
);
10299 super_expr
= build_modify_expr (input_location
, super_expr
, NULL_TREE
,
10300 NOP_EXPR
, input_location
, self_decl
,
10302 super_expr_list
= super_expr
;
10304 /* Set class to begin searching. */
10305 super_expr
= objc_build_component_ref (UOBJC_SUPER_decl
,
10306 get_identifier ("super_class"));
10308 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
10310 /* [_cls, __cls]Super are "pre-built" in
10311 synth_forward_declarations. */
10313 super_expr
= build_modify_expr (input_location
, super_expr
,
10314 NULL_TREE
, NOP_EXPR
,
10316 ((TREE_CODE (objc_method_context
)
10317 == INSTANCE_METHOD_DECL
)
10319 : uucls_super_ref
),
10324 /* We have a category. */
10326 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
10329 /* Barf if super used in a category of Object. */
10332 error ("no super class declared in interface for %qE",
10333 CLASS_NAME (implementation_template
));
10334 return error_mark_node
;
10337 if (flag_next_runtime
&& !flag_zero_link
)
10339 super_class
= objc_get_class_reference (super_name
);
10340 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
10341 /* If we are in a class method, we must retrieve the
10342 _metaclass_ for the current class, pointed at by
10343 the class's "isa" pointer. The following assumes that
10344 "isa" is the first ivar in a class (which it must be). */
10346 = build_indirect_ref
10348 build_c_cast (input_location
,
10349 build_pointer_type (objc_class_type
),
10350 super_class
), RO_UNARY_STAR
);
10354 add_class_reference (super_name
);
10355 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
10356 ? objc_get_class_decl
: objc_get_meta_class_decl
);
10357 assemble_external (super_class
);
10359 = build_function_call
10364 my_build_string_pointer
10365 (IDENTIFIER_LENGTH (super_name
) + 1,
10366 IDENTIFIER_POINTER (super_name
))));
10370 = build_modify_expr (input_location
, super_expr
, NULL_TREE
,
10373 build_c_cast (input_location
,
10374 TREE_TYPE (super_expr
),
10379 super_expr_list
= build_compound_expr (input_location
,
10380 super_expr_list
, super_expr
);
10382 super_expr
= build_unary_op (input_location
,
10383 ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
10384 super_expr_list
= build_compound_expr (input_location
,
10385 super_expr_list
, super_expr
);
10387 return super_expr_list
;
10391 error ("[super ...] must appear in a method context");
10392 return error_mark_node
;
10396 /* When exiting a scope, sever links to a 'super' declaration (if any)
10397 therein contained. */
10400 objc_clear_super_receiver (void)
10402 if (objc_method_context
10403 && UOBJC_SUPER_scope
== objc_get_current_scope ()) {
10404 UOBJC_SUPER_decl
= 0;
10405 UOBJC_SUPER_scope
= 0;
10410 objc_finish_method_definition (tree fndecl
)
10412 /* We cannot validly inline ObjC methods, at least not without a language
10413 extension to declare that a method need not be dynamically
10414 dispatched, so suppress all thoughts of doing so. */
10415 DECL_UNINLINABLE (fndecl
) = 1;
10418 /* The C++ front-end will have called finish_function() for us. */
10419 finish_function ();
10422 METHOD_ENCODING (objc_method_context
)
10423 = encode_method_prototype (objc_method_context
);
10425 /* Required to implement _msgSuper. This must be done AFTER finish_function,
10426 since the optimizer may find "may be used before set" errors. */
10427 objc_method_context
= NULL_TREE
;
10429 if (should_call_super_dealloc
)
10430 warning (0, "method possibly missing a [super dealloc] call");
10433 /* Given a tree DECL node, produce a printable description of it in the given
10434 buffer, overwriting the buffer. */
10437 gen_declaration (tree decl
)
10443 gen_type_name_0 (TREE_TYPE (decl
));
10445 if (DECL_NAME (decl
))
10447 if (!POINTER_TYPE_P (TREE_TYPE (decl
)))
10448 strcat (errbuf
, " ");
10450 strcat (errbuf
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
10453 if (DECL_INITIAL (decl
)
10454 && TREE_CODE (DECL_INITIAL (decl
)) == INTEGER_CST
)
10455 sprintf (errbuf
+ strlen (errbuf
), ": " HOST_WIDE_INT_PRINT_DEC
,
10456 TREE_INT_CST_LOW (DECL_INITIAL (decl
)));
10462 /* Given a tree TYPE node, produce a printable description of it in the given
10463 buffer, overwriting the buffer. */
10466 gen_type_name_0 (tree type
)
10468 tree orig
= type
, proto
;
10470 if (TYPE_P (type
) && TYPE_NAME (type
))
10471 type
= TYPE_NAME (type
);
10472 else if (POINTER_TYPE_P (type
) || TREE_CODE (type
) == ARRAY_TYPE
)
10474 tree inner
= TREE_TYPE (type
);
10476 while (TREE_CODE (inner
) == ARRAY_TYPE
)
10477 inner
= TREE_TYPE (inner
);
10479 gen_type_name_0 (inner
);
10481 if (!POINTER_TYPE_P (inner
))
10482 strcat (errbuf
, " ");
10484 if (POINTER_TYPE_P (type
))
10485 strcat (errbuf
, "*");
10487 while (type
!= inner
)
10489 strcat (errbuf
, "[");
10491 if (TYPE_DOMAIN (type
))
10495 sprintf (sz
, HOST_WIDE_INT_PRINT_DEC
,
10497 (TYPE_MAX_VALUE (TYPE_DOMAIN (type
))) + 1));
10498 strcat (errbuf
, sz
);
10501 strcat (errbuf
, "]");
10502 type
= TREE_TYPE (type
);
10505 goto exit_function
;
10508 if (TREE_CODE (type
) == TYPE_DECL
&& DECL_NAME (type
))
10509 type
= DECL_NAME (type
);
10511 strcat (errbuf
, TREE_CODE (type
) == IDENTIFIER_NODE
10512 ? IDENTIFIER_POINTER (type
)
10515 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
10516 if (objc_is_id (orig
))
10517 orig
= TREE_TYPE (orig
);
10519 proto
= TYPE_HAS_OBJC_INFO (orig
) ? TYPE_OBJC_PROTOCOL_LIST (orig
) : NULL_TREE
;
10523 strcat (errbuf
, " <");
10527 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto
))));
10528 proto
= TREE_CHAIN (proto
);
10529 strcat (errbuf
, proto
? ", " : ">");
10538 gen_type_name (tree type
)
10542 return gen_type_name_0 (type
);
10545 /* Given a method tree, put a printable description into the given
10546 buffer (overwriting) and return a pointer to the buffer. */
10549 gen_method_decl (tree method
)
10553 strcpy (errbuf
, "("); /* NB: Do _not_ call strcat() here. */
10554 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method
)));
10555 strcat (errbuf
, ")");
10556 chain
= METHOD_SEL_ARGS (method
);
10560 /* We have a chain of keyword_decls. */
10563 if (KEYWORD_KEY_NAME (chain
))
10564 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
10566 strcat (errbuf
, ":(");
10567 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain
)));
10568 strcat (errbuf
, ")");
10570 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
10571 if ((chain
= DECL_CHAIN (chain
)))
10572 strcat (errbuf
, " ");
10576 if (METHOD_ADD_ARGS (method
))
10578 chain
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
10580 /* Know we have a chain of parm_decls. */
10583 strcat (errbuf
, ", ");
10584 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain
)));
10585 chain
= TREE_CHAIN (chain
);
10588 if (METHOD_ADD_ARGS_ELLIPSIS_P (method
))
10589 strcat (errbuf
, ", ...");
10594 /* We have a unary selector. */
10595 strcat (errbuf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
10603 /* Dump an @interface declaration of the supplied class CHAIN to the
10604 supplied file FP. Used to implement the -gen-decls option (which
10605 prints out an @interface declaration of all classes compiled in
10606 this run); potentially useful for debugging the compiler too. */
10608 dump_interface (FILE *fp
, tree chain
)
10610 /* FIXME: A heap overflow here whenever a method (or ivar)
10611 declaration is so long that it doesn't fit in the buffer. The
10612 code and all the related functions should be rewritten to avoid
10613 using fixed size buffers. */
10614 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
10615 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
10616 tree nst_methods
= CLASS_NST_METHODS (chain
);
10617 tree cls_methods
= CLASS_CLS_METHODS (chain
);
10619 fprintf (fp
, "\n@interface %s", my_name
);
10621 /* CLASS_SUPER_NAME is used to store the superclass name for
10622 classes, and the category name for categories. */
10623 if (CLASS_SUPER_NAME (chain
))
10625 const char *name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
10627 switch (TREE_CODE (chain
))
10629 case CATEGORY_IMPLEMENTATION_TYPE
:
10630 case CATEGORY_INTERFACE_TYPE
:
10631 fprintf (fp
, " (%s)\n", name
);
10634 fprintf (fp
, " : %s\n", name
);
10639 fprintf (fp
, "\n");
10641 /* FIXME - the following doesn't seem to work at the moment. */
10644 fprintf (fp
, "{\n");
10647 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
));
10648 ivar_decls
= TREE_CHAIN (ivar_decls
);
10650 while (ivar_decls
);
10651 fprintf (fp
, "}\n");
10654 while (nst_methods
)
10656 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
));
10657 nst_methods
= TREE_CHAIN (nst_methods
);
10660 while (cls_methods
)
10662 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
));
10663 cls_methods
= TREE_CHAIN (cls_methods
);
10666 fprintf (fp
, "@end\n");
10670 /* Produce the pretty printing for an Objective-C method. This is
10671 currently unused, but could be handy while reorganizing the pretty
10672 printing to be more robust. */
10673 static const char *
10674 objc_pretty_print_method (bool is_class_method
,
10675 const char *class_name
,
10676 const char *category_name
,
10677 const char *selector
)
10681 char *result
= XNEWVEC (char, strlen (class_name
) + strlen (category_name
)
10682 + strlen (selector
) + 7);
10684 if (is_class_method
)
10685 sprintf (result
, "+[%s(%s) %s]", class_name
, category_name
, selector
);
10687 sprintf (result
, "-[%s(%s) %s]", class_name
, category_name
, selector
);
10693 char *result
= XNEWVEC (char, strlen (class_name
)
10694 + strlen (selector
) + 5);
10696 if (is_class_method
)
10697 sprintf (result
, "+[%s %s]", class_name
, selector
);
10699 sprintf (result
, "-[%s %s]", class_name
, selector
);
10706 /* Demangle function for Objective-C. Attempt to demangle the
10707 function name associated with a method (eg, going from
10708 "_i_NSObject__class" to "-[NSObject class]"); usually for the
10709 purpose of pretty printing or error messages. Return the demangled
10710 name, or NULL if the string is not an Objective-C mangled method
10713 Because of how the mangling is done, any method that has a '_' in
10714 its original name is at risk of being demangled incorrectly. In
10715 some cases there are multiple valid ways to demangle a method name
10716 and there is no way we can decide.
10718 TODO: objc_demangle() can't always get it right; the right way to
10719 get this correct for all method names would be to store the
10720 Objective-C method name somewhere in the function decl. Then,
10721 there is no demangling to do; we'd just pull the method name out of
10722 the decl. As an additional bonus, when printing error messages we
10723 could check for such a method name, and if we find it, we know the
10724 function is actually an Objective-C method and we could print error
10725 messages saying "In method '+[NSObject class]" instead of "In
10726 function '+[NSObject class]" as we do now. */
10727 static const char *
10728 objc_demangle (const char *mangled
)
10730 char *demangled
, *cp
;
10732 if (mangled
[0] == '_' &&
10733 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
10736 cp
= demangled
= XNEWVEC (char, strlen(mangled
) + 2);
10737 if (mangled
[1] == 'i')
10738 *cp
++ = '-'; /* for instance method */
10740 *cp
++ = '+'; /* for class method */
10741 *cp
++ = '['; /* opening left brace */
10742 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
10743 while (*cp
&& *cp
== '_')
10744 cp
++; /* skip any initial underbars in class name */
10745 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
10748 free(demangled
); /* not mangled name */
10751 if (cp
[1] == '_') /* easy case: no category name */
10753 *cp
++ = ' '; /* replace two '_' with one ' ' */
10754 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
10758 *cp
++ = '('; /* less easy case: category name */
10759 cp
= strchr(cp
, '_');
10762 free(demangled
); /* not mangled name */
10766 *cp
++ = ' '; /* overwriting 1st char of method name... */
10767 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
10769 /* Now we have the method name. We need to generally replace
10770 '_' with ':' but trying to preserve '_' if it could only have
10771 been in the mangled string because it was already in the
10772 original name. In cases where it's ambiguous, we assume that
10773 any '_' originated from a ':'. */
10775 /* Initial '_'s in method name can't have been generating by
10776 converting ':'s. Skip them. */
10777 while (*cp
&& *cp
== '_')
10780 /* If the method name does not end with '_', then it has no
10781 arguments and there was no replacement of ':'s with '_'s
10782 during mangling. Check for that case, and skip any
10783 replacement if so. This at least guarantees that methods
10784 with no arguments are always demangled correctly (unless the
10785 original name ends with '_'). */
10786 if (*(mangled
+ strlen (mangled
) - 1) != '_')
10788 /* Skip to the end. */
10794 /* Replace remaining '_' with ':'. This may get it wrong if
10795 there were '_'s in the original name. In most cases it
10796 is impossible to disambiguate. */
10801 *cp
++ = ']'; /* closing right brace */
10802 *cp
++ = 0; /* string terminator */
10806 return NULL
; /* not an objc mangled name */
10809 /* Try to pretty-print a decl. If the 'decl' is an Objective-C
10810 specific decl, return the printable name for it. If not, return
10813 objc_maybe_printable_name (tree decl
, int v ATTRIBUTE_UNUSED
)
10815 switch (TREE_CODE (decl
))
10817 case FUNCTION_DECL
:
10818 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
10821 /* The following happens when we are printing a deprecation
10822 warning for a method. The warn_deprecation() will end up
10823 trying to print the decl for INSTANCE_METHOD_DECL or
10824 CLASS_METHOD_DECL. It would be nice to be able to print
10825 "-[NSObject autorelease] is deprecated", but to do that, we'd
10826 need to store the class and method name in the method decl,
10827 which we currently don't do. For now, just return the name
10828 of the method. We don't return NULL, because that may
10829 trigger further attempts to pretty-print the decl in C/C++,
10830 but they wouldn't know how to pretty-print it. */
10831 case INSTANCE_METHOD_DECL
:
10832 case CLASS_METHOD_DECL
:
10833 return IDENTIFIER_POINTER (DECL_NAME (decl
));
10841 /* Return a printable name for 'decl'. This first tries
10842 objc_maybe_printable_name(), and if that fails, it returns the name
10843 in the decl. This is used as LANG_HOOKS_DECL_PRINTABLE_NAME for
10844 Objective-C; in Objective-C++, setting the hook is not enough
10845 because lots of C++ Front-End code calls cxx_printable_name,
10846 dump_decl and other C++ functions directly. So instead we have
10847 modified dump_decl to call objc_maybe_printable_name directly. */
10849 objc_printable_name (tree decl
, int v
)
10851 const char *demangled_name
= objc_maybe_printable_name (decl
, v
);
10853 if (demangled_name
!= NULL
)
10854 return demangled_name
;
10856 return IDENTIFIER_POINTER (DECL_NAME (decl
));
10862 gcc_obstack_init (&util_obstack
);
10863 util_firstobj
= (char *) obstack_finish (&util_obstack
);
10865 errbuf
= XNEWVEC (char, 1024 * 10);
10867 synth_module_prologue ();
10873 struct imp_entry
*impent
;
10875 /* The internally generated initializers appear to have missing braces.
10876 Don't warn about this. */
10877 int save_warn_missing_braces
= warn_missing_braces
;
10878 warn_missing_braces
= 0;
10880 /* A missing @end may not be detected by the parser. */
10881 if (objc_implementation_context
)
10883 warning (0, "%<@end%> missing in implementation context");
10884 finish_class (objc_implementation_context
);
10885 objc_ivar_chain
= NULL_TREE
;
10886 objc_implementation_context
= NULL_TREE
;
10889 /* Process the static instances here because initialization of objc_symtab
10890 depends on them. */
10891 if (objc_static_instances
)
10892 generate_static_references ();
10894 /* forward declare categories */
10896 forward_declare_categories ();
10898 for (impent
= imp_list
; impent
; impent
= impent
->next
)
10900 objc_implementation_context
= impent
->imp_context
;
10901 implementation_template
= impent
->imp_template
;
10903 /* FIXME: This needs reworking to be more obvious. */
10905 UOBJC_CLASS_decl
= impent
->class_decl
;
10906 UOBJC_METACLASS_decl
= impent
->meta_decl
;
10908 /* Dump the @interface of each class as we compile it, if the
10909 -gen-decls option is in use. TODO: Dump the classes in the
10910 order they were found, rather than in reverse order as we
10912 if (flag_gen_declaration
)
10914 dump_interface (gen_declaration_file
, objc_implementation_context
);
10917 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
10919 /* all of the following reference the string pool... */
10920 generate_ivar_lists ();
10921 generate_dispatch_tables ();
10922 generate_shared_structures (impent
);
10926 generate_dispatch_tables ();
10927 generate_category (impent
);
10930 impent
->class_decl
= UOBJC_CLASS_decl
;
10931 impent
->meta_decl
= UOBJC_METACLASS_decl
;
10934 /* If we are using an array of selectors, we must always
10935 finish up the array decl even if no selectors were used. */
10936 if (flag_next_runtime
)
10937 build_next_selector_translation_table ();
10939 build_gnu_selector_translation_table ();
10941 if (protocol_chain
)
10942 generate_protocols ();
10944 if (flag_next_runtime
)
10945 generate_objc_image_info ();
10947 if (imp_list
|| class_names_chain
10948 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
10949 generate_objc_symtab_decl ();
10951 /* Arrange for ObjC data structures to be initialized at run time. */
10952 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
10953 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
10955 build_module_descriptor ();
10957 if (!flag_next_runtime
)
10958 build_module_initializer_routine ();
10961 /* Dump the class references. This forces the appropriate classes
10962 to be linked into the executable image, preserving unix archive
10963 semantics. This can be removed when we move to a more dynamically
10964 linked environment. */
10966 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
10968 handle_class_ref (chain
);
10969 if (TREE_PURPOSE (chain
))
10970 generate_classref_translation_entry (chain
);
10973 for (impent
= imp_list
; impent
; impent
= impent
->next
)
10974 handle_impent (impent
);
10981 /* Run through the selector hash tables and print a warning for any
10982 selector which has multiple methods. */
10984 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
10986 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
10987 check_duplicates (hsh
, 0, 1);
10988 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
10989 check_duplicates (hsh
, 0, 1);
10993 warn_missing_braces
= save_warn_missing_braces
;
10996 /* Subroutines of finish_objc. */
10999 generate_classref_translation_entry (tree chain
)
11001 tree expr
, decl
, type
;
11003 decl
= TREE_PURPOSE (chain
);
11004 type
= TREE_TYPE (decl
);
11006 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
11007 expr
= convert (type
, expr
); /* cast! */
11009 /* This is a class reference. It is re-written by the runtime,
11010 but will be optimized away unless we force it. */
11011 DECL_PRESERVE_P (decl
) = 1;
11012 finish_var_decl (decl
, expr
);
11017 handle_class_ref (tree chain
)
11019 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
11020 char *string
= (char *) alloca (strlen (name
) + 30);
11024 sprintf (string
, "%sobjc_class_name_%s",
11025 (flag_next_runtime
? "." : "__"), name
);
11027 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
11028 if (flag_next_runtime
)
11030 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
11035 /* Make a decl for this name, so we can use its address in a tree. */
11036 decl
= build_decl (input_location
,
11037 VAR_DECL
, get_identifier (string
), TREE_TYPE (integer_zero_node
));
11038 DECL_EXTERNAL (decl
) = 1;
11039 TREE_PUBLIC (decl
) = 1;
11041 finish_var_decl (decl
, 0);
11043 /* Make a decl for the address. */
11044 sprintf (string
, "%sobjc_class_ref_%s",
11045 (flag_next_runtime
? "." : "__"), name
);
11046 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
11047 decl
= build_decl (input_location
,
11048 VAR_DECL
, get_identifier (string
), string_type_node
);
11049 TREE_STATIC (decl
) = 1;
11050 TREE_USED (decl
) = 1;
11051 DECL_READ_P (decl
) = 1;
11052 DECL_ARTIFICIAL (decl
) = 1;
11053 DECL_INITIAL (decl
) = error_mark_node
;
11055 /* We must force the reference. */
11056 DECL_PRESERVE_P (decl
) = 1;
11059 finish_var_decl (decl
, exp
);
11063 handle_impent (struct imp_entry
*impent
)
11067 objc_implementation_context
= impent
->imp_context
;
11068 implementation_template
= impent
->imp_template
;
11070 switch (TREE_CODE (impent
->imp_context
))
11072 case CLASS_IMPLEMENTATION_TYPE
:
11074 const char *const class_name
=
11075 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
11077 string
= (char *) alloca (strlen (class_name
) + 30);
11079 sprintf (string
, "%sobjc_class_name_%s",
11080 (flag_next_runtime
? "." : "__"), class_name
);
11083 case CATEGORY_IMPLEMENTATION_TYPE
:
11085 const char *const class_name
=
11086 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
11087 const char *const class_super_name
=
11088 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
11090 string
= (char *) alloca (strlen (class_name
)
11091 + strlen (class_super_name
) + 30);
11093 /* Do the same for categories. Even though no references to
11094 these symbols are generated automatically by the compiler,
11095 it gives you a handle to pull them into an archive by
11097 sprintf (string
, "*%sobjc_category_name_%s_%s",
11098 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
11105 #ifdef ASM_DECLARE_CLASS_REFERENCE
11106 if (flag_next_runtime
)
11108 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
11116 init
= integer_zero_node
;
11117 decl
= build_decl (input_location
,
11118 VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
11119 TREE_PUBLIC (decl
) = 1;
11120 TREE_READONLY (decl
) = 1;
11121 TREE_USED (decl
) = 1;
11122 TREE_CONSTANT (decl
) = 1;
11123 DECL_CONTEXT (decl
) = NULL_TREE
;
11124 DECL_ARTIFICIAL (decl
) = 1;
11125 TREE_STATIC (decl
) = 1;
11126 DECL_INITIAL (decl
) = error_mark_node
; /* A real initializer is coming... */
11127 /* We must force the reference. */
11128 DECL_PRESERVE_P (decl
) = 1;
11130 finish_var_decl(decl
, init
) ;
11134 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
11135 later requires that ObjC translation units participating in F&C be
11136 specially marked. The following routine accomplishes this. */
11138 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
11141 generate_objc_image_info (void)
11145 = ((flag_replace_objc_classes
&& imp_count
? 1 : 0)
11146 | (flag_objc_gc
? 2 : 0));
11147 VEC(constructor_elt
,gc
) *v
= NULL
;
11151 return; /* No need for an image_info entry. */
11153 array_type
= build_sized_array_type (integer_type_node
, 2);
11155 decl
= start_var_decl (array_type
, "_OBJC_IMAGE_INFO");
11157 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
11158 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (integer_type_node
, flags
));
11159 /* If we need this (determined above) it is because the runtime wants to
11160 refer to it in a manner hidden from the compiler. So we must force the
11162 DECL_PRESERVE_P (decl
) = 1;
11163 finish_var_decl (decl
, objc_build_constructor (TREE_TYPE (decl
), v
));
11166 /* Routine is called to issue diagnostic when reference to a private
11167 ivar is made and no other variable with same name is found in
11170 objc_diagnose_private_ivar (tree id
)
11173 if (!objc_method_context
)
11175 ivar
= is_ivar (objc_ivar_chain
, id
);
11176 if (ivar
&& is_private (ivar
))
11178 error ("instance variable %qs is declared private",
11179 IDENTIFIER_POINTER (id
));
11185 /* Look up ID as an instance variable. OTHER contains the result of
11186 the C or C++ lookup, which we may want to use instead. */
11187 /* Also handle use of property as setter/getter. */
11189 objc_lookup_ivar (tree other
, tree id
)
11191 tree ivar
, property
;
11193 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
11194 if (!objc_method_context
)
11197 if (!strcmp (IDENTIFIER_POINTER (id
), "super"))
11198 /* We have a message to super. */
11199 return get_super_receiver ();
11201 /* In a class method, look up an instance variable only as a last
11203 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
11204 && other
&& other
!= error_mark_node
)
11207 property
= NULL_TREE
;
11208 if (objc_implementation_context
)
11209 property
= is_property (objc_implementation_context
, id
);
11213 /* Look up the ivar, but do not use it if it is not accessible. */
11214 ivar
= is_ivar (objc_ivar_chain
, id
);
11216 if (!ivar
|| is_private (ivar
))
11220 /* In an instance method, a local variable (or parameter) may hide the
11221 instance variable. */
11222 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
11223 && other
&& other
!= error_mark_node
11225 && CP_DECL_CONTEXT (other
) != global_namespace
)
11227 && !DECL_FILE_SCOPE_P (other
))
11231 warning (0, "local declaration of %qE hides property", id
);
11233 warning (0, "local declaration of %qE hides instance variable", id
);
11239 return build_property_reference (property
, id
);
11241 /* At this point, we are either in an instance method with no obscuring
11242 local definitions, or in a class method with no alternate definitions
11244 return build_ivar_reference (id
);
11247 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
11248 needs to be done if we are calling a function through a cast. */
11251 objc_rewrite_function_call (tree function
, tree first_param
)
11253 if (TREE_CODE (function
) == NOP_EXPR
11254 && TREE_CODE (TREE_OPERAND (function
, 0)) == ADDR_EXPR
11255 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function
, 0), 0))
11258 function
= build3 (OBJ_TYPE_REF
, TREE_TYPE (function
),
11259 TREE_OPERAND (function
, 0),
11260 first_param
, size_zero_node
);
11266 /* Look for the special case of OBJC_TYPE_REF with the address of
11267 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
11268 of its cousins). */
11271 objc_gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
11273 enum gimplify_status r0
, r1
;
11274 if (TREE_CODE (*expr_p
) == OBJ_TYPE_REF
11275 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p
)) == ADDR_EXPR
11276 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p
), 0))
11279 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
11280 value of the OBJ_TYPE_REF, so force them to be emitted
11281 during subexpression evaluation rather than after the
11282 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
11283 C to use direct rather than indirect calls when the
11284 object expression has a postincrement. */
11285 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
, NULL
,
11286 is_gimple_val
, fb_rvalue
);
11287 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
, post_p
,
11288 is_gimple_val
, fb_rvalue
);
11290 return MIN (r0
, r1
);
11294 return (enum gimplify_status
) cp_gimplify_expr (expr_p
, pre_p
, post_p
);
11296 return (enum gimplify_status
) c_gimplify_expr (expr_p
, pre_p
, post_p
);
11300 /* This routine returns true if TYP is a valid objc object type,
11301 suitable for messaging; false otherwise.
11305 objc_type_valid_for_messaging (tree typ
)
11307 if (!POINTER_TYPE_P (typ
))
11311 typ
= TREE_TYPE (typ
); /* Remove indirections. */
11312 while (POINTER_TYPE_P (typ
));
11314 if (TREE_CODE (typ
) != RECORD_TYPE
)
11317 return objc_is_object_id (typ
) || TYPE_HAS_OBJC_INFO (typ
);
11320 /* Begin code generation for fast enumeration (foreach) ... */
11324 struct __objcFastEnumerationState
11326 unsigned long state;
11328 unsigned long *mutationsPtr;
11329 unsigned long extra[5];
11332 Confusingly enough, NSFastEnumeration is then defined by libraries
11333 to be the same structure.
11337 build_fast_enumeration_state_template (void)
11339 tree decls
, *chain
= NULL
;
11342 objc_fast_enumeration_state_template
= objc_start_struct (get_identifier
11343 (TAG_FAST_ENUMERATION_STATE
));
11345 /* unsigned long state; */
11346 decls
= add_field_decl (long_unsigned_type_node
, "state", &chain
);
11348 /* id *itemsPtr; */
11349 add_field_decl (build_pointer_type (objc_object_type
),
11350 "itemsPtr", &chain
);
11352 /* unsigned long *mutationsPtr; */
11353 add_field_decl (build_pointer_type (long_unsigned_type_node
),
11354 "mutationsPtr", &chain
);
11356 /* unsigned long extra[5]; */
11357 add_field_decl (build_sized_array_type (long_unsigned_type_node
, 5),
11361 objc_finish_struct (objc_fast_enumeration_state_template
, decls
);
11365 'objc_finish_foreach_loop()' generates the code for an Objective-C
11366 foreach loop. The 'location' argument is the location of the 'for'
11367 that starts the loop. The 'object_expression' is the expression of
11368 the 'object' that iterates; the 'collection_expression' is the
11369 expression of the collection that we iterate over (we need to make
11370 sure we evaluate this only once); the 'for_body' is the set of
11371 statements to be executed in each iteration; 'break_label' and
11372 'continue_label' are the break and continue labels which we need to
11373 emit since the <statements> may be jumping to 'break_label' (if they
11374 contain 'break') or to 'continue_label' (if they contain
11379 for (<object expression> in <collection expression>)
11382 which is compiled into the following blurb:
11385 id __objc_foreach_collection;
11386 __objc_fast_enumeration_state __objc_foreach_enum_state;
11387 unsigned long __objc_foreach_batchsize;
11388 id __objc_foreach_items[16];
11389 __objc_foreach_collection = <collection expression>;
11390 __objc_foreach_enum_state = { 0 };
11391 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
11393 if (__objc_foreach_batchsize == 0)
11394 <object expression> = nil;
11397 unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
11400 unsigned long __objc_foreach_index;
11401 __objc_foreach_index = 0;
11404 if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
11405 <object expression> = enumState.itemsPtr[__objc_foreach_index];
11406 <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
11409 __objc_foreach_index++;
11410 if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
11411 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
11413 if (__objc_foreach_batchsize != 0) goto next_batch;
11414 <object expression> = nil;
11419 'statements' may contain a 'continue' or 'break' instruction, which
11420 the user expects to 'continue' or 'break' the entire foreach loop.
11421 We are provided the labels that 'break' and 'continue' jump to, so
11422 we place them where we want them to jump to when they pick them.
11424 Optimization TODO: we could cache the IMP of
11425 countByEnumeratingWithState:objects:count:.
11428 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line. */
11429 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
11431 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
11432 #include "tree-pretty-print.h"
11436 objc_finish_foreach_loop (location_t location
, tree object_expression
, tree collection_expression
, tree for_body
,
11437 tree break_label
, tree continue_label
)
11439 /* A tree representing the __objcFastEnumerationState struct type,
11440 or NSFastEnumerationState struct, whatever we are using. */
11441 tree objc_fast_enumeration_state_type
;
11443 /* The trees representing the declarations of each of the local variables. */
11444 tree objc_foreach_collection_decl
;
11445 tree objc_foreach_enum_state_decl
;
11446 tree objc_foreach_items_decl
;
11447 tree objc_foreach_batchsize_decl
;
11448 tree objc_foreach_mutations_pointer_decl
;
11449 tree objc_foreach_index_decl
;
11451 /* A tree representing the selector countByEnumeratingWithState:objects:count:. */
11452 tree selector_name
;
11454 /* A tree representing the local bind. */
11457 /* A tree representing the external 'if (__objc_foreach_batchsize)' */
11460 /* A tree representing the 'else' part of 'first_if' */
11463 /* A tree representing the 'next_batch' label. */
11464 tree next_batch_label_decl
;
11466 /* A tree representing the binding after the 'next_batch' label. */
11467 tree next_batch_bind
;
11469 /* A tree representing the 'next_object' label. */
11470 tree next_object_label_decl
;
11472 /* Temporary variables. */
11476 if (object_expression
== error_mark_node
)
11479 if (collection_expression
== error_mark_node
)
11482 if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression
)))
11484 error ("iterating variable in fast enumeration is not an object");
11488 if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression
)))
11490 error ("collection in fast enumeration is not an object");
11494 /* TODO: Check that object_expression is either a variable
11495 declaration, or an lvalue. */
11497 /* This kludge is an idea from apple. We use the
11498 __objcFastEnumerationState struct implicitly defined by the
11499 compiler, unless a NSFastEnumerationState struct has been defined
11500 (by a Foundation library such as GNUstep Base) in which case, we
11503 objc_fast_enumeration_state_type
= objc_fast_enumeration_state_template
;
11505 tree objc_NSFastEnumeration_type
= lookup_name (get_identifier ("NSFastEnumerationState"));
11507 if (objc_NSFastEnumeration_type
)
11509 /* TODO: We really need to check that
11510 objc_NSFastEnumeration_type is the same as ours! */
11511 if (TREE_CODE (objc_NSFastEnumeration_type
) == TYPE_DECL
)
11513 /* If it's a typedef, use the original type. */
11514 if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type
))
11515 objc_fast_enumeration_state_type
= DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type
);
11517 objc_fast_enumeration_state_type
= TREE_TYPE (objc_NSFastEnumeration_type
);
11523 /* Done by c-parser.c. */
11526 /* Done by c-parser.c. */
11528 /* id __objc_foreach_collection */
11529 objc_foreach_collection_decl
= objc_create_temporary_var (objc_object_type
, "__objc_foreach_collection");
11531 /* __objcFastEnumerationState __objc_foreach_enum_state; */
11532 objc_foreach_enum_state_decl
= objc_create_temporary_var (objc_fast_enumeration_state_type
, "__objc_foreach_enum_state");
11533 TREE_CHAIN (objc_foreach_enum_state_decl
) = objc_foreach_collection_decl
;
11535 /* id __objc_foreach_items[16]; */
11536 objc_foreach_items_decl
= objc_create_temporary_var (build_sized_array_type (objc_object_type
, 16), "__objc_foreach_items");
11537 TREE_CHAIN (objc_foreach_items_decl
) = objc_foreach_enum_state_decl
;
11539 /* unsigned long __objc_foreach_batchsize; */
11540 objc_foreach_batchsize_decl
= objc_create_temporary_var (long_unsigned_type_node
, "__objc_foreach_batchsize");
11541 TREE_CHAIN (objc_foreach_batchsize_decl
) = objc_foreach_items_decl
;
11543 /* Generate the local variable binding. */
11544 bind
= build3 (BIND_EXPR
, void_type_node
, objc_foreach_batchsize_decl
, NULL
, NULL
);
11545 SET_EXPR_LOCATION (bind
, location
);
11546 TREE_SIDE_EFFECTS (bind
) = 1;
11548 /* __objc_foreach_collection = <collection expression>; */
11549 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_collection_decl
, collection_expression
);
11550 SET_EXPR_LOCATION (t
, location
);
11551 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11553 /* __objc_foreach_enum_state.state = 0; */
11554 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11555 get_identifier ("state")),
11556 build_int_cst (long_unsigned_type_node
, 0));
11557 SET_EXPR_LOCATION (t
, location
);
11558 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11560 /* __objc_foreach_enum_state.itemsPtr = NULL; */
11561 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11562 get_identifier ("itemsPtr")),
11563 null_pointer_node
);
11564 SET_EXPR_LOCATION (t
, location
);
11565 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11567 /* __objc_foreach_enum_state.mutationsPtr = NULL; */
11568 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11569 get_identifier ("mutationsPtr")),
11570 null_pointer_node
);
11571 SET_EXPR_LOCATION (t
, location
);
11572 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11574 /* __objc_foreach_enum_state.extra[0] = 0; */
11575 /* __objc_foreach_enum_state.extra[1] = 0; */
11576 /* __objc_foreach_enum_state.extra[2] = 0; */
11577 /* __objc_foreach_enum_state.extra[3] = 0; */
11578 /* __objc_foreach_enum_state.extra[4] = 0; */
11579 for (i
= 0; i
< 5 ; i
++)
11581 t
= build2 (MODIFY_EXPR
, void_type_node
,
11582 build_array_ref (location
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11583 get_identifier ("extra")),
11584 build_int_cst (NULL_TREE
, i
)),
11585 build_int_cst (long_unsigned_type_node
, 0));
11586 SET_EXPR_LOCATION (t
, location
);
11587 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11590 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
11591 selector_name
= get_identifier ("countByEnumeratingWithState:objects:count:");
11593 t
= objc_finish_message_expr (objc_foreach_collection_decl
, selector_name
,
11595 tree_cons
/* &__objc_foreach_enum_state */
11596 (NULL_TREE
, build_fold_addr_expr_loc (location
, objc_foreach_enum_state_decl
),
11597 tree_cons
/* __objc_foreach_items */
11598 (NULL_TREE
, objc_foreach_items_decl
,
11600 (NULL_TREE
, build_int_cst (NULL_TREE
, 16), NULL_TREE
))));
11602 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
11604 struct c_expr array
;
11605 array
.value
= objc_foreach_items_decl
;
11606 t
= objc_finish_message_expr (objc_foreach_collection_decl
, selector_name
,
11608 tree_cons
/* &__objc_foreach_enum_state */
11609 (NULL_TREE
, build_fold_addr_expr_loc (location
, objc_foreach_enum_state_decl
),
11610 tree_cons
/* __objc_foreach_items */
11611 (NULL_TREE
, default_function_array_conversion (location
, array
).value
,
11613 (NULL_TREE
, build_int_cst (NULL_TREE
, 16), NULL_TREE
))));
11616 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_batchsize_decl
,
11617 convert (long_unsigned_type_node
, t
));
11618 SET_EXPR_LOCATION (t
, location
);
11619 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
11621 /* if (__objc_foreach_batchsize == 0) */
11622 first_if
= build3 (COND_EXPR
, void_type_node
,
11625 (c_common_truthvalue_conversion
11627 build_binary_op (location
,
11629 objc_foreach_batchsize_decl
,
11630 build_int_cst (long_unsigned_type_node
, 0), 1)),
11632 /* Then block (we fill it in later). */
11634 /* Else block (we fill it in later). */
11636 SET_EXPR_LOCATION (first_if
, location
);
11637 append_to_statement_list (first_if
, &BIND_EXPR_BODY (bind
));
11639 /* then <object expression> = nil; */
11640 t
= build2 (MODIFY_EXPR
, void_type_node
, object_expression
, convert (objc_object_type
, null_pointer_node
));
11641 SET_EXPR_LOCATION (t
, location
);
11642 COND_EXPR_THEN (first_if
) = t
;
11644 /* Now we build the 'else' part of the if; once we finish building
11645 it, we attach it to first_if as the 'else' part. */
11650 /* unsigned long __objc_foreach_mutations_pointer; */
11651 objc_foreach_mutations_pointer_decl
= objc_create_temporary_var (long_unsigned_type_node
, "__objc_foreach_mutations_pointer");
11653 /* Generate the local variable binding. */
11654 first_else
= build3 (BIND_EXPR
, void_type_node
, objc_foreach_mutations_pointer_decl
, NULL
, NULL
);
11655 SET_EXPR_LOCATION (first_else
, location
);
11656 TREE_SIDE_EFFECTS (first_else
) = 1;
11658 /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
11659 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_mutations_pointer_decl
,
11660 build_indirect_ref (location
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11661 get_identifier ("mutationsPtr")),
11663 SET_EXPR_LOCATION (t
, location
);
11664 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11667 next_batch_label_decl
= create_artificial_label (location
);
11668 t
= build1 (LABEL_EXPR
, void_type_node
, next_batch_label_decl
);
11669 SET_EXPR_LOCATION (t
, location
);
11670 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11674 /* unsigned long __objc_foreach_index; */
11675 objc_foreach_index_decl
= objc_create_temporary_var (long_unsigned_type_node
, "__objc_foreach_index");
11677 /* Generate the local variable binding. */
11678 next_batch_bind
= build3 (BIND_EXPR
, void_type_node
, objc_foreach_index_decl
, NULL
, NULL
);
11679 SET_EXPR_LOCATION (next_batch_bind
, location
);
11680 TREE_SIDE_EFFECTS (next_batch_bind
) = 1;
11681 append_to_statement_list (next_batch_bind
, &BIND_EXPR_BODY (first_else
));
11683 /* __objc_foreach_index = 0; */
11684 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_index_decl
,
11685 build_int_cst (long_unsigned_type_node
, 0));
11686 SET_EXPR_LOCATION (t
, location
);
11687 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11690 next_object_label_decl
= create_artificial_label (location
);
11691 t
= build1 (LABEL_EXPR
, void_type_node
, next_object_label_decl
);
11692 SET_EXPR_LOCATION (t
, location
);
11693 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11695 /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
11696 t
= build3 (COND_EXPR
, void_type_node
,
11699 (c_common_truthvalue_conversion
11704 objc_foreach_mutations_pointer_decl
,
11705 build_indirect_ref (location
,
11706 objc_build_component_ref (objc_foreach_enum_state_decl
,
11707 get_identifier ("mutationsPtr")),
11708 RO_UNARY_STAR
), 1)),
11711 build_function_call (input_location
,
11712 objc_enumeration_mutation_decl
,
11713 tree_cons (NULL
, collection_expression
, NULL
)),
11716 SET_EXPR_LOCATION (t
, location
);
11717 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11719 /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
11720 t
= build2 (MODIFY_EXPR
, void_type_node
, object_expression
,
11721 build_array_ref (location
, objc_build_component_ref (objc_foreach_enum_state_decl
,
11722 get_identifier ("itemsPtr")),
11723 objc_foreach_index_decl
));
11724 SET_EXPR_LOCATION (t
, location
);
11725 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11727 /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
11728 append_to_statement_list (for_body
, &BIND_EXPR_BODY (next_batch_bind
));
11730 /* continue_label: */
11731 if (continue_label
)
11733 t
= build1 (LABEL_EXPR
, void_type_node
, continue_label
);
11734 SET_EXPR_LOCATION (t
, location
);
11735 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11738 /* __objc_foreach_index++; */
11739 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_index_decl
,
11740 build_binary_op (location
,
11742 objc_foreach_index_decl
,
11743 build_int_cst (long_unsigned_type_node
, 1), 1));
11744 SET_EXPR_LOCATION (t
, location
);
11745 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11747 /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
11748 t
= build3 (COND_EXPR
, void_type_node
,
11751 (c_common_truthvalue_conversion
11753 build_binary_op (location
,
11755 objc_foreach_index_decl
,
11756 objc_foreach_batchsize_decl
, 1)),
11759 build1 (GOTO_EXPR
, void_type_node
, next_object_label_decl
),
11762 SET_EXPR_LOCATION (t
, location
);
11763 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11765 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
11767 t
= objc_finish_message_expr (objc_foreach_collection_decl
, selector_name
,
11769 tree_cons
/* &__objc_foreach_enum_state */
11770 (NULL_TREE
, build_fold_addr_expr_loc (location
, objc_foreach_enum_state_decl
),
11771 tree_cons
/* __objc_foreach_items */
11772 (NULL_TREE
, objc_foreach_items_decl
,
11774 (NULL_TREE
, build_int_cst (NULL_TREE
, 16), NULL_TREE
))));
11776 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
11778 struct c_expr array
;
11779 array
.value
= objc_foreach_items_decl
;
11780 t
= objc_finish_message_expr (objc_foreach_collection_decl
, selector_name
,
11782 tree_cons
/* &__objc_foreach_enum_state */
11783 (NULL_TREE
, build_fold_addr_expr_loc (location
, objc_foreach_enum_state_decl
),
11784 tree_cons
/* __objc_foreach_items */
11785 (NULL_TREE
, default_function_array_conversion (location
, array
).value
,
11787 (NULL_TREE
, build_int_cst (NULL_TREE
, 16), NULL_TREE
))));
11790 t
= build2 (MODIFY_EXPR
, void_type_node
, objc_foreach_batchsize_decl
,
11791 convert (long_unsigned_type_node
, t
));
11792 SET_EXPR_LOCATION (t
, location
);
11793 append_to_statement_list (t
, &BIND_EXPR_BODY (next_batch_bind
));
11797 /* if (__objc_foreach_batchsize != 0) goto next_batch; */
11798 t
= build3 (COND_EXPR
, void_type_node
,
11801 (c_common_truthvalue_conversion
11803 build_binary_op (location
,
11805 objc_foreach_batchsize_decl
,
11806 build_int_cst (long_unsigned_type_node
, 0), 1)),
11809 build1 (GOTO_EXPR
, void_type_node
, next_batch_label_decl
),
11812 SET_EXPR_LOCATION (t
, location
);
11813 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11815 /* <object expression> = nil; */
11816 t
= build2 (MODIFY_EXPR
, void_type_node
, object_expression
, convert (objc_object_type
, null_pointer_node
));
11817 SET_EXPR_LOCATION (t
, location
);
11818 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11823 t
= build1 (LABEL_EXPR
, void_type_node
, break_label
);
11824 SET_EXPR_LOCATION (t
, location
);
11825 append_to_statement_list (t
, &BIND_EXPR_BODY (first_else
));
11829 COND_EXPR_ELSE (first_if
) = first_else
;
11831 /* Do the whole thing. */
11834 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
11835 /* This will print to stderr the whole blurb generated by the
11836 compiler while compiling (assuming the compiler doesn't crash
11837 before getting here).
11839 debug_generic_stmt (bind
);
11843 /* Done by c-parser.c */
11846 #include "gt-objc-objc-act.h"