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 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
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 #ifndef USE_MAPPED_LOCATION
488 /* Force the line number back to 0; check_newline will have
489 raised it to 1, which will make the builtin functions appear
490 not to be built in. */
494 /* If gen_declaration desired, open the output file. */
495 if (flag_gen_declaration
)
497 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
498 gen_declaration_file
= fopen (dumpname
, "w");
499 if (gen_declaration_file
== 0)
500 fatal_error ("can't open %s: %m", dumpname
);
504 if (flag_next_runtime
)
506 TAG_GETCLASS
= "objc_getClass";
507 TAG_GETMETACLASS
= "objc_getMetaClass";
508 TAG_MSGSEND
= "objc_msgSend";
509 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
510 TAG_MSGSEND_STRET
= "objc_msgSend_stret";
511 TAG_MSGSENDSUPER_STRET
= "objc_msgSendSuper_stret";
512 default_constant_string_class_name
= "NSConstantString";
516 TAG_GETCLASS
= "objc_get_class";
517 TAG_GETMETACLASS
= "objc_get_meta_class";
518 TAG_MSGSEND
= "objc_msg_lookup";
519 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
520 /* GNU runtime does not provide special functions to support
521 structure-returning methods. */
522 default_constant_string_class_name
= "NXConstantString";
523 flag_typed_selectors
= 1;
528 if (print_struct_values
)
529 generate_struct_by_value_array ();
535 objc_finish_file (void)
537 mark_referenced_methods ();
540 /* We need to instantiate templates _before_ we emit ObjC metadata;
541 if we do not, some metadata (such as selectors) may go missing. */
543 instantiate_pending_templates (0);
546 /* Finalize Objective-C runtime data. No need to generate tables
547 and code if only checking syntax, or if generating a PCH file. */
548 if (!flag_syntax_only
&& !pch_file
)
551 if (gen_declaration_file
)
552 fclose (gen_declaration_file
);
555 /* Return the first occurrence of a method declaration corresponding
556 to sel_name in rproto_list. Search rproto_list recursively.
557 If is_class is 0, search for instance methods, otherwise for class
560 lookup_method_in_protocol_list (tree rproto_list
, tree sel_name
,
566 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
568 p
= TREE_VALUE (rproto
);
570 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
572 if ((fnd
= lookup_method (is_class
573 ? PROTOCOL_CLS_METHODS (p
)
574 : PROTOCOL_NST_METHODS (p
), sel_name
)))
576 else if (PROTOCOL_LIST (p
))
577 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
582 ; /* An identifier...if we could not find a protocol. */
593 lookup_protocol_in_reflist (tree rproto_list
, tree lproto
)
597 /* Make sure the protocol is supported by the object on the rhs. */
598 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
601 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
603 p
= TREE_VALUE (rproto
);
605 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
610 else if (PROTOCOL_LIST (p
))
611 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
620 ; /* An identifier...if we could not find a protocol. */
627 objc_start_class_interface (tree
class, tree super_class
, tree protos
)
629 objc_interface_context
631 = start_class (CLASS_INTERFACE_TYPE
, class, super_class
, protos
);
632 objc_public_flag
= 0;
636 objc_start_category_interface (tree
class, tree categ
, tree protos
)
638 objc_interface_context
639 = start_class (CATEGORY_INTERFACE_TYPE
, class, categ
, protos
);
641 = continue_class (objc_interface_context
);
645 objc_start_protocol (tree name
, tree protos
)
647 objc_interface_context
648 = start_protocol (PROTOCOL_INTERFACE_TYPE
, name
, protos
);
652 objc_continue_interface (void)
655 = continue_class (objc_interface_context
);
659 objc_finish_interface (void)
661 finish_class (objc_interface_context
);
662 objc_interface_context
= NULL_TREE
;
666 objc_start_class_implementation (tree
class, tree super_class
)
668 objc_implementation_context
670 = start_class (CLASS_IMPLEMENTATION_TYPE
, class, super_class
, NULL_TREE
);
671 objc_public_flag
= 0;
675 objc_start_category_implementation (tree
class, tree categ
)
677 objc_implementation_context
678 = start_class (CATEGORY_IMPLEMENTATION_TYPE
, class, categ
, NULL_TREE
);
680 = continue_class (objc_implementation_context
);
684 objc_continue_implementation (void)
687 = continue_class (objc_implementation_context
);
691 objc_finish_implementation (void)
694 if (flag_objc_call_cxx_cdtors
)
695 objc_generate_cxx_cdtors ();
698 if (objc_implementation_context
)
700 finish_class (objc_implementation_context
);
701 objc_ivar_chain
= NULL_TREE
;
702 objc_implementation_context
= NULL_TREE
;
705 warning (0, "%<@end%> must appear in an @implementation context");
709 objc_set_visibility (int visibility
)
711 objc_public_flag
= visibility
;
715 objc_set_method_type (enum tree_code type
)
717 objc_inherit_code
= (type
== PLUS_EXPR
719 : INSTANCE_METHOD_DECL
);
723 objc_build_method_signature (tree rettype
, tree selector
,
724 tree optparms
, bool ellipsis
)
726 return build_method_decl (objc_inherit_code
, rettype
, selector
,
731 objc_add_method_declaration (tree decl
)
733 if (!objc_interface_context
)
734 fatal_error ("method declaration not in @interface context");
736 objc_add_method (objc_interface_context
,
738 objc_inherit_code
== CLASS_METHOD_DECL
);
742 objc_start_method_definition (tree decl
)
744 if (!objc_implementation_context
)
745 fatal_error ("method definition not in @implementation context");
747 objc_add_method (objc_implementation_context
,
749 objc_inherit_code
== CLASS_METHOD_DECL
);
750 start_method_def (decl
);
754 objc_add_instance_variable (tree decl
)
756 (void) add_instance_variable (objc_ivar_context
,
761 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
765 objc_is_reserved_word (tree ident
)
767 unsigned char code
= C_RID_CODE (ident
);
769 return (OBJC_IS_AT_KEYWORD (code
)
771 || code
== RID_CLASS
|| code
== RID_PUBLIC
772 || code
== RID_PROTECTED
|| code
== RID_PRIVATE
773 || code
== RID_TRY
|| code
== RID_THROW
|| code
== RID_CATCH
778 /* Return true if TYPE is 'id'. */
781 objc_is_object_id (tree type
)
783 return OBJC_TYPE_NAME (type
) == objc_object_id
;
787 objc_is_class_id (tree type
)
789 return OBJC_TYPE_NAME (type
) == objc_class_id
;
792 /* Construct a C struct with same name as CLASS, a base struct with tag
793 SUPER_NAME (if any), and FIELDS indicated. */
796 objc_build_struct (tree
class, tree fields
, tree super_name
)
798 tree name
= CLASS_NAME (class);
799 tree s
= start_struct (RECORD_TYPE
, name
);
800 tree super
= (super_name
? xref_tag (RECORD_TYPE
, super_name
) : NULL_TREE
);
801 tree t
, objc_info
= NULL_TREE
;
805 /* Prepend a packed variant of the base class into the layout. This
806 is necessary to preserve ObjC ABI compatibility. */
807 tree base
= build_decl (FIELD_DECL
, NULL_TREE
, super
);
808 tree field
= TYPE_FIELDS (super
);
810 while (field
&& TREE_CHAIN (field
)
811 && TREE_CODE (TREE_CHAIN (field
)) == FIELD_DECL
)
812 field
= TREE_CHAIN (field
);
814 /* For ObjC ABI purposes, the "packed" size of a base class is the
815 the sum of the offset and the size (in bits) of the last field
818 = (field
&& TREE_CODE (field
) == FIELD_DECL
819 ? size_binop (PLUS_EXPR
,
820 size_binop (PLUS_EXPR
,
823 convert (bitsizetype
,
824 DECL_FIELD_OFFSET (field
)),
825 bitsize_int (BITS_PER_UNIT
)),
826 DECL_FIELD_BIT_OFFSET (field
)),
828 : bitsize_zero_node
);
829 DECL_SIZE_UNIT (base
)
830 = size_binop (FLOOR_DIV_EXPR
, convert (sizetype
, DECL_SIZE (base
)),
831 size_int (BITS_PER_UNIT
));
832 DECL_ARTIFICIAL (base
) = 1;
833 DECL_ALIGN (base
) = 1;
834 DECL_FIELD_CONTEXT (base
) = s
;
836 DECL_FIELD_IS_BASE (base
) = 1;
839 TREE_NO_WARNING (fields
) = 1; /* Suppress C++ ABI warnings -- we */
840 #endif /* are following the ObjC ABI here. */
841 TREE_CHAIN (base
) = fields
;
845 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
846 in all variants of this RECORD_TYPE to be clobbered, but it is therein
847 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
848 Hence, we must squirrel away the ObjC-specific information before calling
849 finish_struct(), and then reinstate it afterwards. */
851 for (t
= TYPE_NEXT_VARIANT (s
); t
; t
= TYPE_NEXT_VARIANT (t
))
853 = chainon (objc_info
,
854 build_tree_list (NULL_TREE
, TYPE_OBJC_INFO (t
)));
856 /* Point the struct at its related Objective-C class. */
857 INIT_TYPE_OBJC_INFO (s
);
858 TYPE_OBJC_INTERFACE (s
) = class;
860 s
= finish_struct (s
, fields
, NULL_TREE
);
862 for (t
= TYPE_NEXT_VARIANT (s
); t
;
863 t
= TYPE_NEXT_VARIANT (t
), objc_info
= TREE_CHAIN (objc_info
))
865 TYPE_OBJC_INFO (t
) = TREE_VALUE (objc_info
);
866 /* Replace the IDENTIFIER_NODE with an actual @interface. */
867 TYPE_OBJC_INTERFACE (t
) = class;
870 /* Use TYPE_BINFO structures to point at the super class, if any. */
871 objc_xref_basetypes (s
, super
);
873 /* Mark this struct as a class template. */
874 CLASS_STATIC_TEMPLATE (class) = s
;
879 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
880 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
883 objc_build_volatilized_type (tree type
)
887 /* Check if we have not constructed the desired variant already. */
888 for (t
= TYPE_MAIN_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
890 /* The type qualifiers must (obviously) match up. */
891 if (!TYPE_VOLATILE (t
)
892 || (TYPE_READONLY (t
) != TYPE_READONLY (type
))
893 || (TYPE_RESTRICT (t
) != TYPE_RESTRICT (type
)))
896 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
897 info, if any) must match up. */
898 if (POINTER_TYPE_P (t
)
899 && (TREE_TYPE (t
) != TREE_TYPE (type
)))
902 /* Everything matches up! */
906 /* Ok, we could not re-use any of the pre-existing variants. Create
908 t
= build_variant_type_copy (type
);
909 TYPE_VOLATILE (t
) = 1;
911 /* Set up the canonical type information. */
912 if (TYPE_STRUCTURAL_EQUALITY_P (type
))
913 SET_TYPE_STRUCTURAL_EQUALITY (t
);
914 else if (TYPE_CANONICAL (type
) != type
)
915 TYPE_CANONICAL (t
) = objc_build_volatilized_type (TYPE_CANONICAL (type
));
917 TYPE_CANONICAL (t
) = t
;
922 /* Mark DECL as being 'volatile' for purposes of Darwin
923 _setjmp()/_longjmp() exception handling. Called from
924 objc_mark_locals_volatile(). */
926 objc_volatilize_decl (tree decl
)
928 /* Do not mess with variables that are 'static' or (already)
930 if (!TREE_THIS_VOLATILE (decl
) && !TREE_STATIC (decl
)
931 && (TREE_CODE (decl
) == VAR_DECL
932 || TREE_CODE (decl
) == PARM_DECL
))
934 tree t
= TREE_TYPE (decl
);
935 struct volatilized_type key
;
938 t
= objc_build_volatilized_type (t
);
940 loc
= htab_find_slot (volatilized_htab
, &key
, INSERT
);
944 *loc
= ggc_alloc (sizeof (key
));
945 ((struct volatilized_type
*) *loc
)->type
= t
;
948 TREE_TYPE (decl
) = t
;
949 TREE_THIS_VOLATILE (decl
) = 1;
950 TREE_SIDE_EFFECTS (decl
) = 1;
951 DECL_REGISTER (decl
) = 0;
953 C_DECL_REGISTER (decl
) = 0;
958 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
959 (including its categories and superclasses) or by object type TYP.
960 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
963 objc_lookup_protocol (tree proto
, tree cls
, tree typ
, bool warn
)
965 bool class_type
= (cls
!= NULL_TREE
);
971 /* Check protocols adopted by the class and its categories. */
972 for (c
= cls
; c
; c
= CLASS_CATEGORY_LIST (c
))
974 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c
), proto
))
978 /* Repeat for superclasses. */
979 cls
= lookup_interface (CLASS_SUPER_NAME (cls
));
982 /* Check for any protocols attached directly to the object type. */
983 if (TYPE_HAS_OBJC_INFO (typ
))
985 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ
), proto
))
991 strcpy (errbuf
, class_type
? "class \'" : "type \'");
992 gen_type_name_0 (class_type
? typ
: TYPE_POINTER_TO (typ
));
993 strcat (errbuf
, "\' does not ");
994 /* NB: Types 'id' and 'Class' cannot reasonably be described as
995 "implementing" a given protocol, since they do not have an
997 strcat (errbuf
, class_type
? "implement" : "conform to");
998 strcat (errbuf
, " the \'");
999 strcat (errbuf
, IDENTIFIER_POINTER (PROTOCOL_NAME (proto
)));
1000 strcat (errbuf
, "\' protocol");
1001 warning (0, errbuf
);
1007 /* Check if class RCLS and instance struct type RTYP conform to at least the
1008 same protocols that LCLS and LTYP conform to. */
1011 objc_compare_protocols (tree lcls
, tree ltyp
, tree rcls
, tree rtyp
, bool warn
)
1014 bool have_lproto
= false;
1018 /* NB: We do _not_ look at categories defined for LCLS; these may or
1019 may not get loaded in, and therefore it is unreasonable to require
1020 that RCLS/RTYP must implement any of their protocols. */
1021 for (p
= CLASS_PROTOCOL_LIST (lcls
); p
; p
= TREE_CHAIN (p
))
1025 if (!objc_lookup_protocol (TREE_VALUE (p
), rcls
, rtyp
, warn
))
1029 /* Repeat for superclasses. */
1030 lcls
= lookup_interface (CLASS_SUPER_NAME (lcls
));
1033 /* Check for any protocols attached directly to the object type. */
1034 if (TYPE_HAS_OBJC_INFO (ltyp
))
1036 for (p
= TYPE_OBJC_PROTOCOL_LIST (ltyp
); p
; p
= TREE_CHAIN (p
))
1040 if (!objc_lookup_protocol (TREE_VALUE (p
), rcls
, rtyp
, warn
))
1045 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1046 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1047 away with simply checking for 'id' or 'Class' (!RCLS), since this
1048 routine will not get called in other cases. */
1049 return have_lproto
|| (rcls
!= NULL_TREE
);
1052 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1053 an instance of RTYP to an instance of LTYP or to compare the two
1054 (if ARGNO is equal to -3), per ObjC type system rules. Before
1055 returning 'true', this routine may issue warnings related to, e.g.,
1056 protocol conformance. When returning 'false', the routine must
1057 produce absolutely no warnings; the C or C++ front-end will do so
1058 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1059 the routine must return 'false'.
1061 The ARGNO parameter is encoded as follows:
1062 >= 1 Parameter number (CALLEE contains function being called);
1066 -3 Comparison (LTYP and RTYP may match in either direction). */
1069 objc_compare_types (tree ltyp
, tree rtyp
, int argno
, tree callee
)
1071 tree lcls
, rcls
, lproto
, rproto
;
1072 bool pointers_compatible
;
1074 /* We must be dealing with pointer types */
1075 if (!POINTER_TYPE_P (ltyp
) || !POINTER_TYPE_P (rtyp
))
1080 ltyp
= TREE_TYPE (ltyp
); /* Remove indirections. */
1081 rtyp
= TREE_TYPE (rtyp
);
1083 while (POINTER_TYPE_P (ltyp
) && POINTER_TYPE_P (rtyp
));
1085 /* Past this point, we are only interested in ObjC class instances,
1086 or 'id' or 'Class'. */
1087 if (TREE_CODE (ltyp
) != RECORD_TYPE
|| TREE_CODE (rtyp
) != RECORD_TYPE
)
1090 if (!objc_is_object_id (ltyp
) && !objc_is_class_id (ltyp
)
1091 && !TYPE_HAS_OBJC_INFO (ltyp
))
1094 if (!objc_is_object_id (rtyp
) && !objc_is_class_id (rtyp
)
1095 && !TYPE_HAS_OBJC_INFO (rtyp
))
1098 /* Past this point, we are committed to returning 'true' to the caller.
1099 However, we can still warn about type and/or protocol mismatches. */
1101 if (TYPE_HAS_OBJC_INFO (ltyp
))
1103 lcls
= TYPE_OBJC_INTERFACE (ltyp
);
1104 lproto
= TYPE_OBJC_PROTOCOL_LIST (ltyp
);
1107 lcls
= lproto
= NULL_TREE
;
1109 if (TYPE_HAS_OBJC_INFO (rtyp
))
1111 rcls
= TYPE_OBJC_INTERFACE (rtyp
);
1112 rproto
= TYPE_OBJC_PROTOCOL_LIST (rtyp
);
1115 rcls
= rproto
= NULL_TREE
;
1117 /* If we could not find an @interface declaration, we must have
1118 only seen a @class declaration; for purposes of type comparison,
1119 treat it as a stand-alone (root) class. */
1121 if (lcls
&& TREE_CODE (lcls
) == IDENTIFIER_NODE
)
1124 if (rcls
&& TREE_CODE (rcls
) == IDENTIFIER_NODE
)
1127 /* If either type is an unqualified 'id', we're done. */
1128 if ((!lproto
&& objc_is_object_id (ltyp
))
1129 || (!rproto
&& objc_is_object_id (rtyp
)))
1132 pointers_compatible
= (TYPE_MAIN_VARIANT (ltyp
) == TYPE_MAIN_VARIANT (rtyp
));
1134 /* If the underlying types are the same, and at most one of them has
1135 a protocol list, we do not need to issue any diagnostics. */
1136 if (pointers_compatible
&& (!lproto
|| !rproto
))
1139 /* If exactly one of the types is 'Class', issue a diagnostic; any
1140 exceptions of this rule have already been handled. */
1141 if (objc_is_class_id (ltyp
) ^ objc_is_class_id (rtyp
))
1142 pointers_compatible
= false;
1143 /* Otherwise, check for inheritance relations. */
1146 if (!pointers_compatible
)
1148 = (objc_is_object_id (ltyp
) || objc_is_object_id (rtyp
));
1150 if (!pointers_compatible
)
1151 pointers_compatible
= DERIVED_FROM_P (ltyp
, rtyp
);
1153 if (!pointers_compatible
&& argno
== -3)
1154 pointers_compatible
= DERIVED_FROM_P (rtyp
, ltyp
);
1157 /* If the pointers match modulo protocols, check for protocol conformance
1159 if (pointers_compatible
)
1161 pointers_compatible
= objc_compare_protocols (lcls
, ltyp
, rcls
, rtyp
,
1164 if (!pointers_compatible
&& argno
== -3)
1165 pointers_compatible
= objc_compare_protocols (rcls
, rtyp
, lcls
, ltyp
,
1169 if (!pointers_compatible
)
1171 /* NB: For the time being, we shall make our warnings look like their
1172 C counterparts. In the future, we may wish to make them more
1177 warning (0, "comparison of distinct Objective-C types lacks a cast");
1181 warning (0, "initialization from distinct Objective-C type");
1185 warning (0, "assignment from distinct Objective-C type");
1189 warning (0, "distinct Objective-C type in return");
1193 warning (0, "passing argument %d of %qE from distinct "
1194 "Objective-C type", argno
, callee
);
1202 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1203 lives in the volatilized hash table, ignore the 'volatile' bit when
1204 making the comparison. */
1207 objc_type_quals_match (tree ltyp
, tree rtyp
)
1209 int lquals
= TYPE_QUALS (ltyp
), rquals
= TYPE_QUALS (rtyp
);
1210 struct volatilized_type key
;
1214 if (htab_find_slot (volatilized_htab
, &key
, NO_INSERT
))
1215 lquals
&= ~TYPE_QUAL_VOLATILE
;
1219 if (htab_find_slot (volatilized_htab
, &key
, NO_INSERT
))
1220 rquals
&= ~TYPE_QUAL_VOLATILE
;
1222 return (lquals
== rquals
);
1226 /* Determine if CHILD is derived from PARENT. The routine assumes that
1227 both parameters are RECORD_TYPEs, and is non-reflexive. */
1230 objc_derived_from_p (tree parent
, tree child
)
1232 parent
= TYPE_MAIN_VARIANT (parent
);
1234 for (child
= TYPE_MAIN_VARIANT (child
);
1235 TYPE_BINFO (child
) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child
));)
1237 child
= TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1238 (TYPE_BINFO (child
),
1241 if (child
== parent
)
1250 objc_build_component_ref (tree datum
, tree component
)
1252 /* If COMPONENT is NULL, the caller is referring to the anonymous
1253 base class field. */
1256 tree base
= TYPE_FIELDS (TREE_TYPE (datum
));
1258 return build3 (COMPONENT_REF
, TREE_TYPE (base
), datum
, base
, NULL_TREE
);
1261 /* The 'build_component_ref' routine has been removed from the C++
1262 front-end, but 'finish_class_member_access_expr' seems to be
1263 a worthy substitute. */
1265 return finish_class_member_access_expr (datum
, component
, false);
1267 return build_component_ref (datum
, component
);
1271 /* Recursively copy inheritance information rooted at BINFO. To do this,
1272 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1275 objc_copy_binfo (tree binfo
)
1277 tree btype
= BINFO_TYPE (binfo
);
1278 tree binfo2
= make_tree_binfo (BINFO_N_BASE_BINFOS (binfo
));
1282 BINFO_TYPE (binfo2
) = btype
;
1283 BINFO_OFFSET (binfo2
) = BINFO_OFFSET (binfo
);
1284 BINFO_BASE_ACCESSES (binfo2
) = BINFO_BASE_ACCESSES (binfo
);
1286 /* Recursively copy base binfos of BINFO. */
1287 for (ix
= 0; BINFO_BASE_ITERATE (binfo
, ix
, base_binfo
); ix
++)
1289 tree base_binfo2
= objc_copy_binfo (base_binfo
);
1291 BINFO_INHERITANCE_CHAIN (base_binfo2
) = binfo2
;
1292 BINFO_BASE_APPEND (binfo2
, base_binfo2
);
1298 /* Record superclass information provided in BASETYPE for ObjC class REF.
1299 This is loosely based on cp/decl.c:xref_basetypes(). */
1302 objc_xref_basetypes (tree ref
, tree basetype
)
1304 tree binfo
= make_tree_binfo (basetype
? 1 : 0);
1306 TYPE_BINFO (ref
) = binfo
;
1307 BINFO_OFFSET (binfo
) = size_zero_node
;
1308 BINFO_TYPE (binfo
) = ref
;
1312 tree base_binfo
= objc_copy_binfo (TYPE_BINFO (basetype
));
1314 BINFO_INHERITANCE_CHAIN (base_binfo
) = binfo
;
1315 BINFO_BASE_ACCESSES (binfo
) = VEC_alloc (tree
, gc
, 1);
1316 BINFO_BASE_APPEND (binfo
, base_binfo
);
1317 BINFO_BASE_ACCESS_APPEND (binfo
, access_public_node
);
1322 volatilized_hash (const void *ptr
)
1324 tree typ
= ((struct volatilized_type
*)ptr
)->type
;
1326 return htab_hash_pointer(typ
);
1330 volatilized_eq (const void *ptr1
, const void *ptr2
)
1332 tree typ1
= ((struct volatilized_type
*)ptr1
)->type
;
1333 tree typ2
= ((struct volatilized_type
*)ptr2
)->type
;
1335 return typ1
== typ2
;
1338 /* Called from finish_decl. */
1341 objc_check_decl (tree decl
)
1343 tree type
= TREE_TYPE (decl
);
1345 if (TREE_CODE (type
) != RECORD_TYPE
)
1347 if (OBJC_TYPE_NAME (type
) && (type
= objc_is_class_name (OBJC_TYPE_NAME (type
))))
1348 error ("statically allocated instance of Objective-C class %qs",
1349 IDENTIFIER_POINTER (type
));
1352 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1353 either name an Objective-C class, or refer to the special 'id' or 'Class'
1354 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1357 objc_get_protocol_qualified_type (tree interface
, tree protocols
)
1359 /* If INTERFACE is not provided, default to 'id'. */
1360 tree type
= (interface
? objc_is_id (interface
) : objc_object_type
);
1361 bool is_ptr
= (type
!= NULL_TREE
);
1365 type
= objc_is_class_name (interface
);
1368 type
= xref_tag (RECORD_TYPE
, type
);
1375 type
= build_variant_type_copy (type
);
1377 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1381 tree orig_pointee_type
= TREE_TYPE (type
);
1382 TREE_TYPE (type
) = build_variant_type_copy (orig_pointee_type
);
1384 /* Set up the canonical type information. */
1385 TYPE_CANONICAL (type
)
1386 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type
));
1388 TYPE_POINTER_TO (TREE_TYPE (type
)) = type
;
1389 type
= TREE_TYPE (type
);
1392 /* Look up protocols and install in lang specific list. */
1393 DUP_TYPE_OBJC_INFO (type
, TYPE_MAIN_VARIANT (type
));
1394 TYPE_OBJC_PROTOCOL_LIST (type
) = lookup_and_install_protocols (protocols
);
1396 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1397 return the pointer to the new pointee variant. */
1399 type
= TYPE_POINTER_TO (type
);
1401 TYPE_OBJC_INTERFACE (type
)
1402 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type
));
1408 /* Check for circular dependencies in protocols. The arguments are
1409 PROTO, the protocol to check, and LIST, a list of protocol it
1413 check_protocol_recursively (tree proto
, tree list
)
1417 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1419 tree pp
= TREE_VALUE (p
);
1421 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1422 pp
= lookup_protocol (pp
);
1425 fatal_error ("protocol %qs has circular dependency",
1426 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1428 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1432 /* Look up PROTOCOLS, and return a list of those that are found.
1433 If none are found, return NULL. */
1436 lookup_and_install_protocols (tree protocols
)
1439 tree return_value
= NULL_TREE
;
1441 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1443 tree ident
= TREE_VALUE (proto
);
1444 tree p
= lookup_protocol (ident
);
1447 return_value
= chainon (return_value
,
1448 build_tree_list (NULL_TREE
, p
));
1449 else if (ident
!= error_mark_node
)
1450 error ("cannot find protocol declaration for %qs",
1451 IDENTIFIER_POINTER (ident
));
1454 return return_value
;
1457 /* Create a declaration for field NAME of a given TYPE. */
1460 create_field_decl (tree type
, const char *name
)
1462 return build_decl (FIELD_DECL
, get_identifier (name
), type
);
1465 /* Create a global, static declaration for variable NAME of a given TYPE. The
1466 finish_var_decl() routine will need to be called on it afterwards. */
1469 start_var_decl (tree type
, const char *name
)
1471 tree var
= build_decl (VAR_DECL
, get_identifier (name
), type
);
1473 TREE_STATIC (var
) = 1;
1474 DECL_INITIAL (var
) = error_mark_node
; /* A real initializer is coming... */
1475 DECL_IGNORED_P (var
) = 1;
1476 DECL_ARTIFICIAL (var
) = 1;
1477 DECL_CONTEXT (var
) = NULL_TREE
;
1479 DECL_THIS_STATIC (var
) = 1; /* squash redeclaration errors */
1485 /* Finish off the variable declaration created by start_var_decl(). */
1488 finish_var_decl (tree var
, tree initializer
)
1490 finish_decl (var
, initializer
, NULL_TREE
);
1491 /* Ensure that the variable actually gets output. */
1492 mark_decl_referenced (var
);
1493 /* Mark the decl to avoid "defined but not used" warning. */
1494 TREE_USED (var
) = 1;
1497 /* Find the decl for the constant string class reference. This is only
1498 used for the NeXT runtime. */
1501 setup_string_decl (void)
1506 /* %s in format will provide room for terminating null */
1507 length
= strlen (STRING_OBJECT_GLOBAL_FORMAT
)
1508 + strlen (constant_string_class_name
);
1509 name
= xmalloc (length
);
1510 sprintf (name
, STRING_OBJECT_GLOBAL_FORMAT
,
1511 constant_string_class_name
);
1512 constant_string_global_id
= get_identifier (name
);
1513 string_class_decl
= lookup_name (constant_string_global_id
);
1515 return string_class_decl
;
1518 /* Purpose: "play" parser, creating/installing representations
1519 of the declarations that are required by Objective-C.
1523 type_spec--------->sc_spec
1524 (tree_list) (tree_list)
1527 identifier_node identifier_node */
1530 synth_module_prologue (void)
1533 enum debug_info_type save_write_symbols
= write_symbols
;
1534 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
1536 /* Suppress outputting debug symbols, because
1537 dbxout_init hasn'r been called yet. */
1538 write_symbols
= NO_DEBUG
;
1539 debug_hooks
= &do_nothing_debug_hooks
;
1542 push_lang_context (lang_name_c
); /* extern "C" */
1545 /* The following are also defined in <objc/objc.h> and friends. */
1547 objc_object_id
= get_identifier (TAG_OBJECT
);
1548 objc_class_id
= get_identifier (TAG_CLASS
);
1550 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1551 objc_class_reference
= xref_tag (RECORD_TYPE
, objc_class_id
);
1553 objc_object_type
= build_pointer_type (objc_object_reference
);
1554 objc_class_type
= build_pointer_type (objc_class_reference
);
1556 objc_object_name
= get_identifier (OBJECT_TYPEDEF_NAME
);
1557 objc_class_name
= get_identifier (CLASS_TYPEDEF_NAME
);
1559 /* Declare the 'id' and 'Class' typedefs. */
1561 type
= lang_hooks
.decls
.pushdecl (build_decl (TYPE_DECL
,
1564 DECL_IN_SYSTEM_HEADER (type
) = 1;
1565 type
= lang_hooks
.decls
.pushdecl (build_decl (TYPE_DECL
,
1568 DECL_IN_SYSTEM_HEADER (type
) = 1;
1570 /* Forward-declare '@interface Protocol'. */
1572 type
= get_identifier (PROTOCOL_OBJECT_CLASS_NAME
);
1573 objc_declare_class (tree_cons (NULL_TREE
, type
, NULL_TREE
));
1574 objc_protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1577 /* Declare type of selector-objects that represent an operation name. */
1579 if (flag_next_runtime
)
1580 /* `struct objc_selector *' */
1582 = build_pointer_type (xref_tag (RECORD_TYPE
,
1583 get_identifier (TAG_SELECTOR
)));
1585 /* `const struct objc_selector *' */
1587 = build_pointer_type
1588 (build_qualified_type (xref_tag (RECORD_TYPE
,
1589 get_identifier (TAG_SELECTOR
)),
1592 /* Declare receiver type used for dispatching messages to 'super'. */
1594 /* `struct objc_super *' */
1595 objc_super_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1596 get_identifier (TAG_SUPER
)));
1598 /* Declare pointers to method and ivar lists. */
1599 objc_method_list_ptr
= build_pointer_type
1600 (xref_tag (RECORD_TYPE
,
1601 get_identifier (UTAG_METHOD_LIST
)));
1602 objc_method_proto_list_ptr
1603 = build_pointer_type (xref_tag (RECORD_TYPE
,
1604 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
1605 objc_ivar_list_ptr
= build_pointer_type
1606 (xref_tag (RECORD_TYPE
,
1607 get_identifier (UTAG_IVAR_LIST
)));
1609 /* TREE_NOTHROW is cleared for the message-sending functions,
1610 because the function that gets called can throw in Obj-C++, or
1611 could itself call something that can throw even in Obj-C. */
1613 if (flag_next_runtime
)
1615 /* NB: In order to call one of the ..._stret (struct-returning)
1616 functions, the function *MUST* first be cast to a signature that
1617 corresponds to the actual ObjC method being invoked. This is
1618 what is done by the build_objc_method_call() routine below. */
1620 /* id objc_msgSend (id, SEL, ...); */
1621 /* id objc_msgSendNonNil (id, SEL, ...); */
1622 /* id objc_msgSend_stret (id, SEL, ...); */
1623 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1625 = build_function_type (objc_object_type
,
1626 tree_cons (NULL_TREE
, objc_object_type
,
1627 tree_cons (NULL_TREE
, objc_selector_type
,
1629 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
1630 type
, 0, NOT_BUILT_IN
,
1632 umsg_nonnil_decl
= add_builtin_function (TAG_MSGSEND_NONNIL
,
1633 type
, 0, NOT_BUILT_IN
,
1635 umsg_stret_decl
= add_builtin_function (TAG_MSGSEND_STRET
,
1636 type
, 0, NOT_BUILT_IN
,
1638 umsg_nonnil_stret_decl
= add_builtin_function (TAG_MSGSEND_NONNIL_STRET
,
1639 type
, 0, NOT_BUILT_IN
,
1642 /* These can throw, because the function that gets called can throw
1643 in Obj-C++, or could itself call something that can throw even
1645 TREE_NOTHROW (umsg_decl
) = 0;
1646 TREE_NOTHROW (umsg_nonnil_decl
) = 0;
1647 TREE_NOTHROW (umsg_stret_decl
) = 0;
1648 TREE_NOTHROW (umsg_nonnil_stret_decl
) = 0;
1650 /* id objc_msgSend_Fast (id, SEL, ...)
1651 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1652 #ifdef OFFS_MSGSEND_FAST
1653 umsg_fast_decl
= add_builtin_function (TAG_MSGSEND_FAST
,
1654 type
, 0, NOT_BUILT_IN
,
1656 TREE_NOTHROW (umsg_fast_decl
) = 0;
1657 DECL_ATTRIBUTES (umsg_fast_decl
)
1658 = tree_cons (get_identifier ("hard_coded_address"),
1659 build_int_cst (NULL_TREE
, OFFS_MSGSEND_FAST
),
1662 /* No direct dispatch available. */
1663 umsg_fast_decl
= umsg_decl
;
1666 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1667 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1669 = build_function_type (objc_object_type
,
1670 tree_cons (NULL_TREE
, objc_super_type
,
1671 tree_cons (NULL_TREE
, objc_selector_type
,
1673 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
1674 type
, 0, NOT_BUILT_IN
,
1676 umsg_super_stret_decl
= add_builtin_function (TAG_MSGSENDSUPER_STRET
,
1677 type
, 0, NOT_BUILT_IN
, 0,
1679 TREE_NOTHROW (umsg_super_decl
) = 0;
1680 TREE_NOTHROW (umsg_super_stret_decl
) = 0;
1684 /* GNU runtime messenger entry points. */
1686 /* typedef id (*IMP)(id, SEL, ...); */
1688 = build_pointer_type
1689 (build_function_type (objc_object_type
,
1690 tree_cons (NULL_TREE
, objc_object_type
,
1691 tree_cons (NULL_TREE
, objc_selector_type
,
1694 /* IMP objc_msg_lookup (id, SEL); */
1696 = build_function_type (IMP_type
,
1697 tree_cons (NULL_TREE
, objc_object_type
,
1698 tree_cons (NULL_TREE
, objc_selector_type
,
1699 OBJC_VOID_AT_END
)));
1700 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
1701 type
, 0, NOT_BUILT_IN
,
1703 TREE_NOTHROW (umsg_decl
) = 0;
1705 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1707 = build_function_type (IMP_type
,
1708 tree_cons (NULL_TREE
, objc_super_type
,
1709 tree_cons (NULL_TREE
, objc_selector_type
,
1710 OBJC_VOID_AT_END
)));
1711 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
1712 type
, 0, NOT_BUILT_IN
,
1714 TREE_NOTHROW (umsg_super_decl
) = 0;
1716 /* The following GNU runtime entry point is called to initialize
1719 __objc_exec_class (void *); */
1721 = build_function_type (void_type_node
,
1722 tree_cons (NULL_TREE
, ptr_type_node
,
1724 execclass_decl
= add_builtin_function (TAG_EXECCLASS
,
1725 type
, 0, NOT_BUILT_IN
,
1729 /* id objc_getClass (const char *); */
1731 type
= build_function_type (objc_object_type
,
1732 tree_cons (NULL_TREE
,
1733 const_string_type_node
,
1737 = add_builtin_function (TAG_GETCLASS
, type
, 0, NOT_BUILT_IN
,
1740 /* id objc_getMetaClass (const char *); */
1742 objc_get_meta_class_decl
1743 = add_builtin_function (TAG_GETMETACLASS
, type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
1745 build_class_template ();
1746 build_super_template ();
1747 build_protocol_template ();
1748 build_category_template ();
1749 build_objc_exception_stuff ();
1751 if (flag_next_runtime
)
1752 build_next_objc_exception_stuff ();
1754 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1756 if (! flag_next_runtime
)
1757 build_selector_table_decl ();
1759 /* Forward declare constant_string_id and constant_string_type. */
1760 if (!constant_string_class_name
)
1761 constant_string_class_name
= default_constant_string_class_name
;
1763 constant_string_id
= get_identifier (constant_string_class_name
);
1764 objc_declare_class (tree_cons (NULL_TREE
, constant_string_id
, NULL_TREE
));
1766 /* Pre-build the following entities - for speed/convenience. */
1767 self_id
= get_identifier ("self");
1768 ucmd_id
= get_identifier ("_cmd");
1771 pop_lang_context ();
1774 write_symbols
= save_write_symbols
;
1775 debug_hooks
= save_hooks
;
1778 /* Ensure that the ivar list for NSConstantString/NXConstantString
1779 (or whatever was specified via `-fconstant-string-class')
1780 contains fields at least as large as the following three, so that
1781 the runtime can stomp on them with confidence:
1783 struct STRING_OBJECT_CLASS_NAME
1787 unsigned int length;
1791 check_string_class_template (void)
1793 tree field_decl
= objc_get_class_ivars (constant_string_id
);
1795 #define AT_LEAST_AS_LARGE_AS(F, T) \
1796 (F && TREE_CODE (F) == FIELD_DECL \
1797 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1798 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1800 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
1803 field_decl
= TREE_CHAIN (field_decl
);
1804 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
1807 field_decl
= TREE_CHAIN (field_decl
);
1808 return AT_LEAST_AS_LARGE_AS (field_decl
, unsigned_type_node
);
1810 #undef AT_LEAST_AS_LARGE_AS
1813 /* Avoid calling `check_string_class_template ()' more than once. */
1814 static GTY(()) int string_layout_checked
;
1816 /* Construct an internal string layout to be used as a template for
1817 creating NSConstantString/NXConstantString instances. */
1820 objc_build_internal_const_str_type (void)
1822 tree type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
1823 tree fields
= build_decl (FIELD_DECL
, NULL_TREE
, ptr_type_node
);
1824 tree field
= build_decl (FIELD_DECL
, NULL_TREE
, ptr_type_node
);
1826 TREE_CHAIN (field
) = fields
; fields
= field
;
1827 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
1828 TREE_CHAIN (field
) = fields
; fields
= field
;
1829 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1831 finish_builtin_struct (type
, "__builtin_ObjCString",
1837 /* Custom build_string which sets TREE_TYPE! */
1840 my_build_string (int len
, const char *str
)
1842 return fix_string_type (build_string (len
, str
));
1845 /* Build a string with contents STR and length LEN and convert it to a
1849 my_build_string_pointer (int len
, const char *str
)
1851 tree string
= my_build_string (len
, str
);
1852 tree ptrtype
= build_pointer_type (TREE_TYPE (TREE_TYPE (string
)));
1853 return build1 (ADDR_EXPR
, ptrtype
, string
);
1857 string_hash (const void *ptr
)
1859 tree str
= ((struct string_descriptor
*)ptr
)->literal
;
1860 const unsigned char *p
= (const unsigned char *) TREE_STRING_POINTER (str
);
1861 int i
, len
= TREE_STRING_LENGTH (str
);
1864 for (i
= 0; i
< len
; i
++)
1865 h
= ((h
* 613) + p
[i
]);
1871 string_eq (const void *ptr1
, const void *ptr2
)
1873 tree str1
= ((struct string_descriptor
*)ptr1
)->literal
;
1874 tree str2
= ((struct string_descriptor
*)ptr2
)->literal
;
1875 int len1
= TREE_STRING_LENGTH (str1
);
1877 return (len1
== TREE_STRING_LENGTH (str2
)
1878 && !memcmp (TREE_STRING_POINTER (str1
), TREE_STRING_POINTER (str2
),
1882 /* Given a chain of STRING_CST's, build a static instance of
1883 NXConstantString which points at the concatenation of those
1884 strings. We place the string object in the __string_objects
1885 section of the __OBJC segment. The Objective-C runtime will
1886 initialize the isa pointers of the string objects to point at the
1887 NXConstantString class object. */
1890 objc_build_string_object (tree string
)
1892 tree initlist
, constructor
, constant_string_class
;
1895 struct string_descriptor
*desc
, key
;
1898 /* Prep the string argument. */
1899 string
= fix_string_type (string
);
1900 TREE_SET_CODE (string
, STRING_CST
);
1901 length
= TREE_STRING_LENGTH (string
) - 1;
1903 /* Check whether the string class being used actually exists and has the
1904 correct ivar layout. */
1905 if (!string_layout_checked
)
1907 string_layout_checked
= -1;
1908 constant_string_class
= lookup_interface (constant_string_id
);
1909 internal_const_str_type
= objc_build_internal_const_str_type ();
1911 if (!constant_string_class
1912 || !(constant_string_type
1913 = CLASS_STATIC_TEMPLATE (constant_string_class
)))
1914 error ("cannot find interface declaration for %qs",
1915 IDENTIFIER_POINTER (constant_string_id
));
1916 /* The NSConstantString/NXConstantString ivar layout is now known. */
1917 else if (!check_string_class_template ())
1918 error ("interface %qs does not have valid constant string layout",
1919 IDENTIFIER_POINTER (constant_string_id
));
1920 /* For the NeXT runtime, we can generate a literal reference
1921 to the string class, don't need to run a constructor. */
1922 else if (flag_next_runtime
&& !setup_string_decl ())
1923 error ("cannot find reference tag for class %qs",
1924 IDENTIFIER_POINTER (constant_string_id
));
1927 string_layout_checked
= 1; /* Success! */
1928 add_class_reference (constant_string_id
);
1932 if (string_layout_checked
== -1)
1933 return error_mark_node
;
1935 /* Perhaps we already constructed a constant string just like this one? */
1936 key
.literal
= string
;
1937 loc
= htab_find_slot (string_htab
, &key
, INSERT
);
1943 *loc
= desc
= ggc_alloc (sizeof (*desc
));
1944 desc
->literal
= string
;
1946 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1947 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1948 fields
= TYPE_FIELDS (internal_const_str_type
);
1950 = build_tree_list (fields
,
1952 ? build_unary_op (ADDR_EXPR
, string_class_decl
, 0)
1953 : build_int_cst (NULL_TREE
, 0));
1954 fields
= TREE_CHAIN (fields
);
1955 initlist
= tree_cons (fields
, build_unary_op (ADDR_EXPR
, string
, 1),
1957 fields
= TREE_CHAIN (fields
);
1958 initlist
= tree_cons (fields
, build_int_cst (NULL_TREE
, length
),
1960 constructor
= objc_build_constructor (internal_const_str_type
,
1961 nreverse (initlist
));
1962 TREE_INVARIANT (constructor
) = true;
1964 if (!flag_next_runtime
)
1966 = objc_add_static_instance (constructor
, constant_string_type
);
1969 var
= build_decl (CONST_DECL
, NULL
, TREE_TYPE (constructor
));
1970 DECL_INITIAL (var
) = constructor
;
1971 TREE_STATIC (var
) = 1;
1972 pushdecl_top_level (var
);
1975 desc
->constructor
= constructor
;
1978 addr
= convert (build_pointer_type (constant_string_type
),
1979 build_unary_op (ADDR_EXPR
, desc
->constructor
, 1));
1984 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1986 static GTY(()) int num_static_inst
;
1989 objc_add_static_instance (tree constructor
, tree class_decl
)
1994 /* Find the list of static instances for the CLASS_DECL. Create one if
1996 for (chain
= &objc_static_instances
;
1997 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1998 chain
= &TREE_CHAIN (*chain
));
2001 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
2002 add_objc_string (OBJC_TYPE_NAME (class_decl
), class_names
);
2005 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
2006 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
2007 DECL_COMMON (decl
) = 1;
2008 TREE_STATIC (decl
) = 1;
2009 DECL_ARTIFICIAL (decl
) = 1;
2010 TREE_USED (decl
) = 1;
2011 DECL_INITIAL (decl
) = constructor
;
2013 /* We may be writing something else just now.
2014 Postpone till end of input. */
2015 DECL_DEFER_OUTPUT (decl
) = 1;
2016 pushdecl_top_level (decl
);
2017 rest_of_decl_compilation (decl
, 1, 0);
2019 /* Add the DECL to the head of this CLASS' list. */
2020 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
2025 /* Build a static constant CONSTRUCTOR
2026 with type TYPE and elements ELTS. */
2029 objc_build_constructor (tree type
, tree elts
)
2031 tree constructor
= build_constructor_from_list (type
, elts
);
2033 TREE_CONSTANT (constructor
) = 1;
2034 TREE_STATIC (constructor
) = 1;
2035 TREE_READONLY (constructor
) = 1;
2038 /* Adjust for impedance mismatch. We should figure out how to build
2039 CONSTRUCTORs that consistently please both the C and C++ gods. */
2040 if (!TREE_PURPOSE (elts
))
2041 TREE_TYPE (constructor
) = NULL_TREE
;
2042 TREE_HAS_CONSTRUCTOR (constructor
) = 1;
2048 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2050 /* Predefine the following data type:
2058 void *defs[cls_def_cnt + cat_def_cnt];
2062 build_objc_symtab_template (void)
2064 tree field_decl
, field_decl_chain
;
2066 objc_symtab_template
2067 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
2069 /* long sel_ref_cnt; */
2070 field_decl
= create_field_decl (long_integer_type_node
, "sel_ref_cnt");
2071 field_decl_chain
= field_decl
;
2074 field_decl
= create_field_decl (build_pointer_type (objc_selector_type
),
2076 chainon (field_decl_chain
, field_decl
);
2078 /* short cls_def_cnt; */
2079 field_decl
= create_field_decl (short_integer_type_node
, "cls_def_cnt");
2080 chainon (field_decl_chain
, field_decl
);
2082 /* short cat_def_cnt; */
2083 field_decl
= create_field_decl (short_integer_type_node
,
2085 chainon (field_decl_chain
, field_decl
);
2087 if (imp_count
|| cat_count
|| !flag_next_runtime
)
2089 /* void *defs[imp_count + cat_count (+ 1)]; */
2090 /* NB: The index is one less than the size of the array. */
2091 int index
= imp_count
+ cat_count
2092 + (flag_next_runtime
? -1: 0);
2093 field_decl
= create_field_decl
2096 build_index_type (build_int_cst (NULL_TREE
, index
))),
2098 chainon (field_decl_chain
, field_decl
);
2101 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
2104 /* Create the initial value for the `defs' field of _objc_symtab.
2105 This is a CONSTRUCTOR. */
2108 init_def_list (tree type
)
2110 tree expr
, initlist
= NULL_TREE
;
2111 struct imp_entry
*impent
;
2114 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2116 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
2118 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
2119 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2124 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2126 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
2128 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
2129 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2133 if (!flag_next_runtime
)
2135 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2138 if (static_instances_decl
)
2139 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
2141 expr
= build_int_cst (NULL_TREE
, 0);
2143 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2146 return objc_build_constructor (type
, nreverse (initlist
));
2149 /* Construct the initial value for all of _objc_symtab. */
2152 init_objc_symtab (tree type
)
2156 /* sel_ref_cnt = { ..., 5, ... } */
2158 initlist
= build_tree_list (NULL_TREE
,
2159 build_int_cst (long_integer_type_node
, 0));
2161 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2163 if (flag_next_runtime
|| ! sel_ref_chain
)
2164 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
2167 = tree_cons (NULL_TREE
,
2168 convert (build_pointer_type (objc_selector_type
),
2169 build_unary_op (ADDR_EXPR
,
2170 UOBJC_SELECTOR_TABLE_decl
, 1)),
2173 /* cls_def_cnt = { ..., 5, ... } */
2175 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, imp_count
), initlist
);
2177 /* cat_def_cnt = { ..., 5, ... } */
2179 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, cat_count
), initlist
);
2181 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2183 if (imp_count
|| cat_count
|| !flag_next_runtime
)
2186 tree field
= TYPE_FIELDS (type
);
2187 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
2189 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
2193 return objc_build_constructor (type
, nreverse (initlist
));
2196 /* Generate forward declarations for metadata such as
2197 'OBJC_CLASS_...'. */
2200 build_metadata_decl (const char *name
, tree type
)
2204 /* struct TYPE NAME_<name>; */
2205 decl
= start_var_decl (type
, synth_id_with_class_suffix
2207 objc_implementation_context
));
2212 /* Push forward-declarations of all the categories so that
2213 init_def_list can use them in a CONSTRUCTOR. */
2216 forward_declare_categories (void)
2218 struct imp_entry
*impent
;
2219 tree sav
= objc_implementation_context
;
2221 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2223 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
2225 /* Set an invisible arg to synth_id_with_class_suffix. */
2226 objc_implementation_context
= impent
->imp_context
;
2227 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2228 impent
->class_decl
= build_metadata_decl ("_OBJC_CATEGORY",
2229 objc_category_template
);
2232 objc_implementation_context
= sav
;
2235 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2236 and initialized appropriately. */
2239 generate_objc_symtab_decl (void)
2241 /* forward declare categories */
2243 forward_declare_categories ();
2245 build_objc_symtab_template ();
2246 UOBJC_SYMBOLS_decl
= start_var_decl (objc_symtab_template
, "_OBJC_SYMBOLS");
2247 finish_var_decl (UOBJC_SYMBOLS_decl
,
2248 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)));
2252 init_module_descriptor (tree type
)
2254 tree initlist
, expr
;
2256 /* version = { 1, ... } */
2258 expr
= build_int_cst (long_integer_type_node
, OBJC_VERSION
);
2259 initlist
= build_tree_list (NULL_TREE
, expr
);
2261 /* size = { ..., sizeof (struct _objc_module), ... } */
2263 expr
= convert (long_integer_type_node
,
2264 size_in_bytes (objc_module_template
));
2265 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2267 /* Don't provide any file name for security reasons. */
2268 /* name = { ..., "", ... } */
2270 expr
= add_objc_string (get_identifier (""), class_names
);
2271 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2273 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2275 if (UOBJC_SYMBOLS_decl
)
2276 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
2278 expr
= build_int_cst (NULL_TREE
, 0);
2279 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2281 return objc_build_constructor (type
, nreverse (initlist
));
2284 /* Write out the data structures to describe Objective C classes defined.
2286 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2289 build_module_descriptor (void)
2291 tree field_decl
, field_decl_chain
;
2294 push_lang_context (lang_name_c
); /* extern "C" */
2297 objc_module_template
2298 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
2301 field_decl
= create_field_decl (long_integer_type_node
, "version");
2302 field_decl_chain
= field_decl
;
2305 field_decl
= create_field_decl (long_integer_type_node
, "size");
2306 chainon (field_decl_chain
, field_decl
);
2309 field_decl
= create_field_decl (string_type_node
, "name");
2310 chainon (field_decl_chain
, field_decl
);
2312 /* struct _objc_symtab *symtab; */
2314 = create_field_decl (build_pointer_type
2315 (xref_tag (RECORD_TYPE
,
2316 get_identifier (UTAG_SYMTAB
))),
2318 chainon (field_decl_chain
, field_decl
);
2320 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
2322 /* Create an instance of "_objc_module". */
2323 UOBJC_MODULES_decl
= start_var_decl (objc_module_template
, "_OBJC_MODULES");
2324 finish_var_decl (UOBJC_MODULES_decl
,
2325 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)));
2328 pop_lang_context ();
2332 /* The GNU runtime requires us to provide a static initializer function
2335 static void __objc_gnu_init (void) {
2336 __objc_exec_class (&L_OBJC_MODULES);
2340 build_module_initializer_routine (void)
2345 push_lang_context (lang_name_c
); /* extern "C" */
2348 objc_push_parm (build_decl (PARM_DECL
, NULL_TREE
, void_type_node
));
2349 objc_start_function (get_identifier (TAG_GNUINIT
),
2350 build_function_type (void_type_node
,
2352 NULL_TREE
, objc_get_parm_info (0));
2354 body
= c_begin_compound_stmt (true);
2355 add_stmt (build_function_call
2359 build_unary_op (ADDR_EXPR
,
2360 UOBJC_MODULES_decl
, 0))));
2361 add_stmt (c_end_compound_stmt (body
, true));
2363 TREE_PUBLIC (current_function_decl
) = 0;
2366 /* For Objective-C++, we will need to call __objc_gnu_init
2367 from objc_generate_static_init_call() below. */
2368 DECL_STATIC_CONSTRUCTOR (current_function_decl
) = 1;
2371 GNU_INIT_decl
= current_function_decl
;
2375 pop_lang_context ();
2380 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2381 to be called by the module initializer routine. */
2384 objc_static_init_needed_p (void)
2386 return (GNU_INIT_decl
!= NULL_TREE
);
2389 /* Generate a call to the __objc_gnu_init initializer function. */
2392 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED
)
2394 add_stmt (build_stmt (EXPR_STMT
,
2395 build_function_call (GNU_INIT_decl
, NULL_TREE
)));
2399 #endif /* OBJCPLUS */
2401 /* Return the DECL of the string IDENT in the SECTION. */
2404 get_objc_string_decl (tree ident
, enum string_section section
)
2408 if (section
== class_names
)
2409 chain
= class_names_chain
;
2410 else if (section
== meth_var_names
)
2411 chain
= meth_var_names_chain
;
2412 else if (section
== meth_var_types
)
2413 chain
= meth_var_types_chain
;
2417 for (; chain
!= 0; chain
= TREE_CHAIN (chain
))
2418 if (TREE_VALUE (chain
) == ident
)
2419 return (TREE_PURPOSE (chain
));
2425 /* Output references to all statically allocated objects. Return the DECL
2426 for the array built. */
2429 generate_static_references (void)
2431 tree decls
= NULL_TREE
, expr
= NULL_TREE
;
2432 tree class_name
, class, decl
, initlist
;
2433 tree cl_chain
, in_chain
, type
2434 = build_array_type (build_pointer_type (void_type_node
), NULL_TREE
);
2435 int num_inst
, num_class
;
2438 if (flag_next_runtime
)
2441 for (cl_chain
= objc_static_instances
, num_class
= 0;
2442 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
2444 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
2445 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
2447 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
2448 decl
= start_var_decl (type
, buf
);
2450 /* Output {class_name, ...}. */
2451 class = TREE_VALUE (cl_chain
);
2452 class_name
= get_objc_string_decl (OBJC_TYPE_NAME (class), class_names
);
2453 initlist
= build_tree_list (NULL_TREE
,
2454 build_unary_op (ADDR_EXPR
, class_name
, 1));
2456 /* Output {..., instance, ...}. */
2457 for (in_chain
= TREE_PURPOSE (cl_chain
);
2458 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
2460 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
2461 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2464 /* Output {..., NULL}. */
2465 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
2467 expr
= objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
2468 finish_var_decl (decl
, expr
);
2470 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
2473 decls
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), decls
);
2474 expr
= objc_build_constructor (type
, nreverse (decls
));
2475 static_instances_decl
= start_var_decl (type
, "_OBJC_STATIC_INSTANCES");
2476 finish_var_decl (static_instances_decl
, expr
);
2479 static GTY(()) int selector_reference_idx
;
2482 build_selector_reference_decl (void)
2487 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx
++);
2488 decl
= start_var_decl (objc_selector_type
, buf
);
2494 build_selector_table_decl (void)
2498 if (flag_typed_selectors
)
2500 build_selector_template ();
2501 temp
= build_array_type (objc_selector_template
, NULL_TREE
);
2504 temp
= build_array_type (objc_selector_type
, NULL_TREE
);
2506 UOBJC_SELECTOR_TABLE_decl
= start_var_decl (temp
, "_OBJC_SELECTOR_TABLE");
2509 /* Just a handy wrapper for add_objc_string. */
2512 build_selector (tree ident
)
2514 return convert (objc_selector_type
,
2515 add_objc_string (ident
, meth_var_names
));
2519 build_selector_translation_table (void)
2521 tree chain
, initlist
= NULL_TREE
;
2523 tree decl
= NULL_TREE
;
2525 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2529 if (warn_selector
&& objc_implementation_context
)
2533 for (method_chain
= meth_var_names_chain
;
2535 method_chain
= TREE_CHAIN (method_chain
))
2537 if (TREE_VALUE (method_chain
) == TREE_VALUE (chain
))
2546 if (flag_next_runtime
&& TREE_PURPOSE (chain
))
2547 loc
= &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain
));
2549 loc
= &input_location
;
2550 warning (0, "%Hcreating selector for nonexistent method %qE",
2551 loc
, TREE_VALUE (chain
));
2555 expr
= build_selector (TREE_VALUE (chain
));
2556 /* add one for the '\0' character */
2557 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2559 if (flag_next_runtime
)
2561 decl
= TREE_PURPOSE (chain
);
2562 finish_var_decl (decl
, expr
);
2566 if (flag_typed_selectors
)
2568 tree eltlist
= NULL_TREE
;
2569 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2570 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2571 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2572 expr
= objc_build_constructor (objc_selector_template
,
2573 nreverse (eltlist
));
2576 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2580 if (! flag_next_runtime
)
2582 /* Cause the selector table (previously forward-declared)
2583 to be actually output. */
2584 initlist
= tree_cons (NULL_TREE
,
2585 flag_typed_selectors
2586 ? objc_build_constructor
2587 (objc_selector_template
,
2588 tree_cons (NULL_TREE
,
2589 build_int_cst (NULL_TREE
, 0),
2590 tree_cons (NULL_TREE
,
2591 build_int_cst (NULL_TREE
, 0),
2593 : build_int_cst (NULL_TREE
, 0), initlist
);
2594 initlist
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2595 nreverse (initlist
));
2596 finish_var_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
);
2601 get_proto_encoding (tree proto
)
2606 if (! METHOD_ENCODING (proto
))
2608 encoding
= encode_method_prototype (proto
);
2609 METHOD_ENCODING (proto
) = encoding
;
2612 encoding
= METHOD_ENCODING (proto
);
2614 return add_objc_string (encoding
, meth_var_types
);
2617 return build_int_cst (NULL_TREE
, 0);
2620 /* sel_ref_chain is a list whose "value" fields will be instances of
2621 identifier_node that represent the selector. */
2624 build_typed_selector_reference (tree ident
, tree prototype
)
2626 tree
*chain
= &sel_ref_chain
;
2632 if (TREE_PURPOSE (*chain
) == prototype
&& TREE_VALUE (*chain
) == ident
)
2633 goto return_at_index
;
2636 chain
= &TREE_CHAIN (*chain
);
2639 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
2642 expr
= build_unary_op (ADDR_EXPR
,
2643 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2644 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
)));
2665 chain
= &TREE_CHAIN (*chain
);
2668 expr
= (flag_next_runtime
? build_selector_reference_decl (): NULL_TREE
);
2670 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2672 return (flag_next_runtime
2674 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2675 build_int_cst (NULL_TREE
, index
)));
2678 static GTY(()) int class_reference_idx
;
2681 build_class_reference_decl (void)
2686 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx
++);
2687 decl
= start_var_decl (objc_class_type
, buf
);
2692 /* Create a class reference, but don't create a variable to reference
2696 add_class_reference (tree ident
)
2700 if ((chain
= cls_ref_chain
))
2705 if (ident
== TREE_VALUE (chain
))
2709 chain
= TREE_CHAIN (chain
);
2713 /* Append to the end of the list */
2714 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2717 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2720 /* Get a class reference, creating it if necessary. Also create the
2721 reference variable. */
2724 objc_get_class_reference (tree ident
)
2726 tree orig_ident
= (DECL_P (ident
)
2729 ? OBJC_TYPE_NAME (ident
)
2731 bool local_scope
= false;
2734 if (processing_template_decl
)
2735 /* Must wait until template instantiation time. */
2736 return build_min_nt (CLASS_REFERENCE_EXPR
, ident
);
2739 if (TREE_CODE (ident
) == TYPE_DECL
)
2740 ident
= (DECL_ORIGINAL_TYPE (ident
)
2741 ? DECL_ORIGINAL_TYPE (ident
)
2742 : TREE_TYPE (ident
));
2745 if (TYPE_P (ident
) && TYPE_CONTEXT (ident
)
2746 && TYPE_CONTEXT (ident
) != global_namespace
)
2750 if (local_scope
|| !(ident
= objc_is_class_name (ident
)))
2752 error ("%qs is not an Objective-C class name or alias",
2753 IDENTIFIER_POINTER (orig_ident
));
2754 return error_mark_node
;
2757 if (flag_next_runtime
&& !flag_zero_link
)
2762 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2763 if (TREE_VALUE (*chain
) == ident
)
2765 if (! TREE_PURPOSE (*chain
))
2766 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2768 return TREE_PURPOSE (*chain
);
2771 decl
= build_class_reference_decl ();
2772 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2779 add_class_reference (ident
);
2781 params
= build_tree_list (NULL_TREE
,
2782 my_build_string_pointer
2783 (IDENTIFIER_LENGTH (ident
) + 1,
2784 IDENTIFIER_POINTER (ident
)));
2786 assemble_external (objc_get_class_decl
);
2787 return build_function_call (objc_get_class_decl
, params
);
2791 /* For each string section we have a chain which maps identifier nodes
2792 to decls for the strings. */
2795 add_objc_string (tree ident
, enum string_section section
)
2797 tree
*chain
, decl
, type
, string_expr
;
2799 if (section
== class_names
)
2800 chain
= &class_names_chain
;
2801 else if (section
== meth_var_names
)
2802 chain
= &meth_var_names_chain
;
2803 else if (section
== meth_var_types
)
2804 chain
= &meth_var_types_chain
;
2810 if (TREE_VALUE (*chain
) == ident
)
2811 return convert (string_type_node
,
2812 build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1));
2814 chain
= &TREE_CHAIN (*chain
);
2817 decl
= build_objc_string_decl (section
);
2819 type
= build_array_type
2822 (build_int_cst (NULL_TREE
,
2823 IDENTIFIER_LENGTH (ident
))));
2824 decl
= start_var_decl (type
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
2825 string_expr
= my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2826 IDENTIFIER_POINTER (ident
));
2827 finish_var_decl (decl
, string_expr
);
2829 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2831 return convert (string_type_node
, build_unary_op (ADDR_EXPR
, decl
, 1));
2834 static GTY(()) int class_names_idx
;
2835 static GTY(()) int meth_var_names_idx
;
2836 static GTY(()) int meth_var_types_idx
;
2839 build_objc_string_decl (enum string_section section
)
2844 if (section
== class_names
)
2845 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2846 else if (section
== meth_var_names
)
2847 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2848 else if (section
== meth_var_types
)
2849 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2851 ident
= get_identifier (buf
);
2853 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2854 DECL_EXTERNAL (decl
) = 1;
2855 TREE_PUBLIC (decl
) = 0;
2856 TREE_USED (decl
) = 1;
2857 TREE_CONSTANT (decl
) = 1;
2858 DECL_CONTEXT (decl
) = 0;
2859 DECL_ARTIFICIAL (decl
) = 1;
2861 DECL_THIS_STATIC (decl
) = 1; /* squash redeclaration errors */
2864 make_decl_rtl (decl
);
2865 pushdecl_top_level (decl
);
2872 objc_declare_alias (tree alias_ident
, tree class_ident
)
2874 tree underlying_class
;
2877 if (current_namespace
!= global_namespace
) {
2878 error ("Objective-C declarations may only appear in global scope");
2880 #endif /* OBJCPLUS */
2882 if (!(underlying_class
= objc_is_class_name (class_ident
)))
2883 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident
));
2884 else if (objc_is_class_name (alias_ident
))
2885 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident
));
2888 /* Implement @compatibility_alias as a typedef. */
2890 push_lang_context (lang_name_c
); /* extern "C" */
2892 lang_hooks
.decls
.pushdecl (build_decl
2895 xref_tag (RECORD_TYPE
, underlying_class
)));
2897 pop_lang_context ();
2899 alias_chain
= tree_cons (underlying_class
, alias_ident
, alias_chain
);
2904 objc_declare_class (tree ident_list
)
2908 if (current_namespace
!= global_namespace
) {
2909 error ("Objective-C declarations may only appear in global scope");
2911 #endif /* OBJCPLUS */
2913 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2915 tree ident
= TREE_VALUE (list
);
2917 if (! objc_is_class_name (ident
))
2919 tree record
= lookup_name (ident
), type
= record
;
2923 if (TREE_CODE (record
) == TYPE_DECL
)
2924 type
= DECL_ORIGINAL_TYPE (record
);
2926 if (!TYPE_HAS_OBJC_INFO (type
)
2927 || !TYPE_OBJC_INTERFACE (type
))
2929 error ("%qs redeclared as different kind of symbol",
2930 IDENTIFIER_POINTER (ident
));
2931 error ("previous declaration of %q+D",
2936 record
= xref_tag (RECORD_TYPE
, ident
);
2937 INIT_TYPE_OBJC_INFO (record
);
2938 TYPE_OBJC_INTERFACE (record
) = ident
;
2939 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2945 objc_is_class_name (tree ident
)
2949 if (ident
&& TREE_CODE (ident
) == IDENTIFIER_NODE
2950 && identifier_global_value (ident
))
2951 ident
= identifier_global_value (ident
);
2952 while (ident
&& TREE_CODE (ident
) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (ident
))
2953 ident
= OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident
));
2955 if (ident
&& TREE_CODE (ident
) == RECORD_TYPE
)
2956 ident
= OBJC_TYPE_NAME (ident
);
2958 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
2959 ident
= DECL_NAME (ident
);
2961 if (!ident
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
2964 if (lookup_interface (ident
))
2967 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2969 if (ident
== TREE_VALUE (chain
))
2973 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2975 if (ident
== TREE_VALUE (chain
))
2976 return TREE_PURPOSE (chain
);
2982 /* Check whether TYPE is either 'id' or 'Class'. */
2985 objc_is_id (tree type
)
2987 if (type
&& TREE_CODE (type
) == IDENTIFIER_NODE
2988 && identifier_global_value (type
))
2989 type
= identifier_global_value (type
);
2991 if (type
&& TREE_CODE (type
) == TYPE_DECL
)
2992 type
= TREE_TYPE (type
);
2994 /* NB: This function may be called before the ObjC front-end has
2995 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2996 return (objc_object_type
&& type
2997 && (IS_ID (type
) || IS_CLASS (type
) || IS_SUPER (type
))
3002 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3003 class instance. This is needed by other parts of the compiler to
3004 handle ObjC types gracefully. */
3007 objc_is_object_ptr (tree type
)
3011 type
= TYPE_MAIN_VARIANT (type
);
3012 if (!POINTER_TYPE_P (type
))
3015 ret
= objc_is_id (type
);
3017 ret
= objc_is_class_name (TREE_TYPE (type
));
3023 objc_is_gcable_type (tree type
, int or_strong_p
)
3029 if (objc_is_id (TYPE_MAIN_VARIANT (type
)))
3031 if (or_strong_p
&& lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type
)))
3033 if (TREE_CODE (type
) != POINTER_TYPE
&& TREE_CODE (type
) != INDIRECT_REF
)
3035 type
= TREE_TYPE (type
);
3036 if (TREE_CODE (type
) != RECORD_TYPE
)
3038 name
= TYPE_NAME (type
);
3039 return (objc_is_class_name (name
) != NULL_TREE
);
3043 objc_substitute_decl (tree expr
, tree oldexpr
, tree newexpr
)
3045 if (expr
== oldexpr
)
3048 switch (TREE_CODE (expr
))
3051 return objc_build_component_ref
3052 (objc_substitute_decl (TREE_OPERAND (expr
, 0),
3055 DECL_NAME (TREE_OPERAND (expr
, 1)));
3057 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr
, 0),
3060 TREE_OPERAND (expr
, 1));
3062 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr
, 0),
3071 objc_build_ivar_assignment (tree outervar
, tree lhs
, tree rhs
)
3074 /* The LHS parameter contains the expression 'outervar->memberspec';
3075 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3076 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3079 = objc_substitute_decl
3080 (lhs
, outervar
, convert (TREE_TYPE (outervar
), integer_zero_node
));
3082 = (flag_objc_direct_dispatch
3083 ? objc_assign_ivar_fast_decl
3084 : objc_assign_ivar_decl
);
3086 offs
= convert (integer_type_node
, build_unary_op (ADDR_EXPR
, offs
, 0));
3088 func_params
= tree_cons (NULL_TREE
,
3089 convert (objc_object_type
, rhs
),
3090 tree_cons (NULL_TREE
, convert (objc_object_type
, outervar
),
3091 tree_cons (NULL_TREE
, offs
,
3094 assemble_external (func
);
3095 return build_function_call (func
, func_params
);
3099 objc_build_global_assignment (tree lhs
, tree rhs
)
3101 tree func_params
= tree_cons (NULL_TREE
,
3102 convert (objc_object_type
, rhs
),
3103 tree_cons (NULL_TREE
, convert (build_pointer_type (objc_object_type
),
3104 build_unary_op (ADDR_EXPR
, lhs
, 0)),
3107 assemble_external (objc_assign_global_decl
);
3108 return build_function_call (objc_assign_global_decl
, func_params
);
3112 objc_build_strong_cast_assignment (tree lhs
, tree rhs
)
3114 tree func_params
= tree_cons (NULL_TREE
,
3115 convert (objc_object_type
, rhs
),
3116 tree_cons (NULL_TREE
, convert (build_pointer_type (objc_object_type
),
3117 build_unary_op (ADDR_EXPR
, lhs
, 0)),
3120 assemble_external (objc_assign_strong_cast_decl
);
3121 return build_function_call (objc_assign_strong_cast_decl
, func_params
);
3125 objc_is_gcable_p (tree expr
)
3127 return (TREE_CODE (expr
) == COMPONENT_REF
3128 ? objc_is_gcable_p (TREE_OPERAND (expr
, 1))
3129 : TREE_CODE (expr
) == ARRAY_REF
3130 ? (objc_is_gcable_p (TREE_TYPE (expr
))
3131 || objc_is_gcable_p (TREE_OPERAND (expr
, 0)))
3132 : TREE_CODE (expr
) == ARRAY_TYPE
3133 ? objc_is_gcable_p (TREE_TYPE (expr
))
3135 ? objc_is_gcable_type (expr
, 1)
3136 : (objc_is_gcable_p (TREE_TYPE (expr
))
3138 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr
)))));
3142 objc_is_ivar_reference_p (tree expr
)
3144 return (TREE_CODE (expr
) == ARRAY_REF
3145 ? objc_is_ivar_reference_p (TREE_OPERAND (expr
, 0))
3146 : TREE_CODE (expr
) == COMPONENT_REF
3147 ? TREE_CODE (TREE_OPERAND (expr
, 1)) == FIELD_DECL
3152 objc_is_global_reference_p (tree expr
)
3154 return (TREE_CODE (expr
) == INDIRECT_REF
|| TREE_CODE (expr
) == PLUS_EXPR
3155 ? objc_is_global_reference_p (TREE_OPERAND (expr
, 0))
3157 ? (!DECL_CONTEXT (expr
) || TREE_STATIC (expr
))
3162 objc_generate_write_barrier (tree lhs
, enum tree_code modifycode
, tree rhs
)
3164 tree result
= NULL_TREE
, outer
;
3165 int strong_cast_p
= 0, outer_gc_p
= 0, indirect_p
= 0;
3167 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3168 will have been transformed to the form '*(type *)&expr'. */
3169 if (TREE_CODE (lhs
) == INDIRECT_REF
)
3171 outer
= TREE_OPERAND (lhs
, 0);
3173 while (!strong_cast_p
3174 && (TREE_CODE (outer
) == CONVERT_EXPR
3175 || TREE_CODE (outer
) == NOP_EXPR
3176 || TREE_CODE (outer
) == NON_LVALUE_EXPR
))
3178 tree lhstype
= TREE_TYPE (outer
);
3180 /* Descend down the cast chain, and record the first objc_gc
3182 if (POINTER_TYPE_P (lhstype
))
3185 = lookup_attribute ("objc_gc",
3186 TYPE_ATTRIBUTES (TREE_TYPE (lhstype
)));
3192 outer
= TREE_OPERAND (outer
, 0);
3196 /* If we have a __strong cast, it trumps all else. */
3199 if (modifycode
!= NOP_EXPR
)
3200 goto invalid_pointer_arithmetic
;
3202 if (warn_assign_intercept
)
3203 warning (0, "strong-cast assignment has been intercepted");
3205 result
= objc_build_strong_cast_assignment (lhs
, rhs
);
3210 /* the lhs must be of a suitable type, regardless of its underlying
3212 if (!objc_is_gcable_p (lhs
))
3218 && (TREE_CODE (outer
) == COMPONENT_REF
3219 || TREE_CODE (outer
) == ARRAY_REF
))
3220 outer
= TREE_OPERAND (outer
, 0);
3222 if (TREE_CODE (outer
) == INDIRECT_REF
)
3224 outer
= TREE_OPERAND (outer
, 0);
3228 outer_gc_p
= objc_is_gcable_p (outer
);
3230 /* Handle ivar assignments. */
3231 if (objc_is_ivar_reference_p (lhs
))
3233 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3234 doesn't cut it here), the best we can do here is suggest a cast. */
3235 if (!objc_is_gcable_type (TREE_TYPE (outer
), 0))
3237 /* We may still be able to use the global write barrier... */
3238 if (!indirect_p
&& objc_is_global_reference_p (outer
))
3239 goto global_reference
;
3242 if (modifycode
== NOP_EXPR
)
3244 if (warn_assign_intercept
)
3245 warning (0, "strong-cast may possibly be needed");
3251 if (modifycode
!= NOP_EXPR
)
3252 goto invalid_pointer_arithmetic
;
3254 if (warn_assign_intercept
)
3255 warning (0, "instance variable assignment has been intercepted");
3257 result
= objc_build_ivar_assignment (outer
, lhs
, rhs
);
3262 /* Likewise, intercept assignment to global/static variables if their type is
3264 if (objc_is_global_reference_p (outer
))
3270 if (modifycode
!= NOP_EXPR
)
3272 invalid_pointer_arithmetic
:
3274 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3279 if (warn_assign_intercept
)
3280 warning (0, "global/static variable assignment has been intercepted");
3282 result
= objc_build_global_assignment (lhs
, rhs
);
3285 /* In all other cases, fall back to the normal mechanism. */
3290 struct interface_tuple
GTY(())
3296 static GTY ((param_is (struct interface_tuple
))) htab_t interface_htab
;
3299 hash_interface (const void *p
)
3301 const struct interface_tuple
*d
= p
;
3302 return IDENTIFIER_HASH_VALUE (d
->id
);
3306 eq_interface (const void *p1
, const void *p2
)
3308 const struct interface_tuple
*d
= p1
;
3313 lookup_interface (tree ident
)
3316 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
3317 ident
= DECL_NAME (ident
);
3320 if (ident
== NULL_TREE
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
3324 struct interface_tuple
**slot
;
3329 slot
= (struct interface_tuple
**)
3330 htab_find_slot_with_hash (interface_htab
, ident
,
3331 IDENTIFIER_HASH_VALUE (ident
),
3334 i
= (*slot
)->class_name
;
3340 /* Implement @defs (<classname>) within struct bodies. */
3343 objc_get_class_ivars (tree class_name
)
3345 tree interface
= lookup_interface (class_name
);
3348 return get_class_ivars (interface
, true);
3350 error ("cannot find interface declaration for %qs",
3351 IDENTIFIER_POINTER (class_name
));
3353 return error_mark_node
;
3356 /* Used by: build_private_template, continue_class,
3357 and for @defs constructs. */
3360 get_class_ivars (tree interface
, bool inherited
)
3362 tree ivar_chain
= copy_list (CLASS_RAW_IVARS (interface
));
3364 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3365 by the current class (i.e., they do not include super-class ivars).
3366 However, the CLASS_IVARS list will be side-effected by a call to
3367 finish_struct(), which will fill in field offsets. */
3368 if (!CLASS_IVARS (interface
))
3369 CLASS_IVARS (interface
) = ivar_chain
;
3374 while (CLASS_SUPER_NAME (interface
))
3376 /* Prepend super-class ivars. */
3377 interface
= lookup_interface (CLASS_SUPER_NAME (interface
));
3378 ivar_chain
= chainon (copy_list (CLASS_RAW_IVARS (interface
)),
3386 objc_create_temporary_var (tree type
)
3390 decl
= build_decl (VAR_DECL
, NULL_TREE
, type
);
3391 TREE_USED (decl
) = 1;
3392 DECL_ARTIFICIAL (decl
) = 1;
3393 DECL_IGNORED_P (decl
) = 1;
3394 DECL_CONTEXT (decl
) = current_function_decl
;
3399 /* Exception handling constructs. We begin by having the parser do most
3400 of the work and passing us blocks. What we do next depends on whether
3401 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3402 We abstract all of this in a handful of appropriately named routines. */
3404 /* Stack of open try blocks. */
3406 struct objc_try_context
3408 struct objc_try_context
*outer
;
3410 /* Statements (or statement lists) as processed by the parser. */
3414 /* Some file position locations. */
3415 location_t try_locus
;
3416 location_t end_try_locus
;
3417 location_t end_catch_locus
;
3418 location_t finally_locus
;
3419 location_t end_finally_locus
;
3421 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3422 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3425 /* The CATCH_EXPR of an open @catch clause. */
3428 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3434 static struct objc_try_context
*cur_try_context
;
3436 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3437 that represents TYPE. For Objective-C, this is just the class name. */
3438 /* ??? Isn't there a class object or some such? Is it easy to get? */
3442 objc_eh_runtime_type (tree type
)
3444 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type
)), class_names
);
3448 /* Initialize exception handling. */
3451 objc_init_exceptions (void)
3453 static bool done
= false;
3458 if (flag_objc_sjlj_exceptions
)
3460 /* On Darwin, ObjC exceptions require a sufficiently recent
3461 version of the runtime, so the user must ask for them explicitly. */
3462 if (!flag_objc_exceptions
)
3463 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3464 "exception syntax");
3469 c_eh_initialized_p
= true;
3470 eh_personality_libfunc
3471 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3472 ? "__gnu_objc_personality_sj0"
3473 : "__gnu_objc_personality_v0");
3474 default_init_unwind_resume_libfunc ();
3475 using_eh_for_cleanups ();
3476 lang_eh_runtime_type
= objc_eh_runtime_type
;
3481 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3482 we'll arrange for it to be initialized (and associated with a binding)
3486 objc_build_exc_ptr (void)
3488 if (flag_objc_sjlj_exceptions
)
3490 tree var
= cur_try_context
->caught_decl
;
3493 var
= objc_create_temporary_var (objc_object_type
);
3494 cur_try_context
->caught_decl
= var
;
3499 return build0 (EXC_PTR_EXPR
, objc_object_type
);
3502 /* Build "objc_exception_try_exit(&_stack)". */
3505 next_sjlj_build_try_exit (void)
3508 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
3509 t
= tree_cons (NULL
, t
, NULL
);
3510 t
= build_function_call (objc_exception_try_exit_decl
, t
);
3515 objc_exception_try_enter (&_stack);
3516 if (_setjmp(&_stack.buf))
3520 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3521 empty, ready for the caller to fill them in. */
3524 next_sjlj_build_enter_and_setjmp (void)
3526 tree t
, enter
, sj
, cond
;
3528 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
3529 t
= tree_cons (NULL
, t
, NULL
);
3530 enter
= build_function_call (objc_exception_try_enter_decl
, t
);
3532 t
= objc_build_component_ref (cur_try_context
->stack_decl
,
3533 get_identifier ("buf"));
3534 t
= build_fold_addr_expr (t
);
3536 /* Convert _setjmp argument to type that is expected. */
3537 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl
)))
3538 t
= convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl
))), t
);
3540 t
= convert (ptr_type_node
, t
);
3542 t
= convert (ptr_type_node
, t
);
3544 t
= tree_cons (NULL
, t
, NULL
);
3545 sj
= build_function_call (objc_setjmp_decl
, t
);
3547 cond
= build2 (COMPOUND_EXPR
, TREE_TYPE (sj
), enter
, sj
);
3548 cond
= c_common_truthvalue_conversion (cond
);
3550 return build3 (COND_EXPR
, void_type_node
, cond
, NULL
, NULL
);
3555 DECL = objc_exception_extract(&_stack); */
3558 next_sjlj_build_exc_extract (tree decl
)
3562 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
3563 t
= tree_cons (NULL
, t
, NULL
);
3564 t
= build_function_call (objc_exception_extract_decl
, t
);
3565 t
= convert (TREE_TYPE (decl
), t
);
3566 t
= build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
3572 if (objc_exception_match(obj_get_class(TYPE), _caught)
3579 objc_exception_try_exit(&_stack);
3581 from the sequence of CATCH_EXPRs in the current try context. */
3584 next_sjlj_build_catch_list (void)
3586 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
3588 tree
*last
= &catch_seq
;
3589 bool saw_id
= false;
3591 for (; !tsi_end_p (i
); tsi_next (&i
))
3593 tree stmt
= tsi_stmt (i
);
3594 tree type
= CATCH_TYPES (stmt
);
3595 tree body
= CATCH_BODY (stmt
);
3607 if (type
== error_mark_node
)
3608 cond
= error_mark_node
;
3611 args
= tree_cons (NULL
, cur_try_context
->caught_decl
, NULL
);
3612 t
= objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type
)));
3613 args
= tree_cons (NULL
, t
, args
);
3614 t
= build_function_call (objc_exception_match_decl
, args
);
3615 cond
= c_common_truthvalue_conversion (t
);
3617 t
= build3 (COND_EXPR
, void_type_node
, cond
, body
, NULL
);
3618 SET_EXPR_LOCUS (t
, EXPR_LOCUS (stmt
));
3621 last
= &COND_EXPR_ELSE (t
);
3627 t
= build2 (MODIFY_EXPR
, void_type_node
, cur_try_context
->rethrow_decl
,
3628 cur_try_context
->caught_decl
);
3629 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
3630 append_to_statement_list (t
, last
);
3632 t
= next_sjlj_build_try_exit ();
3633 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
3634 append_to_statement_list (t
, last
);
3640 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3641 exception handling. We aim to build:
3644 struct _objc_exception_data _stack;
3645 id volatile _rethrow = 0;
3648 objc_exception_try_enter (&_stack);
3649 if (_setjmp(&_stack.buf))
3651 id _caught = objc_exception_extract(&_stack);
3652 objc_exception_try_enter (&_stack);
3653 if (_setjmp(&_stack.buf))
3654 _rethrow = objc_exception_extract(&_stack);
3664 objc_exception_try_exit(&_stack);
3667 objc_exception_throw(_rethrow);
3671 If CATCH-LIST is empty, we can omit all of the block containing
3672 "_caught" except for the setting of _rethrow. Note the use of
3673 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3674 but handles goto and other exits from the block. */
3677 next_sjlj_build_try_catch_finally (void)
3679 tree rethrow_decl
, stack_decl
, t
;
3680 tree catch_seq
, try_fin
, bind
;
3682 /* Create the declarations involved. */
3683 t
= xref_tag (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
3684 stack_decl
= objc_create_temporary_var (t
);
3685 cur_try_context
->stack_decl
= stack_decl
;
3687 rethrow_decl
= objc_create_temporary_var (objc_object_type
);
3688 cur_try_context
->rethrow_decl
= rethrow_decl
;
3689 TREE_THIS_VOLATILE (rethrow_decl
) = 1;
3690 TREE_CHAIN (rethrow_decl
) = stack_decl
;
3692 /* Build the outermost variable binding level. */
3693 bind
= build3 (BIND_EXPR
, void_type_node
, rethrow_decl
, NULL
, NULL
);
3694 SET_EXPR_LOCATION (bind
, cur_try_context
->try_locus
);
3695 TREE_SIDE_EFFECTS (bind
) = 1;
3697 /* Initialize rethrow_decl. */
3698 t
= build2 (MODIFY_EXPR
, void_type_node
, rethrow_decl
,
3699 convert (objc_object_type
, null_pointer_node
));
3700 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
3701 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
3703 /* Build the outermost TRY_FINALLY_EXPR. */
3704 try_fin
= build2 (TRY_FINALLY_EXPR
, void_type_node
, NULL
, NULL
);
3705 SET_EXPR_LOCATION (try_fin
, cur_try_context
->try_locus
);
3706 TREE_SIDE_EFFECTS (try_fin
) = 1;
3707 append_to_statement_list (try_fin
, &BIND_EXPR_BODY (bind
));
3709 /* Create the complete catch sequence. */
3710 if (cur_try_context
->catch_list
)
3712 tree caught_decl
= objc_build_exc_ptr ();
3713 catch_seq
= build_stmt (BIND_EXPR
, caught_decl
, NULL
, NULL
);
3714 TREE_SIDE_EFFECTS (catch_seq
) = 1;
3716 t
= next_sjlj_build_exc_extract (caught_decl
);
3717 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
3719 t
= next_sjlj_build_enter_and_setjmp ();
3720 COND_EXPR_THEN (t
) = next_sjlj_build_exc_extract (rethrow_decl
);
3721 COND_EXPR_ELSE (t
) = next_sjlj_build_catch_list ();
3722 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
3725 catch_seq
= next_sjlj_build_exc_extract (rethrow_decl
);
3726 SET_EXPR_LOCATION (catch_seq
, cur_try_context
->end_try_locus
);
3728 /* Build the main register-and-try if statement. */
3729 t
= next_sjlj_build_enter_and_setjmp ();
3730 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
3731 COND_EXPR_THEN (t
) = catch_seq
;
3732 COND_EXPR_ELSE (t
) = cur_try_context
->try_body
;
3733 TREE_OPERAND (try_fin
, 0) = t
;
3735 /* Build the complete FINALLY statement list. */
3736 t
= next_sjlj_build_try_exit ();
3737 t
= build_stmt (COND_EXPR
,
3738 c_common_truthvalue_conversion (rethrow_decl
),
3740 SET_EXPR_LOCATION (t
, cur_try_context
->finally_locus
);
3741 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
3743 append_to_statement_list (cur_try_context
->finally_body
,
3744 &TREE_OPERAND (try_fin
, 1));
3746 t
= tree_cons (NULL
, rethrow_decl
, NULL
);
3747 t
= build_function_call (objc_exception_throw_decl
, t
);
3748 t
= build_stmt (COND_EXPR
,
3749 c_common_truthvalue_conversion (rethrow_decl
),
3751 SET_EXPR_LOCATION (t
, cur_try_context
->end_finally_locus
);
3752 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
3757 /* Called just after parsing the @try and its associated BODY. We now
3758 must prepare for the tricky bits -- handling the catches and finally. */
3761 objc_begin_try_stmt (location_t try_locus
, tree body
)
3763 struct objc_try_context
*c
= xcalloc (1, sizeof (*c
));
3764 c
->outer
= cur_try_context
;
3766 c
->try_locus
= try_locus
;
3767 c
->end_try_locus
= input_location
;
3768 cur_try_context
= c
;
3770 objc_init_exceptions ();
3772 if (flag_objc_sjlj_exceptions
)
3773 objc_mark_locals_volatile (NULL
);
3776 /* Called just after parsing "@catch (parm)". Open a binding level,
3777 enter DECL into the binding level, and initialize it. Leave the
3778 binding level open while the body of the compound statement is parsed. */
3781 objc_begin_catch_clause (tree decl
)
3783 tree compound
, type
, t
;
3785 /* Begin a new scope that the entire catch clause will live in. */
3786 compound
= c_begin_compound_stmt (true);
3788 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3789 decl
= build_decl (VAR_DECL
, DECL_NAME (decl
), TREE_TYPE (decl
));
3790 lang_hooks
.decls
.pushdecl (decl
);
3792 /* Since a decl is required here by syntax, don't warn if its unused. */
3793 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3794 be what the previous objc implementation did. */
3795 TREE_USED (decl
) = 1;
3797 /* Verify that the type of the catch is valid. It must be a pointer
3798 to an Objective-C class, or "id" (which is catch-all). */
3799 type
= TREE_TYPE (decl
);
3801 if (POINTER_TYPE_P (type
) && objc_is_object_id (TREE_TYPE (type
)))
3803 else if (!POINTER_TYPE_P (type
) || !TYPED_OBJECT (TREE_TYPE (type
)))
3805 error ("@catch parameter is not a known Objective-C class type");
3806 type
= error_mark_node
;
3808 else if (cur_try_context
->catch_list
)
3810 /* Examine previous @catch clauses and see if we've already
3811 caught the type in question. */
3812 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
3813 for (; !tsi_end_p (i
); tsi_next (&i
))
3815 tree stmt
= tsi_stmt (i
);
3816 t
= CATCH_TYPES (stmt
);
3817 if (t
== error_mark_node
)
3819 if (!t
|| DERIVED_FROM_P (TREE_TYPE (t
), TREE_TYPE (type
)))
3821 warning (0, "exception of type %<%T%> will be caught",
3823 warning (0, "%H by earlier handler for %<%T%>",
3824 EXPR_LOCUS (stmt
), TREE_TYPE (t
? t
: objc_object_type
));
3830 /* Record the data for the catch in the try context so that we can
3831 finalize it later. */
3832 t
= build_stmt (CATCH_EXPR
, type
, compound
);
3833 cur_try_context
->current_catch
= t
;
3835 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3836 t
= objc_build_exc_ptr ();
3837 t
= convert (TREE_TYPE (decl
), t
);
3838 t
= build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
3842 /* Called just after parsing the closing brace of a @catch clause. Close
3843 the open binding level, and record a CATCH_EXPR for it. */
3846 objc_finish_catch_clause (void)
3848 tree c
= cur_try_context
->current_catch
;
3849 cur_try_context
->current_catch
= NULL
;
3850 cur_try_context
->end_catch_locus
= input_location
;
3852 CATCH_BODY (c
) = c_end_compound_stmt (CATCH_BODY (c
), 1);
3853 append_to_statement_list (c
, &cur_try_context
->catch_list
);
3856 /* Called after parsing a @finally clause and its associated BODY.
3857 Record the body for later placement. */
3860 objc_build_finally_clause (location_t finally_locus
, tree body
)
3862 cur_try_context
->finally_body
= body
;
3863 cur_try_context
->finally_locus
= finally_locus
;
3864 cur_try_context
->end_finally_locus
= input_location
;
3867 /* Called to finalize a @try construct. */
3870 objc_finish_try_stmt (void)
3872 struct objc_try_context
*c
= cur_try_context
;
3875 if (c
->catch_list
== NULL
&& c
->finally_body
== NULL
)
3876 error ("%<@try%> without %<@catch%> or %<@finally%>");
3878 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3879 if (flag_objc_sjlj_exceptions
)
3881 if (!cur_try_context
->finally_body
)
3883 cur_try_context
->finally_locus
= input_location
;
3884 cur_try_context
->end_finally_locus
= input_location
;
3886 stmt
= next_sjlj_build_try_catch_finally ();
3890 /* Otherwise, nest the CATCH inside a FINALLY. */
3894 stmt
= build_stmt (TRY_CATCH_EXPR
, stmt
, c
->catch_list
);
3895 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
3897 if (c
->finally_body
)
3899 stmt
= build_stmt (TRY_FINALLY_EXPR
, stmt
, c
->finally_body
);
3900 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
3905 cur_try_context
= c
->outer
;
3911 objc_build_throw_stmt (tree throw_expr
)
3915 objc_init_exceptions ();
3917 if (throw_expr
== NULL
)
3919 /* If we're not inside a @catch block, there is no "current
3920 exception" to be rethrown. */
3921 if (cur_try_context
== NULL
3922 || cur_try_context
->current_catch
== NULL
)
3924 error ("%<@throw%> (rethrow) used outside of a @catch block");
3928 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3929 value that we get from the runtime. */
3930 throw_expr
= objc_build_exc_ptr ();
3933 /* A throw is just a call to the runtime throw function with the
3934 object as a parameter. */
3935 args
= tree_cons (NULL
, throw_expr
, NULL
);
3936 return add_stmt (build_function_call (objc_exception_throw_decl
, args
));
3940 objc_build_synchronized (location_t start_locus
, tree mutex
, tree body
)
3944 /* First lock the mutex. */
3945 mutex
= save_expr (mutex
);
3946 args
= tree_cons (NULL
, mutex
, NULL
);
3947 call
= build_function_call (objc_sync_enter_decl
, args
);
3948 SET_EXPR_LOCATION (call
, start_locus
);
3951 /* Build the mutex unlock. */
3952 args
= tree_cons (NULL
, mutex
, NULL
);
3953 call
= build_function_call (objc_sync_exit_decl
, args
);
3954 SET_EXPR_LOCATION (call
, input_location
);
3956 /* Put the that and the body in a TRY_FINALLY. */
3957 objc_begin_try_stmt (start_locus
, body
);
3958 objc_build_finally_clause (input_location
, call
);
3959 return objc_finish_try_stmt ();
3963 /* Predefine the following data type:
3965 struct _objc_exception_data
3967 int buf[OBJC_JBLEN];
3971 /* The following yuckiness should prevent users from having to #include
3972 <setjmp.h> in their code... */
3974 /* Define to a harmless positive value so the below code doesn't die. */
3976 #define OBJC_JBLEN 18
3980 build_next_objc_exception_stuff (void)
3982 tree field_decl
, field_decl_chain
, index
, temp_type
;
3984 objc_exception_data_template
3985 = start_struct (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
3987 /* int buf[OBJC_JBLEN]; */
3989 index
= build_index_type (build_int_cst (NULL_TREE
, OBJC_JBLEN
- 1));
3990 field_decl
= create_field_decl (build_array_type (integer_type_node
, index
),
3992 field_decl_chain
= field_decl
;
3994 /* void *pointers[4]; */
3996 index
= build_index_type (build_int_cst (NULL_TREE
, 4 - 1));
3997 field_decl
= create_field_decl (build_array_type (ptr_type_node
, index
),
3999 chainon (field_decl_chain
, field_decl
);
4001 finish_struct (objc_exception_data_template
, field_decl_chain
, NULL_TREE
);
4003 /* int _setjmp(...); */
4004 /* If the user includes <setjmp.h>, this shall be superseded by
4005 'int _setjmp(jmp_buf);' */
4006 temp_type
= build_function_type (integer_type_node
, NULL_TREE
);
4008 = add_builtin_function (TAG_SETJMP
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
4010 /* id objc_exception_extract(struct _objc_exception_data *); */
4012 = build_function_type (objc_object_type
,
4013 tree_cons (NULL_TREE
,
4014 build_pointer_type (objc_exception_data_template
),
4016 objc_exception_extract_decl
4017 = add_builtin_function (TAG_EXCEPTIONEXTRACT
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4019 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4020 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4022 = build_function_type (void_type_node
,
4023 tree_cons (NULL_TREE
,
4024 build_pointer_type (objc_exception_data_template
),
4026 objc_exception_try_enter_decl
4027 = add_builtin_function (TAG_EXCEPTIONTRYENTER
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4029 objc_exception_try_exit_decl
4030 = add_builtin_function (TAG_EXCEPTIONTRYEXIT
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4033 /* int objc_exception_match(id, id); */
4035 = build_function_type (integer_type_node
,
4036 tree_cons (NULL_TREE
, objc_object_type
,
4037 tree_cons (NULL_TREE
, objc_object_type
,
4038 OBJC_VOID_AT_END
)));
4039 objc_exception_match_decl
4040 = add_builtin_function (TAG_EXCEPTIONMATCH
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4043 /* id objc_assign_ivar (id, id, unsigned int); */
4044 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4045 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4047 = build_function_type (objc_object_type
,
4049 (NULL_TREE
, objc_object_type
,
4050 tree_cons (NULL_TREE
, objc_object_type
,
4051 tree_cons (NULL_TREE
,
4053 OBJC_VOID_AT_END
))));
4054 objc_assign_ivar_decl
4055 = add_builtin_function (TAG_ASSIGNIVAR
, temp_type
, 0, NOT_BUILT_IN
,
4057 #ifdef OFFS_ASSIGNIVAR_FAST
4058 objc_assign_ivar_fast_decl
4059 = add_builtin_function (TAG_ASSIGNIVAR_FAST
, temp_type
, 0,
4060 NOT_BUILT_IN
, NULL
, NULL_TREE
);
4061 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl
)
4062 = tree_cons (get_identifier ("hard_coded_address"),
4063 build_int_cst (NULL_TREE
, OFFS_ASSIGNIVAR_FAST
),
4066 /* Default to slower ivar method. */
4067 objc_assign_ivar_fast_decl
= objc_assign_ivar_decl
;
4070 /* id objc_assign_global (id, id *); */
4071 /* id objc_assign_strongCast (id, id *); */
4072 temp_type
= build_function_type (objc_object_type
,
4073 tree_cons (NULL_TREE
, objc_object_type
,
4074 tree_cons (NULL_TREE
, build_pointer_type (objc_object_type
),
4075 OBJC_VOID_AT_END
)));
4076 objc_assign_global_decl
4077 = add_builtin_function (TAG_ASSIGNGLOBAL
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4079 objc_assign_strong_cast_decl
4080 = add_builtin_function (TAG_ASSIGNSTRONGCAST
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4085 build_objc_exception_stuff (void)
4087 tree noreturn_list
, nothrow_list
, temp_type
;
4089 noreturn_list
= tree_cons (get_identifier ("noreturn"), NULL
, NULL
);
4090 nothrow_list
= tree_cons (get_identifier ("nothrow"), NULL
, NULL
);
4092 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4093 /* void objc_sync_enter(id); */
4094 /* void objc_sync_exit(id); */
4095 temp_type
= build_function_type (void_type_node
,
4096 tree_cons (NULL_TREE
, objc_object_type
,
4098 objc_exception_throw_decl
4099 = add_builtin_function (TAG_EXCEPTIONTHROW
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
4101 objc_sync_enter_decl
4102 = add_builtin_function (TAG_SYNCENTER
, temp_type
, 0, NOT_BUILT_IN
,
4103 NULL
, nothrow_list
);
4105 = add_builtin_function (TAG_SYNCEXIT
, temp_type
, 0, NOT_BUILT_IN
,
4106 NULL
, nothrow_list
);
4109 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4112 struct <classname> {
4113 struct _objc_class *isa;
4118 build_private_template (tree
class)
4120 if (!CLASS_STATIC_TEMPLATE (class))
4122 tree record
= objc_build_struct (class,
4123 get_class_ivars (class, false),
4124 CLASS_SUPER_NAME (class));
4126 /* Set the TREE_USED bit for this struct, so that stab generator
4127 can emit stabs for this struct type. */
4128 if (flag_debug_only_used_symbols
&& TYPE_STUB_DECL (record
))
4129 TREE_USED (TYPE_STUB_DECL (record
)) = 1;
4133 /* Begin code generation for protocols... */
4135 /* struct _objc_protocol {
4136 struct _objc_class *isa;
4137 char *protocol_name;
4138 struct _objc_protocol **protocol_list;
4139 struct _objc__method_prototype_list *instance_methods;
4140 struct _objc__method_prototype_list *class_methods;
4144 build_protocol_template (void)
4146 tree field_decl
, field_decl_chain
;
4148 objc_protocol_template
= start_struct (RECORD_TYPE
,
4149 get_identifier (UTAG_PROTOCOL
));
4151 /* struct _objc_class *isa; */
4152 field_decl
= create_field_decl (build_pointer_type
4153 (xref_tag (RECORD_TYPE
,
4154 get_identifier (UTAG_CLASS
))),
4156 field_decl_chain
= field_decl
;
4158 /* char *protocol_name; */
4159 field_decl
= create_field_decl (string_type_node
, "protocol_name");
4160 chainon (field_decl_chain
, field_decl
);
4162 /* struct _objc_protocol **protocol_list; */
4163 field_decl
= create_field_decl (build_pointer_type
4165 (objc_protocol_template
)),
4167 chainon (field_decl_chain
, field_decl
);
4169 /* struct _objc__method_prototype_list *instance_methods; */
4170 field_decl
= create_field_decl (objc_method_proto_list_ptr
,
4171 "instance_methods");
4172 chainon (field_decl_chain
, field_decl
);
4174 /* struct _objc__method_prototype_list *class_methods; */
4175 field_decl
= create_field_decl (objc_method_proto_list_ptr
,
4177 chainon (field_decl_chain
, field_decl
);
4179 finish_struct (objc_protocol_template
, field_decl_chain
, NULL_TREE
);
4183 build_descriptor_table_initializer (tree type
, tree entries
)
4185 tree initlist
= NULL_TREE
;
4189 tree eltlist
= NULL_TREE
;
4192 = tree_cons (NULL_TREE
,
4193 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
4195 = tree_cons (NULL_TREE
,
4196 add_objc_string (METHOD_ENCODING (entries
),
4201 = tree_cons (NULL_TREE
,
4202 objc_build_constructor (type
, nreverse (eltlist
)),
4205 entries
= TREE_CHAIN (entries
);
4209 return objc_build_constructor (build_array_type (type
, 0),
4210 nreverse (initlist
));
4213 /* struct objc_method_prototype_list {
4215 struct objc_method_prototype {
4222 build_method_prototype_list_template (tree list_type
, int size
)
4224 tree objc_ivar_list_record
;
4225 tree field_decl
, field_decl_chain
;
4227 /* Generate an unnamed struct definition. */
4229 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
4231 /* int method_count; */
4232 field_decl
= create_field_decl (integer_type_node
, "method_count");
4233 field_decl_chain
= field_decl
;
4235 /* struct objc_method method_list[]; */
4236 field_decl
= create_field_decl (build_array_type
4239 (build_int_cst (NULL_TREE
, size
- 1))),
4241 chainon (field_decl_chain
, field_decl
);
4243 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
4245 return objc_ivar_list_record
;
4249 build_method_prototype_template (void)
4252 tree field_decl
, field_decl_chain
;
4255 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
4258 field_decl
= create_field_decl (objc_selector_type
, "_cmd");
4259 field_decl_chain
= field_decl
;
4261 /* char *method_types; */
4262 field_decl
= create_field_decl (string_type_node
, "method_types");
4263 chainon (field_decl_chain
, field_decl
);
4265 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
4267 return proto_record
;
4271 objc_method_parm_type (tree type
)
4273 type
= TREE_VALUE (TREE_TYPE (type
));
4274 if (TREE_CODE (type
) == TYPE_DECL
)
4275 type
= TREE_TYPE (type
);
4280 objc_encoded_type_size (tree type
)
4282 int sz
= int_size_in_bytes (type
);
4284 /* Make all integer and enum types at least as large
4286 if (sz
> 0 && INTEGRAL_TYPE_P (type
))
4287 sz
= MAX (sz
, int_size_in_bytes (integer_type_node
));
4288 /* Treat arrays as pointers, since that's how they're
4290 else if (TREE_CODE (type
) == ARRAY_TYPE
)
4291 sz
= int_size_in_bytes (ptr_type_node
);
4296 encode_method_prototype (tree method_decl
)
4303 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4304 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
4306 /* Encode return type. */
4307 encode_type (objc_method_parm_type (method_decl
),
4308 obstack_object_size (&util_obstack
),
4309 OBJC_ENCODE_INLINE_DEFS
);
4312 /* The first two arguments (self and _cmd) are pointers; account for
4314 i
= int_size_in_bytes (ptr_type_node
);
4315 parm_offset
= 2 * i
;
4316 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
4317 parms
= TREE_CHAIN (parms
))
4319 tree type
= objc_method_parm_type (parms
);
4320 int sz
= objc_encoded_type_size (type
);
4322 /* If a type size is not known, bail out. */
4325 error ("type %q+D does not have a known size",
4327 /* Pretend that the encoding succeeded; the compilation will
4328 fail nevertheless. */
4329 goto finish_encoding
;
4334 sprintf (buf
, "%d@0:%d", parm_offset
, i
);
4335 obstack_grow (&util_obstack
, buf
, strlen (buf
));
4337 /* Argument types. */
4338 parm_offset
= 2 * i
;
4339 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
4340 parms
= TREE_CHAIN (parms
))
4342 tree type
= objc_method_parm_type (parms
);
4344 /* Process argument qualifiers for user supplied arguments. */
4345 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms
)));
4348 encode_type (type
, obstack_object_size (&util_obstack
),
4349 OBJC_ENCODE_INLINE_DEFS
);
4351 /* Compute offset. */
4352 sprintf (buf
, "%d", parm_offset
);
4353 parm_offset
+= objc_encoded_type_size (type
);
4355 obstack_grow (&util_obstack
, buf
, strlen (buf
));
4359 obstack_1grow (&util_obstack
, '\0');
4360 result
= get_identifier (obstack_finish (&util_obstack
));
4361 obstack_free (&util_obstack
, util_firstobj
);
4366 generate_descriptor_table (tree type
, const char *name
, int size
, tree list
,
4369 tree decl
, initlist
;
4371 decl
= start_var_decl (type
, synth_id_with_class_suffix (name
, proto
));
4373 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, size
));
4374 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4376 finish_var_decl (decl
, objc_build_constructor (type
, nreverse (initlist
)));
4382 generate_method_descriptors (tree protocol
)
4384 tree initlist
, chain
, method_list_template
;
4387 if (!objc_method_prototype_template
)
4388 objc_method_prototype_template
= build_method_prototype_template ();
4390 chain
= PROTOCOL_CLS_METHODS (protocol
);
4393 size
= list_length (chain
);
4395 method_list_template
4396 = build_method_prototype_list_template (objc_method_prototype_template
,
4400 = build_descriptor_table_initializer (objc_method_prototype_template
,
4403 UOBJC_CLASS_METHODS_decl
4404 = generate_descriptor_table (method_list_template
,
4405 "_OBJC_PROTOCOL_CLASS_METHODS",
4406 size
, initlist
, protocol
);
4409 UOBJC_CLASS_METHODS_decl
= 0;
4411 chain
= PROTOCOL_NST_METHODS (protocol
);
4414 size
= list_length (chain
);
4416 method_list_template
4417 = build_method_prototype_list_template (objc_method_prototype_template
,
4420 = build_descriptor_table_initializer (objc_method_prototype_template
,
4423 UOBJC_INSTANCE_METHODS_decl
4424 = generate_descriptor_table (method_list_template
,
4425 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4426 size
, initlist
, protocol
);
4429 UOBJC_INSTANCE_METHODS_decl
= 0;
4433 generate_protocol_references (tree plist
)
4437 /* Forward declare protocols referenced. */
4438 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4440 tree proto
= TREE_VALUE (lproto
);
4442 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
4443 && PROTOCOL_NAME (proto
))
4445 if (! PROTOCOL_FORWARD_DECL (proto
))
4446 build_protocol_reference (proto
);
4448 if (PROTOCOL_LIST (proto
))
4449 generate_protocol_references (PROTOCOL_LIST (proto
));
4454 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4458 objc_generate_cxx_ctor_or_dtor (bool dtor
)
4460 tree fn
, body
, compound_stmt
, ivar
;
4462 /* - (id) .cxx_construct { ... return self; } */
4463 /* - (void) .cxx_construct { ... } */
4465 objc_set_method_type (MINUS_EXPR
);
4466 objc_start_method_definition
4467 (objc_build_method_signature (build_tree_list (NULL_TREE
,
4470 : objc_object_type
),
4471 get_identifier (dtor
4473 : TAG_CXX_CONSTRUCT
),
4474 make_node (TREE_LIST
),
4476 body
= begin_function_body ();
4477 compound_stmt
= begin_compound_stmt (0);
4479 ivar
= CLASS_IVARS (implementation_template
);
4480 /* Destroy ivars in reverse order. */
4482 ivar
= nreverse (copy_list (ivar
));
4484 for (; ivar
; ivar
= TREE_CHAIN (ivar
))
4486 if (TREE_CODE (ivar
) == FIELD_DECL
)
4488 tree type
= TREE_TYPE (ivar
);
4490 /* Call the ivar's default constructor or destructor. Do not
4491 call the destructor unless a corresponding constructor call
4492 has also been made (or is not needed). */
4493 if (IS_AGGR_TYPE (type
)
4495 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type
)
4496 && (!TYPE_NEEDS_CONSTRUCTING (type
)
4497 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type
)))
4498 : (TYPE_NEEDS_CONSTRUCTING (type
)
4499 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type
))))
4501 (build_special_member_call
4502 (build_ivar_reference (DECL_NAME (ivar
)),
4503 dtor
? complete_dtor_identifier
: complete_ctor_identifier
,
4504 NULL_TREE
, type
, LOOKUP_NORMAL
));
4508 /* The constructor returns 'self'. */
4510 finish_return_stmt (self_decl
);
4512 finish_compound_stmt (compound_stmt
);
4513 finish_function_body (body
);
4514 fn
= current_function_decl
;
4516 objc_finish_method_definition (fn
);
4519 /* The following routine will examine the current @interface for any
4520 non-POD C++ ivars requiring non-trivial construction and/or
4521 destruction, and then synthesize special '- .cxx_construct' and/or
4522 '- .cxx_destruct' methods which will run the appropriate
4523 construction or destruction code. Note that ivars inherited from
4524 super-classes are _not_ considered. */
4526 objc_generate_cxx_cdtors (void)
4528 bool need_ctor
= false, need_dtor
= false;
4531 /* We do not want to do this for categories, since they do not have
4534 if (TREE_CODE (objc_implementation_context
) != CLASS_IMPLEMENTATION_TYPE
)
4537 /* First, determine if we even need a constructor and/or destructor. */
4539 for (ivar
= CLASS_IVARS (implementation_template
); ivar
;
4540 ivar
= TREE_CHAIN (ivar
))
4542 if (TREE_CODE (ivar
) == FIELD_DECL
)
4544 tree type
= TREE_TYPE (ivar
);
4546 if (IS_AGGR_TYPE (type
))
4548 if (TYPE_NEEDS_CONSTRUCTING (type
)
4549 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type
))
4550 /* NB: If a default constructor is not available, we will not
4551 be able to initialize this ivar; the add_instance_variable()
4552 routine will already have warned about this. */
4555 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type
)
4556 && (!TYPE_NEEDS_CONSTRUCTING (type
)
4557 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type
)))
4558 /* NB: If a default constructor is not available, we will not
4559 call the destructor either, for symmetry. */
4565 /* Generate '- .cxx_construct' if needed. */
4568 objc_generate_cxx_ctor_or_dtor (false);
4570 /* Generate '- .cxx_destruct' if needed. */
4573 objc_generate_cxx_ctor_or_dtor (true);
4575 /* The 'imp_list' variable points at an imp_entry record for the current
4576 @implementation. Record the existence of '- .cxx_construct' and/or
4577 '- .cxx_destruct' methods therein; it will be included in the
4578 metadata for the class. */
4579 if (flag_next_runtime
)
4580 imp_list
->has_cxx_cdtors
= (need_ctor
|| need_dtor
);
4584 /* For each protocol which was referenced either from a @protocol()
4585 expression, or because a class/category implements it (then a
4586 pointer to the protocol is stored in the struct describing the
4587 class/category), we create a statically allocated instance of the
4588 Protocol class. The code is written in such a way as to generate
4589 as few Protocol objects as possible; we generate a unique Protocol
4590 instance for each protocol, and we don't generate a Protocol
4591 instance if the protocol is never referenced (either from a
4592 @protocol() or from a class/category implementation). These
4593 statically allocated objects can be referred to via the static
4594 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4596 The statically allocated Protocol objects that we generate here
4597 need to be fixed up at runtime in order to be used: the 'isa'
4598 pointer of the objects need to be set up to point to the 'Protocol'
4599 class, as known at runtime.
4601 The NeXT runtime fixes up all protocols at program startup time,
4602 before main() is entered. It uses a low-level trick to look up all
4603 those symbols, then loops on them and fixes them up.
4605 The GNU runtime as well fixes up all protocols before user code
4606 from the module is executed; it requires pointers to those symbols
4607 to be put in the objc_symtab (which is then passed as argument to
4608 the function __objc_exec_class() which the compiler sets up to be
4609 executed automatically when the module is loaded); setup of those
4610 Protocol objects happen in two ways in the GNU runtime: all
4611 Protocol objects referred to by a class or category implementation
4612 are fixed up when the class/category is loaded; all Protocol
4613 objects referred to by a @protocol() expression are added by the
4614 compiler to the list of statically allocated instances to fixup
4615 (the same list holding the statically allocated constant string
4616 objects). Because, as explained above, the compiler generates as
4617 few Protocol objects as possible, some Protocol object might end up
4618 being referenced multiple times when compiled with the GNU runtime,
4619 and end up being fixed up multiple times at runtime initialization.
4620 But that doesn't hurt, it's just a little inefficient. */
4623 generate_protocols (void)
4627 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
4629 /* If a protocol was directly referenced, pull in indirect references. */
4630 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
4631 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
4632 generate_protocol_references (PROTOCOL_LIST (p
));
4634 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
4636 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
4637 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
4639 /* If protocol wasn't referenced, don't generate any code. */
4640 decl
= PROTOCOL_FORWARD_DECL (p
);
4645 /* Make sure we link in the Protocol class. */
4646 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
4650 if (! METHOD_ENCODING (nst_methods
))
4652 encoding
= encode_method_prototype (nst_methods
);
4653 METHOD_ENCODING (nst_methods
) = encoding
;
4655 nst_methods
= TREE_CHAIN (nst_methods
);
4660 if (! METHOD_ENCODING (cls_methods
))
4662 encoding
= encode_method_prototype (cls_methods
);
4663 METHOD_ENCODING (cls_methods
) = encoding
;
4666 cls_methods
= TREE_CHAIN (cls_methods
);
4668 generate_method_descriptors (p
);
4670 if (PROTOCOL_LIST (p
))
4671 refs_decl
= generate_protocol_list (p
);
4675 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4676 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
4679 refs_expr
= convert (build_pointer_type (build_pointer_type
4680 (objc_protocol_template
)),
4681 build_unary_op (ADDR_EXPR
, refs_decl
, 0));
4683 refs_expr
= build_int_cst (NULL_TREE
, 0);
4685 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4686 by generate_method_descriptors, which is called above. */
4687 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
4688 protocol_name_expr
, refs_expr
,
4689 UOBJC_INSTANCE_METHODS_decl
,
4690 UOBJC_CLASS_METHODS_decl
);
4691 finish_var_decl (decl
, initlist
);
4696 build_protocol_initializer (tree type
, tree protocol_name
,
4697 tree protocol_list
, tree instance_methods
,
4700 tree initlist
= NULL_TREE
, expr
;
4701 tree cast_type
= build_pointer_type
4702 (xref_tag (RECORD_TYPE
,
4703 get_identifier (UTAG_CLASS
)));
4705 /* Filling the "isa" in with one allows the runtime system to
4706 detect that the version change...should remove before final release. */
4708 expr
= build_int_cst (cast_type
, PROTOCOL_VERSION
);
4709 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4710 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
4711 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
4713 if (!instance_methods
)
4714 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4717 expr
= convert (objc_method_proto_list_ptr
,
4718 build_unary_op (ADDR_EXPR
, instance_methods
, 0));
4719 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4723 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4726 expr
= convert (objc_method_proto_list_ptr
,
4727 build_unary_op (ADDR_EXPR
, class_methods
, 0));
4728 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4731 return objc_build_constructor (type
, nreverse (initlist
));
4734 /* struct _objc_category {
4735 char *category_name;
4737 struct _objc_method_list *instance_methods;
4738 struct _objc_method_list *class_methods;
4739 struct _objc_protocol_list *protocols;
4743 build_category_template (void)
4745 tree field_decl
, field_decl_chain
;
4747 objc_category_template
= start_struct (RECORD_TYPE
,
4748 get_identifier (UTAG_CATEGORY
));
4750 /* char *category_name; */
4751 field_decl
= create_field_decl (string_type_node
, "category_name");
4752 field_decl_chain
= field_decl
;
4754 /* char *class_name; */
4755 field_decl
= create_field_decl (string_type_node
, "class_name");
4756 chainon (field_decl_chain
, field_decl
);
4758 /* struct _objc_method_list *instance_methods; */
4759 field_decl
= create_field_decl (objc_method_list_ptr
,
4760 "instance_methods");
4761 chainon (field_decl_chain
, field_decl
);
4763 /* struct _objc_method_list *class_methods; */
4764 field_decl
= create_field_decl (objc_method_list_ptr
,
4766 chainon (field_decl_chain
, field_decl
);
4768 /* struct _objc_protocol **protocol_list; */
4769 field_decl
= create_field_decl (build_pointer_type
4771 (objc_protocol_template
)),
4773 chainon (field_decl_chain
, field_decl
);
4775 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
4778 /* struct _objc_selector {
4784 build_selector_template (void)
4787 tree field_decl
, field_decl_chain
;
4789 objc_selector_template
4790 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
4793 field_decl
= create_field_decl (objc_selector_type
, "sel_id");
4794 field_decl_chain
= field_decl
;
4796 /* char *sel_type; */
4797 field_decl
= create_field_decl (string_type_node
, "sel_type");
4798 chainon (field_decl_chain
, field_decl
);
4800 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
4803 /* struct _objc_class {
4804 struct _objc_class *isa;
4805 struct _objc_class *super_class;
4810 struct _objc_ivar_list *ivars;
4811 struct _objc_method_list *methods;
4812 #ifdef __NEXT_RUNTIME__
4813 struct objc_cache *cache;
4815 struct sarray *dtable;
4816 struct _objc_class *subclass_list;
4817 struct _objc_class *sibling_class;
4819 struct _objc_protocol_list *protocols;
4820 #ifdef __NEXT_RUNTIME__
4823 void *gc_object_type;
4826 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4827 the NeXT/Apple runtime; still, the compiler must generate them to
4828 maintain backward binary compatibility (and to allow for future
4832 build_class_template (void)
4834 tree field_decl
, field_decl_chain
;
4837 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
4839 /* struct _objc_class *isa; */
4840 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4842 field_decl_chain
= field_decl
;
4844 /* struct _objc_class *super_class; */
4845 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4847 chainon (field_decl_chain
, field_decl
);
4850 field_decl
= create_field_decl (string_type_node
, "name");
4851 chainon (field_decl_chain
, field_decl
);
4854 field_decl
= create_field_decl (long_integer_type_node
, "version");
4855 chainon (field_decl_chain
, field_decl
);
4858 field_decl
= create_field_decl (long_integer_type_node
, "info");
4859 chainon (field_decl_chain
, field_decl
);
4861 /* long instance_size; */
4862 field_decl
= create_field_decl (long_integer_type_node
, "instance_size");
4863 chainon (field_decl_chain
, field_decl
);
4865 /* struct _objc_ivar_list *ivars; */
4866 field_decl
= create_field_decl (objc_ivar_list_ptr
,
4868 chainon (field_decl_chain
, field_decl
);
4870 /* struct _objc_method_list *methods; */
4871 field_decl
= create_field_decl (objc_method_list_ptr
,
4873 chainon (field_decl_chain
, field_decl
);
4875 if (flag_next_runtime
)
4877 /* struct objc_cache *cache; */
4878 field_decl
= create_field_decl (build_pointer_type
4879 (xref_tag (RECORD_TYPE
,
4883 chainon (field_decl_chain
, field_decl
);
4887 /* struct sarray *dtable; */
4888 field_decl
= create_field_decl (build_pointer_type
4889 (xref_tag (RECORD_TYPE
,
4893 chainon (field_decl_chain
, field_decl
);
4895 /* struct objc_class *subclass_list; */
4896 field_decl
= create_field_decl (build_pointer_type
4897 (objc_class_template
),
4899 chainon (field_decl_chain
, field_decl
);
4901 /* struct objc_class *sibling_class; */
4902 field_decl
= create_field_decl (build_pointer_type
4903 (objc_class_template
),
4905 chainon (field_decl_chain
, field_decl
);
4908 /* struct _objc_protocol **protocol_list; */
4909 field_decl
= create_field_decl (build_pointer_type
4911 (xref_tag (RECORD_TYPE
,
4915 chainon (field_decl_chain
, field_decl
);
4917 if (flag_next_runtime
)
4920 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4922 chainon (field_decl_chain
, field_decl
);
4925 /* void *gc_object_type; */
4926 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4928 chainon (field_decl_chain
, field_decl
);
4930 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
4933 /* Generate appropriate forward declarations for an implementation. */
4936 synth_forward_declarations (void)
4940 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4941 UOBJC_CLASS_decl
= build_metadata_decl ("_OBJC_CLASS",
4942 objc_class_template
);
4944 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4945 UOBJC_METACLASS_decl
= build_metadata_decl ("_OBJC_METACLASS",
4946 objc_class_template
);
4948 /* Pre-build the following entities - for speed/convenience. */
4950 an_id
= get_identifier ("super_class");
4951 ucls_super_ref
= objc_build_component_ref (UOBJC_CLASS_decl
, an_id
);
4952 uucls_super_ref
= objc_build_component_ref (UOBJC_METACLASS_decl
, an_id
);
4956 error_with_ivar (const char *message
, tree decl
)
4958 error ("%J%s %qs", decl
,
4959 message
, gen_declaration (decl
));
4964 check_ivars (tree inter
, tree imp
)
4966 tree intdecls
= CLASS_RAW_IVARS (inter
);
4967 tree impdecls
= CLASS_RAW_IVARS (imp
);
4974 if (intdecls
&& TREE_CODE (intdecls
) == TYPE_DECL
)
4975 intdecls
= TREE_CHAIN (intdecls
);
4977 if (intdecls
== 0 && impdecls
== 0)
4979 if (intdecls
== 0 || impdecls
== 0)
4981 error ("inconsistent instance variable specification");
4985 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
4987 if (!comptypes (t1
, t2
)
4988 || !tree_int_cst_equal (DECL_INITIAL (intdecls
),
4989 DECL_INITIAL (impdecls
)))
4991 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
4993 error_with_ivar ("conflicting instance variable type",
4995 error_with_ivar ("previous declaration of",
4998 else /* both the type and the name don't match */
5000 error ("inconsistent instance variable specification");
5005 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
5007 error_with_ivar ("conflicting instance variable name",
5009 error_with_ivar ("previous declaration of",
5013 intdecls
= TREE_CHAIN (intdecls
);
5014 impdecls
= TREE_CHAIN (impdecls
);
5018 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5019 This needs to be done just once per compilation. */
5021 /* struct _objc_super {
5022 struct _objc_object *self;
5023 struct _objc_class *super_class;
5027 build_super_template (void)
5029 tree field_decl
, field_decl_chain
;
5031 objc_super_template
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
5033 /* struct _objc_object *self; */
5034 field_decl
= create_field_decl (objc_object_type
, "self");
5035 field_decl_chain
= field_decl
;
5037 /* struct _objc_class *super_class; */
5038 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
5040 chainon (field_decl_chain
, field_decl
);
5042 finish_struct (objc_super_template
, field_decl_chain
, NULL_TREE
);
5045 /* struct _objc_ivar {
5052 build_ivar_template (void)
5054 tree objc_ivar_id
, objc_ivar_record
;
5055 tree field_decl
, field_decl_chain
;
5057 objc_ivar_id
= get_identifier (UTAG_IVAR
);
5058 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
5060 /* char *ivar_name; */
5061 field_decl
= create_field_decl (string_type_node
, "ivar_name");
5062 field_decl_chain
= field_decl
;
5064 /* char *ivar_type; */
5065 field_decl
= create_field_decl (string_type_node
, "ivar_type");
5066 chainon (field_decl_chain
, field_decl
);
5068 /* int ivar_offset; */
5069 field_decl
= create_field_decl (integer_type_node
, "ivar_offset");
5070 chainon (field_decl_chain
, field_decl
);
5072 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
5074 return objc_ivar_record
;
5079 struct objc_ivar ivar_list[ivar_count];
5083 build_ivar_list_template (tree list_type
, int size
)
5085 tree objc_ivar_list_record
;
5086 tree field_decl
, field_decl_chain
;
5088 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
5090 /* int ivar_count; */
5091 field_decl
= create_field_decl (integer_type_node
, "ivar_count");
5092 field_decl_chain
= field_decl
;
5094 /* struct objc_ivar ivar_list[]; */
5095 field_decl
= create_field_decl (build_array_type
5098 (build_int_cst (NULL_TREE
, size
- 1))),
5100 chainon (field_decl_chain
, field_decl
);
5102 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
5104 return objc_ivar_list_record
;
5108 struct _objc__method_prototype_list *method_next;
5110 struct objc_method method_list[method_count];
5114 build_method_list_template (tree list_type
, int size
)
5116 tree objc_ivar_list_record
;
5117 tree field_decl
, field_decl_chain
;
5119 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
5121 /* struct _objc__method_prototype_list *method_next; */
5122 field_decl
= create_field_decl (objc_method_proto_list_ptr
,
5124 field_decl_chain
= field_decl
;
5126 /* int method_count; */
5127 field_decl
= create_field_decl (integer_type_node
, "method_count");
5128 chainon (field_decl_chain
, field_decl
);
5130 /* struct objc_method method_list[]; */
5131 field_decl
= create_field_decl (build_array_type
5134 (build_int_cst (NULL_TREE
, size
- 1))),
5136 chainon (field_decl_chain
, field_decl
);
5138 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
5140 return objc_ivar_list_record
;
5144 build_ivar_list_initializer (tree type
, tree field_decl
)
5146 tree initlist
= NULL_TREE
;
5150 tree ivar
= NULL_TREE
;
5153 if (DECL_NAME (field_decl
))
5154 ivar
= tree_cons (NULL_TREE
,
5155 add_objc_string (DECL_NAME (field_decl
),
5159 /* Unnamed bit-field ivar (yuck). */
5160 ivar
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), ivar
);
5163 encode_field_decl (field_decl
,
5164 obstack_object_size (&util_obstack
),
5165 OBJC_ENCODE_DONT_INLINE_DEFS
);
5167 /* Null terminate string. */
5168 obstack_1grow (&util_obstack
, 0);
5172 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
5175 obstack_free (&util_obstack
, util_firstobj
);
5178 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
5179 initlist
= tree_cons (NULL_TREE
,
5180 objc_build_constructor (type
, nreverse (ivar
)),
5183 field_decl
= TREE_CHAIN (field_decl
);
5184 while (field_decl
&& TREE_CODE (field_decl
) != FIELD_DECL
);
5188 return objc_build_constructor (build_array_type (type
, 0),
5189 nreverse (initlist
));
5193 generate_ivars_list (tree type
, const char *name
, int size
, tree list
)
5195 tree decl
, initlist
;
5197 decl
= start_var_decl (type
, synth_id_with_class_suffix
5198 (name
, objc_implementation_context
));
5200 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, size
));
5201 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
5203 finish_var_decl (decl
,
5204 objc_build_constructor (TREE_TYPE (decl
),
5205 nreverse (initlist
)));
5210 /* Count only the fields occurring in T. */
5213 ivar_list_length (tree t
)
5217 for (; t
; t
= TREE_CHAIN (t
))
5218 if (TREE_CODE (t
) == FIELD_DECL
)
5225 generate_ivar_lists (void)
5227 tree initlist
, ivar_list_template
, chain
;
5230 generating_instance_variables
= 1;
5232 if (!objc_ivar_template
)
5233 objc_ivar_template
= build_ivar_template ();
5235 /* Only generate class variables for the root of the inheritance
5236 hierarchy since these will be the same for every class. */
5238 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
5239 && (chain
= TYPE_FIELDS (objc_class_template
)))
5241 size
= ivar_list_length (chain
);
5243 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
5244 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
5246 UOBJC_CLASS_VARIABLES_decl
5247 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
5251 UOBJC_CLASS_VARIABLES_decl
= 0;
5253 chain
= CLASS_IVARS (implementation_template
);
5256 size
= ivar_list_length (chain
);
5257 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
5258 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
5260 UOBJC_INSTANCE_VARIABLES_decl
5261 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
5265 UOBJC_INSTANCE_VARIABLES_decl
= 0;
5267 generating_instance_variables
= 0;
5271 build_dispatch_table_initializer (tree type
, tree entries
)
5273 tree initlist
= NULL_TREE
;
5277 tree elemlist
= NULL_TREE
;
5279 elemlist
= tree_cons (NULL_TREE
,
5280 build_selector (METHOD_SEL_NAME (entries
)),
5283 /* Generate the method encoding if we don't have one already. */
5284 if (! METHOD_ENCODING (entries
))
5285 METHOD_ENCODING (entries
) =
5286 encode_method_prototype (entries
);
5288 elemlist
= tree_cons (NULL_TREE
,
5289 add_objc_string (METHOD_ENCODING (entries
),
5294 = tree_cons (NULL_TREE
,
5295 convert (ptr_type_node
,
5296 build_unary_op (ADDR_EXPR
,
5297 METHOD_DEFINITION (entries
), 1)),
5300 initlist
= tree_cons (NULL_TREE
,
5301 objc_build_constructor (type
, nreverse (elemlist
)),
5304 entries
= TREE_CHAIN (entries
);
5308 return objc_build_constructor (build_array_type (type
, 0),
5309 nreverse (initlist
));
5312 /* To accomplish method prototyping without generating all kinds of
5313 inane warnings, the definition of the dispatch table entries were
5316 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5318 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5321 build_method_template (void)
5324 tree field_decl
, field_decl_chain
;
5326 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
5329 field_decl
= create_field_decl (objc_selector_type
, "_cmd");
5330 field_decl_chain
= field_decl
;
5332 /* char *method_types; */
5333 field_decl
= create_field_decl (string_type_node
, "method_types");
5334 chainon (field_decl_chain
, field_decl
);
5337 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
5339 chainon (field_decl_chain
, field_decl
);
5341 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
5348 generate_dispatch_table (tree type
, const char *name
, int size
, tree list
)
5350 tree decl
, initlist
;
5352 decl
= start_var_decl (type
, synth_id_with_class_suffix
5353 (name
, objc_implementation_context
));
5355 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, 0));
5356 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, size
), initlist
);
5357 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
5359 finish_var_decl (decl
,
5360 objc_build_constructor (TREE_TYPE (decl
),
5361 nreverse (initlist
)));
5367 mark_referenced_methods (void)
5369 struct imp_entry
*impent
;
5372 for (impent
= imp_list
; impent
; impent
= impent
->next
)
5374 chain
= CLASS_CLS_METHODS (impent
->imp_context
);
5377 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
5378 chain
= TREE_CHAIN (chain
);
5381 chain
= CLASS_NST_METHODS (impent
->imp_context
);
5384 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
5385 chain
= TREE_CHAIN (chain
);
5391 generate_dispatch_tables (void)
5393 tree initlist
, chain
, method_list_template
;
5396 if (!objc_method_template
)
5397 objc_method_template
= build_method_template ();
5399 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
5402 size
= list_length (chain
);
5404 method_list_template
5405 = build_method_list_template (objc_method_template
, size
);
5407 = build_dispatch_table_initializer (objc_method_template
, chain
);
5409 UOBJC_CLASS_METHODS_decl
5410 = generate_dispatch_table (method_list_template
,
5411 ((TREE_CODE (objc_implementation_context
)
5412 == CLASS_IMPLEMENTATION_TYPE
)
5413 ? "_OBJC_CLASS_METHODS"
5414 : "_OBJC_CATEGORY_CLASS_METHODS"),
5418 UOBJC_CLASS_METHODS_decl
= 0;
5420 chain
= CLASS_NST_METHODS (objc_implementation_context
);
5423 size
= list_length (chain
);
5425 method_list_template
5426 = build_method_list_template (objc_method_template
, size
);
5428 = build_dispatch_table_initializer (objc_method_template
, chain
);
5430 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
5431 UOBJC_INSTANCE_METHODS_decl
5432 = generate_dispatch_table (method_list_template
,
5433 "_OBJC_INSTANCE_METHODS",
5436 /* We have a category. */
5437 UOBJC_INSTANCE_METHODS_decl
5438 = generate_dispatch_table (method_list_template
,
5439 "_OBJC_CATEGORY_INSTANCE_METHODS",
5443 UOBJC_INSTANCE_METHODS_decl
= 0;
5447 generate_protocol_list (tree i_or_p
)
5450 tree refs_decl
, lproto
, e
, plist
;
5452 const char *ref_name
;
5454 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
5455 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
5456 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
5457 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
5458 plist
= PROTOCOL_LIST (i_or_p
);
5463 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
5464 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
5465 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
5468 /* Build initializer. */
5469 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), NULL_TREE
);
5470 e
= build_int_cst (build_pointer_type (objc_protocol_template
), size
);
5471 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
5473 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
5475 tree pval
= TREE_VALUE (lproto
);
5477 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
5478 && PROTOCOL_FORWARD_DECL (pval
))
5480 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
5481 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
5485 /* static struct objc_protocol *refs[n]; */
5487 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
5488 ref_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p
);
5489 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
5490 ref_name
= synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p
);
5491 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
5492 ref_name
= synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p
);
5496 refs_decl
= start_var_decl
5498 (build_pointer_type (objc_protocol_template
),
5499 build_index_type (build_int_cst (NULL_TREE
, size
+ 2))),
5502 finish_var_decl (refs_decl
, objc_build_constructor (TREE_TYPE (refs_decl
),
5503 nreverse (initlist
)));
5509 build_category_initializer (tree type
, tree cat_name
, tree class_name
,
5510 tree instance_methods
, tree class_methods
,
5513 tree initlist
= NULL_TREE
, expr
;
5515 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
5516 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
5518 if (!instance_methods
)
5519 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5522 expr
= convert (objc_method_list_ptr
,
5523 build_unary_op (ADDR_EXPR
, instance_methods
, 0));
5524 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
5527 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5530 expr
= convert (objc_method_list_ptr
,
5531 build_unary_op (ADDR_EXPR
, class_methods
, 0));
5532 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
5535 /* protocol_list = */
5537 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5540 expr
= convert (build_pointer_type
5542 (objc_protocol_template
)),
5543 build_unary_op (ADDR_EXPR
, protocol_list
, 0));
5544 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
5547 return objc_build_constructor (type
, nreverse (initlist
));
5550 /* struct _objc_class {
5551 struct objc_class *isa;
5552 struct objc_class *super_class;
5557 struct objc_ivar_list *ivars;
5558 struct objc_method_list *methods;
5559 if (flag_next_runtime)
5560 struct objc_cache *cache;
5562 struct sarray *dtable;
5563 struct objc_class *subclass_list;
5564 struct objc_class *sibling_class;
5566 struct objc_protocol_list *protocols;
5567 if (flag_next_runtime)
5569 void *gc_object_type;
5573 build_shared_structure_initializer (tree type
, tree isa
, tree super
,
5574 tree name
, tree size
, int status
,
5575 tree dispatch_table
, tree ivar_list
,
5578 tree initlist
= NULL_TREE
, expr
;
5581 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
5584 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
5587 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
5590 initlist
= tree_cons (NULL_TREE
, build_int_cst (long_integer_type_node
, 0),
5594 initlist
= tree_cons (NULL_TREE
,
5595 build_int_cst (long_integer_type_node
, status
),
5598 /* instance_size = */
5599 initlist
= tree_cons (NULL_TREE
, convert (long_integer_type_node
, size
),
5602 /* objc_ivar_list = */
5604 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5607 expr
= convert (objc_ivar_list_ptr
,
5608 build_unary_op (ADDR_EXPR
, ivar_list
, 0));
5609 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
5612 /* objc_method_list = */
5613 if (!dispatch_table
)
5614 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5617 expr
= convert (objc_method_list_ptr
,
5618 build_unary_op (ADDR_EXPR
, dispatch_table
, 0));
5619 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
5622 if (flag_next_runtime
)
5623 /* method_cache = */
5624 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5628 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5630 /* subclass_list = */
5631 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5633 /* sibling_class = */
5634 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5637 /* protocol_list = */
5638 if (! protocol_list
)
5639 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5642 expr
= convert (build_pointer_type
5644 (objc_protocol_template
)),
5645 build_unary_op (ADDR_EXPR
, protocol_list
, 0));
5646 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
5649 if (flag_next_runtime
)
5651 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5653 /* gc_object_type = NULL */
5654 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
5656 return objc_build_constructor (type
, nreverse (initlist
));
5659 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5662 lookup_category (tree
class, tree cat_name
)
5664 tree category
= CLASS_CATEGORY_LIST (class);
5666 while (category
&& CLASS_SUPER_NAME (category
) != cat_name
)
5667 category
= CLASS_CATEGORY_LIST (category
);
5671 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5674 generate_category (tree cat
)
5677 tree initlist
, cat_name_expr
, class_name_expr
;
5678 tree protocol_decl
, category
;
5680 add_class_reference (CLASS_NAME (cat
));
5681 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
5683 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
5685 category
= lookup_category (implementation_template
,
5686 CLASS_SUPER_NAME (cat
));
5688 if (category
&& CLASS_PROTOCOL_LIST (category
))
5690 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
5691 protocol_decl
= generate_protocol_list (category
);
5696 decl
= start_var_decl (objc_category_template
,
5697 synth_id_with_class_suffix
5698 ("_OBJC_CATEGORY", objc_implementation_context
));
5700 initlist
= build_category_initializer (TREE_TYPE (decl
),
5701 cat_name_expr
, class_name_expr
,
5702 UOBJC_INSTANCE_METHODS_decl
,
5703 UOBJC_CLASS_METHODS_decl
,
5706 finish_var_decl (decl
, initlist
);
5709 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5710 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5713 generate_shared_structures (int cls_flags
)
5715 tree sc_spec
, decl_specs
, decl
;
5716 tree name_expr
, super_expr
, root_expr
;
5717 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
5718 tree cast_type
, initlist
, protocol_decl
;
5720 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
5723 add_class_reference (my_super_id
);
5725 /* Compute "my_root_id" - this is required for code generation.
5726 the "isa" for all meta class structures points to the root of
5727 the inheritance hierarchy (e.g. "__Object")... */
5728 my_root_id
= my_super_id
;
5731 tree my_root_int
= lookup_interface (my_root_id
);
5733 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
5734 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
5741 /* No super class. */
5742 my_root_id
= CLASS_NAME (implementation_template
);
5744 cast_type
= build_pointer_type (objc_class_template
);
5745 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
5748 /* Install class `isa' and `super' pointers at runtime. */
5751 super_expr
= add_objc_string (my_super_id
, class_names
);
5752 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
5755 super_expr
= build_int_cst (NULL_TREE
, 0);
5757 root_expr
= add_objc_string (my_root_id
, class_names
);
5758 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
5760 if (CLASS_PROTOCOL_LIST (implementation_template
))
5762 generate_protocol_references
5763 (CLASS_PROTOCOL_LIST (implementation_template
));
5764 protocol_decl
= generate_protocol_list (implementation_template
);
5769 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5771 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
5772 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
5774 decl
= start_var_decl (objc_class_template
,
5776 (DECL_NAME (UOBJC_METACLASS_decl
)));
5779 = build_shared_structure_initializer
5781 root_expr
, super_expr
, name_expr
,
5782 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
5784 UOBJC_CLASS_METHODS_decl
,
5785 UOBJC_CLASS_VARIABLES_decl
,
5788 finish_var_decl (decl
, initlist
);
5790 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5792 decl
= start_var_decl (objc_class_template
,
5794 (DECL_NAME (UOBJC_CLASS_decl
)));
5797 = build_shared_structure_initializer
5799 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
5800 super_expr
, name_expr
,
5801 convert (integer_type_node
,
5802 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5803 (implementation_template
))),
5804 1 /*CLS_FACTORY*/ | cls_flags
,
5805 UOBJC_INSTANCE_METHODS_decl
,
5806 UOBJC_INSTANCE_VARIABLES_decl
,
5809 finish_var_decl (decl
, initlist
);
5814 synth_id_with_class_suffix (const char *preamble
, tree ctxt
)
5816 static char string
[BUFSIZE
];
5818 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
5819 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
5821 sprintf (string
, "%s_%s", preamble
,
5822 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
5824 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
5825 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
5827 /* We have a category. */
5828 const char *const class_name
5829 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
5830 const char *const class_super_name
5831 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
5832 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
5834 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
5836 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
5837 sprintf (string
, "%s_%s", preamble
, protocol_name
);
5845 /* If type is empty or only type qualifiers are present, add default
5846 type of id (otherwise grokdeclarator will default to int). */
5849 adjust_type_for_id_default (tree type
)
5852 type
= make_node (TREE_LIST
);
5854 if (!TREE_VALUE (type
))
5855 TREE_VALUE (type
) = objc_object_type
;
5856 else if (TREE_CODE (TREE_VALUE (type
)) == RECORD_TYPE
5857 && TYPED_OBJECT (TREE_VALUE (type
)))
5858 error ("can not use an object as parameter to a method");
5865 selector ':' '(' typename ')' identifier
5868 Transform an Objective-C keyword argument into
5869 the C equivalent parameter declarator.
5871 In: key_name, an "identifier_node" (optional).
5872 arg_type, a "tree_list" (optional).
5873 arg_name, an "identifier_node".
5875 Note: It would be really nice to strongly type the preceding
5876 arguments in the function prototype; however, then I
5877 could not use the "accessor" macros defined in "tree.h".
5879 Out: an instance of "keyword_decl". */
5882 objc_build_keyword_decl (tree key_name
, tree arg_type
, tree arg_name
)
5886 /* If no type is specified, default to "id". */
5887 arg_type
= adjust_type_for_id_default (arg_type
);
5889 keyword_decl
= make_node (KEYWORD_DECL
);
5891 TREE_TYPE (keyword_decl
) = arg_type
;
5892 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
5893 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
5895 return keyword_decl
;
5898 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5901 build_keyword_selector (tree selector
)
5904 tree key_chain
, key_name
;
5907 /* Scan the selector to see how much space we'll need. */
5908 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
5910 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5911 key_name
= KEYWORD_KEY_NAME (key_chain
);
5912 else if (TREE_CODE (selector
) == TREE_LIST
)
5913 key_name
= TREE_PURPOSE (key_chain
);
5918 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
5920 /* Just a ':' arg. */
5924 buf
= (char *) alloca (len
+ 1);
5925 /* Start the buffer out as an empty string. */
5928 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
5930 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5931 key_name
= KEYWORD_KEY_NAME (key_chain
);
5932 else if (TREE_CODE (selector
) == TREE_LIST
)
5934 key_name
= TREE_PURPOSE (key_chain
);
5935 /* The keyword decl chain will later be used as a function argument
5936 chain. Unhook the selector itself so as to not confuse other
5937 parts of the compiler. */
5938 TREE_PURPOSE (key_chain
) = NULL_TREE
;
5944 strcat (buf
, IDENTIFIER_POINTER (key_name
));
5948 return get_identifier (buf
);
5951 /* Used for declarations and definitions. */
5954 build_method_decl (enum tree_code code
, tree ret_type
, tree selector
,
5955 tree add_args
, bool ellipsis
)
5959 /* If no type is specified, default to "id". */
5960 ret_type
= adjust_type_for_id_default (ret_type
);
5962 method_decl
= make_node (code
);
5963 TREE_TYPE (method_decl
) = ret_type
;
5965 /* If we have a keyword selector, create an identifier_node that
5966 represents the full selector name (`:' included)... */
5967 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5969 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
5970 METHOD_SEL_ARGS (method_decl
) = selector
;
5971 METHOD_ADD_ARGS (method_decl
) = add_args
;
5972 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl
) = ellipsis
;
5976 METHOD_SEL_NAME (method_decl
) = selector
;
5977 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
5978 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
5984 #define METHOD_DEF 0
5985 #define METHOD_REF 1
5987 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5988 an argument list for method METH. CONTEXT is either METHOD_DEF or
5989 METHOD_REF, saying whether we are trying to define a method or call
5990 one. SUPERFLAG says this is for a send to super; this makes a
5991 difference for the NeXT calling sequence in which the lookup and
5992 the method call are done together. If METH is null, user-defined
5993 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5996 get_arg_type_list (tree meth
, int context
, int superflag
)
6000 /* Receiver type. */
6001 if (flag_next_runtime
&& superflag
)
6002 arglist
= build_tree_list (NULL_TREE
, objc_super_type
);
6003 else if (context
== METHOD_DEF
&& TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
6004 arglist
= build_tree_list (NULL_TREE
, objc_instance_type
);
6006 arglist
= build_tree_list (NULL_TREE
, objc_object_type
);
6008 /* Selector type - will eventually change to `int'. */
6009 chainon (arglist
, build_tree_list (NULL_TREE
, objc_selector_type
));
6011 /* No actual method prototype given -- assume that remaining arguments
6016 /* Build a list of argument types. */
6017 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
6019 tree arg_type
= TREE_VALUE (TREE_TYPE (akey
));
6021 /* Decay arrays and functions into pointers. */
6022 if (TREE_CODE (arg_type
) == ARRAY_TYPE
)
6023 arg_type
= build_pointer_type (TREE_TYPE (arg_type
));
6024 else if (TREE_CODE (arg_type
) == FUNCTION_TYPE
)
6025 arg_type
= build_pointer_type (arg_type
);
6027 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
6030 if (METHOD_ADD_ARGS (meth
))
6032 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
6033 akey
; akey
= TREE_CHAIN (akey
))
6035 tree arg_type
= TREE_TYPE (TREE_VALUE (akey
));
6037 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
6040 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth
))
6041 goto lack_of_ellipsis
;
6046 chainon (arglist
, OBJC_VOID_AT_END
);
6053 check_duplicates (hash hsh
, int methods
, int is_class
)
6055 tree meth
= NULL_TREE
;
6063 /* We have two or more methods with the same name but
6067 /* But just how different are those types? If
6068 -Wno-strict-selector-match is specified, we shall not
6069 complain if the differences are solely among types with
6070 identical size and alignment. */
6071 if (!warn_strict_selector_match
)
6073 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
6074 if (!comp_proto_with_proto (meth
, loop
->value
, 0))
6081 warning (0, "multiple %s named %<%c%s%> found",
6082 methods
? "methods" : "selectors",
6083 (is_class
? '+' : '-'),
6084 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
6086 warn_with_method (methods
? "using" : "found",
6087 ((TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
6091 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
6092 warn_with_method ("also found",
6093 ((TREE_CODE (loop
->value
) == INSTANCE_METHOD_DECL
)
6102 /* If RECEIVER is a class reference, return the identifier node for
6103 the referenced class. RECEIVER is created by objc_get_class_reference,
6104 so we check the exact form created depending on which runtimes are
6108 receiver_is_class_object (tree receiver
, int self
, int super
)
6110 tree chain
, exp
, arg
;
6112 /* The receiver is 'self' or 'super' in the context of a class method. */
6113 if (objc_method_context
6114 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
6117 ? CLASS_SUPER_NAME (implementation_template
)
6118 : CLASS_NAME (implementation_template
));
6120 if (flag_next_runtime
)
6122 /* The receiver is a variable created by
6123 build_class_reference_decl. */
6124 if (TREE_CODE (receiver
) == VAR_DECL
&& IS_CLASS (TREE_TYPE (receiver
)))
6125 /* Look up the identifier. */
6126 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
6127 if (TREE_PURPOSE (chain
) == receiver
)
6128 return TREE_VALUE (chain
);
6131 /* The receiver is a function call that returns an id. Check if
6132 it is a call to objc_getClass, if so, pick up the class name. */
6133 if (TREE_CODE (receiver
) == CALL_EXPR
6134 && (exp
= CALL_EXPR_FN (receiver
))
6135 && TREE_CODE (exp
) == ADDR_EXPR
6136 && (exp
= TREE_OPERAND (exp
, 0))
6137 && TREE_CODE (exp
) == FUNCTION_DECL
6138 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6139 prototypes for objc_get_class(). Thankfully, they seem to share the
6140 same function type. */
6141 && TREE_TYPE (exp
) == TREE_TYPE (objc_get_class_decl
)
6142 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp
)), TAG_GETCLASS
)
6143 /* We have a call to objc_get_class/objc_getClass! */
6144 && (arg
= CALL_EXPR_ARG (receiver
, 0)))
6147 if (TREE_CODE (arg
) == ADDR_EXPR
6148 && (arg
= TREE_OPERAND (arg
, 0))
6149 && TREE_CODE (arg
) == STRING_CST
)
6150 /* Finally, we have the class name. */
6151 return get_identifier (TREE_STRING_POINTER (arg
));
6156 /* If we are currently building a message expr, this holds
6157 the identifier of the selector of the message. This is
6158 used when printing warnings about argument mismatches. */
6160 static tree current_objc_message_selector
= 0;
6163 objc_message_selector (void)
6165 return current_objc_message_selector
;
6168 /* Construct an expression for sending a message.
6169 MESS has the object to send to in TREE_PURPOSE
6170 and the argument list (including selector) in TREE_VALUE.
6172 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6173 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6176 objc_build_message_expr (tree mess
)
6178 tree receiver
= TREE_PURPOSE (mess
);
6181 tree args
= TREE_PURPOSE (TREE_VALUE (mess
));
6183 tree args
= TREE_VALUE (mess
);
6185 tree method_params
= NULL_TREE
;
6187 if (TREE_CODE (receiver
) == ERROR_MARK
)
6188 return error_mark_node
;
6190 /* Obtain the full selector name. */
6191 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
6192 /* A unary selector. */
6194 else if (TREE_CODE (args
) == TREE_LIST
)
6195 sel_name
= build_keyword_selector (args
);
6199 /* Build the parameter list to give to the method. */
6200 if (TREE_CODE (args
) == TREE_LIST
)
6202 method_params
= chainon (args
, TREE_VALUE (TREE_VALUE (mess
)));
6205 tree chain
= args
, prev
= NULL_TREE
;
6207 /* We have a keyword selector--check for comma expressions. */
6210 tree element
= TREE_VALUE (chain
);
6212 /* We have a comma expression, must collapse... */
6213 if (TREE_CODE (element
) == TREE_LIST
)
6216 TREE_CHAIN (prev
) = element
;
6221 chain
= TREE_CHAIN (chain
);
6223 method_params
= args
;
6228 if (processing_template_decl
)
6229 /* Must wait until template instantiation time. */
6230 return build_min_nt (MESSAGE_SEND_EXPR
, receiver
, sel_name
,
6234 return objc_finish_message_expr (receiver
, sel_name
, method_params
);
6237 /* Look up method SEL_NAME that would be suitable for receiver
6238 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6239 nonzero), and report on any duplicates. */
6242 lookup_method_in_hash_lists (tree sel_name
, int is_class
)
6244 hash method_prototype
= NULL
;
6247 method_prototype
= hash_lookup (nst_method_hash_list
,
6250 if (!method_prototype
)
6252 method_prototype
= hash_lookup (cls_method_hash_list
,
6257 return check_duplicates (method_prototype
, 1, is_class
);
6260 /* The 'objc_finish_message_expr' routine is called from within
6261 'objc_build_message_expr' for non-template functions. In the case of
6262 C++ template functions, it is called from 'build_expr_from_tree'
6263 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6266 objc_finish_message_expr (tree receiver
, tree sel_name
, tree method_params
)
6268 tree method_prototype
= NULL_TREE
, rprotos
= NULL_TREE
, rtype
;
6269 tree selector
, retval
, class_tree
;
6270 int self
, super
, have_cast
;
6272 /* Extract the receiver of the message, as well as its type
6273 (where the latter may take the form of a cast or be inferred
6274 from the implementation context). */
6276 while (TREE_CODE (rtype
) == COMPOUND_EXPR
6277 || TREE_CODE (rtype
) == MODIFY_EXPR
6278 || TREE_CODE (rtype
) == NOP_EXPR
6279 || TREE_CODE (rtype
) == CONVERT_EXPR
6280 || TREE_CODE (rtype
) == COMPONENT_REF
)
6281 rtype
= TREE_OPERAND (rtype
, 0);
6282 self
= (rtype
== self_decl
);
6283 super
= (rtype
== UOBJC_SUPER_decl
);
6284 rtype
= TREE_TYPE (receiver
);
6285 have_cast
= (TREE_CODE (receiver
) == NOP_EXPR
6286 || (TREE_CODE (receiver
) == COMPOUND_EXPR
6287 && !IS_SUPER (rtype
)));
6289 /* If we are calling [super dealloc], reset our warning flag. */
6290 if (super
&& !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name
)))
6291 should_call_super_dealloc
= 0;
6293 /* If the receiver is a class object, retrieve the corresponding
6294 @interface, if one exists. */
6295 class_tree
= receiver_is_class_object (receiver
, self
, super
);
6297 /* Now determine the receiver type (if an explicit cast has not been
6302 rtype
= lookup_interface (class_tree
);
6303 /* Handle `self' and `super'. */
6306 if (!CLASS_SUPER_NAME (implementation_template
))
6308 error ("no super class declared in @interface for %qs",
6309 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
6310 return error_mark_node
;
6312 rtype
= lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6315 rtype
= lookup_interface (CLASS_NAME (implementation_template
));
6318 /* If receiver is of type `id' or `Class' (or if the @interface for a
6319 class is not visible), we shall be satisfied with the existence of
6320 any instance or class method. */
6321 if (objc_is_id (rtype
))
6323 class_tree
= (IS_CLASS (rtype
) ? objc_class_name
: NULL_TREE
);
6324 rprotos
= (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype
))
6325 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype
))
6331 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6332 in protocols themselves for the method prototype. */
6334 = lookup_method_in_protocol_list (rprotos
, sel_name
,
6335 class_tree
!= NULL_TREE
);
6337 /* If messaging 'Class <Proto>' but did not find a class method
6338 prototype, search for an instance method instead, and warn
6339 about having done so. */
6340 if (!method_prototype
&& !rtype
&& class_tree
!= NULL_TREE
)
6343 = lookup_method_in_protocol_list (rprotos
, sel_name
, 0);
6345 if (method_prototype
)
6346 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6347 IDENTIFIER_POINTER (sel_name
),
6348 IDENTIFIER_POINTER (sel_name
));
6354 tree orig_rtype
= rtype
, saved_rtype
;
6356 if (TREE_CODE (rtype
) == POINTER_TYPE
)
6357 rtype
= TREE_TYPE (rtype
);
6358 /* Traverse typedef aliases */
6359 while (TREE_CODE (rtype
) == RECORD_TYPE
&& OBJC_TYPE_NAME (rtype
)
6360 && TREE_CODE (OBJC_TYPE_NAME (rtype
)) == TYPE_DECL
6361 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
)))
6362 rtype
= DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
));
6363 saved_rtype
= rtype
;
6364 if (TYPED_OBJECT (rtype
))
6366 rprotos
= TYPE_OBJC_PROTOCOL_LIST (rtype
);
6367 rtype
= TYPE_OBJC_INTERFACE (rtype
);
6369 /* If we could not find an @interface declaration, we must have
6370 only seen a @class declaration; so, we cannot say anything
6371 more intelligent about which methods the receiver will
6373 if (!rtype
|| TREE_CODE (rtype
) == IDENTIFIER_NODE
)
6375 else if (TREE_CODE (rtype
) == CLASS_INTERFACE_TYPE
6376 || TREE_CODE (rtype
) == CLASS_IMPLEMENTATION_TYPE
)
6378 /* We have a valid ObjC class name. Look up the method name
6379 in the published @interface for the class (and its
6382 = lookup_method_static (rtype
, sel_name
, class_tree
!= NULL_TREE
);
6384 /* If the method was not found in the @interface, it may still
6385 exist locally as part of the @implementation. */
6386 if (!method_prototype
&& objc_implementation_context
6387 && CLASS_NAME (objc_implementation_context
)
6388 == OBJC_TYPE_NAME (rtype
))
6392 ? CLASS_CLS_METHODS (objc_implementation_context
)
6393 : CLASS_NST_METHODS (objc_implementation_context
)),
6396 /* If we haven't found a candidate method by now, try looking for
6397 it in the protocol list. */
6398 if (!method_prototype
&& rprotos
)
6400 = lookup_method_in_protocol_list (rprotos
, sel_name
,
6401 class_tree
!= NULL_TREE
);
6405 warning (0, "invalid receiver type %qs",
6406 gen_type_name (orig_rtype
));
6407 /* After issuing the "invalid receiver" warning, perform method
6408 lookup as if we were messaging 'id'. */
6409 rtype
= rprotos
= NULL_TREE
;
6414 /* For 'id' or 'Class' receivers, search in the global hash table
6415 as a last resort. For all receivers, warn if protocol searches
6417 if (!method_prototype
)
6420 warning (0, "%<%c%s%> not found in protocol(s)",
6421 (class_tree
? '+' : '-'),
6422 IDENTIFIER_POINTER (sel_name
));
6426 = lookup_method_in_hash_lists (sel_name
, class_tree
!= NULL_TREE
);
6429 if (!method_prototype
)
6431 static bool warn_missing_methods
= false;
6434 warning (0, "%qs may not respond to %<%c%s%>",
6435 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype
)),
6436 (class_tree
? '+' : '-'),
6437 IDENTIFIER_POINTER (sel_name
));
6438 /* If we are messaging an 'id' or 'Class' object and made it here,
6439 then we have failed to find _any_ instance or class method,
6442 warning (0, "no %<%c%s%> method found",
6443 (class_tree
? '+' : '-'),
6444 IDENTIFIER_POINTER (sel_name
));
6446 if (!warn_missing_methods
)
6448 warning (0, "(Messages without a matching method signature");
6449 warning (0, "will be assumed to return %<id%> and accept");
6450 warning (0, "%<...%> as arguments.)");
6451 warn_missing_methods
= true;
6455 /* Save the selector name for printing error messages. */
6456 current_objc_message_selector
= sel_name
;
6458 /* Build the parameters list for looking up the method.
6459 These are the object itself and the selector. */
6461 if (flag_typed_selectors
)
6462 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
6464 selector
= build_selector_reference (sel_name
);
6466 retval
= build_objc_method_call (super
, method_prototype
,
6468 selector
, method_params
);
6470 current_objc_message_selector
= 0;
6475 /* Build a tree expression to send OBJECT the operation SELECTOR,
6476 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6477 assuming the method has prototype METHOD_PROTOTYPE.
6478 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6479 Use METHOD_PARAMS as list of args to pass to the method.
6480 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6483 build_objc_method_call (int super_flag
, tree method_prototype
,
6484 tree lookup_object
, tree selector
,
6487 tree sender
= (super_flag
? umsg_super_decl
:
6488 (!flag_next_runtime
|| flag_nil_receivers
6489 ? (flag_objc_direct_dispatch
6492 : umsg_nonnil_decl
));
6493 tree rcv_p
= (super_flag
? objc_super_type
: objc_object_type
);
6495 /* If a prototype for the method to be called exists, then cast
6496 the sender's return type and arguments to match that of the method.
6497 Otherwise, leave sender as is. */
6500 ? TREE_VALUE (TREE_TYPE (method_prototype
))
6501 : objc_object_type
);
6503 = build_pointer_type
6504 (build_function_type
6507 (method_prototype
, METHOD_REF
, super_flag
)));
6510 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
6512 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6513 lookup_object
= save_expr (lookup_object
);
6515 if (flag_next_runtime
)
6517 /* If we are returning a struct in memory, and the address
6518 of that memory location is passed as a hidden first
6519 argument, then change which messenger entry point this
6520 expr will call. NB: Note that sender_cast remains
6521 unchanged (it already has a struct return type). */
6522 if (!targetm
.calls
.struct_value_rtx (0, 0)
6523 && (TREE_CODE (ret_type
) == RECORD_TYPE
6524 || TREE_CODE (ret_type
) == UNION_TYPE
)
6525 && targetm
.calls
.return_in_memory (ret_type
, 0))
6526 sender
= (super_flag
? umsg_super_stret_decl
:
6527 flag_nil_receivers
? umsg_stret_decl
: umsg_nonnil_stret_decl
);
6529 method_params
= tree_cons (NULL_TREE
, lookup_object
,
6530 tree_cons (NULL_TREE
, selector
,
6532 method
= build_fold_addr_expr (sender
);
6536 /* This is the portable (GNU) way. */
6539 /* First, call the lookup function to get a pointer to the method,
6540 then cast the pointer, then call it with the method arguments. */
6542 object
= (super_flag
? self_decl
: lookup_object
);
6544 t
= tree_cons (NULL_TREE
, selector
, NULL_TREE
);
6545 t
= tree_cons (NULL_TREE
, lookup_object
, t
);
6546 method
= build_function_call (sender
, t
);
6548 /* Pass the object to the method. */
6549 method_params
= tree_cons (NULL_TREE
, object
,
6550 tree_cons (NULL_TREE
, selector
,
6554 /* ??? Selector is not at this point something we can use inside
6555 the compiler itself. Set it to garbage for the nonce. */
6556 t
= build3 (OBJ_TYPE_REF
, sender_cast
, method
, lookup_object
, size_zero_node
);
6557 return build_function_call (t
, method_params
);
6561 build_protocol_reference (tree p
)
6564 const char *proto_name
;
6566 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6568 proto_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
6569 decl
= start_var_decl (objc_protocol_template
, proto_name
);
6571 PROTOCOL_FORWARD_DECL (p
) = decl
;
6574 /* This function is called by the parser when (and only when) a
6575 @protocol() expression is found, in order to compile it. */
6577 objc_build_protocol_expr (tree protoname
)
6580 tree p
= lookup_protocol (protoname
);
6584 error ("cannot find protocol declaration for %qs",
6585 IDENTIFIER_POINTER (protoname
));
6586 return error_mark_node
;
6589 if (!PROTOCOL_FORWARD_DECL (p
))
6590 build_protocol_reference (p
);
6592 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
6594 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6595 if we have it, rather than converting it here. */
6596 expr
= convert (objc_protocol_type
, expr
);
6598 /* The @protocol() expression is being compiled into a pointer to a
6599 statically allocated instance of the Protocol class. To become
6600 usable at runtime, the 'isa' pointer of the instance need to be
6601 fixed up at runtime by the runtime library, to point to the
6602 actual 'Protocol' class. */
6604 /* For the GNU runtime, put the static Protocol instance in the list
6605 of statically allocated instances, so that we make sure that its
6606 'isa' pointer is fixed up at runtime by the GNU runtime library
6607 to point to the Protocol class (at runtime, when loading the
6608 module, the GNU runtime library loops on the statically allocated
6609 instances (as found in the defs field in objc_symtab) and fixups
6610 all the 'isa' pointers of those objects). */
6611 if (! flag_next_runtime
)
6613 /* This type is a struct containing the fields of a Protocol
6614 object. (Cfr. objc_protocol_type instead is the type of a pointer
6615 to such a struct). */
6616 tree protocol_struct_type
= xref_tag
6617 (RECORD_TYPE
, get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
6620 /* Look for the list of Protocol statically allocated instances
6621 to fixup at runtime. Create a new list to hold Protocol
6622 statically allocated instances, if the list is not found. At
6623 present there is only another list, holding NSConstantString
6624 static instances to be fixed up at runtime. */
6625 for (chain
= &objc_static_instances
;
6626 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
6627 chain
= &TREE_CHAIN (*chain
));
6630 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
6631 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type
),
6635 /* Add this statically allocated instance to the Protocol list. */
6636 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
6637 PROTOCOL_FORWARD_DECL (p
),
6638 TREE_PURPOSE (*chain
));
6645 /* This function is called by the parser when a @selector() expression
6646 is found, in order to compile it. It is only called by the parser
6647 and only to compile a @selector(). */
6649 objc_build_selector_expr (tree selnamelist
)
6653 /* Obtain the full selector name. */
6654 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
6655 /* A unary selector. */
6656 selname
= selnamelist
;
6657 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
6658 selname
= build_keyword_selector (selnamelist
);
6662 /* If we are required to check @selector() expressions as they
6663 are found, check that the selector has been declared. */
6664 if (warn_undeclared_selector
)
6666 /* Look the selector up in the list of all known class and
6667 instance methods (up to this line) to check that the selector
6671 /* First try with instance methods. */
6672 hsh
= hash_lookup (nst_method_hash_list
, selname
);
6674 /* If not found, try with class methods. */
6677 hsh
= hash_lookup (cls_method_hash_list
, selname
);
6680 /* If still not found, print out a warning. */
6683 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname
));
6688 if (flag_typed_selectors
)
6689 return build_typed_selector_reference (selname
, 0);
6691 return build_selector_reference (selname
);
6695 objc_build_encode_expr (tree type
)
6700 encode_type (type
, obstack_object_size (&util_obstack
),
6701 OBJC_ENCODE_INLINE_DEFS
);
6702 obstack_1grow (&util_obstack
, 0); /* null terminate string */
6703 string
= obstack_finish (&util_obstack
);
6705 /* Synthesize a string that represents the encoded struct/union. */
6706 result
= my_build_string (strlen (string
) + 1, string
);
6707 obstack_free (&util_obstack
, util_firstobj
);
6712 build_ivar_reference (tree id
)
6714 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
6716 /* Historically, a class method that produced objects (factory
6717 method) would assign `self' to the instance that it
6718 allocated. This would effectively turn the class method into
6719 an instance method. Following this assignment, the instance
6720 variables could be accessed. That practice, while safe,
6721 violates the simple rule that a class method should not refer
6722 to an instance variable. It's better to catch the cases
6723 where this is done unknowingly than to support the above
6725 warning (0, "instance variable %qs accessed in class method",
6726 IDENTIFIER_POINTER (id
));
6727 self_decl
= convert (objc_instance_type
, self_decl
); /* cast */
6730 return objc_build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
6733 /* Compute a hash value for a given method SEL_NAME. */
6736 hash_func (tree sel_name
)
6738 const unsigned char *s
6739 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
6743 h
= h
* 67 + *s
++ - 113;
6750 nst_method_hash_list
6751 = (hash
*) ggc_alloc_cleared (SIZEHASHTABLE
* sizeof (hash
));
6752 cls_method_hash_list
6753 = (hash
*) ggc_alloc_cleared (SIZEHASHTABLE
* sizeof (hash
));
6755 /* Initialize the hash table used to hold the constant string objects. */
6756 string_htab
= htab_create_ggc (31, string_hash
,
6759 /* Initialize the hash table used to hold EH-volatilized types. */
6760 volatilized_htab
= htab_create_ggc (31, volatilized_hash
,
6761 volatilized_eq
, NULL
);
6764 /* WARNING!!!! hash_enter is called with a method, and will peek
6765 inside to find its selector! But hash_lookup is given a selector
6766 directly, and looks for the selector that's inside the found
6767 entry's key (method) for comparison. */
6770 hash_enter (hash
*hashlist
, tree method
)
6773 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
6775 obj
= (hash
) ggc_alloc (sizeof (struct hashed_entry
));
6777 obj
->next
= hashlist
[slot
];
6780 hashlist
[slot
] = obj
; /* append to front */
6784 hash_lookup (hash
*hashlist
, tree sel_name
)
6788 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
6792 if (sel_name
== METHOD_SEL_NAME (target
->key
))
6795 target
= target
->next
;
6801 hash_add_attr (hash entry
, tree value
)
6805 obj
= (attr
) ggc_alloc (sizeof (struct hashed_attribute
));
6806 obj
->next
= entry
->list
;
6809 entry
->list
= obj
; /* append to front */
6813 lookup_method (tree mchain
, tree method
)
6817 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
6820 key
= METHOD_SEL_NAME (method
);
6824 if (METHOD_SEL_NAME (mchain
) == key
)
6827 mchain
= TREE_CHAIN (mchain
);
6832 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6833 in INTERFACE, along with any categories and protocols attached thereto.
6834 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6835 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6836 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6837 be found in INTERFACE or any of its superclasses, look for an _instance_
6838 method of the same name in the root class as a last resort.
6840 If a suitable method cannot be found, return NULL_TREE. */
6843 lookup_method_static (tree interface
, tree ident
, int flags
)
6845 tree meth
= NULL_TREE
, root_inter
= NULL_TREE
;
6846 tree inter
= interface
;
6847 int is_class
= (flags
& OBJC_LOOKUP_CLASS
);
6848 int no_superclasses
= (flags
& OBJC_LOOKUP_NO_SUPER
);
6852 tree chain
= is_class
? CLASS_CLS_METHODS (inter
) : CLASS_NST_METHODS (inter
);
6853 tree category
= inter
;
6855 /* First, look up the method in the class itself. */
6856 if ((meth
= lookup_method (chain
, ident
)))
6859 /* Failing that, look for the method in each category of the class. */
6860 while ((category
= CLASS_CATEGORY_LIST (category
)))
6862 chain
= is_class
? CLASS_CLS_METHODS (category
) : CLASS_NST_METHODS (category
);
6864 /* Check directly in each category. */
6865 if ((meth
= lookup_method (chain
, ident
)))
6868 /* Failing that, check in each category's protocols. */
6869 if (CLASS_PROTOCOL_LIST (category
))
6871 if ((meth
= (lookup_method_in_protocol_list
6872 (CLASS_PROTOCOL_LIST (category
), ident
, is_class
))))
6877 /* If not found in categories, check in protocols of the main class. */
6878 if (CLASS_PROTOCOL_LIST (inter
))
6880 if ((meth
= (lookup_method_in_protocol_list
6881 (CLASS_PROTOCOL_LIST (inter
), ident
, is_class
))))
6885 /* If we were instructed not to look in superclasses, don't. */
6886 if (no_superclasses
)
6889 /* Failing that, climb up the inheritance hierarchy. */
6891 inter
= lookup_interface (CLASS_SUPER_NAME (inter
));
6895 /* If no class (factory) method was found, check if an _instance_
6896 method of the same name exists in the root class. This is what
6897 the Objective-C runtime will do. If an instance method was not
6899 return is_class
? lookup_method_static (root_inter
, ident
, 0): NULL_TREE
;
6902 /* Add the method to the hash list if it doesn't contain an identical
6906 add_method_to_hash_list (hash
*hash_list
, tree method
)
6910 if (!(hsh
= hash_lookup (hash_list
, METHOD_SEL_NAME (method
))))
6912 /* Install on a global chain. */
6913 hash_enter (hash_list
, method
);
6917 /* Check types against those; if different, add to a list. */
6919 int already_there
= comp_proto_with_proto (method
, hsh
->key
, 1);
6920 for (loop
= hsh
->list
; !already_there
&& loop
; loop
= loop
->next
)
6921 already_there
|= comp_proto_with_proto (method
, loop
->value
, 1);
6923 hash_add_attr (hsh
, method
);
6928 objc_add_method (tree
class, tree method
, int is_class
)
6932 if (!(mth
= lookup_method (is_class
6933 ? CLASS_CLS_METHODS (class)
6934 : CLASS_NST_METHODS (class), method
)))
6936 /* put method on list in reverse order */
6939 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
6940 CLASS_CLS_METHODS (class) = method
;
6944 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
6945 CLASS_NST_METHODS (class) = method
;
6950 /* When processing an @interface for a class or category, give hard
6951 errors on methods with identical selectors but differing argument
6952 and/or return types. We do not do this for @implementations, because
6953 C/C++ will do it for us (i.e., there will be duplicate function
6954 definition errors). */
6955 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6956 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
)
6957 && !comp_proto_with_proto (method
, mth
, 1))
6958 error ("duplicate declaration of method %<%c%s%>",
6959 is_class
? '+' : '-',
6960 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
6964 add_method_to_hash_list (cls_method_hash_list
, method
);
6967 add_method_to_hash_list (nst_method_hash_list
, method
);
6969 /* Instance methods in root classes (and categories thereof)
6970 may act as class methods as a last resort. We also add
6971 instance methods listed in @protocol declarations to
6972 the class hash table, on the assumption that @protocols
6973 may be adopted by root classes or categories. */
6974 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6975 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6976 class = lookup_interface (CLASS_NAME (class));
6978 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6979 || !CLASS_SUPER_NAME (class))
6980 add_method_to_hash_list (cls_method_hash_list
, method
);
6987 add_class (tree class_name
, tree name
)
6989 struct interface_tuple
**slot
;
6991 /* Put interfaces on list in reverse order. */
6992 TREE_CHAIN (class_name
) = interface_chain
;
6993 interface_chain
= class_name
;
6995 if (interface_htab
== NULL
)
6996 interface_htab
= htab_create_ggc (31, hash_interface
, eq_interface
, NULL
);
6997 slot
= (struct interface_tuple
**)
6998 htab_find_slot_with_hash (interface_htab
, name
,
6999 IDENTIFIER_HASH_VALUE (name
),
7003 *slot
= (struct interface_tuple
*) ggc_alloc_cleared (sizeof (struct interface_tuple
));
7006 (*slot
)->class_name
= class_name
;
7008 return interface_chain
;
7012 add_category (tree
class, tree category
)
7014 /* Put categories on list in reverse order. */
7015 tree cat
= lookup_category (class, CLASS_SUPER_NAME (category
));
7019 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7020 IDENTIFIER_POINTER (CLASS_NAME (class)),
7021 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
7025 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
7026 CLASS_CATEGORY_LIST (class) = category
;
7030 /* Called after parsing each instance variable declaration. Necessary to
7031 preserve typedefs and implement public/private...
7033 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
7036 add_instance_variable (tree
class, int public, tree field_decl
)
7038 tree field_type
= TREE_TYPE (field_decl
);
7039 const char *ivar_name
= DECL_NAME (field_decl
)
7040 ? IDENTIFIER_POINTER (DECL_NAME (field_decl
))
7044 if (TREE_CODE (field_type
) == REFERENCE_TYPE
)
7046 error ("illegal reference type specified for instance variable %qs",
7048 /* Return class as is without adding this ivar. */
7053 if (field_type
== error_mark_node
|| !TYPE_SIZE (field_type
)
7054 || TYPE_SIZE (field_type
) == error_mark_node
)
7055 /* 'type[0]' is allowed, but 'type[]' is not! */
7057 error ("instance variable %qs has unknown size", ivar_name
);
7058 /* Return class as is without adding this ivar. */
7063 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7064 need to either (1) warn the user about it or (2) generate suitable
7065 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7066 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7067 if (IS_AGGR_TYPE (field_type
)
7068 && (TYPE_NEEDS_CONSTRUCTING (field_type
)
7069 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
)
7070 || TYPE_POLYMORPHIC_P (field_type
)))
7072 const char *type_name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type
));
7074 if (flag_objc_call_cxx_cdtors
)
7076 /* Since the ObjC runtime will be calling the constructors and
7077 destructors for us, the only thing we can't handle is the lack
7078 of a default constructor. */
7079 if (TYPE_NEEDS_CONSTRUCTING (field_type
)
7080 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type
))
7082 warning (0, "type %qs has no default constructor to call",
7085 /* If we cannot call a constructor, we should also avoid
7086 calling the destructor, for symmetry. */
7087 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
7088 warning (0, "destructor for %qs shall not be run either",
7094 static bool warn_cxx_ivars
= false;
7096 if (TYPE_POLYMORPHIC_P (field_type
))
7098 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7100 error ("type %qs has virtual member functions", type_name
);
7101 error ("illegal aggregate type %qs specified "
7102 "for instance variable %qs",
7103 type_name
, ivar_name
);
7104 /* Return class as is without adding this ivar. */
7108 /* User-defined constructors and destructors are not known to Obj-C
7109 and hence will not be called. This may or may not be a problem. */
7110 if (TYPE_NEEDS_CONSTRUCTING (field_type
))
7111 warning (0, "type %qs has a user-defined constructor", type_name
);
7112 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
7113 warning (0, "type %qs has a user-defined destructor", type_name
);
7115 if (!warn_cxx_ivars
)
7117 warning (0, "C++ constructors and destructors will not "
7118 "be invoked for Objective-C fields");
7119 warn_cxx_ivars
= true;
7125 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7129 TREE_PUBLIC (field_decl
) = 0;
7130 TREE_PRIVATE (field_decl
) = 0;
7131 TREE_PROTECTED (field_decl
) = 1;
7135 TREE_PUBLIC (field_decl
) = 1;
7136 TREE_PRIVATE (field_decl
) = 0;
7137 TREE_PROTECTED (field_decl
) = 0;
7141 TREE_PUBLIC (field_decl
) = 0;
7142 TREE_PRIVATE (field_decl
) = 1;
7143 TREE_PROTECTED (field_decl
) = 0;
7148 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl
);
7154 is_ivar (tree decl_chain
, tree ident
)
7156 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
7157 if (DECL_NAME (decl_chain
) == ident
)
7162 /* True if the ivar is private and we are not in its implementation. */
7165 is_private (tree decl
)
7167 return (TREE_PRIVATE (decl
)
7168 && ! is_ivar (CLASS_IVARS (implementation_template
),
7172 /* We have an instance variable reference;, check to see if it is public. */
7175 objc_is_public (tree expr
, tree identifier
)
7177 tree basetype
, decl
;
7180 if (processing_template_decl
)
7184 if (TREE_TYPE (expr
) == error_mark_node
)
7187 basetype
= TYPE_MAIN_VARIANT (TREE_TYPE (expr
));
7189 if (basetype
&& TREE_CODE (basetype
) == RECORD_TYPE
)
7191 if (TYPE_HAS_OBJC_INFO (basetype
) && TYPE_OBJC_INTERFACE (basetype
))
7193 tree
class = lookup_interface (OBJC_TYPE_NAME (basetype
));
7197 error ("cannot find interface declaration for %qs",
7198 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype
)));
7202 if ((decl
= is_ivar (get_class_ivars (class, true), identifier
)))
7204 if (TREE_PUBLIC (decl
))
7207 /* Important difference between the Stepstone translator:
7208 all instance variables should be public within the context
7209 of the implementation. */
7210 if (objc_implementation_context
7211 && ((TREE_CODE (objc_implementation_context
)
7212 == CLASS_IMPLEMENTATION_TYPE
)
7213 || (TREE_CODE (objc_implementation_context
)
7214 == CATEGORY_IMPLEMENTATION_TYPE
)))
7216 tree curtype
= TYPE_MAIN_VARIANT
7217 (CLASS_STATIC_TEMPLATE
7218 (implementation_template
));
7220 if (basetype
== curtype
7221 || DERIVED_FROM_P (basetype
, curtype
))
7223 int private = is_private (decl
);
7226 error ("instance variable %qs is declared private",
7227 IDENTIFIER_POINTER (DECL_NAME (decl
)));
7233 /* The 2.95.2 compiler sometimes allowed C functions to access
7234 non-@public ivars. We will let this slide for now... */
7235 if (!objc_method_context
)
7237 warning (0, "instance variable %qs is %s; "
7238 "this will be a hard error in the future",
7239 IDENTIFIER_POINTER (identifier
),
7240 TREE_PRIVATE (decl
) ? "@private" : "@protected");
7244 error ("instance variable %qs is declared %s",
7245 IDENTIFIER_POINTER (identifier
),
7246 TREE_PRIVATE (decl
) ? "private" : "protected");
7255 /* Make sure all entries in CHAIN are also in LIST. */
7258 check_methods (tree chain
, tree list
, int mtype
)
7264 if (!lookup_method (list
, chain
))
7268 if (TREE_CODE (objc_implementation_context
)
7269 == CLASS_IMPLEMENTATION_TYPE
)
7270 warning (0, "incomplete implementation of class %qs",
7271 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
7272 else if (TREE_CODE (objc_implementation_context
)
7273 == CATEGORY_IMPLEMENTATION_TYPE
)
7274 warning (0, "incomplete implementation of category %qs",
7275 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7279 warning (0, "method definition for %<%c%s%> not found",
7280 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
7283 chain
= TREE_CHAIN (chain
);
7289 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7292 conforms_to_protocol (tree
class, tree protocol
)
7294 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
7296 tree p
= CLASS_PROTOCOL_LIST (class);
7297 while (p
&& TREE_VALUE (p
) != protocol
)
7302 tree super
= (CLASS_SUPER_NAME (class)
7303 ? lookup_interface (CLASS_SUPER_NAME (class))
7305 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
7314 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7315 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7318 check_methods_accessible (tree chain
, tree context
, int mtype
)
7322 tree base_context
= context
;
7326 context
= base_context
;
7330 list
= CLASS_CLS_METHODS (context
);
7332 list
= CLASS_NST_METHODS (context
);
7334 if (lookup_method (list
, chain
))
7337 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
7338 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
7339 context
= (CLASS_SUPER_NAME (context
)
7340 ? lookup_interface (CLASS_SUPER_NAME (context
))
7343 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
7344 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
7345 context
= (CLASS_NAME (context
)
7346 ? lookup_interface (CLASS_NAME (context
))
7352 if (context
== NULL_TREE
)
7356 if (TREE_CODE (objc_implementation_context
)
7357 == CLASS_IMPLEMENTATION_TYPE
)
7358 warning (0, "incomplete implementation of class %qs",
7360 (CLASS_NAME (objc_implementation_context
)));
7361 else if (TREE_CODE (objc_implementation_context
)
7362 == CATEGORY_IMPLEMENTATION_TYPE
)
7363 warning (0, "incomplete implementation of category %qs",
7365 (CLASS_SUPER_NAME (objc_implementation_context
)));
7368 warning (0, "method definition for %<%c%s%> not found",
7369 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
7372 chain
= TREE_CHAIN (chain
); /* next method... */
7377 /* Check whether the current interface (accessible via
7378 'objc_implementation_context') actually implements protocol P, along
7379 with any protocols that P inherits. */
7382 check_protocol (tree p
, const char *type
, const char *name
)
7384 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
7388 /* Ensure that all protocols have bodies! */
7391 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
7392 CLASS_CLS_METHODS (objc_implementation_context
),
7394 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
7395 CLASS_NST_METHODS (objc_implementation_context
),
7400 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
7401 objc_implementation_context
,
7403 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
7404 objc_implementation_context
,
7409 warning (0, "%s %qs does not fully implement the %qs protocol",
7410 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
7413 /* Check protocols recursively. */
7414 if (PROTOCOL_LIST (p
))
7416 tree subs
= PROTOCOL_LIST (p
);
7418 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
7422 tree sub
= TREE_VALUE (subs
);
7424 /* If the superclass does not conform to the protocols
7425 inherited by P, then we must! */
7426 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
7427 check_protocol (sub
, type
, name
);
7428 subs
= TREE_CHAIN (subs
);
7433 /* Check whether the current interface (accessible via
7434 'objc_implementation_context') actually implements the protocols listed
7438 check_protocols (tree proto_list
, const char *type
, const char *name
)
7440 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
7442 tree p
= TREE_VALUE (proto_list
);
7444 check_protocol (p
, type
, name
);
7448 /* Make sure that the class CLASS_NAME is defined
7449 CODE says which kind of thing CLASS_NAME ought to be.
7450 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7451 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7454 start_class (enum tree_code code
, tree class_name
, tree super_name
,
7460 if (current_namespace
!= global_namespace
) {
7461 error ("Objective-C declarations may only appear in global scope");
7463 #endif /* OBJCPLUS */
7465 if (objc_implementation_context
)
7467 warning (0, "%<@end%> missing in implementation context");
7468 finish_class (objc_implementation_context
);
7469 objc_ivar_chain
= NULL_TREE
;
7470 objc_implementation_context
= NULL_TREE
;
7473 class = make_node (code
);
7474 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS
);
7476 /* Check for existence of the super class, if one was specified. Note
7477 that we must have seen an @interface, not just a @class. If we
7478 are looking at a @compatibility_alias, traverse it first. */
7479 if ((code
== CLASS_INTERFACE_TYPE
|| code
== CLASS_IMPLEMENTATION_TYPE
)
7482 tree super
= objc_is_class_name (super_name
);
7484 if (!super
|| !lookup_interface (super
))
7486 error ("cannot find interface declaration for %qs, superclass of %qs",
7487 IDENTIFIER_POINTER (super
? super
: super_name
),
7488 IDENTIFIER_POINTER (class_name
));
7489 super_name
= NULL_TREE
;
7495 CLASS_NAME (class) = class_name
;
7496 CLASS_SUPER_NAME (class) = super_name
;
7497 CLASS_CLS_METHODS (class) = NULL_TREE
;
7499 if (! objc_is_class_name (class_name
)
7500 && (decl
= lookup_name (class_name
)))
7502 error ("%qs redeclared as different kind of symbol",
7503 IDENTIFIER_POINTER (class_name
));
7504 error ("previous declaration of %q+D",
7508 if (code
== CLASS_IMPLEMENTATION_TYPE
)
7513 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
7514 if (TREE_VALUE (chain
) == class_name
)
7516 error ("reimplementation of class %qs",
7517 IDENTIFIER_POINTER (class_name
));
7518 return error_mark_node
;
7520 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
7521 implemented_classes
);
7524 /* Reset for multiple classes per file. */
7527 objc_implementation_context
= class;
7529 /* Lookup the interface for this implementation. */
7531 if (!(implementation_template
= lookup_interface (class_name
)))
7533 warning (0, "cannot find interface declaration for %qs",
7534 IDENTIFIER_POINTER (class_name
));
7535 add_class (implementation_template
= objc_implementation_context
,
7539 /* If a super class has been specified in the implementation,
7540 insure it conforms to the one specified in the interface. */
7543 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
7545 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
7546 const char *const name
=
7547 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
7548 error ("conflicting super class name %qs",
7549 IDENTIFIER_POINTER (super_name
));
7550 error ("previous declaration of %qs", name
);
7553 else if (! super_name
)
7555 CLASS_SUPER_NAME (objc_implementation_context
)
7556 = CLASS_SUPER_NAME (implementation_template
);
7560 else if (code
== CLASS_INTERFACE_TYPE
)
7562 if (lookup_interface (class_name
))
7564 error ("duplicate interface declaration for class %qs",
7566 warning (0, "duplicate interface declaration for class %qs",
7568 IDENTIFIER_POINTER (class_name
));
7570 add_class (class, class_name
);
7573 CLASS_PROTOCOL_LIST (class)
7574 = lookup_and_install_protocols (protocol_list
);
7577 else if (code
== CATEGORY_INTERFACE_TYPE
)
7579 tree class_category_is_assoc_with
;
7581 /* For a category, class_name is really the name of the class that
7582 the following set of methods will be associated with. We must
7583 find the interface so that can derive the objects template. */
7585 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
7587 error ("cannot find interface declaration for %qs",
7588 IDENTIFIER_POINTER (class_name
));
7589 exit (FATAL_EXIT_CODE
);
7592 add_category (class_category_is_assoc_with
, class);
7595 CLASS_PROTOCOL_LIST (class)
7596 = lookup_and_install_protocols (protocol_list
);
7599 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
7601 /* Reset for multiple classes per file. */
7604 objc_implementation_context
= class;
7606 /* For a category, class_name is really the name of the class that
7607 the following set of methods will be associated with. We must
7608 find the interface so that can derive the objects template. */
7610 if (!(implementation_template
= lookup_interface (class_name
)))
7612 error ("cannot find interface declaration for %qs",
7613 IDENTIFIER_POINTER (class_name
));
7614 exit (FATAL_EXIT_CODE
);
7621 continue_class (tree
class)
7623 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
7624 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
7626 struct imp_entry
*imp_entry
;
7628 /* Check consistency of the instance variables. */
7630 if (CLASS_RAW_IVARS (class))
7631 check_ivars (implementation_template
, class);
7633 /* code generation */
7636 push_lang_context (lang_name_c
);
7639 build_private_template (implementation_template
);
7640 uprivate_record
= CLASS_STATIC_TEMPLATE (implementation_template
);
7641 objc_instance_type
= build_pointer_type (uprivate_record
);
7643 imp_entry
= (struct imp_entry
*) ggc_alloc (sizeof (struct imp_entry
));
7645 imp_entry
->next
= imp_list
;
7646 imp_entry
->imp_context
= class;
7647 imp_entry
->imp_template
= implementation_template
;
7649 synth_forward_declarations ();
7650 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
7651 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
7652 imp_entry
->has_cxx_cdtors
= 0;
7654 /* Append to front and increment count. */
7655 imp_list
= imp_entry
;
7656 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
7662 pop_lang_context ();
7663 #endif /* OBJCPLUS */
7665 return get_class_ivars (implementation_template
, true);
7668 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
7671 push_lang_context (lang_name_c
);
7672 #endif /* OBJCPLUS */
7674 build_private_template (class);
7677 pop_lang_context ();
7678 #endif /* OBJCPLUS */
7684 return error_mark_node
;
7687 /* This is called once we see the "@end" in an interface/implementation. */
7690 finish_class (tree
class)
7692 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
7694 /* All code generation is done in finish_objc. */
7696 if (implementation_template
!= objc_implementation_context
)
7698 /* Ensure that all method listed in the interface contain bodies. */
7699 check_methods (CLASS_CLS_METHODS (implementation_template
),
7700 CLASS_CLS_METHODS (objc_implementation_context
), '+');
7701 check_methods (CLASS_NST_METHODS (implementation_template
),
7702 CLASS_NST_METHODS (objc_implementation_context
), '-');
7704 if (CLASS_PROTOCOL_LIST (implementation_template
))
7705 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
7707 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
7711 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
7713 tree category
= lookup_category (implementation_template
, CLASS_SUPER_NAME (class));
7717 /* Ensure all method listed in the interface contain bodies. */
7718 check_methods (CLASS_CLS_METHODS (category
),
7719 CLASS_CLS_METHODS (objc_implementation_context
), '+');
7720 check_methods (CLASS_NST_METHODS (category
),
7721 CLASS_NST_METHODS (objc_implementation_context
), '-');
7723 if (CLASS_PROTOCOL_LIST (category
))
7724 check_protocols (CLASS_PROTOCOL_LIST (category
),
7726 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7732 add_protocol (tree protocol
)
7734 /* Put protocol on list in reverse order. */
7735 TREE_CHAIN (protocol
) = protocol_chain
;
7736 protocol_chain
= protocol
;
7737 return protocol_chain
;
7741 lookup_protocol (tree ident
)
7745 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
7746 if (ident
== PROTOCOL_NAME (chain
))
7752 /* This function forward declares the protocols named by NAMES. If
7753 they are already declared or defined, the function has no effect. */
7756 objc_declare_protocols (tree names
)
7761 if (current_namespace
!= global_namespace
) {
7762 error ("Objective-C declarations may only appear in global scope");
7764 #endif /* OBJCPLUS */
7766 for (list
= names
; list
; list
= TREE_CHAIN (list
))
7768 tree name
= TREE_VALUE (list
);
7770 if (lookup_protocol (name
) == NULL_TREE
)
7772 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
7774 TYPE_LANG_SLOT_1 (protocol
)
7775 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
7776 PROTOCOL_NAME (protocol
) = name
;
7777 PROTOCOL_LIST (protocol
) = NULL_TREE
;
7778 add_protocol (protocol
);
7779 PROTOCOL_DEFINED (protocol
) = 0;
7780 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
7786 start_protocol (enum tree_code code
, tree name
, tree list
)
7791 if (current_namespace
!= global_namespace
) {
7792 error ("Objective-C declarations may only appear in global scope");
7794 #endif /* OBJCPLUS */
7796 protocol
= lookup_protocol (name
);
7800 protocol
= make_node (code
);
7801 TYPE_LANG_SLOT_1 (protocol
) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
7803 PROTOCOL_NAME (protocol
) = name
;
7804 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
7805 add_protocol (protocol
);
7806 PROTOCOL_DEFINED (protocol
) = 1;
7807 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
7809 check_protocol_recursively (protocol
, list
);
7811 else if (! PROTOCOL_DEFINED (protocol
))
7813 PROTOCOL_DEFINED (protocol
) = 1;
7814 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
7816 check_protocol_recursively (protocol
, list
);
7820 warning (0, "duplicate declaration for protocol %qs",
7821 IDENTIFIER_POINTER (name
));
7827 /* "Encode" a data type into a string, which grows in util_obstack.
7828 ??? What is the FORMAT? Someone please document this! */
7831 encode_type_qualifiers (tree declspecs
)
7835 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
7837 if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
7838 obstack_1grow (&util_obstack
, 'n');
7839 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
7840 obstack_1grow (&util_obstack
, 'N');
7841 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
7842 obstack_1grow (&util_obstack
, 'o');
7843 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
7844 obstack_1grow (&util_obstack
, 'O');
7845 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
7846 obstack_1grow (&util_obstack
, 'R');
7847 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
7848 obstack_1grow (&util_obstack
, 'V');
7852 /* Encode a pointer type. */
7855 encode_pointer (tree type
, int curtype
, int format
)
7857 tree pointer_to
= TREE_TYPE (type
);
7859 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
7861 if (OBJC_TYPE_NAME (pointer_to
)
7862 && TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
7864 const char *name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to
));
7866 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
7868 obstack_1grow (&util_obstack
, '@');
7871 else if (TYPE_HAS_OBJC_INFO (pointer_to
)
7872 && TYPE_OBJC_INTERFACE (pointer_to
))
7874 if (generating_instance_variables
)
7876 obstack_1grow (&util_obstack
, '@');
7877 obstack_1grow (&util_obstack
, '"');
7878 obstack_grow (&util_obstack
, name
, strlen (name
));
7879 obstack_1grow (&util_obstack
, '"');
7884 obstack_1grow (&util_obstack
, '@');
7888 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
7890 obstack_1grow (&util_obstack
, '#');
7893 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
7895 obstack_1grow (&util_obstack
, ':');
7900 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
7901 && TYPE_MODE (pointer_to
) == QImode
)
7903 tree pname
= TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
7904 ? OBJC_TYPE_NAME (pointer_to
)
7905 : DECL_NAME (OBJC_TYPE_NAME (pointer_to
));
7907 if (!flag_next_runtime
|| strcmp (IDENTIFIER_POINTER (pname
), "BOOL"))
7909 /* It appears that "r*" means "const char *" rather than
7911 if (TYPE_READONLY (pointer_to
))
7912 obstack_1grow (&util_obstack
, 'r');
7914 obstack_1grow (&util_obstack
, '*');
7919 /* We have a type that does not get special treatment. */
7921 /* NeXT extension */
7922 obstack_1grow (&util_obstack
, '^');
7923 encode_type (pointer_to
, curtype
, format
);
7927 encode_array (tree type
, int curtype
, int format
)
7929 tree an_int_cst
= TYPE_SIZE (type
);
7930 tree array_of
= TREE_TYPE (type
);
7933 /* An incomplete array is treated like a pointer. */
7934 if (an_int_cst
== NULL
)
7936 encode_pointer (type
, curtype
, format
);
7940 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of
)) == 0)
7941 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
)0);
7943 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
,
7944 TREE_INT_CST_LOW (an_int_cst
)
7945 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
)));
7947 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7948 encode_type (array_of
, curtype
, format
);
7949 obstack_1grow (&util_obstack
, ']');
7954 encode_aggregate_fields (tree type
, int pointed_to
, int curtype
, int format
)
7956 tree field
= TYPE_FIELDS (type
);
7958 for (; field
; field
= TREE_CHAIN (field
))
7961 /* C++ static members, and things that are not field at all,
7962 should not appear in the encoding. */
7963 if (TREE_CODE (field
) != FIELD_DECL
|| TREE_STATIC (field
))
7967 /* Recursively encode fields of embedded base classes. */
7968 if (DECL_ARTIFICIAL (field
) && !DECL_NAME (field
)
7969 && TREE_CODE (TREE_TYPE (field
)) == RECORD_TYPE
)
7971 encode_aggregate_fields (TREE_TYPE (field
),
7972 pointed_to
, curtype
, format
);
7976 if (generating_instance_variables
&& !pointed_to
)
7978 tree fname
= DECL_NAME (field
);
7980 obstack_1grow (&util_obstack
, '"');
7982 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
7983 obstack_grow (&util_obstack
,
7984 IDENTIFIER_POINTER (fname
),
7985 strlen (IDENTIFIER_POINTER (fname
)));
7987 obstack_1grow (&util_obstack
, '"');
7990 encode_field_decl (field
, curtype
, format
);
7995 encode_aggregate_within (tree type
, int curtype
, int format
, int left
,
7999 /* NB: aggregates that are pointed to have slightly different encoding
8000 rules in that you never encode the names of instance variables. */
8001 int ob_size
= obstack_object_size (&util_obstack
);
8002 char c1
= ob_size
> 1 ? *(obstack_next_free (&util_obstack
) - 2) : 0;
8003 char c0
= ob_size
> 0 ? *(obstack_next_free (&util_obstack
) - 1) : 0;
8004 int pointed_to
= (c0
== '^' || (c1
== '^' && c0
== 'r'));
8006 = ((format
== OBJC_ENCODE_INLINE_DEFS
|| generating_instance_variables
)
8007 && (!pointed_to
|| ob_size
- curtype
== (c1
== 'r' ? 2 : 1)));
8009 /* Traverse struct aliases; it is important to get the
8010 original struct and its tag name (if any). */
8011 type
= TYPE_MAIN_VARIANT (type
);
8012 name
= OBJC_TYPE_NAME (type
);
8013 /* Open parenth/bracket. */
8014 obstack_1grow (&util_obstack
, left
);
8016 /* Encode the struct/union tag name, or '?' if a tag was
8017 not provided. Typedef aliases do not qualify. */
8018 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
8020 /* Did this struct have a tag? */
8021 && !TYPE_WAS_ANONYMOUS (type
)
8024 obstack_grow (&util_obstack
,
8025 IDENTIFIER_POINTER (name
),
8026 strlen (IDENTIFIER_POINTER (name
)));
8028 obstack_1grow (&util_obstack
, '?');
8030 /* Encode the types (and possibly names) of the inner fields,
8032 if (inline_contents
)
8034 obstack_1grow (&util_obstack
, '=');
8035 encode_aggregate_fields (type
, pointed_to
, curtype
, format
);
8037 /* Close parenth/bracket. */
8038 obstack_1grow (&util_obstack
, right
);
8042 encode_aggregate (tree type
, int curtype
, int format
)
8044 enum tree_code code
= TREE_CODE (type
);
8050 encode_aggregate_within (type
, curtype
, format
, '{', '}');
8055 encode_aggregate_within (type
, curtype
, format
, '(', ')');
8060 obstack_1grow (&util_obstack
, 'i');
8068 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8072 encode_next_bitfield (int width
)
8075 sprintf (buffer
, "b%d", width
);
8076 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
8079 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8081 encode_type (tree type
, int curtype
, int format
)
8083 enum tree_code code
= TREE_CODE (type
);
8086 if (TYPE_READONLY (type
))
8087 obstack_1grow (&util_obstack
, 'r');
8089 if (code
== INTEGER_TYPE
)
8091 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
8093 case 8: c
= TYPE_UNSIGNED (type
) ? 'C' : 'c'; break;
8094 case 16: c
= TYPE_UNSIGNED (type
) ? 'S' : 's'; break;
8096 if (type
== long_unsigned_type_node
8097 || type
== long_integer_type_node
)
8098 c
= TYPE_UNSIGNED (type
) ? 'L' : 'l';
8100 c
= TYPE_UNSIGNED (type
) ? 'I' : 'i';
8102 case 64: c
= TYPE_UNSIGNED (type
) ? 'Q' : 'q'; break;
8105 obstack_1grow (&util_obstack
, c
);
8108 else if (code
== REAL_TYPE
)
8110 /* Floating point types. */
8111 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
8113 case 32: c
= 'f'; break;
8116 case 128: c
= 'd'; break;
8119 obstack_1grow (&util_obstack
, c
);
8122 else if (code
== VOID_TYPE
)
8123 obstack_1grow (&util_obstack
, 'v');
8125 else if (code
== BOOLEAN_TYPE
)
8126 obstack_1grow (&util_obstack
, 'B');
8128 else if (code
== ARRAY_TYPE
)
8129 encode_array (type
, curtype
, format
);
8131 else if (code
== POINTER_TYPE
)
8132 encode_pointer (type
, curtype
, format
);
8134 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
8135 encode_aggregate (type
, curtype
, format
);
8137 else if (code
== FUNCTION_TYPE
) /* '?' */
8138 obstack_1grow (&util_obstack
, '?');
8140 else if (code
== COMPLEX_TYPE
)
8142 obstack_1grow (&util_obstack
, 'j');
8143 encode_type (TREE_TYPE (type
), curtype
, format
);
8148 encode_gnu_bitfield (int position
, tree type
, int size
)
8150 enum tree_code code
= TREE_CODE (type
);
8152 char charType
= '?';
8154 if (code
== INTEGER_TYPE
)
8156 if (integer_zerop (TYPE_MIN_VALUE (type
)))
8158 /* Unsigned integer types. */
8160 if (TYPE_MODE (type
) == QImode
)
8162 else if (TYPE_MODE (type
) == HImode
)
8164 else if (TYPE_MODE (type
) == SImode
)
8166 if (type
== long_unsigned_type_node
)
8171 else if (TYPE_MODE (type
) == DImode
)
8176 /* Signed integer types. */
8178 if (TYPE_MODE (type
) == QImode
)
8180 else if (TYPE_MODE (type
) == HImode
)
8182 else if (TYPE_MODE (type
) == SImode
)
8184 if (type
== long_integer_type_node
)
8190 else if (TYPE_MODE (type
) == DImode
)
8194 else if (code
== ENUMERAL_TYPE
)
8199 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
8200 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
8204 encode_field_decl (tree field_decl
, int curtype
, int format
)
8209 /* C++ static members, and things that are not fields at all,
8210 should not appear in the encoding. */
8211 if (TREE_CODE (field_decl
) != FIELD_DECL
|| TREE_STATIC (field_decl
))
8215 type
= TREE_TYPE (field_decl
);
8217 /* Generate the bitfield typing information, if needed. Note the difference
8218 between GNU and NeXT runtimes. */
8219 if (DECL_BIT_FIELD_TYPE (field_decl
))
8221 int size
= tree_low_cst (DECL_SIZE (field_decl
), 1);
8223 if (flag_next_runtime
)
8224 encode_next_bitfield (size
);
8226 encode_gnu_bitfield (int_bit_position (field_decl
),
8227 DECL_BIT_FIELD_TYPE (field_decl
), size
);
8230 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
8233 static GTY(()) tree objc_parmlist
= NULL_TREE
;
8235 /* Append PARM to a list of formal parameters of a method, making a necessary
8236 array-to-pointer adjustment along the way. */
8239 objc_push_parm (tree parm
)
8241 bool relayout_needed
= false;
8242 /* Decay arrays and functions into pointers. */
8243 if (TREE_CODE (TREE_TYPE (parm
)) == ARRAY_TYPE
)
8245 TREE_TYPE (parm
) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm
)));
8246 relayout_needed
= true;
8248 else if (TREE_CODE (TREE_TYPE (parm
)) == FUNCTION_TYPE
)
8250 TREE_TYPE (parm
) = build_pointer_type (TREE_TYPE (parm
));
8251 relayout_needed
= true;
8254 if (relayout_needed
)
8255 relayout_decl (parm
);
8258 DECL_ARG_TYPE (parm
)
8259 = lang_hooks
.types
.type_promotes_to (TREE_TYPE (parm
));
8261 /* Record constancy and volatility. */
8262 c_apply_type_quals_to_decl
8263 ((TYPE_READONLY (TREE_TYPE (parm
)) ? TYPE_QUAL_CONST
: 0)
8264 | (TYPE_RESTRICT (TREE_TYPE (parm
)) ? TYPE_QUAL_RESTRICT
: 0)
8265 | (TYPE_VOLATILE (TREE_TYPE (parm
)) ? TYPE_QUAL_VOLATILE
: 0), parm
);
8267 objc_parmlist
= chainon (objc_parmlist
, parm
);
8270 /* Retrieve the formal parameter list constructed via preceding calls to
8271 objc_push_parm(). */
8275 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED
)
8277 static struct c_arg_info
*
8278 objc_get_parm_info (int have_ellipsis
)
8282 tree parm_info
= objc_parmlist
;
8283 objc_parmlist
= NULL_TREE
;
8287 tree parm_info
= objc_parmlist
;
8288 struct c_arg_info
*arg_info
;
8289 /* The C front-end requires an elaborate song and dance at
8292 declare_parm_level ();
8295 tree next
= TREE_CHAIN (parm_info
);
8297 TREE_CHAIN (parm_info
) = NULL_TREE
;
8298 parm_info
= pushdecl (parm_info
);
8299 finish_decl (parm_info
, NULL_TREE
, NULL_TREE
);
8302 arg_info
= get_parm_info (have_ellipsis
);
8304 objc_parmlist
= NULL_TREE
;
8309 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8310 method definitions. In the case of instance methods, we can be more
8311 specific as to the type of 'self'. */
8314 synth_self_and_ucmd_args (void)
8318 if (objc_method_context
8319 && TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
8320 self_type
= objc_instance_type
;
8322 /* Really a `struct objc_class *'. However, we allow people to
8323 assign to self, which changes its type midstream. */
8324 self_type
= objc_object_type
;
8327 objc_push_parm (build_decl (PARM_DECL
, self_id
, self_type
));
8330 objc_push_parm (build_decl (PARM_DECL
, ucmd_id
, objc_selector_type
));
8333 /* Transform an Objective-C method definition into a static C function
8334 definition, synthesizing the first two arguments, "self" and "_cmd",
8338 start_method_def (tree method
)
8344 struct c_arg_info
*parm_info
;
8346 int have_ellipsis
= 0;
8348 /* If we are defining a "dealloc" method in a non-root class, we
8349 will need to check if a [super dealloc] is missing, and warn if
8351 if(CLASS_SUPER_NAME (objc_implementation_context
)
8352 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method
))))
8353 should_call_super_dealloc
= 1;
8355 should_call_super_dealloc
= 0;
8357 /* Required to implement _msgSuper. */
8358 objc_method_context
= method
;
8359 UOBJC_SUPER_decl
= NULL_TREE
;
8361 /* Generate prototype declarations for arguments..."new-style". */
8362 synth_self_and_ucmd_args ();
8364 /* Generate argument declarations if a keyword_decl. */
8365 parmlist
= METHOD_SEL_ARGS (method
);
8368 tree type
= TREE_VALUE (TREE_TYPE (parmlist
)), parm
;
8370 parm
= build_decl (PARM_DECL
, KEYWORD_ARG_NAME (parmlist
), type
);
8371 objc_push_parm (parm
);
8372 parmlist
= TREE_CHAIN (parmlist
);
8375 if (METHOD_ADD_ARGS (method
))
8379 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
8380 akey
; akey
= TREE_CHAIN (akey
))
8382 objc_push_parm (TREE_VALUE (akey
));
8385 if (METHOD_ADD_ARGS_ELLIPSIS_P (method
))
8389 parm_info
= objc_get_parm_info (have_ellipsis
);
8391 really_start_method (objc_method_context
, parm_info
);
8395 warn_with_method (const char *message
, int mtype
, tree method
)
8397 /* Add a readable method name to the warning. */
8398 warning (0, "%J%s %<%c%s%>", method
,
8399 message
, mtype
, gen_method_decl (method
));
8402 /* Return 1 if TYPE1 is equivalent to TYPE2
8403 for purposes of method overloading. */
8406 objc_types_are_equivalent (tree type1
, tree type2
)
8411 /* Strip away indirections. */
8412 while ((TREE_CODE (type1
) == ARRAY_TYPE
|| TREE_CODE (type1
) == POINTER_TYPE
)
8413 && (TREE_CODE (type1
) == TREE_CODE (type2
)))
8414 type1
= TREE_TYPE (type1
), type2
= TREE_TYPE (type2
);
8415 if (TYPE_MAIN_VARIANT (type1
) != TYPE_MAIN_VARIANT (type2
))
8418 type1
= (TYPE_HAS_OBJC_INFO (type1
)
8419 ? TYPE_OBJC_PROTOCOL_LIST (type1
)
8421 type2
= (TYPE_HAS_OBJC_INFO (type2
)
8422 ? TYPE_OBJC_PROTOCOL_LIST (type2
)
8425 if (list_length (type1
) == list_length (type2
))
8427 for (; type2
; type2
= TREE_CHAIN (type2
))
8428 if (!lookup_protocol_in_reflist (type1
, TREE_VALUE (type2
)))
8435 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8438 objc_types_share_size_and_alignment (tree type1
, tree type2
)
8440 return (simple_cst_equal (TYPE_SIZE (type1
), TYPE_SIZE (type2
))
8441 && TYPE_ALIGN (type1
) == TYPE_ALIGN (type2
));
8444 /* Return 1 if PROTO1 is equivalent to PROTO2
8445 for purposes of method overloading. Ordinarily, the type signatures
8446 should match up exactly, unless STRICT is zero, in which case we
8447 shall allow differences in which the size and alignment of a type
8451 comp_proto_with_proto (tree proto1
, tree proto2
, int strict
)
8455 /* The following test is needed in case there are hashing
8457 if (METHOD_SEL_NAME (proto1
) != METHOD_SEL_NAME (proto2
))
8460 /* Compare return types. */
8461 type1
= TREE_VALUE (TREE_TYPE (proto1
));
8462 type2
= TREE_VALUE (TREE_TYPE (proto2
));
8464 if (!objc_types_are_equivalent (type1
, type2
)
8465 && (strict
|| !objc_types_share_size_and_alignment (type1
, type2
)))
8468 /* Compare argument types. */
8469 for (type1
= get_arg_type_list (proto1
, METHOD_REF
, 0),
8470 type2
= get_arg_type_list (proto2
, METHOD_REF
, 0);
8472 type1
= TREE_CHAIN (type1
), type2
= TREE_CHAIN (type2
))
8474 if (!objc_types_are_equivalent (TREE_VALUE (type1
), TREE_VALUE (type2
))
8476 || !objc_types_share_size_and_alignment (TREE_VALUE (type1
),
8477 TREE_VALUE (type2
))))
8481 return (!type1
&& !type2
);
8484 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8485 this occurs. ObjC method dispatches are _not_ like C++ virtual
8486 member function dispatches, and we account for the difference here. */
8489 objc_fold_obj_type_ref (tree ref
, tree known_type
)
8491 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED
,
8492 tree known_type ATTRIBUTE_UNUSED
)
8496 tree v
= BINFO_VIRTUALS (TYPE_BINFO (known_type
));
8498 /* If the receiver does not have virtual member functions, there
8499 is nothing we can (or need to) do here. */
8503 /* Let C++ handle C++ virtual functions. */
8504 return cp_fold_obj_type_ref (ref
, known_type
);
8506 /* For plain ObjC, we currently do not need to do anything. */
8512 objc_start_function (tree name
, tree type
, tree attrs
,
8516 struct c_arg_info
*params
8520 tree fndecl
= build_decl (FUNCTION_DECL
, name
, type
);
8523 DECL_ARGUMENTS (fndecl
) = params
;
8524 DECL_INITIAL (fndecl
) = error_mark_node
;
8525 DECL_EXTERNAL (fndecl
) = 0;
8526 TREE_STATIC (fndecl
) = 1;
8527 retrofit_lang_decl (fndecl
);
8528 cplus_decl_attributes (&fndecl
, attrs
, 0);
8529 start_preparsed_function (fndecl
, attrs
, /*flags=*/SF_DEFAULT
);
8531 struct c_label_context_se
*nstack_se
;
8532 struct c_label_context_vm
*nstack_vm
;
8533 nstack_se
= XOBNEW (&parser_obstack
, struct c_label_context_se
);
8534 nstack_se
->labels_def
= NULL
;
8535 nstack_se
->labels_used
= NULL
;
8536 nstack_se
->next
= label_context_stack_se
;
8537 label_context_stack_se
= nstack_se
;
8538 nstack_vm
= XOBNEW (&parser_obstack
, struct c_label_context_vm
);
8539 nstack_vm
->labels_def
= NULL
;
8540 nstack_vm
->labels_used
= NULL
;
8541 nstack_vm
->scope
= 0;
8542 nstack_vm
->next
= label_context_stack_vm
;
8543 label_context_stack_vm
= nstack_vm
;
8544 current_function_returns_value
= 0; /* Assume, until we see it does. */
8545 current_function_returns_null
= 0;
8547 decl_attributes (&fndecl
, attrs
, 0);
8548 announce_function (fndecl
);
8549 DECL_INITIAL (fndecl
) = error_mark_node
;
8550 DECL_EXTERNAL (fndecl
) = 0;
8551 TREE_STATIC (fndecl
) = 1;
8552 current_function_decl
= pushdecl (fndecl
);
8554 declare_parm_level ();
8555 DECL_RESULT (current_function_decl
)
8556 = build_decl (RESULT_DECL
, NULL_TREE
,
8557 TREE_TYPE (TREE_TYPE (current_function_decl
)));
8558 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl
)) = 1;
8559 DECL_IGNORED_P (DECL_RESULT (current_function_decl
)) = 1;
8560 start_fname_decls ();
8561 store_parm_decls_from (params
);
8564 TREE_USED (current_function_decl
) = 1;
8567 /* - Generate an identifier for the function. the format is "_n_cls",
8568 where 1 <= n <= nMethods, and cls is the name the implementation we
8570 - Install the return type from the method declaration.
8571 - If we have a prototype, check for type consistency. */
8574 really_start_method (tree method
,
8578 struct c_arg_info
*parmlist
8582 tree ret_type
, meth_type
;
8584 const char *sel_name
, *class_name
, *cat_name
;
8587 /* Synth the storage class & assemble the return type. */
8588 ret_type
= TREE_VALUE (TREE_TYPE (method
));
8590 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
8591 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
8592 cat_name
= ((TREE_CODE (objc_implementation_context
)
8593 == CLASS_IMPLEMENTATION_TYPE
)
8595 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
8598 /* Make sure this is big enough for any plausible method label. */
8599 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
8600 + (cat_name
? strlen (cat_name
) : 0));
8602 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
8603 class_name
, cat_name
, sel_name
, method_slot
);
8605 method_id
= get_identifier (buf
);
8608 /* Objective-C methods cannot be overloaded, so we don't need
8609 the type encoding appended. It looks bad anyway... */
8610 push_lang_context (lang_name_c
);
8614 = build_function_type (ret_type
,
8615 get_arg_type_list (method
, METHOD_DEF
, 0));
8616 objc_start_function (method_id
, meth_type
, NULL_TREE
, parmlist
);
8618 /* Set self_decl from the first argument. */
8619 self_decl
= DECL_ARGUMENTS (current_function_decl
);
8621 /* Suppress unused warnings. */
8622 TREE_USED (self_decl
) = 1;
8623 TREE_USED (TREE_CHAIN (self_decl
)) = 1;
8625 pop_lang_context ();
8628 METHOD_DEFINITION (method
) = current_function_decl
;
8630 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8632 if (implementation_template
!= objc_implementation_context
)
8635 = lookup_method_static (implementation_template
,
8636 METHOD_SEL_NAME (method
),
8637 ((TREE_CODE (method
) == CLASS_METHOD_DECL
)
8638 | OBJC_LOOKUP_NO_SUPER
));
8642 if (!comp_proto_with_proto (method
, proto
, 1))
8644 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
8646 warn_with_method ("conflicting types for", type
, method
);
8647 warn_with_method ("previous declaration of", type
, proto
);
8652 /* We have a method @implementation even though we did not
8653 see a corresponding @interface declaration (which is allowed
8654 by Objective-C rules). Go ahead and place the method in
8655 the @interface anyway, so that message dispatch lookups
8657 tree interface
= implementation_template
;
8659 if (TREE_CODE (objc_implementation_context
)
8660 == CATEGORY_IMPLEMENTATION_TYPE
)
8661 interface
= lookup_category
8663 CLASS_SUPER_NAME (objc_implementation_context
));
8666 objc_add_method (interface
, copy_node (method
),
8667 TREE_CODE (method
) == CLASS_METHOD_DECL
);
8672 static void *UOBJC_SUPER_scope
= 0;
8674 /* _n_Method (id self, SEL sel, ...)
8676 struct objc_super _S;
8677 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8681 get_super_receiver (void)
8683 if (objc_method_context
)
8685 tree super_expr
, super_expr_list
;
8687 if (!UOBJC_SUPER_decl
)
8689 UOBJC_SUPER_decl
= build_decl (VAR_DECL
, get_identifier (TAG_SUPER
),
8690 objc_super_template
);
8691 /* This prevents `unused variable' warnings when compiling with -Wall. */
8692 TREE_USED (UOBJC_SUPER_decl
) = 1;
8693 lang_hooks
.decls
.pushdecl (UOBJC_SUPER_decl
);
8694 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
8695 UOBJC_SUPER_scope
= objc_get_current_scope ();
8698 /* Set receiver to self. */
8699 super_expr
= objc_build_component_ref (UOBJC_SUPER_decl
, self_id
);
8700 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
8701 super_expr_list
= super_expr
;
8703 /* Set class to begin searching. */
8704 super_expr
= objc_build_component_ref (UOBJC_SUPER_decl
,
8705 get_identifier ("super_class"));
8707 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8709 /* [_cls, __cls]Super are "pre-built" in
8710 synth_forward_declarations. */
8712 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
8713 ((TREE_CODE (objc_method_context
)
8714 == INSTANCE_METHOD_DECL
)
8716 : uucls_super_ref
));
8720 /* We have a category. */
8722 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
8725 /* Barf if super used in a category of Object. */
8728 error ("no super class declared in interface for %qs",
8729 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
8730 return error_mark_node
;
8733 if (flag_next_runtime
&& !flag_zero_link
)
8735 super_class
= objc_get_class_reference (super_name
);
8736 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
8737 /* If we are in a class method, we must retrieve the
8738 _metaclass_ for the current class, pointed at by
8739 the class's "isa" pointer. The following assumes that
8740 "isa" is the first ivar in a class (which it must be). */
8742 = build_indirect_ref
8743 (build_c_cast (build_pointer_type (objc_class_type
),
8744 super_class
), "unary *");
8748 add_class_reference (super_name
);
8749 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
8750 ? objc_get_class_decl
: objc_get_meta_class_decl
);
8751 assemble_external (super_class
);
8753 = build_function_call
8757 my_build_string_pointer
8758 (IDENTIFIER_LENGTH (super_name
) + 1,
8759 IDENTIFIER_POINTER (super_name
))));
8763 = build_modify_expr (super_expr
, NOP_EXPR
,
8764 build_c_cast (TREE_TYPE (super_expr
),
8768 super_expr_list
= build_compound_expr (super_expr_list
, super_expr
);
8770 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
8771 super_expr_list
= build_compound_expr (super_expr_list
, super_expr
);
8773 return super_expr_list
;
8777 error ("[super ...] must appear in a method context");
8778 return error_mark_node
;
8782 /* When exiting a scope, sever links to a 'super' declaration (if any)
8783 therein contained. */
8786 objc_clear_super_receiver (void)
8788 if (objc_method_context
8789 && UOBJC_SUPER_scope
== objc_get_current_scope ()) {
8790 UOBJC_SUPER_decl
= 0;
8791 UOBJC_SUPER_scope
= 0;
8796 objc_finish_method_definition (tree fndecl
)
8798 /* We cannot validly inline ObjC methods, at least not without a language
8799 extension to declare that a method need not be dynamically
8800 dispatched, so suppress all thoughts of doing so. */
8801 DECL_INLINE (fndecl
) = 0;
8802 DECL_UNINLINABLE (fndecl
) = 1;
8805 /* The C++ front-end will have called finish_function() for us. */
8809 METHOD_ENCODING (objc_method_context
)
8810 = encode_method_prototype (objc_method_context
);
8812 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8813 since the optimizer may find "may be used before set" errors. */
8814 objc_method_context
= NULL_TREE
;
8816 if (should_call_super_dealloc
)
8817 warning (0, "method possibly missing a [super dealloc] call");
8822 lang_report_error_function (tree decl
)
8824 if (objc_method_context
)
8826 fprintf (stderr
, "In method %qs\n",
8827 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
8836 /* Given a tree DECL node, produce a printable description of it in the given
8837 buffer, overwriting the buffer. */
8840 gen_declaration (tree decl
)
8846 gen_type_name_0 (TREE_TYPE (decl
));
8848 if (DECL_NAME (decl
))
8850 if (!POINTER_TYPE_P (TREE_TYPE (decl
)))
8851 strcat (errbuf
, " ");
8853 strcat (errbuf
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
8856 if (DECL_INITIAL (decl
)
8857 && TREE_CODE (DECL_INITIAL (decl
)) == INTEGER_CST
)
8858 sprintf (errbuf
+ strlen (errbuf
), ": " HOST_WIDE_INT_PRINT_DEC
,
8859 TREE_INT_CST_LOW (DECL_INITIAL (decl
)));
8865 /* Given a tree TYPE node, produce a printable description of it in the given
8866 buffer, overwriting the buffer. */
8869 gen_type_name_0 (tree type
)
8871 tree orig
= type
, proto
;
8873 if (TYPE_P (type
) && TYPE_NAME (type
))
8874 type
= TYPE_NAME (type
);
8875 else if (POINTER_TYPE_P (type
) || TREE_CODE (type
) == ARRAY_TYPE
)
8877 tree inner
= TREE_TYPE (type
);
8879 while (TREE_CODE (inner
) == ARRAY_TYPE
)
8880 inner
= TREE_TYPE (inner
);
8882 gen_type_name_0 (inner
);
8884 if (!POINTER_TYPE_P (inner
))
8885 strcat (errbuf
, " ");
8887 if (POINTER_TYPE_P (type
))
8888 strcat (errbuf
, "*");
8890 while (type
!= inner
)
8892 strcat (errbuf
, "[");
8894 if (TYPE_DOMAIN (type
))
8898 sprintf (sz
, HOST_WIDE_INT_PRINT_DEC
,
8900 (TYPE_MAX_VALUE (TYPE_DOMAIN (type
))) + 1));
8901 strcat (errbuf
, sz
);
8904 strcat (errbuf
, "]");
8905 type
= TREE_TYPE (type
);
8911 if (TREE_CODE (type
) == TYPE_DECL
&& DECL_NAME (type
))
8912 type
= DECL_NAME (type
);
8914 strcat (errbuf
, TREE_CODE (type
) == IDENTIFIER_NODE
8915 ? IDENTIFIER_POINTER (type
)
8918 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8919 if (objc_is_id (orig
))
8920 orig
= TREE_TYPE (orig
);
8922 proto
= TYPE_HAS_OBJC_INFO (orig
) ? TYPE_OBJC_PROTOCOL_LIST (orig
) : NULL_TREE
;
8926 strcat (errbuf
, " <");
8930 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto
))));
8931 proto
= TREE_CHAIN (proto
);
8932 strcat (errbuf
, proto
? ", " : ">");
8941 gen_type_name (tree type
)
8945 return gen_type_name_0 (type
);
8948 /* Given a method tree, put a printable description into the given
8949 buffer (overwriting) and return a pointer to the buffer. */
8952 gen_method_decl (tree method
)
8956 strcpy (errbuf
, "("); /* NB: Do _not_ call strcat() here. */
8957 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method
)));
8958 strcat (errbuf
, ")");
8959 chain
= METHOD_SEL_ARGS (method
);
8963 /* We have a chain of keyword_decls. */
8966 if (KEYWORD_KEY_NAME (chain
))
8967 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
8969 strcat (errbuf
, ":(");
8970 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain
)));
8971 strcat (errbuf
, ")");
8973 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
8974 if ((chain
= TREE_CHAIN (chain
)))
8975 strcat (errbuf
, " ");
8979 if (METHOD_ADD_ARGS (method
))
8981 chain
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
8983 /* Know we have a chain of parm_decls. */
8986 strcat (errbuf
, ", ");
8987 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain
)));
8988 chain
= TREE_CHAIN (chain
);
8991 if (METHOD_ADD_ARGS_ELLIPSIS_P (method
))
8992 strcat (errbuf
, ", ...");
8997 /* We have a unary selector. */
8998 strcat (errbuf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
9006 /* Dump an @interface declaration of the supplied class CHAIN to the
9007 supplied file FP. Used to implement the -gen-decls option (which
9008 prints out an @interface declaration of all classes compiled in
9009 this run); potentially useful for debugging the compiler too. */
9011 dump_interface (FILE *fp
, tree chain
)
9013 /* FIXME: A heap overflow here whenever a method (or ivar)
9014 declaration is so long that it doesn't fit in the buffer. The
9015 code and all the related functions should be rewritten to avoid
9016 using fixed size buffers. */
9017 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
9018 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
9019 tree nst_methods
= CLASS_NST_METHODS (chain
);
9020 tree cls_methods
= CLASS_CLS_METHODS (chain
);
9022 fprintf (fp
, "\n@interface %s", my_name
);
9024 /* CLASS_SUPER_NAME is used to store the superclass name for
9025 classes, and the category name for categories. */
9026 if (CLASS_SUPER_NAME (chain
))
9028 const char *name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
9030 if (TREE_CODE (chain
) == CATEGORY_IMPLEMENTATION_TYPE
9031 || TREE_CODE (chain
) == CATEGORY_INTERFACE_TYPE
)
9033 fprintf (fp
, " (%s)\n", name
);
9037 fprintf (fp
, " : %s\n", name
);
9043 /* FIXME - the following doesn't seem to work at the moment. */
9046 fprintf (fp
, "{\n");
9049 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
));
9050 ivar_decls
= TREE_CHAIN (ivar_decls
);
9053 fprintf (fp
, "}\n");
9058 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
));
9059 nst_methods
= TREE_CHAIN (nst_methods
);
9064 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
));
9065 cls_methods
= TREE_CHAIN (cls_methods
);
9068 fprintf (fp
, "@end\n");
9071 /* Demangle function for Objective-C */
9073 objc_demangle (const char *mangled
)
9075 char *demangled
, *cp
;
9077 if (mangled
[0] == '_' &&
9078 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
9081 cp
= demangled
= XNEWVEC (char, strlen(mangled
) + 2);
9082 if (mangled
[1] == 'i')
9083 *cp
++ = '-'; /* for instance method */
9085 *cp
++ = '+'; /* for class method */
9086 *cp
++ = '['; /* opening left brace */
9087 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
9088 while (*cp
&& *cp
== '_')
9089 cp
++; /* skip any initial underbars in class name */
9090 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
9093 free(demangled
); /* not mangled name */
9096 if (cp
[1] == '_') /* easy case: no category name */
9098 *cp
++ = ' '; /* replace two '_' with one ' ' */
9099 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
9103 *cp
++ = '('; /* less easy case: category name */
9104 cp
= strchr(cp
, '_');
9107 free(demangled
); /* not mangled name */
9111 *cp
++ = ' '; /* overwriting 1st char of method name... */
9112 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
9114 while (*cp
&& *cp
== '_')
9115 cp
++; /* skip any initial underbars in method name */
9118 *cp
= ':'; /* replace remaining '_' with ':' */
9119 *cp
++ = ']'; /* closing right brace */
9120 *cp
++ = 0; /* string terminator */
9124 return mangled
; /* not an objc mangled name */
9128 objc_printable_name (tree decl
, int kind ATTRIBUTE_UNUSED
)
9130 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
9136 gcc_obstack_init (&util_obstack
);
9137 util_firstobj
= (char *) obstack_finish (&util_obstack
);
9139 errbuf
= XNEWVEC (char, 1024 * 10);
9141 synth_module_prologue ();
9147 struct imp_entry
*impent
;
9149 /* The internally generated initializers appear to have missing braces.
9150 Don't warn about this. */
9151 int save_warn_missing_braces
= warn_missing_braces
;
9152 warn_missing_braces
= 0;
9154 /* A missing @end may not be detected by the parser. */
9155 if (objc_implementation_context
)
9157 warning (0, "%<@end%> missing in implementation context");
9158 finish_class (objc_implementation_context
);
9159 objc_ivar_chain
= NULL_TREE
;
9160 objc_implementation_context
= NULL_TREE
;
9163 /* Process the static instances here because initialization of objc_symtab
9165 if (objc_static_instances
)
9166 generate_static_references ();
9168 if (imp_list
|| class_names_chain
9169 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
9170 generate_objc_symtab_decl ();
9172 for (impent
= imp_list
; impent
; impent
= impent
->next
)
9174 objc_implementation_context
= impent
->imp_context
;
9175 implementation_template
= impent
->imp_template
;
9177 UOBJC_CLASS_decl
= impent
->class_decl
;
9178 UOBJC_METACLASS_decl
= impent
->meta_decl
;
9180 /* Dump the @interface of each class as we compile it, if the
9181 -gen-decls option is in use. TODO: Dump the classes in the
9182 order they were found, rather than in reverse order as we
9184 if (flag_gen_declaration
)
9186 dump_interface (gen_declaration_file
, objc_implementation_context
);
9189 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
9191 /* all of the following reference the string pool... */
9192 generate_ivar_lists ();
9193 generate_dispatch_tables ();
9194 generate_shared_structures (impent
->has_cxx_cdtors
9195 ? CLS_HAS_CXX_STRUCTORS
9200 generate_dispatch_tables ();
9201 generate_category (objc_implementation_context
);
9205 /* If we are using an array of selectors, we must always
9206 finish up the array decl even if no selectors were used. */
9207 if (! flag_next_runtime
|| sel_ref_chain
)
9208 build_selector_translation_table ();
9211 generate_protocols ();
9213 if ((flag_replace_objc_classes
&& imp_list
) || flag_objc_gc
)
9214 generate_objc_image_info ();
9216 /* Arrange for ObjC data structures to be initialized at run time. */
9217 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
9218 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
9220 build_module_descriptor ();
9222 if (!flag_next_runtime
)
9223 build_module_initializer_routine ();
9226 /* Dump the class references. This forces the appropriate classes
9227 to be linked into the executable image, preserving unix archive
9228 semantics. This can be removed when we move to a more dynamically
9229 linked environment. */
9231 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
9233 handle_class_ref (chain
);
9234 if (TREE_PURPOSE (chain
))
9235 generate_classref_translation_entry (chain
);
9238 for (impent
= imp_list
; impent
; impent
= impent
->next
)
9239 handle_impent (impent
);
9246 /* Run through the selector hash tables and print a warning for any
9247 selector which has multiple methods. */
9249 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
9251 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
9252 check_duplicates (hsh
, 0, 1);
9253 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
9254 check_duplicates (hsh
, 0, 1);
9258 warn_missing_braces
= save_warn_missing_braces
;
9261 /* Subroutines of finish_objc. */
9264 generate_classref_translation_entry (tree chain
)
9266 tree expr
, decl
, type
;
9268 decl
= TREE_PURPOSE (chain
);
9269 type
= TREE_TYPE (decl
);
9271 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
9272 expr
= convert (type
, expr
); /* cast! */
9274 /* The decl that is the one that we
9275 forward declared in build_class_reference. */
9276 finish_var_decl (decl
, expr
);
9281 handle_class_ref (tree chain
)
9283 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
9284 char *string
= (char *) alloca (strlen (name
) + 30);
9288 sprintf (string
, "%sobjc_class_name_%s",
9289 (flag_next_runtime
? "." : "__"), name
);
9291 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9292 if (flag_next_runtime
)
9294 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
9299 /* Make a decl for this name, so we can use its address in a tree. */
9300 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
9301 DECL_EXTERNAL (decl
) = 1;
9302 TREE_PUBLIC (decl
) = 1;
9305 rest_of_decl_compilation (decl
, 0, 0);
9307 /* Make a decl for the address. */
9308 sprintf (string
, "%sobjc_class_ref_%s",
9309 (flag_next_runtime
? "." : "__"), name
);
9310 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
9311 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
9312 DECL_INITIAL (decl
) = exp
;
9313 TREE_STATIC (decl
) = 1;
9314 TREE_USED (decl
) = 1;
9315 /* Force the output of the decl as this forces the reference of the class. */
9316 mark_decl_referenced (decl
);
9319 rest_of_decl_compilation (decl
, 0, 0);
9323 handle_impent (struct imp_entry
*impent
)
9327 objc_implementation_context
= impent
->imp_context
;
9328 implementation_template
= impent
->imp_template
;
9330 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
9332 const char *const class_name
=
9333 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
9335 string
= (char *) alloca (strlen (class_name
) + 30);
9337 sprintf (string
, "%sobjc_class_name_%s",
9338 (flag_next_runtime
? "." : "__"), class_name
);
9340 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
9342 const char *const class_name
=
9343 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
9344 const char *const class_super_name
=
9345 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
9347 string
= (char *) alloca (strlen (class_name
)
9348 + strlen (class_super_name
) + 30);
9350 /* Do the same for categories. Even though no references to
9351 these symbols are generated automatically by the compiler, it
9352 gives you a handle to pull them into an archive by hand. */
9353 sprintf (string
, "*%sobjc_category_name_%s_%s",
9354 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
9359 #ifdef ASM_DECLARE_CLASS_REFERENCE
9360 if (flag_next_runtime
)
9362 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
9370 init
= build_int_cst (c_common_type_for_size (BITS_PER_WORD
, 1), 0);
9371 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
9372 TREE_PUBLIC (decl
) = 1;
9373 TREE_READONLY (decl
) = 1;
9374 TREE_USED (decl
) = 1;
9375 TREE_CONSTANT (decl
) = 1;
9376 DECL_CONTEXT (decl
) = 0;
9377 DECL_ARTIFICIAL (decl
) = 1;
9378 DECL_INITIAL (decl
) = init
;
9379 assemble_variable (decl
, 1, 0, 0);
9383 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9384 later requires that ObjC translation units participating in F&C be
9385 specially marked. The following routine accomplishes this. */
9387 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9390 generate_objc_image_info (void)
9392 tree decl
, initlist
;
9394 = ((flag_replace_objc_classes
&& imp_list
? 1 : 0)
9395 | (flag_objc_gc
? 2 : 0));
9397 decl
= start_var_decl (build_array_type
9399 build_index_type (build_int_cst (NULL_TREE
, 2 - 1))),
9400 "_OBJC_IMAGE_INFO");
9402 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, 0));
9403 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, flags
), initlist
);
9404 initlist
= objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
9406 finish_var_decl (decl
, initlist
);
9409 /* Look up ID as an instance variable. OTHER contains the result of
9410 the C or C++ lookup, which we may want to use instead. */
9413 objc_lookup_ivar (tree other
, tree id
)
9417 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9418 if (!objc_method_context
)
9421 if (!strcmp (IDENTIFIER_POINTER (id
), "super"))
9422 /* We have a message to super. */
9423 return get_super_receiver ();
9425 /* In a class method, look up an instance variable only as a last
9427 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
9428 && other
&& other
!= error_mark_node
)
9431 /* Look up the ivar, but do not use it if it is not accessible. */
9432 ivar
= is_ivar (objc_ivar_chain
, id
);
9434 if (!ivar
|| is_private (ivar
))
9437 /* In an instance method, a local variable (or parameter) may hide the
9438 instance variable. */
9439 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
9440 && other
&& other
!= error_mark_node
9442 && CP_DECL_CONTEXT (other
) != global_namespace
)
9444 && !DECL_FILE_SCOPE_P (other
))
9447 warning (0, "local declaration of %qs hides instance variable",
9448 IDENTIFIER_POINTER (id
));
9453 /* At this point, we are either in an instance method with no obscuring
9454 local definitions, or in a class method with no alternate definitions
9456 return build_ivar_reference (id
);
9459 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9460 needs to be done if we are calling a function through a cast. */
9463 objc_rewrite_function_call (tree function
, tree params
)
9465 if (TREE_CODE (function
) == NOP_EXPR
9466 && TREE_CODE (TREE_OPERAND (function
, 0)) == ADDR_EXPR
9467 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function
, 0), 0))
9470 function
= build3 (OBJ_TYPE_REF
, TREE_TYPE (function
),
9471 TREE_OPERAND (function
, 0),
9472 TREE_VALUE (params
), size_zero_node
);
9478 /* Look for the special case of OBJC_TYPE_REF with the address of
9479 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9482 enum gimplify_status
9483 objc_gimplify_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
9485 enum gimplify_status r0
, r1
;
9486 if (TREE_CODE (*expr_p
) == OBJ_TYPE_REF
9487 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p
)) == ADDR_EXPR
9488 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p
), 0))
9491 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9492 value of the OBJ_TYPE_REF, so force them to be emitted
9493 during subexpression evaluation rather than after the
9494 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9495 C to use direct rather than indirect calls when the
9496 object expression has a postincrement. */
9497 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
, NULL
,
9498 is_gimple_val
, fb_rvalue
);
9499 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
, post_p
,
9500 is_gimple_val
, fb_rvalue
);
9502 return MIN (r0
, r1
);
9506 return cp_gimplify_expr (expr_p
, pre_p
, post_p
);
9508 return c_gimplify_expr (expr_p
, pre_p
, post_p
);
9512 /* Given a CALL expression, find the function being called. The ObjC
9513 version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend. */
9516 objc_get_callee_fndecl (tree call_expr
)
9518 tree addr
= CALL_EXPR_FN (call_expr
);
9519 if (TREE_CODE (addr
) != OBJ_TYPE_REF
)
9522 addr
= OBJ_TYPE_REF_EXPR (addr
);
9524 /* If the address is just `&f' for some function `f', then we know
9525 that `f' is being called. */
9526 if (TREE_CODE (addr
) == ADDR_EXPR
9527 && TREE_CODE (TREE_OPERAND (addr
, 0)) == FUNCTION_DECL
)
9528 return TREE_OPERAND (addr
, 0);
9533 #include "gt-objc-objc-act.h"