1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
60 #include "langhooks.h"
71 #include "diagnostic.h"
73 #include "tree-iterator.h"
76 #include "langhooks-def.h"
78 #define OBJC_VOID_AT_END void_list_node
80 static unsigned int should_call_super_dealloc
= 0;
82 /* When building Objective-C++, we are not linking against the C front-end
83 and so need to replicate the C tree-construction functions in some way. */
85 #define OBJCP_REMAP_FUNCTIONS
86 #include "objcp-decl.h"
89 /* This is the default way of generating a method name. */
90 /* I am not sure it is really correct.
91 Perhaps there's a danger that it will make name conflicts
92 if method names contain underscores. -- rms. */
93 #ifndef OBJC_GEN_METHOD_LABEL
94 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
97 sprintf ((BUF), "_%s_%s_%s_%s", \
98 ((IS_INST) ? "i" : "c"), \
100 ((CAT_NAME)? (CAT_NAME) : ""), \
102 for (temp = (BUF); *temp; temp++) \
103 if (*temp == ':') *temp = '_'; \
107 /* These need specifying. */
108 #ifndef OBJC_FORWARDING_STACK_OFFSET
109 #define OBJC_FORWARDING_STACK_OFFSET 0
112 #ifndef OBJC_FORWARDING_MIN_OFFSET
113 #define OBJC_FORWARDING_MIN_OFFSET 0
116 /* Set up for use of obstacks. */
120 /* This obstack is used to accumulate the encoding of a data type. */
121 static struct obstack util_obstack
;
123 /* This points to the beginning of obstack contents, so we can free
124 the whole contents. */
127 /* The version identifies which language generation and runtime
128 the module (file) was compiled for, and is recorded in the
129 module descriptor. */
131 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
132 #define PROTOCOL_VERSION 2
134 /* (Decide if these can ever be validly changed.) */
135 #define OBJC_ENCODE_INLINE_DEFS 0
136 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
138 /*** Private Interface (procedures) ***/
140 /* Used by compile_file. */
142 static void init_objc (void);
143 static void finish_objc (void);
145 /* Code generation. */
147 static tree
objc_build_constructor (tree
, tree
);
148 static tree
build_objc_method_call (int, tree
, tree
, tree
, tree
);
149 static tree
get_proto_encoding (tree
);
150 static tree
lookup_interface (tree
);
151 static tree
objc_add_static_instance (tree
, tree
);
153 static tree
start_class (enum tree_code
, tree
, tree
, tree
);
154 static tree
continue_class (tree
);
155 static void finish_class (tree
);
156 static void start_method_def (tree
);
158 static void objc_start_function (tree
, tree
, tree
, tree
);
160 static void objc_start_function (tree
, tree
, tree
, struct c_arg_info
*);
162 static tree
start_protocol (enum tree_code
, tree
, tree
);
163 static tree
build_method_decl (enum tree_code
, tree
, tree
, tree
, bool);
164 static tree
objc_add_method (tree
, tree
, int);
165 static tree
add_instance_variable (tree
, int, tree
);
166 static tree
build_ivar_reference (tree
);
167 static tree
is_ivar (tree
, tree
);
169 static void build_objc_exception_stuff (void);
170 static void build_next_objc_exception_stuff (void);
172 /* We only need the following for ObjC; ObjC++ will use C++'s definition
173 of DERIVED_FROM_P. */
175 static bool objc_derived_from_p (tree
, tree
);
176 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
178 static void objc_xref_basetypes (tree
, tree
);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static void build_super_template (void);
184 static tree
build_protocol_initializer (tree
, tree
, tree
, tree
, tree
);
185 static tree
get_class_ivars (tree
, bool);
186 static tree
generate_protocol_list (tree
);
187 static void build_protocol_reference (tree
);
190 static void objc_generate_cxx_cdtors (void);
193 static const char *synth_id_with_class_suffix (const char *, tree
);
195 /* Hash tables to manage the global pool of method prototypes. */
197 hash
*nst_method_hash_list
= 0;
198 hash
*cls_method_hash_list
= 0;
200 static hash
hash_lookup (hash
*, tree
);
201 static tree
lookup_method (tree
, tree
);
202 static tree
lookup_method_static (tree
, tree
, int);
206 class_names
, /* class, category, protocol, module names */
207 meth_var_names
, /* method and variable names */
208 meth_var_types
/* method and variable type descriptors */
211 static tree
add_objc_string (tree
, enum string_section
);
212 static tree
build_objc_string_decl (enum string_section
);
213 static void build_selector_table_decl (void);
215 /* Protocol additions. */
217 static tree
lookup_protocol (tree
);
218 static tree
lookup_and_install_protocols (tree
);
222 static void encode_type_qualifiers (tree
);
223 static void encode_type (tree
, int, int);
224 static void encode_field_decl (tree
, int, int);
227 static void really_start_method (tree
, tree
);
229 static void really_start_method (tree
, struct c_arg_info
*);
231 static int comp_proto_with_proto (tree
, tree
, int);
232 static void objc_push_parm (tree
);
234 static tree
objc_get_parm_info (int);
236 static struct c_arg_info
*objc_get_parm_info (int);
239 /* Utilities for debugging and error diagnostics. */
241 static void warn_with_method (const char *, int, tree
);
242 static char *gen_type_name (tree
);
243 static char *gen_type_name_0 (tree
);
244 static char *gen_method_decl (tree
);
245 static char *gen_declaration (tree
);
247 /* Everything else. */
249 static tree
create_field_decl (tree
, const char *);
250 static void add_class_reference (tree
);
251 static void build_protocol_template (void);
252 static tree
encode_method_prototype (tree
);
253 static void generate_classref_translation_entry (tree
);
254 static void handle_class_ref (tree
);
255 static void generate_struct_by_value_array (void)
257 static void mark_referenced_methods (void);
258 static void generate_objc_image_info (void);
260 /*** Private Interface (data) ***/
262 /* Reserved tag definitions. */
264 #define OBJECT_TYPEDEF_NAME "id"
265 #define CLASS_TYPEDEF_NAME "Class"
267 #define TAG_OBJECT "objc_object"
268 #define TAG_CLASS "objc_class"
269 #define TAG_SUPER "objc_super"
270 #define TAG_SELECTOR "objc_selector"
272 #define UTAG_CLASS "_objc_class"
273 #define UTAG_IVAR "_objc_ivar"
274 #define UTAG_IVAR_LIST "_objc_ivar_list"
275 #define UTAG_METHOD "_objc_method"
276 #define UTAG_METHOD_LIST "_objc_method_list"
277 #define UTAG_CATEGORY "_objc_category"
278 #define UTAG_MODULE "_objc_module"
279 #define UTAG_SYMTAB "_objc_symtab"
280 #define UTAG_SUPER "_objc_super"
281 #define UTAG_SELECTOR "_objc_selector"
283 #define UTAG_PROTOCOL "_objc_protocol"
284 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
285 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
287 /* Note that the string object global name is only needed for the
289 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
291 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
293 static const char *TAG_GETCLASS
;
294 static const char *TAG_GETMETACLASS
;
295 static const char *TAG_MSGSEND
;
296 static const char *TAG_MSGSENDSUPER
;
297 /* The NeXT Objective-C messenger may have two extra entry points, for use
298 when returning a structure. */
299 static const char *TAG_MSGSEND_STRET
;
300 static const char *TAG_MSGSENDSUPER_STRET
;
301 static const char *default_constant_string_class_name
;
303 /* Runtime metadata flags. */
304 #define CLS_FACTORY 0x0001L
305 #define CLS_META 0x0002L
306 #define CLS_HAS_CXX_STRUCTORS 0x2000L
308 #define OBJC_MODIFIER_STATIC 0x00000001
309 #define OBJC_MODIFIER_FINAL 0x00000002
310 #define OBJC_MODIFIER_PUBLIC 0x00000004
311 #define OBJC_MODIFIER_PRIVATE 0x00000008
312 #define OBJC_MODIFIER_PROTECTED 0x00000010
313 #define OBJC_MODIFIER_NATIVE 0x00000020
314 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
315 #define OBJC_MODIFIER_ABSTRACT 0x00000080
316 #define OBJC_MODIFIER_VOLATILE 0x00000100
317 #define OBJC_MODIFIER_TRANSIENT 0x00000200
318 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
320 /* NeXT-specific tags. */
322 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
323 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
324 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
325 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
326 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
327 #define TAG_EXCEPTIONMATCH "objc_exception_match"
328 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
329 #define TAG_SYNCENTER "objc_sync_enter"
330 #define TAG_SYNCEXIT "objc_sync_exit"
331 #define TAG_SETJMP "_setjmp"
332 #define UTAG_EXCDATA "_objc_exception_data"
334 #define TAG_ASSIGNIVAR "objc_assign_ivar"
335 #define TAG_ASSIGNGLOBAL "objc_assign_global"
336 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
338 /* Branch entry points. All that matters here are the addresses;
339 functions with these names do not really exist in libobjc. */
341 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
342 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
344 #define TAG_CXX_CONSTRUCT ".cxx_construct"
345 #define TAG_CXX_DESTRUCT ".cxx_destruct"
347 /* GNU-specific tags. */
349 #define TAG_EXECCLASS "__objc_exec_class"
350 #define TAG_GNUINIT "__objc_gnu_init"
352 /* Flags for lookup_method_static(). */
353 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
354 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
356 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
357 tree objc_global_trees
[OCTI_MAX
];
359 static void handle_impent (struct imp_entry
*);
361 struct imp_entry
*imp_list
= 0;
362 int imp_count
= 0; /* `@implementation' */
363 int cat_count
= 0; /* `@category' */
365 enum tree_code objc_inherit_code
;
366 int objc_public_flag
;
368 /* Use to generate method labels. */
369 static int method_slot
= 0;
373 static char *errbuf
; /* Buffer for error diagnostics */
375 /* Data imported from tree.c. */
377 extern enum debug_info_type write_symbols
;
379 /* Data imported from toplev.c. */
381 extern const char *dump_base_name
;
383 static int flag_typed_selectors
;
385 /* Store all constructed constant strings in a hash table so that
386 they get uniqued properly. */
388 struct string_descriptor
GTY(())
390 /* The literal argument . */
393 /* The resulting constant string. */
397 static GTY((param_is (struct string_descriptor
))) htab_t string_htab
;
399 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
400 struct volatilized_type
GTY(())
405 static GTY((param_is (struct volatilized_type
))) htab_t volatilized_htab
;
407 FILE *gen_declaration_file
;
409 /* Tells "encode_pointer/encode_aggregate" whether we are generating
410 type descriptors for instance variables (as opposed to methods).
411 Type descriptors for instance variables contain more information
412 than methods (for static typing and embedded structures). */
414 static int generating_instance_variables
= 0;
416 /* Some platforms pass small structures through registers versus
417 through an invisible pointer. Determine at what size structure is
418 the transition point between the two possibilities. */
421 generate_struct_by_value_array (void)
424 tree field_decl
, field_decl_chain
;
426 int aggregate_in_mem
[32];
429 /* Presumably no platform passes 32 byte structures in a register. */
430 for (i
= 1; i
< 32; i
++)
434 /* Create an unnamed struct that has `i' character components */
435 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
437 strcpy (buffer
, "c1");
438 field_decl
= create_field_decl (char_type_node
,
440 field_decl_chain
= field_decl
;
442 for (j
= 1; j
< i
; j
++)
444 sprintf (buffer
, "c%d", j
+ 1);
445 field_decl
= create_field_decl (char_type_node
,
447 chainon (field_decl_chain
, field_decl
);
449 finish_struct (type
, field_decl_chain
, NULL_TREE
);
451 aggregate_in_mem
[i
] = aggregate_value_p (type
, 0);
452 if (!aggregate_in_mem
[i
])
456 /* We found some structures that are returned in registers instead of memory
457 so output the necessary data. */
460 for (i
= 31; i
>= 0; i
--)
461 if (!aggregate_in_mem
[i
])
463 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
465 /* The first member of the structure is always 0 because we don't handle
466 structures with 0 members */
467 printf ("static int struct_forward_array[] = {\n 0");
469 for (j
= 1; j
<= i
; j
++)
470 printf (", %d", aggregate_in_mem
[j
]);
481 if (cxx_init () == false)
483 if (c_objc_common_init () == false)
487 /* If gen_declaration desired, open the output file. */
488 if (flag_gen_declaration
)
490 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
491 gen_declaration_file
= fopen (dumpname
, "w");
492 if (gen_declaration_file
== 0)
493 fatal_error ("can't open %s: %m", dumpname
);
497 if (flag_next_runtime
)
499 TAG_GETCLASS
= "objc_getClass";
500 TAG_GETMETACLASS
= "objc_getMetaClass";
501 TAG_MSGSEND
= "objc_msgSend";
502 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
503 TAG_MSGSEND_STRET
= "objc_msgSend_stret";
504 TAG_MSGSENDSUPER_STRET
= "objc_msgSendSuper_stret";
505 default_constant_string_class_name
= "NSConstantString";
509 TAG_GETCLASS
= "objc_get_class";
510 TAG_GETMETACLASS
= "objc_get_meta_class";
511 TAG_MSGSEND
= "objc_msg_lookup";
512 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
513 /* GNU runtime does not provide special functions to support
514 structure-returning methods. */
515 default_constant_string_class_name
= "NXConstantString";
516 flag_typed_selectors
= 1;
521 if (print_struct_values
)
522 generate_struct_by_value_array ();
528 objc_finish_file (void)
530 mark_referenced_methods ();
533 /* We need to instantiate templates _before_ we emit ObjC metadata;
534 if we do not, some metadata (such as selectors) may go missing. */
536 instantiate_pending_templates (0);
539 /* Finalize Objective-C runtime data. No need to generate tables
540 and code if only checking syntax, or if generating a PCH file. */
541 if (!flag_syntax_only
&& !pch_file
)
544 if (gen_declaration_file
)
545 fclose (gen_declaration_file
);
548 /* Return the first occurrence of a method declaration corresponding
549 to sel_name in rproto_list. Search rproto_list recursively.
550 If is_class is 0, search for instance methods, otherwise for class
553 lookup_method_in_protocol_list (tree rproto_list
, tree sel_name
,
559 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
561 p
= TREE_VALUE (rproto
);
563 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
565 if ((fnd
= lookup_method (is_class
566 ? PROTOCOL_CLS_METHODS (p
)
567 : PROTOCOL_NST_METHODS (p
), sel_name
)))
569 else if (PROTOCOL_LIST (p
))
570 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
575 ; /* An identifier...if we could not find a protocol. */
586 lookup_protocol_in_reflist (tree rproto_list
, tree lproto
)
590 /* Make sure the protocol is supported by the object on the rhs. */
591 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
594 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
596 p
= TREE_VALUE (rproto
);
598 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
603 else if (PROTOCOL_LIST (p
))
604 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
613 ; /* An identifier...if we could not find a protocol. */
620 objc_start_class_interface (tree klass
, tree super_class
, tree protos
)
622 objc_interface_context
624 = start_class (CLASS_INTERFACE_TYPE
, klass
, super_class
, protos
);
625 objc_public_flag
= 0;
629 objc_start_category_interface (tree klass
, tree categ
, tree protos
)
631 objc_interface_context
632 = start_class (CATEGORY_INTERFACE_TYPE
, klass
, categ
, protos
);
634 = continue_class (objc_interface_context
);
638 objc_start_protocol (tree name
, tree protos
)
640 objc_interface_context
641 = start_protocol (PROTOCOL_INTERFACE_TYPE
, name
, protos
);
645 objc_continue_interface (void)
648 = continue_class (objc_interface_context
);
652 objc_finish_interface (void)
654 finish_class (objc_interface_context
);
655 objc_interface_context
= NULL_TREE
;
659 objc_start_class_implementation (tree klass
, tree super_class
)
661 objc_implementation_context
663 = start_class (CLASS_IMPLEMENTATION_TYPE
, klass
, super_class
, NULL_TREE
);
664 objc_public_flag
= 0;
668 objc_start_category_implementation (tree klass
, tree categ
)
670 objc_implementation_context
671 = start_class (CATEGORY_IMPLEMENTATION_TYPE
, klass
, categ
, NULL_TREE
);
673 = continue_class (objc_implementation_context
);
677 objc_continue_implementation (void)
680 = continue_class (objc_implementation_context
);
684 objc_finish_implementation (void)
687 if (flag_objc_call_cxx_cdtors
)
688 objc_generate_cxx_cdtors ();
691 if (objc_implementation_context
)
693 finish_class (objc_implementation_context
);
694 objc_ivar_chain
= NULL_TREE
;
695 objc_implementation_context
= NULL_TREE
;
698 warning (0, "%<@end%> must appear in an @implementation context");
702 objc_set_visibility (int visibility
)
704 objc_public_flag
= visibility
;
708 objc_set_method_type (enum tree_code type
)
710 objc_inherit_code
= (type
== PLUS_EXPR
712 : INSTANCE_METHOD_DECL
);
716 objc_build_method_signature (tree rettype
, tree selector
,
717 tree optparms
, bool ellipsis
)
719 return build_method_decl (objc_inherit_code
, rettype
, selector
,
724 objc_add_method_declaration (tree decl
)
726 if (!objc_interface_context
)
727 fatal_error ("method declaration not in @interface context");
729 objc_add_method (objc_interface_context
,
731 objc_inherit_code
== CLASS_METHOD_DECL
);
735 objc_start_method_definition (tree decl
)
737 if (!objc_implementation_context
)
738 fatal_error ("method definition not in @implementation context");
740 objc_add_method (objc_implementation_context
,
742 objc_inherit_code
== CLASS_METHOD_DECL
);
743 start_method_def (decl
);
747 objc_add_instance_variable (tree decl
)
749 (void) add_instance_variable (objc_ivar_context
,
754 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
758 objc_is_reserved_word (tree ident
)
760 unsigned char code
= C_RID_CODE (ident
);
762 return (OBJC_IS_AT_KEYWORD (code
)
763 || code
== RID_CLASS
|| code
== RID_PUBLIC
764 || code
== RID_PROTECTED
|| code
== RID_PRIVATE
765 || code
== RID_TRY
|| code
== RID_THROW
|| code
== RID_CATCH
);
768 /* Return true if TYPE is 'id'. */
771 objc_is_object_id (tree type
)
773 return OBJC_TYPE_NAME (type
) == objc_object_id
;
777 objc_is_class_id (tree type
)
779 return OBJC_TYPE_NAME (type
) == objc_class_id
;
782 /* Construct a C struct with same name as KLASS, a base struct with tag
783 SUPER_NAME (if any), and FIELDS indicated. */
786 objc_build_struct (tree klass
, tree fields
, tree super_name
)
788 tree name
= CLASS_NAME (klass
);
789 tree s
= start_struct (RECORD_TYPE
, name
);
790 tree super
= (super_name
? xref_tag (RECORD_TYPE
, super_name
) : NULL_TREE
);
791 tree t
, objc_info
= NULL_TREE
;
795 /* Prepend a packed variant of the base class into the layout. This
796 is necessary to preserve ObjC ABI compatibility. */
797 tree base
= build_decl (FIELD_DECL
, NULL_TREE
, super
);
798 tree field
= TYPE_FIELDS (super
);
800 while (field
&& TREE_CHAIN (field
)
801 && TREE_CODE (TREE_CHAIN (field
)) == FIELD_DECL
)
802 field
= TREE_CHAIN (field
);
804 /* For ObjC ABI purposes, the "packed" size of a base class is
805 the sum of the offset and the size (in bits) of the last field
808 = (field
&& TREE_CODE (field
) == FIELD_DECL
809 ? size_binop (PLUS_EXPR
,
810 size_binop (PLUS_EXPR
,
813 convert (bitsizetype
,
814 DECL_FIELD_OFFSET (field
)),
815 bitsize_int (BITS_PER_UNIT
)),
816 DECL_FIELD_BIT_OFFSET (field
)),
818 : bitsize_zero_node
);
819 DECL_SIZE_UNIT (base
)
820 = size_binop (FLOOR_DIV_EXPR
, convert (sizetype
, DECL_SIZE (base
)),
821 size_int (BITS_PER_UNIT
));
822 DECL_ARTIFICIAL (base
) = 1;
823 DECL_ALIGN (base
) = 1;
824 DECL_FIELD_CONTEXT (base
) = s
;
826 DECL_FIELD_IS_BASE (base
) = 1;
829 TREE_NO_WARNING (fields
) = 1; /* Suppress C++ ABI warnings -- we */
830 #endif /* are following the ObjC ABI here. */
831 TREE_CHAIN (base
) = fields
;
835 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
836 in all variants of this RECORD_TYPE to be clobbered, but it is therein
837 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
838 Hence, we must squirrel away the ObjC-specific information before calling
839 finish_struct(), and then reinstate it afterwards. */
841 for (t
= TYPE_NEXT_VARIANT (s
); t
; t
= TYPE_NEXT_VARIANT (t
))
843 = chainon (objc_info
,
844 build_tree_list (NULL_TREE
, TYPE_OBJC_INFO (t
)));
846 /* Point the struct at its related Objective-C class. */
847 INIT_TYPE_OBJC_INFO (s
);
848 TYPE_OBJC_INTERFACE (s
) = klass
;
850 s
= finish_struct (s
, fields
, NULL_TREE
);
852 for (t
= TYPE_NEXT_VARIANT (s
); t
;
853 t
= TYPE_NEXT_VARIANT (t
), objc_info
= TREE_CHAIN (objc_info
))
855 TYPE_OBJC_INFO (t
) = TREE_VALUE (objc_info
);
856 /* Replace the IDENTIFIER_NODE with an actual @interface. */
857 TYPE_OBJC_INTERFACE (t
) = klass
;
860 /* Use TYPE_BINFO structures to point at the super class, if any. */
861 objc_xref_basetypes (s
, super
);
863 /* Mark this struct as a class template. */
864 CLASS_STATIC_TEMPLATE (klass
) = s
;
869 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
870 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
873 objc_build_volatilized_type (tree type
)
877 /* Check if we have not constructed the desired variant already. */
878 for (t
= TYPE_MAIN_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
880 /* The type qualifiers must (obviously) match up. */
881 if (!TYPE_VOLATILE (t
)
882 || (TYPE_READONLY (t
) != TYPE_READONLY (type
))
883 || (TYPE_RESTRICT (t
) != TYPE_RESTRICT (type
)))
886 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
887 info, if any) must match up. */
888 if (POINTER_TYPE_P (t
)
889 && (TREE_TYPE (t
) != TREE_TYPE (type
)))
892 /* Everything matches up! */
896 /* Ok, we could not re-use any of the pre-existing variants. Create
898 t
= build_variant_type_copy (type
);
899 TYPE_VOLATILE (t
) = 1;
901 /* Set up the canonical type information. */
902 if (TYPE_STRUCTURAL_EQUALITY_P (type
))
903 SET_TYPE_STRUCTURAL_EQUALITY (t
);
904 else if (TYPE_CANONICAL (type
) != type
)
905 TYPE_CANONICAL (t
) = objc_build_volatilized_type (TYPE_CANONICAL (type
));
907 TYPE_CANONICAL (t
) = t
;
912 /* Mark DECL as being 'volatile' for purposes of Darwin
913 _setjmp()/_longjmp() exception handling. Called from
914 objc_mark_locals_volatile(). */
916 objc_volatilize_decl (tree decl
)
918 /* Do not mess with variables that are 'static' or (already)
920 if (!TREE_THIS_VOLATILE (decl
) && !TREE_STATIC (decl
)
921 && (TREE_CODE (decl
) == VAR_DECL
922 || TREE_CODE (decl
) == PARM_DECL
))
924 tree t
= TREE_TYPE (decl
);
925 struct volatilized_type key
;
928 t
= objc_build_volatilized_type (t
);
930 loc
= htab_find_slot (volatilized_htab
, &key
, INSERT
);
934 *loc
= ggc_alloc (sizeof (key
));
935 ((struct volatilized_type
*) *loc
)->type
= t
;
938 TREE_TYPE (decl
) = t
;
939 TREE_THIS_VOLATILE (decl
) = 1;
940 TREE_SIDE_EFFECTS (decl
) = 1;
941 DECL_REGISTER (decl
) = 0;
943 C_DECL_REGISTER (decl
) = 0;
948 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
949 (including its categories and superclasses) or by object type TYP.
950 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
953 objc_lookup_protocol (tree proto
, tree cls
, tree typ
, bool warn
)
955 bool class_type
= (cls
!= NULL_TREE
);
961 /* Check protocols adopted by the class and its categories. */
962 for (c
= cls
; c
; c
= CLASS_CATEGORY_LIST (c
))
964 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c
), proto
))
968 /* Repeat for superclasses. */
969 cls
= lookup_interface (CLASS_SUPER_NAME (cls
));
972 /* Check for any protocols attached directly to the object type. */
973 if (TYPE_HAS_OBJC_INFO (typ
))
975 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ
), proto
))
981 strcpy (errbuf
, class_type
? "class \'" : "type \'");
982 gen_type_name_0 (class_type
? typ
: TYPE_POINTER_TO (typ
));
983 strcat (errbuf
, "\' does not ");
984 /* NB: Types 'id' and 'Class' cannot reasonably be described as
985 "implementing" a given protocol, since they do not have an
987 strcat (errbuf
, class_type
? "implement" : "conform to");
988 strcat (errbuf
, " the \'");
989 strcat (errbuf
, IDENTIFIER_POINTER (PROTOCOL_NAME (proto
)));
990 strcat (errbuf
, "\' protocol");
997 /* Check if class RCLS and instance struct type RTYP conform to at least the
998 same protocols that LCLS and LTYP conform to. */
1001 objc_compare_protocols (tree lcls
, tree ltyp
, tree rcls
, tree rtyp
, bool warn
)
1004 bool have_lproto
= false;
1008 /* NB: We do _not_ look at categories defined for LCLS; these may or
1009 may not get loaded in, and therefore it is unreasonable to require
1010 that RCLS/RTYP must implement any of their protocols. */
1011 for (p
= CLASS_PROTOCOL_LIST (lcls
); p
; p
= TREE_CHAIN (p
))
1015 if (!objc_lookup_protocol (TREE_VALUE (p
), rcls
, rtyp
, warn
))
1019 /* Repeat for superclasses. */
1020 lcls
= lookup_interface (CLASS_SUPER_NAME (lcls
));
1023 /* Check for any protocols attached directly to the object type. */
1024 if (TYPE_HAS_OBJC_INFO (ltyp
))
1026 for (p
= TYPE_OBJC_PROTOCOL_LIST (ltyp
); p
; p
= TREE_CHAIN (p
))
1030 if (!objc_lookup_protocol (TREE_VALUE (p
), rcls
, rtyp
, warn
))
1035 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1036 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1037 away with simply checking for 'id' or 'Class' (!RCLS), since this
1038 routine will not get called in other cases. */
1039 return have_lproto
|| (rcls
!= NULL_TREE
);
1042 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1043 an instance of RTYP to an instance of LTYP or to compare the two
1044 (if ARGNO is equal to -3), per ObjC type system rules. Before
1045 returning 'true', this routine may issue warnings related to, e.g.,
1046 protocol conformance. When returning 'false', the routine must
1047 produce absolutely no warnings; the C or C++ front-end will do so
1048 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1049 the routine must return 'false'.
1051 The ARGNO parameter is encoded as follows:
1052 >= 1 Parameter number (CALLEE contains function being called);
1056 -3 Comparison (LTYP and RTYP may match in either direction). */
1059 objc_compare_types (tree ltyp
, tree rtyp
, int argno
, tree callee
)
1061 tree lcls
, rcls
, lproto
, rproto
;
1062 bool pointers_compatible
;
1064 /* We must be dealing with pointer types */
1065 if (!POINTER_TYPE_P (ltyp
) || !POINTER_TYPE_P (rtyp
))
1070 ltyp
= TREE_TYPE (ltyp
); /* Remove indirections. */
1071 rtyp
= TREE_TYPE (rtyp
);
1073 while (POINTER_TYPE_P (ltyp
) && POINTER_TYPE_P (rtyp
));
1075 /* Past this point, we are only interested in ObjC class instances,
1076 or 'id' or 'Class'. */
1077 if (TREE_CODE (ltyp
) != RECORD_TYPE
|| TREE_CODE (rtyp
) != RECORD_TYPE
)
1080 if (!objc_is_object_id (ltyp
) && !objc_is_class_id (ltyp
)
1081 && !TYPE_HAS_OBJC_INFO (ltyp
))
1084 if (!objc_is_object_id (rtyp
) && !objc_is_class_id (rtyp
)
1085 && !TYPE_HAS_OBJC_INFO (rtyp
))
1088 /* Past this point, we are committed to returning 'true' to the caller.
1089 However, we can still warn about type and/or protocol mismatches. */
1091 if (TYPE_HAS_OBJC_INFO (ltyp
))
1093 lcls
= TYPE_OBJC_INTERFACE (ltyp
);
1094 lproto
= TYPE_OBJC_PROTOCOL_LIST (ltyp
);
1097 lcls
= lproto
= NULL_TREE
;
1099 if (TYPE_HAS_OBJC_INFO (rtyp
))
1101 rcls
= TYPE_OBJC_INTERFACE (rtyp
);
1102 rproto
= TYPE_OBJC_PROTOCOL_LIST (rtyp
);
1105 rcls
= rproto
= NULL_TREE
;
1107 /* If we could not find an @interface declaration, we must have
1108 only seen a @class declaration; for purposes of type comparison,
1109 treat it as a stand-alone (root) class. */
1111 if (lcls
&& TREE_CODE (lcls
) == IDENTIFIER_NODE
)
1114 if (rcls
&& TREE_CODE (rcls
) == IDENTIFIER_NODE
)
1117 /* If either type is an unqualified 'id', we're done. */
1118 if ((!lproto
&& objc_is_object_id (ltyp
))
1119 || (!rproto
&& objc_is_object_id (rtyp
)))
1122 pointers_compatible
= (TYPE_MAIN_VARIANT (ltyp
) == TYPE_MAIN_VARIANT (rtyp
));
1124 /* If the underlying types are the same, and at most one of them has
1125 a protocol list, we do not need to issue any diagnostics. */
1126 if (pointers_compatible
&& (!lproto
|| !rproto
))
1129 /* If exactly one of the types is 'Class', issue a diagnostic; any
1130 exceptions of this rule have already been handled. */
1131 if (objc_is_class_id (ltyp
) ^ objc_is_class_id (rtyp
))
1132 pointers_compatible
= false;
1133 /* Otherwise, check for inheritance relations. */
1136 if (!pointers_compatible
)
1138 = (objc_is_object_id (ltyp
) || objc_is_object_id (rtyp
));
1140 if (!pointers_compatible
)
1141 pointers_compatible
= DERIVED_FROM_P (ltyp
, rtyp
);
1143 if (!pointers_compatible
&& argno
== -3)
1144 pointers_compatible
= DERIVED_FROM_P (rtyp
, ltyp
);
1147 /* If the pointers match modulo protocols, check for protocol conformance
1149 if (pointers_compatible
)
1151 pointers_compatible
= objc_compare_protocols (lcls
, ltyp
, rcls
, rtyp
,
1154 if (!pointers_compatible
&& argno
== -3)
1155 pointers_compatible
= objc_compare_protocols (rcls
, rtyp
, lcls
, ltyp
,
1159 if (!pointers_compatible
)
1161 /* NB: For the time being, we shall make our warnings look like their
1162 C counterparts. In the future, we may wish to make them more
1167 warning (0, "comparison of distinct Objective-C types lacks a cast");
1171 warning (0, "initialization from distinct Objective-C type");
1175 warning (0, "assignment from distinct Objective-C type");
1179 warning (0, "distinct Objective-C type in return");
1183 warning (0, "passing argument %d of %qE from distinct "
1184 "Objective-C type", argno
, callee
);
1192 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1193 lives in the volatilized hash table, ignore the 'volatile' bit when
1194 making the comparison. */
1197 objc_type_quals_match (tree ltyp
, tree rtyp
)
1199 int lquals
= TYPE_QUALS (ltyp
), rquals
= TYPE_QUALS (rtyp
);
1200 struct volatilized_type key
;
1204 if (htab_find_slot (volatilized_htab
, &key
, NO_INSERT
))
1205 lquals
&= ~TYPE_QUAL_VOLATILE
;
1209 if (htab_find_slot (volatilized_htab
, &key
, NO_INSERT
))
1210 rquals
&= ~TYPE_QUAL_VOLATILE
;
1212 return (lquals
== rquals
);
1216 /* Determine if CHILD is derived from PARENT. The routine assumes that
1217 both parameters are RECORD_TYPEs, and is non-reflexive. */
1220 objc_derived_from_p (tree parent
, tree child
)
1222 parent
= TYPE_MAIN_VARIANT (parent
);
1224 for (child
= TYPE_MAIN_VARIANT (child
);
1225 TYPE_BINFO (child
) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child
));)
1227 child
= TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1228 (TYPE_BINFO (child
),
1231 if (child
== parent
)
1240 objc_build_component_ref (tree datum
, tree component
)
1242 /* If COMPONENT is NULL, the caller is referring to the anonymous
1243 base class field. */
1246 tree base
= TYPE_FIELDS (TREE_TYPE (datum
));
1248 return build3 (COMPONENT_REF
, TREE_TYPE (base
), datum
, base
, NULL_TREE
);
1251 /* The 'build_component_ref' routine has been removed from the C++
1252 front-end, but 'finish_class_member_access_expr' seems to be
1253 a worthy substitute. */
1255 return finish_class_member_access_expr (datum
, component
, false,
1256 tf_warning_or_error
);
1258 return build_component_ref (datum
, component
);
1262 /* Recursively copy inheritance information rooted at BINFO. To do this,
1263 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1266 objc_copy_binfo (tree binfo
)
1268 tree btype
= BINFO_TYPE (binfo
);
1269 tree binfo2
= make_tree_binfo (BINFO_N_BASE_BINFOS (binfo
));
1273 BINFO_TYPE (binfo2
) = btype
;
1274 BINFO_OFFSET (binfo2
) = BINFO_OFFSET (binfo
);
1275 BINFO_BASE_ACCESSES (binfo2
) = BINFO_BASE_ACCESSES (binfo
);
1277 /* Recursively copy base binfos of BINFO. */
1278 for (ix
= 0; BINFO_BASE_ITERATE (binfo
, ix
, base_binfo
); ix
++)
1280 tree base_binfo2
= objc_copy_binfo (base_binfo
);
1282 BINFO_INHERITANCE_CHAIN (base_binfo2
) = binfo2
;
1283 BINFO_BASE_APPEND (binfo2
, base_binfo2
);
1289 /* Record superclass information provided in BASETYPE for ObjC class REF.
1290 This is loosely based on cp/decl.c:xref_basetypes(). */
1293 objc_xref_basetypes (tree ref
, tree basetype
)
1295 tree binfo
= make_tree_binfo (basetype
? 1 : 0);
1297 TYPE_BINFO (ref
) = binfo
;
1298 BINFO_OFFSET (binfo
) = size_zero_node
;
1299 BINFO_TYPE (binfo
) = ref
;
1303 tree base_binfo
= objc_copy_binfo (TYPE_BINFO (basetype
));
1305 BINFO_INHERITANCE_CHAIN (base_binfo
) = binfo
;
1306 BINFO_BASE_ACCESSES (binfo
) = VEC_alloc (tree
, gc
, 1);
1307 BINFO_BASE_APPEND (binfo
, base_binfo
);
1308 BINFO_BASE_ACCESS_APPEND (binfo
, access_public_node
);
1313 volatilized_hash (const void *ptr
)
1315 const_tree
const typ
= ((const struct volatilized_type
*)ptr
)->type
;
1317 return htab_hash_pointer(typ
);
1321 volatilized_eq (const void *ptr1
, const void *ptr2
)
1323 const_tree
const typ1
= ((const struct volatilized_type
*)ptr1
)->type
;
1324 const_tree
const typ2
= ((const struct volatilized_type
*)ptr2
)->type
;
1326 return typ1
== typ2
;
1329 /* Called from finish_decl. */
1332 objc_check_decl (tree decl
)
1334 tree type
= TREE_TYPE (decl
);
1336 if (TREE_CODE (type
) != RECORD_TYPE
)
1338 if (OBJC_TYPE_NAME (type
) && (type
= objc_is_class_name (OBJC_TYPE_NAME (type
))))
1339 error ("statically allocated instance of Objective-C class %qs",
1340 IDENTIFIER_POINTER (type
));
1343 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1344 either name an Objective-C class, or refer to the special 'id' or 'Class'
1345 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1348 objc_get_protocol_qualified_type (tree interface
, tree protocols
)
1350 /* If INTERFACE is not provided, default to 'id'. */
1351 tree type
= (interface
? objc_is_id (interface
) : objc_object_type
);
1352 bool is_ptr
= (type
!= NULL_TREE
);
1356 type
= objc_is_class_name (interface
);
1359 type
= xref_tag (RECORD_TYPE
, type
);
1366 type
= build_variant_type_copy (type
);
1368 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1372 tree orig_pointee_type
= TREE_TYPE (type
);
1373 TREE_TYPE (type
) = build_variant_type_copy (orig_pointee_type
);
1375 /* Set up the canonical type information. */
1376 TYPE_CANONICAL (type
)
1377 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type
));
1379 TYPE_POINTER_TO (TREE_TYPE (type
)) = type
;
1380 type
= TREE_TYPE (type
);
1383 /* Look up protocols and install in lang specific list. */
1384 DUP_TYPE_OBJC_INFO (type
, TYPE_MAIN_VARIANT (type
));
1385 TYPE_OBJC_PROTOCOL_LIST (type
) = lookup_and_install_protocols (protocols
);
1387 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1388 return the pointer to the new pointee variant. */
1390 type
= TYPE_POINTER_TO (type
);
1392 TYPE_OBJC_INTERFACE (type
)
1393 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type
));
1399 /* Check for circular dependencies in protocols. The arguments are
1400 PROTO, the protocol to check, and LIST, a list of protocol it
1404 check_protocol_recursively (tree proto
, tree list
)
1408 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1410 tree pp
= TREE_VALUE (p
);
1412 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1413 pp
= lookup_protocol (pp
);
1416 fatal_error ("protocol %qs has circular dependency",
1417 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1419 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1423 /* Look up PROTOCOLS, and return a list of those that are found.
1424 If none are found, return NULL. */
1427 lookup_and_install_protocols (tree protocols
)
1430 tree return_value
= NULL_TREE
;
1432 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1434 tree ident
= TREE_VALUE (proto
);
1435 tree p
= lookup_protocol (ident
);
1438 return_value
= chainon (return_value
,
1439 build_tree_list (NULL_TREE
, p
));
1440 else if (ident
!= error_mark_node
)
1441 error ("cannot find protocol declaration for %qs",
1442 IDENTIFIER_POINTER (ident
));
1445 return return_value
;
1448 /* Create a declaration for field NAME of a given TYPE. */
1451 create_field_decl (tree type
, const char *name
)
1453 return build_decl (FIELD_DECL
, get_identifier (name
), type
);
1456 /* Create a global, static declaration for variable NAME of a given TYPE. The
1457 finish_var_decl() routine will need to be called on it afterwards. */
1460 start_var_decl (tree type
, const char *name
)
1462 tree var
= build_decl (VAR_DECL
, get_identifier (name
), type
);
1464 TREE_STATIC (var
) = 1;
1465 DECL_INITIAL (var
) = error_mark_node
; /* A real initializer is coming... */
1466 DECL_IGNORED_P (var
) = 1;
1467 DECL_ARTIFICIAL (var
) = 1;
1468 DECL_CONTEXT (var
) = NULL_TREE
;
1470 DECL_THIS_STATIC (var
) = 1; /* squash redeclaration errors */
1476 /* Finish off the variable declaration created by start_var_decl(). */
1479 finish_var_decl (tree var
, tree initializer
)
1481 finish_decl (var
, initializer
, NULL_TREE
);
1482 /* Ensure that the variable actually gets output. */
1483 mark_decl_referenced (var
);
1484 /* Mark the decl to avoid "defined but not used" warning. */
1485 TREE_USED (var
) = 1;
1488 /* Find the decl for the constant string class reference. This is only
1489 used for the NeXT runtime. */
1492 setup_string_decl (void)
1497 /* %s in format will provide room for terminating null */
1498 length
= strlen (STRING_OBJECT_GLOBAL_FORMAT
)
1499 + strlen (constant_string_class_name
);
1500 name
= XNEWVEC (char, length
);
1501 sprintf (name
, STRING_OBJECT_GLOBAL_FORMAT
,
1502 constant_string_class_name
);
1503 constant_string_global_id
= get_identifier (name
);
1504 string_class_decl
= lookup_name (constant_string_global_id
);
1506 return string_class_decl
;
1509 /* Purpose: "play" parser, creating/installing representations
1510 of the declarations that are required by Objective-C.
1514 type_spec--------->sc_spec
1515 (tree_list) (tree_list)
1518 identifier_node identifier_node */
1521 synth_module_prologue (void)
1524 enum debug_info_type save_write_symbols
= write_symbols
;
1525 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
1527 /* Suppress outputting debug symbols, because
1528 dbxout_init hasn't been called yet. */
1529 write_symbols
= NO_DEBUG
;
1530 debug_hooks
= &do_nothing_debug_hooks
;
1533 push_lang_context (lang_name_c
); /* extern "C" */
1536 /* The following are also defined in <objc/objc.h> and friends. */
1538 objc_object_id
= get_identifier (TAG_OBJECT
);
1539 objc_class_id
= get_identifier (TAG_CLASS
);
1541 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1542 objc_class_reference
= xref_tag (RECORD_TYPE
, objc_class_id
);
1544 objc_object_type
= build_pointer_type (objc_object_reference
);
1545 objc_class_type
= build_pointer_type (objc_class_reference
);
1547 objc_object_name
= get_identifier (OBJECT_TYPEDEF_NAME
);
1548 objc_class_name
= get_identifier (CLASS_TYPEDEF_NAME
);
1550 /* Declare the 'id' and 'Class' typedefs. */
1552 type
= lang_hooks
.decls
.pushdecl (build_decl (TYPE_DECL
,
1555 TREE_NO_WARNING (type
) = 1;
1556 type
= lang_hooks
.decls
.pushdecl (build_decl (TYPE_DECL
,
1559 TREE_NO_WARNING (type
) = 1;
1561 /* Forward-declare '@interface Protocol'. */
1563 type
= get_identifier (PROTOCOL_OBJECT_CLASS_NAME
);
1564 objc_declare_class (tree_cons (NULL_TREE
, type
, NULL_TREE
));
1565 objc_protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1568 /* Declare type of selector-objects that represent an operation name. */
1570 if (flag_next_runtime
)
1571 /* `struct objc_selector *' */
1573 = build_pointer_type (xref_tag (RECORD_TYPE
,
1574 get_identifier (TAG_SELECTOR
)));
1576 /* `const struct objc_selector *' */
1578 = build_pointer_type
1579 (build_qualified_type (xref_tag (RECORD_TYPE
,
1580 get_identifier (TAG_SELECTOR
)),
1583 /* Declare receiver type used for dispatching messages to 'super'. */
1585 /* `struct objc_super *' */
1586 objc_super_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1587 get_identifier (TAG_SUPER
)));
1589 /* Declare pointers to method and ivar lists. */
1590 objc_method_list_ptr
= build_pointer_type
1591 (xref_tag (RECORD_TYPE
,
1592 get_identifier (UTAG_METHOD_LIST
)));
1593 objc_method_proto_list_ptr
1594 = build_pointer_type (xref_tag (RECORD_TYPE
,
1595 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
1596 objc_ivar_list_ptr
= build_pointer_type
1597 (xref_tag (RECORD_TYPE
,
1598 get_identifier (UTAG_IVAR_LIST
)));
1600 /* TREE_NOTHROW is cleared for the message-sending functions,
1601 because the function that gets called can throw in Obj-C++, or
1602 could itself call something that can throw even in Obj-C. */
1604 if (flag_next_runtime
)
1606 /* NB: In order to call one of the ..._stret (struct-returning)
1607 functions, the function *MUST* first be cast to a signature that
1608 corresponds to the actual ObjC method being invoked. This is
1609 what is done by the build_objc_method_call() routine below. */
1611 /* id objc_msgSend (id, SEL, ...); */
1612 /* id objc_msgSendNonNil (id, SEL, ...); */
1613 /* id objc_msgSend_stret (id, SEL, ...); */
1614 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1616 = build_function_type (objc_object_type
,
1617 tree_cons (NULL_TREE
, objc_object_type
,
1618 tree_cons (NULL_TREE
, objc_selector_type
,
1620 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
1621 type
, 0, NOT_BUILT_IN
,
1623 umsg_nonnil_decl
= add_builtin_function (TAG_MSGSEND_NONNIL
,
1624 type
, 0, NOT_BUILT_IN
,
1626 umsg_stret_decl
= add_builtin_function (TAG_MSGSEND_STRET
,
1627 type
, 0, NOT_BUILT_IN
,
1629 umsg_nonnil_stret_decl
= add_builtin_function (TAG_MSGSEND_NONNIL_STRET
,
1630 type
, 0, NOT_BUILT_IN
,
1633 /* These can throw, because the function that gets called can throw
1634 in Obj-C++, or could itself call something that can throw even
1636 TREE_NOTHROW (umsg_decl
) = 0;
1637 TREE_NOTHROW (umsg_nonnil_decl
) = 0;
1638 TREE_NOTHROW (umsg_stret_decl
) = 0;
1639 TREE_NOTHROW (umsg_nonnil_stret_decl
) = 0;
1641 /* id objc_msgSend_Fast (id, SEL, ...)
1642 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1643 #ifdef OFFS_MSGSEND_FAST
1644 umsg_fast_decl
= add_builtin_function (TAG_MSGSEND_FAST
,
1645 type
, 0, NOT_BUILT_IN
,
1647 TREE_NOTHROW (umsg_fast_decl
) = 0;
1648 DECL_ATTRIBUTES (umsg_fast_decl
)
1649 = tree_cons (get_identifier ("hard_coded_address"),
1650 build_int_cst (NULL_TREE
, OFFS_MSGSEND_FAST
),
1653 /* No direct dispatch available. */
1654 umsg_fast_decl
= umsg_decl
;
1657 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1658 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1660 = build_function_type (objc_object_type
,
1661 tree_cons (NULL_TREE
, objc_super_type
,
1662 tree_cons (NULL_TREE
, objc_selector_type
,
1664 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
1665 type
, 0, NOT_BUILT_IN
,
1667 umsg_super_stret_decl
= add_builtin_function (TAG_MSGSENDSUPER_STRET
,
1668 type
, 0, NOT_BUILT_IN
, 0,
1670 TREE_NOTHROW (umsg_super_decl
) = 0;
1671 TREE_NOTHROW (umsg_super_stret_decl
) = 0;
1675 /* GNU runtime messenger entry points. */
1677 /* typedef id (*IMP)(id, SEL, ...); */
1679 = build_pointer_type
1680 (build_function_type (objc_object_type
,
1681 tree_cons (NULL_TREE
, objc_object_type
,
1682 tree_cons (NULL_TREE
, objc_selector_type
,
1685 /* IMP objc_msg_lookup (id, SEL); */
1687 = build_function_type (IMP_type
,
1688 tree_cons (NULL_TREE
, objc_object_type
,
1689 tree_cons (NULL_TREE
, objc_selector_type
,
1690 OBJC_VOID_AT_END
)));
1691 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
1692 type
, 0, NOT_BUILT_IN
,
1694 TREE_NOTHROW (umsg_decl
) = 0;
1696 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1698 = build_function_type (IMP_type
,
1699 tree_cons (NULL_TREE
, objc_super_type
,
1700 tree_cons (NULL_TREE
, objc_selector_type
,
1701 OBJC_VOID_AT_END
)));
1702 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
1703 type
, 0, NOT_BUILT_IN
,
1705 TREE_NOTHROW (umsg_super_decl
) = 0;
1707 /* The following GNU runtime entry point is called to initialize
1710 __objc_exec_class (void *); */
1712 = build_function_type (void_type_node
,
1713 tree_cons (NULL_TREE
, ptr_type_node
,
1715 execclass_decl
= add_builtin_function (TAG_EXECCLASS
,
1716 type
, 0, NOT_BUILT_IN
,
1720 /* id objc_getClass (const char *); */
1722 type
= build_function_type (objc_object_type
,
1723 tree_cons (NULL_TREE
,
1724 const_string_type_node
,
1728 = add_builtin_function (TAG_GETCLASS
, type
, 0, NOT_BUILT_IN
,
1731 /* id objc_getMetaClass (const char *); */
1733 objc_get_meta_class_decl
1734 = add_builtin_function (TAG_GETMETACLASS
, type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
1736 build_class_template ();
1737 build_super_template ();
1738 build_protocol_template ();
1739 build_category_template ();
1740 build_objc_exception_stuff ();
1742 if (flag_next_runtime
)
1743 build_next_objc_exception_stuff ();
1745 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1747 if (! flag_next_runtime
)
1748 build_selector_table_decl ();
1750 /* Forward declare constant_string_id and constant_string_type. */
1751 if (!constant_string_class_name
)
1752 constant_string_class_name
= default_constant_string_class_name
;
1754 constant_string_id
= get_identifier (constant_string_class_name
);
1755 objc_declare_class (tree_cons (NULL_TREE
, constant_string_id
, NULL_TREE
));
1757 /* Pre-build the following entities - for speed/convenience. */
1758 self_id
= get_identifier ("self");
1759 ucmd_id
= get_identifier ("_cmd");
1762 pop_lang_context ();
1765 write_symbols
= save_write_symbols
;
1766 debug_hooks
= save_hooks
;
1769 /* Ensure that the ivar list for NSConstantString/NXConstantString
1770 (or whatever was specified via `-fconstant-string-class')
1771 contains fields at least as large as the following three, so that
1772 the runtime can stomp on them with confidence:
1774 struct STRING_OBJECT_CLASS_NAME
1778 unsigned int length;
1782 check_string_class_template (void)
1784 tree field_decl
= objc_get_class_ivars (constant_string_id
);
1786 #define AT_LEAST_AS_LARGE_AS(F, T) \
1787 (F && TREE_CODE (F) == FIELD_DECL \
1788 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1789 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1791 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
1794 field_decl
= TREE_CHAIN (field_decl
);
1795 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
1798 field_decl
= TREE_CHAIN (field_decl
);
1799 return AT_LEAST_AS_LARGE_AS (field_decl
, unsigned_type_node
);
1801 #undef AT_LEAST_AS_LARGE_AS
1804 /* Avoid calling `check_string_class_template ()' more than once. */
1805 static GTY(()) int string_layout_checked
;
1807 /* Construct an internal string layout to be used as a template for
1808 creating NSConstantString/NXConstantString instances. */
1811 objc_build_internal_const_str_type (void)
1813 tree type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
1814 tree fields
= build_decl (FIELD_DECL
, NULL_TREE
, ptr_type_node
);
1815 tree field
= build_decl (FIELD_DECL
, NULL_TREE
, ptr_type_node
);
1817 TREE_CHAIN (field
) = fields
; fields
= field
;
1818 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
1819 TREE_CHAIN (field
) = fields
; fields
= field
;
1820 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1822 finish_builtin_struct (type
, "__builtin_ObjCString",
1828 /* Custom build_string which sets TREE_TYPE! */
1831 my_build_string (int len
, const char *str
)
1833 return fix_string_type (build_string (len
, str
));
1836 /* Build a string with contents STR and length LEN and convert it to a
1840 my_build_string_pointer (int len
, const char *str
)
1842 tree string
= my_build_string (len
, str
);
1843 tree ptrtype
= build_pointer_type (TREE_TYPE (TREE_TYPE (string
)));
1844 return build1 (ADDR_EXPR
, ptrtype
, string
);
1848 string_hash (const void *ptr
)
1850 const_tree
const str
= ((const struct string_descriptor
*)ptr
)->literal
;
1851 const unsigned char *p
= (const unsigned char *) TREE_STRING_POINTER (str
);
1852 int i
, len
= TREE_STRING_LENGTH (str
);
1855 for (i
= 0; i
< len
; i
++)
1856 h
= ((h
* 613) + p
[i
]);
1862 string_eq (const void *ptr1
, const void *ptr2
)
1864 const_tree
const str1
= ((const struct string_descriptor
*)ptr1
)->literal
;
1865 const_tree
const str2
= ((const struct string_descriptor
*)ptr2
)->literal
;
1866 int len1
= TREE_STRING_LENGTH (str1
);
1868 return (len1
== TREE_STRING_LENGTH (str2
)
1869 && !memcmp (TREE_STRING_POINTER (str1
), TREE_STRING_POINTER (str2
),
1873 /* Given a chain of STRING_CST's, build a static instance of
1874 NXConstantString which points at the concatenation of those
1875 strings. We place the string object in the __string_objects
1876 section of the __OBJC segment. The Objective-C runtime will
1877 initialize the isa pointers of the string objects to point at the
1878 NXConstantString class object. */
1881 objc_build_string_object (tree string
)
1883 tree initlist
, constructor
, constant_string_class
;
1886 struct string_descriptor
*desc
, key
;
1889 /* Prep the string argument. */
1890 string
= fix_string_type (string
);
1891 TREE_SET_CODE (string
, STRING_CST
);
1892 length
= TREE_STRING_LENGTH (string
) - 1;
1894 /* Check whether the string class being used actually exists and has the
1895 correct ivar layout. */
1896 if (!string_layout_checked
)
1898 string_layout_checked
= -1;
1899 constant_string_class
= lookup_interface (constant_string_id
);
1900 internal_const_str_type
= objc_build_internal_const_str_type ();
1902 if (!constant_string_class
1903 || !(constant_string_type
1904 = CLASS_STATIC_TEMPLATE (constant_string_class
)))
1905 error ("cannot find interface declaration for %qs",
1906 IDENTIFIER_POINTER (constant_string_id
));
1907 /* The NSConstantString/NXConstantString ivar layout is now known. */
1908 else if (!check_string_class_template ())
1909 error ("interface %qs does not have valid constant string layout",
1910 IDENTIFIER_POINTER (constant_string_id
));
1911 /* For the NeXT runtime, we can generate a literal reference
1912 to the string class, don't need to run a constructor. */
1913 else if (flag_next_runtime
&& !setup_string_decl ())
1914 error ("cannot find reference tag for class %qs",
1915 IDENTIFIER_POINTER (constant_string_id
));
1918 string_layout_checked
= 1; /* Success! */
1919 add_class_reference (constant_string_id
);
1923 if (string_layout_checked
== -1)
1924 return error_mark_node
;
1926 /* Perhaps we already constructed a constant string just like this one? */
1927 key
.literal
= string
;
1928 loc
= htab_find_slot (string_htab
, &key
, INSERT
);
1929 desc
= (struct string_descriptor
*) *loc
;
1934 *loc
= desc
= GGC_NEW (struct string_descriptor
);
1935 desc
->literal
= string
;
1937 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1938 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1939 fields
= TYPE_FIELDS (internal_const_str_type
);
1941 = build_tree_list (fields
,
1943 ? build_unary_op (input_location
,
1944 ADDR_EXPR
, string_class_decl
, 0)
1945 : build_int_cst (NULL_TREE
, 0));
1946 fields
= TREE_CHAIN (fields
);
1947 initlist
= tree_cons (fields
, build_unary_op (input_location
,
1948 ADDR_EXPR
, string
, 1),
1950 fields
= TREE_CHAIN (fields
);
1951 initlist
= tree_cons (fields
, build_int_cst (NULL_TREE
, length
),
1953 constructor
= objc_build_constructor (internal_const_str_type
,
1954 nreverse (initlist
));
1956 if (!flag_next_runtime
)
1958 = objc_add_static_instance (constructor
, constant_string_type
);
1961 var
= build_decl (CONST_DECL
, NULL
, TREE_TYPE (constructor
));
1962 DECL_INITIAL (var
) = constructor
;
1963 TREE_STATIC (var
) = 1;
1964 pushdecl_top_level (var
);
1967 desc
->constructor
= constructor
;
1970 addr
= convert (build_pointer_type (constant_string_type
),
1971 build_unary_op (input_location
,
1972 ADDR_EXPR
, desc
->constructor
, 1));
1977 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1979 static GTY(()) int num_static_inst
;
1982 objc_add_static_instance (tree constructor
, tree class_decl
)
1987 /* Find the list of static instances for the CLASS_DECL. Create one if
1989 for (chain
= &objc_static_instances
;
1990 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1991 chain
= &TREE_CHAIN (*chain
));
1994 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1995 add_objc_string (OBJC_TYPE_NAME (class_decl
), class_names
);
1998 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1999 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
2000 DECL_COMMON (decl
) = 1;
2001 TREE_STATIC (decl
) = 1;
2002 DECL_ARTIFICIAL (decl
) = 1;
2003 TREE_USED (decl
) = 1;
2004 DECL_INITIAL (decl
) = constructor
;
2006 /* We may be writing something else just now.
2007 Postpone till end of input. */
2008 DECL_DEFER_OUTPUT (decl
) = 1;
2009 pushdecl_top_level (decl
);
2010 rest_of_decl_compilation (decl
, 1, 0);
2012 /* Add the DECL to the head of this CLASS' list. */
2013 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
2018 /* Build a static constant CONSTRUCTOR
2019 with type TYPE and elements ELTS. */
2022 objc_build_constructor (tree type
, tree elts
)
2024 tree constructor
= build_constructor_from_list (type
, elts
);
2026 TREE_CONSTANT (constructor
) = 1;
2027 TREE_STATIC (constructor
) = 1;
2028 TREE_READONLY (constructor
) = 1;
2031 /* Adjust for impedance mismatch. We should figure out how to build
2032 CONSTRUCTORs that consistently please both the C and C++ gods. */
2033 if (!TREE_PURPOSE (elts
))
2034 TREE_TYPE (constructor
) = init_list_type_node
;
2040 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2042 /* Predefine the following data type:
2050 void *defs[cls_def_cnt + cat_def_cnt];
2054 build_objc_symtab_template (void)
2056 tree field_decl
, field_decl_chain
;
2058 objc_symtab_template
2059 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
2061 /* long sel_ref_cnt; */
2062 field_decl
= create_field_decl (long_integer_type_node
, "sel_ref_cnt");
2063 field_decl_chain
= field_decl
;
2066 field_decl
= create_field_decl (build_pointer_type (objc_selector_type
),
2068 chainon (field_decl_chain
, field_decl
);
2070 /* short cls_def_cnt; */
2071 field_decl
= create_field_decl (short_integer_type_node
, "cls_def_cnt");
2072 chainon (field_decl_chain
, field_decl
);
2074 /* short cat_def_cnt; */
2075 field_decl
= create_field_decl (short_integer_type_node
,
2077 chainon (field_decl_chain
, field_decl
);
2079 if (imp_count
|| cat_count
|| !flag_next_runtime
)
2081 /* void *defs[imp_count + cat_count (+ 1)]; */
2082 /* NB: The index is one less than the size of the array. */
2083 int index
= imp_count
+ cat_count
2084 + (flag_next_runtime
? -1: 0);
2085 field_decl
= create_field_decl
2088 build_index_type (build_int_cst (NULL_TREE
, index
))),
2090 chainon (field_decl_chain
, field_decl
);
2093 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
2096 /* Create the initial value for the `defs' field of _objc_symtab.
2097 This is a CONSTRUCTOR. */
2100 init_def_list (tree type
)
2102 tree expr
, initlist
= NULL_TREE
;
2103 struct imp_entry
*impent
;
2106 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2108 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
2110 expr
= build_unary_op (input_location
,
2111 ADDR_EXPR
, impent
->class_decl
, 0);
2112 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2117 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2119 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
2121 expr
= build_unary_op (input_location
,
2122 ADDR_EXPR
, impent
->class_decl
, 0);
2123 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2127 if (!flag_next_runtime
)
2129 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2132 if (static_instances_decl
)
2133 expr
= build_unary_op (input_location
,
2134 ADDR_EXPR
, static_instances_decl
, 0);
2136 expr
= build_int_cst (NULL_TREE
, 0);
2138 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2141 return objc_build_constructor (type
, nreverse (initlist
));
2144 /* Construct the initial value for all of _objc_symtab. */
2147 init_objc_symtab (tree type
)
2151 /* sel_ref_cnt = { ..., 5, ... } */
2153 initlist
= build_tree_list (NULL_TREE
,
2154 build_int_cst (long_integer_type_node
, 0));
2156 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2158 if (flag_next_runtime
|| ! sel_ref_chain
)
2159 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
2162 = tree_cons (NULL_TREE
,
2163 convert (build_pointer_type (objc_selector_type
),
2164 build_unary_op (input_location
, ADDR_EXPR
,
2165 UOBJC_SELECTOR_TABLE_decl
, 1)),
2168 /* cls_def_cnt = { ..., 5, ... } */
2170 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, imp_count
), initlist
);
2172 /* cat_def_cnt = { ..., 5, ... } */
2174 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, cat_count
), initlist
);
2176 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2178 if (imp_count
|| cat_count
|| !flag_next_runtime
)
2181 tree field
= TYPE_FIELDS (type
);
2182 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
2184 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
2188 return objc_build_constructor (type
, nreverse (initlist
));
2191 /* Generate forward declarations for metadata such as
2192 'OBJC_CLASS_...'. */
2195 build_metadata_decl (const char *name
, tree type
)
2199 /* struct TYPE NAME_<name>; */
2200 decl
= start_var_decl (type
, synth_id_with_class_suffix
2202 objc_implementation_context
));
2207 /* Push forward-declarations of all the categories so that
2208 init_def_list can use them in a CONSTRUCTOR. */
2211 forward_declare_categories (void)
2213 struct imp_entry
*impent
;
2214 tree sav
= objc_implementation_context
;
2216 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2218 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
2220 /* Set an invisible arg to synth_id_with_class_suffix. */
2221 objc_implementation_context
= impent
->imp_context
;
2222 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2223 impent
->class_decl
= build_metadata_decl ("_OBJC_CATEGORY",
2224 objc_category_template
);
2227 objc_implementation_context
= sav
;
2230 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2231 and initialized appropriately. */
2234 generate_objc_symtab_decl (void)
2236 /* forward declare categories */
2238 forward_declare_categories ();
2240 build_objc_symtab_template ();
2241 UOBJC_SYMBOLS_decl
= start_var_decl (objc_symtab_template
, "_OBJC_SYMBOLS");
2242 finish_var_decl (UOBJC_SYMBOLS_decl
,
2243 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)));
2247 init_module_descriptor (tree type
)
2249 tree initlist
, expr
;
2251 /* version = { 1, ... } */
2253 expr
= build_int_cst (long_integer_type_node
, OBJC_VERSION
);
2254 initlist
= build_tree_list (NULL_TREE
, expr
);
2256 /* size = { ..., sizeof (struct _objc_module), ... } */
2258 expr
= convert (long_integer_type_node
,
2259 size_in_bytes (objc_module_template
));
2260 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2262 /* Don't provide any file name for security reasons. */
2263 /* name = { ..., "", ... } */
2265 expr
= add_objc_string (get_identifier (""), class_names
);
2266 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2268 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2270 if (UOBJC_SYMBOLS_decl
)
2271 expr
= build_unary_op (input_location
,
2272 ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
2274 expr
= build_int_cst (NULL_TREE
, 0);
2275 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2277 return objc_build_constructor (type
, nreverse (initlist
));
2280 /* Write out the data structures to describe Objective C classes defined.
2282 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2285 build_module_descriptor (void)
2287 tree field_decl
, field_decl_chain
;
2290 push_lang_context (lang_name_c
); /* extern "C" */
2293 objc_module_template
2294 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
2297 field_decl
= create_field_decl (long_integer_type_node
, "version");
2298 field_decl_chain
= field_decl
;
2301 field_decl
= create_field_decl (long_integer_type_node
, "size");
2302 chainon (field_decl_chain
, field_decl
);
2305 field_decl
= create_field_decl (string_type_node
, "name");
2306 chainon (field_decl_chain
, field_decl
);
2308 /* struct _objc_symtab *symtab; */
2310 = create_field_decl (build_pointer_type
2311 (xref_tag (RECORD_TYPE
,
2312 get_identifier (UTAG_SYMTAB
))),
2314 chainon (field_decl_chain
, field_decl
);
2316 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
2318 /* Create an instance of "_objc_module". */
2319 UOBJC_MODULES_decl
= start_var_decl (objc_module_template
, "_OBJC_MODULES");
2320 finish_var_decl (UOBJC_MODULES_decl
,
2321 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)));
2324 pop_lang_context ();
2328 /* The GNU runtime requires us to provide a static initializer function
2331 static void __objc_gnu_init (void) {
2332 __objc_exec_class (&L_OBJC_MODULES);
2336 build_module_initializer_routine (void)
2341 push_lang_context (lang_name_c
); /* extern "C" */
2344 objc_push_parm (build_decl (PARM_DECL
, NULL_TREE
, void_type_node
));
2345 objc_start_function (get_identifier (TAG_GNUINIT
),
2346 build_function_type (void_type_node
,
2348 NULL_TREE
, objc_get_parm_info (0));
2350 body
= c_begin_compound_stmt (true);
2351 add_stmt (build_function_call
2355 build_unary_op (input_location
, ADDR_EXPR
,
2356 UOBJC_MODULES_decl
, 0))));
2357 add_stmt (c_end_compound_stmt (body
, true));
2359 TREE_PUBLIC (current_function_decl
) = 0;
2362 /* For Objective-C++, we will need to call __objc_gnu_init
2363 from objc_generate_static_init_call() below. */
2364 DECL_STATIC_CONSTRUCTOR (current_function_decl
) = 1;
2367 GNU_INIT_decl
= current_function_decl
;
2371 pop_lang_context ();
2376 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2377 to be called by the module initializer routine. */
2380 objc_static_init_needed_p (void)
2382 return (GNU_INIT_decl
!= NULL_TREE
);
2385 /* Generate a call to the __objc_gnu_init initializer function. */
2388 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED
)
2390 add_stmt (build_stmt (EXPR_STMT
,
2391 build_function_call (GNU_INIT_decl
, NULL_TREE
)));
2395 #endif /* OBJCPLUS */
2397 /* Return the DECL of the string IDENT in the SECTION. */
2400 get_objc_string_decl (tree ident
, enum string_section section
)
2404 if (section
== class_names
)
2405 chain
= class_names_chain
;
2406 else if (section
== meth_var_names
)
2407 chain
= meth_var_names_chain
;
2408 else if (section
== meth_var_types
)
2409 chain
= meth_var_types_chain
;
2413 for (; chain
!= 0; chain
= TREE_CHAIN (chain
))
2414 if (TREE_VALUE (chain
) == ident
)
2415 return (TREE_PURPOSE (chain
));
2421 /* Output references to all statically allocated objects. Return the DECL
2422 for the array built. */
2425 generate_static_references (void)
2427 tree decls
= NULL_TREE
, expr
= NULL_TREE
;
2428 tree class_name
, klass
, decl
, initlist
;
2429 tree cl_chain
, in_chain
, type
2430 = build_array_type (build_pointer_type (void_type_node
), NULL_TREE
);
2431 int num_inst
, num_class
;
2434 if (flag_next_runtime
)
2437 for (cl_chain
= objc_static_instances
, num_class
= 0;
2438 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
2440 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
2441 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
2443 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
2444 decl
= start_var_decl (type
, buf
);
2446 /* Output {class_name, ...}. */
2447 klass
= TREE_VALUE (cl_chain
);
2448 class_name
= get_objc_string_decl (OBJC_TYPE_NAME (klass
), class_names
);
2449 initlist
= build_tree_list (NULL_TREE
,
2450 build_unary_op (input_location
,
2451 ADDR_EXPR
, class_name
, 1));
2453 /* Output {..., instance, ...}. */
2454 for (in_chain
= TREE_PURPOSE (cl_chain
);
2455 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
2457 expr
= build_unary_op (input_location
,
2458 ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
2459 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2462 /* Output {..., NULL}. */
2463 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
2465 expr
= objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
2466 finish_var_decl (decl
, expr
);
2468 = tree_cons (NULL_TREE
, build_unary_op (input_location
,
2469 ADDR_EXPR
, decl
, 1), decls
);
2472 decls
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), decls
);
2473 expr
= objc_build_constructor (type
, nreverse (decls
));
2474 static_instances_decl
= start_var_decl (type
, "_OBJC_STATIC_INSTANCES");
2475 finish_var_decl (static_instances_decl
, expr
);
2478 static GTY(()) int selector_reference_idx
;
2481 build_selector_reference_decl (void)
2486 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx
++);
2487 decl
= start_var_decl (objc_selector_type
, buf
);
2493 build_selector_table_decl (void)
2497 if (flag_typed_selectors
)
2499 build_selector_template ();
2500 temp
= build_array_type (objc_selector_template
, NULL_TREE
);
2503 temp
= build_array_type (objc_selector_type
, NULL_TREE
);
2505 UOBJC_SELECTOR_TABLE_decl
= start_var_decl (temp
, "_OBJC_SELECTOR_TABLE");
2508 /* Just a handy wrapper for add_objc_string. */
2511 build_selector (tree ident
)
2513 return convert (objc_selector_type
,
2514 add_objc_string (ident
, meth_var_names
));
2518 build_selector_translation_table (void)
2520 tree chain
, initlist
= NULL_TREE
;
2522 tree decl
= NULL_TREE
;
2524 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2528 if (warn_selector
&& objc_implementation_context
)
2532 for (method_chain
= meth_var_names_chain
;
2534 method_chain
= TREE_CHAIN (method_chain
))
2536 if (TREE_VALUE (method_chain
) == TREE_VALUE (chain
))
2545 if (flag_next_runtime
&& TREE_PURPOSE (chain
))
2546 loc
= &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain
));
2548 loc
= &input_location
;
2549 warning (0, "%Hcreating selector for nonexistent method %qE",
2550 loc
, TREE_VALUE (chain
));
2554 expr
= build_selector (TREE_VALUE (chain
));
2555 /* add one for the '\0' character */
2556 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2558 if (flag_next_runtime
)
2560 decl
= TREE_PURPOSE (chain
);
2561 finish_var_decl (decl
, expr
);
2565 if (flag_typed_selectors
)
2567 tree eltlist
= NULL_TREE
;
2568 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2569 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2570 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2571 expr
= objc_build_constructor (objc_selector_template
,
2572 nreverse (eltlist
));
2575 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2579 if (! flag_next_runtime
)
2581 /* Cause the selector table (previously forward-declared)
2582 to be actually output. */
2583 initlist
= tree_cons (NULL_TREE
,
2584 flag_typed_selectors
2585 ? objc_build_constructor
2586 (objc_selector_template
,
2587 tree_cons (NULL_TREE
,
2588 build_int_cst (NULL_TREE
, 0),
2589 tree_cons (NULL_TREE
,
2590 build_int_cst (NULL_TREE
, 0),
2592 : build_int_cst (NULL_TREE
, 0), initlist
);
2593 initlist
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2594 nreverse (initlist
));
2595 finish_var_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
);
2600 get_proto_encoding (tree proto
)
2605 if (! METHOD_ENCODING (proto
))
2607 encoding
= encode_method_prototype (proto
);
2608 METHOD_ENCODING (proto
) = encoding
;
2611 encoding
= METHOD_ENCODING (proto
);
2613 return add_objc_string (encoding
, meth_var_types
);
2616 return build_int_cst (NULL_TREE
, 0);
2619 /* sel_ref_chain is a list whose "value" fields will be instances of
2620 identifier_node that represent the selector. */
2623 build_typed_selector_reference (tree ident
, tree prototype
)
2625 tree
*chain
= &sel_ref_chain
;
2631 if (TREE_PURPOSE (*chain
) == prototype
&& TREE_VALUE (*chain
) == ident
)
2632 goto return_at_index
;
2635 chain
= &TREE_CHAIN (*chain
);
2638 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
2641 expr
= build_unary_op (input_location
, ADDR_EXPR
,
2642 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2643 build_int_cst (NULL_TREE
, index
),
2646 return convert (objc_selector_type
, expr
);
2650 build_selector_reference (tree ident
)
2652 tree
*chain
= &sel_ref_chain
;
2658 if (TREE_VALUE (*chain
) == ident
)
2659 return (flag_next_runtime
2660 ? TREE_PURPOSE (*chain
)
2661 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2662 build_int_cst (NULL_TREE
, index
),
2666 chain
= &TREE_CHAIN (*chain
);
2669 expr
= (flag_next_runtime
? build_selector_reference_decl (): NULL_TREE
);
2671 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2673 return (flag_next_runtime
2675 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2676 build_int_cst (NULL_TREE
, index
),
2680 static GTY(()) int class_reference_idx
;
2683 build_class_reference_decl (void)
2688 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx
++);
2689 decl
= start_var_decl (objc_class_type
, buf
);
2694 /* Create a class reference, but don't create a variable to reference
2698 add_class_reference (tree ident
)
2702 if ((chain
= cls_ref_chain
))
2707 if (ident
== TREE_VALUE (chain
))
2711 chain
= TREE_CHAIN (chain
);
2715 /* Append to the end of the list */
2716 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2719 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2722 /* Get a class reference, creating it if necessary. Also create the
2723 reference variable. */
2726 objc_get_class_reference (tree ident
)
2728 tree orig_ident
= (DECL_P (ident
)
2731 ? OBJC_TYPE_NAME (ident
)
2733 bool local_scope
= false;
2736 if (processing_template_decl
)
2737 /* Must wait until template instantiation time. */
2738 return build_min_nt (CLASS_REFERENCE_EXPR
, ident
);
2741 if (TREE_CODE (ident
) == TYPE_DECL
)
2742 ident
= (DECL_ORIGINAL_TYPE (ident
)
2743 ? DECL_ORIGINAL_TYPE (ident
)
2744 : TREE_TYPE (ident
));
2747 if (TYPE_P (ident
) && TYPE_CONTEXT (ident
)
2748 && TYPE_CONTEXT (ident
) != global_namespace
)
2752 if (local_scope
|| !(ident
= objc_is_class_name (ident
)))
2754 error ("%qs is not an Objective-C class name or alias",
2755 IDENTIFIER_POINTER (orig_ident
));
2756 return error_mark_node
;
2759 if (flag_next_runtime
&& !flag_zero_link
)
2764 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2765 if (TREE_VALUE (*chain
) == ident
)
2767 if (! TREE_PURPOSE (*chain
))
2768 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2770 return TREE_PURPOSE (*chain
);
2773 decl
= build_class_reference_decl ();
2774 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2781 add_class_reference (ident
);
2783 params
= build_tree_list (NULL_TREE
,
2784 my_build_string_pointer
2785 (IDENTIFIER_LENGTH (ident
) + 1,
2786 IDENTIFIER_POINTER (ident
)));
2788 assemble_external (objc_get_class_decl
);
2789 return build_function_call (objc_get_class_decl
, params
);
2793 /* For each string section we have a chain which maps identifier nodes
2794 to decls for the strings. */
2797 add_objc_string (tree ident
, enum string_section section
)
2799 tree
*chain
, decl
, type
, string_expr
;
2801 if (section
== class_names
)
2802 chain
= &class_names_chain
;
2803 else if (section
== meth_var_names
)
2804 chain
= &meth_var_names_chain
;
2805 else if (section
== meth_var_types
)
2806 chain
= &meth_var_types_chain
;
2812 if (TREE_VALUE (*chain
) == ident
)
2813 return convert (string_type_node
,
2814 build_unary_op (input_location
,
2815 ADDR_EXPR
, TREE_PURPOSE (*chain
), 1));
2817 chain
= &TREE_CHAIN (*chain
);
2820 decl
= build_objc_string_decl (section
);
2822 type
= build_array_type
2825 (build_int_cst (NULL_TREE
,
2826 IDENTIFIER_LENGTH (ident
))));
2827 decl
= start_var_decl (type
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
2828 string_expr
= my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2829 IDENTIFIER_POINTER (ident
));
2830 finish_var_decl (decl
, string_expr
);
2832 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2834 return convert (string_type_node
, build_unary_op (input_location
,
2835 ADDR_EXPR
, decl
, 1));
2838 static GTY(()) int class_names_idx
;
2839 static GTY(()) int meth_var_names_idx
;
2840 static GTY(()) int meth_var_types_idx
;
2843 build_objc_string_decl (enum string_section section
)
2848 if (section
== class_names
)
2849 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2850 else if (section
== meth_var_names
)
2851 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2852 else if (section
== meth_var_types
)
2853 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2855 ident
= get_identifier (buf
);
2857 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2858 DECL_EXTERNAL (decl
) = 1;
2859 TREE_PUBLIC (decl
) = 0;
2860 TREE_USED (decl
) = 1;
2861 TREE_CONSTANT (decl
) = 1;
2862 DECL_CONTEXT (decl
) = 0;
2863 DECL_ARTIFICIAL (decl
) = 1;
2865 DECL_THIS_STATIC (decl
) = 1; /* squash redeclaration errors */
2868 make_decl_rtl (decl
);
2869 pushdecl_top_level (decl
);
2876 objc_declare_alias (tree alias_ident
, tree class_ident
)
2878 tree underlying_class
;
2881 if (current_namespace
!= global_namespace
) {
2882 error ("Objective-C declarations may only appear in global scope");
2884 #endif /* OBJCPLUS */
2886 if (!(underlying_class
= objc_is_class_name (class_ident
)))
2887 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident
));
2888 else if (objc_is_class_name (alias_ident
))
2889 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident
));
2892 /* Implement @compatibility_alias as a typedef. */
2894 push_lang_context (lang_name_c
); /* extern "C" */
2896 lang_hooks
.decls
.pushdecl (build_decl
2899 xref_tag (RECORD_TYPE
, underlying_class
)));
2901 pop_lang_context ();
2903 alias_chain
= tree_cons (underlying_class
, alias_ident
, alias_chain
);
2908 objc_declare_class (tree ident_list
)
2912 if (current_namespace
!= global_namespace
) {
2913 error ("Objective-C declarations may only appear in global scope");
2915 #endif /* OBJCPLUS */
2917 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2919 tree ident
= TREE_VALUE (list
);
2921 if (! objc_is_class_name (ident
))
2923 tree record
= lookup_name (ident
), type
= record
;
2927 if (TREE_CODE (record
) == TYPE_DECL
)
2928 type
= DECL_ORIGINAL_TYPE (record
);
2930 if (!TYPE_HAS_OBJC_INFO (type
)
2931 || !TYPE_OBJC_INTERFACE (type
))
2933 error ("%qs redeclared as different kind of symbol",
2934 IDENTIFIER_POINTER (ident
));
2935 error ("previous declaration of %q+D",
2940 record
= xref_tag (RECORD_TYPE
, ident
);
2941 INIT_TYPE_OBJC_INFO (record
);
2942 TYPE_OBJC_INTERFACE (record
) = ident
;
2943 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2949 objc_is_class_name (tree ident
)
2953 if (ident
&& TREE_CODE (ident
) == IDENTIFIER_NODE
2954 && identifier_global_value (ident
))
2955 ident
= identifier_global_value (ident
);
2956 while (ident
&& TREE_CODE (ident
) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (ident
))
2957 ident
= OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident
));
2959 if (ident
&& TREE_CODE (ident
) == RECORD_TYPE
)
2960 ident
= OBJC_TYPE_NAME (ident
);
2962 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
2963 ident
= DECL_NAME (ident
);
2965 if (!ident
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
2968 if (lookup_interface (ident
))
2971 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2973 if (ident
== TREE_VALUE (chain
))
2977 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2979 if (ident
== TREE_VALUE (chain
))
2980 return TREE_PURPOSE (chain
);
2986 /* Check whether TYPE is either 'id' or 'Class'. */
2989 objc_is_id (tree type
)
2991 if (type
&& TREE_CODE (type
) == IDENTIFIER_NODE
2992 && identifier_global_value (type
))
2993 type
= identifier_global_value (type
);
2995 if (type
&& TREE_CODE (type
) == TYPE_DECL
)
2996 type
= TREE_TYPE (type
);
2998 /* NB: This function may be called before the ObjC front-end has
2999 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3000 return (objc_object_type
&& type
3001 && (IS_ID (type
) || IS_CLASS (type
) || IS_SUPER (type
))
3006 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3007 class instance. This is needed by other parts of the compiler to
3008 handle ObjC types gracefully. */
3011 objc_is_object_ptr (tree type
)
3015 type
= TYPE_MAIN_VARIANT (type
);
3016 if (!POINTER_TYPE_P (type
))
3019 ret
= objc_is_id (type
);
3021 ret
= objc_is_class_name (TREE_TYPE (type
));
3027 objc_is_gcable_type (tree type
, int or_strong_p
)
3033 if (objc_is_id (TYPE_MAIN_VARIANT (type
)))
3035 if (or_strong_p
&& lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type
)))
3037 if (TREE_CODE (type
) != POINTER_TYPE
&& TREE_CODE (type
) != INDIRECT_REF
)
3039 type
= TREE_TYPE (type
);
3040 if (TREE_CODE (type
) != RECORD_TYPE
)
3042 name
= TYPE_NAME (type
);
3043 return (objc_is_class_name (name
) != NULL_TREE
);
3047 objc_substitute_decl (tree expr
, tree oldexpr
, tree newexpr
)
3049 if (expr
== oldexpr
)
3052 switch (TREE_CODE (expr
))
3055 return objc_build_component_ref
3056 (objc_substitute_decl (TREE_OPERAND (expr
, 0),
3059 DECL_NAME (TREE_OPERAND (expr
, 1)));
3061 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr
, 0),
3064 TREE_OPERAND (expr
, 1),
3067 return build_indirect_ref (input_location
,
3068 objc_substitute_decl (TREE_OPERAND (expr
, 0),
3077 objc_build_ivar_assignment (tree outervar
, tree lhs
, tree rhs
)
3080 /* The LHS parameter contains the expression 'outervar->memberspec';
3081 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3082 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3085 = objc_substitute_decl
3086 (lhs
, outervar
, convert (TREE_TYPE (outervar
), integer_zero_node
));
3088 = (flag_objc_direct_dispatch
3089 ? objc_assign_ivar_fast_decl
3090 : objc_assign_ivar_decl
);
3092 offs
= convert (integer_type_node
, build_unary_op (input_location
,
3093 ADDR_EXPR
, offs
, 0));
3095 func_params
= tree_cons (NULL_TREE
,
3096 convert (objc_object_type
, rhs
),
3097 tree_cons (NULL_TREE
, convert (objc_object_type
, outervar
),
3098 tree_cons (NULL_TREE
, offs
,
3101 assemble_external (func
);
3102 return build_function_call (func
, func_params
);
3106 objc_build_global_assignment (tree lhs
, tree rhs
)
3108 tree func_params
= tree_cons (NULL_TREE
,
3109 convert (objc_object_type
, rhs
),
3110 tree_cons (NULL_TREE
, convert (build_pointer_type (objc_object_type
),
3111 build_unary_op (input_location
, ADDR_EXPR
, lhs
, 0)),
3114 assemble_external (objc_assign_global_decl
);
3115 return build_function_call (objc_assign_global_decl
, func_params
);
3119 objc_build_strong_cast_assignment (tree lhs
, tree rhs
)
3121 tree func_params
= tree_cons (NULL_TREE
,
3122 convert (objc_object_type
, rhs
),
3123 tree_cons (NULL_TREE
, convert (build_pointer_type (objc_object_type
),
3124 build_unary_op (input_location
, ADDR_EXPR
, lhs
, 0)),
3127 assemble_external (objc_assign_strong_cast_decl
);
3128 return build_function_call (objc_assign_strong_cast_decl
, func_params
);
3132 objc_is_gcable_p (tree expr
)
3134 return (TREE_CODE (expr
) == COMPONENT_REF
3135 ? objc_is_gcable_p (TREE_OPERAND (expr
, 1))
3136 : TREE_CODE (expr
) == ARRAY_REF
3137 ? (objc_is_gcable_p (TREE_TYPE (expr
))
3138 || objc_is_gcable_p (TREE_OPERAND (expr
, 0)))
3139 : TREE_CODE (expr
) == ARRAY_TYPE
3140 ? objc_is_gcable_p (TREE_TYPE (expr
))
3142 ? objc_is_gcable_type (expr
, 1)
3143 : (objc_is_gcable_p (TREE_TYPE (expr
))
3145 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr
)))));
3149 objc_is_ivar_reference_p (tree expr
)
3151 return (TREE_CODE (expr
) == ARRAY_REF
3152 ? objc_is_ivar_reference_p (TREE_OPERAND (expr
, 0))
3153 : TREE_CODE (expr
) == COMPONENT_REF
3154 ? TREE_CODE (TREE_OPERAND (expr
, 1)) == FIELD_DECL
3159 objc_is_global_reference_p (tree expr
)
3161 return (TREE_CODE (expr
) == INDIRECT_REF
|| TREE_CODE (expr
) == PLUS_EXPR
3162 ? objc_is_global_reference_p (TREE_OPERAND (expr
, 0))
3164 ? (!DECL_CONTEXT (expr
) || TREE_STATIC (expr
))
3169 objc_generate_write_barrier (tree lhs
, enum tree_code modifycode
, tree rhs
)
3171 tree result
= NULL_TREE
, outer
;
3172 int strong_cast_p
= 0, outer_gc_p
= 0, indirect_p
= 0;
3174 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3175 will have been transformed to the form '*(type *)&expr'. */
3176 if (TREE_CODE (lhs
) == INDIRECT_REF
)
3178 outer
= TREE_OPERAND (lhs
, 0);
3180 while (!strong_cast_p
3181 && (CONVERT_EXPR_P (outer
)
3182 || TREE_CODE (outer
) == NON_LVALUE_EXPR
))
3184 tree lhstype
= TREE_TYPE (outer
);
3186 /* Descend down the cast chain, and record the first objc_gc
3188 if (POINTER_TYPE_P (lhstype
))
3191 = lookup_attribute ("objc_gc",
3192 TYPE_ATTRIBUTES (TREE_TYPE (lhstype
)));
3198 outer
= TREE_OPERAND (outer
, 0);
3202 /* If we have a __strong cast, it trumps all else. */
3205 if (modifycode
!= NOP_EXPR
)
3206 goto invalid_pointer_arithmetic
;
3208 if (warn_assign_intercept
)
3209 warning (0, "strong-cast assignment has been intercepted");
3211 result
= objc_build_strong_cast_assignment (lhs
, rhs
);
3216 /* the lhs must be of a suitable type, regardless of its underlying
3218 if (!objc_is_gcable_p (lhs
))
3224 && (TREE_CODE (outer
) == COMPONENT_REF
3225 || TREE_CODE (outer
) == ARRAY_REF
))
3226 outer
= TREE_OPERAND (outer
, 0);
3228 if (TREE_CODE (outer
) == INDIRECT_REF
)
3230 outer
= TREE_OPERAND (outer
, 0);
3234 outer_gc_p
= objc_is_gcable_p (outer
);
3236 /* Handle ivar assignments. */
3237 if (objc_is_ivar_reference_p (lhs
))
3239 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3240 doesn't cut it here), the best we can do here is suggest a cast. */
3241 if (!objc_is_gcable_type (TREE_TYPE (outer
), 0))
3243 /* We may still be able to use the global write barrier... */
3244 if (!indirect_p
&& objc_is_global_reference_p (outer
))
3245 goto global_reference
;
3248 if (modifycode
== NOP_EXPR
)
3250 if (warn_assign_intercept
)
3251 warning (0, "strong-cast may possibly be needed");
3257 if (modifycode
!= NOP_EXPR
)
3258 goto invalid_pointer_arithmetic
;
3260 if (warn_assign_intercept
)
3261 warning (0, "instance variable assignment has been intercepted");
3263 result
= objc_build_ivar_assignment (outer
, lhs
, rhs
);
3268 /* Likewise, intercept assignment to global/static variables if their type is
3270 if (objc_is_global_reference_p (outer
))
3276 if (modifycode
!= NOP_EXPR
)
3278 invalid_pointer_arithmetic
:
3280 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3285 if (warn_assign_intercept
)
3286 warning (0, "global/static variable assignment has been intercepted");
3288 result
= objc_build_global_assignment (lhs
, rhs
);
3291 /* In all other cases, fall back to the normal mechanism. */
3296 struct interface_tuple
GTY(())
3302 static GTY ((param_is (struct interface_tuple
))) htab_t interface_htab
;
3305 hash_interface (const void *p
)
3307 const struct interface_tuple
*d
= (const struct interface_tuple
*) p
;
3308 return IDENTIFIER_HASH_VALUE (d
->id
);
3312 eq_interface (const void *p1
, const void *p2
)
3314 const struct interface_tuple
*d
= (const struct interface_tuple
*) p1
;
3319 lookup_interface (tree ident
)
3322 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
3323 ident
= DECL_NAME (ident
);
3326 if (ident
== NULL_TREE
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
3330 struct interface_tuple
**slot
;
3335 slot
= (struct interface_tuple
**)
3336 htab_find_slot_with_hash (interface_htab
, ident
,
3337 IDENTIFIER_HASH_VALUE (ident
),
3340 i
= (*slot
)->class_name
;
3346 /* Implement @defs (<classname>) within struct bodies. */
3349 objc_get_class_ivars (tree class_name
)
3351 tree interface
= lookup_interface (class_name
);
3354 return get_class_ivars (interface
, true);
3356 error ("cannot find interface declaration for %qs",
3357 IDENTIFIER_POINTER (class_name
));
3359 return error_mark_node
;
3362 /* Used by: build_private_template, continue_class,
3363 and for @defs constructs. */
3366 get_class_ivars (tree interface
, bool inherited
)
3368 tree ivar_chain
= copy_list (CLASS_RAW_IVARS (interface
));
3370 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3371 by the current class (i.e., they do not include super-class ivars).
3372 However, the CLASS_IVARS list will be side-effected by a call to
3373 finish_struct(), which will fill in field offsets. */
3374 if (!CLASS_IVARS (interface
))
3375 CLASS_IVARS (interface
) = ivar_chain
;
3380 while (CLASS_SUPER_NAME (interface
))
3382 /* Prepend super-class ivars. */
3383 interface
= lookup_interface (CLASS_SUPER_NAME (interface
));
3384 ivar_chain
= chainon (copy_list (CLASS_RAW_IVARS (interface
)),
3392 objc_create_temporary_var (tree type
)
3396 decl
= build_decl (VAR_DECL
, NULL_TREE
, type
);
3397 TREE_USED (decl
) = 1;
3398 DECL_ARTIFICIAL (decl
) = 1;
3399 DECL_IGNORED_P (decl
) = 1;
3400 DECL_CONTEXT (decl
) = current_function_decl
;
3405 /* Exception handling constructs. We begin by having the parser do most
3406 of the work and passing us blocks. What we do next depends on whether
3407 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3408 We abstract all of this in a handful of appropriately named routines. */
3410 /* Stack of open try blocks. */
3412 struct objc_try_context
3414 struct objc_try_context
*outer
;
3416 /* Statements (or statement lists) as processed by the parser. */
3420 /* Some file position locations. */
3421 location_t try_locus
;
3422 location_t end_try_locus
;
3423 location_t end_catch_locus
;
3424 location_t finally_locus
;
3425 location_t end_finally_locus
;
3427 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3428 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3431 /* The CATCH_EXPR of an open @catch clause. */
3434 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3440 static struct objc_try_context
*cur_try_context
;
3442 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3443 that represents TYPE. For Objective-C, this is just the class name. */
3444 /* ??? Isn't there a class object or some such? Is it easy to get? */
3448 objc_eh_runtime_type (tree type
)
3450 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type
)), class_names
);
3454 /* Initialize exception handling. */
3457 objc_init_exceptions (void)
3459 static bool done
= false;
3464 if (flag_objc_sjlj_exceptions
)
3466 /* On Darwin, ObjC exceptions require a sufficiently recent
3467 version of the runtime, so the user must ask for them explicitly. */
3468 if (!flag_objc_exceptions
)
3469 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3470 "exception syntax");
3475 c_eh_initialized_p
= true;
3476 eh_personality_libfunc
3477 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3478 ? "__gnu_objc_personality_sj0"
3479 : "__gnu_objc_personality_v0");
3480 default_init_unwind_resume_libfunc ();
3481 using_eh_for_cleanups ();
3482 lang_eh_runtime_type
= objc_eh_runtime_type
;
3487 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3488 we'll arrange for it to be initialized (and associated with a binding)
3492 objc_build_exc_ptr (void)
3494 if (flag_objc_sjlj_exceptions
)
3496 tree var
= cur_try_context
->caught_decl
;
3499 var
= objc_create_temporary_var (objc_object_type
);
3500 cur_try_context
->caught_decl
= var
;
3505 return build0 (EXC_PTR_EXPR
, objc_object_type
);
3508 /* Build "objc_exception_try_exit(&_stack)". */
3511 next_sjlj_build_try_exit (void)
3514 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
3515 t
= tree_cons (NULL
, t
, NULL
);
3516 t
= build_function_call (objc_exception_try_exit_decl
, t
);
3521 objc_exception_try_enter (&_stack);
3522 if (_setjmp(&_stack.buf))
3526 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3527 empty, ready for the caller to fill them in. */
3530 next_sjlj_build_enter_and_setjmp (void)
3532 tree t
, enter
, sj
, cond
;
3534 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
3535 t
= tree_cons (NULL
, t
, NULL
);
3536 enter
= build_function_call (objc_exception_try_enter_decl
, t
);
3538 t
= objc_build_component_ref (cur_try_context
->stack_decl
,
3539 get_identifier ("buf"));
3540 t
= build_fold_addr_expr (t
);
3542 /* Convert _setjmp argument to type that is expected. */
3543 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl
)))
3544 t
= convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl
))), t
);
3546 t
= convert (ptr_type_node
, t
);
3548 t
= convert (ptr_type_node
, t
);
3550 t
= tree_cons (NULL
, t
, NULL
);
3551 sj
= build_function_call (objc_setjmp_decl
, t
);
3553 cond
= build2 (COMPOUND_EXPR
, TREE_TYPE (sj
), enter
, sj
);
3554 cond
= c_common_truthvalue_conversion (input_location
, cond
);
3556 return build3 (COND_EXPR
, void_type_node
, cond
, NULL
, NULL
);
3561 DECL = objc_exception_extract(&_stack); */
3564 next_sjlj_build_exc_extract (tree decl
)
3568 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
3569 t
= tree_cons (NULL
, t
, NULL
);
3570 t
= build_function_call (objc_exception_extract_decl
, t
);
3571 t
= convert (TREE_TYPE (decl
), t
);
3572 t
= build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
3578 if (objc_exception_match(obj_get_class(TYPE), _caught)
3585 objc_exception_try_exit(&_stack);
3587 from the sequence of CATCH_EXPRs in the current try context. */
3590 next_sjlj_build_catch_list (void)
3592 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
3594 tree
*last
= &catch_seq
;
3595 bool saw_id
= false;
3597 for (; !tsi_end_p (i
); tsi_next (&i
))
3599 tree stmt
= tsi_stmt (i
);
3600 tree type
= CATCH_TYPES (stmt
);
3601 tree body
= CATCH_BODY (stmt
);
3613 if (type
== error_mark_node
)
3614 cond
= error_mark_node
;
3617 args
= tree_cons (NULL
, cur_try_context
->caught_decl
, NULL
);
3618 t
= objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type
)));
3619 args
= tree_cons (NULL
, t
, args
);
3620 t
= build_function_call (objc_exception_match_decl
, args
);
3621 cond
= c_common_truthvalue_conversion (input_location
, t
);
3623 t
= build3 (COND_EXPR
, void_type_node
, cond
, body
, NULL
);
3624 SET_EXPR_LOCUS (t
, EXPR_LOCUS (stmt
));
3627 last
= &COND_EXPR_ELSE (t
);
3633 t
= build2 (MODIFY_EXPR
, void_type_node
, cur_try_context
->rethrow_decl
,
3634 cur_try_context
->caught_decl
);
3635 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
3636 append_to_statement_list (t
, last
);
3638 t
= next_sjlj_build_try_exit ();
3639 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
3640 append_to_statement_list (t
, last
);
3646 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3647 exception handling. We aim to build:
3650 struct _objc_exception_data _stack;
3654 objc_exception_try_enter (&_stack);
3655 if (_setjmp(&_stack.buf))
3657 id _caught = objc_exception_extract(&_stack);
3658 objc_exception_try_enter (&_stack);
3659 if (_setjmp(&_stack.buf))
3660 _rethrow = objc_exception_extract(&_stack);
3670 objc_exception_try_exit(&_stack);
3673 objc_exception_throw(_rethrow);
3677 If CATCH-LIST is empty, we can omit all of the block containing
3678 "_caught" except for the setting of _rethrow. Note the use of
3679 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3680 but handles goto and other exits from the block. */
3683 next_sjlj_build_try_catch_finally (void)
3685 tree rethrow_decl
, stack_decl
, t
;
3686 tree catch_seq
, try_fin
, bind
;
3688 /* Create the declarations involved. */
3689 t
= xref_tag (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
3690 stack_decl
= objc_create_temporary_var (t
);
3691 cur_try_context
->stack_decl
= stack_decl
;
3693 rethrow_decl
= objc_create_temporary_var (objc_object_type
);
3694 cur_try_context
->rethrow_decl
= rethrow_decl
;
3695 TREE_CHAIN (rethrow_decl
) = stack_decl
;
3697 /* Build the outermost variable binding level. */
3698 bind
= build3 (BIND_EXPR
, void_type_node
, rethrow_decl
, NULL
, NULL
);
3699 SET_EXPR_LOCATION (bind
, cur_try_context
->try_locus
);
3700 TREE_SIDE_EFFECTS (bind
) = 1;
3702 /* Initialize rethrow_decl. */
3703 t
= build2 (MODIFY_EXPR
, void_type_node
, rethrow_decl
,
3704 convert (objc_object_type
, null_pointer_node
));
3705 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
3706 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
3708 /* Build the outermost TRY_FINALLY_EXPR. */
3709 try_fin
= build2 (TRY_FINALLY_EXPR
, void_type_node
, NULL
, NULL
);
3710 SET_EXPR_LOCATION (try_fin
, cur_try_context
->try_locus
);
3711 TREE_SIDE_EFFECTS (try_fin
) = 1;
3712 append_to_statement_list (try_fin
, &BIND_EXPR_BODY (bind
));
3714 /* Create the complete catch sequence. */
3715 if (cur_try_context
->catch_list
)
3717 tree caught_decl
= objc_build_exc_ptr ();
3718 catch_seq
= build_stmt (BIND_EXPR
, caught_decl
, NULL
, NULL
);
3719 TREE_SIDE_EFFECTS (catch_seq
) = 1;
3721 t
= next_sjlj_build_exc_extract (caught_decl
);
3722 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
3724 t
= next_sjlj_build_enter_and_setjmp ();
3725 COND_EXPR_THEN (t
) = next_sjlj_build_exc_extract (rethrow_decl
);
3726 COND_EXPR_ELSE (t
) = next_sjlj_build_catch_list ();
3727 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
3730 catch_seq
= next_sjlj_build_exc_extract (rethrow_decl
);
3731 SET_EXPR_LOCATION (catch_seq
, cur_try_context
->end_try_locus
);
3733 /* Build the main register-and-try if statement. */
3734 t
= next_sjlj_build_enter_and_setjmp ();
3735 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
3736 COND_EXPR_THEN (t
) = catch_seq
;
3737 COND_EXPR_ELSE (t
) = cur_try_context
->try_body
;
3738 TREE_OPERAND (try_fin
, 0) = t
;
3740 /* Build the complete FINALLY statement list. */
3741 t
= next_sjlj_build_try_exit ();
3742 t
= build_stmt (COND_EXPR
,
3743 c_common_truthvalue_conversion
3744 (input_location
, rethrow_decl
),
3746 SET_EXPR_LOCATION (t
, cur_try_context
->finally_locus
);
3747 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
3749 append_to_statement_list (cur_try_context
->finally_body
,
3750 &TREE_OPERAND (try_fin
, 1));
3752 t
= tree_cons (NULL
, rethrow_decl
, NULL
);
3753 t
= build_function_call (objc_exception_throw_decl
, t
);
3754 t
= build_stmt (COND_EXPR
,
3755 c_common_truthvalue_conversion (input_location
,
3758 SET_EXPR_LOCATION (t
, cur_try_context
->end_finally_locus
);
3759 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
3764 /* Called just after parsing the @try and its associated BODY. We now
3765 must prepare for the tricky bits -- handling the catches and finally. */
3768 objc_begin_try_stmt (location_t try_locus
, tree body
)
3770 struct objc_try_context
*c
= XCNEW (struct objc_try_context
);
3771 c
->outer
= cur_try_context
;
3773 c
->try_locus
= try_locus
;
3774 c
->end_try_locus
= input_location
;
3775 cur_try_context
= c
;
3777 objc_init_exceptions ();
3779 if (flag_objc_sjlj_exceptions
)
3780 objc_mark_locals_volatile (NULL
);
3783 /* Called just after parsing "@catch (parm)". Open a binding level,
3784 enter DECL into the binding level, and initialize it. Leave the
3785 binding level open while the body of the compound statement is parsed. */
3788 objc_begin_catch_clause (tree decl
)
3790 tree compound
, type
, t
;
3792 /* Begin a new scope that the entire catch clause will live in. */
3793 compound
= c_begin_compound_stmt (true);
3795 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3796 decl
= build_decl (VAR_DECL
, DECL_NAME (decl
), TREE_TYPE (decl
));
3797 lang_hooks
.decls
.pushdecl (decl
);
3799 /* Since a decl is required here by syntax, don't warn if its unused. */
3800 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3801 be what the previous objc implementation did. */
3802 TREE_USED (decl
) = 1;
3804 /* Verify that the type of the catch is valid. It must be a pointer
3805 to an Objective-C class, or "id" (which is catch-all). */
3806 type
= TREE_TYPE (decl
);
3808 if (POINTER_TYPE_P (type
) && objc_is_object_id (TREE_TYPE (type
)))
3810 else if (!POINTER_TYPE_P (type
) || !TYPED_OBJECT (TREE_TYPE (type
)))
3812 error ("@catch parameter is not a known Objective-C class type");
3813 type
= error_mark_node
;
3815 else if (cur_try_context
->catch_list
)
3817 /* Examine previous @catch clauses and see if we've already
3818 caught the type in question. */
3819 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
3820 for (; !tsi_end_p (i
); tsi_next (&i
))
3822 tree stmt
= tsi_stmt (i
);
3823 t
= CATCH_TYPES (stmt
);
3824 if (t
== error_mark_node
)
3826 if (!t
|| DERIVED_FROM_P (TREE_TYPE (t
), TREE_TYPE (type
)))
3828 warning (0, "exception of type %<%T%> will be caught",
3830 warning (0, "%H by earlier handler for %<%T%>",
3831 EXPR_LOCUS (stmt
), TREE_TYPE (t
? t
: objc_object_type
));
3837 /* Record the data for the catch in the try context so that we can
3838 finalize it later. */
3839 t
= build_stmt (CATCH_EXPR
, type
, compound
);
3840 cur_try_context
->current_catch
= t
;
3842 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3843 t
= objc_build_exc_ptr ();
3844 t
= convert (TREE_TYPE (decl
), t
);
3845 t
= build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
3849 /* Called just after parsing the closing brace of a @catch clause. Close
3850 the open binding level, and record a CATCH_EXPR for it. */
3853 objc_finish_catch_clause (void)
3855 tree c
= cur_try_context
->current_catch
;
3856 cur_try_context
->current_catch
= NULL
;
3857 cur_try_context
->end_catch_locus
= input_location
;
3859 CATCH_BODY (c
) = c_end_compound_stmt (CATCH_BODY (c
), 1);
3860 append_to_statement_list (c
, &cur_try_context
->catch_list
);
3863 /* Called after parsing a @finally clause and its associated BODY.
3864 Record the body for later placement. */
3867 objc_build_finally_clause (location_t finally_locus
, tree body
)
3869 cur_try_context
->finally_body
= body
;
3870 cur_try_context
->finally_locus
= finally_locus
;
3871 cur_try_context
->end_finally_locus
= input_location
;
3874 /* Called to finalize a @try construct. */
3877 objc_finish_try_stmt (void)
3879 struct objc_try_context
*c
= cur_try_context
;
3882 if (c
->catch_list
== NULL
&& c
->finally_body
== NULL
)
3883 error ("%<@try%> without %<@catch%> or %<@finally%>");
3885 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3886 if (flag_objc_sjlj_exceptions
)
3888 if (!cur_try_context
->finally_body
)
3890 cur_try_context
->finally_locus
= input_location
;
3891 cur_try_context
->end_finally_locus
= input_location
;
3893 stmt
= next_sjlj_build_try_catch_finally ();
3897 /* Otherwise, nest the CATCH inside a FINALLY. */
3901 stmt
= build_stmt (TRY_CATCH_EXPR
, stmt
, c
->catch_list
);
3902 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
3904 if (c
->finally_body
)
3906 stmt
= build_stmt (TRY_FINALLY_EXPR
, stmt
, c
->finally_body
);
3907 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
3912 cur_try_context
= c
->outer
;
3918 objc_build_throw_stmt (tree throw_expr
)
3922 objc_init_exceptions ();
3924 if (throw_expr
== NULL
)
3926 /* If we're not inside a @catch block, there is no "current
3927 exception" to be rethrown. */
3928 if (cur_try_context
== NULL
3929 || cur_try_context
->current_catch
== NULL
)
3931 error ("%<@throw%> (rethrow) used outside of a @catch block");
3935 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3936 value that we get from the runtime. */
3937 throw_expr
= objc_build_exc_ptr ();
3940 /* A throw is just a call to the runtime throw function with the
3941 object as a parameter. */
3942 args
= tree_cons (NULL
, throw_expr
, NULL
);
3943 return add_stmt (build_function_call (objc_exception_throw_decl
, args
));
3947 objc_build_synchronized (location_t start_locus
, tree mutex
, tree body
)
3951 /* First lock the mutex. */
3952 mutex
= save_expr (mutex
);
3953 args
= tree_cons (NULL
, mutex
, NULL
);
3954 call
= build_function_call (objc_sync_enter_decl
, args
);
3955 SET_EXPR_LOCATION (call
, start_locus
);
3958 /* Build the mutex unlock. */
3959 args
= tree_cons (NULL
, mutex
, NULL
);
3960 call
= build_function_call (objc_sync_exit_decl
, args
);
3961 SET_EXPR_LOCATION (call
, input_location
);
3963 /* Put the that and the body in a TRY_FINALLY. */
3964 objc_begin_try_stmt (start_locus
, body
);
3965 objc_build_finally_clause (input_location
, call
);
3966 return objc_finish_try_stmt ();
3970 /* Predefine the following data type:
3972 struct _objc_exception_data
3974 int buf[OBJC_JBLEN];
3978 /* The following yuckiness should prevent users from having to #include
3979 <setjmp.h> in their code... */
3981 /* Define to a harmless positive value so the below code doesn't die. */
3983 #define OBJC_JBLEN 18
3987 build_next_objc_exception_stuff (void)
3989 tree field_decl
, field_decl_chain
, index
, temp_type
;
3991 objc_exception_data_template
3992 = start_struct (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
3994 /* int buf[OBJC_JBLEN]; */
3996 index
= build_index_type (build_int_cst (NULL_TREE
, OBJC_JBLEN
- 1));
3997 field_decl
= create_field_decl (build_array_type (integer_type_node
, index
),
3999 field_decl_chain
= field_decl
;
4001 /* void *pointers[4]; */
4003 index
= build_index_type (build_int_cst (NULL_TREE
, 4 - 1));
4004 field_decl
= create_field_decl (build_array_type (ptr_type_node
, index
),
4006 chainon (field_decl_chain
, field_decl
);
4008 finish_struct (objc_exception_data_template
, field_decl_chain
, NULL_TREE
);
4010 /* int _setjmp(...); */
4011 /* If the user includes <setjmp.h>, this shall be superseded by
4012 'int _setjmp(jmp_buf);' */
4013 temp_type
= build_function_type (integer_type_node
, NULL_TREE
);
4015 = add_builtin_function (TAG_SETJMP
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
4017 /* id objc_exception_extract(struct _objc_exception_data *); */
4019 = build_function_type (objc_object_type
,
4020 tree_cons (NULL_TREE
,
4021 build_pointer_type (objc_exception_data_template
),
4023 objc_exception_extract_decl
4024 = add_builtin_function (TAG_EXCEPTIONEXTRACT
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4026 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4027 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4029 = build_function_type (void_type_node
,
4030 tree_cons (NULL_TREE
,
4031 build_pointer_type (objc_exception_data_template
),
4033 objc_exception_try_enter_decl
4034 = add_builtin_function (TAG_EXCEPTIONTRYENTER
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4036 objc_exception_try_exit_decl
4037 = add_builtin_function (TAG_EXCEPTIONTRYEXIT
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4040 /* int objc_exception_match(id, id); */
4042 = build_function_type (integer_type_node
,
4043 tree_cons (NULL_TREE
, objc_object_type
,
4044 tree_cons (NULL_TREE
, objc_object_type
,
4045 OBJC_VOID_AT_END
)));
4046 objc_exception_match_decl
4047 = add_builtin_function (TAG_EXCEPTIONMATCH
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4050 /* id objc_assign_ivar (id, id, unsigned int); */
4051 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4052 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4054 = build_function_type (objc_object_type
,
4056 (NULL_TREE
, objc_object_type
,
4057 tree_cons (NULL_TREE
, objc_object_type
,
4058 tree_cons (NULL_TREE
,
4060 OBJC_VOID_AT_END
))));
4061 objc_assign_ivar_decl
4062 = add_builtin_function (TAG_ASSIGNIVAR
, temp_type
, 0, NOT_BUILT_IN
,
4064 #ifdef OFFS_ASSIGNIVAR_FAST
4065 objc_assign_ivar_fast_decl
4066 = add_builtin_function (TAG_ASSIGNIVAR_FAST
, temp_type
, 0,
4067 NOT_BUILT_IN
, NULL
, NULL_TREE
);
4068 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl
)
4069 = tree_cons (get_identifier ("hard_coded_address"),
4070 build_int_cst (NULL_TREE
, OFFS_ASSIGNIVAR_FAST
),
4073 /* Default to slower ivar method. */
4074 objc_assign_ivar_fast_decl
= objc_assign_ivar_decl
;
4077 /* id objc_assign_global (id, id *); */
4078 /* id objc_assign_strongCast (id, id *); */
4079 temp_type
= build_function_type (objc_object_type
,
4080 tree_cons (NULL_TREE
, objc_object_type
,
4081 tree_cons (NULL_TREE
, build_pointer_type (objc_object_type
),
4082 OBJC_VOID_AT_END
)));
4083 objc_assign_global_decl
4084 = add_builtin_function (TAG_ASSIGNGLOBAL
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4086 objc_assign_strong_cast_decl
4087 = add_builtin_function (TAG_ASSIGNSTRONGCAST
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4092 build_objc_exception_stuff (void)
4094 tree noreturn_list
, nothrow_list
, temp_type
;
4096 noreturn_list
= tree_cons (get_identifier ("noreturn"), NULL
, NULL
);
4097 nothrow_list
= tree_cons (get_identifier ("nothrow"), NULL
, NULL
);
4099 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4100 /* void objc_sync_enter(id); */
4101 /* void objc_sync_exit(id); */
4102 temp_type
= build_function_type (void_type_node
,
4103 tree_cons (NULL_TREE
, objc_object_type
,
4105 objc_exception_throw_decl
4106 = add_builtin_function (TAG_EXCEPTIONTHROW
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4108 objc_sync_enter_decl
4109 = add_builtin_function (TAG_SYNCENTER
, temp_type
, 0, NOT_BUILT_IN
,
4110 NULL
, nothrow_list
);
4112 = add_builtin_function (TAG_SYNCEXIT
, temp_type
, 0, NOT_BUILT_IN
,
4113 NULL
, nothrow_list
);
4116 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4119 struct <classname> {
4120 struct _objc_class *isa;
4125 build_private_template (tree klass
)
4127 if (!CLASS_STATIC_TEMPLATE (klass
))
4129 tree record
= objc_build_struct (klass
,
4130 get_class_ivars (klass
, false),
4131 CLASS_SUPER_NAME (klass
));
4133 /* Set the TREE_USED bit for this struct, so that stab generator
4134 can emit stabs for this struct type. */
4135 if (flag_debug_only_used_symbols
&& TYPE_STUB_DECL (record
))
4136 TREE_USED (TYPE_STUB_DECL (record
)) = 1;
4140 /* Begin code generation for protocols... */
4142 /* struct _objc_protocol {
4143 struct _objc_class *isa;
4144 char *protocol_name;
4145 struct _objc_protocol **protocol_list;
4146 struct _objc__method_prototype_list *instance_methods;
4147 struct _objc__method_prototype_list *class_methods;
4151 build_protocol_template (void)
4153 tree field_decl
, field_decl_chain
;
4155 objc_protocol_template
= start_struct (RECORD_TYPE
,
4156 get_identifier (UTAG_PROTOCOL
));
4158 /* struct _objc_class *isa; */
4159 field_decl
= create_field_decl (build_pointer_type
4160 (xref_tag (RECORD_TYPE
,
4161 get_identifier (UTAG_CLASS
))),
4163 field_decl_chain
= field_decl
;
4165 /* char *protocol_name; */
4166 field_decl
= create_field_decl (string_type_node
, "protocol_name");
4167 chainon (field_decl_chain
, field_decl
);
4169 /* struct _objc_protocol **protocol_list; */
4170 field_decl
= create_field_decl (build_pointer_type
4172 (objc_protocol_template
)),
4174 chainon (field_decl_chain
, field_decl
);
4176 /* struct _objc__method_prototype_list *instance_methods; */
4177 field_decl
= create_field_decl (objc_method_proto_list_ptr
,
4178 "instance_methods");
4179 chainon (field_decl_chain
, field_decl
);
4181 /* struct _objc__method_prototype_list *class_methods; */
4182 field_decl
= create_field_decl (objc_method_proto_list_ptr
,
4184 chainon (field_decl_chain
, field_decl
);
4186 finish_struct (objc_protocol_template
, field_decl_chain
, NULL_TREE
);
4190 build_descriptor_table_initializer (tree type
, tree entries
)
4192 tree initlist
= NULL_TREE
;
4196 tree eltlist
= NULL_TREE
;
4199 = tree_cons (NULL_TREE
,
4200 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
4202 = tree_cons (NULL_TREE
,
4203 add_objc_string (METHOD_ENCODING (entries
),
4208 = tree_cons (NULL_TREE
,
4209 objc_build_constructor (type
, nreverse (eltlist
)),
4212 entries
= TREE_CHAIN (entries
);
4216 return objc_build_constructor (build_array_type (type
, 0),
4217 nreverse (initlist
));
4220 /* struct objc_method_prototype_list {
4222 struct objc_method_prototype {
4229 build_method_prototype_list_template (tree list_type
, int size
)
4231 tree objc_ivar_list_record
;
4232 tree field_decl
, field_decl_chain
;
4234 /* Generate an unnamed struct definition. */
4236 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
4238 /* int method_count; */
4239 field_decl
= create_field_decl (integer_type_node
, "method_count");
4240 field_decl_chain
= field_decl
;
4242 /* struct objc_method method_list[]; */
4243 field_decl
= create_field_decl (build_array_type
4246 (build_int_cst (NULL_TREE
, size
- 1))),
4248 chainon (field_decl_chain
, field_decl
);
4250 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
4252 return objc_ivar_list_record
;
4256 build_method_prototype_template (void)
4259 tree field_decl
, field_decl_chain
;
4262 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
4265 field_decl
= create_field_decl (objc_selector_type
, "_cmd");
4266 field_decl_chain
= field_decl
;
4268 /* char *method_types; */
4269 field_decl
= create_field_decl (string_type_node
, "method_types");
4270 chainon (field_decl_chain
, field_decl
);
4272 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
4274 return proto_record
;
4278 objc_method_parm_type (tree type
)
4280 type
= TREE_VALUE (TREE_TYPE (type
));
4281 if (TREE_CODE (type
) == TYPE_DECL
)
4282 type
= TREE_TYPE (type
);
4287 objc_encoded_type_size (tree type
)
4289 int sz
= int_size_in_bytes (type
);
4291 /* Make all integer and enum types at least as large
4293 if (sz
> 0 && INTEGRAL_TYPE_P (type
))
4294 sz
= MAX (sz
, int_size_in_bytes (integer_type_node
));
4295 /* Treat arrays as pointers, since that's how they're
4297 else if (TREE_CODE (type
) == ARRAY_TYPE
)
4298 sz
= int_size_in_bytes (ptr_type_node
);
4303 encode_method_prototype (tree method_decl
)
4310 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4311 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
4313 /* Encode return type. */
4314 encode_type (objc_method_parm_type (method_decl
),
4315 obstack_object_size (&util_obstack
),
4316 OBJC_ENCODE_INLINE_DEFS
);
4319 /* The first two arguments (self and _cmd) are pointers; account for
4321 i
= int_size_in_bytes (ptr_type_node
);
4322 parm_offset
= 2 * i
;
4323 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
4324 parms
= TREE_CHAIN (parms
))
4326 tree type
= objc_method_parm_type (parms
);
4327 int sz
= objc_encoded_type_size (type
);
4329 /* If a type size is not known, bail out. */
4332 error ("type %q+D does not have a known size",
4334 /* Pretend that the encoding succeeded; the compilation will
4335 fail nevertheless. */
4336 goto finish_encoding
;
4341 sprintf (buf
, "%d@0:%d", parm_offset
, i
);
4342 obstack_grow (&util_obstack
, buf
, strlen (buf
));
4344 /* Argument types. */
4345 parm_offset
= 2 * i
;
4346 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
4347 parms
= TREE_CHAIN (parms
))
4349 tree type
= objc_method_parm_type (parms
);
4351 /* Process argument qualifiers for user supplied arguments. */
4352 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms
)));
4355 encode_type (type
, obstack_object_size (&util_obstack
),
4356 OBJC_ENCODE_INLINE_DEFS
);
4358 /* Compute offset. */
4359 sprintf (buf
, "%d", parm_offset
);
4360 parm_offset
+= objc_encoded_type_size (type
);
4362 obstack_grow (&util_obstack
, buf
, strlen (buf
));
4366 obstack_1grow (&util_obstack
, '\0');
4367 result
= get_identifier (XOBFINISH (&util_obstack
, char *));
4368 obstack_free (&util_obstack
, util_firstobj
);
4373 generate_descriptor_table (tree type
, const char *name
, int size
, tree list
,
4376 tree decl
, initlist
;
4378 decl
= start_var_decl (type
, synth_id_with_class_suffix (name
, proto
));
4380 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, size
));
4381 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4383 finish_var_decl (decl
, objc_build_constructor (type
, nreverse (initlist
)));
4389 generate_method_descriptors (tree protocol
)
4391 tree initlist
, chain
, method_list_template
;
4394 if (!objc_method_prototype_template
)
4395 objc_method_prototype_template
= build_method_prototype_template ();
4397 chain
= PROTOCOL_CLS_METHODS (protocol
);
4400 size
= list_length (chain
);
4402 method_list_template
4403 = build_method_prototype_list_template (objc_method_prototype_template
,
4407 = build_descriptor_table_initializer (objc_method_prototype_template
,
4410 UOBJC_CLASS_METHODS_decl
4411 = generate_descriptor_table (method_list_template
,
4412 "_OBJC_PROTOCOL_CLASS_METHODS",
4413 size
, initlist
, protocol
);
4416 UOBJC_CLASS_METHODS_decl
= 0;
4418 chain
= PROTOCOL_NST_METHODS (protocol
);
4421 size
= list_length (chain
);
4423 method_list_template
4424 = build_method_prototype_list_template (objc_method_prototype_template
,
4427 = build_descriptor_table_initializer (objc_method_prototype_template
,
4430 UOBJC_INSTANCE_METHODS_decl
4431 = generate_descriptor_table (method_list_template
,
4432 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4433 size
, initlist
, protocol
);
4436 UOBJC_INSTANCE_METHODS_decl
= 0;
4440 generate_protocol_references (tree plist
)
4444 /* Forward declare protocols referenced. */
4445 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4447 tree proto
= TREE_VALUE (lproto
);
4449 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
4450 && PROTOCOL_NAME (proto
))
4452 if (! PROTOCOL_FORWARD_DECL (proto
))
4453 build_protocol_reference (proto
);
4455 if (PROTOCOL_LIST (proto
))
4456 generate_protocol_references (PROTOCOL_LIST (proto
));
4461 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4465 objc_generate_cxx_ctor_or_dtor (bool dtor
)
4467 tree fn
, body
, compound_stmt
, ivar
;
4469 /* - (id) .cxx_construct { ... return self; } */
4470 /* - (void) .cxx_construct { ... } */
4472 objc_set_method_type (MINUS_EXPR
);
4473 objc_start_method_definition
4474 (objc_build_method_signature (build_tree_list (NULL_TREE
,
4477 : objc_object_type
),
4478 get_identifier (dtor
4480 : TAG_CXX_CONSTRUCT
),
4481 make_node (TREE_LIST
),
4483 body
= begin_function_body ();
4484 compound_stmt
= begin_compound_stmt (0);
4486 ivar
= CLASS_IVARS (implementation_template
);
4487 /* Destroy ivars in reverse order. */
4489 ivar
= nreverse (copy_list (ivar
));
4491 for (; ivar
; ivar
= TREE_CHAIN (ivar
))
4493 if (TREE_CODE (ivar
) == FIELD_DECL
)
4495 tree type
= TREE_TYPE (ivar
);
4497 /* Call the ivar's default constructor or destructor. Do not
4498 call the destructor unless a corresponding constructor call
4499 has also been made (or is not needed). */
4500 if (MAYBE_CLASS_TYPE_P (type
)
4502 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type
)
4503 && (!TYPE_NEEDS_CONSTRUCTING (type
)
4504 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type
)))
4505 : (TYPE_NEEDS_CONSTRUCTING (type
)
4506 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type
))))
4508 (build_special_member_call
4509 (build_ivar_reference (DECL_NAME (ivar
)),
4510 dtor
? complete_dtor_identifier
: complete_ctor_identifier
,
4511 NULL_TREE
, type
, LOOKUP_NORMAL
, tf_warning_or_error
));
4515 /* The constructor returns 'self'. */
4517 finish_return_stmt (self_decl
);
4519 finish_compound_stmt (compound_stmt
);
4520 finish_function_body (body
);
4521 fn
= current_function_decl
;
4523 objc_finish_method_definition (fn
);
4526 /* The following routine will examine the current @interface for any
4527 non-POD C++ ivars requiring non-trivial construction and/or
4528 destruction, and then synthesize special '- .cxx_construct' and/or
4529 '- .cxx_destruct' methods which will run the appropriate
4530 construction or destruction code. Note that ivars inherited from
4531 super-classes are _not_ considered. */
4533 objc_generate_cxx_cdtors (void)
4535 bool need_ctor
= false, need_dtor
= false;
4538 /* We do not want to do this for categories, since they do not have
4541 if (TREE_CODE (objc_implementation_context
) != CLASS_IMPLEMENTATION_TYPE
)
4544 /* First, determine if we even need a constructor and/or destructor. */
4546 for (ivar
= CLASS_IVARS (implementation_template
); ivar
;
4547 ivar
= TREE_CHAIN (ivar
))
4549 if (TREE_CODE (ivar
) == FIELD_DECL
)
4551 tree type
= TREE_TYPE (ivar
);
4553 if (MAYBE_CLASS_TYPE_P (type
))
4555 if (TYPE_NEEDS_CONSTRUCTING (type
)
4556 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type
))
4557 /* NB: If a default constructor is not available, we will not
4558 be able to initialize this ivar; the add_instance_variable()
4559 routine will already have warned about this. */
4562 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type
)
4563 && (!TYPE_NEEDS_CONSTRUCTING (type
)
4564 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type
)))
4565 /* NB: If a default constructor is not available, we will not
4566 call the destructor either, for symmetry. */
4572 /* Generate '- .cxx_construct' if needed. */
4575 objc_generate_cxx_ctor_or_dtor (false);
4577 /* Generate '- .cxx_destruct' if needed. */
4580 objc_generate_cxx_ctor_or_dtor (true);
4582 /* The 'imp_list' variable points at an imp_entry record for the current
4583 @implementation. Record the existence of '- .cxx_construct' and/or
4584 '- .cxx_destruct' methods therein; it will be included in the
4585 metadata for the class. */
4586 if (flag_next_runtime
)
4587 imp_list
->has_cxx_cdtors
= (need_ctor
|| need_dtor
);
4591 /* For each protocol which was referenced either from a @protocol()
4592 expression, or because a class/category implements it (then a
4593 pointer to the protocol is stored in the struct describing the
4594 class/category), we create a statically allocated instance of the
4595 Protocol class. The code is written in such a way as to generate
4596 as few Protocol objects as possible; we generate a unique Protocol
4597 instance for each protocol, and we don't generate a Protocol
4598 instance if the protocol is never referenced (either from a
4599 @protocol() or from a class/category implementation). These
4600 statically allocated objects can be referred to via the static
4601 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4603 The statically allocated Protocol objects that we generate here
4604 need to be fixed up at runtime in order to be used: the 'isa'
4605 pointer of the objects need to be set up to point to the 'Protocol'
4606 class, as known at runtime.
4608 The NeXT runtime fixes up all protocols at program startup time,
4609 before main() is entered. It uses a low-level trick to look up all
4610 those symbols, then loops on them and fixes them up.
4612 The GNU runtime as well fixes up all protocols before user code
4613 from the module is executed; it requires pointers to those symbols
4614 to be put in the objc_symtab (which is then passed as argument to
4615 the function __objc_exec_class() which the compiler sets up to be
4616 executed automatically when the module is loaded); setup of those
4617 Protocol objects happen in two ways in the GNU runtime: all
4618 Protocol objects referred to by a class or category implementation
4619 are fixed up when the class/category is loaded; all Protocol
4620 objects referred to by a @protocol() expression are added by the
4621 compiler to the list of statically allocated instances to fixup
4622 (the same list holding the statically allocated constant string
4623 objects). Because, as explained above, the compiler generates as
4624 few Protocol objects as possible, some Protocol object might end up
4625 being referenced multiple times when compiled with the GNU runtime,
4626 and end up being fixed up multiple times at runtime initialization.
4627 But that doesn't hurt, it's just a little inefficient. */
4630 generate_protocols (void)
4634 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
4636 /* If a protocol was directly referenced, pull in indirect references. */
4637 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
4638 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
4639 generate_protocol_references (PROTOCOL_LIST (p
));
4641 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
4643 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
4644 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
4646 /* If protocol wasn't referenced, don't generate any code. */
4647 decl
= PROTOCOL_FORWARD_DECL (p
);
4652 /* Make sure we link in the Protocol class. */
4653 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
4657 if (! METHOD_ENCODING (nst_methods
))
4659 encoding
= encode_method_prototype (nst_methods
);
4660 METHOD_ENCODING (nst_methods
) = encoding
;
4662 nst_methods
= TREE_CHAIN (nst_methods
);
4667 if (! METHOD_ENCODING (cls_methods
))
4669 encoding
= encode_method_prototype (cls_methods
);
4670 METHOD_ENCODING (cls_methods
) = encoding
;
4673 cls_methods
= TREE_CHAIN (cls_methods
);
4675 generate_method_descriptors (p
);
4677 if (PROTOCOL_LIST (p
))
4678 refs_decl
= generate_protocol_list (p
);
4682 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4683 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
4686 refs_expr
= convert (build_pointer_type (build_pointer_type
4687 (objc_protocol_template
)),
4688 build_unary_op (input_location
,
4689 ADDR_EXPR
, refs_decl
, 0));
4691 refs_expr
= build_int_cst (NULL_TREE
, 0);
4693 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4694 by generate_method_descriptors, which is called above. */
4695 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
4696 protocol_name_expr
, refs_expr
,
4697 UOBJC_INSTANCE_METHODS_decl
,
4698 UOBJC_CLASS_METHODS_decl
);
4699 finish_var_decl (decl
, initlist
);
4704 build_protocol_initializer (tree type
, tree protocol_name
,
4705 tree protocol_list
, tree instance_methods
,
4708 tree initlist
= NULL_TREE
, expr
;
4709 tree cast_type
= build_pointer_type
4710 (xref_tag (RECORD_TYPE
,
4711 get_identifier (UTAG_CLASS
)));
4713 /* Filling the "isa" in with one allows the runtime system to
4714 detect that the version change...should remove before final release. */
4716 expr
= build_int_cst (cast_type
, PROTOCOL_VERSION
);
4717 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4718 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
4719 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
4721 if (!instance_methods
)
4722 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4725 expr
= convert (objc_method_proto_list_ptr
,
4726 build_unary_op (input_location
,
4727 ADDR_EXPR
, instance_methods
, 0));
4728 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4732 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4735 expr
= convert (objc_method_proto_list_ptr
,
4736 build_unary_op (input_location
,
4737 ADDR_EXPR
, class_methods
, 0));
4738 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4741 return objc_build_constructor (type
, nreverse (initlist
));
4744 /* struct _objc_category {
4745 char *category_name;
4747 struct _objc_method_list *instance_methods;
4748 struct _objc_method_list *class_methods;
4749 struct _objc_protocol_list *protocols;
4753 build_category_template (void)
4755 tree field_decl
, field_decl_chain
;
4757 objc_category_template
= start_struct (RECORD_TYPE
,
4758 get_identifier (UTAG_CATEGORY
));
4760 /* char *category_name; */
4761 field_decl
= create_field_decl (string_type_node
, "category_name");
4762 field_decl_chain
= field_decl
;
4764 /* char *class_name; */
4765 field_decl
= create_field_decl (string_type_node
, "class_name");
4766 chainon (field_decl_chain
, field_decl
);
4768 /* struct _objc_method_list *instance_methods; */
4769 field_decl
= create_field_decl (objc_method_list_ptr
,
4770 "instance_methods");
4771 chainon (field_decl_chain
, field_decl
);
4773 /* struct _objc_method_list *class_methods; */
4774 field_decl
= create_field_decl (objc_method_list_ptr
,
4776 chainon (field_decl_chain
, field_decl
);
4778 /* struct _objc_protocol **protocol_list; */
4779 field_decl
= create_field_decl (build_pointer_type
4781 (objc_protocol_template
)),
4783 chainon (field_decl_chain
, field_decl
);
4785 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
4788 /* struct _objc_selector {
4794 build_selector_template (void)
4797 tree field_decl
, field_decl_chain
;
4799 objc_selector_template
4800 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
4803 field_decl
= create_field_decl (objc_selector_type
, "sel_id");
4804 field_decl_chain
= field_decl
;
4806 /* char *sel_type; */
4807 field_decl
= create_field_decl (string_type_node
, "sel_type");
4808 chainon (field_decl_chain
, field_decl
);
4810 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
4813 /* struct _objc_class {
4814 struct _objc_class *isa;
4815 struct _objc_class *super_class;
4820 struct _objc_ivar_list *ivars;
4821 struct _objc_method_list *methods;
4822 #ifdef __NEXT_RUNTIME__
4823 struct objc_cache *cache;
4825 struct sarray *dtable;
4826 struct _objc_class *subclass_list;
4827 struct _objc_class *sibling_class;
4829 struct _objc_protocol_list *protocols;
4830 #ifdef __NEXT_RUNTIME__
4833 void *gc_object_type;
4836 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4837 the NeXT/Apple runtime; still, the compiler must generate them to
4838 maintain backward binary compatibility (and to allow for future
4842 build_class_template (void)
4844 tree field_decl
, field_decl_chain
;
4847 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
4849 /* struct _objc_class *isa; */
4850 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4852 field_decl_chain
= field_decl
;
4854 /* struct _objc_class *super_class; */
4855 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4857 chainon (field_decl_chain
, field_decl
);
4860 field_decl
= create_field_decl (string_type_node
, "name");
4861 chainon (field_decl_chain
, field_decl
);
4864 field_decl
= create_field_decl (long_integer_type_node
, "version");
4865 chainon (field_decl_chain
, field_decl
);
4868 field_decl
= create_field_decl (long_integer_type_node
, "info");
4869 chainon (field_decl_chain
, field_decl
);
4871 /* long instance_size; */
4872 field_decl
= create_field_decl (long_integer_type_node
, "instance_size");
4873 chainon (field_decl_chain
, field_decl
);
4875 /* struct _objc_ivar_list *ivars; */
4876 field_decl
= create_field_decl (objc_ivar_list_ptr
,
4878 chainon (field_decl_chain
, field_decl
);
4880 /* struct _objc_method_list *methods; */
4881 field_decl
= create_field_decl (objc_method_list_ptr
,
4883 chainon (field_decl_chain
, field_decl
);
4885 if (flag_next_runtime
)
4887 /* struct objc_cache *cache; */
4888 field_decl
= create_field_decl (build_pointer_type
4889 (xref_tag (RECORD_TYPE
,
4893 chainon (field_decl_chain
, field_decl
);
4897 /* struct sarray *dtable; */
4898 field_decl
= create_field_decl (build_pointer_type
4899 (xref_tag (RECORD_TYPE
,
4903 chainon (field_decl_chain
, field_decl
);
4905 /* struct objc_class *subclass_list; */
4906 field_decl
= create_field_decl (build_pointer_type
4907 (objc_class_template
),
4909 chainon (field_decl_chain
, field_decl
);
4911 /* struct objc_class *sibling_class; */
4912 field_decl
= create_field_decl (build_pointer_type
4913 (objc_class_template
),
4915 chainon (field_decl_chain
, field_decl
);
4918 /* struct _objc_protocol **protocol_list; */
4919 field_decl
= create_field_decl (build_pointer_type
4921 (xref_tag (RECORD_TYPE
,
4925 chainon (field_decl_chain
, field_decl
);
4927 if (flag_next_runtime
)
4930 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4932 chainon (field_decl_chain
, field_decl
);
4935 /* void *gc_object_type; */
4936 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4938 chainon (field_decl_chain
, field_decl
);
4940 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
4943 /* Generate appropriate forward declarations for an implementation. */
4946 synth_forward_declarations (void)
4950 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4951 UOBJC_CLASS_decl
= build_metadata_decl ("_OBJC_CLASS",
4952 objc_class_template
);
4954 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4955 UOBJC_METACLASS_decl
= build_metadata_decl ("_OBJC_METACLASS",
4956 objc_class_template
);
4958 /* Pre-build the following entities - for speed/convenience. */
4960 an_id
= get_identifier ("super_class");
4961 ucls_super_ref
= objc_build_component_ref (UOBJC_CLASS_decl
, an_id
);
4962 uucls_super_ref
= objc_build_component_ref (UOBJC_METACLASS_decl
, an_id
);
4966 error_with_ivar (const char *message
, tree decl
)
4968 error ("%J%s %qs", decl
,
4969 message
, gen_declaration (decl
));
4974 check_ivars (tree inter
, tree imp
)
4976 tree intdecls
= CLASS_RAW_IVARS (inter
);
4977 tree impdecls
= CLASS_RAW_IVARS (imp
);
4984 if (intdecls
&& TREE_CODE (intdecls
) == TYPE_DECL
)
4985 intdecls
= TREE_CHAIN (intdecls
);
4987 if (intdecls
== 0 && impdecls
== 0)
4989 if (intdecls
== 0 || impdecls
== 0)
4991 error ("inconsistent instance variable specification");
4995 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
4997 if (!comptypes (t1
, t2
)
4998 || !tree_int_cst_equal (DECL_INITIAL (intdecls
),
4999 DECL_INITIAL (impdecls
)))
5001 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
5003 error_with_ivar ("conflicting instance variable type",
5005 error_with_ivar ("previous declaration of",
5008 else /* both the type and the name don't match */
5010 error ("inconsistent instance variable specification");
5015 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
5017 error_with_ivar ("conflicting instance variable name",
5019 error_with_ivar ("previous declaration of",
5023 intdecls
= TREE_CHAIN (intdecls
);
5024 impdecls
= TREE_CHAIN (impdecls
);
5028 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5029 This needs to be done just once per compilation. */
5031 /* struct _objc_super {
5032 struct _objc_object *self;
5033 struct _objc_class *super_class;
5037 build_super_template (void)
5039 tree field_decl
, field_decl_chain
;
5041 objc_super_template
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
5043 /* struct _objc_object *self; */
5044 field_decl
= create_field_decl (objc_object_type
, "self");
5045 field_decl_chain
= field_decl
;
5047 /* struct _objc_class *super_class; */
5048 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
5050 chainon (field_decl_chain
, field_decl
);
5052 finish_struct (objc_super_template
, field_decl_chain
, NULL_TREE
);
5055 /* struct _objc_ivar {
5062 build_ivar_template (void)
5064 tree objc_ivar_id
, objc_ivar_record
;
5065 tree field_decl
, field_decl_chain
;
5067 objc_ivar_id
= get_identifier (UTAG_IVAR
);
5068 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
5070 /* char *ivar_name; */
5071 field_decl
= create_field_decl (string_type_node
, "ivar_name");
5072 field_decl_chain
= field_decl
;
5074 /* char *ivar_type; */
5075 field_decl
= create_field_decl (string_type_node
, "ivar_type");
5076 chainon (field_decl_chain
, field_decl
);
5078 /* int ivar_offset; */
5079 field_decl
= create_field_decl (integer_type_node
, "ivar_offset");
5080 chainon (field_decl_chain
, field_decl
);
5082 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
5084 return objc_ivar_record
;
5089 struct objc_ivar ivar_list[ivar_count];
5093 build_ivar_list_template (tree list_type
, int size
)
5095 tree objc_ivar_list_record
;
5096 tree field_decl
, field_decl_chain
;
5098 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
5100 /* int ivar_count; */
5101 field_decl
= create_field_decl (integer_type_node
, "ivar_count");
5102 field_decl_chain
= field_decl
;
5104 /* struct objc_ivar ivar_list[]; */
5105 field_decl
= create_field_decl (build_array_type
5108 (build_int_cst (NULL_TREE
, size
- 1))),
5110 chainon (field_decl_chain
, field_decl
);
5112 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
5114 return objc_ivar_list_record
;
5118 struct _objc__method_prototype_list *method_next;
5120 struct objc_method method_list[method_count];
5124 build_method_list_template (tree list_type
, int size
)
5126 tree objc_ivar_list_record
;
5127 tree field_decl
, field_decl_chain
;
5129 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
5131 /* struct _objc__method_prototype_list *method_next; */
5132 field_decl
= create_field_decl (objc_method_proto_list_ptr
,
5134 field_decl_chain
= field_decl
;
5136 /* int method_count; */
5137 field_decl
= create_field_decl (integer_type_node
, "method_count");
5138 chainon (field_decl_chain
, field_decl
);
5140 /* struct objc_method method_list[]; */
5141 field_decl
= create_field_decl (build_array_type
5144 (build_int_cst (NULL_TREE
, size
- 1))),
5146 chainon (field_decl_chain
, field_decl
);
5148 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
5150 return objc_ivar_list_record
;
5154 build_ivar_list_initializer (tree type
, tree field_decl
)
5156 tree initlist
= NULL_TREE
;
5160 tree ivar
= NULL_TREE
;
5163 if (DECL_NAME (field_decl
))
5164 ivar
= tree_cons (NULL_TREE
,
5165 add_objc_string (DECL_NAME (field_decl
),
5169 /* Unnamed bit-field ivar (yuck). */
5170 ivar
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), ivar
);
5173 encode_field_decl (field_decl
,
5174 obstack_object_size (&util_obstack
),
5175 OBJC_ENCODE_DONT_INLINE_DEFS
);
5177 /* Null terminate string. */
5178 obstack_1grow (&util_obstack
, 0);
5182 add_objc_string (get_identifier (XOBFINISH (&util_obstack
, char *)),
5185 obstack_free (&util_obstack
, util_firstobj
);
5188 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
5189 initlist
= tree_cons (NULL_TREE
,
5190 objc_build_constructor (type
, nreverse (ivar
)),
5193 field_decl
= TREE_CHAIN (field_decl
);
5194 while (field_decl
&& TREE_CODE (field_decl
) != FIELD_DECL
);
5198 return objc_build_constructor (build_array_type (type
, 0),
5199 nreverse (initlist
));
5203 generate_ivars_list (tree type
, const char *name
, int size
, tree list
)
5205 tree decl
, initlist
;
5207 decl
= start_var_decl (type
, synth_id_with_class_suffix
5208 (name
, objc_implementation_context
));
5210 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, size
));
5211 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
5213 finish_var_decl (decl
,
5214 objc_build_constructor (TREE_TYPE (decl
),
5215 nreverse (initlist
)));
5220 /* Count only the fields occurring in T. */
5223 ivar_list_length (tree t
)
5227 for (; t
; t
= TREE_CHAIN (t
))
5228 if (TREE_CODE (t
) == FIELD_DECL
)
5235 generate_ivar_lists (void)
5237 tree initlist
, ivar_list_template
, chain
;
5240 generating_instance_variables
= 1;
5242 if (!objc_ivar_template
)
5243 objc_ivar_template
= build_ivar_template ();
5245 /* Only generate class variables for the root of the inheritance
5246 hierarchy since these will be the same for every class. */
5248 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
5249 && (chain
= TYPE_FIELDS (objc_class_template
)))
5251 size
= ivar_list_length (chain
);
5253 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
5254 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
5256 UOBJC_CLASS_VARIABLES_decl
5257 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
5261 UOBJC_CLASS_VARIABLES_decl
= 0;
5263 chain
= CLASS_IVARS (implementation_template
);
5266 size
= ivar_list_length (chain
);
5267 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
5268 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
5270 UOBJC_INSTANCE_VARIABLES_decl
5271 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
5275 UOBJC_INSTANCE_VARIABLES_decl
= 0;
5277 generating_instance_variables
= 0;
5281 build_dispatch_table_initializer (tree type
, tree entries
)
5283 tree initlist
= NULL_TREE
;
5287 tree elemlist
= NULL_TREE
;
5289 elemlist
= tree_cons (NULL_TREE
,
5290 build_selector (METHOD_SEL_NAME (entries
)),
5293 /* Generate the method encoding if we don't have one already. */
5294 if (! METHOD_ENCODING (entries
))
5295 METHOD_ENCODING (entries
) =
5296 encode_method_prototype (entries
);
5298 elemlist
= tree_cons (NULL_TREE
,
5299 add_objc_string (METHOD_ENCODING (entries
),
5304 = tree_cons (NULL_TREE
,
5305 convert (ptr_type_node
,
5306 build_unary_op (input_location
, ADDR_EXPR
,
5307 METHOD_DEFINITION (entries
), 1)),
5310 initlist
= tree_cons (NULL_TREE
,
5311 objc_build_constructor (type
, nreverse (elemlist
)),
5314 entries
= TREE_CHAIN (entries
);
5318 return objc_build_constructor (build_array_type (type
, 0),
5319 nreverse (initlist
));
5322 /* To accomplish method prototyping without generating all kinds of
5323 inane warnings, the definition of the dispatch table entries were
5326 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5328 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5331 build_method_template (void)
5334 tree field_decl
, field_decl_chain
;
5336 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
5339 field_decl
= create_field_decl (objc_selector_type
, "_cmd");
5340 field_decl_chain
= field_decl
;
5342 /* char *method_types; */
5343 field_decl
= create_field_decl (string_type_node
, "method_types");
5344 chainon (field_decl_chain
, field_decl
);
5347 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
5349 chainon (field_decl_chain
, field_decl
);
5351 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
5358 generate_dispatch_table (tree type
, const char *name
, int size
, tree list
)
5360 tree decl
, initlist
;
5362 decl
= start_var_decl (type
, synth_id_with_class_suffix
5363 (name
, objc_implementation_context
));
5365 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, 0));
5366 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, size
), initlist
);
5367 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
5369 finish_var_decl (decl
,
5370 objc_build_constructor (TREE_TYPE (decl
),
5371 nreverse (initlist
)));
5377 mark_referenced_methods (void)
5379 struct imp_entry
*impent
;
5382 for (impent
= imp_list
; impent
; impent
= impent
->next
)
5384 chain
= CLASS_CLS_METHODS (impent
->imp_context
);
5387 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
5388 chain
= TREE_CHAIN (chain
);
5391 chain
= CLASS_NST_METHODS (impent
->imp_context
);
5394 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
5395 chain
= TREE_CHAIN (chain
);
5401 generate_dispatch_tables (void)
5403 tree initlist
, chain
, method_list_template
;
5406 if (!objc_method_template
)
5407 objc_method_template
= build_method_template ();
5409 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
5412 size
= list_length (chain
);
5414 method_list_template
5415 = build_method_list_template (objc_method_template
, size
);
5417 = build_dispatch_table_initializer (objc_method_template
, chain
);
5419 UOBJC_CLASS_METHODS_decl
5420 = generate_dispatch_table (method_list_template
,
5421 ((TREE_CODE (objc_implementation_context
)
5422 == CLASS_IMPLEMENTATION_TYPE
)
5423 ? "_OBJC_CLASS_METHODS"
5424 : "_OBJC_CATEGORY_CLASS_METHODS"),
5428 UOBJC_CLASS_METHODS_decl
= 0;
5430 chain
= CLASS_NST_METHODS (objc_implementation_context
);
5433 size
= list_length (chain
);
5435 method_list_template
5436 = build_method_list_template (objc_method_template
, size
);
5438 = build_dispatch_table_initializer (objc_method_template
, chain
);
5440 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
5441 UOBJC_INSTANCE_METHODS_decl
5442 = generate_dispatch_table (method_list_template
,
5443 "_OBJC_INSTANCE_METHODS",
5446 /* We have a category. */
5447 UOBJC_INSTANCE_METHODS_decl
5448 = generate_dispatch_table (method_list_template
,
5449 "_OBJC_CATEGORY_INSTANCE_METHODS",
5453 UOBJC_INSTANCE_METHODS_decl
= 0;
5457 generate_protocol_list (tree i_or_p
)
5460 tree refs_decl
, lproto
, e
, plist
;
5462 const char *ref_name
;
5464 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
5465 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
5466 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
5467 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
5468 plist
= PROTOCOL_LIST (i_or_p
);
5473 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
5474 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
5475 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
5478 /* Build initializer. */
5479 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), NULL_TREE
);
5480 e
= build_int_cst (build_pointer_type (objc_protocol_template
), size
);
5481 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
5483 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
5485 tree pval
= TREE_VALUE (lproto
);
5487 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
5488 && PROTOCOL_FORWARD_DECL (pval
))
5490 e
= build_unary_op (input_location
, ADDR_EXPR
,
5491 PROTOCOL_FORWARD_DECL (pval
), 0);
5492 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
5496 /* static struct objc_protocol *refs[n]; */
5498 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
5499 ref_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p
);
5500 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
5501 ref_name
= synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p
);
5502 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
5503 ref_name
= synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p
);
5507 refs_decl
= start_var_decl
5509 (build_pointer_type (objc_protocol_template
),
5510 build_index_type (build_int_cst (NULL_TREE
, size
+ 2))),
5513 finish_var_decl (refs_decl
, objc_build_constructor (TREE_TYPE (refs_decl
),
5514 nreverse (initlist
)));
5520 build_category_initializer (tree type
, tree cat_name
, tree class_name
,
5521 tree instance_methods
, tree class_methods
,
5524 tree initlist
= NULL_TREE
, expr
;
5526 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
5527 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
5529 if (!instance_methods
)
5530 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5533 expr
= convert (objc_method_list_ptr
,
5534 build_unary_op (input_location
, ADDR_EXPR
,
5535 instance_methods
, 0));
5536 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
5539 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5542 expr
= convert (objc_method_list_ptr
,
5543 build_unary_op (input_location
, ADDR_EXPR
,
5545 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
5548 /* protocol_list = */
5550 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5553 expr
= convert (build_pointer_type
5555 (objc_protocol_template
)),
5556 build_unary_op (input_location
, ADDR_EXPR
,
5558 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
5561 return objc_build_constructor (type
, nreverse (initlist
));
5564 /* struct _objc_class {
5565 struct objc_class *isa;
5566 struct objc_class *super_class;
5571 struct objc_ivar_list *ivars;
5572 struct objc_method_list *methods;
5573 if (flag_next_runtime)
5574 struct objc_cache *cache;
5576 struct sarray *dtable;
5577 struct objc_class *subclass_list;
5578 struct objc_class *sibling_class;
5580 struct objc_protocol_list *protocols;
5581 if (flag_next_runtime)
5583 void *gc_object_type;
5587 build_shared_structure_initializer (tree type
, tree isa
, tree super
,
5588 tree name
, tree size
, int status
,
5589 tree dispatch_table
, tree ivar_list
,
5592 tree initlist
= NULL_TREE
, expr
;
5595 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
5598 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
5601 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
5604 initlist
= tree_cons (NULL_TREE
, build_int_cst (long_integer_type_node
, 0),
5608 initlist
= tree_cons (NULL_TREE
,
5609 build_int_cst (long_integer_type_node
, status
),
5612 /* instance_size = */
5613 initlist
= tree_cons (NULL_TREE
, convert (long_integer_type_node
, size
),
5616 /* objc_ivar_list = */
5618 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5621 expr
= convert (objc_ivar_list_ptr
,
5622 build_unary_op (input_location
, ADDR_EXPR
,
5624 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
5627 /* objc_method_list = */
5628 if (!dispatch_table
)
5629 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5632 expr
= convert (objc_method_list_ptr
,
5633 build_unary_op (input_location
, ADDR_EXPR
,
5634 dispatch_table
, 0));
5635 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
5638 if (flag_next_runtime
)
5639 /* method_cache = */
5640 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5644 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5646 /* subclass_list = */
5647 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5649 /* sibling_class = */
5650 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5653 /* protocol_list = */
5654 if (! protocol_list
)
5655 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5658 expr
= convert (build_pointer_type
5660 (objc_protocol_template
)),
5661 build_unary_op (input_location
, ADDR_EXPR
,
5663 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
5666 if (flag_next_runtime
)
5668 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5670 /* gc_object_type = NULL */
5671 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5673 return objc_build_constructor (type
, nreverse (initlist
));
5676 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5679 lookup_category (tree klass
, tree cat_name
)
5681 tree category
= CLASS_CATEGORY_LIST (klass
);
5683 while (category
&& CLASS_SUPER_NAME (category
) != cat_name
)
5684 category
= CLASS_CATEGORY_LIST (category
);
5688 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5691 generate_category (tree cat
)
5694 tree initlist
, cat_name_expr
, class_name_expr
;
5695 tree protocol_decl
, category
;
5697 add_class_reference (CLASS_NAME (cat
));
5698 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
5700 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
5702 category
= lookup_category (implementation_template
,
5703 CLASS_SUPER_NAME (cat
));
5705 if (category
&& CLASS_PROTOCOL_LIST (category
))
5707 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
5708 protocol_decl
= generate_protocol_list (category
);
5713 decl
= start_var_decl (objc_category_template
,
5714 synth_id_with_class_suffix
5715 ("_OBJC_CATEGORY", objc_implementation_context
));
5717 initlist
= build_category_initializer (TREE_TYPE (decl
),
5718 cat_name_expr
, class_name_expr
,
5719 UOBJC_INSTANCE_METHODS_decl
,
5720 UOBJC_CLASS_METHODS_decl
,
5723 finish_var_decl (decl
, initlist
);
5726 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5727 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5730 generate_shared_structures (int cls_flags
)
5732 tree sc_spec
, decl_specs
, decl
;
5733 tree name_expr
, super_expr
, root_expr
;
5734 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
5735 tree cast_type
, initlist
, protocol_decl
;
5737 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
5740 add_class_reference (my_super_id
);
5742 /* Compute "my_root_id" - this is required for code generation.
5743 the "isa" for all meta class structures points to the root of
5744 the inheritance hierarchy (e.g. "__Object")... */
5745 my_root_id
= my_super_id
;
5748 tree my_root_int
= lookup_interface (my_root_id
);
5750 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
5751 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
5758 /* No super class. */
5759 my_root_id
= CLASS_NAME (implementation_template
);
5761 cast_type
= build_pointer_type (objc_class_template
);
5762 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
5765 /* Install class `isa' and `super' pointers at runtime. */
5768 super_expr
= add_objc_string (my_super_id
, class_names
);
5769 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
5772 super_expr
= build_int_cst (NULL_TREE
, 0);
5774 root_expr
= add_objc_string (my_root_id
, class_names
);
5775 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
5777 if (CLASS_PROTOCOL_LIST (implementation_template
))
5779 generate_protocol_references
5780 (CLASS_PROTOCOL_LIST (implementation_template
));
5781 protocol_decl
= generate_protocol_list (implementation_template
);
5786 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5788 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
5789 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
5791 decl
= start_var_decl (objc_class_template
,
5793 (DECL_NAME (UOBJC_METACLASS_decl
)));
5796 = build_shared_structure_initializer
5798 root_expr
, super_expr
, name_expr
,
5799 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
5801 UOBJC_CLASS_METHODS_decl
,
5802 UOBJC_CLASS_VARIABLES_decl
,
5805 finish_var_decl (decl
, initlist
);
5807 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5809 decl
= start_var_decl (objc_class_template
,
5811 (DECL_NAME (UOBJC_CLASS_decl
)));
5814 = build_shared_structure_initializer
5816 build_unary_op (input_location
, ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
5817 super_expr
, name_expr
,
5818 convert (integer_type_node
,
5819 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5820 (implementation_template
))),
5821 1 /*CLS_FACTORY*/ | cls_flags
,
5822 UOBJC_INSTANCE_METHODS_decl
,
5823 UOBJC_INSTANCE_VARIABLES_decl
,
5826 finish_var_decl (decl
, initlist
);
5831 synth_id_with_class_suffix (const char *preamble
, tree ctxt
)
5833 static char string
[BUFSIZE
];
5835 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
5836 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
5838 sprintf (string
, "%s_%s", preamble
,
5839 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
5841 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
5842 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
5844 /* We have a category. */
5845 const char *const class_name
5846 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
5847 const char *const class_super_name
5848 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
5849 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
5851 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
5853 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
5854 sprintf (string
, "%s_%s", preamble
, protocol_name
);
5862 /* If type is empty or only type qualifiers are present, add default
5863 type of id (otherwise grokdeclarator will default to int). */
5866 adjust_type_for_id_default (tree type
)
5869 type
= make_node (TREE_LIST
);
5871 if (!TREE_VALUE (type
))
5872 TREE_VALUE (type
) = objc_object_type
;
5873 else if (TREE_CODE (TREE_VALUE (type
)) == RECORD_TYPE
5874 && TYPED_OBJECT (TREE_VALUE (type
)))
5875 error ("can not use an object as parameter to a method");
5882 selector ':' '(' typename ')' identifier
5885 Transform an Objective-C keyword argument into
5886 the C equivalent parameter declarator.
5888 In: key_name, an "identifier_node" (optional).
5889 arg_type, a "tree_list" (optional).
5890 arg_name, an "identifier_node".
5892 Note: It would be really nice to strongly type the preceding
5893 arguments in the function prototype; however, then I
5894 could not use the "accessor" macros defined in "tree.h".
5896 Out: an instance of "keyword_decl". */
5899 objc_build_keyword_decl (tree key_name
, tree arg_type
, tree arg_name
)
5903 /* If no type is specified, default to "id". */
5904 arg_type
= adjust_type_for_id_default (arg_type
);
5906 keyword_decl
= make_node (KEYWORD_DECL
);
5908 TREE_TYPE (keyword_decl
) = arg_type
;
5909 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
5910 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
5912 return keyword_decl
;
5915 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5918 build_keyword_selector (tree selector
)
5921 tree key_chain
, key_name
;
5924 /* Scan the selector to see how much space we'll need. */
5925 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
5927 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5928 key_name
= KEYWORD_KEY_NAME (key_chain
);
5929 else if (TREE_CODE (selector
) == TREE_LIST
)
5930 key_name
= TREE_PURPOSE (key_chain
);
5935 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
5937 /* Just a ':' arg. */
5941 buf
= (char *) alloca (len
+ 1);
5942 /* Start the buffer out as an empty string. */
5945 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
5947 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5948 key_name
= KEYWORD_KEY_NAME (key_chain
);
5949 else if (TREE_CODE (selector
) == TREE_LIST
)
5951 key_name
= TREE_PURPOSE (key_chain
);
5952 /* The keyword decl chain will later be used as a function argument
5953 chain. Unhook the selector itself so as to not confuse other
5954 parts of the compiler. */
5955 TREE_PURPOSE (key_chain
) = NULL_TREE
;
5961 strcat (buf
, IDENTIFIER_POINTER (key_name
));
5965 return get_identifier (buf
);
5968 /* Used for declarations and definitions. */
5971 build_method_decl (enum tree_code code
, tree ret_type
, tree selector
,
5972 tree add_args
, bool ellipsis
)
5976 /* If no type is specified, default to "id". */
5977 ret_type
= adjust_type_for_id_default (ret_type
);
5979 method_decl
= make_node (code
);
5980 TREE_TYPE (method_decl
) = ret_type
;
5982 /* If we have a keyword selector, create an identifier_node that
5983 represents the full selector name (`:' included)... */
5984 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5986 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
5987 METHOD_SEL_ARGS (method_decl
) = selector
;
5988 METHOD_ADD_ARGS (method_decl
) = add_args
;
5989 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl
) = ellipsis
;
5993 METHOD_SEL_NAME (method_decl
) = selector
;
5994 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
5995 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
6001 #define METHOD_DEF 0
6002 #define METHOD_REF 1
6004 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6005 an argument list for method METH. CONTEXT is either METHOD_DEF or
6006 METHOD_REF, saying whether we are trying to define a method or call
6007 one. SUPERFLAG says this is for a send to super; this makes a
6008 difference for the NeXT calling sequence in which the lookup and
6009 the method call are done together. If METH is null, user-defined
6010 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6013 get_arg_type_list (tree meth
, int context
, int superflag
)
6017 /* Receiver type. */
6018 if (flag_next_runtime
&& superflag
)
6019 arglist
= build_tree_list (NULL_TREE
, objc_super_type
);
6020 else if (context
== METHOD_DEF
&& TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
6021 arglist
= build_tree_list (NULL_TREE
, objc_instance_type
);
6023 arglist
= build_tree_list (NULL_TREE
, objc_object_type
);
6025 /* Selector type - will eventually change to `int'. */
6026 chainon (arglist
, build_tree_list (NULL_TREE
, objc_selector_type
));
6028 /* No actual method prototype given -- assume that remaining arguments
6033 /* Build a list of argument types. */
6034 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
6036 tree arg_type
= TREE_VALUE (TREE_TYPE (akey
));
6038 /* Decay arrays and functions into pointers. */
6039 if (TREE_CODE (arg_type
) == ARRAY_TYPE
)
6040 arg_type
= build_pointer_type (TREE_TYPE (arg_type
));
6041 else if (TREE_CODE (arg_type
) == FUNCTION_TYPE
)
6042 arg_type
= build_pointer_type (arg_type
);
6044 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
6047 if (METHOD_ADD_ARGS (meth
))
6049 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
6050 akey
; akey
= TREE_CHAIN (akey
))
6052 tree arg_type
= TREE_TYPE (TREE_VALUE (akey
));
6054 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
6057 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth
))
6058 goto lack_of_ellipsis
;
6063 chainon (arglist
, OBJC_VOID_AT_END
);
6070 check_duplicates (hash hsh
, int methods
, int is_class
)
6072 tree meth
= NULL_TREE
;
6080 /* We have two or more methods with the same name but
6084 /* But just how different are those types? If
6085 -Wno-strict-selector-match is specified, we shall not
6086 complain if the differences are solely among types with
6087 identical size and alignment. */
6088 if (!warn_strict_selector_match
)
6090 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
6091 if (!comp_proto_with_proto (meth
, loop
->value
, 0))
6098 warning (0, "multiple %s named %<%c%s%> found",
6099 methods
? "methods" : "selectors",
6100 (is_class
? '+' : '-'),
6101 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
6103 warn_with_method (methods
? "using" : "found",
6104 ((TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
6108 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
6109 warn_with_method ("also found",
6110 ((TREE_CODE (loop
->value
) == INSTANCE_METHOD_DECL
)
6119 /* If RECEIVER is a class reference, return the identifier node for
6120 the referenced class. RECEIVER is created by objc_get_class_reference,
6121 so we check the exact form created depending on which runtimes are
6125 receiver_is_class_object (tree receiver
, int self
, int super
)
6127 tree chain
, exp
, arg
;
6129 /* The receiver is 'self' or 'super' in the context of a class method. */
6130 if (objc_method_context
6131 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
6134 ? CLASS_SUPER_NAME (implementation_template
)
6135 : CLASS_NAME (implementation_template
));
6137 if (flag_next_runtime
)
6139 /* The receiver is a variable created by
6140 build_class_reference_decl. */
6141 if (TREE_CODE (receiver
) == VAR_DECL
&& IS_CLASS (TREE_TYPE (receiver
)))
6142 /* Look up the identifier. */
6143 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
6144 if (TREE_PURPOSE (chain
) == receiver
)
6145 return TREE_VALUE (chain
);
6148 /* The receiver is a function call that returns an id. Check if
6149 it is a call to objc_getClass, if so, pick up the class name. */
6150 if (TREE_CODE (receiver
) == CALL_EXPR
6151 && (exp
= CALL_EXPR_FN (receiver
))
6152 && TREE_CODE (exp
) == ADDR_EXPR
6153 && (exp
= TREE_OPERAND (exp
, 0))
6154 && TREE_CODE (exp
) == FUNCTION_DECL
6155 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6156 prototypes for objc_get_class(). Thankfully, they seem to share the
6157 same function type. */
6158 && TREE_TYPE (exp
) == TREE_TYPE (objc_get_class_decl
)
6159 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp
)), TAG_GETCLASS
)
6160 /* We have a call to objc_get_class/objc_getClass! */
6161 && (arg
= CALL_EXPR_ARG (receiver
, 0)))
6164 if (TREE_CODE (arg
) == ADDR_EXPR
6165 && (arg
= TREE_OPERAND (arg
, 0))
6166 && TREE_CODE (arg
) == STRING_CST
)
6167 /* Finally, we have the class name. */
6168 return get_identifier (TREE_STRING_POINTER (arg
));
6173 /* If we are currently building a message expr, this holds
6174 the identifier of the selector of the message. This is
6175 used when printing warnings about argument mismatches. */
6177 static tree current_objc_message_selector
= 0;
6180 objc_message_selector (void)
6182 return current_objc_message_selector
;
6185 /* Construct an expression for sending a message.
6186 MESS has the object to send to in TREE_PURPOSE
6187 and the argument list (including selector) in TREE_VALUE.
6189 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6190 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6193 objc_build_message_expr (tree mess
)
6195 tree receiver
= TREE_PURPOSE (mess
);
6198 tree args
= TREE_PURPOSE (TREE_VALUE (mess
));
6200 tree args
= TREE_VALUE (mess
);
6202 tree method_params
= NULL_TREE
;
6204 if (TREE_CODE (receiver
) == ERROR_MARK
)
6205 return error_mark_node
;
6207 /* Obtain the full selector name. */
6208 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
6209 /* A unary selector. */
6211 else if (TREE_CODE (args
) == TREE_LIST
)
6212 sel_name
= build_keyword_selector (args
);
6216 /* Build the parameter list to give to the method. */
6217 if (TREE_CODE (args
) == TREE_LIST
)
6219 method_params
= chainon (args
, TREE_VALUE (TREE_VALUE (mess
)));
6222 tree chain
= args
, prev
= NULL_TREE
;
6224 /* We have a keyword selector--check for comma expressions. */
6227 tree element
= TREE_VALUE (chain
);
6229 /* We have a comma expression, must collapse... */
6230 if (TREE_CODE (element
) == TREE_LIST
)
6233 TREE_CHAIN (prev
) = element
;
6238 chain
= TREE_CHAIN (chain
);
6240 method_params
= args
;
6245 if (processing_template_decl
)
6246 /* Must wait until template instantiation time. */
6247 return build_min_nt (MESSAGE_SEND_EXPR
, receiver
, sel_name
,
6251 return objc_finish_message_expr (receiver
, sel_name
, method_params
);
6254 /* Look up method SEL_NAME that would be suitable for receiver
6255 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6256 nonzero), and report on any duplicates. */
6259 lookup_method_in_hash_lists (tree sel_name
, int is_class
)
6261 hash method_prototype
= NULL
;
6264 method_prototype
= hash_lookup (nst_method_hash_list
,
6267 if (!method_prototype
)
6269 method_prototype
= hash_lookup (cls_method_hash_list
,
6274 return check_duplicates (method_prototype
, 1, is_class
);
6277 /* The 'objc_finish_message_expr' routine is called from within
6278 'objc_build_message_expr' for non-template functions. In the case of
6279 C++ template functions, it is called from 'build_expr_from_tree'
6280 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6283 objc_finish_message_expr (tree receiver
, tree sel_name
, tree method_params
)
6285 tree method_prototype
= NULL_TREE
, rprotos
= NULL_TREE
, rtype
;
6286 tree selector
, retval
, class_tree
;
6287 int self
, super
, have_cast
;
6289 /* Extract the receiver of the message, as well as its type
6290 (where the latter may take the form of a cast or be inferred
6291 from the implementation context). */
6293 while (TREE_CODE (rtype
) == COMPOUND_EXPR
6294 || TREE_CODE (rtype
) == MODIFY_EXPR
6295 || CONVERT_EXPR_P (rtype
)
6296 || TREE_CODE (rtype
) == COMPONENT_REF
)
6297 rtype
= TREE_OPERAND (rtype
, 0);
6298 self
= (rtype
== self_decl
);
6299 super
= (rtype
== UOBJC_SUPER_decl
);
6300 rtype
= TREE_TYPE (receiver
);
6301 have_cast
= (TREE_CODE (receiver
) == NOP_EXPR
6302 || (TREE_CODE (receiver
) == COMPOUND_EXPR
6303 && !IS_SUPER (rtype
)));
6305 /* If we are calling [super dealloc], reset our warning flag. */
6306 if (super
&& !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name
)))
6307 should_call_super_dealloc
= 0;
6309 /* If the receiver is a class object, retrieve the corresponding
6310 @interface, if one exists. */
6311 class_tree
= receiver_is_class_object (receiver
, self
, super
);
6313 /* Now determine the receiver type (if an explicit cast has not been
6318 rtype
= lookup_interface (class_tree
);
6319 /* Handle `self' and `super'. */
6322 if (!CLASS_SUPER_NAME (implementation_template
))
6324 error ("no super class declared in @interface for %qs",
6325 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
6326 return error_mark_node
;
6328 rtype
= lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6331 rtype
= lookup_interface (CLASS_NAME (implementation_template
));
6334 /* If receiver is of type `id' or `Class' (or if the @interface for a
6335 class is not visible), we shall be satisfied with the existence of
6336 any instance or class method. */
6337 if (objc_is_id (rtype
))
6339 class_tree
= (IS_CLASS (rtype
) ? objc_class_name
: NULL_TREE
);
6340 rprotos
= (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype
))
6341 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype
))
6347 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6348 in protocols themselves for the method prototype. */
6350 = lookup_method_in_protocol_list (rprotos
, sel_name
,
6351 class_tree
!= NULL_TREE
);
6353 /* If messaging 'Class <Proto>' but did not find a class method
6354 prototype, search for an instance method instead, and warn
6355 about having done so. */
6356 if (!method_prototype
&& !rtype
&& class_tree
!= NULL_TREE
)
6359 = lookup_method_in_protocol_list (rprotos
, sel_name
, 0);
6361 if (method_prototype
)
6362 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6363 IDENTIFIER_POINTER (sel_name
),
6364 IDENTIFIER_POINTER (sel_name
));
6370 tree orig_rtype
= rtype
, saved_rtype
;
6372 if (TREE_CODE (rtype
) == POINTER_TYPE
)
6373 rtype
= TREE_TYPE (rtype
);
6374 /* Traverse typedef aliases */
6375 while (TREE_CODE (rtype
) == RECORD_TYPE
&& OBJC_TYPE_NAME (rtype
)
6376 && TREE_CODE (OBJC_TYPE_NAME (rtype
)) == TYPE_DECL
6377 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
)))
6378 rtype
= DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
));
6379 saved_rtype
= rtype
;
6380 if (TYPED_OBJECT (rtype
))
6382 rprotos
= TYPE_OBJC_PROTOCOL_LIST (rtype
);
6383 rtype
= TYPE_OBJC_INTERFACE (rtype
);
6385 /* If we could not find an @interface declaration, we must have
6386 only seen a @class declaration; so, we cannot say anything
6387 more intelligent about which methods the receiver will
6389 if (!rtype
|| TREE_CODE (rtype
) == IDENTIFIER_NODE
)
6391 else if (TREE_CODE (rtype
) == CLASS_INTERFACE_TYPE
6392 || TREE_CODE (rtype
) == CLASS_IMPLEMENTATION_TYPE
)
6394 /* We have a valid ObjC class name. Look up the method name
6395 in the published @interface for the class (and its
6398 = lookup_method_static (rtype
, sel_name
, class_tree
!= NULL_TREE
);
6400 /* If the method was not found in the @interface, it may still
6401 exist locally as part of the @implementation. */
6402 if (!method_prototype
&& objc_implementation_context
6403 && CLASS_NAME (objc_implementation_context
)
6404 == OBJC_TYPE_NAME (rtype
))
6408 ? CLASS_CLS_METHODS (objc_implementation_context
)
6409 : CLASS_NST_METHODS (objc_implementation_context
)),
6412 /* If we haven't found a candidate method by now, try looking for
6413 it in the protocol list. */
6414 if (!method_prototype
&& rprotos
)
6416 = lookup_method_in_protocol_list (rprotos
, sel_name
,
6417 class_tree
!= NULL_TREE
);
6421 warning (0, "invalid receiver type %qs",
6422 gen_type_name (orig_rtype
));
6423 /* After issuing the "invalid receiver" warning, perform method
6424 lookup as if we were messaging 'id'. */
6425 rtype
= rprotos
= NULL_TREE
;
6430 /* For 'id' or 'Class' receivers, search in the global hash table
6431 as a last resort. For all receivers, warn if protocol searches
6433 if (!method_prototype
)
6436 warning (0, "%<%c%s%> not found in protocol(s)",
6437 (class_tree
? '+' : '-'),
6438 IDENTIFIER_POINTER (sel_name
));
6442 = lookup_method_in_hash_lists (sel_name
, class_tree
!= NULL_TREE
);
6445 if (!method_prototype
)
6447 static bool warn_missing_methods
= false;
6450 warning (0, "%qs may not respond to %<%c%s%>",
6451 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype
)),
6452 (class_tree
? '+' : '-'),
6453 IDENTIFIER_POINTER (sel_name
));
6454 /* If we are messaging an 'id' or 'Class' object and made it here,
6455 then we have failed to find _any_ instance or class method,
6458 warning (0, "no %<%c%s%> method found",
6459 (class_tree
? '+' : '-'),
6460 IDENTIFIER_POINTER (sel_name
));
6462 if (!warn_missing_methods
)
6464 warning (0, "(Messages without a matching method signature");
6465 warning (0, "will be assumed to return %<id%> and accept");
6466 warning (0, "%<...%> as arguments.)");
6467 warn_missing_methods
= true;
6471 /* Save the selector name for printing error messages. */
6472 current_objc_message_selector
= sel_name
;
6474 /* Build the parameters list for looking up the method.
6475 These are the object itself and the selector. */
6477 if (flag_typed_selectors
)
6478 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
6480 selector
= build_selector_reference (sel_name
);
6482 retval
= build_objc_method_call (super
, method_prototype
,
6484 selector
, method_params
);
6486 current_objc_message_selector
= 0;
6491 /* Build a tree expression to send OBJECT the operation SELECTOR,
6492 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6493 assuming the method has prototype METHOD_PROTOTYPE.
6494 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6495 Use METHOD_PARAMS as list of args to pass to the method.
6496 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6499 build_objc_method_call (int super_flag
, tree method_prototype
,
6500 tree lookup_object
, tree selector
,
6503 tree sender
= (super_flag
? umsg_super_decl
:
6504 (!flag_next_runtime
|| flag_nil_receivers
6505 ? (flag_objc_direct_dispatch
6508 : umsg_nonnil_decl
));
6509 tree rcv_p
= (super_flag
? objc_super_type
: objc_object_type
);
6511 /* If a prototype for the method to be called exists, then cast
6512 the sender's return type and arguments to match that of the method.
6513 Otherwise, leave sender as is. */
6516 ? TREE_VALUE (TREE_TYPE (method_prototype
))
6517 : objc_object_type
);
6519 = build_pointer_type
6520 (build_function_type
6523 (method_prototype
, METHOD_REF
, super_flag
)));
6526 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
6528 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6529 lookup_object
= save_expr (lookup_object
);
6531 if (flag_next_runtime
)
6533 /* If we are returning a struct in memory, and the address
6534 of that memory location is passed as a hidden first
6535 argument, then change which messenger entry point this
6536 expr will call. NB: Note that sender_cast remains
6537 unchanged (it already has a struct return type). */
6538 if (!targetm
.calls
.struct_value_rtx (0, 0)
6539 && (TREE_CODE (ret_type
) == RECORD_TYPE
6540 || TREE_CODE (ret_type
) == UNION_TYPE
)
6541 && targetm
.calls
.return_in_memory (ret_type
, 0))
6542 sender
= (super_flag
? umsg_super_stret_decl
:
6543 flag_nil_receivers
? umsg_stret_decl
: umsg_nonnil_stret_decl
);
6545 method_params
= tree_cons (NULL_TREE
, lookup_object
,
6546 tree_cons (NULL_TREE
, selector
,
6548 method
= build_fold_addr_expr (sender
);
6552 /* This is the portable (GNU) way. */
6555 /* First, call the lookup function to get a pointer to the method,
6556 then cast the pointer, then call it with the method arguments. */
6558 object
= (super_flag
? self_decl
: lookup_object
);
6560 t
= tree_cons (NULL_TREE
, selector
, NULL_TREE
);
6561 t
= tree_cons (NULL_TREE
, lookup_object
, t
);
6562 method
= build_function_call (sender
, t
);
6564 /* Pass the object to the method. */
6565 method_params
= tree_cons (NULL_TREE
, object
,
6566 tree_cons (NULL_TREE
, selector
,
6570 /* ??? Selector is not at this point something we can use inside
6571 the compiler itself. Set it to garbage for the nonce. */
6572 t
= build3 (OBJ_TYPE_REF
, sender_cast
, method
, lookup_object
, size_zero_node
);
6573 return build_function_call (t
, method_params
);
6577 build_protocol_reference (tree p
)
6580 const char *proto_name
;
6582 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6584 proto_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
6585 decl
= start_var_decl (objc_protocol_template
, proto_name
);
6587 PROTOCOL_FORWARD_DECL (p
) = decl
;
6590 /* This function is called by the parser when (and only when) a
6591 @protocol() expression is found, in order to compile it. */
6593 objc_build_protocol_expr (tree protoname
)
6596 tree p
= lookup_protocol (protoname
);
6600 error ("cannot find protocol declaration for %qs",
6601 IDENTIFIER_POINTER (protoname
));
6602 return error_mark_node
;
6605 if (!PROTOCOL_FORWARD_DECL (p
))
6606 build_protocol_reference (p
);
6608 expr
= build_unary_op (input_location
,
6609 ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
6611 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6612 if we have it, rather than converting it here. */
6613 expr
= convert (objc_protocol_type
, expr
);
6615 /* The @protocol() expression is being compiled into a pointer to a
6616 statically allocated instance of the Protocol class. To become
6617 usable at runtime, the 'isa' pointer of the instance need to be
6618 fixed up at runtime by the runtime library, to point to the
6619 actual 'Protocol' class. */
6621 /* For the GNU runtime, put the static Protocol instance in the list
6622 of statically allocated instances, so that we make sure that its
6623 'isa' pointer is fixed up at runtime by the GNU runtime library
6624 to point to the Protocol class (at runtime, when loading the
6625 module, the GNU runtime library loops on the statically allocated
6626 instances (as found in the defs field in objc_symtab) and fixups
6627 all the 'isa' pointers of those objects). */
6628 if (! flag_next_runtime
)
6630 /* This type is a struct containing the fields of a Protocol
6631 object. (Cfr. objc_protocol_type instead is the type of a pointer
6632 to such a struct). */
6633 tree protocol_struct_type
= xref_tag
6634 (RECORD_TYPE
, get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
6637 /* Look for the list of Protocol statically allocated instances
6638 to fixup at runtime. Create a new list to hold Protocol
6639 statically allocated instances, if the list is not found. At
6640 present there is only another list, holding NSConstantString
6641 static instances to be fixed up at runtime. */
6642 for (chain
= &objc_static_instances
;
6643 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
6644 chain
= &TREE_CHAIN (*chain
));
6647 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
6648 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type
),
6652 /* Add this statically allocated instance to the Protocol list. */
6653 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
6654 PROTOCOL_FORWARD_DECL (p
),
6655 TREE_PURPOSE (*chain
));
6662 /* This function is called by the parser when a @selector() expression
6663 is found, in order to compile it. It is only called by the parser
6664 and only to compile a @selector(). */
6666 objc_build_selector_expr (tree selnamelist
)
6670 /* Obtain the full selector name. */
6671 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
6672 /* A unary selector. */
6673 selname
= selnamelist
;
6674 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
6675 selname
= build_keyword_selector (selnamelist
);
6679 /* If we are required to check @selector() expressions as they
6680 are found, check that the selector has been declared. */
6681 if (warn_undeclared_selector
)
6683 /* Look the selector up in the list of all known class and
6684 instance methods (up to this line) to check that the selector
6688 /* First try with instance methods. */
6689 hsh
= hash_lookup (nst_method_hash_list
, selname
);
6691 /* If not found, try with class methods. */
6694 hsh
= hash_lookup (cls_method_hash_list
, selname
);
6697 /* If still not found, print out a warning. */
6700 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname
));
6705 if (flag_typed_selectors
)
6706 return build_typed_selector_reference (selname
, 0);
6708 return build_selector_reference (selname
);
6712 objc_build_encode_expr (tree type
)
6717 encode_type (type
, obstack_object_size (&util_obstack
),
6718 OBJC_ENCODE_INLINE_DEFS
);
6719 obstack_1grow (&util_obstack
, 0); /* null terminate string */
6720 string
= XOBFINISH (&util_obstack
, const char *);
6722 /* Synthesize a string that represents the encoded struct/union. */
6723 result
= my_build_string (strlen (string
) + 1, string
);
6724 obstack_free (&util_obstack
, util_firstobj
);
6729 build_ivar_reference (tree id
)
6731 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
6733 /* Historically, a class method that produced objects (factory
6734 method) would assign `self' to the instance that it
6735 allocated. This would effectively turn the class method into
6736 an instance method. Following this assignment, the instance
6737 variables could be accessed. That practice, while safe,
6738 violates the simple rule that a class method should not refer
6739 to an instance variable. It's better to catch the cases
6740 where this is done unknowingly than to support the above
6742 warning (0, "instance variable %qs accessed in class method",
6743 IDENTIFIER_POINTER (id
));
6744 self_decl
= convert (objc_instance_type
, self_decl
); /* cast */
6747 return objc_build_component_ref (build_indirect_ref (input_location
,
6748 self_decl
, "->"), id
);
6751 /* Compute a hash value for a given method SEL_NAME. */
6754 hash_func (tree sel_name
)
6756 const unsigned char *s
6757 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
6761 h
= h
* 67 + *s
++ - 113;
6768 nst_method_hash_list
6769 = (hash
*) ggc_alloc_cleared (SIZEHASHTABLE
* sizeof (hash
));
6770 cls_method_hash_list
6771 = (hash
*) ggc_alloc_cleared (SIZEHASHTABLE
* sizeof (hash
));
6773 /* Initialize the hash table used to hold the constant string objects. */
6774 string_htab
= htab_create_ggc (31, string_hash
,
6777 /* Initialize the hash table used to hold EH-volatilized types. */
6778 volatilized_htab
= htab_create_ggc (31, volatilized_hash
,
6779 volatilized_eq
, NULL
);
6782 /* WARNING!!!! hash_enter is called with a method, and will peek
6783 inside to find its selector! But hash_lookup is given a selector
6784 directly, and looks for the selector that's inside the found
6785 entry's key (method) for comparison. */
6788 hash_enter (hash
*hashlist
, tree method
)
6791 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
6793 obj
= (hash
) ggc_alloc (sizeof (struct hashed_entry
));
6795 obj
->next
= hashlist
[slot
];
6798 hashlist
[slot
] = obj
; /* append to front */
6802 hash_lookup (hash
*hashlist
, tree sel_name
)
6806 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
6810 if (sel_name
== METHOD_SEL_NAME (target
->key
))
6813 target
= target
->next
;
6819 hash_add_attr (hash entry
, tree value
)
6823 obj
= (attr
) ggc_alloc (sizeof (struct hashed_attribute
));
6824 obj
->next
= entry
->list
;
6827 entry
->list
= obj
; /* append to front */
6831 lookup_method (tree mchain
, tree method
)
6835 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
6838 key
= METHOD_SEL_NAME (method
);
6842 if (METHOD_SEL_NAME (mchain
) == key
)
6845 mchain
= TREE_CHAIN (mchain
);
6850 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6851 in INTERFACE, along with any categories and protocols attached thereto.
6852 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6853 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6854 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6855 be found in INTERFACE or any of its superclasses, look for an _instance_
6856 method of the same name in the root class as a last resort.
6858 If a suitable method cannot be found, return NULL_TREE. */
6861 lookup_method_static (tree interface
, tree ident
, int flags
)
6863 tree meth
= NULL_TREE
, root_inter
= NULL_TREE
;
6864 tree inter
= interface
;
6865 int is_class
= (flags
& OBJC_LOOKUP_CLASS
);
6866 int no_superclasses
= (flags
& OBJC_LOOKUP_NO_SUPER
);
6870 tree chain
= is_class
? CLASS_CLS_METHODS (inter
) : CLASS_NST_METHODS (inter
);
6871 tree category
= inter
;
6873 /* First, look up the method in the class itself. */
6874 if ((meth
= lookup_method (chain
, ident
)))
6877 /* Failing that, look for the method in each category of the class. */
6878 while ((category
= CLASS_CATEGORY_LIST (category
)))
6880 chain
= is_class
? CLASS_CLS_METHODS (category
) : CLASS_NST_METHODS (category
);
6882 /* Check directly in each category. */
6883 if ((meth
= lookup_method (chain
, ident
)))
6886 /* Failing that, check in each category's protocols. */
6887 if (CLASS_PROTOCOL_LIST (category
))
6889 if ((meth
= (lookup_method_in_protocol_list
6890 (CLASS_PROTOCOL_LIST (category
), ident
, is_class
))))
6895 /* If not found in categories, check in protocols of the main class. */
6896 if (CLASS_PROTOCOL_LIST (inter
))
6898 if ((meth
= (lookup_method_in_protocol_list
6899 (CLASS_PROTOCOL_LIST (inter
), ident
, is_class
))))
6903 /* If we were instructed not to look in superclasses, don't. */
6904 if (no_superclasses
)
6907 /* Failing that, climb up the inheritance hierarchy. */
6909 inter
= lookup_interface (CLASS_SUPER_NAME (inter
));
6913 /* If no class (factory) method was found, check if an _instance_
6914 method of the same name exists in the root class. This is what
6915 the Objective-C runtime will do. If an instance method was not
6917 return is_class
? lookup_method_static (root_inter
, ident
, 0): NULL_TREE
;
6920 /* Add the method to the hash list if it doesn't contain an identical
6924 add_method_to_hash_list (hash
*hash_list
, tree method
)
6928 if (!(hsh
= hash_lookup (hash_list
, METHOD_SEL_NAME (method
))))
6930 /* Install on a global chain. */
6931 hash_enter (hash_list
, method
);
6935 /* Check types against those; if different, add to a list. */
6937 int already_there
= comp_proto_with_proto (method
, hsh
->key
, 1);
6938 for (loop
= hsh
->list
; !already_there
&& loop
; loop
= loop
->next
)
6939 already_there
|= comp_proto_with_proto (method
, loop
->value
, 1);
6941 hash_add_attr (hsh
, method
);
6946 objc_add_method (tree klass
, tree method
, int is_class
)
6950 if (!(mth
= lookup_method (is_class
6951 ? CLASS_CLS_METHODS (klass
)
6952 : CLASS_NST_METHODS (klass
), method
)))
6954 /* put method on list in reverse order */
6957 TREE_CHAIN (method
) = CLASS_CLS_METHODS (klass
);
6958 CLASS_CLS_METHODS (klass
) = method
;
6962 TREE_CHAIN (method
) = CLASS_NST_METHODS (klass
);
6963 CLASS_NST_METHODS (klass
) = method
;
6968 /* When processing an @interface for a class or category, give hard
6969 errors on methods with identical selectors but differing argument
6970 and/or return types. We do not do this for @implementations, because
6971 C/C++ will do it for us (i.e., there will be duplicate function
6972 definition errors). */
6973 if ((TREE_CODE (klass
) == CLASS_INTERFACE_TYPE
6974 || TREE_CODE (klass
) == CATEGORY_INTERFACE_TYPE
)
6975 && !comp_proto_with_proto (method
, mth
, 1))
6976 error ("duplicate declaration of method %<%c%s%>",
6977 is_class
? '+' : '-',
6978 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
6982 add_method_to_hash_list (cls_method_hash_list
, method
);
6985 add_method_to_hash_list (nst_method_hash_list
, method
);
6987 /* Instance methods in root classes (and categories thereof)
6988 may act as class methods as a last resort. We also add
6989 instance methods listed in @protocol declarations to
6990 the class hash table, on the assumption that @protocols
6991 may be adopted by root classes or categories. */
6992 if (TREE_CODE (klass
) == CATEGORY_INTERFACE_TYPE
6993 || TREE_CODE (klass
) == CATEGORY_IMPLEMENTATION_TYPE
)
6994 klass
= lookup_interface (CLASS_NAME (klass
));
6996 if (TREE_CODE (klass
) == PROTOCOL_INTERFACE_TYPE
6997 || !CLASS_SUPER_NAME (klass
))
6998 add_method_to_hash_list (cls_method_hash_list
, method
);
7005 add_class (tree class_name
, tree name
)
7007 struct interface_tuple
**slot
;
7009 /* Put interfaces on list in reverse order. */
7010 TREE_CHAIN (class_name
) = interface_chain
;
7011 interface_chain
= class_name
;
7013 if (interface_htab
== NULL
)
7014 interface_htab
= htab_create_ggc (31, hash_interface
, eq_interface
, NULL
);
7015 slot
= (struct interface_tuple
**)
7016 htab_find_slot_with_hash (interface_htab
, name
,
7017 IDENTIFIER_HASH_VALUE (name
),
7021 *slot
= (struct interface_tuple
*) ggc_alloc_cleared (sizeof (struct interface_tuple
));
7024 (*slot
)->class_name
= class_name
;
7026 return interface_chain
;
7030 add_category (tree klass
, tree category
)
7032 /* Put categories on list in reverse order. */
7033 tree cat
= lookup_category (klass
, CLASS_SUPER_NAME (category
));
7037 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7038 IDENTIFIER_POINTER (CLASS_NAME (klass
)),
7039 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
7043 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (klass
);
7044 CLASS_CATEGORY_LIST (klass
) = category
;
7048 /* Called after parsing each instance variable declaration. Necessary to
7049 preserve typedefs and implement public/private...
7051 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7054 add_instance_variable (tree klass
, int visibility
, tree field_decl
)
7056 tree field_type
= TREE_TYPE (field_decl
);
7057 const char *ivar_name
= DECL_NAME (field_decl
)
7058 ? IDENTIFIER_POINTER (DECL_NAME (field_decl
))
7062 if (TREE_CODE (field_type
) == REFERENCE_TYPE
)
7064 error ("illegal reference type specified for instance variable %qs",
7066 /* Return class as is without adding this ivar. */
7071 if (field_type
== error_mark_node
|| !TYPE_SIZE (field_type
)
7072 || TYPE_SIZE (field_type
) == error_mark_node
)
7073 /* 'type[0]' is allowed, but 'type[]' is not! */
7075 error ("instance variable %qs has unknown size", ivar_name
);
7076 /* Return class as is without adding this ivar. */
7081 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7082 need to either (1) warn the user about it or (2) generate suitable
7083 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7084 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7085 if (MAYBE_CLASS_TYPE_P (field_type
)
7086 && (TYPE_NEEDS_CONSTRUCTING (field_type
)
7087 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
)
7088 || TYPE_POLYMORPHIC_P (field_type
)))
7090 const char *type_name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type
));
7092 if (flag_objc_call_cxx_cdtors
)
7094 /* Since the ObjC runtime will be calling the constructors and
7095 destructors for us, the only thing we can't handle is the lack
7096 of a default constructor. */
7097 if (TYPE_NEEDS_CONSTRUCTING (field_type
)
7098 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type
))
7100 warning (0, "type %qs has no default constructor to call",
7103 /* If we cannot call a constructor, we should also avoid
7104 calling the destructor, for symmetry. */
7105 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
7106 warning (0, "destructor for %qs shall not be run either",
7112 static bool warn_cxx_ivars
= false;
7114 if (TYPE_POLYMORPHIC_P (field_type
))
7116 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7118 error ("type %qs has virtual member functions", type_name
);
7119 error ("illegal aggregate type %qs specified "
7120 "for instance variable %qs",
7121 type_name
, ivar_name
);
7122 /* Return class as is without adding this ivar. */
7126 /* User-defined constructors and destructors are not known to Obj-C
7127 and hence will not be called. This may or may not be a problem. */
7128 if (TYPE_NEEDS_CONSTRUCTING (field_type
))
7129 warning (0, "type %qs has a user-defined constructor", type_name
);
7130 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
7131 warning (0, "type %qs has a user-defined destructor", type_name
);
7133 if (!warn_cxx_ivars
)
7135 warning (0, "C++ constructors and destructors will not "
7136 "be invoked for Objective-C fields");
7137 warn_cxx_ivars
= true;
7143 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7147 TREE_PUBLIC (field_decl
) = 0;
7148 TREE_PRIVATE (field_decl
) = 0;
7149 TREE_PROTECTED (field_decl
) = 1;
7153 TREE_PUBLIC (field_decl
) = 1;
7154 TREE_PRIVATE (field_decl
) = 0;
7155 TREE_PROTECTED (field_decl
) = 0;
7159 TREE_PUBLIC (field_decl
) = 0;
7160 TREE_PRIVATE (field_decl
) = 1;
7161 TREE_PROTECTED (field_decl
) = 0;
7166 CLASS_RAW_IVARS (klass
) = chainon (CLASS_RAW_IVARS (klass
), field_decl
);
7172 is_ivar (tree decl_chain
, tree ident
)
7174 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
7175 if (DECL_NAME (decl_chain
) == ident
)
7180 /* True if the ivar is private and we are not in its implementation. */
7183 is_private (tree decl
)
7185 return (TREE_PRIVATE (decl
)
7186 && ! is_ivar (CLASS_IVARS (implementation_template
),
7190 /* We have an instance variable reference;, check to see if it is public. */
7193 objc_is_public (tree expr
, tree identifier
)
7195 tree basetype
, decl
;
7198 if (processing_template_decl
)
7202 if (TREE_TYPE (expr
) == error_mark_node
)
7205 basetype
= TYPE_MAIN_VARIANT (TREE_TYPE (expr
));
7207 if (basetype
&& TREE_CODE (basetype
) == RECORD_TYPE
)
7209 if (TYPE_HAS_OBJC_INFO (basetype
) && TYPE_OBJC_INTERFACE (basetype
))
7211 tree klass
= lookup_interface (OBJC_TYPE_NAME (basetype
));
7215 error ("cannot find interface declaration for %qs",
7216 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype
)));
7220 if ((decl
= is_ivar (get_class_ivars (klass
, true), identifier
)))
7222 if (TREE_PUBLIC (decl
))
7225 /* Important difference between the Stepstone translator:
7226 all instance variables should be public within the context
7227 of the implementation. */
7228 if (objc_implementation_context
7229 && ((TREE_CODE (objc_implementation_context
)
7230 == CLASS_IMPLEMENTATION_TYPE
)
7231 || (TREE_CODE (objc_implementation_context
)
7232 == CATEGORY_IMPLEMENTATION_TYPE
)))
7234 tree curtype
= TYPE_MAIN_VARIANT
7235 (CLASS_STATIC_TEMPLATE
7236 (implementation_template
));
7238 if (basetype
== curtype
7239 || DERIVED_FROM_P (basetype
, curtype
))
7241 int priv
= is_private (decl
);
7244 error ("instance variable %qs is declared private",
7245 IDENTIFIER_POINTER (DECL_NAME (decl
)));
7251 /* The 2.95.2 compiler sometimes allowed C functions to access
7252 non-@public ivars. We will let this slide for now... */
7253 if (!objc_method_context
)
7255 warning (0, "instance variable %qs is %s; "
7256 "this will be a hard error in the future",
7257 IDENTIFIER_POINTER (identifier
),
7258 TREE_PRIVATE (decl
) ? "@private" : "@protected");
7262 error ("instance variable %qs is declared %s",
7263 IDENTIFIER_POINTER (identifier
),
7264 TREE_PRIVATE (decl
) ? "private" : "protected");
7273 /* Make sure all entries in CHAIN are also in LIST. */
7276 check_methods (tree chain
, tree list
, int mtype
)
7282 if (!lookup_method (list
, chain
))
7286 if (TREE_CODE (objc_implementation_context
)
7287 == CLASS_IMPLEMENTATION_TYPE
)
7288 warning (0, "incomplete implementation of class %qs",
7289 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
7290 else if (TREE_CODE (objc_implementation_context
)
7291 == CATEGORY_IMPLEMENTATION_TYPE
)
7292 warning (0, "incomplete implementation of category %qs",
7293 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7297 warning (0, "method definition for %<%c%s%> not found",
7298 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
7301 chain
= TREE_CHAIN (chain
);
7307 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7310 conforms_to_protocol (tree klass
, tree protocol
)
7312 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
7314 tree p
= CLASS_PROTOCOL_LIST (klass
);
7315 while (p
&& TREE_VALUE (p
) != protocol
)
7320 tree super
= (CLASS_SUPER_NAME (klass
)
7321 ? lookup_interface (CLASS_SUPER_NAME (klass
))
7323 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
7332 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7333 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7336 check_methods_accessible (tree chain
, tree context
, int mtype
)
7340 tree base_context
= context
;
7344 context
= base_context
;
7348 list
= CLASS_CLS_METHODS (context
);
7350 list
= CLASS_NST_METHODS (context
);
7352 if (lookup_method (list
, chain
))
7355 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
7356 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
7357 context
= (CLASS_SUPER_NAME (context
)
7358 ? lookup_interface (CLASS_SUPER_NAME (context
))
7361 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
7362 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
7363 context
= (CLASS_NAME (context
)
7364 ? lookup_interface (CLASS_NAME (context
))
7370 if (context
== NULL_TREE
)
7374 if (TREE_CODE (objc_implementation_context
)
7375 == CLASS_IMPLEMENTATION_TYPE
)
7376 warning (0, "incomplete implementation of class %qs",
7378 (CLASS_NAME (objc_implementation_context
)));
7379 else if (TREE_CODE (objc_implementation_context
)
7380 == CATEGORY_IMPLEMENTATION_TYPE
)
7381 warning (0, "incomplete implementation of category %qs",
7383 (CLASS_SUPER_NAME (objc_implementation_context
)));
7386 warning (0, "method definition for %<%c%s%> not found",
7387 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
7390 chain
= TREE_CHAIN (chain
); /* next method... */
7395 /* Check whether the current interface (accessible via
7396 'objc_implementation_context') actually implements protocol P, along
7397 with any protocols that P inherits. */
7400 check_protocol (tree p
, const char *type
, const char *name
)
7402 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
7406 /* Ensure that all protocols have bodies! */
7409 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
7410 CLASS_CLS_METHODS (objc_implementation_context
),
7412 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
7413 CLASS_NST_METHODS (objc_implementation_context
),
7418 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
7419 objc_implementation_context
,
7421 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
7422 objc_implementation_context
,
7427 warning (0, "%s %qs does not fully implement the %qs protocol",
7428 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
7431 /* Check protocols recursively. */
7432 if (PROTOCOL_LIST (p
))
7434 tree subs
= PROTOCOL_LIST (p
);
7436 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
7440 tree sub
= TREE_VALUE (subs
);
7442 /* If the superclass does not conform to the protocols
7443 inherited by P, then we must! */
7444 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
7445 check_protocol (sub
, type
, name
);
7446 subs
= TREE_CHAIN (subs
);
7451 /* Check whether the current interface (accessible via
7452 'objc_implementation_context') actually implements the protocols listed
7456 check_protocols (tree proto_list
, const char *type
, const char *name
)
7458 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
7460 tree p
= TREE_VALUE (proto_list
);
7462 check_protocol (p
, type
, name
);
7466 /* Make sure that the class CLASS_NAME is defined
7467 CODE says which kind of thing CLASS_NAME ought to be.
7468 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7469 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7472 start_class (enum tree_code code
, tree class_name
, tree super_name
,
7478 if (current_namespace
!= global_namespace
) {
7479 error ("Objective-C declarations may only appear in global scope");
7481 #endif /* OBJCPLUS */
7483 if (objc_implementation_context
)
7485 warning (0, "%<@end%> missing in implementation context");
7486 finish_class (objc_implementation_context
);
7487 objc_ivar_chain
= NULL_TREE
;
7488 objc_implementation_context
= NULL_TREE
;
7491 klass
= make_node (code
);
7492 TYPE_LANG_SLOT_1 (klass
) = make_tree_vec (CLASS_LANG_SLOT_ELTS
);
7494 /* Check for existence of the super class, if one was specified. Note
7495 that we must have seen an @interface, not just a @class. If we
7496 are looking at a @compatibility_alias, traverse it first. */
7497 if ((code
== CLASS_INTERFACE_TYPE
|| code
== CLASS_IMPLEMENTATION_TYPE
)
7500 tree super
= objc_is_class_name (super_name
);
7502 if (!super
|| !lookup_interface (super
))
7504 error ("cannot find interface declaration for %qs, superclass of %qs",
7505 IDENTIFIER_POINTER (super
? super
: super_name
),
7506 IDENTIFIER_POINTER (class_name
));
7507 super_name
= NULL_TREE
;
7513 CLASS_NAME (klass
) = class_name
;
7514 CLASS_SUPER_NAME (klass
) = super_name
;
7515 CLASS_CLS_METHODS (klass
) = NULL_TREE
;
7517 if (! objc_is_class_name (class_name
)
7518 && (decl
= lookup_name (class_name
)))
7520 error ("%qs redeclared as different kind of symbol",
7521 IDENTIFIER_POINTER (class_name
));
7522 error ("previous declaration of %q+D",
7526 if (code
== CLASS_IMPLEMENTATION_TYPE
)
7531 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
7532 if (TREE_VALUE (chain
) == class_name
)
7534 error ("reimplementation of class %qs",
7535 IDENTIFIER_POINTER (class_name
));
7536 return error_mark_node
;
7538 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
7539 implemented_classes
);
7542 /* Reset for multiple classes per file. */
7545 objc_implementation_context
= klass
;
7547 /* Lookup the interface for this implementation. */
7549 if (!(implementation_template
= lookup_interface (class_name
)))
7551 warning (0, "cannot find interface declaration for %qs",
7552 IDENTIFIER_POINTER (class_name
));
7553 add_class (implementation_template
= objc_implementation_context
,
7557 /* If a super class has been specified in the implementation,
7558 insure it conforms to the one specified in the interface. */
7561 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
7563 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
7564 const char *const name
=
7565 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
7566 error ("conflicting super class name %qs",
7567 IDENTIFIER_POINTER (super_name
));
7568 error ("previous declaration of %qs", name
);
7571 else if (! super_name
)
7573 CLASS_SUPER_NAME (objc_implementation_context
)
7574 = CLASS_SUPER_NAME (implementation_template
);
7578 else if (code
== CLASS_INTERFACE_TYPE
)
7580 if (lookup_interface (class_name
))
7582 error ("duplicate interface declaration for class %qs",
7584 warning (0, "duplicate interface declaration for class %qs",
7586 IDENTIFIER_POINTER (class_name
));
7588 add_class (klass
, class_name
);
7591 CLASS_PROTOCOL_LIST (klass
)
7592 = lookup_and_install_protocols (protocol_list
);
7595 else if (code
== CATEGORY_INTERFACE_TYPE
)
7597 tree class_category_is_assoc_with
;
7599 /* For a category, class_name is really the name of the class that
7600 the following set of methods will be associated with. We must
7601 find the interface so that can derive the objects template. */
7603 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
7605 error ("cannot find interface declaration for %qs",
7606 IDENTIFIER_POINTER (class_name
));
7607 exit (FATAL_EXIT_CODE
);
7610 add_category (class_category_is_assoc_with
, klass
);
7613 CLASS_PROTOCOL_LIST (klass
)
7614 = lookup_and_install_protocols (protocol_list
);
7617 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
7619 /* Reset for multiple classes per file. */
7622 objc_implementation_context
= klass
;
7624 /* For a category, class_name is really the name of the class that
7625 the following set of methods will be associated with. We must
7626 find the interface so that can derive the objects template. */
7628 if (!(implementation_template
= lookup_interface (class_name
)))
7630 error ("cannot find interface declaration for %qs",
7631 IDENTIFIER_POINTER (class_name
));
7632 exit (FATAL_EXIT_CODE
);
7639 continue_class (tree klass
)
7641 if (TREE_CODE (klass
) == CLASS_IMPLEMENTATION_TYPE
7642 || TREE_CODE (klass
) == CATEGORY_IMPLEMENTATION_TYPE
)
7644 struct imp_entry
*imp_entry
;
7646 /* Check consistency of the instance variables. */
7648 if (CLASS_RAW_IVARS (klass
))
7649 check_ivars (implementation_template
, klass
);
7651 /* code generation */
7654 push_lang_context (lang_name_c
);
7657 build_private_template (implementation_template
);
7658 uprivate_record
= CLASS_STATIC_TEMPLATE (implementation_template
);
7659 objc_instance_type
= build_pointer_type (uprivate_record
);
7661 imp_entry
= (struct imp_entry
*) ggc_alloc (sizeof (struct imp_entry
));
7663 imp_entry
->next
= imp_list
;
7664 imp_entry
->imp_context
= klass
;
7665 imp_entry
->imp_template
= implementation_template
;
7667 synth_forward_declarations ();
7668 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
7669 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
7670 imp_entry
->has_cxx_cdtors
= 0;
7672 /* Append to front and increment count. */
7673 imp_list
= imp_entry
;
7674 if (TREE_CODE (klass
) == CLASS_IMPLEMENTATION_TYPE
)
7680 pop_lang_context ();
7681 #endif /* OBJCPLUS */
7683 return get_class_ivars (implementation_template
, true);
7686 else if (TREE_CODE (klass
) == CLASS_INTERFACE_TYPE
)
7689 push_lang_context (lang_name_c
);
7690 #endif /* OBJCPLUS */
7692 build_private_template (klass
);
7695 pop_lang_context ();
7696 #endif /* OBJCPLUS */
7702 return error_mark_node
;
7705 /* This is called once we see the "@end" in an interface/implementation. */
7708 finish_class (tree klass
)
7710 if (TREE_CODE (klass
) == CLASS_IMPLEMENTATION_TYPE
)
7712 /* All code generation is done in finish_objc. */
7714 if (implementation_template
!= objc_implementation_context
)
7716 /* Ensure that all method listed in the interface contain bodies. */
7717 check_methods (CLASS_CLS_METHODS (implementation_template
),
7718 CLASS_CLS_METHODS (objc_implementation_context
), '+');
7719 check_methods (CLASS_NST_METHODS (implementation_template
),
7720 CLASS_NST_METHODS (objc_implementation_context
), '-');
7722 if (CLASS_PROTOCOL_LIST (implementation_template
))
7723 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
7725 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
7729 else if (TREE_CODE (klass
) == CATEGORY_IMPLEMENTATION_TYPE
)
7731 tree category
= lookup_category (implementation_template
, CLASS_SUPER_NAME (klass
));
7735 /* Ensure all method listed in the interface contain bodies. */
7736 check_methods (CLASS_CLS_METHODS (category
),
7737 CLASS_CLS_METHODS (objc_implementation_context
), '+');
7738 check_methods (CLASS_NST_METHODS (category
),
7739 CLASS_NST_METHODS (objc_implementation_context
), '-');
7741 if (CLASS_PROTOCOL_LIST (category
))
7742 check_protocols (CLASS_PROTOCOL_LIST (category
),
7744 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7750 add_protocol (tree protocol
)
7752 /* Put protocol on list in reverse order. */
7753 TREE_CHAIN (protocol
) = protocol_chain
;
7754 protocol_chain
= protocol
;
7755 return protocol_chain
;
7759 lookup_protocol (tree ident
)
7763 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
7764 if (ident
== PROTOCOL_NAME (chain
))
7770 /* This function forward declares the protocols named by NAMES. If
7771 they are already declared or defined, the function has no effect. */
7774 objc_declare_protocols (tree names
)
7779 if (current_namespace
!= global_namespace
) {
7780 error ("Objective-C declarations may only appear in global scope");
7782 #endif /* OBJCPLUS */
7784 for (list
= names
; list
; list
= TREE_CHAIN (list
))
7786 tree name
= TREE_VALUE (list
);
7788 if (lookup_protocol (name
) == NULL_TREE
)
7790 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
7792 TYPE_LANG_SLOT_1 (protocol
)
7793 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
7794 PROTOCOL_NAME (protocol
) = name
;
7795 PROTOCOL_LIST (protocol
) = NULL_TREE
;
7796 add_protocol (protocol
);
7797 PROTOCOL_DEFINED (protocol
) = 0;
7798 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
7804 start_protocol (enum tree_code code
, tree name
, tree list
)
7809 if (current_namespace
!= global_namespace
) {
7810 error ("Objective-C declarations may only appear in global scope");
7812 #endif /* OBJCPLUS */
7814 protocol
= lookup_protocol (name
);
7818 protocol
= make_node (code
);
7819 TYPE_LANG_SLOT_1 (protocol
) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
7821 PROTOCOL_NAME (protocol
) = name
;
7822 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
7823 add_protocol (protocol
);
7824 PROTOCOL_DEFINED (protocol
) = 1;
7825 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
7827 check_protocol_recursively (protocol
, list
);
7829 else if (! PROTOCOL_DEFINED (protocol
))
7831 PROTOCOL_DEFINED (protocol
) = 1;
7832 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
7834 check_protocol_recursively (protocol
, list
);
7838 warning (0, "duplicate declaration for protocol %qs",
7839 IDENTIFIER_POINTER (name
));
7845 /* "Encode" a data type into a string, which grows in util_obstack.
7846 ??? What is the FORMAT? Someone please document this! */
7849 encode_type_qualifiers (tree declspecs
)
7853 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
7855 if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
7856 obstack_1grow (&util_obstack
, 'n');
7857 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
7858 obstack_1grow (&util_obstack
, 'N');
7859 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
7860 obstack_1grow (&util_obstack
, 'o');
7861 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
7862 obstack_1grow (&util_obstack
, 'O');
7863 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
7864 obstack_1grow (&util_obstack
, 'R');
7865 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
7866 obstack_1grow (&util_obstack
, 'V');
7870 /* Encode a pointer type. */
7873 encode_pointer (tree type
, int curtype
, int format
)
7875 tree pointer_to
= TREE_TYPE (type
);
7877 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
7879 if (OBJC_TYPE_NAME (pointer_to
)
7880 && TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
7882 const char *name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to
));
7884 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
7886 obstack_1grow (&util_obstack
, '@');
7889 else if (TYPE_HAS_OBJC_INFO (pointer_to
)
7890 && TYPE_OBJC_INTERFACE (pointer_to
))
7892 if (generating_instance_variables
)
7894 obstack_1grow (&util_obstack
, '@');
7895 obstack_1grow (&util_obstack
, '"');
7896 obstack_grow (&util_obstack
, name
, strlen (name
));
7897 obstack_1grow (&util_obstack
, '"');
7902 obstack_1grow (&util_obstack
, '@');
7906 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
7908 obstack_1grow (&util_obstack
, '#');
7911 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
7913 obstack_1grow (&util_obstack
, ':');
7918 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
7919 && TYPE_MODE (pointer_to
) == QImode
)
7921 tree pname
= TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
7922 ? OBJC_TYPE_NAME (pointer_to
)
7923 : DECL_NAME (OBJC_TYPE_NAME (pointer_to
));
7925 if (!flag_next_runtime
|| strcmp (IDENTIFIER_POINTER (pname
), "BOOL"))
7927 /* It appears that "r*" means "const char *" rather than
7929 if (TYPE_READONLY (pointer_to
))
7930 obstack_1grow (&util_obstack
, 'r');
7932 obstack_1grow (&util_obstack
, '*');
7937 /* We have a type that does not get special treatment. */
7939 /* NeXT extension */
7940 obstack_1grow (&util_obstack
, '^');
7941 encode_type (pointer_to
, curtype
, format
);
7945 encode_array (tree type
, int curtype
, int format
)
7947 tree an_int_cst
= TYPE_SIZE (type
);
7948 tree array_of
= TREE_TYPE (type
);
7951 /* An incomplete array is treated like a pointer. */
7952 if (an_int_cst
== NULL
)
7954 encode_pointer (type
, curtype
, format
);
7958 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of
)) == 0)
7959 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
)0);
7961 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
,
7962 TREE_INT_CST_LOW (an_int_cst
)
7963 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
)));
7965 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7966 encode_type (array_of
, curtype
, format
);
7967 obstack_1grow (&util_obstack
, ']');
7972 encode_aggregate_fields (tree type
, int pointed_to
, int curtype
, int format
)
7974 tree field
= TYPE_FIELDS (type
);
7976 for (; field
; field
= TREE_CHAIN (field
))
7979 /* C++ static members, and things that are not field at all,
7980 should not appear in the encoding. */
7981 if (TREE_CODE (field
) != FIELD_DECL
|| TREE_STATIC (field
))
7985 /* Recursively encode fields of embedded base classes. */
7986 if (DECL_ARTIFICIAL (field
) && !DECL_NAME (field
)
7987 && TREE_CODE (TREE_TYPE (field
)) == RECORD_TYPE
)
7989 encode_aggregate_fields (TREE_TYPE (field
),
7990 pointed_to
, curtype
, format
);
7994 if (generating_instance_variables
&& !pointed_to
)
7996 tree fname
= DECL_NAME (field
);
7998 obstack_1grow (&util_obstack
, '"');
8000 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
8001 obstack_grow (&util_obstack
,
8002 IDENTIFIER_POINTER (fname
),
8003 strlen (IDENTIFIER_POINTER (fname
)));
8005 obstack_1grow (&util_obstack
, '"');
8008 encode_field_decl (field
, curtype
, format
);
8013 encode_aggregate_within (tree type
, int curtype
, int format
, int left
,
8017 /* NB: aggregates that are pointed to have slightly different encoding
8018 rules in that you never encode the names of instance variables. */
8019 int ob_size
= obstack_object_size (&util_obstack
);
8020 char c1
= ob_size
> 1 ? *(obstack_next_free (&util_obstack
) - 2) : 0;
8021 char c0
= ob_size
> 0 ? *(obstack_next_free (&util_obstack
) - 1) : 0;
8022 int pointed_to
= (c0
== '^' || (c1
== '^' && c0
== 'r'));
8024 = ((format
== OBJC_ENCODE_INLINE_DEFS
|| generating_instance_variables
)
8025 && (!pointed_to
|| ob_size
- curtype
== (c1
== 'r' ? 2 : 1)));
8027 /* Traverse struct aliases; it is important to get the
8028 original struct and its tag name (if any). */
8029 type
= TYPE_MAIN_VARIANT (type
);
8030 name
= OBJC_TYPE_NAME (type
);
8031 /* Open parenth/bracket. */
8032 obstack_1grow (&util_obstack
, left
);
8034 /* Encode the struct/union tag name, or '?' if a tag was
8035 not provided. Typedef aliases do not qualify. */
8036 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
8038 /* Did this struct have a tag? */
8039 && !TYPE_WAS_ANONYMOUS (type
)
8042 obstack_grow (&util_obstack
,
8043 IDENTIFIER_POINTER (name
),
8044 strlen (IDENTIFIER_POINTER (name
)));
8046 obstack_1grow (&util_obstack
, '?');
8048 /* Encode the types (and possibly names) of the inner fields,
8050 if (inline_contents
)
8052 obstack_1grow (&util_obstack
, '=');
8053 encode_aggregate_fields (type
, pointed_to
, curtype
, format
);
8055 /* Close parenth/bracket. */
8056 obstack_1grow (&util_obstack
, right
);
8060 encode_aggregate (tree type
, int curtype
, int format
)
8062 enum tree_code code
= TREE_CODE (type
);
8068 encode_aggregate_within (type
, curtype
, format
, '{', '}');
8073 encode_aggregate_within (type
, curtype
, format
, '(', ')');
8078 obstack_1grow (&util_obstack
, 'i');
8086 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8090 encode_next_bitfield (int width
)
8093 sprintf (buffer
, "b%d", width
);
8094 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
8097 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8099 encode_type (tree type
, int curtype
, int format
)
8101 enum tree_code code
= TREE_CODE (type
);
8104 if (type
== error_mark_node
)
8107 if (TYPE_READONLY (type
))
8108 obstack_1grow (&util_obstack
, 'r');
8110 if (code
== INTEGER_TYPE
)
8112 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
8114 case 8: c
= TYPE_UNSIGNED (type
) ? 'C' : 'c'; break;
8115 case 16: c
= TYPE_UNSIGNED (type
) ? 'S' : 's'; break;
8117 if (type
== long_unsigned_type_node
8118 || type
== long_integer_type_node
)
8119 c
= TYPE_UNSIGNED (type
) ? 'L' : 'l';
8121 c
= TYPE_UNSIGNED (type
) ? 'I' : 'i';
8123 case 64: c
= TYPE_UNSIGNED (type
) ? 'Q' : 'q'; break;
8126 obstack_1grow (&util_obstack
, c
);
8129 else if (code
== REAL_TYPE
)
8131 /* Floating point types. */
8132 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
8134 case 32: c
= 'f'; break;
8137 case 128: c
= 'd'; break;
8140 obstack_1grow (&util_obstack
, c
);
8143 else if (code
== VOID_TYPE
)
8144 obstack_1grow (&util_obstack
, 'v');
8146 else if (code
== BOOLEAN_TYPE
)
8147 obstack_1grow (&util_obstack
, 'B');
8149 else if (code
== ARRAY_TYPE
)
8150 encode_array (type
, curtype
, format
);
8152 else if (code
== POINTER_TYPE
)
8153 encode_pointer (type
, curtype
, format
);
8155 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
8156 encode_aggregate (type
, curtype
, format
);
8158 else if (code
== FUNCTION_TYPE
) /* '?' */
8159 obstack_1grow (&util_obstack
, '?');
8161 else if (code
== COMPLEX_TYPE
)
8163 obstack_1grow (&util_obstack
, 'j');
8164 encode_type (TREE_TYPE (type
), curtype
, format
);
8169 encode_gnu_bitfield (int position
, tree type
, int size
)
8171 enum tree_code code
= TREE_CODE (type
);
8173 char charType
= '?';
8175 if (code
== INTEGER_TYPE
)
8177 if (integer_zerop (TYPE_MIN_VALUE (type
)))
8179 /* Unsigned integer types. */
8181 if (TYPE_MODE (type
) == QImode
)
8183 else if (TYPE_MODE (type
) == HImode
)
8185 else if (TYPE_MODE (type
) == SImode
)
8187 if (type
== long_unsigned_type_node
)
8192 else if (TYPE_MODE (type
) == DImode
)
8197 /* Signed integer types. */
8199 if (TYPE_MODE (type
) == QImode
)
8201 else if (TYPE_MODE (type
) == HImode
)
8203 else if (TYPE_MODE (type
) == SImode
)
8205 if (type
== long_integer_type_node
)
8211 else if (TYPE_MODE (type
) == DImode
)
8215 else if (code
== ENUMERAL_TYPE
)
8220 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
8221 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
8225 encode_field_decl (tree field_decl
, int curtype
, int format
)
8230 /* C++ static members, and things that are not fields at all,
8231 should not appear in the encoding. */
8232 if (TREE_CODE (field_decl
) != FIELD_DECL
|| TREE_STATIC (field_decl
))
8236 type
= TREE_TYPE (field_decl
);
8238 /* Generate the bitfield typing information, if needed. Note the difference
8239 between GNU and NeXT runtimes. */
8240 if (DECL_BIT_FIELD_TYPE (field_decl
))
8242 int size
= tree_low_cst (DECL_SIZE (field_decl
), 1);
8244 if (flag_next_runtime
)
8245 encode_next_bitfield (size
);
8247 encode_gnu_bitfield (int_bit_position (field_decl
),
8248 DECL_BIT_FIELD_TYPE (field_decl
), size
);
8251 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
8254 static GTY(()) tree objc_parmlist
= NULL_TREE
;
8256 /* Append PARM to a list of formal parameters of a method, making a necessary
8257 array-to-pointer adjustment along the way. */
8260 objc_push_parm (tree parm
)
8262 bool relayout_needed
= false;
8264 if (TREE_TYPE (parm
) == error_mark_node
)
8266 objc_parmlist
= chainon (objc_parmlist
, parm
);
8270 /* Decay arrays and functions into pointers. */
8271 if (TREE_CODE (TREE_TYPE (parm
)) == ARRAY_TYPE
)
8273 TREE_TYPE (parm
) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm
)));
8274 relayout_needed
= true;
8276 else if (TREE_CODE (TREE_TYPE (parm
)) == FUNCTION_TYPE
)
8278 TREE_TYPE (parm
) = build_pointer_type (TREE_TYPE (parm
));
8279 relayout_needed
= true;
8282 if (relayout_needed
)
8283 relayout_decl (parm
);
8286 DECL_ARG_TYPE (parm
)
8287 = lang_hooks
.types
.type_promotes_to (TREE_TYPE (parm
));
8289 /* Record constancy and volatility. */
8290 c_apply_type_quals_to_decl
8291 ((TYPE_READONLY (TREE_TYPE (parm
)) ? TYPE_QUAL_CONST
: 0)
8292 | (TYPE_RESTRICT (TREE_TYPE (parm
)) ? TYPE_QUAL_RESTRICT
: 0)
8293 | (TYPE_VOLATILE (TREE_TYPE (parm
)) ? TYPE_QUAL_VOLATILE
: 0), parm
);
8295 objc_parmlist
= chainon (objc_parmlist
, parm
);
8298 /* Retrieve the formal parameter list constructed via preceding calls to
8299 objc_push_parm(). */
8303 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED
)
8305 static struct c_arg_info
*
8306 objc_get_parm_info (int have_ellipsis
)
8310 tree parm_info
= objc_parmlist
;
8311 objc_parmlist
= NULL_TREE
;
8315 tree parm_info
= objc_parmlist
;
8316 struct c_arg_info
*arg_info
;
8317 /* The C front-end requires an elaborate song and dance at
8320 declare_parm_level ();
8323 tree next
= TREE_CHAIN (parm_info
);
8325 TREE_CHAIN (parm_info
) = NULL_TREE
;
8326 parm_info
= pushdecl (parm_info
);
8327 finish_decl (parm_info
, NULL_TREE
, NULL_TREE
);
8330 arg_info
= get_parm_info (have_ellipsis
);
8332 objc_parmlist
= NULL_TREE
;
8337 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8338 method definitions. In the case of instance methods, we can be more
8339 specific as to the type of 'self'. */
8342 synth_self_and_ucmd_args (void)
8346 if (objc_method_context
8347 && TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
8348 self_type
= objc_instance_type
;
8350 /* Really a `struct objc_class *'. However, we allow people to
8351 assign to self, which changes its type midstream. */
8352 self_type
= objc_object_type
;
8355 objc_push_parm (build_decl (PARM_DECL
, self_id
, self_type
));
8358 objc_push_parm (build_decl (PARM_DECL
, ucmd_id
, objc_selector_type
));
8361 /* Transform an Objective-C method definition into a static C function
8362 definition, synthesizing the first two arguments, "self" and "_cmd",
8366 start_method_def (tree method
)
8372 struct c_arg_info
*parm_info
;
8374 int have_ellipsis
= 0;
8376 /* If we are defining a "dealloc" method in a non-root class, we
8377 will need to check if a [super dealloc] is missing, and warn if
8379 if(CLASS_SUPER_NAME (objc_implementation_context
)
8380 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method
))))
8381 should_call_super_dealloc
= 1;
8383 should_call_super_dealloc
= 0;
8385 /* Required to implement _msgSuper. */
8386 objc_method_context
= method
;
8387 UOBJC_SUPER_decl
= NULL_TREE
;
8389 /* Generate prototype declarations for arguments..."new-style". */
8390 synth_self_and_ucmd_args ();
8392 /* Generate argument declarations if a keyword_decl. */
8393 parmlist
= METHOD_SEL_ARGS (method
);
8396 tree type
= TREE_VALUE (TREE_TYPE (parmlist
)), parm
;
8398 parm
= build_decl (PARM_DECL
, KEYWORD_ARG_NAME (parmlist
), type
);
8399 objc_push_parm (parm
);
8400 parmlist
= TREE_CHAIN (parmlist
);
8403 if (METHOD_ADD_ARGS (method
))
8407 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
8408 akey
; akey
= TREE_CHAIN (akey
))
8410 objc_push_parm (TREE_VALUE (akey
));
8413 if (METHOD_ADD_ARGS_ELLIPSIS_P (method
))
8417 parm_info
= objc_get_parm_info (have_ellipsis
);
8419 really_start_method (objc_method_context
, parm_info
);
8423 warn_with_method (const char *message
, int mtype
, tree method
)
8425 /* Add a readable method name to the warning. */
8426 warning (0, "%J%s %<%c%s%>", method
,
8427 message
, mtype
, gen_method_decl (method
));
8430 /* Return 1 if TYPE1 is equivalent to TYPE2
8431 for purposes of method overloading. */
8434 objc_types_are_equivalent (tree type1
, tree type2
)
8439 /* Strip away indirections. */
8440 while ((TREE_CODE (type1
) == ARRAY_TYPE
|| TREE_CODE (type1
) == POINTER_TYPE
)
8441 && (TREE_CODE (type1
) == TREE_CODE (type2
)))
8442 type1
= TREE_TYPE (type1
), type2
= TREE_TYPE (type2
);
8443 if (TYPE_MAIN_VARIANT (type1
) != TYPE_MAIN_VARIANT (type2
))
8446 type1
= (TYPE_HAS_OBJC_INFO (type1
)
8447 ? TYPE_OBJC_PROTOCOL_LIST (type1
)
8449 type2
= (TYPE_HAS_OBJC_INFO (type2
)
8450 ? TYPE_OBJC_PROTOCOL_LIST (type2
)
8453 if (list_length (type1
) == list_length (type2
))
8455 for (; type2
; type2
= TREE_CHAIN (type2
))
8456 if (!lookup_protocol_in_reflist (type1
, TREE_VALUE (type2
)))
8463 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8466 objc_types_share_size_and_alignment (tree type1
, tree type2
)
8468 return (simple_cst_equal (TYPE_SIZE (type1
), TYPE_SIZE (type2
))
8469 && TYPE_ALIGN (type1
) == TYPE_ALIGN (type2
));
8472 /* Return 1 if PROTO1 is equivalent to PROTO2
8473 for purposes of method overloading. Ordinarily, the type signatures
8474 should match up exactly, unless STRICT is zero, in which case we
8475 shall allow differences in which the size and alignment of a type
8479 comp_proto_with_proto (tree proto1
, tree proto2
, int strict
)
8483 /* The following test is needed in case there are hashing
8485 if (METHOD_SEL_NAME (proto1
) != METHOD_SEL_NAME (proto2
))
8488 /* Compare return types. */
8489 type1
= TREE_VALUE (TREE_TYPE (proto1
));
8490 type2
= TREE_VALUE (TREE_TYPE (proto2
));
8492 if (!objc_types_are_equivalent (type1
, type2
)
8493 && (strict
|| !objc_types_share_size_and_alignment (type1
, type2
)))
8496 /* Compare argument types. */
8497 for (type1
= get_arg_type_list (proto1
, METHOD_REF
, 0),
8498 type2
= get_arg_type_list (proto2
, METHOD_REF
, 0);
8500 type1
= TREE_CHAIN (type1
), type2
= TREE_CHAIN (type2
))
8502 if (!objc_types_are_equivalent (TREE_VALUE (type1
), TREE_VALUE (type2
))
8504 || !objc_types_share_size_and_alignment (TREE_VALUE (type1
),
8505 TREE_VALUE (type2
))))
8509 return (!type1
&& !type2
);
8512 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8513 this occurs. ObjC method dispatches are _not_ like C++ virtual
8514 member function dispatches, and we account for the difference here. */
8517 objc_fold_obj_type_ref (tree ref
, tree known_type
)
8519 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED
,
8520 tree known_type ATTRIBUTE_UNUSED
)
8524 tree v
= BINFO_VIRTUALS (TYPE_BINFO (known_type
));
8526 /* If the receiver does not have virtual member functions, there
8527 is nothing we can (or need to) do here. */
8531 /* Let C++ handle C++ virtual functions. */
8532 return cp_fold_obj_type_ref (ref
, known_type
);
8534 /* For plain ObjC, we currently do not need to do anything. */
8540 objc_start_function (tree name
, tree type
, tree attrs
,
8544 struct c_arg_info
*params
8548 tree fndecl
= build_decl (FUNCTION_DECL
, name
, type
);
8551 DECL_ARGUMENTS (fndecl
) = params
;
8552 DECL_INITIAL (fndecl
) = error_mark_node
;
8553 DECL_EXTERNAL (fndecl
) = 0;
8554 TREE_STATIC (fndecl
) = 1;
8555 retrofit_lang_decl (fndecl
);
8556 cplus_decl_attributes (&fndecl
, attrs
, 0);
8557 start_preparsed_function (fndecl
, attrs
, /*flags=*/SF_DEFAULT
);
8559 struct c_label_context_se
*nstack_se
;
8560 struct c_label_context_vm
*nstack_vm
;
8561 nstack_se
= XOBNEW (&parser_obstack
, struct c_label_context_se
);
8562 nstack_se
->labels_def
= NULL
;
8563 nstack_se
->labels_used
= NULL
;
8564 nstack_se
->next
= label_context_stack_se
;
8565 label_context_stack_se
= nstack_se
;
8566 nstack_vm
= XOBNEW (&parser_obstack
, struct c_label_context_vm
);
8567 nstack_vm
->labels_def
= NULL
;
8568 nstack_vm
->labels_used
= NULL
;
8569 nstack_vm
->scope
= 0;
8570 nstack_vm
->next
= label_context_stack_vm
;
8571 label_context_stack_vm
= nstack_vm
;
8572 current_function_returns_value
= 0; /* Assume, until we see it does. */
8573 current_function_returns_null
= 0;
8575 decl_attributes (&fndecl
, attrs
, 0);
8576 announce_function (fndecl
);
8577 DECL_INITIAL (fndecl
) = error_mark_node
;
8578 DECL_EXTERNAL (fndecl
) = 0;
8579 TREE_STATIC (fndecl
) = 1;
8580 current_function_decl
= pushdecl (fndecl
);
8582 declare_parm_level ();
8583 DECL_RESULT (current_function_decl
)
8584 = build_decl (RESULT_DECL
, NULL_TREE
,
8585 TREE_TYPE (TREE_TYPE (current_function_decl
)));
8586 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl
)) = 1;
8587 DECL_IGNORED_P (DECL_RESULT (current_function_decl
)) = 1;
8588 start_fname_decls ();
8589 store_parm_decls_from (params
);
8592 TREE_USED (current_function_decl
) = 1;
8595 /* - Generate an identifier for the function. the format is "_n_cls",
8596 where 1 <= n <= nMethods, and cls is the name the implementation we
8598 - Install the return type from the method declaration.
8599 - If we have a prototype, check for type consistency. */
8602 really_start_method (tree method
,
8606 struct c_arg_info
*parmlist
8610 tree ret_type
, meth_type
;
8612 const char *sel_name
, *class_name
, *cat_name
;
8615 /* Synth the storage class & assemble the return type. */
8616 ret_type
= TREE_VALUE (TREE_TYPE (method
));
8618 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
8619 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
8620 cat_name
= ((TREE_CODE (objc_implementation_context
)
8621 == CLASS_IMPLEMENTATION_TYPE
)
8623 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
8626 /* Make sure this is big enough for any plausible method label. */
8627 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
8628 + (cat_name
? strlen (cat_name
) : 0));
8630 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
8631 class_name
, cat_name
, sel_name
, method_slot
);
8633 method_id
= get_identifier (buf
);
8636 /* Objective-C methods cannot be overloaded, so we don't need
8637 the type encoding appended. It looks bad anyway... */
8638 push_lang_context (lang_name_c
);
8642 = build_function_type (ret_type
,
8643 get_arg_type_list (method
, METHOD_DEF
, 0));
8644 objc_start_function (method_id
, meth_type
, NULL_TREE
, parmlist
);
8646 /* Set self_decl from the first argument. */
8647 self_decl
= DECL_ARGUMENTS (current_function_decl
);
8649 /* Suppress unused warnings. */
8650 TREE_USED (self_decl
) = 1;
8651 TREE_USED (TREE_CHAIN (self_decl
)) = 1;
8653 pop_lang_context ();
8656 METHOD_DEFINITION (method
) = current_function_decl
;
8658 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8660 if (implementation_template
!= objc_implementation_context
)
8663 = lookup_method_static (implementation_template
,
8664 METHOD_SEL_NAME (method
),
8665 ((TREE_CODE (method
) == CLASS_METHOD_DECL
)
8666 | OBJC_LOOKUP_NO_SUPER
));
8670 if (!comp_proto_with_proto (method
, proto
, 1))
8672 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
8674 warn_with_method ("conflicting types for", type
, method
);
8675 warn_with_method ("previous declaration of", type
, proto
);
8680 /* We have a method @implementation even though we did not
8681 see a corresponding @interface declaration (which is allowed
8682 by Objective-C rules). Go ahead and place the method in
8683 the @interface anyway, so that message dispatch lookups
8685 tree interface
= implementation_template
;
8687 if (TREE_CODE (objc_implementation_context
)
8688 == CATEGORY_IMPLEMENTATION_TYPE
)
8689 interface
= lookup_category
8691 CLASS_SUPER_NAME (objc_implementation_context
));
8694 objc_add_method (interface
, copy_node (method
),
8695 TREE_CODE (method
) == CLASS_METHOD_DECL
);
8700 static void *UOBJC_SUPER_scope
= 0;
8702 /* _n_Method (id self, SEL sel, ...)
8704 struct objc_super _S;
8705 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8709 get_super_receiver (void)
8711 if (objc_method_context
)
8713 tree super_expr
, super_expr_list
;
8715 if (!UOBJC_SUPER_decl
)
8717 UOBJC_SUPER_decl
= build_decl (VAR_DECL
, get_identifier (TAG_SUPER
),
8718 objc_super_template
);
8719 /* This prevents `unused variable' warnings when compiling with -Wall. */
8720 TREE_USED (UOBJC_SUPER_decl
) = 1;
8721 lang_hooks
.decls
.pushdecl (UOBJC_SUPER_decl
);
8722 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
8723 UOBJC_SUPER_scope
= objc_get_current_scope ();
8726 /* Set receiver to self. */
8727 super_expr
= objc_build_component_ref (UOBJC_SUPER_decl
, self_id
);
8728 super_expr
= build_modify_expr (input_location
,
8729 super_expr
, NOP_EXPR
, self_decl
);
8730 super_expr_list
= super_expr
;
8732 /* Set class to begin searching. */
8733 super_expr
= objc_build_component_ref (UOBJC_SUPER_decl
,
8734 get_identifier ("super_class"));
8736 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8738 /* [_cls, __cls]Super are "pre-built" in
8739 synth_forward_declarations. */
8741 super_expr
= build_modify_expr (input_location
, super_expr
, NOP_EXPR
,
8742 ((TREE_CODE (objc_method_context
)
8743 == INSTANCE_METHOD_DECL
)
8745 : uucls_super_ref
));
8749 /* We have a category. */
8751 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
8754 /* Barf if super used in a category of Object. */
8757 error ("no super class declared in interface for %qs",
8758 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
8759 return error_mark_node
;
8762 if (flag_next_runtime
&& !flag_zero_link
)
8764 super_class
= objc_get_class_reference (super_name
);
8765 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
8766 /* If we are in a class method, we must retrieve the
8767 _metaclass_ for the current class, pointed at by
8768 the class's "isa" pointer. The following assumes that
8769 "isa" is the first ivar in a class (which it must be). */
8771 = build_indirect_ref
8773 build_c_cast (build_pointer_type (objc_class_type
),
8774 super_class
), "unary *");
8778 add_class_reference (super_name
);
8779 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
8780 ? objc_get_class_decl
: objc_get_meta_class_decl
);
8781 assemble_external (super_class
);
8783 = build_function_call
8787 my_build_string_pointer
8788 (IDENTIFIER_LENGTH (super_name
) + 1,
8789 IDENTIFIER_POINTER (super_name
))));
8793 = build_modify_expr (input_location
, super_expr
, NOP_EXPR
,
8794 build_c_cast (TREE_TYPE (super_expr
),
8798 super_expr_list
= build_compound_expr (super_expr_list
, super_expr
);
8800 super_expr
= build_unary_op (input_location
,
8801 ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
8802 super_expr_list
= build_compound_expr (super_expr_list
, super_expr
);
8804 return super_expr_list
;
8808 error ("[super ...] must appear in a method context");
8809 return error_mark_node
;
8813 /* When exiting a scope, sever links to a 'super' declaration (if any)
8814 therein contained. */
8817 objc_clear_super_receiver (void)
8819 if (objc_method_context
8820 && UOBJC_SUPER_scope
== objc_get_current_scope ()) {
8821 UOBJC_SUPER_decl
= 0;
8822 UOBJC_SUPER_scope
= 0;
8827 objc_finish_method_definition (tree fndecl
)
8829 /* We cannot validly inline ObjC methods, at least not without a language
8830 extension to declare that a method need not be dynamically
8831 dispatched, so suppress all thoughts of doing so. */
8832 DECL_UNINLINABLE (fndecl
) = 1;
8835 /* The C++ front-end will have called finish_function() for us. */
8839 METHOD_ENCODING (objc_method_context
)
8840 = encode_method_prototype (objc_method_context
);
8842 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8843 since the optimizer may find "may be used before set" errors. */
8844 objc_method_context
= NULL_TREE
;
8846 if (should_call_super_dealloc
)
8847 warning (0, "method possibly missing a [super dealloc] call");
8852 lang_report_error_function (tree decl
)
8854 if (objc_method_context
)
8856 fprintf (stderr
, "In method %qs\n",
8857 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
8866 /* Given a tree DECL node, produce a printable description of it in the given
8867 buffer, overwriting the buffer. */
8870 gen_declaration (tree decl
)
8876 gen_type_name_0 (TREE_TYPE (decl
));
8878 if (DECL_NAME (decl
))
8880 if (!POINTER_TYPE_P (TREE_TYPE (decl
)))
8881 strcat (errbuf
, " ");
8883 strcat (errbuf
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
8886 if (DECL_INITIAL (decl
)
8887 && TREE_CODE (DECL_INITIAL (decl
)) == INTEGER_CST
)
8888 sprintf (errbuf
+ strlen (errbuf
), ": " HOST_WIDE_INT_PRINT_DEC
,
8889 TREE_INT_CST_LOW (DECL_INITIAL (decl
)));
8895 /* Given a tree TYPE node, produce a printable description of it in the given
8896 buffer, overwriting the buffer. */
8899 gen_type_name_0 (tree type
)
8901 tree orig
= type
, proto
;
8903 if (TYPE_P (type
) && TYPE_NAME (type
))
8904 type
= TYPE_NAME (type
);
8905 else if (POINTER_TYPE_P (type
) || TREE_CODE (type
) == ARRAY_TYPE
)
8907 tree inner
= TREE_TYPE (type
);
8909 while (TREE_CODE (inner
) == ARRAY_TYPE
)
8910 inner
= TREE_TYPE (inner
);
8912 gen_type_name_0 (inner
);
8914 if (!POINTER_TYPE_P (inner
))
8915 strcat (errbuf
, " ");
8917 if (POINTER_TYPE_P (type
))
8918 strcat (errbuf
, "*");
8920 while (type
!= inner
)
8922 strcat (errbuf
, "[");
8924 if (TYPE_DOMAIN (type
))
8928 sprintf (sz
, HOST_WIDE_INT_PRINT_DEC
,
8930 (TYPE_MAX_VALUE (TYPE_DOMAIN (type
))) + 1));
8931 strcat (errbuf
, sz
);
8934 strcat (errbuf
, "]");
8935 type
= TREE_TYPE (type
);
8941 if (TREE_CODE (type
) == TYPE_DECL
&& DECL_NAME (type
))
8942 type
= DECL_NAME (type
);
8944 strcat (errbuf
, TREE_CODE (type
) == IDENTIFIER_NODE
8945 ? IDENTIFIER_POINTER (type
)
8948 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8949 if (objc_is_id (orig
))
8950 orig
= TREE_TYPE (orig
);
8952 proto
= TYPE_HAS_OBJC_INFO (orig
) ? TYPE_OBJC_PROTOCOL_LIST (orig
) : NULL_TREE
;
8956 strcat (errbuf
, " <");
8960 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto
))));
8961 proto
= TREE_CHAIN (proto
);
8962 strcat (errbuf
, proto
? ", " : ">");
8971 gen_type_name (tree type
)
8975 return gen_type_name_0 (type
);
8978 /* Given a method tree, put a printable description into the given
8979 buffer (overwriting) and return a pointer to the buffer. */
8982 gen_method_decl (tree method
)
8986 strcpy (errbuf
, "("); /* NB: Do _not_ call strcat() here. */
8987 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method
)));
8988 strcat (errbuf
, ")");
8989 chain
= METHOD_SEL_ARGS (method
);
8993 /* We have a chain of keyword_decls. */
8996 if (KEYWORD_KEY_NAME (chain
))
8997 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
8999 strcat (errbuf
, ":(");
9000 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain
)));
9001 strcat (errbuf
, ")");
9003 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
9004 if ((chain
= TREE_CHAIN (chain
)))
9005 strcat (errbuf
, " ");
9009 if (METHOD_ADD_ARGS (method
))
9011 chain
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
9013 /* Know we have a chain of parm_decls. */
9016 strcat (errbuf
, ", ");
9017 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain
)));
9018 chain
= TREE_CHAIN (chain
);
9021 if (METHOD_ADD_ARGS_ELLIPSIS_P (method
))
9022 strcat (errbuf
, ", ...");
9027 /* We have a unary selector. */
9028 strcat (errbuf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
9036 /* Dump an @interface declaration of the supplied class CHAIN to the
9037 supplied file FP. Used to implement the -gen-decls option (which
9038 prints out an @interface declaration of all classes compiled in
9039 this run); potentially useful for debugging the compiler too. */
9041 dump_interface (FILE *fp
, tree chain
)
9043 /* FIXME: A heap overflow here whenever a method (or ivar)
9044 declaration is so long that it doesn't fit in the buffer. The
9045 code and all the related functions should be rewritten to avoid
9046 using fixed size buffers. */
9047 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
9048 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
9049 tree nst_methods
= CLASS_NST_METHODS (chain
);
9050 tree cls_methods
= CLASS_CLS_METHODS (chain
);
9052 fprintf (fp
, "\n@interface %s", my_name
);
9054 /* CLASS_SUPER_NAME is used to store the superclass name for
9055 classes, and the category name for categories. */
9056 if (CLASS_SUPER_NAME (chain
))
9058 const char *name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
9060 if (TREE_CODE (chain
) == CATEGORY_IMPLEMENTATION_TYPE
9061 || TREE_CODE (chain
) == CATEGORY_INTERFACE_TYPE
)
9063 fprintf (fp
, " (%s)\n", name
);
9067 fprintf (fp
, " : %s\n", name
);
9073 /* FIXME - the following doesn't seem to work at the moment. */
9076 fprintf (fp
, "{\n");
9079 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
));
9080 ivar_decls
= TREE_CHAIN (ivar_decls
);
9083 fprintf (fp
, "}\n");
9088 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
));
9089 nst_methods
= TREE_CHAIN (nst_methods
);
9094 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
));
9095 cls_methods
= TREE_CHAIN (cls_methods
);
9098 fprintf (fp
, "@end\n");
9101 /* Demangle function for Objective-C */
9103 objc_demangle (const char *mangled
)
9105 char *demangled
, *cp
;
9107 if (mangled
[0] == '_' &&
9108 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
9111 cp
= demangled
= XNEWVEC (char, strlen(mangled
) + 2);
9112 if (mangled
[1] == 'i')
9113 *cp
++ = '-'; /* for instance method */
9115 *cp
++ = '+'; /* for class method */
9116 *cp
++ = '['; /* opening left brace */
9117 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
9118 while (*cp
&& *cp
== '_')
9119 cp
++; /* skip any initial underbars in class name */
9120 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
9123 free(demangled
); /* not mangled name */
9126 if (cp
[1] == '_') /* easy case: no category name */
9128 *cp
++ = ' '; /* replace two '_' with one ' ' */
9129 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
9133 *cp
++ = '('; /* less easy case: category name */
9134 cp
= strchr(cp
, '_');
9137 free(demangled
); /* not mangled name */
9141 *cp
++ = ' '; /* overwriting 1st char of method name... */
9142 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
9144 while (*cp
&& *cp
== '_')
9145 cp
++; /* skip any initial underbars in method name */
9148 *cp
= ':'; /* replace remaining '_' with ':' */
9149 *cp
++ = ']'; /* closing right brace */
9150 *cp
++ = 0; /* string terminator */
9154 return mangled
; /* not an objc mangled name */
9158 objc_printable_name (tree decl
, int kind ATTRIBUTE_UNUSED
)
9160 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
9166 gcc_obstack_init (&util_obstack
);
9167 util_firstobj
= (char *) obstack_finish (&util_obstack
);
9169 errbuf
= XNEWVEC (char, 1024 * 10);
9171 synth_module_prologue ();
9177 struct imp_entry
*impent
;
9179 /* The internally generated initializers appear to have missing braces.
9180 Don't warn about this. */
9181 int save_warn_missing_braces
= warn_missing_braces
;
9182 warn_missing_braces
= 0;
9184 /* A missing @end may not be detected by the parser. */
9185 if (objc_implementation_context
)
9187 warning (0, "%<@end%> missing in implementation context");
9188 finish_class (objc_implementation_context
);
9189 objc_ivar_chain
= NULL_TREE
;
9190 objc_implementation_context
= NULL_TREE
;
9193 /* Process the static instances here because initialization of objc_symtab
9195 if (objc_static_instances
)
9196 generate_static_references ();
9198 if (imp_list
|| class_names_chain
9199 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
9200 generate_objc_symtab_decl ();
9202 for (impent
= imp_list
; impent
; impent
= impent
->next
)
9204 objc_implementation_context
= impent
->imp_context
;
9205 implementation_template
= impent
->imp_template
;
9207 UOBJC_CLASS_decl
= impent
->class_decl
;
9208 UOBJC_METACLASS_decl
= impent
->meta_decl
;
9210 /* Dump the @interface of each class as we compile it, if the
9211 -gen-decls option is in use. TODO: Dump the classes in the
9212 order they were found, rather than in reverse order as we
9214 if (flag_gen_declaration
)
9216 dump_interface (gen_declaration_file
, objc_implementation_context
);
9219 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
9221 /* all of the following reference the string pool... */
9222 generate_ivar_lists ();
9223 generate_dispatch_tables ();
9224 generate_shared_structures (impent
->has_cxx_cdtors
9225 ? CLS_HAS_CXX_STRUCTORS
9230 generate_dispatch_tables ();
9231 generate_category (objc_implementation_context
);
9235 /* If we are using an array of selectors, we must always
9236 finish up the array decl even if no selectors were used. */
9237 if (! flag_next_runtime
|| sel_ref_chain
)
9238 build_selector_translation_table ();
9241 generate_protocols ();
9243 if ((flag_replace_objc_classes
&& imp_list
) || flag_objc_gc
)
9244 generate_objc_image_info ();
9246 /* Arrange for ObjC data structures to be initialized at run time. */
9247 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
9248 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
9250 build_module_descriptor ();
9252 if (!flag_next_runtime
)
9253 build_module_initializer_routine ();
9256 /* Dump the class references. This forces the appropriate classes
9257 to be linked into the executable image, preserving unix archive
9258 semantics. This can be removed when we move to a more dynamically
9259 linked environment. */
9261 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
9263 handle_class_ref (chain
);
9264 if (TREE_PURPOSE (chain
))
9265 generate_classref_translation_entry (chain
);
9268 for (impent
= imp_list
; impent
; impent
= impent
->next
)
9269 handle_impent (impent
);
9276 /* Run through the selector hash tables and print a warning for any
9277 selector which has multiple methods. */
9279 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
9281 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
9282 check_duplicates (hsh
, 0, 1);
9283 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
9284 check_duplicates (hsh
, 0, 1);
9288 warn_missing_braces
= save_warn_missing_braces
;
9291 /* Subroutines of finish_objc. */
9294 generate_classref_translation_entry (tree chain
)
9296 tree expr
, decl
, type
;
9298 decl
= TREE_PURPOSE (chain
);
9299 type
= TREE_TYPE (decl
);
9301 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
9302 expr
= convert (type
, expr
); /* cast! */
9304 /* The decl that is the one that we
9305 forward declared in build_class_reference. */
9306 finish_var_decl (decl
, expr
);
9311 handle_class_ref (tree chain
)
9313 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
9314 char *string
= (char *) alloca (strlen (name
) + 30);
9318 sprintf (string
, "%sobjc_class_name_%s",
9319 (flag_next_runtime
? "." : "__"), name
);
9321 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9322 if (flag_next_runtime
)
9324 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
9329 /* Make a decl for this name, so we can use its address in a tree. */
9330 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
9331 DECL_EXTERNAL (decl
) = 1;
9332 TREE_PUBLIC (decl
) = 1;
9335 rest_of_decl_compilation (decl
, 0, 0);
9337 /* Make a decl for the address. */
9338 sprintf (string
, "%sobjc_class_ref_%s",
9339 (flag_next_runtime
? "." : "__"), name
);
9340 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
9341 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
9342 DECL_INITIAL (decl
) = exp
;
9343 TREE_STATIC (decl
) = 1;
9344 TREE_USED (decl
) = 1;
9345 /* Force the output of the decl as this forces the reference of the class. */
9346 mark_decl_referenced (decl
);
9349 rest_of_decl_compilation (decl
, 0, 0);
9353 handle_impent (struct imp_entry
*impent
)
9357 objc_implementation_context
= impent
->imp_context
;
9358 implementation_template
= impent
->imp_template
;
9360 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
9362 const char *const class_name
=
9363 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
9365 string
= (char *) alloca (strlen (class_name
) + 30);
9367 sprintf (string
, "%sobjc_class_name_%s",
9368 (flag_next_runtime
? "." : "__"), class_name
);
9370 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
9372 const char *const class_name
=
9373 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
9374 const char *const class_super_name
=
9375 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
9377 string
= (char *) alloca (strlen (class_name
)
9378 + strlen (class_super_name
) + 30);
9380 /* Do the same for categories. Even though no references to
9381 these symbols are generated automatically by the compiler, it
9382 gives you a handle to pull them into an archive by hand. */
9383 sprintf (string
, "*%sobjc_category_name_%s_%s",
9384 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
9389 #ifdef ASM_DECLARE_CLASS_REFERENCE
9390 if (flag_next_runtime
)
9392 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
9400 init
= build_int_cst (c_common_type_for_size (BITS_PER_WORD
, 1), 0);
9401 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
9402 TREE_PUBLIC (decl
) = 1;
9403 TREE_READONLY (decl
) = 1;
9404 TREE_USED (decl
) = 1;
9405 TREE_CONSTANT (decl
) = 1;
9406 DECL_CONTEXT (decl
) = 0;
9407 DECL_ARTIFICIAL (decl
) = 1;
9408 DECL_INITIAL (decl
) = init
;
9409 assemble_variable (decl
, 1, 0, 0);
9413 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9414 later requires that ObjC translation units participating in F&C be
9415 specially marked. The following routine accomplishes this. */
9417 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9420 generate_objc_image_info (void)
9422 tree decl
, initlist
;
9424 = ((flag_replace_objc_classes
&& imp_list
? 1 : 0)
9425 | (flag_objc_gc
? 2 : 0));
9427 decl
= start_var_decl (build_array_type
9429 build_index_type (build_int_cst (NULL_TREE
, 2 - 1))),
9430 "_OBJC_IMAGE_INFO");
9432 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, 0));
9433 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, flags
), initlist
);
9434 initlist
= objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
9436 finish_var_decl (decl
, initlist
);
9439 /* Look up ID as an instance variable. OTHER contains the result of
9440 the C or C++ lookup, which we may want to use instead. */
9443 objc_lookup_ivar (tree other
, tree id
)
9447 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9448 if (!objc_method_context
)
9451 if (!strcmp (IDENTIFIER_POINTER (id
), "super"))
9452 /* We have a message to super. */
9453 return get_super_receiver ();
9455 /* In a class method, look up an instance variable only as a last
9457 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
9458 && other
&& other
!= error_mark_node
)
9461 /* Look up the ivar, but do not use it if it is not accessible. */
9462 ivar
= is_ivar (objc_ivar_chain
, id
);
9464 if (!ivar
|| is_private (ivar
))
9467 /* In an instance method, a local variable (or parameter) may hide the
9468 instance variable. */
9469 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
9470 && other
&& other
!= error_mark_node
9472 && CP_DECL_CONTEXT (other
) != global_namespace
)
9474 && !DECL_FILE_SCOPE_P (other
))
9477 warning (0, "local declaration of %qs hides instance variable",
9478 IDENTIFIER_POINTER (id
));
9483 /* At this point, we are either in an instance method with no obscuring
9484 local definitions, or in a class method with no alternate definitions
9486 return build_ivar_reference (id
);
9489 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9490 needs to be done if we are calling a function through a cast. */
9493 objc_rewrite_function_call (tree function
, tree params
)
9495 if (TREE_CODE (function
) == NOP_EXPR
9496 && TREE_CODE (TREE_OPERAND (function
, 0)) == ADDR_EXPR
9497 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function
, 0), 0))
9500 function
= build3 (OBJ_TYPE_REF
, TREE_TYPE (function
),
9501 TREE_OPERAND (function
, 0),
9502 TREE_VALUE (params
), size_zero_node
);
9508 /* Look for the special case of OBJC_TYPE_REF with the address of
9509 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9512 enum gimplify_status
9513 objc_gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
9515 enum gimplify_status r0
, r1
;
9516 if (TREE_CODE (*expr_p
) == OBJ_TYPE_REF
9517 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p
)) == ADDR_EXPR
9518 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p
), 0))
9521 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9522 value of the OBJ_TYPE_REF, so force them to be emitted
9523 during subexpression evaluation rather than after the
9524 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9525 C to use direct rather than indirect calls when the
9526 object expression has a postincrement. */
9527 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
, NULL
,
9528 is_gimple_val
, fb_rvalue
);
9529 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
, post_p
,
9530 is_gimple_val
, fb_rvalue
);
9532 return MIN (r0
, r1
);
9536 return cp_gimplify_expr (expr_p
, pre_p
, post_p
);
9538 return c_gimplify_expr (expr_p
, pre_p
, post_p
);
9542 #include "gt-objc-objc-act.h"