1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
60 #include "langhooks.h"
71 #include "diagnostic.h"
73 #include "tree-iterator.h"
76 #include "langhooks-def.h"
78 #define OBJC_VOID_AT_END void_list_node
80 static unsigned int should_call_super_dealloc = 0;
82 /* When building Objective-C++, we are not linking against the C front-end
83 and so need to replicate the C tree-construction functions in some way. */
85 #define OBJCP_REMAP_FUNCTIONS
86 #include "objcp-decl.h"
89 /* This is the default way of generating a method name. */
90 /* I am not sure it is really correct.
91 Perhaps there's a danger that it will make name conflicts
92 if method names contain underscores. -- rms. */
93 #ifndef OBJC_GEN_METHOD_LABEL
94 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
97 sprintf ((BUF), "_%s_%s_%s_%s", \
98 ((IS_INST) ? "i" : "c"), \
100 ((CAT_NAME)? (CAT_NAME) : ""), \
102 for (temp = (BUF); *temp; temp++) \
103 if (*temp == ':') *temp = '_'; \
107 /* These need specifying. */
108 #ifndef OBJC_FORWARDING_STACK_OFFSET
109 #define OBJC_FORWARDING_STACK_OFFSET 0
112 #ifndef OBJC_FORWARDING_MIN_OFFSET
113 #define OBJC_FORWARDING_MIN_OFFSET 0
116 /* Set up for use of obstacks. */
120 /* This obstack is used to accumulate the encoding of a data type. */
121 static struct obstack util_obstack;
123 /* This points to the beginning of obstack contents, so we can free
124 the whole contents. */
127 /* The version identifies which language generation and runtime
128 the module (file) was compiled for, and is recorded in the
129 module descriptor. */
131 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
132 #define PROTOCOL_VERSION 2
134 /* (Decide if these can ever be validly changed.) */
135 #define OBJC_ENCODE_INLINE_DEFS 0
136 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
138 /*** Private Interface (procedures) ***/
140 /* Used by compile_file. */
142 static void init_objc (void);
143 static void finish_objc (void);
145 /* Code generation. */
147 static tree objc_build_constructor (tree, tree);
148 static tree build_objc_method_call (int, tree, tree, tree, tree);
149 static tree get_proto_encoding (tree);
150 static tree lookup_interface (tree);
151 static tree objc_add_static_instance (tree, tree);
153 static tree start_class (enum tree_code, tree, tree, tree);
154 static tree continue_class (tree);
155 static void finish_class (tree);
156 static void start_method_def (tree);
158 static void objc_start_function (tree, tree, tree, tree);
160 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
162 static tree start_protocol (enum tree_code, tree, tree);
163 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
164 static tree objc_add_method (tree, tree, int);
165 static tree add_instance_variable (tree, int, tree);
166 static tree build_ivar_reference (tree);
167 static tree is_ivar (tree, tree);
169 static void build_objc_exception_stuff (void);
170 static void build_next_objc_exception_stuff (void);
172 /* We only need the following for ObjC; ObjC++ will use C++'s definition
173 of DERIVED_FROM_P. */
175 static bool objc_derived_from_p (tree, tree);
176 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
178 static void objc_xref_basetypes (tree, tree);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static void build_super_template (void);
184 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
185 static tree get_class_ivars (tree, bool);
186 static tree generate_protocol_list (tree);
187 static void build_protocol_reference (tree);
190 static void objc_generate_cxx_cdtors (void);
193 static const char *synth_id_with_class_suffix (const char *, tree);
195 /* Hash tables to manage the global pool of method prototypes. */
197 hash *nst_method_hash_list = 0;
198 hash *cls_method_hash_list = 0;
200 static hash hash_lookup (hash *, tree);
201 static tree lookup_method (tree, tree);
202 static tree lookup_method_static (tree, tree, int);
206 class_names, /* class, category, protocol, module names */
207 meth_var_names, /* method and variable names */
208 meth_var_types /* method and variable type descriptors */
211 static tree add_objc_string (tree, enum string_section);
212 static tree build_objc_string_decl (enum string_section);
213 static void build_selector_table_decl (void);
215 /* Protocol additions. */
217 static tree lookup_protocol (tree);
218 static tree lookup_and_install_protocols (tree);
222 static void encode_type_qualifiers (tree);
223 static void encode_type (tree, int, int);
224 static void encode_field_decl (tree, int, int);
227 static void really_start_method (tree, tree);
229 static void really_start_method (tree, struct c_arg_info *);
231 static int comp_proto_with_proto (tree, tree, int);
232 static void objc_push_parm (tree);
234 static tree objc_get_parm_info (int);
236 static struct c_arg_info *objc_get_parm_info (int);
239 /* Utilities for debugging and error diagnostics. */
241 static void warn_with_method (const char *, int, tree);
242 static char *gen_type_name (tree);
243 static char *gen_type_name_0 (tree);
244 static char *gen_method_decl (tree);
245 static char *gen_declaration (tree);
247 /* Everything else. */
249 static tree create_field_decl (tree, const char *);
250 static void add_class_reference (tree);
251 static void build_protocol_template (void);
252 static tree encode_method_prototype (tree);
253 static void generate_classref_translation_entry (tree);
254 static void handle_class_ref (tree);
255 static void generate_struct_by_value_array (void)
257 static void mark_referenced_methods (void);
258 static void generate_objc_image_info (void);
260 /*** Private Interface (data) ***/
262 /* Reserved tag definitions. */
264 #define OBJECT_TYPEDEF_NAME "id"
265 #define CLASS_TYPEDEF_NAME "Class"
267 #define TAG_OBJECT "objc_object"
268 #define TAG_CLASS "objc_class"
269 #define TAG_SUPER "objc_super"
270 #define TAG_SELECTOR "objc_selector"
272 #define UTAG_CLASS "_objc_class"
273 #define UTAG_IVAR "_objc_ivar"
274 #define UTAG_IVAR_LIST "_objc_ivar_list"
275 #define UTAG_METHOD "_objc_method"
276 #define UTAG_METHOD_LIST "_objc_method_list"
277 #define UTAG_CATEGORY "_objc_category"
278 #define UTAG_MODULE "_objc_module"
279 #define UTAG_SYMTAB "_objc_symtab"
280 #define UTAG_SUPER "_objc_super"
281 #define UTAG_SELECTOR "_objc_selector"
283 #define UTAG_PROTOCOL "_objc_protocol"
284 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
285 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
287 /* Note that the string object global name is only needed for the
289 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
291 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
293 static const char *TAG_GETCLASS;
294 static const char *TAG_GETMETACLASS;
295 static const char *TAG_MSGSEND;
296 static const char *TAG_MSGSENDSUPER;
297 /* The NeXT Objective-C messenger may have two extra entry points, for use
298 when returning a structure. */
299 static const char *TAG_MSGSEND_STRET;
300 static const char *TAG_MSGSENDSUPER_STRET;
301 static const char *default_constant_string_class_name;
303 /* Runtime metadata flags. */
304 #define CLS_FACTORY 0x0001L
305 #define CLS_META 0x0002L
306 #define CLS_HAS_CXX_STRUCTORS 0x2000L
308 #define OBJC_MODIFIER_STATIC 0x00000001
309 #define OBJC_MODIFIER_FINAL 0x00000002
310 #define OBJC_MODIFIER_PUBLIC 0x00000004
311 #define OBJC_MODIFIER_PRIVATE 0x00000008
312 #define OBJC_MODIFIER_PROTECTED 0x00000010
313 #define OBJC_MODIFIER_NATIVE 0x00000020
314 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
315 #define OBJC_MODIFIER_ABSTRACT 0x00000080
316 #define OBJC_MODIFIER_VOLATILE 0x00000100
317 #define OBJC_MODIFIER_TRANSIENT 0x00000200
318 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
320 /* NeXT-specific tags. */
322 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
323 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
324 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
325 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
326 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
327 #define TAG_EXCEPTIONMATCH "objc_exception_match"
328 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
329 #define TAG_SYNCENTER "objc_sync_enter"
330 #define TAG_SYNCEXIT "objc_sync_exit"
331 #define TAG_SETJMP "_setjmp"
332 #define UTAG_EXCDATA "_objc_exception_data"
334 #define TAG_ASSIGNIVAR "objc_assign_ivar"
335 #define TAG_ASSIGNGLOBAL "objc_assign_global"
336 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
338 /* Branch entry points. All that matters here are the addresses;
339 functions with these names do not really exist in libobjc. */
341 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
342 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
344 #define TAG_CXX_CONSTRUCT ".cxx_construct"
345 #define TAG_CXX_DESTRUCT ".cxx_destruct"
347 /* GNU-specific tags. */
349 #define TAG_EXECCLASS "__objc_exec_class"
350 #define TAG_GNUINIT "__objc_gnu_init"
352 /* Flags for lookup_method_static(). */
353 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
354 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
356 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
357 tree objc_global_trees[OCTI_MAX];
359 static void handle_impent (struct imp_entry *);
361 struct imp_entry *imp_list = 0;
362 int imp_count = 0; /* `@implementation' */
363 int cat_count = 0; /* `@category' */
365 enum tree_code objc_inherit_code;
366 int objc_public_flag;
368 /* Use to generate method labels. */
369 static int method_slot = 0;
373 static char *errbuf; /* Buffer for error diagnostics */
375 /* Data imported from tree.c. */
377 extern enum debug_info_type write_symbols;
379 /* Data imported from toplev.c. */
381 extern const char *dump_base_name;
383 static int flag_typed_selectors;
385 /* Store all constructed constant strings in a hash table so that
386 they get uniqued properly. */
388 struct string_descriptor GTY(())
390 /* The literal argument . */
393 /* The resulting constant string. */
397 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
399 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
400 struct volatilized_type GTY(())
405 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
407 FILE *gen_declaration_file;
409 /* Tells "encode_pointer/encode_aggregate" whether we are generating
410 type descriptors for instance variables (as opposed to methods).
411 Type descriptors for instance variables contain more information
412 than methods (for static typing and embedded structures). */
414 static int generating_instance_variables = 0;
416 /* Some platforms pass small structures through registers versus
417 through an invisible pointer. Determine at what size structure is
418 the transition point between the two possibilities. */
421 generate_struct_by_value_array (void)
424 tree field_decl, field_decl_chain;
426 int aggregate_in_mem[32];
429 /* Presumably no platform passes 32 byte structures in a register. */
430 for (i = 1; i < 32; i++)
434 /* Create an unnamed struct that has `i' character components */
435 type = start_struct (RECORD_TYPE, NULL_TREE);
437 strcpy (buffer, "c1");
438 field_decl = create_field_decl (char_type_node,
440 field_decl_chain = field_decl;
442 for (j = 1; j < i; j++)
444 sprintf (buffer, "c%d", j + 1);
445 field_decl = create_field_decl (char_type_node,
447 chainon (field_decl_chain, field_decl);
449 finish_struct (type, field_decl_chain, NULL_TREE);
451 aggregate_in_mem[i] = aggregate_value_p (type, 0);
452 if (!aggregate_in_mem[i])
456 /* We found some structures that are returned in registers instead of memory
457 so output the necessary data. */
460 for (i = 31; i >= 0; i--)
461 if (!aggregate_in_mem[i])
463 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
465 /* The first member of the structure is always 0 because we don't handle
466 structures with 0 members */
467 printf ("static int struct_forward_array[] = {\n 0");
469 for (j = 1; j <= i; j++)
470 printf (", %d", aggregate_in_mem[j]);
481 if (cxx_init () == false)
483 if (c_objc_common_init () == false)
487 /* If gen_declaration desired, open the output file. */
488 if (flag_gen_declaration)
490 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
491 gen_declaration_file = fopen (dumpname, "w");
492 if (gen_declaration_file == 0)
493 fatal_error ("can't open %s: %m", dumpname);
497 if (flag_next_runtime)
499 TAG_GETCLASS = "objc_getClass";
500 TAG_GETMETACLASS = "objc_getMetaClass";
501 TAG_MSGSEND = "objc_msgSend";
502 TAG_MSGSENDSUPER = "objc_msgSendSuper";
503 TAG_MSGSEND_STRET = "objc_msgSend_stret";
504 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
505 default_constant_string_class_name = "NSConstantString";
509 TAG_GETCLASS = "objc_get_class";
510 TAG_GETMETACLASS = "objc_get_meta_class";
511 TAG_MSGSEND = "objc_msg_lookup";
512 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
513 /* GNU runtime does not provide special functions to support
514 structure-returning methods. */
515 default_constant_string_class_name = "NXConstantString";
516 flag_typed_selectors = 1;
521 if (print_struct_values)
522 generate_struct_by_value_array ();
528 objc_finish_file (void)
530 mark_referenced_methods ();
533 /* We need to instantiate templates _before_ we emit ObjC metadata;
534 if we do not, some metadata (such as selectors) may go missing. */
536 instantiate_pending_templates (0);
539 /* Finalize Objective-C runtime data. No need to generate tables
540 and code if only checking syntax, or if generating a PCH file. */
541 if (!flag_syntax_only && !pch_file)
544 if (gen_declaration_file)
545 fclose (gen_declaration_file);
548 /* Return the first occurrence of a method declaration corresponding
549 to sel_name in rproto_list. Search rproto_list recursively.
550 If is_class is 0, search for instance methods, otherwise for class
553 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
559 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
561 p = TREE_VALUE (rproto);
563 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
565 if ((fnd = lookup_method (is_class
566 ? PROTOCOL_CLS_METHODS (p)
567 : PROTOCOL_NST_METHODS (p), sel_name)))
569 else if (PROTOCOL_LIST (p))
570 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
575 ; /* An identifier...if we could not find a protocol. */
586 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
590 /* Make sure the protocol is supported by the object on the rhs. */
591 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
594 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
596 p = TREE_VALUE (rproto);
598 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
603 else if (PROTOCOL_LIST (p))
604 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
613 ; /* An identifier...if we could not find a protocol. */
620 objc_start_class_interface (tree class, tree super_class, tree protos)
622 objc_interface_context
624 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
625 objc_public_flag = 0;
629 objc_start_category_interface (tree class, tree categ, tree protos)
631 objc_interface_context
632 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
634 = continue_class (objc_interface_context);
638 objc_start_protocol (tree name, tree protos)
640 objc_interface_context
641 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
645 objc_continue_interface (void)
648 = continue_class (objc_interface_context);
652 objc_finish_interface (void)
654 finish_class (objc_interface_context);
655 objc_interface_context = NULL_TREE;
659 objc_start_class_implementation (tree class, tree super_class)
661 objc_implementation_context
663 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
664 objc_public_flag = 0;
668 objc_start_category_implementation (tree class, tree categ)
670 objc_implementation_context
671 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
673 = continue_class (objc_implementation_context);
677 objc_continue_implementation (void)
680 = continue_class (objc_implementation_context);
684 objc_finish_implementation (void)
687 if (flag_objc_call_cxx_cdtors)
688 objc_generate_cxx_cdtors ();
691 if (objc_implementation_context)
693 finish_class (objc_implementation_context);
694 objc_ivar_chain = NULL_TREE;
695 objc_implementation_context = NULL_TREE;
698 warning (0, "%<@end%> must appear in an @implementation context");
702 objc_set_visibility (int visibility)
704 objc_public_flag = visibility;
708 objc_set_method_type (enum tree_code type)
710 objc_inherit_code = (type == PLUS_EXPR
712 : INSTANCE_METHOD_DECL);
716 objc_build_method_signature (tree rettype, tree selector,
717 tree optparms, bool ellipsis)
719 return build_method_decl (objc_inherit_code, rettype, selector,
724 objc_add_method_declaration (tree decl)
726 if (!objc_interface_context)
727 fatal_error ("method declaration not in @interface context");
729 objc_add_method (objc_interface_context,
731 objc_inherit_code == CLASS_METHOD_DECL);
735 objc_start_method_definition (tree decl)
737 if (!objc_implementation_context)
738 fatal_error ("method definition not in @implementation context");
740 objc_add_method (objc_implementation_context,
742 objc_inherit_code == CLASS_METHOD_DECL);
743 start_method_def (decl);
747 objc_add_instance_variable (tree decl)
749 (void) add_instance_variable (objc_ivar_context,
754 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
758 objc_is_reserved_word (tree ident)
760 unsigned char code = C_RID_CODE (ident);
762 return (OBJC_IS_AT_KEYWORD (code)
764 || code == RID_CLASS || code == RID_PUBLIC
765 || code == RID_PROTECTED || code == RID_PRIVATE
766 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
771 /* Return true if TYPE is 'id'. */
774 objc_is_object_id (tree type)
776 return OBJC_TYPE_NAME (type) == objc_object_id;
780 objc_is_class_id (tree type)
782 return OBJC_TYPE_NAME (type) == objc_class_id;
785 /* Construct a C struct with same name as CLASS, a base struct with tag
786 SUPER_NAME (if any), and FIELDS indicated. */
789 objc_build_struct (tree class, tree fields, tree super_name)
791 tree name = CLASS_NAME (class);
792 tree s = start_struct (RECORD_TYPE, name);
793 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
794 tree t, objc_info = NULL_TREE;
798 /* Prepend a packed variant of the base class into the layout. This
799 is necessary to preserve ObjC ABI compatibility. */
800 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
801 tree field = TYPE_FIELDS (super);
803 while (field && TREE_CHAIN (field)
804 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
805 field = TREE_CHAIN (field);
807 /* For ObjC ABI purposes, the "packed" size of a base class is the
808 the sum of the offset and the size (in bits) of the last field
811 = (field && TREE_CODE (field) == FIELD_DECL
812 ? size_binop (PLUS_EXPR,
813 size_binop (PLUS_EXPR,
816 convert (bitsizetype,
817 DECL_FIELD_OFFSET (field)),
818 bitsize_int (BITS_PER_UNIT)),
819 DECL_FIELD_BIT_OFFSET (field)),
821 : bitsize_zero_node);
822 DECL_SIZE_UNIT (base)
823 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
824 size_int (BITS_PER_UNIT));
825 DECL_ARTIFICIAL (base) = 1;
826 DECL_ALIGN (base) = 1;
827 DECL_FIELD_CONTEXT (base) = s;
829 DECL_FIELD_IS_BASE (base) = 1;
832 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
833 #endif /* are following the ObjC ABI here. */
834 TREE_CHAIN (base) = fields;
838 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
839 in all variants of this RECORD_TYPE to be clobbered, but it is therein
840 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
841 Hence, we must squirrel away the ObjC-specific information before calling
842 finish_struct(), and then reinstate it afterwards. */
844 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
846 = chainon (objc_info,
847 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
849 /* Point the struct at its related Objective-C class. */
850 INIT_TYPE_OBJC_INFO (s);
851 TYPE_OBJC_INTERFACE (s) = class;
853 s = finish_struct (s, fields, NULL_TREE);
855 for (t = TYPE_NEXT_VARIANT (s); t;
856 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
858 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
859 /* Replace the IDENTIFIER_NODE with an actual @interface. */
860 TYPE_OBJC_INTERFACE (t) = class;
863 /* Use TYPE_BINFO structures to point at the super class, if any. */
864 objc_xref_basetypes (s, super);
866 /* Mark this struct as a class template. */
867 CLASS_STATIC_TEMPLATE (class) = s;
872 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
873 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
876 objc_build_volatilized_type (tree type)
880 /* Check if we have not constructed the desired variant already. */
881 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
883 /* The type qualifiers must (obviously) match up. */
884 if (!TYPE_VOLATILE (t)
885 || (TYPE_READONLY (t) != TYPE_READONLY (type))
886 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
889 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
890 info, if any) must match up. */
891 if (POINTER_TYPE_P (t)
892 && (TREE_TYPE (t) != TREE_TYPE (type)))
895 /* Everything matches up! */
899 /* Ok, we could not re-use any of the pre-existing variants. Create
901 t = build_variant_type_copy (type);
902 TYPE_VOLATILE (t) = 1;
904 /* Set up the canonical type information. */
905 if (TYPE_STRUCTURAL_EQUALITY_P (type))
906 SET_TYPE_STRUCTURAL_EQUALITY (t);
907 else if (TYPE_CANONICAL (type) != type)
908 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
910 TYPE_CANONICAL (t) = t;
915 /* Mark DECL as being 'volatile' for purposes of Darwin
916 _setjmp()/_longjmp() exception handling. Called from
917 objc_mark_locals_volatile(). */
919 objc_volatilize_decl (tree decl)
921 /* Do not mess with variables that are 'static' or (already)
923 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
924 && (TREE_CODE (decl) == VAR_DECL
925 || TREE_CODE (decl) == PARM_DECL))
927 tree t = TREE_TYPE (decl);
928 struct volatilized_type key;
931 t = objc_build_volatilized_type (t);
933 loc = htab_find_slot (volatilized_htab, &key, INSERT);
937 *loc = ggc_alloc (sizeof (key));
938 ((struct volatilized_type *) *loc)->type = t;
941 TREE_TYPE (decl) = t;
942 TREE_THIS_VOLATILE (decl) = 1;
943 TREE_SIDE_EFFECTS (decl) = 1;
944 DECL_REGISTER (decl) = 0;
946 C_DECL_REGISTER (decl) = 0;
951 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
952 (including its categories and superclasses) or by object type TYP.
953 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
956 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
958 bool class_type = (cls != NULL_TREE);
964 /* Check protocols adopted by the class and its categories. */
965 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
967 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
971 /* Repeat for superclasses. */
972 cls = lookup_interface (CLASS_SUPER_NAME (cls));
975 /* Check for any protocols attached directly to the object type. */
976 if (TYPE_HAS_OBJC_INFO (typ))
978 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
984 strcpy (errbuf, class_type ? "class \'" : "type \'");
985 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
986 strcat (errbuf, "\' does not ");
987 /* NB: Types 'id' and 'Class' cannot reasonably be described as
988 "implementing" a given protocol, since they do not have an
990 strcat (errbuf, class_type ? "implement" : "conform to");
991 strcat (errbuf, " the \'");
992 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
993 strcat (errbuf, "\' protocol");
1000 /* Check if class RCLS and instance struct type RTYP conform to at least the
1001 same protocols that LCLS and LTYP conform to. */
1004 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1007 bool have_lproto = false;
1011 /* NB: We do _not_ look at categories defined for LCLS; these may or
1012 may not get loaded in, and therefore it is unreasonable to require
1013 that RCLS/RTYP must implement any of their protocols. */
1014 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1018 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1022 /* Repeat for superclasses. */
1023 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1026 /* Check for any protocols attached directly to the object type. */
1027 if (TYPE_HAS_OBJC_INFO (ltyp))
1029 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1033 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1038 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1039 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1040 away with simply checking for 'id' or 'Class' (!RCLS), since this
1041 routine will not get called in other cases. */
1042 return have_lproto || (rcls != NULL_TREE);
1045 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1046 an instance of RTYP to an instance of LTYP or to compare the two
1047 (if ARGNO is equal to -3), per ObjC type system rules. Before
1048 returning 'true', this routine may issue warnings related to, e.g.,
1049 protocol conformance. When returning 'false', the routine must
1050 produce absolutely no warnings; the C or C++ front-end will do so
1051 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1052 the routine must return 'false'.
1054 The ARGNO parameter is encoded as follows:
1055 >= 1 Parameter number (CALLEE contains function being called);
1059 -3 Comparison (LTYP and RTYP may match in either direction). */
1062 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1064 tree lcls, rcls, lproto, rproto;
1065 bool pointers_compatible;
1067 /* We must be dealing with pointer types */
1068 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1073 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1074 rtyp = TREE_TYPE (rtyp);
1076 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1078 /* Past this point, we are only interested in ObjC class instances,
1079 or 'id' or 'Class'. */
1080 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1083 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1084 && !TYPE_HAS_OBJC_INFO (ltyp))
1087 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1088 && !TYPE_HAS_OBJC_INFO (rtyp))
1091 /* Past this point, we are committed to returning 'true' to the caller.
1092 However, we can still warn about type and/or protocol mismatches. */
1094 if (TYPE_HAS_OBJC_INFO (ltyp))
1096 lcls = TYPE_OBJC_INTERFACE (ltyp);
1097 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1100 lcls = lproto = NULL_TREE;
1102 if (TYPE_HAS_OBJC_INFO (rtyp))
1104 rcls = TYPE_OBJC_INTERFACE (rtyp);
1105 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1108 rcls = rproto = NULL_TREE;
1110 /* If we could not find an @interface declaration, we must have
1111 only seen a @class declaration; for purposes of type comparison,
1112 treat it as a stand-alone (root) class. */
1114 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1117 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1120 /* If either type is an unqualified 'id', we're done. */
1121 if ((!lproto && objc_is_object_id (ltyp))
1122 || (!rproto && objc_is_object_id (rtyp)))
1125 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1127 /* If the underlying types are the same, and at most one of them has
1128 a protocol list, we do not need to issue any diagnostics. */
1129 if (pointers_compatible && (!lproto || !rproto))
1132 /* If exactly one of the types is 'Class', issue a diagnostic; any
1133 exceptions of this rule have already been handled. */
1134 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1135 pointers_compatible = false;
1136 /* Otherwise, check for inheritance relations. */
1139 if (!pointers_compatible)
1141 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1143 if (!pointers_compatible)
1144 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1146 if (!pointers_compatible && argno == -3)
1147 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1150 /* If the pointers match modulo protocols, check for protocol conformance
1152 if (pointers_compatible)
1154 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1157 if (!pointers_compatible && argno == -3)
1158 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1162 if (!pointers_compatible)
1164 /* NB: For the time being, we shall make our warnings look like their
1165 C counterparts. In the future, we may wish to make them more
1170 warning (0, "comparison of distinct Objective-C types lacks a cast");
1174 warning (0, "initialization from distinct Objective-C type");
1178 warning (0, "assignment from distinct Objective-C type");
1182 warning (0, "distinct Objective-C type in return");
1186 warning (0, "passing argument %d of %qE from distinct "
1187 "Objective-C type", argno, callee);
1195 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1196 lives in the volatilized hash table, ignore the 'volatile' bit when
1197 making the comparison. */
1200 objc_type_quals_match (tree ltyp, tree rtyp)
1202 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1203 struct volatilized_type key;
1207 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1208 lquals &= ~TYPE_QUAL_VOLATILE;
1212 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1213 rquals &= ~TYPE_QUAL_VOLATILE;
1215 return (lquals == rquals);
1219 /* Determine if CHILD is derived from PARENT. The routine assumes that
1220 both parameters are RECORD_TYPEs, and is non-reflexive. */
1223 objc_derived_from_p (tree parent, tree child)
1225 parent = TYPE_MAIN_VARIANT (parent);
1227 for (child = TYPE_MAIN_VARIANT (child);
1228 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1230 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1231 (TYPE_BINFO (child),
1234 if (child == parent)
1243 objc_build_component_ref (tree datum, tree component)
1245 /* If COMPONENT is NULL, the caller is referring to the anonymous
1246 base class field. */
1249 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1251 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1254 /* The 'build_component_ref' routine has been removed from the C++
1255 front-end, but 'finish_class_member_access_expr' seems to be
1256 a worthy substitute. */
1258 return finish_class_member_access_expr (datum, component, false);
1260 return build_component_ref (datum, component);
1264 /* Recursively copy inheritance information rooted at BINFO. To do this,
1265 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1268 objc_copy_binfo (tree binfo)
1270 tree btype = BINFO_TYPE (binfo);
1271 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1275 BINFO_TYPE (binfo2) = btype;
1276 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1277 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1279 /* Recursively copy base binfos of BINFO. */
1280 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1282 tree base_binfo2 = objc_copy_binfo (base_binfo);
1284 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1285 BINFO_BASE_APPEND (binfo2, base_binfo2);
1291 /* Record superclass information provided in BASETYPE for ObjC class REF.
1292 This is loosely based on cp/decl.c:xref_basetypes(). */
1295 objc_xref_basetypes (tree ref, tree basetype)
1297 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1299 TYPE_BINFO (ref) = binfo;
1300 BINFO_OFFSET (binfo) = size_zero_node;
1301 BINFO_TYPE (binfo) = ref;
1305 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1307 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1308 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1309 BINFO_BASE_APPEND (binfo, base_binfo);
1310 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1315 volatilized_hash (const void *ptr)
1317 const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1319 return htab_hash_pointer(typ);
1323 volatilized_eq (const void *ptr1, const void *ptr2)
1325 const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1326 const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1328 return typ1 == typ2;
1331 /* Called from finish_decl. */
1334 objc_check_decl (tree decl)
1336 tree type = TREE_TYPE (decl);
1338 if (TREE_CODE (type) != RECORD_TYPE)
1340 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1341 error ("statically allocated instance of Objective-C class %qs",
1342 IDENTIFIER_POINTER (type));
1345 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1346 either name an Objective-C class, or refer to the special 'id' or 'Class'
1347 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1350 objc_get_protocol_qualified_type (tree interface, tree protocols)
1352 /* If INTERFACE is not provided, default to 'id'. */
1353 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1354 bool is_ptr = (type != NULL_TREE);
1358 type = objc_is_class_name (interface);
1361 type = xref_tag (RECORD_TYPE, type);
1368 type = build_variant_type_copy (type);
1370 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1374 tree orig_pointee_type = TREE_TYPE (type);
1375 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1377 /* Set up the canonical type information. */
1378 TYPE_CANONICAL (type)
1379 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1381 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1382 type = TREE_TYPE (type);
1385 /* Look up protocols and install in lang specific list. */
1386 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1387 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1389 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1390 return the pointer to the new pointee variant. */
1392 type = TYPE_POINTER_TO (type);
1394 TYPE_OBJC_INTERFACE (type)
1395 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1401 /* Check for circular dependencies in protocols. The arguments are
1402 PROTO, the protocol to check, and LIST, a list of protocol it
1406 check_protocol_recursively (tree proto, tree list)
1410 for (p = list; p; p = TREE_CHAIN (p))
1412 tree pp = TREE_VALUE (p);
1414 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1415 pp = lookup_protocol (pp);
1418 fatal_error ("protocol %qs has circular dependency",
1419 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1421 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1425 /* Look up PROTOCOLS, and return a list of those that are found.
1426 If none are found, return NULL. */
1429 lookup_and_install_protocols (tree protocols)
1432 tree return_value = NULL_TREE;
1434 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1436 tree ident = TREE_VALUE (proto);
1437 tree p = lookup_protocol (ident);
1440 return_value = chainon (return_value,
1441 build_tree_list (NULL_TREE, p));
1442 else if (ident != error_mark_node)
1443 error ("cannot find protocol declaration for %qs",
1444 IDENTIFIER_POINTER (ident));
1447 return return_value;
1450 /* Create a declaration for field NAME of a given TYPE. */
1453 create_field_decl (tree type, const char *name)
1455 return build_decl (FIELD_DECL, get_identifier (name), type);
1458 /* Create a global, static declaration for variable NAME of a given TYPE. The
1459 finish_var_decl() routine will need to be called on it afterwards. */
1462 start_var_decl (tree type, const char *name)
1464 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1466 TREE_STATIC (var) = 1;
1467 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1468 DECL_IGNORED_P (var) = 1;
1469 DECL_ARTIFICIAL (var) = 1;
1470 DECL_CONTEXT (var) = NULL_TREE;
1472 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1478 /* Finish off the variable declaration created by start_var_decl(). */
1481 finish_var_decl (tree var, tree initializer)
1483 finish_decl (var, initializer, NULL_TREE);
1484 /* Ensure that the variable actually gets output. */
1485 mark_decl_referenced (var);
1486 /* Mark the decl to avoid "defined but not used" warning. */
1487 TREE_USED (var) = 1;
1490 /* Find the decl for the constant string class reference. This is only
1491 used for the NeXT runtime. */
1494 setup_string_decl (void)
1499 /* %s in format will provide room for terminating null */
1500 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1501 + strlen (constant_string_class_name);
1502 name = xmalloc (length);
1503 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1504 constant_string_class_name);
1505 constant_string_global_id = get_identifier (name);
1506 string_class_decl = lookup_name (constant_string_global_id);
1508 return string_class_decl;
1511 /* Purpose: "play" parser, creating/installing representations
1512 of the declarations that are required by Objective-C.
1516 type_spec--------->sc_spec
1517 (tree_list) (tree_list)
1520 identifier_node identifier_node */
1523 synth_module_prologue (void)
1526 enum debug_info_type save_write_symbols = write_symbols;
1527 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1529 /* Suppress outputting debug symbols, because
1530 dbxout_init hasn'r been called yet. */
1531 write_symbols = NO_DEBUG;
1532 debug_hooks = &do_nothing_debug_hooks;
1535 push_lang_context (lang_name_c); /* extern "C" */
1538 /* The following are also defined in <objc/objc.h> and friends. */
1540 objc_object_id = get_identifier (TAG_OBJECT);
1541 objc_class_id = get_identifier (TAG_CLASS);
1543 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1544 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1546 objc_object_type = build_pointer_type (objc_object_reference);
1547 objc_class_type = build_pointer_type (objc_class_reference);
1549 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1550 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1552 /* Declare the 'id' and 'Class' typedefs. */
1554 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1557 DECL_IN_SYSTEM_HEADER (type) = 1;
1558 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1561 DECL_IN_SYSTEM_HEADER (type) = 1;
1563 /* Forward-declare '@interface Protocol'. */
1565 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1566 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1567 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1570 /* Declare type of selector-objects that represent an operation name. */
1572 if (flag_next_runtime)
1573 /* `struct objc_selector *' */
1575 = build_pointer_type (xref_tag (RECORD_TYPE,
1576 get_identifier (TAG_SELECTOR)));
1578 /* `const struct objc_selector *' */
1580 = build_pointer_type
1581 (build_qualified_type (xref_tag (RECORD_TYPE,
1582 get_identifier (TAG_SELECTOR)),
1585 /* Declare receiver type used for dispatching messages to 'super'. */
1587 /* `struct objc_super *' */
1588 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1589 get_identifier (TAG_SUPER)));
1591 /* Declare pointers to method and ivar lists. */
1592 objc_method_list_ptr = build_pointer_type
1593 (xref_tag (RECORD_TYPE,
1594 get_identifier (UTAG_METHOD_LIST)));
1595 objc_method_proto_list_ptr
1596 = build_pointer_type (xref_tag (RECORD_TYPE,
1597 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1598 objc_ivar_list_ptr = build_pointer_type
1599 (xref_tag (RECORD_TYPE,
1600 get_identifier (UTAG_IVAR_LIST)));
1602 /* TREE_NOTHROW is cleared for the message-sending functions,
1603 because the function that gets called can throw in Obj-C++, or
1604 could itself call something that can throw even in Obj-C. */
1606 if (flag_next_runtime)
1608 /* NB: In order to call one of the ..._stret (struct-returning)
1609 functions, the function *MUST* first be cast to a signature that
1610 corresponds to the actual ObjC method being invoked. This is
1611 what is done by the build_objc_method_call() routine below. */
1613 /* id objc_msgSend (id, SEL, ...); */
1614 /* id objc_msgSendNonNil (id, SEL, ...); */
1615 /* id objc_msgSend_stret (id, SEL, ...); */
1616 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1618 = build_function_type (objc_object_type,
1619 tree_cons (NULL_TREE, objc_object_type,
1620 tree_cons (NULL_TREE, objc_selector_type,
1622 umsg_decl = add_builtin_function (TAG_MSGSEND,
1623 type, 0, NOT_BUILT_IN,
1625 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1626 type, 0, NOT_BUILT_IN,
1628 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1629 type, 0, NOT_BUILT_IN,
1631 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1632 type, 0, NOT_BUILT_IN,
1635 /* These can throw, because the function that gets called can throw
1636 in Obj-C++, or could itself call something that can throw even
1638 TREE_NOTHROW (umsg_decl) = 0;
1639 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1640 TREE_NOTHROW (umsg_stret_decl) = 0;
1641 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1643 /* id objc_msgSend_Fast (id, SEL, ...)
1644 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1645 #ifdef OFFS_MSGSEND_FAST
1646 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1647 type, 0, NOT_BUILT_IN,
1649 TREE_NOTHROW (umsg_fast_decl) = 0;
1650 DECL_ATTRIBUTES (umsg_fast_decl)
1651 = tree_cons (get_identifier ("hard_coded_address"),
1652 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1655 /* No direct dispatch available. */
1656 umsg_fast_decl = umsg_decl;
1659 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1660 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1662 = build_function_type (objc_object_type,
1663 tree_cons (NULL_TREE, objc_super_type,
1664 tree_cons (NULL_TREE, objc_selector_type,
1666 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1667 type, 0, NOT_BUILT_IN,
1669 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1670 type, 0, NOT_BUILT_IN, 0,
1672 TREE_NOTHROW (umsg_super_decl) = 0;
1673 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1677 /* GNU runtime messenger entry points. */
1679 /* typedef id (*IMP)(id, SEL, ...); */
1681 = build_pointer_type
1682 (build_function_type (objc_object_type,
1683 tree_cons (NULL_TREE, objc_object_type,
1684 tree_cons (NULL_TREE, objc_selector_type,
1687 /* IMP objc_msg_lookup (id, SEL); */
1689 = build_function_type (IMP_type,
1690 tree_cons (NULL_TREE, objc_object_type,
1691 tree_cons (NULL_TREE, objc_selector_type,
1692 OBJC_VOID_AT_END)));
1693 umsg_decl = add_builtin_function (TAG_MSGSEND,
1694 type, 0, NOT_BUILT_IN,
1696 TREE_NOTHROW (umsg_decl) = 0;
1698 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1700 = build_function_type (IMP_type,
1701 tree_cons (NULL_TREE, objc_super_type,
1702 tree_cons (NULL_TREE, objc_selector_type,
1703 OBJC_VOID_AT_END)));
1704 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1705 type, 0, NOT_BUILT_IN,
1707 TREE_NOTHROW (umsg_super_decl) = 0;
1709 /* The following GNU runtime entry point is called to initialize
1712 __objc_exec_class (void *); */
1714 = build_function_type (void_type_node,
1715 tree_cons (NULL_TREE, ptr_type_node,
1717 execclass_decl = add_builtin_function (TAG_EXECCLASS,
1718 type, 0, NOT_BUILT_IN,
1722 /* id objc_getClass (const char *); */
1724 type = build_function_type (objc_object_type,
1725 tree_cons (NULL_TREE,
1726 const_string_type_node,
1730 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1733 /* id objc_getMetaClass (const char *); */
1735 objc_get_meta_class_decl
1736 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1738 build_class_template ();
1739 build_super_template ();
1740 build_protocol_template ();
1741 build_category_template ();
1742 build_objc_exception_stuff ();
1744 if (flag_next_runtime)
1745 build_next_objc_exception_stuff ();
1747 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1749 if (! flag_next_runtime)
1750 build_selector_table_decl ();
1752 /* Forward declare constant_string_id and constant_string_type. */
1753 if (!constant_string_class_name)
1754 constant_string_class_name = default_constant_string_class_name;
1756 constant_string_id = get_identifier (constant_string_class_name);
1757 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1759 /* Pre-build the following entities - for speed/convenience. */
1760 self_id = get_identifier ("self");
1761 ucmd_id = get_identifier ("_cmd");
1764 pop_lang_context ();
1767 write_symbols = save_write_symbols;
1768 debug_hooks = save_hooks;
1771 /* Ensure that the ivar list for NSConstantString/NXConstantString
1772 (or whatever was specified via `-fconstant-string-class')
1773 contains fields at least as large as the following three, so that
1774 the runtime can stomp on them with confidence:
1776 struct STRING_OBJECT_CLASS_NAME
1780 unsigned int length;
1784 check_string_class_template (void)
1786 tree field_decl = objc_get_class_ivars (constant_string_id);
1788 #define AT_LEAST_AS_LARGE_AS(F, T) \
1789 (F && TREE_CODE (F) == FIELD_DECL \
1790 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1791 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1793 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1796 field_decl = TREE_CHAIN (field_decl);
1797 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1800 field_decl = TREE_CHAIN (field_decl);
1801 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1803 #undef AT_LEAST_AS_LARGE_AS
1806 /* Avoid calling `check_string_class_template ()' more than once. */
1807 static GTY(()) int string_layout_checked;
1809 /* Construct an internal string layout to be used as a template for
1810 creating NSConstantString/NXConstantString instances. */
1813 objc_build_internal_const_str_type (void)
1815 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1816 tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1817 tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1819 TREE_CHAIN (field) = fields; fields = field;
1820 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1821 TREE_CHAIN (field) = fields; fields = field;
1822 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1824 finish_builtin_struct (type, "__builtin_ObjCString",
1830 /* Custom build_string which sets TREE_TYPE! */
1833 my_build_string (int len, const char *str)
1835 return fix_string_type (build_string (len, str));
1838 /* Build a string with contents STR and length LEN and convert it to a
1842 my_build_string_pointer (int len, const char *str)
1844 tree string = my_build_string (len, str);
1845 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1846 return build1 (ADDR_EXPR, ptrtype, string);
1850 string_hash (const void *ptr)
1852 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1853 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1854 int i, len = TREE_STRING_LENGTH (str);
1857 for (i = 0; i < len; i++)
1858 h = ((h * 613) + p[i]);
1864 string_eq (const void *ptr1, const void *ptr2)
1866 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
1867 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
1868 int len1 = TREE_STRING_LENGTH (str1);
1870 return (len1 == TREE_STRING_LENGTH (str2)
1871 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1875 /* Given a chain of STRING_CST's, build a static instance of
1876 NXConstantString which points at the concatenation of those
1877 strings. We place the string object in the __string_objects
1878 section of the __OBJC segment. The Objective-C runtime will
1879 initialize the isa pointers of the string objects to point at the
1880 NXConstantString class object. */
1883 objc_build_string_object (tree string)
1885 tree initlist, constructor, constant_string_class;
1888 struct string_descriptor *desc, key;
1891 /* Prep the string argument. */
1892 string = fix_string_type (string);
1893 TREE_SET_CODE (string, STRING_CST);
1894 length = TREE_STRING_LENGTH (string) - 1;
1896 /* Check whether the string class being used actually exists and has the
1897 correct ivar layout. */
1898 if (!string_layout_checked)
1900 string_layout_checked = -1;
1901 constant_string_class = lookup_interface (constant_string_id);
1902 internal_const_str_type = objc_build_internal_const_str_type ();
1904 if (!constant_string_class
1905 || !(constant_string_type
1906 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1907 error ("cannot find interface declaration for %qs",
1908 IDENTIFIER_POINTER (constant_string_id));
1909 /* The NSConstantString/NXConstantString ivar layout is now known. */
1910 else if (!check_string_class_template ())
1911 error ("interface %qs does not have valid constant string layout",
1912 IDENTIFIER_POINTER (constant_string_id));
1913 /* For the NeXT runtime, we can generate a literal reference
1914 to the string class, don't need to run a constructor. */
1915 else if (flag_next_runtime && !setup_string_decl ())
1916 error ("cannot find reference tag for class %qs",
1917 IDENTIFIER_POINTER (constant_string_id));
1920 string_layout_checked = 1; /* Success! */
1921 add_class_reference (constant_string_id);
1925 if (string_layout_checked == -1)
1926 return error_mark_node;
1928 /* Perhaps we already constructed a constant string just like this one? */
1929 key.literal = string;
1930 loc = htab_find_slot (string_htab, &key, INSERT);
1936 *loc = desc = ggc_alloc (sizeof (*desc));
1937 desc->literal = string;
1939 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1940 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1941 fields = TYPE_FIELDS (internal_const_str_type);
1943 = build_tree_list (fields,
1945 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1946 : build_int_cst (NULL_TREE, 0));
1947 fields = TREE_CHAIN (fields);
1948 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1950 fields = TREE_CHAIN (fields);
1951 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1953 constructor = objc_build_constructor (internal_const_str_type,
1954 nreverse (initlist));
1955 TREE_INVARIANT (constructor) = true;
1957 if (!flag_next_runtime)
1959 = objc_add_static_instance (constructor, constant_string_type);
1962 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1963 DECL_INITIAL (var) = constructor;
1964 TREE_STATIC (var) = 1;
1965 pushdecl_top_level (var);
1968 desc->constructor = constructor;
1971 addr = convert (build_pointer_type (constant_string_type),
1972 build_unary_op (ADDR_EXPR, desc->constructor, 1));
1977 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1979 static GTY(()) int num_static_inst;
1982 objc_add_static_instance (tree constructor, tree class_decl)
1987 /* Find the list of static instances for the CLASS_DECL. Create one if
1989 for (chain = &objc_static_instances;
1990 *chain && TREE_VALUE (*chain) != class_decl;
1991 chain = &TREE_CHAIN (*chain));
1994 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1995 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1998 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1999 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
2000 DECL_COMMON (decl) = 1;
2001 TREE_STATIC (decl) = 1;
2002 DECL_ARTIFICIAL (decl) = 1;
2003 TREE_USED (decl) = 1;
2004 DECL_INITIAL (decl) = constructor;
2006 /* We may be writing something else just now.
2007 Postpone till end of input. */
2008 DECL_DEFER_OUTPUT (decl) = 1;
2009 pushdecl_top_level (decl);
2010 rest_of_decl_compilation (decl, 1, 0);
2012 /* Add the DECL to the head of this CLASS' list. */
2013 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2018 /* Build a static constant CONSTRUCTOR
2019 with type TYPE and elements ELTS. */
2022 objc_build_constructor (tree type, tree elts)
2024 tree constructor = build_constructor_from_list (type, elts);
2026 TREE_CONSTANT (constructor) = 1;
2027 TREE_STATIC (constructor) = 1;
2028 TREE_READONLY (constructor) = 1;
2031 /* Adjust for impedance mismatch. We should figure out how to build
2032 CONSTRUCTORs that consistently please both the C and C++ gods. */
2033 if (!TREE_PURPOSE (elts))
2034 TREE_TYPE (constructor) = NULL_TREE;
2035 TREE_HAS_CONSTRUCTOR (constructor) = 1;
2041 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2043 /* Predefine the following data type:
2051 void *defs[cls_def_cnt + cat_def_cnt];
2055 build_objc_symtab_template (void)
2057 tree field_decl, field_decl_chain;
2059 objc_symtab_template
2060 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
2062 /* long sel_ref_cnt; */
2063 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2064 field_decl_chain = field_decl;
2067 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2069 chainon (field_decl_chain, field_decl);
2071 /* short cls_def_cnt; */
2072 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2073 chainon (field_decl_chain, field_decl);
2075 /* short cat_def_cnt; */
2076 field_decl = create_field_decl (short_integer_type_node,
2078 chainon (field_decl_chain, field_decl);
2080 if (imp_count || cat_count || !flag_next_runtime)
2082 /* void *defs[imp_count + cat_count (+ 1)]; */
2083 /* NB: The index is one less than the size of the array. */
2084 int index = imp_count + cat_count
2085 + (flag_next_runtime? -1: 0);
2086 field_decl = create_field_decl
2089 build_index_type (build_int_cst (NULL_TREE, index))),
2091 chainon (field_decl_chain, field_decl);
2094 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
2097 /* Create the initial value for the `defs' field of _objc_symtab.
2098 This is a CONSTRUCTOR. */
2101 init_def_list (tree type)
2103 tree expr, initlist = NULL_TREE;
2104 struct imp_entry *impent;
2107 for (impent = imp_list; impent; impent = impent->next)
2109 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2111 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2112 initlist = tree_cons (NULL_TREE, expr, initlist);
2117 for (impent = imp_list; impent; impent = impent->next)
2119 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2121 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2122 initlist = tree_cons (NULL_TREE, expr, initlist);
2126 if (!flag_next_runtime)
2128 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2131 if (static_instances_decl)
2132 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
2134 expr = build_int_cst (NULL_TREE, 0);
2136 initlist = tree_cons (NULL_TREE, expr, initlist);
2139 return objc_build_constructor (type, nreverse (initlist));
2142 /* Construct the initial value for all of _objc_symtab. */
2145 init_objc_symtab (tree type)
2149 /* sel_ref_cnt = { ..., 5, ... } */
2151 initlist = build_tree_list (NULL_TREE,
2152 build_int_cst (long_integer_type_node, 0));
2154 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2156 if (flag_next_runtime || ! sel_ref_chain)
2157 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2160 = tree_cons (NULL_TREE,
2161 convert (build_pointer_type (objc_selector_type),
2162 build_unary_op (ADDR_EXPR,
2163 UOBJC_SELECTOR_TABLE_decl, 1)),
2166 /* cls_def_cnt = { ..., 5, ... } */
2168 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2170 /* cat_def_cnt = { ..., 5, ... } */
2172 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2174 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2176 if (imp_count || cat_count || !flag_next_runtime)
2179 tree field = TYPE_FIELDS (type);
2180 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2182 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2186 return objc_build_constructor (type, nreverse (initlist));
2189 /* Generate forward declarations for metadata such as
2190 'OBJC_CLASS_...'. */
2193 build_metadata_decl (const char *name, tree type)
2197 /* struct TYPE NAME_<name>; */
2198 decl = start_var_decl (type, synth_id_with_class_suffix
2200 objc_implementation_context));
2205 /* Push forward-declarations of all the categories so that
2206 init_def_list can use them in a CONSTRUCTOR. */
2209 forward_declare_categories (void)
2211 struct imp_entry *impent;
2212 tree sav = objc_implementation_context;
2214 for (impent = imp_list; impent; impent = impent->next)
2216 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2218 /* Set an invisible arg to synth_id_with_class_suffix. */
2219 objc_implementation_context = impent->imp_context;
2220 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2221 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2222 objc_category_template);
2225 objc_implementation_context = sav;
2228 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2229 and initialized appropriately. */
2232 generate_objc_symtab_decl (void)
2234 /* forward declare categories */
2236 forward_declare_categories ();
2238 build_objc_symtab_template ();
2239 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2240 finish_var_decl (UOBJC_SYMBOLS_decl,
2241 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2245 init_module_descriptor (tree type)
2247 tree initlist, expr;
2249 /* version = { 1, ... } */
2251 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2252 initlist = build_tree_list (NULL_TREE, expr);
2254 /* size = { ..., sizeof (struct _objc_module), ... } */
2256 expr = convert (long_integer_type_node,
2257 size_in_bytes (objc_module_template));
2258 initlist = tree_cons (NULL_TREE, expr, initlist);
2260 /* Don't provide any file name for security reasons. */
2261 /* name = { ..., "", ... } */
2263 expr = add_objc_string (get_identifier (""), class_names);
2264 initlist = tree_cons (NULL_TREE, expr, initlist);
2266 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2268 if (UOBJC_SYMBOLS_decl)
2269 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2271 expr = build_int_cst (NULL_TREE, 0);
2272 initlist = tree_cons (NULL_TREE, expr, initlist);
2274 return objc_build_constructor (type, nreverse (initlist));
2277 /* Write out the data structures to describe Objective C classes defined.
2279 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2282 build_module_descriptor (void)
2284 tree field_decl, field_decl_chain;
2287 push_lang_context (lang_name_c); /* extern "C" */
2290 objc_module_template
2291 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2294 field_decl = create_field_decl (long_integer_type_node, "version");
2295 field_decl_chain = field_decl;
2298 field_decl = create_field_decl (long_integer_type_node, "size");
2299 chainon (field_decl_chain, field_decl);
2302 field_decl = create_field_decl (string_type_node, "name");
2303 chainon (field_decl_chain, field_decl);
2305 /* struct _objc_symtab *symtab; */
2307 = create_field_decl (build_pointer_type
2308 (xref_tag (RECORD_TYPE,
2309 get_identifier (UTAG_SYMTAB))),
2311 chainon (field_decl_chain, field_decl);
2313 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2315 /* Create an instance of "_objc_module". */
2316 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2317 finish_var_decl (UOBJC_MODULES_decl,
2318 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2321 pop_lang_context ();
2325 /* The GNU runtime requires us to provide a static initializer function
2328 static void __objc_gnu_init (void) {
2329 __objc_exec_class (&L_OBJC_MODULES);
2333 build_module_initializer_routine (void)
2338 push_lang_context (lang_name_c); /* extern "C" */
2341 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2342 objc_start_function (get_identifier (TAG_GNUINIT),
2343 build_function_type (void_type_node,
2345 NULL_TREE, objc_get_parm_info (0));
2347 body = c_begin_compound_stmt (true);
2348 add_stmt (build_function_call
2352 build_unary_op (ADDR_EXPR,
2353 UOBJC_MODULES_decl, 0))));
2354 add_stmt (c_end_compound_stmt (body, true));
2356 TREE_PUBLIC (current_function_decl) = 0;
2359 /* For Objective-C++, we will need to call __objc_gnu_init
2360 from objc_generate_static_init_call() below. */
2361 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2364 GNU_INIT_decl = current_function_decl;
2368 pop_lang_context ();
2373 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2374 to be called by the module initializer routine. */
2377 objc_static_init_needed_p (void)
2379 return (GNU_INIT_decl != NULL_TREE);
2382 /* Generate a call to the __objc_gnu_init initializer function. */
2385 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2387 add_stmt (build_stmt (EXPR_STMT,
2388 build_function_call (GNU_INIT_decl, NULL_TREE)));
2392 #endif /* OBJCPLUS */
2394 /* Return the DECL of the string IDENT in the SECTION. */
2397 get_objc_string_decl (tree ident, enum string_section section)
2401 if (section == class_names)
2402 chain = class_names_chain;
2403 else if (section == meth_var_names)
2404 chain = meth_var_names_chain;
2405 else if (section == meth_var_types)
2406 chain = meth_var_types_chain;
2410 for (; chain != 0; chain = TREE_CHAIN (chain))
2411 if (TREE_VALUE (chain) == ident)
2412 return (TREE_PURPOSE (chain));
2418 /* Output references to all statically allocated objects. Return the DECL
2419 for the array built. */
2422 generate_static_references (void)
2424 tree decls = NULL_TREE, expr = NULL_TREE;
2425 tree class_name, class, decl, initlist;
2426 tree cl_chain, in_chain, type
2427 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2428 int num_inst, num_class;
2431 if (flag_next_runtime)
2434 for (cl_chain = objc_static_instances, num_class = 0;
2435 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2437 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2438 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2440 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2441 decl = start_var_decl (type, buf);
2443 /* Output {class_name, ...}. */
2444 class = TREE_VALUE (cl_chain);
2445 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2446 initlist = build_tree_list (NULL_TREE,
2447 build_unary_op (ADDR_EXPR, class_name, 1));
2449 /* Output {..., instance, ...}. */
2450 for (in_chain = TREE_PURPOSE (cl_chain);
2451 in_chain; in_chain = TREE_CHAIN (in_chain))
2453 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2454 initlist = tree_cons (NULL_TREE, expr, initlist);
2457 /* Output {..., NULL}. */
2458 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2460 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2461 finish_var_decl (decl, expr);
2463 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2466 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2467 expr = objc_build_constructor (type, nreverse (decls));
2468 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2469 finish_var_decl (static_instances_decl, expr);
2472 static GTY(()) int selector_reference_idx;
2475 build_selector_reference_decl (void)
2480 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2481 decl = start_var_decl (objc_selector_type, buf);
2487 build_selector_table_decl (void)
2491 if (flag_typed_selectors)
2493 build_selector_template ();
2494 temp = build_array_type (objc_selector_template, NULL_TREE);
2497 temp = build_array_type (objc_selector_type, NULL_TREE);
2499 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2502 /* Just a handy wrapper for add_objc_string. */
2505 build_selector (tree ident)
2507 return convert (objc_selector_type,
2508 add_objc_string (ident, meth_var_names));
2512 build_selector_translation_table (void)
2514 tree chain, initlist = NULL_TREE;
2516 tree decl = NULL_TREE;
2518 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2522 if (warn_selector && objc_implementation_context)
2526 for (method_chain = meth_var_names_chain;
2528 method_chain = TREE_CHAIN (method_chain))
2530 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2539 if (flag_next_runtime && TREE_PURPOSE (chain))
2540 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2542 loc = &input_location;
2543 warning (0, "%Hcreating selector for nonexistent method %qE",
2544 loc, TREE_VALUE (chain));
2548 expr = build_selector (TREE_VALUE (chain));
2549 /* add one for the '\0' character */
2550 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2552 if (flag_next_runtime)
2554 decl = TREE_PURPOSE (chain);
2555 finish_var_decl (decl, expr);
2559 if (flag_typed_selectors)
2561 tree eltlist = NULL_TREE;
2562 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2563 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2564 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2565 expr = objc_build_constructor (objc_selector_template,
2566 nreverse (eltlist));
2569 initlist = tree_cons (NULL_TREE, expr, initlist);
2573 if (! flag_next_runtime)
2575 /* Cause the selector table (previously forward-declared)
2576 to be actually output. */
2577 initlist = tree_cons (NULL_TREE,
2578 flag_typed_selectors
2579 ? objc_build_constructor
2580 (objc_selector_template,
2581 tree_cons (NULL_TREE,
2582 build_int_cst (NULL_TREE, 0),
2583 tree_cons (NULL_TREE,
2584 build_int_cst (NULL_TREE, 0),
2586 : build_int_cst (NULL_TREE, 0), initlist);
2587 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2588 nreverse (initlist));
2589 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2594 get_proto_encoding (tree proto)
2599 if (! METHOD_ENCODING (proto))
2601 encoding = encode_method_prototype (proto);
2602 METHOD_ENCODING (proto) = encoding;
2605 encoding = METHOD_ENCODING (proto);
2607 return add_objc_string (encoding, meth_var_types);
2610 return build_int_cst (NULL_TREE, 0);
2613 /* sel_ref_chain is a list whose "value" fields will be instances of
2614 identifier_node that represent the selector. */
2617 build_typed_selector_reference (tree ident, tree prototype)
2619 tree *chain = &sel_ref_chain;
2625 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2626 goto return_at_index;
2629 chain = &TREE_CHAIN (*chain);
2632 *chain = tree_cons (prototype, ident, NULL_TREE);
2635 expr = build_unary_op (ADDR_EXPR,
2636 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2637 build_int_cst (NULL_TREE, index)),
2639 return convert (objc_selector_type, expr);
2643 build_selector_reference (tree ident)
2645 tree *chain = &sel_ref_chain;
2651 if (TREE_VALUE (*chain) == ident)
2652 return (flag_next_runtime
2653 ? TREE_PURPOSE (*chain)
2654 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2655 build_int_cst (NULL_TREE, index)));
2658 chain = &TREE_CHAIN (*chain);
2661 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2663 *chain = tree_cons (expr, ident, NULL_TREE);
2665 return (flag_next_runtime
2667 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2668 build_int_cst (NULL_TREE, index)));
2671 static GTY(()) int class_reference_idx;
2674 build_class_reference_decl (void)
2679 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2680 decl = start_var_decl (objc_class_type, buf);
2685 /* Create a class reference, but don't create a variable to reference
2689 add_class_reference (tree ident)
2693 if ((chain = cls_ref_chain))
2698 if (ident == TREE_VALUE (chain))
2702 chain = TREE_CHAIN (chain);
2706 /* Append to the end of the list */
2707 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2710 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2713 /* Get a class reference, creating it if necessary. Also create the
2714 reference variable. */
2717 objc_get_class_reference (tree ident)
2719 tree orig_ident = (DECL_P (ident)
2722 ? OBJC_TYPE_NAME (ident)
2724 bool local_scope = false;
2727 if (processing_template_decl)
2728 /* Must wait until template instantiation time. */
2729 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2732 if (TREE_CODE (ident) == TYPE_DECL)
2733 ident = (DECL_ORIGINAL_TYPE (ident)
2734 ? DECL_ORIGINAL_TYPE (ident)
2735 : TREE_TYPE (ident));
2738 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2739 && TYPE_CONTEXT (ident) != global_namespace)
2743 if (local_scope || !(ident = objc_is_class_name (ident)))
2745 error ("%qs is not an Objective-C class name or alias",
2746 IDENTIFIER_POINTER (orig_ident));
2747 return error_mark_node;
2750 if (flag_next_runtime && !flag_zero_link)
2755 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2756 if (TREE_VALUE (*chain) == ident)
2758 if (! TREE_PURPOSE (*chain))
2759 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2761 return TREE_PURPOSE (*chain);
2764 decl = build_class_reference_decl ();
2765 *chain = tree_cons (decl, ident, NULL_TREE);
2772 add_class_reference (ident);
2774 params = build_tree_list (NULL_TREE,
2775 my_build_string_pointer
2776 (IDENTIFIER_LENGTH (ident) + 1,
2777 IDENTIFIER_POINTER (ident)));
2779 assemble_external (objc_get_class_decl);
2780 return build_function_call (objc_get_class_decl, params);
2784 /* For each string section we have a chain which maps identifier nodes
2785 to decls for the strings. */
2788 add_objc_string (tree ident, enum string_section section)
2790 tree *chain, decl, type, string_expr;
2792 if (section == class_names)
2793 chain = &class_names_chain;
2794 else if (section == meth_var_names)
2795 chain = &meth_var_names_chain;
2796 else if (section == meth_var_types)
2797 chain = &meth_var_types_chain;
2803 if (TREE_VALUE (*chain) == ident)
2804 return convert (string_type_node,
2805 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2807 chain = &TREE_CHAIN (*chain);
2810 decl = build_objc_string_decl (section);
2812 type = build_array_type
2815 (build_int_cst (NULL_TREE,
2816 IDENTIFIER_LENGTH (ident))));
2817 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2818 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2819 IDENTIFIER_POINTER (ident));
2820 finish_var_decl (decl, string_expr);
2822 *chain = tree_cons (decl, ident, NULL_TREE);
2824 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2827 static GTY(()) int class_names_idx;
2828 static GTY(()) int meth_var_names_idx;
2829 static GTY(()) int meth_var_types_idx;
2832 build_objc_string_decl (enum string_section section)
2837 if (section == class_names)
2838 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2839 else if (section == meth_var_names)
2840 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2841 else if (section == meth_var_types)
2842 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2844 ident = get_identifier (buf);
2846 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2847 DECL_EXTERNAL (decl) = 1;
2848 TREE_PUBLIC (decl) = 0;
2849 TREE_USED (decl) = 1;
2850 TREE_CONSTANT (decl) = 1;
2851 DECL_CONTEXT (decl) = 0;
2852 DECL_ARTIFICIAL (decl) = 1;
2854 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2857 make_decl_rtl (decl);
2858 pushdecl_top_level (decl);
2865 objc_declare_alias (tree alias_ident, tree class_ident)
2867 tree underlying_class;
2870 if (current_namespace != global_namespace) {
2871 error ("Objective-C declarations may only appear in global scope");
2873 #endif /* OBJCPLUS */
2875 if (!(underlying_class = objc_is_class_name (class_ident)))
2876 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2877 else if (objc_is_class_name (alias_ident))
2878 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2881 /* Implement @compatibility_alias as a typedef. */
2883 push_lang_context (lang_name_c); /* extern "C" */
2885 lang_hooks.decls.pushdecl (build_decl
2888 xref_tag (RECORD_TYPE, underlying_class)));
2890 pop_lang_context ();
2892 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2897 objc_declare_class (tree ident_list)
2901 if (current_namespace != global_namespace) {
2902 error ("Objective-C declarations may only appear in global scope");
2904 #endif /* OBJCPLUS */
2906 for (list = ident_list; list; list = TREE_CHAIN (list))
2908 tree ident = TREE_VALUE (list);
2910 if (! objc_is_class_name (ident))
2912 tree record = lookup_name (ident), type = record;
2916 if (TREE_CODE (record) == TYPE_DECL)
2917 type = DECL_ORIGINAL_TYPE (record);
2919 if (!TYPE_HAS_OBJC_INFO (type)
2920 || !TYPE_OBJC_INTERFACE (type))
2922 error ("%qs redeclared as different kind of symbol",
2923 IDENTIFIER_POINTER (ident));
2924 error ("previous declaration of %q+D",
2929 record = xref_tag (RECORD_TYPE, ident);
2930 INIT_TYPE_OBJC_INFO (record);
2931 TYPE_OBJC_INTERFACE (record) = ident;
2932 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2938 objc_is_class_name (tree ident)
2942 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2943 && identifier_global_value (ident))
2944 ident = identifier_global_value (ident);
2945 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2946 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2948 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2949 ident = OBJC_TYPE_NAME (ident);
2951 if (ident && TREE_CODE (ident) == TYPE_DECL)
2952 ident = DECL_NAME (ident);
2954 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2957 if (lookup_interface (ident))
2960 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2962 if (ident == TREE_VALUE (chain))
2966 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2968 if (ident == TREE_VALUE (chain))
2969 return TREE_PURPOSE (chain);
2975 /* Check whether TYPE is either 'id' or 'Class'. */
2978 objc_is_id (tree type)
2980 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2981 && identifier_global_value (type))
2982 type = identifier_global_value (type);
2984 if (type && TREE_CODE (type) == TYPE_DECL)
2985 type = TREE_TYPE (type);
2987 /* NB: This function may be called before the ObjC front-end has
2988 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2989 return (objc_object_type && type
2990 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2995 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2996 class instance. This is needed by other parts of the compiler to
2997 handle ObjC types gracefully. */
3000 objc_is_object_ptr (tree type)
3004 type = TYPE_MAIN_VARIANT (type);
3005 if (!POINTER_TYPE_P (type))
3008 ret = objc_is_id (type);
3010 ret = objc_is_class_name (TREE_TYPE (type));
3016 objc_is_gcable_type (tree type, int or_strong_p)
3022 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3024 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3026 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3028 type = TREE_TYPE (type);
3029 if (TREE_CODE (type) != RECORD_TYPE)
3031 name = TYPE_NAME (type);
3032 return (objc_is_class_name (name) != NULL_TREE);
3036 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3038 if (expr == oldexpr)
3041 switch (TREE_CODE (expr))
3044 return objc_build_component_ref
3045 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3048 DECL_NAME (TREE_OPERAND (expr, 1)));
3050 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3053 TREE_OPERAND (expr, 1));
3055 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3064 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3067 /* The LHS parameter contains the expression 'outervar->memberspec';
3068 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3069 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3072 = objc_substitute_decl
3073 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3075 = (flag_objc_direct_dispatch
3076 ? objc_assign_ivar_fast_decl
3077 : objc_assign_ivar_decl);
3079 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
3081 func_params = tree_cons (NULL_TREE,
3082 convert (objc_object_type, rhs),
3083 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3084 tree_cons (NULL_TREE, offs,
3087 assemble_external (func);
3088 return build_function_call (func, func_params);
3092 objc_build_global_assignment (tree lhs, tree rhs)
3094 tree func_params = tree_cons (NULL_TREE,
3095 convert (objc_object_type, rhs),
3096 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3097 build_unary_op (ADDR_EXPR, lhs, 0)),
3100 assemble_external (objc_assign_global_decl);
3101 return build_function_call (objc_assign_global_decl, func_params);
3105 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3107 tree func_params = tree_cons (NULL_TREE,
3108 convert (objc_object_type, rhs),
3109 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3110 build_unary_op (ADDR_EXPR, lhs, 0)),
3113 assemble_external (objc_assign_strong_cast_decl);
3114 return build_function_call (objc_assign_strong_cast_decl, func_params);
3118 objc_is_gcable_p (tree expr)
3120 return (TREE_CODE (expr) == COMPONENT_REF
3121 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3122 : TREE_CODE (expr) == ARRAY_REF
3123 ? (objc_is_gcable_p (TREE_TYPE (expr))
3124 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3125 : TREE_CODE (expr) == ARRAY_TYPE
3126 ? objc_is_gcable_p (TREE_TYPE (expr))
3128 ? objc_is_gcable_type (expr, 1)
3129 : (objc_is_gcable_p (TREE_TYPE (expr))
3131 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3135 objc_is_ivar_reference_p (tree expr)
3137 return (TREE_CODE (expr) == ARRAY_REF
3138 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3139 : TREE_CODE (expr) == COMPONENT_REF
3140 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3145 objc_is_global_reference_p (tree expr)
3147 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3148 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3150 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3155 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3157 tree result = NULL_TREE, outer;
3158 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3160 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3161 will have been transformed to the form '*(type *)&expr'. */
3162 if (TREE_CODE (lhs) == INDIRECT_REF)
3164 outer = TREE_OPERAND (lhs, 0);
3166 while (!strong_cast_p
3167 && (TREE_CODE (outer) == CONVERT_EXPR
3168 || TREE_CODE (outer) == NOP_EXPR
3169 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3171 tree lhstype = TREE_TYPE (outer);
3173 /* Descend down the cast chain, and record the first objc_gc
3175 if (POINTER_TYPE_P (lhstype))
3178 = lookup_attribute ("objc_gc",
3179 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3185 outer = TREE_OPERAND (outer, 0);
3189 /* If we have a __strong cast, it trumps all else. */
3192 if (modifycode != NOP_EXPR)
3193 goto invalid_pointer_arithmetic;
3195 if (warn_assign_intercept)
3196 warning (0, "strong-cast assignment has been intercepted");
3198 result = objc_build_strong_cast_assignment (lhs, rhs);
3203 /* the lhs must be of a suitable type, regardless of its underlying
3205 if (!objc_is_gcable_p (lhs))
3211 && (TREE_CODE (outer) == COMPONENT_REF
3212 || TREE_CODE (outer) == ARRAY_REF))
3213 outer = TREE_OPERAND (outer, 0);
3215 if (TREE_CODE (outer) == INDIRECT_REF)
3217 outer = TREE_OPERAND (outer, 0);
3221 outer_gc_p = objc_is_gcable_p (outer);
3223 /* Handle ivar assignments. */
3224 if (objc_is_ivar_reference_p (lhs))
3226 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3227 doesn't cut it here), the best we can do here is suggest a cast. */
3228 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3230 /* We may still be able to use the global write barrier... */
3231 if (!indirect_p && objc_is_global_reference_p (outer))
3232 goto global_reference;
3235 if (modifycode == NOP_EXPR)
3237 if (warn_assign_intercept)
3238 warning (0, "strong-cast may possibly be needed");
3244 if (modifycode != NOP_EXPR)
3245 goto invalid_pointer_arithmetic;
3247 if (warn_assign_intercept)
3248 warning (0, "instance variable assignment has been intercepted");
3250 result = objc_build_ivar_assignment (outer, lhs, rhs);
3255 /* Likewise, intercept assignment to global/static variables if their type is
3257 if (objc_is_global_reference_p (outer))
3263 if (modifycode != NOP_EXPR)
3265 invalid_pointer_arithmetic:
3267 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3272 if (warn_assign_intercept)
3273 warning (0, "global/static variable assignment has been intercepted");
3275 result = objc_build_global_assignment (lhs, rhs);
3278 /* In all other cases, fall back to the normal mechanism. */
3283 struct interface_tuple GTY(())
3289 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3292 hash_interface (const void *p)
3294 const struct interface_tuple *d = p;
3295 return IDENTIFIER_HASH_VALUE (d->id);
3299 eq_interface (const void *p1, const void *p2)
3301 const struct interface_tuple *d = p1;
3306 lookup_interface (tree ident)
3309 if (ident && TREE_CODE (ident) == TYPE_DECL)
3310 ident = DECL_NAME (ident);
3313 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3317 struct interface_tuple **slot;
3322 slot = (struct interface_tuple **)
3323 htab_find_slot_with_hash (interface_htab, ident,
3324 IDENTIFIER_HASH_VALUE (ident),
3327 i = (*slot)->class_name;
3333 /* Implement @defs (<classname>) within struct bodies. */
3336 objc_get_class_ivars (tree class_name)
3338 tree interface = lookup_interface (class_name);
3341 return get_class_ivars (interface, true);
3343 error ("cannot find interface declaration for %qs",
3344 IDENTIFIER_POINTER (class_name));
3346 return error_mark_node;
3349 /* Used by: build_private_template, continue_class,
3350 and for @defs constructs. */
3353 get_class_ivars (tree interface, bool inherited)
3355 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3357 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3358 by the current class (i.e., they do not include super-class ivars).
3359 However, the CLASS_IVARS list will be side-effected by a call to
3360 finish_struct(), which will fill in field offsets. */
3361 if (!CLASS_IVARS (interface))
3362 CLASS_IVARS (interface) = ivar_chain;
3367 while (CLASS_SUPER_NAME (interface))
3369 /* Prepend super-class ivars. */
3370 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3371 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3379 objc_create_temporary_var (tree type)
3383 decl = build_decl (VAR_DECL, NULL_TREE, type);
3384 TREE_USED (decl) = 1;
3385 DECL_ARTIFICIAL (decl) = 1;
3386 DECL_IGNORED_P (decl) = 1;
3387 DECL_CONTEXT (decl) = current_function_decl;
3392 /* Exception handling constructs. We begin by having the parser do most
3393 of the work and passing us blocks. What we do next depends on whether
3394 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3395 We abstract all of this in a handful of appropriately named routines. */
3397 /* Stack of open try blocks. */
3399 struct objc_try_context
3401 struct objc_try_context *outer;
3403 /* Statements (or statement lists) as processed by the parser. */
3407 /* Some file position locations. */
3408 location_t try_locus;
3409 location_t end_try_locus;
3410 location_t end_catch_locus;
3411 location_t finally_locus;
3412 location_t end_finally_locus;
3414 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3415 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3418 /* The CATCH_EXPR of an open @catch clause. */
3421 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3427 static struct objc_try_context *cur_try_context;
3429 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3430 that represents TYPE. For Objective-C, this is just the class name. */
3431 /* ??? Isn't there a class object or some such? Is it easy to get? */
3435 objc_eh_runtime_type (tree type)
3437 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3441 /* Initialize exception handling. */
3444 objc_init_exceptions (void)
3446 static bool done = false;
3451 if (flag_objc_sjlj_exceptions)
3453 /* On Darwin, ObjC exceptions require a sufficiently recent
3454 version of the runtime, so the user must ask for them explicitly. */
3455 if (!flag_objc_exceptions)
3456 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3457 "exception syntax");
3462 c_eh_initialized_p = true;
3463 eh_personality_libfunc
3464 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3465 ? "__gnu_objc_personality_sj0"
3466 : "__gnu_objc_personality_v0");
3467 default_init_unwind_resume_libfunc ();
3468 using_eh_for_cleanups ();
3469 lang_eh_runtime_type = objc_eh_runtime_type;
3474 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3475 we'll arrange for it to be initialized (and associated with a binding)
3479 objc_build_exc_ptr (void)
3481 if (flag_objc_sjlj_exceptions)
3483 tree var = cur_try_context->caught_decl;
3486 var = objc_create_temporary_var (objc_object_type);
3487 cur_try_context->caught_decl = var;
3492 return build0 (EXC_PTR_EXPR, objc_object_type);
3495 /* Build "objc_exception_try_exit(&_stack)". */
3498 next_sjlj_build_try_exit (void)
3501 t = build_fold_addr_expr (cur_try_context->stack_decl);
3502 t = tree_cons (NULL, t, NULL);
3503 t = build_function_call (objc_exception_try_exit_decl, t);
3508 objc_exception_try_enter (&_stack);
3509 if (_setjmp(&_stack.buf))
3513 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3514 empty, ready for the caller to fill them in. */
3517 next_sjlj_build_enter_and_setjmp (void)
3519 tree t, enter, sj, cond;
3521 t = build_fold_addr_expr (cur_try_context->stack_decl);
3522 t = tree_cons (NULL, t, NULL);
3523 enter = build_function_call (objc_exception_try_enter_decl, t);
3525 t = objc_build_component_ref (cur_try_context->stack_decl,
3526 get_identifier ("buf"));
3527 t = build_fold_addr_expr (t);
3529 /* Convert _setjmp argument to type that is expected. */
3530 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3531 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3533 t = convert (ptr_type_node, t);
3535 t = convert (ptr_type_node, t);
3537 t = tree_cons (NULL, t, NULL);
3538 sj = build_function_call (objc_setjmp_decl, t);
3540 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3541 cond = c_common_truthvalue_conversion (cond);
3543 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3548 DECL = objc_exception_extract(&_stack); */
3551 next_sjlj_build_exc_extract (tree decl)
3555 t = build_fold_addr_expr (cur_try_context->stack_decl);
3556 t = tree_cons (NULL, t, NULL);
3557 t = build_function_call (objc_exception_extract_decl, t);
3558 t = convert (TREE_TYPE (decl), t);
3559 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3565 if (objc_exception_match(obj_get_class(TYPE), _caught)
3572 objc_exception_try_exit(&_stack);
3574 from the sequence of CATCH_EXPRs in the current try context. */
3577 next_sjlj_build_catch_list (void)
3579 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3581 tree *last = &catch_seq;
3582 bool saw_id = false;
3584 for (; !tsi_end_p (i); tsi_next (&i))
3586 tree stmt = tsi_stmt (i);
3587 tree type = CATCH_TYPES (stmt);
3588 tree body = CATCH_BODY (stmt);
3600 if (type == error_mark_node)
3601 cond = error_mark_node;
3604 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3605 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3606 args = tree_cons (NULL, t, args);
3607 t = build_function_call (objc_exception_match_decl, args);
3608 cond = c_common_truthvalue_conversion (t);
3610 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3611 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3614 last = &COND_EXPR_ELSE (t);
3620 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3621 cur_try_context->caught_decl);
3622 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3623 append_to_statement_list (t, last);
3625 t = next_sjlj_build_try_exit ();
3626 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3627 append_to_statement_list (t, last);
3633 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3634 exception handling. We aim to build:
3637 struct _objc_exception_data _stack;
3641 objc_exception_try_enter (&_stack);
3642 if (_setjmp(&_stack.buf))
3644 id _caught = objc_exception_extract(&_stack);
3645 objc_exception_try_enter (&_stack);
3646 if (_setjmp(&_stack.buf))
3647 _rethrow = objc_exception_extract(&_stack);
3657 objc_exception_try_exit(&_stack);
3660 objc_exception_throw(_rethrow);
3664 If CATCH-LIST is empty, we can omit all of the block containing
3665 "_caught" except for the setting of _rethrow. Note the use of
3666 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3667 but handles goto and other exits from the block. */
3670 next_sjlj_build_try_catch_finally (void)
3672 tree rethrow_decl, stack_decl, t;
3673 tree catch_seq, try_fin, bind;
3675 /* Create the declarations involved. */
3676 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3677 stack_decl = objc_create_temporary_var (t);
3678 cur_try_context->stack_decl = stack_decl;
3680 rethrow_decl = objc_create_temporary_var (objc_object_type);
3681 cur_try_context->rethrow_decl = rethrow_decl;
3682 TREE_CHAIN (rethrow_decl) = stack_decl;
3684 /* Build the outermost variable binding level. */
3685 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3686 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3687 TREE_SIDE_EFFECTS (bind) = 1;
3689 /* Initialize rethrow_decl. */
3690 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3691 convert (objc_object_type, null_pointer_node));
3692 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3693 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3695 /* Build the outermost TRY_FINALLY_EXPR. */
3696 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3697 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3698 TREE_SIDE_EFFECTS (try_fin) = 1;
3699 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3701 /* Create the complete catch sequence. */
3702 if (cur_try_context->catch_list)
3704 tree caught_decl = objc_build_exc_ptr ();
3705 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3706 TREE_SIDE_EFFECTS (catch_seq) = 1;
3708 t = next_sjlj_build_exc_extract (caught_decl);
3709 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3711 t = next_sjlj_build_enter_and_setjmp ();
3712 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3713 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3714 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3717 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3718 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3720 /* Build the main register-and-try if statement. */
3721 t = next_sjlj_build_enter_and_setjmp ();
3722 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3723 COND_EXPR_THEN (t) = catch_seq;
3724 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3725 TREE_OPERAND (try_fin, 0) = t;
3727 /* Build the complete FINALLY statement list. */
3728 t = next_sjlj_build_try_exit ();
3729 t = build_stmt (COND_EXPR,
3730 c_common_truthvalue_conversion (rethrow_decl),
3732 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3733 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3735 append_to_statement_list (cur_try_context->finally_body,
3736 &TREE_OPERAND (try_fin, 1));
3738 t = tree_cons (NULL, rethrow_decl, NULL);
3739 t = build_function_call (objc_exception_throw_decl, t);
3740 t = build_stmt (COND_EXPR,
3741 c_common_truthvalue_conversion (rethrow_decl),
3743 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3744 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3749 /* Called just after parsing the @try and its associated BODY. We now
3750 must prepare for the tricky bits -- handling the catches and finally. */
3753 objc_begin_try_stmt (location_t try_locus, tree body)
3755 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3756 c->outer = cur_try_context;
3758 c->try_locus = try_locus;
3759 c->end_try_locus = input_location;
3760 cur_try_context = c;
3762 objc_init_exceptions ();
3764 if (flag_objc_sjlj_exceptions)
3765 objc_mark_locals_volatile (NULL);
3768 /* Called just after parsing "@catch (parm)". Open a binding level,
3769 enter DECL into the binding level, and initialize it. Leave the
3770 binding level open while the body of the compound statement is parsed. */
3773 objc_begin_catch_clause (tree decl)
3775 tree compound, type, t;
3777 /* Begin a new scope that the entire catch clause will live in. */
3778 compound = c_begin_compound_stmt (true);
3780 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3781 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3782 lang_hooks.decls.pushdecl (decl);
3784 /* Since a decl is required here by syntax, don't warn if its unused. */
3785 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3786 be what the previous objc implementation did. */
3787 TREE_USED (decl) = 1;
3789 /* Verify that the type of the catch is valid. It must be a pointer
3790 to an Objective-C class, or "id" (which is catch-all). */
3791 type = TREE_TYPE (decl);
3793 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3795 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3797 error ("@catch parameter is not a known Objective-C class type");
3798 type = error_mark_node;
3800 else if (cur_try_context->catch_list)
3802 /* Examine previous @catch clauses and see if we've already
3803 caught the type in question. */
3804 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3805 for (; !tsi_end_p (i); tsi_next (&i))
3807 tree stmt = tsi_stmt (i);
3808 t = CATCH_TYPES (stmt);
3809 if (t == error_mark_node)
3811 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3813 warning (0, "exception of type %<%T%> will be caught",
3815 warning (0, "%H by earlier handler for %<%T%>",
3816 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3822 /* Record the data for the catch in the try context so that we can
3823 finalize it later. */
3824 t = build_stmt (CATCH_EXPR, type, compound);
3825 cur_try_context->current_catch = t;
3827 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3828 t = objc_build_exc_ptr ();
3829 t = convert (TREE_TYPE (decl), t);
3830 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3834 /* Called just after parsing the closing brace of a @catch clause. Close
3835 the open binding level, and record a CATCH_EXPR for it. */
3838 objc_finish_catch_clause (void)
3840 tree c = cur_try_context->current_catch;
3841 cur_try_context->current_catch = NULL;
3842 cur_try_context->end_catch_locus = input_location;
3844 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3845 append_to_statement_list (c, &cur_try_context->catch_list);
3848 /* Called after parsing a @finally clause and its associated BODY.
3849 Record the body for later placement. */
3852 objc_build_finally_clause (location_t finally_locus, tree body)
3854 cur_try_context->finally_body = body;
3855 cur_try_context->finally_locus = finally_locus;
3856 cur_try_context->end_finally_locus = input_location;
3859 /* Called to finalize a @try construct. */
3862 objc_finish_try_stmt (void)
3864 struct objc_try_context *c = cur_try_context;
3867 if (c->catch_list == NULL && c->finally_body == NULL)
3868 error ("%<@try%> without %<@catch%> or %<@finally%>");
3870 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3871 if (flag_objc_sjlj_exceptions)
3873 if (!cur_try_context->finally_body)
3875 cur_try_context->finally_locus = input_location;
3876 cur_try_context->end_finally_locus = input_location;
3878 stmt = next_sjlj_build_try_catch_finally ();
3882 /* Otherwise, nest the CATCH inside a FINALLY. */
3886 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3887 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3889 if (c->finally_body)
3891 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3892 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3897 cur_try_context = c->outer;
3903 objc_build_throw_stmt (tree throw_expr)
3907 objc_init_exceptions ();
3909 if (throw_expr == NULL)
3911 /* If we're not inside a @catch block, there is no "current
3912 exception" to be rethrown. */
3913 if (cur_try_context == NULL
3914 || cur_try_context->current_catch == NULL)
3916 error ("%<@throw%> (rethrow) used outside of a @catch block");
3920 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3921 value that we get from the runtime. */
3922 throw_expr = objc_build_exc_ptr ();
3925 /* A throw is just a call to the runtime throw function with the
3926 object as a parameter. */
3927 args = tree_cons (NULL, throw_expr, NULL);
3928 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3932 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3936 /* First lock the mutex. */
3937 mutex = save_expr (mutex);
3938 args = tree_cons (NULL, mutex, NULL);
3939 call = build_function_call (objc_sync_enter_decl, args);
3940 SET_EXPR_LOCATION (call, start_locus);
3943 /* Build the mutex unlock. */
3944 args = tree_cons (NULL, mutex, NULL);
3945 call = build_function_call (objc_sync_exit_decl, args);
3946 SET_EXPR_LOCATION (call, input_location);
3948 /* Put the that and the body in a TRY_FINALLY. */
3949 objc_begin_try_stmt (start_locus, body);
3950 objc_build_finally_clause (input_location, call);
3951 return objc_finish_try_stmt ();
3955 /* Predefine the following data type:
3957 struct _objc_exception_data
3959 int buf[OBJC_JBLEN];
3963 /* The following yuckiness should prevent users from having to #include
3964 <setjmp.h> in their code... */
3966 /* Define to a harmless positive value so the below code doesn't die. */
3968 #define OBJC_JBLEN 18
3972 build_next_objc_exception_stuff (void)
3974 tree field_decl, field_decl_chain, index, temp_type;
3976 objc_exception_data_template
3977 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3979 /* int buf[OBJC_JBLEN]; */
3981 index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
3982 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3984 field_decl_chain = field_decl;
3986 /* void *pointers[4]; */
3988 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3989 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3991 chainon (field_decl_chain, field_decl);
3993 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3995 /* int _setjmp(...); */
3996 /* If the user includes <setjmp.h>, this shall be superseded by
3997 'int _setjmp(jmp_buf);' */
3998 temp_type = build_function_type (integer_type_node, NULL_TREE);
4000 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4002 /* id objc_exception_extract(struct _objc_exception_data *); */
4004 = build_function_type (objc_object_type,
4005 tree_cons (NULL_TREE,
4006 build_pointer_type (objc_exception_data_template),
4008 objc_exception_extract_decl
4009 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4011 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4012 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4014 = build_function_type (void_type_node,
4015 tree_cons (NULL_TREE,
4016 build_pointer_type (objc_exception_data_template),
4018 objc_exception_try_enter_decl
4019 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4021 objc_exception_try_exit_decl
4022 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4025 /* int objc_exception_match(id, id); */
4027 = build_function_type (integer_type_node,
4028 tree_cons (NULL_TREE, objc_object_type,
4029 tree_cons (NULL_TREE, objc_object_type,
4030 OBJC_VOID_AT_END)));
4031 objc_exception_match_decl
4032 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4035 /* id objc_assign_ivar (id, id, unsigned int); */
4036 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4037 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4039 = build_function_type (objc_object_type,
4041 (NULL_TREE, objc_object_type,
4042 tree_cons (NULL_TREE, objc_object_type,
4043 tree_cons (NULL_TREE,
4045 OBJC_VOID_AT_END))));
4046 objc_assign_ivar_decl
4047 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4049 #ifdef OFFS_ASSIGNIVAR_FAST
4050 objc_assign_ivar_fast_decl
4051 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4052 NOT_BUILT_IN, NULL, NULL_TREE);
4053 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4054 = tree_cons (get_identifier ("hard_coded_address"),
4055 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4058 /* Default to slower ivar method. */
4059 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4062 /* id objc_assign_global (id, id *); */
4063 /* id objc_assign_strongCast (id, id *); */
4064 temp_type = build_function_type (objc_object_type,
4065 tree_cons (NULL_TREE, objc_object_type,
4066 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4067 OBJC_VOID_AT_END)));
4068 objc_assign_global_decl
4069 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4071 objc_assign_strong_cast_decl
4072 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4077 build_objc_exception_stuff (void)
4079 tree noreturn_list, nothrow_list, temp_type;
4081 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4082 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4084 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4085 /* void objc_sync_enter(id); */
4086 /* void objc_sync_exit(id); */
4087 temp_type = build_function_type (void_type_node,
4088 tree_cons (NULL_TREE, objc_object_type,
4090 objc_exception_throw_decl
4091 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4093 objc_sync_enter_decl
4094 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4095 NULL, nothrow_list);
4097 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4098 NULL, nothrow_list);
4101 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4104 struct <classname> {
4105 struct _objc_class *isa;
4110 build_private_template (tree class)
4112 if (!CLASS_STATIC_TEMPLATE (class))
4114 tree record = objc_build_struct (class,
4115 get_class_ivars (class, false),
4116 CLASS_SUPER_NAME (class));
4118 /* Set the TREE_USED bit for this struct, so that stab generator
4119 can emit stabs for this struct type. */
4120 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4121 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4125 /* Begin code generation for protocols... */
4127 /* struct _objc_protocol {
4128 struct _objc_class *isa;
4129 char *protocol_name;
4130 struct _objc_protocol **protocol_list;
4131 struct _objc__method_prototype_list *instance_methods;
4132 struct _objc__method_prototype_list *class_methods;
4136 build_protocol_template (void)
4138 tree field_decl, field_decl_chain;
4140 objc_protocol_template = start_struct (RECORD_TYPE,
4141 get_identifier (UTAG_PROTOCOL));
4143 /* struct _objc_class *isa; */
4144 field_decl = create_field_decl (build_pointer_type
4145 (xref_tag (RECORD_TYPE,
4146 get_identifier (UTAG_CLASS))),
4148 field_decl_chain = field_decl;
4150 /* char *protocol_name; */
4151 field_decl = create_field_decl (string_type_node, "protocol_name");
4152 chainon (field_decl_chain, field_decl);
4154 /* struct _objc_protocol **protocol_list; */
4155 field_decl = create_field_decl (build_pointer_type
4157 (objc_protocol_template)),
4159 chainon (field_decl_chain, field_decl);
4161 /* struct _objc__method_prototype_list *instance_methods; */
4162 field_decl = create_field_decl (objc_method_proto_list_ptr,
4163 "instance_methods");
4164 chainon (field_decl_chain, field_decl);
4166 /* struct _objc__method_prototype_list *class_methods; */
4167 field_decl = create_field_decl (objc_method_proto_list_ptr,
4169 chainon (field_decl_chain, field_decl);
4171 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4175 build_descriptor_table_initializer (tree type, tree entries)
4177 tree initlist = NULL_TREE;
4181 tree eltlist = NULL_TREE;
4184 = tree_cons (NULL_TREE,
4185 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4187 = tree_cons (NULL_TREE,
4188 add_objc_string (METHOD_ENCODING (entries),
4193 = tree_cons (NULL_TREE,
4194 objc_build_constructor (type, nreverse (eltlist)),
4197 entries = TREE_CHAIN (entries);
4201 return objc_build_constructor (build_array_type (type, 0),
4202 nreverse (initlist));
4205 /* struct objc_method_prototype_list {
4207 struct objc_method_prototype {
4214 build_method_prototype_list_template (tree list_type, int size)
4216 tree objc_ivar_list_record;
4217 tree field_decl, field_decl_chain;
4219 /* Generate an unnamed struct definition. */
4221 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4223 /* int method_count; */
4224 field_decl = create_field_decl (integer_type_node, "method_count");
4225 field_decl_chain = field_decl;
4227 /* struct objc_method method_list[]; */
4228 field_decl = create_field_decl (build_array_type
4231 (build_int_cst (NULL_TREE, size - 1))),
4233 chainon (field_decl_chain, field_decl);
4235 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4237 return objc_ivar_list_record;
4241 build_method_prototype_template (void)
4244 tree field_decl, field_decl_chain;
4247 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4250 field_decl = create_field_decl (objc_selector_type, "_cmd");
4251 field_decl_chain = field_decl;
4253 /* char *method_types; */
4254 field_decl = create_field_decl (string_type_node, "method_types");
4255 chainon (field_decl_chain, field_decl);
4257 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4259 return proto_record;
4263 objc_method_parm_type (tree type)
4265 type = TREE_VALUE (TREE_TYPE (type));
4266 if (TREE_CODE (type) == TYPE_DECL)
4267 type = TREE_TYPE (type);
4272 objc_encoded_type_size (tree type)
4274 int sz = int_size_in_bytes (type);
4276 /* Make all integer and enum types at least as large
4278 if (sz > 0 && INTEGRAL_TYPE_P (type))
4279 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4280 /* Treat arrays as pointers, since that's how they're
4282 else if (TREE_CODE (type) == ARRAY_TYPE)
4283 sz = int_size_in_bytes (ptr_type_node);
4288 encode_method_prototype (tree method_decl)
4295 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4296 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4298 /* Encode return type. */
4299 encode_type (objc_method_parm_type (method_decl),
4300 obstack_object_size (&util_obstack),
4301 OBJC_ENCODE_INLINE_DEFS);
4304 /* The first two arguments (self and _cmd) are pointers; account for
4306 i = int_size_in_bytes (ptr_type_node);
4307 parm_offset = 2 * i;
4308 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4309 parms = TREE_CHAIN (parms))
4311 tree type = objc_method_parm_type (parms);
4312 int sz = objc_encoded_type_size (type);
4314 /* If a type size is not known, bail out. */
4317 error ("type %q+D does not have a known size",
4319 /* Pretend that the encoding succeeded; the compilation will
4320 fail nevertheless. */
4321 goto finish_encoding;
4326 sprintf (buf, "%d@0:%d", parm_offset, i);
4327 obstack_grow (&util_obstack, buf, strlen (buf));
4329 /* Argument types. */
4330 parm_offset = 2 * i;
4331 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4332 parms = TREE_CHAIN (parms))
4334 tree type = objc_method_parm_type (parms);
4336 /* Process argument qualifiers for user supplied arguments. */
4337 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4340 encode_type (type, obstack_object_size (&util_obstack),
4341 OBJC_ENCODE_INLINE_DEFS);
4343 /* Compute offset. */
4344 sprintf (buf, "%d", parm_offset);
4345 parm_offset += objc_encoded_type_size (type);
4347 obstack_grow (&util_obstack, buf, strlen (buf));
4351 obstack_1grow (&util_obstack, '\0');
4352 result = get_identifier (obstack_finish (&util_obstack));
4353 obstack_free (&util_obstack, util_firstobj);
4358 generate_descriptor_table (tree type, const char *name, int size, tree list,
4361 tree decl, initlist;
4363 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4365 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4366 initlist = tree_cons (NULL_TREE, list, initlist);
4368 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4374 generate_method_descriptors (tree protocol)
4376 tree initlist, chain, method_list_template;
4379 if (!objc_method_prototype_template)
4380 objc_method_prototype_template = build_method_prototype_template ();
4382 chain = PROTOCOL_CLS_METHODS (protocol);
4385 size = list_length (chain);
4387 method_list_template
4388 = build_method_prototype_list_template (objc_method_prototype_template,
4392 = build_descriptor_table_initializer (objc_method_prototype_template,
4395 UOBJC_CLASS_METHODS_decl
4396 = generate_descriptor_table (method_list_template,
4397 "_OBJC_PROTOCOL_CLASS_METHODS",
4398 size, initlist, protocol);
4401 UOBJC_CLASS_METHODS_decl = 0;
4403 chain = PROTOCOL_NST_METHODS (protocol);
4406 size = list_length (chain);
4408 method_list_template
4409 = build_method_prototype_list_template (objc_method_prototype_template,
4412 = build_descriptor_table_initializer (objc_method_prototype_template,
4415 UOBJC_INSTANCE_METHODS_decl
4416 = generate_descriptor_table (method_list_template,
4417 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4418 size, initlist, protocol);
4421 UOBJC_INSTANCE_METHODS_decl = 0;
4425 generate_protocol_references (tree plist)
4429 /* Forward declare protocols referenced. */
4430 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4432 tree proto = TREE_VALUE (lproto);
4434 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4435 && PROTOCOL_NAME (proto))
4437 if (! PROTOCOL_FORWARD_DECL (proto))
4438 build_protocol_reference (proto);
4440 if (PROTOCOL_LIST (proto))
4441 generate_protocol_references (PROTOCOL_LIST (proto));
4446 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4450 objc_generate_cxx_ctor_or_dtor (bool dtor)
4452 tree fn, body, compound_stmt, ivar;
4454 /* - (id) .cxx_construct { ... return self; } */
4455 /* - (void) .cxx_construct { ... } */
4457 objc_set_method_type (MINUS_EXPR);
4458 objc_start_method_definition
4459 (objc_build_method_signature (build_tree_list (NULL_TREE,
4462 : objc_object_type),
4463 get_identifier (dtor
4465 : TAG_CXX_CONSTRUCT),
4466 make_node (TREE_LIST),
4468 body = begin_function_body ();
4469 compound_stmt = begin_compound_stmt (0);
4471 ivar = CLASS_IVARS (implementation_template);
4472 /* Destroy ivars in reverse order. */
4474 ivar = nreverse (copy_list (ivar));
4476 for (; ivar; ivar = TREE_CHAIN (ivar))
4478 if (TREE_CODE (ivar) == FIELD_DECL)
4480 tree type = TREE_TYPE (ivar);
4482 /* Call the ivar's default constructor or destructor. Do not
4483 call the destructor unless a corresponding constructor call
4484 has also been made (or is not needed). */
4485 if (MAYBE_CLASS_TYPE_P (type)
4487 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4488 && (!TYPE_NEEDS_CONSTRUCTING (type)
4489 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4490 : (TYPE_NEEDS_CONSTRUCTING (type)
4491 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4493 (build_special_member_call
4494 (build_ivar_reference (DECL_NAME (ivar)),
4495 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4496 NULL_TREE, type, LOOKUP_NORMAL));
4500 /* The constructor returns 'self'. */
4502 finish_return_stmt (self_decl);
4504 finish_compound_stmt (compound_stmt);
4505 finish_function_body (body);
4506 fn = current_function_decl;
4508 objc_finish_method_definition (fn);
4511 /* The following routine will examine the current @interface for any
4512 non-POD C++ ivars requiring non-trivial construction and/or
4513 destruction, and then synthesize special '- .cxx_construct' and/or
4514 '- .cxx_destruct' methods which will run the appropriate
4515 construction or destruction code. Note that ivars inherited from
4516 super-classes are _not_ considered. */
4518 objc_generate_cxx_cdtors (void)
4520 bool need_ctor = false, need_dtor = false;
4523 /* We do not want to do this for categories, since they do not have
4526 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4529 /* First, determine if we even need a constructor and/or destructor. */
4531 for (ivar = CLASS_IVARS (implementation_template); ivar;
4532 ivar = TREE_CHAIN (ivar))
4534 if (TREE_CODE (ivar) == FIELD_DECL)
4536 tree type = TREE_TYPE (ivar);
4538 if (MAYBE_CLASS_TYPE_P (type))
4540 if (TYPE_NEEDS_CONSTRUCTING (type)
4541 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4542 /* NB: If a default constructor is not available, we will not
4543 be able to initialize this ivar; the add_instance_variable()
4544 routine will already have warned about this. */
4547 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4548 && (!TYPE_NEEDS_CONSTRUCTING (type)
4549 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4550 /* NB: If a default constructor is not available, we will not
4551 call the destructor either, for symmetry. */
4557 /* Generate '- .cxx_construct' if needed. */
4560 objc_generate_cxx_ctor_or_dtor (false);
4562 /* Generate '- .cxx_destruct' if needed. */
4565 objc_generate_cxx_ctor_or_dtor (true);
4567 /* The 'imp_list' variable points at an imp_entry record for the current
4568 @implementation. Record the existence of '- .cxx_construct' and/or
4569 '- .cxx_destruct' methods therein; it will be included in the
4570 metadata for the class. */
4571 if (flag_next_runtime)
4572 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4576 /* For each protocol which was referenced either from a @protocol()
4577 expression, or because a class/category implements it (then a
4578 pointer to the protocol is stored in the struct describing the
4579 class/category), we create a statically allocated instance of the
4580 Protocol class. The code is written in such a way as to generate
4581 as few Protocol objects as possible; we generate a unique Protocol
4582 instance for each protocol, and we don't generate a Protocol
4583 instance if the protocol is never referenced (either from a
4584 @protocol() or from a class/category implementation). These
4585 statically allocated objects can be referred to via the static
4586 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4588 The statically allocated Protocol objects that we generate here
4589 need to be fixed up at runtime in order to be used: the 'isa'
4590 pointer of the objects need to be set up to point to the 'Protocol'
4591 class, as known at runtime.
4593 The NeXT runtime fixes up all protocols at program startup time,
4594 before main() is entered. It uses a low-level trick to look up all
4595 those symbols, then loops on them and fixes them up.
4597 The GNU runtime as well fixes up all protocols before user code
4598 from the module is executed; it requires pointers to those symbols
4599 to be put in the objc_symtab (which is then passed as argument to
4600 the function __objc_exec_class() which the compiler sets up to be
4601 executed automatically when the module is loaded); setup of those
4602 Protocol objects happen in two ways in the GNU runtime: all
4603 Protocol objects referred to by a class or category implementation
4604 are fixed up when the class/category is loaded; all Protocol
4605 objects referred to by a @protocol() expression are added by the
4606 compiler to the list of statically allocated instances to fixup
4607 (the same list holding the statically allocated constant string
4608 objects). Because, as explained above, the compiler generates as
4609 few Protocol objects as possible, some Protocol object might end up
4610 being referenced multiple times when compiled with the GNU runtime,
4611 and end up being fixed up multiple times at runtime initialization.
4612 But that doesn't hurt, it's just a little inefficient. */
4615 generate_protocols (void)
4619 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4621 /* If a protocol was directly referenced, pull in indirect references. */
4622 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4623 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4624 generate_protocol_references (PROTOCOL_LIST (p));
4626 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4628 tree nst_methods = PROTOCOL_NST_METHODS (p);
4629 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4631 /* If protocol wasn't referenced, don't generate any code. */
4632 decl = PROTOCOL_FORWARD_DECL (p);
4637 /* Make sure we link in the Protocol class. */
4638 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4642 if (! METHOD_ENCODING (nst_methods))
4644 encoding = encode_method_prototype (nst_methods);
4645 METHOD_ENCODING (nst_methods) = encoding;
4647 nst_methods = TREE_CHAIN (nst_methods);
4652 if (! METHOD_ENCODING (cls_methods))
4654 encoding = encode_method_prototype (cls_methods);
4655 METHOD_ENCODING (cls_methods) = encoding;
4658 cls_methods = TREE_CHAIN (cls_methods);
4660 generate_method_descriptors (p);
4662 if (PROTOCOL_LIST (p))
4663 refs_decl = generate_protocol_list (p);
4667 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4668 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4671 refs_expr = convert (build_pointer_type (build_pointer_type
4672 (objc_protocol_template)),
4673 build_unary_op (ADDR_EXPR, refs_decl, 0));
4675 refs_expr = build_int_cst (NULL_TREE, 0);
4677 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4678 by generate_method_descriptors, which is called above. */
4679 initlist = build_protocol_initializer (TREE_TYPE (decl),
4680 protocol_name_expr, refs_expr,
4681 UOBJC_INSTANCE_METHODS_decl,
4682 UOBJC_CLASS_METHODS_decl);
4683 finish_var_decl (decl, initlist);
4688 build_protocol_initializer (tree type, tree protocol_name,
4689 tree protocol_list, tree instance_methods,
4692 tree initlist = NULL_TREE, expr;
4693 tree cast_type = build_pointer_type
4694 (xref_tag (RECORD_TYPE,
4695 get_identifier (UTAG_CLASS)));
4697 /* Filling the "isa" in with one allows the runtime system to
4698 detect that the version change...should remove before final release. */
4700 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4701 initlist = tree_cons (NULL_TREE, expr, initlist);
4702 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4703 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4705 if (!instance_methods)
4706 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4709 expr = convert (objc_method_proto_list_ptr,
4710 build_unary_op (ADDR_EXPR, instance_methods, 0));
4711 initlist = tree_cons (NULL_TREE, expr, initlist);
4715 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4718 expr = convert (objc_method_proto_list_ptr,
4719 build_unary_op (ADDR_EXPR, class_methods, 0));
4720 initlist = tree_cons (NULL_TREE, expr, initlist);
4723 return objc_build_constructor (type, nreverse (initlist));
4726 /* struct _objc_category {
4727 char *category_name;
4729 struct _objc_method_list *instance_methods;
4730 struct _objc_method_list *class_methods;
4731 struct _objc_protocol_list *protocols;
4735 build_category_template (void)
4737 tree field_decl, field_decl_chain;
4739 objc_category_template = start_struct (RECORD_TYPE,
4740 get_identifier (UTAG_CATEGORY));
4742 /* char *category_name; */
4743 field_decl = create_field_decl (string_type_node, "category_name");
4744 field_decl_chain = field_decl;
4746 /* char *class_name; */
4747 field_decl = create_field_decl (string_type_node, "class_name");
4748 chainon (field_decl_chain, field_decl);
4750 /* struct _objc_method_list *instance_methods; */
4751 field_decl = create_field_decl (objc_method_list_ptr,
4752 "instance_methods");
4753 chainon (field_decl_chain, field_decl);
4755 /* struct _objc_method_list *class_methods; */
4756 field_decl = create_field_decl (objc_method_list_ptr,
4758 chainon (field_decl_chain, field_decl);
4760 /* struct _objc_protocol **protocol_list; */
4761 field_decl = create_field_decl (build_pointer_type
4763 (objc_protocol_template)),
4765 chainon (field_decl_chain, field_decl);
4767 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4770 /* struct _objc_selector {
4776 build_selector_template (void)
4779 tree field_decl, field_decl_chain;
4781 objc_selector_template
4782 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4785 field_decl = create_field_decl (objc_selector_type, "sel_id");
4786 field_decl_chain = field_decl;
4788 /* char *sel_type; */
4789 field_decl = create_field_decl (string_type_node, "sel_type");
4790 chainon (field_decl_chain, field_decl);
4792 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4795 /* struct _objc_class {
4796 struct _objc_class *isa;
4797 struct _objc_class *super_class;
4802 struct _objc_ivar_list *ivars;
4803 struct _objc_method_list *methods;
4804 #ifdef __NEXT_RUNTIME__
4805 struct objc_cache *cache;
4807 struct sarray *dtable;
4808 struct _objc_class *subclass_list;
4809 struct _objc_class *sibling_class;
4811 struct _objc_protocol_list *protocols;
4812 #ifdef __NEXT_RUNTIME__
4815 void *gc_object_type;
4818 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4819 the NeXT/Apple runtime; still, the compiler must generate them to
4820 maintain backward binary compatibility (and to allow for future
4824 build_class_template (void)
4826 tree field_decl, field_decl_chain;
4829 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4831 /* struct _objc_class *isa; */
4832 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4834 field_decl_chain = field_decl;
4836 /* struct _objc_class *super_class; */
4837 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4839 chainon (field_decl_chain, field_decl);
4842 field_decl = create_field_decl (string_type_node, "name");
4843 chainon (field_decl_chain, field_decl);
4846 field_decl = create_field_decl (long_integer_type_node, "version");
4847 chainon (field_decl_chain, field_decl);
4850 field_decl = create_field_decl (long_integer_type_node, "info");
4851 chainon (field_decl_chain, field_decl);
4853 /* long instance_size; */
4854 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4855 chainon (field_decl_chain, field_decl);
4857 /* struct _objc_ivar_list *ivars; */
4858 field_decl = create_field_decl (objc_ivar_list_ptr,
4860 chainon (field_decl_chain, field_decl);
4862 /* struct _objc_method_list *methods; */
4863 field_decl = create_field_decl (objc_method_list_ptr,
4865 chainon (field_decl_chain, field_decl);
4867 if (flag_next_runtime)
4869 /* struct objc_cache *cache; */
4870 field_decl = create_field_decl (build_pointer_type
4871 (xref_tag (RECORD_TYPE,
4875 chainon (field_decl_chain, field_decl);
4879 /* struct sarray *dtable; */
4880 field_decl = create_field_decl (build_pointer_type
4881 (xref_tag (RECORD_TYPE,
4885 chainon (field_decl_chain, field_decl);
4887 /* struct objc_class *subclass_list; */
4888 field_decl = create_field_decl (build_pointer_type
4889 (objc_class_template),
4891 chainon (field_decl_chain, field_decl);
4893 /* struct objc_class *sibling_class; */
4894 field_decl = create_field_decl (build_pointer_type
4895 (objc_class_template),
4897 chainon (field_decl_chain, field_decl);
4900 /* struct _objc_protocol **protocol_list; */
4901 field_decl = create_field_decl (build_pointer_type
4903 (xref_tag (RECORD_TYPE,
4907 chainon (field_decl_chain, field_decl);
4909 if (flag_next_runtime)
4912 field_decl = create_field_decl (build_pointer_type (void_type_node),
4914 chainon (field_decl_chain, field_decl);
4917 /* void *gc_object_type; */
4918 field_decl = create_field_decl (build_pointer_type (void_type_node),
4920 chainon (field_decl_chain, field_decl);
4922 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4925 /* Generate appropriate forward declarations for an implementation. */
4928 synth_forward_declarations (void)
4932 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4933 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4934 objc_class_template);
4936 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4937 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4938 objc_class_template);
4940 /* Pre-build the following entities - for speed/convenience. */
4942 an_id = get_identifier ("super_class");
4943 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4944 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4948 error_with_ivar (const char *message, tree decl)
4950 error ("%J%s %qs", decl,
4951 message, gen_declaration (decl));
4956 check_ivars (tree inter, tree imp)
4958 tree intdecls = CLASS_RAW_IVARS (inter);
4959 tree impdecls = CLASS_RAW_IVARS (imp);
4966 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4967 intdecls = TREE_CHAIN (intdecls);
4969 if (intdecls == 0 && impdecls == 0)
4971 if (intdecls == 0 || impdecls == 0)
4973 error ("inconsistent instance variable specification");
4977 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4979 if (!comptypes (t1, t2)
4980 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4981 DECL_INITIAL (impdecls)))
4983 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4985 error_with_ivar ("conflicting instance variable type",
4987 error_with_ivar ("previous declaration of",
4990 else /* both the type and the name don't match */
4992 error ("inconsistent instance variable specification");
4997 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4999 error_with_ivar ("conflicting instance variable name",
5001 error_with_ivar ("previous declaration of",
5005 intdecls = TREE_CHAIN (intdecls);
5006 impdecls = TREE_CHAIN (impdecls);
5010 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5011 This needs to be done just once per compilation. */
5013 /* struct _objc_super {
5014 struct _objc_object *self;
5015 struct _objc_class *super_class;
5019 build_super_template (void)
5021 tree field_decl, field_decl_chain;
5023 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
5025 /* struct _objc_object *self; */
5026 field_decl = create_field_decl (objc_object_type, "self");
5027 field_decl_chain = field_decl;
5029 /* struct _objc_class *super_class; */
5030 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5032 chainon (field_decl_chain, field_decl);
5034 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
5037 /* struct _objc_ivar {
5044 build_ivar_template (void)
5046 tree objc_ivar_id, objc_ivar_record;
5047 tree field_decl, field_decl_chain;
5049 objc_ivar_id = get_identifier (UTAG_IVAR);
5050 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
5052 /* char *ivar_name; */
5053 field_decl = create_field_decl (string_type_node, "ivar_name");
5054 field_decl_chain = field_decl;
5056 /* char *ivar_type; */
5057 field_decl = create_field_decl (string_type_node, "ivar_type");
5058 chainon (field_decl_chain, field_decl);
5060 /* int ivar_offset; */
5061 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5062 chainon (field_decl_chain, field_decl);
5064 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5066 return objc_ivar_record;
5071 struct objc_ivar ivar_list[ivar_count];
5075 build_ivar_list_template (tree list_type, int size)
5077 tree objc_ivar_list_record;
5078 tree field_decl, field_decl_chain;
5080 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5082 /* int ivar_count; */
5083 field_decl = create_field_decl (integer_type_node, "ivar_count");
5084 field_decl_chain = field_decl;
5086 /* struct objc_ivar ivar_list[]; */
5087 field_decl = create_field_decl (build_array_type
5090 (build_int_cst (NULL_TREE, size - 1))),
5092 chainon (field_decl_chain, field_decl);
5094 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5096 return objc_ivar_list_record;
5100 struct _objc__method_prototype_list *method_next;
5102 struct objc_method method_list[method_count];
5106 build_method_list_template (tree list_type, int size)
5108 tree objc_ivar_list_record;
5109 tree field_decl, field_decl_chain;
5111 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5113 /* struct _objc__method_prototype_list *method_next; */
5114 field_decl = create_field_decl (objc_method_proto_list_ptr,
5116 field_decl_chain = field_decl;
5118 /* int method_count; */
5119 field_decl = create_field_decl (integer_type_node, "method_count");
5120 chainon (field_decl_chain, field_decl);
5122 /* struct objc_method method_list[]; */
5123 field_decl = create_field_decl (build_array_type
5126 (build_int_cst (NULL_TREE, size - 1))),
5128 chainon (field_decl_chain, field_decl);
5130 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5132 return objc_ivar_list_record;
5136 build_ivar_list_initializer (tree type, tree field_decl)
5138 tree initlist = NULL_TREE;
5142 tree ivar = NULL_TREE;
5145 if (DECL_NAME (field_decl))
5146 ivar = tree_cons (NULL_TREE,
5147 add_objc_string (DECL_NAME (field_decl),
5151 /* Unnamed bit-field ivar (yuck). */
5152 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5155 encode_field_decl (field_decl,
5156 obstack_object_size (&util_obstack),
5157 OBJC_ENCODE_DONT_INLINE_DEFS);
5159 /* Null terminate string. */
5160 obstack_1grow (&util_obstack, 0);
5164 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
5167 obstack_free (&util_obstack, util_firstobj);
5170 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5171 initlist = tree_cons (NULL_TREE,
5172 objc_build_constructor (type, nreverse (ivar)),
5175 field_decl = TREE_CHAIN (field_decl);
5176 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5180 return objc_build_constructor (build_array_type (type, 0),
5181 nreverse (initlist));
5185 generate_ivars_list (tree type, const char *name, int size, tree list)
5187 tree decl, initlist;
5189 decl = start_var_decl (type, synth_id_with_class_suffix
5190 (name, objc_implementation_context));
5192 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5193 initlist = tree_cons (NULL_TREE, list, initlist);
5195 finish_var_decl (decl,
5196 objc_build_constructor (TREE_TYPE (decl),
5197 nreverse (initlist)));
5202 /* Count only the fields occurring in T. */
5205 ivar_list_length (tree t)
5209 for (; t; t = TREE_CHAIN (t))
5210 if (TREE_CODE (t) == FIELD_DECL)
5217 generate_ivar_lists (void)
5219 tree initlist, ivar_list_template, chain;
5222 generating_instance_variables = 1;
5224 if (!objc_ivar_template)
5225 objc_ivar_template = build_ivar_template ();
5227 /* Only generate class variables for the root of the inheritance
5228 hierarchy since these will be the same for every class. */
5230 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5231 && (chain = TYPE_FIELDS (objc_class_template)))
5233 size = ivar_list_length (chain);
5235 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5236 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5238 UOBJC_CLASS_VARIABLES_decl
5239 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5243 UOBJC_CLASS_VARIABLES_decl = 0;
5245 chain = CLASS_IVARS (implementation_template);
5248 size = ivar_list_length (chain);
5249 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5250 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5252 UOBJC_INSTANCE_VARIABLES_decl
5253 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5257 UOBJC_INSTANCE_VARIABLES_decl = 0;
5259 generating_instance_variables = 0;
5263 build_dispatch_table_initializer (tree type, tree entries)
5265 tree initlist = NULL_TREE;
5269 tree elemlist = NULL_TREE;
5271 elemlist = tree_cons (NULL_TREE,
5272 build_selector (METHOD_SEL_NAME (entries)),
5275 /* Generate the method encoding if we don't have one already. */
5276 if (! METHOD_ENCODING (entries))
5277 METHOD_ENCODING (entries) =
5278 encode_method_prototype (entries);
5280 elemlist = tree_cons (NULL_TREE,
5281 add_objc_string (METHOD_ENCODING (entries),
5286 = tree_cons (NULL_TREE,
5287 convert (ptr_type_node,
5288 build_unary_op (ADDR_EXPR,
5289 METHOD_DEFINITION (entries), 1)),
5292 initlist = tree_cons (NULL_TREE,
5293 objc_build_constructor (type, nreverse (elemlist)),
5296 entries = TREE_CHAIN (entries);
5300 return objc_build_constructor (build_array_type (type, 0),
5301 nreverse (initlist));
5304 /* To accomplish method prototyping without generating all kinds of
5305 inane warnings, the definition of the dispatch table entries were
5308 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5310 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5313 build_method_template (void)
5316 tree field_decl, field_decl_chain;
5318 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5321 field_decl = create_field_decl (objc_selector_type, "_cmd");
5322 field_decl_chain = field_decl;
5324 /* char *method_types; */
5325 field_decl = create_field_decl (string_type_node, "method_types");
5326 chainon (field_decl_chain, field_decl);
5329 field_decl = create_field_decl (build_pointer_type (void_type_node),
5331 chainon (field_decl_chain, field_decl);
5333 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5340 generate_dispatch_table (tree type, const char *name, int size, tree list)
5342 tree decl, initlist;
5344 decl = start_var_decl (type, synth_id_with_class_suffix
5345 (name, objc_implementation_context));
5347 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5348 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5349 initlist = tree_cons (NULL_TREE, list, initlist);
5351 finish_var_decl (decl,
5352 objc_build_constructor (TREE_TYPE (decl),
5353 nreverse (initlist)));
5359 mark_referenced_methods (void)
5361 struct imp_entry *impent;
5364 for (impent = imp_list; impent; impent = impent->next)
5366 chain = CLASS_CLS_METHODS (impent->imp_context);
5369 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5370 chain = TREE_CHAIN (chain);
5373 chain = CLASS_NST_METHODS (impent->imp_context);
5376 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5377 chain = TREE_CHAIN (chain);
5383 generate_dispatch_tables (void)
5385 tree initlist, chain, method_list_template;
5388 if (!objc_method_template)
5389 objc_method_template = build_method_template ();
5391 chain = CLASS_CLS_METHODS (objc_implementation_context);
5394 size = list_length (chain);
5396 method_list_template
5397 = build_method_list_template (objc_method_template, size);
5399 = build_dispatch_table_initializer (objc_method_template, chain);
5401 UOBJC_CLASS_METHODS_decl
5402 = generate_dispatch_table (method_list_template,
5403 ((TREE_CODE (objc_implementation_context)
5404 == CLASS_IMPLEMENTATION_TYPE)
5405 ? "_OBJC_CLASS_METHODS"
5406 : "_OBJC_CATEGORY_CLASS_METHODS"),
5410 UOBJC_CLASS_METHODS_decl = 0;
5412 chain = CLASS_NST_METHODS (objc_implementation_context);
5415 size = list_length (chain);
5417 method_list_template
5418 = build_method_list_template (objc_method_template, size);
5420 = build_dispatch_table_initializer (objc_method_template, chain);
5422 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5423 UOBJC_INSTANCE_METHODS_decl
5424 = generate_dispatch_table (method_list_template,
5425 "_OBJC_INSTANCE_METHODS",
5428 /* We have a category. */
5429 UOBJC_INSTANCE_METHODS_decl
5430 = generate_dispatch_table (method_list_template,
5431 "_OBJC_CATEGORY_INSTANCE_METHODS",
5435 UOBJC_INSTANCE_METHODS_decl = 0;
5439 generate_protocol_list (tree i_or_p)
5442 tree refs_decl, lproto, e, plist;
5444 const char *ref_name;
5446 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5447 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5448 plist = CLASS_PROTOCOL_LIST (i_or_p);
5449 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5450 plist = PROTOCOL_LIST (i_or_p);
5455 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5456 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5457 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5460 /* Build initializer. */
5461 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5462 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5463 initlist = tree_cons (NULL_TREE, e, initlist);
5465 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5467 tree pval = TREE_VALUE (lproto);
5469 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5470 && PROTOCOL_FORWARD_DECL (pval))
5472 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
5473 initlist = tree_cons (NULL_TREE, e, initlist);
5477 /* static struct objc_protocol *refs[n]; */
5479 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5480 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5481 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5482 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5483 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5484 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5488 refs_decl = start_var_decl
5490 (build_pointer_type (objc_protocol_template),
5491 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5494 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5495 nreverse (initlist)));
5501 build_category_initializer (tree type, tree cat_name, tree class_name,
5502 tree instance_methods, tree class_methods,
5505 tree initlist = NULL_TREE, expr;
5507 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5508 initlist = tree_cons (NULL_TREE, class_name, initlist);
5510 if (!instance_methods)
5511 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5514 expr = convert (objc_method_list_ptr,
5515 build_unary_op (ADDR_EXPR, instance_methods, 0));
5516 initlist = tree_cons (NULL_TREE, expr, initlist);
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, class_methods, 0));
5524 initlist = tree_cons (NULL_TREE, expr, initlist);
5527 /* protocol_list = */
5529 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5532 expr = convert (build_pointer_type
5534 (objc_protocol_template)),
5535 build_unary_op (ADDR_EXPR, protocol_list, 0));
5536 initlist = tree_cons (NULL_TREE, expr, initlist);
5539 return objc_build_constructor (type, nreverse (initlist));
5542 /* struct _objc_class {
5543 struct objc_class *isa;
5544 struct objc_class *super_class;
5549 struct objc_ivar_list *ivars;
5550 struct objc_method_list *methods;
5551 if (flag_next_runtime)
5552 struct objc_cache *cache;
5554 struct sarray *dtable;
5555 struct objc_class *subclass_list;
5556 struct objc_class *sibling_class;
5558 struct objc_protocol_list *protocols;
5559 if (flag_next_runtime)
5561 void *gc_object_type;
5565 build_shared_structure_initializer (tree type, tree isa, tree super,
5566 tree name, tree size, int status,
5567 tree dispatch_table, tree ivar_list,
5570 tree initlist = NULL_TREE, expr;
5573 initlist = tree_cons (NULL_TREE, isa, initlist);
5576 initlist = tree_cons (NULL_TREE, super, initlist);
5579 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5582 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5586 initlist = tree_cons (NULL_TREE,
5587 build_int_cst (long_integer_type_node, status),
5590 /* instance_size = */
5591 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5594 /* objc_ivar_list = */
5596 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5599 expr = convert (objc_ivar_list_ptr,
5600 build_unary_op (ADDR_EXPR, ivar_list, 0));
5601 initlist = tree_cons (NULL_TREE, expr, initlist);
5604 /* objc_method_list = */
5605 if (!dispatch_table)
5606 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5609 expr = convert (objc_method_list_ptr,
5610 build_unary_op (ADDR_EXPR, dispatch_table, 0));
5611 initlist = tree_cons (NULL_TREE, expr, initlist);
5614 if (flag_next_runtime)
5615 /* method_cache = */
5616 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5620 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5622 /* subclass_list = */
5623 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5625 /* sibling_class = */
5626 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5629 /* protocol_list = */
5630 if (! protocol_list)
5631 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5634 expr = convert (build_pointer_type
5636 (objc_protocol_template)),
5637 build_unary_op (ADDR_EXPR, protocol_list, 0));
5638 initlist = tree_cons (NULL_TREE, expr, initlist);
5641 if (flag_next_runtime)
5643 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5645 /* gc_object_type = NULL */
5646 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5648 return objc_build_constructor (type, nreverse (initlist));
5651 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5654 lookup_category (tree class, tree cat_name)
5656 tree category = CLASS_CATEGORY_LIST (class);
5658 while (category && CLASS_SUPER_NAME (category) != cat_name)
5659 category = CLASS_CATEGORY_LIST (category);
5663 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5666 generate_category (tree cat)
5669 tree initlist, cat_name_expr, class_name_expr;
5670 tree protocol_decl, category;
5672 add_class_reference (CLASS_NAME (cat));
5673 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5675 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5677 category = lookup_category (implementation_template,
5678 CLASS_SUPER_NAME (cat));
5680 if (category && CLASS_PROTOCOL_LIST (category))
5682 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5683 protocol_decl = generate_protocol_list (category);
5688 decl = start_var_decl (objc_category_template,
5689 synth_id_with_class_suffix
5690 ("_OBJC_CATEGORY", objc_implementation_context));
5692 initlist = build_category_initializer (TREE_TYPE (decl),
5693 cat_name_expr, class_name_expr,
5694 UOBJC_INSTANCE_METHODS_decl,
5695 UOBJC_CLASS_METHODS_decl,
5698 finish_var_decl (decl, initlist);
5701 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5702 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5705 generate_shared_structures (int cls_flags)
5707 tree sc_spec, decl_specs, decl;
5708 tree name_expr, super_expr, root_expr;
5709 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5710 tree cast_type, initlist, protocol_decl;
5712 my_super_id = CLASS_SUPER_NAME (implementation_template);
5715 add_class_reference (my_super_id);
5717 /* Compute "my_root_id" - this is required for code generation.
5718 the "isa" for all meta class structures points to the root of
5719 the inheritance hierarchy (e.g. "__Object")... */
5720 my_root_id = my_super_id;
5723 tree my_root_int = lookup_interface (my_root_id);
5725 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5726 my_root_id = CLASS_SUPER_NAME (my_root_int);
5733 /* No super class. */
5734 my_root_id = CLASS_NAME (implementation_template);
5736 cast_type = build_pointer_type (objc_class_template);
5737 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5740 /* Install class `isa' and `super' pointers at runtime. */
5743 super_expr = add_objc_string (my_super_id, class_names);
5744 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5747 super_expr = build_int_cst (NULL_TREE, 0);
5749 root_expr = add_objc_string (my_root_id, class_names);
5750 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5752 if (CLASS_PROTOCOL_LIST (implementation_template))
5754 generate_protocol_references
5755 (CLASS_PROTOCOL_LIST (implementation_template));
5756 protocol_decl = generate_protocol_list (implementation_template);
5761 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5763 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5764 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5766 decl = start_var_decl (objc_class_template,
5768 (DECL_NAME (UOBJC_METACLASS_decl)));
5771 = build_shared_structure_initializer
5773 root_expr, super_expr, name_expr,
5774 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5776 UOBJC_CLASS_METHODS_decl,
5777 UOBJC_CLASS_VARIABLES_decl,
5780 finish_var_decl (decl, initlist);
5782 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5784 decl = start_var_decl (objc_class_template,
5786 (DECL_NAME (UOBJC_CLASS_decl)));
5789 = build_shared_structure_initializer
5791 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5792 super_expr, name_expr,
5793 convert (integer_type_node,
5794 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5795 (implementation_template))),
5796 1 /*CLS_FACTORY*/ | cls_flags,
5797 UOBJC_INSTANCE_METHODS_decl,
5798 UOBJC_INSTANCE_VARIABLES_decl,
5801 finish_var_decl (decl, initlist);
5806 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5808 static char string[BUFSIZE];
5810 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5811 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5813 sprintf (string, "%s_%s", preamble,
5814 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5816 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5817 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5819 /* We have a category. */
5820 const char *const class_name
5821 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5822 const char *const class_super_name
5823 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5824 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5826 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5828 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5829 sprintf (string, "%s_%s", preamble, protocol_name);
5837 /* If type is empty or only type qualifiers are present, add default
5838 type of id (otherwise grokdeclarator will default to int). */
5841 adjust_type_for_id_default (tree type)
5844 type = make_node (TREE_LIST);
5846 if (!TREE_VALUE (type))
5847 TREE_VALUE (type) = objc_object_type;
5848 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5849 && TYPED_OBJECT (TREE_VALUE (type)))
5850 error ("can not use an object as parameter to a method");
5857 selector ':' '(' typename ')' identifier
5860 Transform an Objective-C keyword argument into
5861 the C equivalent parameter declarator.
5863 In: key_name, an "identifier_node" (optional).
5864 arg_type, a "tree_list" (optional).
5865 arg_name, an "identifier_node".
5867 Note: It would be really nice to strongly type the preceding
5868 arguments in the function prototype; however, then I
5869 could not use the "accessor" macros defined in "tree.h".
5871 Out: an instance of "keyword_decl". */
5874 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5878 /* If no type is specified, default to "id". */
5879 arg_type = adjust_type_for_id_default (arg_type);
5881 keyword_decl = make_node (KEYWORD_DECL);
5883 TREE_TYPE (keyword_decl) = arg_type;
5884 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5885 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5887 return keyword_decl;
5890 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5893 build_keyword_selector (tree selector)
5896 tree key_chain, key_name;
5899 /* Scan the selector to see how much space we'll need. */
5900 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5902 if (TREE_CODE (selector) == KEYWORD_DECL)
5903 key_name = KEYWORD_KEY_NAME (key_chain);
5904 else if (TREE_CODE (selector) == TREE_LIST)
5905 key_name = TREE_PURPOSE (key_chain);
5910 len += IDENTIFIER_LENGTH (key_name) + 1;
5912 /* Just a ':' arg. */
5916 buf = (char *) alloca (len + 1);
5917 /* Start the buffer out as an empty string. */
5920 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5922 if (TREE_CODE (selector) == KEYWORD_DECL)
5923 key_name = KEYWORD_KEY_NAME (key_chain);
5924 else if (TREE_CODE (selector) == TREE_LIST)
5926 key_name = TREE_PURPOSE (key_chain);
5927 /* The keyword decl chain will later be used as a function argument
5928 chain. Unhook the selector itself so as to not confuse other
5929 parts of the compiler. */
5930 TREE_PURPOSE (key_chain) = NULL_TREE;
5936 strcat (buf, IDENTIFIER_POINTER (key_name));
5940 return get_identifier (buf);
5943 /* Used for declarations and definitions. */
5946 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5947 tree add_args, bool ellipsis)
5951 /* If no type is specified, default to "id". */
5952 ret_type = adjust_type_for_id_default (ret_type);
5954 method_decl = make_node (code);
5955 TREE_TYPE (method_decl) = ret_type;
5957 /* If we have a keyword selector, create an identifier_node that
5958 represents the full selector name (`:' included)... */
5959 if (TREE_CODE (selector) == KEYWORD_DECL)
5961 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5962 METHOD_SEL_ARGS (method_decl) = selector;
5963 METHOD_ADD_ARGS (method_decl) = add_args;
5964 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5968 METHOD_SEL_NAME (method_decl) = selector;
5969 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5970 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5976 #define METHOD_DEF 0
5977 #define METHOD_REF 1
5979 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5980 an argument list for method METH. CONTEXT is either METHOD_DEF or
5981 METHOD_REF, saying whether we are trying to define a method or call
5982 one. SUPERFLAG says this is for a send to super; this makes a
5983 difference for the NeXT calling sequence in which the lookup and
5984 the method call are done together. If METH is null, user-defined
5985 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5988 get_arg_type_list (tree meth, int context, int superflag)
5992 /* Receiver type. */
5993 if (flag_next_runtime && superflag)
5994 arglist = build_tree_list (NULL_TREE, objc_super_type);
5995 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5996 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5998 arglist = build_tree_list (NULL_TREE, objc_object_type);
6000 /* Selector type - will eventually change to `int'. */
6001 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6003 /* No actual method prototype given -- assume that remaining arguments
6008 /* Build a list of argument types. */
6009 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6011 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6013 /* Decay arrays and functions into pointers. */
6014 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6015 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6016 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6017 arg_type = build_pointer_type (arg_type);
6019 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6022 if (METHOD_ADD_ARGS (meth))
6024 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6025 akey; akey = TREE_CHAIN (akey))
6027 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6029 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6032 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6033 goto lack_of_ellipsis;
6038 chainon (arglist, OBJC_VOID_AT_END);
6045 check_duplicates (hash hsh, int methods, int is_class)
6047 tree meth = NULL_TREE;
6055 /* We have two or more methods with the same name but
6059 /* But just how different are those types? If
6060 -Wno-strict-selector-match is specified, we shall not
6061 complain if the differences are solely among types with
6062 identical size and alignment. */
6063 if (!warn_strict_selector_match)
6065 for (loop = hsh->list; loop; loop = loop->next)
6066 if (!comp_proto_with_proto (meth, loop->value, 0))
6073 warning (0, "multiple %s named %<%c%s%> found",
6074 methods ? "methods" : "selectors",
6075 (is_class ? '+' : '-'),
6076 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6078 warn_with_method (methods ? "using" : "found",
6079 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6083 for (loop = hsh->list; loop; loop = loop->next)
6084 warn_with_method ("also found",
6085 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6094 /* If RECEIVER is a class reference, return the identifier node for
6095 the referenced class. RECEIVER is created by objc_get_class_reference,
6096 so we check the exact form created depending on which runtimes are
6100 receiver_is_class_object (tree receiver, int self, int super)
6102 tree chain, exp, arg;
6104 /* The receiver is 'self' or 'super' in the context of a class method. */
6105 if (objc_method_context
6106 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6109 ? CLASS_SUPER_NAME (implementation_template)
6110 : CLASS_NAME (implementation_template));
6112 if (flag_next_runtime)
6114 /* The receiver is a variable created by
6115 build_class_reference_decl. */
6116 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6117 /* Look up the identifier. */
6118 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6119 if (TREE_PURPOSE (chain) == receiver)
6120 return TREE_VALUE (chain);
6123 /* The receiver is a function call that returns an id. Check if
6124 it is a call to objc_getClass, if so, pick up the class name. */
6125 if (TREE_CODE (receiver) == CALL_EXPR
6126 && (exp = CALL_EXPR_FN (receiver))
6127 && TREE_CODE (exp) == ADDR_EXPR
6128 && (exp = TREE_OPERAND (exp, 0))
6129 && TREE_CODE (exp) == FUNCTION_DECL
6130 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6131 prototypes for objc_get_class(). Thankfully, they seem to share the
6132 same function type. */
6133 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6134 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6135 /* We have a call to objc_get_class/objc_getClass! */
6136 && (arg = CALL_EXPR_ARG (receiver, 0)))
6139 if (TREE_CODE (arg) == ADDR_EXPR
6140 && (arg = TREE_OPERAND (arg, 0))
6141 && TREE_CODE (arg) == STRING_CST)
6142 /* Finally, we have the class name. */
6143 return get_identifier (TREE_STRING_POINTER (arg));
6148 /* If we are currently building a message expr, this holds
6149 the identifier of the selector of the message. This is
6150 used when printing warnings about argument mismatches. */
6152 static tree current_objc_message_selector = 0;
6155 objc_message_selector (void)
6157 return current_objc_message_selector;
6160 /* Construct an expression for sending a message.
6161 MESS has the object to send to in TREE_PURPOSE
6162 and the argument list (including selector) in TREE_VALUE.
6164 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6165 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6168 objc_build_message_expr (tree mess)
6170 tree receiver = TREE_PURPOSE (mess);
6173 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6175 tree args = TREE_VALUE (mess);
6177 tree method_params = NULL_TREE;
6179 if (TREE_CODE (receiver) == ERROR_MARK)
6180 return error_mark_node;
6182 /* Obtain the full selector name. */
6183 if (TREE_CODE (args) == IDENTIFIER_NODE)
6184 /* A unary selector. */
6186 else if (TREE_CODE (args) == TREE_LIST)
6187 sel_name = build_keyword_selector (args);
6191 /* Build the parameter list to give to the method. */
6192 if (TREE_CODE (args) == TREE_LIST)
6194 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6197 tree chain = args, prev = NULL_TREE;
6199 /* We have a keyword selector--check for comma expressions. */
6202 tree element = TREE_VALUE (chain);
6204 /* We have a comma expression, must collapse... */
6205 if (TREE_CODE (element) == TREE_LIST)
6208 TREE_CHAIN (prev) = element;
6213 chain = TREE_CHAIN (chain);
6215 method_params = args;
6220 if (processing_template_decl)
6221 /* Must wait until template instantiation time. */
6222 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6226 return objc_finish_message_expr (receiver, sel_name, method_params);
6229 /* Look up method SEL_NAME that would be suitable for receiver
6230 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6231 nonzero), and report on any duplicates. */
6234 lookup_method_in_hash_lists (tree sel_name, int is_class)
6236 hash method_prototype = NULL;
6239 method_prototype = hash_lookup (nst_method_hash_list,
6242 if (!method_prototype)
6244 method_prototype = hash_lookup (cls_method_hash_list,
6249 return check_duplicates (method_prototype, 1, is_class);
6252 /* The 'objc_finish_message_expr' routine is called from within
6253 'objc_build_message_expr' for non-template functions. In the case of
6254 C++ template functions, it is called from 'build_expr_from_tree'
6255 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6258 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6260 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6261 tree selector, retval, class_tree;
6262 int self, super, have_cast;
6264 /* Extract the receiver of the message, as well as its type
6265 (where the latter may take the form of a cast or be inferred
6266 from the implementation context). */
6268 while (TREE_CODE (rtype) == COMPOUND_EXPR
6269 || TREE_CODE (rtype) == MODIFY_EXPR
6270 || TREE_CODE (rtype) == NOP_EXPR
6271 || TREE_CODE (rtype) == CONVERT_EXPR
6272 || TREE_CODE (rtype) == COMPONENT_REF)
6273 rtype = TREE_OPERAND (rtype, 0);
6274 self = (rtype == self_decl);
6275 super = (rtype == UOBJC_SUPER_decl);
6276 rtype = TREE_TYPE (receiver);
6277 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6278 || (TREE_CODE (receiver) == COMPOUND_EXPR
6279 && !IS_SUPER (rtype)));
6281 /* If we are calling [super dealloc], reset our warning flag. */
6282 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6283 should_call_super_dealloc = 0;
6285 /* If the receiver is a class object, retrieve the corresponding
6286 @interface, if one exists. */
6287 class_tree = receiver_is_class_object (receiver, self, super);
6289 /* Now determine the receiver type (if an explicit cast has not been
6294 rtype = lookup_interface (class_tree);
6295 /* Handle `self' and `super'. */
6298 if (!CLASS_SUPER_NAME (implementation_template))
6300 error ("no super class declared in @interface for %qs",
6301 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6302 return error_mark_node;
6304 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6307 rtype = lookup_interface (CLASS_NAME (implementation_template));
6310 /* If receiver is of type `id' or `Class' (or if the @interface for a
6311 class is not visible), we shall be satisfied with the existence of
6312 any instance or class method. */
6313 if (objc_is_id (rtype))
6315 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6316 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6317 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6323 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6324 in protocols themselves for the method prototype. */
6326 = lookup_method_in_protocol_list (rprotos, sel_name,
6327 class_tree != NULL_TREE);
6329 /* If messaging 'Class <Proto>' but did not find a class method
6330 prototype, search for an instance method instead, and warn
6331 about having done so. */
6332 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6335 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6337 if (method_prototype)
6338 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6339 IDENTIFIER_POINTER (sel_name),
6340 IDENTIFIER_POINTER (sel_name));
6346 tree orig_rtype = rtype, saved_rtype;
6348 if (TREE_CODE (rtype) == POINTER_TYPE)
6349 rtype = TREE_TYPE (rtype);
6350 /* Traverse typedef aliases */
6351 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6352 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6353 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6354 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6355 saved_rtype = rtype;
6356 if (TYPED_OBJECT (rtype))
6358 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6359 rtype = TYPE_OBJC_INTERFACE (rtype);
6361 /* If we could not find an @interface declaration, we must have
6362 only seen a @class declaration; so, we cannot say anything
6363 more intelligent about which methods the receiver will
6365 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6367 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6368 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6370 /* We have a valid ObjC class name. Look up the method name
6371 in the published @interface for the class (and its
6374 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6376 /* If the method was not found in the @interface, it may still
6377 exist locally as part of the @implementation. */
6378 if (!method_prototype && objc_implementation_context
6379 && CLASS_NAME (objc_implementation_context)
6380 == OBJC_TYPE_NAME (rtype))
6384 ? CLASS_CLS_METHODS (objc_implementation_context)
6385 : CLASS_NST_METHODS (objc_implementation_context)),
6388 /* If we haven't found a candidate method by now, try looking for
6389 it in the protocol list. */
6390 if (!method_prototype && rprotos)
6392 = lookup_method_in_protocol_list (rprotos, sel_name,
6393 class_tree != NULL_TREE);
6397 warning (0, "invalid receiver type %qs",
6398 gen_type_name (orig_rtype));
6399 /* After issuing the "invalid receiver" warning, perform method
6400 lookup as if we were messaging 'id'. */
6401 rtype = rprotos = NULL_TREE;
6406 /* For 'id' or 'Class' receivers, search in the global hash table
6407 as a last resort. For all receivers, warn if protocol searches
6409 if (!method_prototype)
6412 warning (0, "%<%c%s%> not found in protocol(s)",
6413 (class_tree ? '+' : '-'),
6414 IDENTIFIER_POINTER (sel_name));
6418 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6421 if (!method_prototype)
6423 static bool warn_missing_methods = false;
6426 warning (0, "%qs may not respond to %<%c%s%>",
6427 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6428 (class_tree ? '+' : '-'),
6429 IDENTIFIER_POINTER (sel_name));
6430 /* If we are messaging an 'id' or 'Class' object and made it here,
6431 then we have failed to find _any_ instance or class method,
6434 warning (0, "no %<%c%s%> method found",
6435 (class_tree ? '+' : '-'),
6436 IDENTIFIER_POINTER (sel_name));
6438 if (!warn_missing_methods)
6440 warning (0, "(Messages without a matching method signature");
6441 warning (0, "will be assumed to return %<id%> and accept");
6442 warning (0, "%<...%> as arguments.)");
6443 warn_missing_methods = true;
6447 /* Save the selector name for printing error messages. */
6448 current_objc_message_selector = sel_name;
6450 /* Build the parameters list for looking up the method.
6451 These are the object itself and the selector. */
6453 if (flag_typed_selectors)
6454 selector = build_typed_selector_reference (sel_name, method_prototype);
6456 selector = build_selector_reference (sel_name);
6458 retval = build_objc_method_call (super, method_prototype,
6460 selector, method_params);
6462 current_objc_message_selector = 0;
6467 /* Build a tree expression to send OBJECT the operation SELECTOR,
6468 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6469 assuming the method has prototype METHOD_PROTOTYPE.
6470 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6471 Use METHOD_PARAMS as list of args to pass to the method.
6472 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6475 build_objc_method_call (int super_flag, tree method_prototype,
6476 tree lookup_object, tree selector,
6479 tree sender = (super_flag ? umsg_super_decl :
6480 (!flag_next_runtime || flag_nil_receivers
6481 ? (flag_objc_direct_dispatch
6484 : umsg_nonnil_decl));
6485 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6487 /* If a prototype for the method to be called exists, then cast
6488 the sender's return type and arguments to match that of the method.
6489 Otherwise, leave sender as is. */
6492 ? TREE_VALUE (TREE_TYPE (method_prototype))
6493 : objc_object_type);
6495 = build_pointer_type
6496 (build_function_type
6499 (method_prototype, METHOD_REF, super_flag)));
6502 lookup_object = build_c_cast (rcv_p, lookup_object);
6504 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6505 lookup_object = save_expr (lookup_object);
6507 if (flag_next_runtime)
6509 /* If we are returning a struct in memory, and the address
6510 of that memory location is passed as a hidden first
6511 argument, then change which messenger entry point this
6512 expr will call. NB: Note that sender_cast remains
6513 unchanged (it already has a struct return type). */
6514 if (!targetm.calls.struct_value_rtx (0, 0)
6515 && (TREE_CODE (ret_type) == RECORD_TYPE
6516 || TREE_CODE (ret_type) == UNION_TYPE)
6517 && targetm.calls.return_in_memory (ret_type, 0))
6518 sender = (super_flag ? umsg_super_stret_decl :
6519 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6521 method_params = tree_cons (NULL_TREE, lookup_object,
6522 tree_cons (NULL_TREE, selector,
6524 method = build_fold_addr_expr (sender);
6528 /* This is the portable (GNU) way. */
6531 /* First, call the lookup function to get a pointer to the method,
6532 then cast the pointer, then call it with the method arguments. */
6534 object = (super_flag ? self_decl : lookup_object);
6536 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6537 t = tree_cons (NULL_TREE, lookup_object, t);
6538 method = build_function_call (sender, t);
6540 /* Pass the object to the method. */
6541 method_params = tree_cons (NULL_TREE, object,
6542 tree_cons (NULL_TREE, selector,
6546 /* ??? Selector is not at this point something we can use inside
6547 the compiler itself. Set it to garbage for the nonce. */
6548 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6549 return build_function_call (t, method_params);
6553 build_protocol_reference (tree p)
6556 const char *proto_name;
6558 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6560 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6561 decl = start_var_decl (objc_protocol_template, proto_name);
6563 PROTOCOL_FORWARD_DECL (p) = decl;
6566 /* This function is called by the parser when (and only when) a
6567 @protocol() expression is found, in order to compile it. */
6569 objc_build_protocol_expr (tree protoname)
6572 tree p = lookup_protocol (protoname);
6576 error ("cannot find protocol declaration for %qs",
6577 IDENTIFIER_POINTER (protoname));
6578 return error_mark_node;
6581 if (!PROTOCOL_FORWARD_DECL (p))
6582 build_protocol_reference (p);
6584 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6586 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6587 if we have it, rather than converting it here. */
6588 expr = convert (objc_protocol_type, expr);
6590 /* The @protocol() expression is being compiled into a pointer to a
6591 statically allocated instance of the Protocol class. To become
6592 usable at runtime, the 'isa' pointer of the instance need to be
6593 fixed up at runtime by the runtime library, to point to the
6594 actual 'Protocol' class. */
6596 /* For the GNU runtime, put the static Protocol instance in the list
6597 of statically allocated instances, so that we make sure that its
6598 'isa' pointer is fixed up at runtime by the GNU runtime library
6599 to point to the Protocol class (at runtime, when loading the
6600 module, the GNU runtime library loops on the statically allocated
6601 instances (as found in the defs field in objc_symtab) and fixups
6602 all the 'isa' pointers of those objects). */
6603 if (! flag_next_runtime)
6605 /* This type is a struct containing the fields of a Protocol
6606 object. (Cfr. objc_protocol_type instead is the type of a pointer
6607 to such a struct). */
6608 tree protocol_struct_type = xref_tag
6609 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6612 /* Look for the list of Protocol statically allocated instances
6613 to fixup at runtime. Create a new list to hold Protocol
6614 statically allocated instances, if the list is not found. At
6615 present there is only another list, holding NSConstantString
6616 static instances to be fixed up at runtime. */
6617 for (chain = &objc_static_instances;
6618 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6619 chain = &TREE_CHAIN (*chain));
6622 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6623 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6627 /* Add this statically allocated instance to the Protocol list. */
6628 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6629 PROTOCOL_FORWARD_DECL (p),
6630 TREE_PURPOSE (*chain));
6637 /* This function is called by the parser when a @selector() expression
6638 is found, in order to compile it. It is only called by the parser
6639 and only to compile a @selector(). */
6641 objc_build_selector_expr (tree selnamelist)
6645 /* Obtain the full selector name. */
6646 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6647 /* A unary selector. */
6648 selname = selnamelist;
6649 else if (TREE_CODE (selnamelist) == TREE_LIST)
6650 selname = build_keyword_selector (selnamelist);
6654 /* If we are required to check @selector() expressions as they
6655 are found, check that the selector has been declared. */
6656 if (warn_undeclared_selector)
6658 /* Look the selector up in the list of all known class and
6659 instance methods (up to this line) to check that the selector
6663 /* First try with instance methods. */
6664 hsh = hash_lookup (nst_method_hash_list, selname);
6666 /* If not found, try with class methods. */
6669 hsh = hash_lookup (cls_method_hash_list, selname);
6672 /* If still not found, print out a warning. */
6675 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6680 if (flag_typed_selectors)
6681 return build_typed_selector_reference (selname, 0);
6683 return build_selector_reference (selname);
6687 objc_build_encode_expr (tree type)
6692 encode_type (type, obstack_object_size (&util_obstack),
6693 OBJC_ENCODE_INLINE_DEFS);
6694 obstack_1grow (&util_obstack, 0); /* null terminate string */
6695 string = obstack_finish (&util_obstack);
6697 /* Synthesize a string that represents the encoded struct/union. */
6698 result = my_build_string (strlen (string) + 1, string);
6699 obstack_free (&util_obstack, util_firstobj);
6704 build_ivar_reference (tree id)
6706 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6708 /* Historically, a class method that produced objects (factory
6709 method) would assign `self' to the instance that it
6710 allocated. This would effectively turn the class method into
6711 an instance method. Following this assignment, the instance
6712 variables could be accessed. That practice, while safe,
6713 violates the simple rule that a class method should not refer
6714 to an instance variable. It's better to catch the cases
6715 where this is done unknowingly than to support the above
6717 warning (0, "instance variable %qs accessed in class method",
6718 IDENTIFIER_POINTER (id));
6719 self_decl = convert (objc_instance_type, self_decl); /* cast */
6722 return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
6725 /* Compute a hash value for a given method SEL_NAME. */
6728 hash_func (tree sel_name)
6730 const unsigned char *s
6731 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6735 h = h * 67 + *s++ - 113;
6742 nst_method_hash_list
6743 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6744 cls_method_hash_list
6745 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6747 /* Initialize the hash table used to hold the constant string objects. */
6748 string_htab = htab_create_ggc (31, string_hash,
6751 /* Initialize the hash table used to hold EH-volatilized types. */
6752 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6753 volatilized_eq, NULL);
6756 /* WARNING!!!! hash_enter is called with a method, and will peek
6757 inside to find its selector! But hash_lookup is given a selector
6758 directly, and looks for the selector that's inside the found
6759 entry's key (method) for comparison. */
6762 hash_enter (hash *hashlist, tree method)
6765 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6767 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6769 obj->next = hashlist[slot];
6772 hashlist[slot] = obj; /* append to front */
6776 hash_lookup (hash *hashlist, tree sel_name)
6780 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6784 if (sel_name == METHOD_SEL_NAME (target->key))
6787 target = target->next;
6793 hash_add_attr (hash entry, tree value)
6797 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6798 obj->next = entry->list;
6801 entry->list = obj; /* append to front */
6805 lookup_method (tree mchain, tree method)
6809 if (TREE_CODE (method) == IDENTIFIER_NODE)
6812 key = METHOD_SEL_NAME (method);
6816 if (METHOD_SEL_NAME (mchain) == key)
6819 mchain = TREE_CHAIN (mchain);
6824 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6825 in INTERFACE, along with any categories and protocols attached thereto.
6826 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6827 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6828 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6829 be found in INTERFACE or any of its superclasses, look for an _instance_
6830 method of the same name in the root class as a last resort.
6832 If a suitable method cannot be found, return NULL_TREE. */
6835 lookup_method_static (tree interface, tree ident, int flags)
6837 tree meth = NULL_TREE, root_inter = NULL_TREE;
6838 tree inter = interface;
6839 int is_class = (flags & OBJC_LOOKUP_CLASS);
6840 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6844 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6845 tree category = inter;
6847 /* First, look up the method in the class itself. */
6848 if ((meth = lookup_method (chain, ident)))
6851 /* Failing that, look for the method in each category of the class. */
6852 while ((category = CLASS_CATEGORY_LIST (category)))
6854 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6856 /* Check directly in each category. */
6857 if ((meth = lookup_method (chain, ident)))
6860 /* Failing that, check in each category's protocols. */
6861 if (CLASS_PROTOCOL_LIST (category))
6863 if ((meth = (lookup_method_in_protocol_list
6864 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6869 /* If not found in categories, check in protocols of the main class. */
6870 if (CLASS_PROTOCOL_LIST (inter))
6872 if ((meth = (lookup_method_in_protocol_list
6873 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6877 /* If we were instructed not to look in superclasses, don't. */
6878 if (no_superclasses)
6881 /* Failing that, climb up the inheritance hierarchy. */
6883 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6887 /* If no class (factory) method was found, check if an _instance_
6888 method of the same name exists in the root class. This is what
6889 the Objective-C runtime will do. If an instance method was not
6891 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6894 /* Add the method to the hash list if it doesn't contain an identical
6898 add_method_to_hash_list (hash *hash_list, tree method)
6902 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6904 /* Install on a global chain. */
6905 hash_enter (hash_list, method);
6909 /* Check types against those; if different, add to a list. */
6911 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6912 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6913 already_there |= comp_proto_with_proto (method, loop->value, 1);
6915 hash_add_attr (hsh, method);
6920 objc_add_method (tree class, tree method, int is_class)
6924 if (!(mth = lookup_method (is_class
6925 ? CLASS_CLS_METHODS (class)
6926 : CLASS_NST_METHODS (class), method)))
6928 /* put method on list in reverse order */
6931 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6932 CLASS_CLS_METHODS (class) = method;
6936 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6937 CLASS_NST_METHODS (class) = method;
6942 /* When processing an @interface for a class or category, give hard
6943 errors on methods with identical selectors but differing argument
6944 and/or return types. We do not do this for @implementations, because
6945 C/C++ will do it for us (i.e., there will be duplicate function
6946 definition errors). */
6947 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6948 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6949 && !comp_proto_with_proto (method, mth, 1))
6950 error ("duplicate declaration of method %<%c%s%>",
6951 is_class ? '+' : '-',
6952 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6956 add_method_to_hash_list (cls_method_hash_list, method);
6959 add_method_to_hash_list (nst_method_hash_list, method);
6961 /* Instance methods in root classes (and categories thereof)
6962 may act as class methods as a last resort. We also add
6963 instance methods listed in @protocol declarations to
6964 the class hash table, on the assumption that @protocols
6965 may be adopted by root classes or categories. */
6966 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6967 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6968 class = lookup_interface (CLASS_NAME (class));
6970 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6971 || !CLASS_SUPER_NAME (class))
6972 add_method_to_hash_list (cls_method_hash_list, method);
6979 add_class (tree class_name, tree name)
6981 struct interface_tuple **slot;
6983 /* Put interfaces on list in reverse order. */
6984 TREE_CHAIN (class_name) = interface_chain;
6985 interface_chain = class_name;
6987 if (interface_htab == NULL)
6988 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6989 slot = (struct interface_tuple **)
6990 htab_find_slot_with_hash (interface_htab, name,
6991 IDENTIFIER_HASH_VALUE (name),
6995 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
6998 (*slot)->class_name = class_name;
7000 return interface_chain;
7004 add_category (tree class, tree category)
7006 /* Put categories on list in reverse order. */
7007 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
7011 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7012 IDENTIFIER_POINTER (CLASS_NAME (class)),
7013 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
7017 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
7018 CLASS_CATEGORY_LIST (class) = category;
7022 /* Called after parsing each instance variable declaration. Necessary to
7023 preserve typedefs and implement public/private...
7025 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
7028 add_instance_variable (tree class, int public, tree field_decl)
7030 tree field_type = TREE_TYPE (field_decl);
7031 const char *ivar_name = DECL_NAME (field_decl)
7032 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
7036 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7038 error ("illegal reference type specified for instance variable %qs",
7040 /* Return class as is without adding this ivar. */
7045 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7046 || TYPE_SIZE (field_type) == error_mark_node)
7047 /* 'type[0]' is allowed, but 'type[]' is not! */
7049 error ("instance variable %qs has unknown size", ivar_name);
7050 /* Return class as is without adding this ivar. */
7055 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7056 need to either (1) warn the user about it or (2) generate suitable
7057 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7058 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7059 if (MAYBE_CLASS_TYPE_P (field_type)
7060 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7061 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7062 || TYPE_POLYMORPHIC_P (field_type)))
7064 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7066 if (flag_objc_call_cxx_cdtors)
7068 /* Since the ObjC runtime will be calling the constructors and
7069 destructors for us, the only thing we can't handle is the lack
7070 of a default constructor. */
7071 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7072 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7074 warning (0, "type %qs has no default constructor to call",
7077 /* If we cannot call a constructor, we should also avoid
7078 calling the destructor, for symmetry. */
7079 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7080 warning (0, "destructor for %qs shall not be run either",
7086 static bool warn_cxx_ivars = false;
7088 if (TYPE_POLYMORPHIC_P (field_type))
7090 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7092 error ("type %qs has virtual member functions", type_name);
7093 error ("illegal aggregate type %qs specified "
7094 "for instance variable %qs",
7095 type_name, ivar_name);
7096 /* Return class as is without adding this ivar. */
7100 /* User-defined constructors and destructors are not known to Obj-C
7101 and hence will not be called. This may or may not be a problem. */
7102 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7103 warning (0, "type %qs has a user-defined constructor", type_name);
7104 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7105 warning (0, "type %qs has a user-defined destructor", type_name);
7107 if (!warn_cxx_ivars)
7109 warning (0, "C++ constructors and destructors will not "
7110 "be invoked for Objective-C fields");
7111 warn_cxx_ivars = true;
7117 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7121 TREE_PUBLIC (field_decl) = 0;
7122 TREE_PRIVATE (field_decl) = 0;
7123 TREE_PROTECTED (field_decl) = 1;
7127 TREE_PUBLIC (field_decl) = 1;
7128 TREE_PRIVATE (field_decl) = 0;
7129 TREE_PROTECTED (field_decl) = 0;
7133 TREE_PUBLIC (field_decl) = 0;
7134 TREE_PRIVATE (field_decl) = 1;
7135 TREE_PROTECTED (field_decl) = 0;
7140 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
7146 is_ivar (tree decl_chain, tree ident)
7148 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7149 if (DECL_NAME (decl_chain) == ident)
7154 /* True if the ivar is private and we are not in its implementation. */
7157 is_private (tree decl)
7159 return (TREE_PRIVATE (decl)
7160 && ! is_ivar (CLASS_IVARS (implementation_template),
7164 /* We have an instance variable reference;, check to see if it is public. */
7167 objc_is_public (tree expr, tree identifier)
7169 tree basetype, decl;
7172 if (processing_template_decl)
7176 if (TREE_TYPE (expr) == error_mark_node)
7179 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7181 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7183 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7185 tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
7189 error ("cannot find interface declaration for %qs",
7190 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7194 if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
7196 if (TREE_PUBLIC (decl))
7199 /* Important difference between the Stepstone translator:
7200 all instance variables should be public within the context
7201 of the implementation. */
7202 if (objc_implementation_context
7203 && ((TREE_CODE (objc_implementation_context)
7204 == CLASS_IMPLEMENTATION_TYPE)
7205 || (TREE_CODE (objc_implementation_context)
7206 == CATEGORY_IMPLEMENTATION_TYPE)))
7208 tree curtype = TYPE_MAIN_VARIANT
7209 (CLASS_STATIC_TEMPLATE
7210 (implementation_template));
7212 if (basetype == curtype
7213 || DERIVED_FROM_P (basetype, curtype))
7215 int private = is_private (decl);
7218 error ("instance variable %qs is declared private",
7219 IDENTIFIER_POINTER (DECL_NAME (decl)));
7225 /* The 2.95.2 compiler sometimes allowed C functions to access
7226 non-@public ivars. We will let this slide for now... */
7227 if (!objc_method_context)
7229 warning (0, "instance variable %qs is %s; "
7230 "this will be a hard error in the future",
7231 IDENTIFIER_POINTER (identifier),
7232 TREE_PRIVATE (decl) ? "@private" : "@protected");
7236 error ("instance variable %qs is declared %s",
7237 IDENTIFIER_POINTER (identifier),
7238 TREE_PRIVATE (decl) ? "private" : "protected");
7247 /* Make sure all entries in CHAIN are also in LIST. */
7250 check_methods (tree chain, tree list, int mtype)
7256 if (!lookup_method (list, chain))
7260 if (TREE_CODE (objc_implementation_context)
7261 == CLASS_IMPLEMENTATION_TYPE)
7262 warning (0, "incomplete implementation of class %qs",
7263 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7264 else if (TREE_CODE (objc_implementation_context)
7265 == CATEGORY_IMPLEMENTATION_TYPE)
7266 warning (0, "incomplete implementation of category %qs",
7267 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7271 warning (0, "method definition for %<%c%s%> not found",
7272 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7275 chain = TREE_CHAIN (chain);
7281 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7284 conforms_to_protocol (tree class, tree protocol)
7286 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7288 tree p = CLASS_PROTOCOL_LIST (class);
7289 while (p && TREE_VALUE (p) != protocol)
7294 tree super = (CLASS_SUPER_NAME (class)
7295 ? lookup_interface (CLASS_SUPER_NAME (class))
7297 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7306 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7307 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7310 check_methods_accessible (tree chain, tree context, int mtype)
7314 tree base_context = context;
7318 context = base_context;
7322 list = CLASS_CLS_METHODS (context);
7324 list = CLASS_NST_METHODS (context);
7326 if (lookup_method (list, chain))
7329 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7330 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7331 context = (CLASS_SUPER_NAME (context)
7332 ? lookup_interface (CLASS_SUPER_NAME (context))
7335 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7336 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7337 context = (CLASS_NAME (context)
7338 ? lookup_interface (CLASS_NAME (context))
7344 if (context == NULL_TREE)
7348 if (TREE_CODE (objc_implementation_context)
7349 == CLASS_IMPLEMENTATION_TYPE)
7350 warning (0, "incomplete implementation of class %qs",
7352 (CLASS_NAME (objc_implementation_context)));
7353 else if (TREE_CODE (objc_implementation_context)
7354 == CATEGORY_IMPLEMENTATION_TYPE)
7355 warning (0, "incomplete implementation of category %qs",
7357 (CLASS_SUPER_NAME (objc_implementation_context)));
7360 warning (0, "method definition for %<%c%s%> not found",
7361 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7364 chain = TREE_CHAIN (chain); /* next method... */
7369 /* Check whether the current interface (accessible via
7370 'objc_implementation_context') actually implements protocol P, along
7371 with any protocols that P inherits. */
7374 check_protocol (tree p, const char *type, const char *name)
7376 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7380 /* Ensure that all protocols have bodies! */
7383 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7384 CLASS_CLS_METHODS (objc_implementation_context),
7386 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7387 CLASS_NST_METHODS (objc_implementation_context),
7392 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7393 objc_implementation_context,
7395 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7396 objc_implementation_context,
7401 warning (0, "%s %qs does not fully implement the %qs protocol",
7402 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7405 /* Check protocols recursively. */
7406 if (PROTOCOL_LIST (p))
7408 tree subs = PROTOCOL_LIST (p);
7410 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7414 tree sub = TREE_VALUE (subs);
7416 /* If the superclass does not conform to the protocols
7417 inherited by P, then we must! */
7418 if (!super_class || !conforms_to_protocol (super_class, sub))
7419 check_protocol (sub, type, name);
7420 subs = TREE_CHAIN (subs);
7425 /* Check whether the current interface (accessible via
7426 'objc_implementation_context') actually implements the protocols listed
7430 check_protocols (tree proto_list, const char *type, const char *name)
7432 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7434 tree p = TREE_VALUE (proto_list);
7436 check_protocol (p, type, name);
7440 /* Make sure that the class CLASS_NAME is defined
7441 CODE says which kind of thing CLASS_NAME ought to be.
7442 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7443 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7446 start_class (enum tree_code code, tree class_name, tree super_name,
7452 if (current_namespace != global_namespace) {
7453 error ("Objective-C declarations may only appear in global scope");
7455 #endif /* OBJCPLUS */
7457 if (objc_implementation_context)
7459 warning (0, "%<@end%> missing in implementation context");
7460 finish_class (objc_implementation_context);
7461 objc_ivar_chain = NULL_TREE;
7462 objc_implementation_context = NULL_TREE;
7465 class = make_node (code);
7466 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7468 /* Check for existence of the super class, if one was specified. Note
7469 that we must have seen an @interface, not just a @class. If we
7470 are looking at a @compatibility_alias, traverse it first. */
7471 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7474 tree super = objc_is_class_name (super_name);
7476 if (!super || !lookup_interface (super))
7478 error ("cannot find interface declaration for %qs, superclass of %qs",
7479 IDENTIFIER_POINTER (super ? super : super_name),
7480 IDENTIFIER_POINTER (class_name));
7481 super_name = NULL_TREE;
7487 CLASS_NAME (class) = class_name;
7488 CLASS_SUPER_NAME (class) = super_name;
7489 CLASS_CLS_METHODS (class) = NULL_TREE;
7491 if (! objc_is_class_name (class_name)
7492 && (decl = lookup_name (class_name)))
7494 error ("%qs redeclared as different kind of symbol",
7495 IDENTIFIER_POINTER (class_name));
7496 error ("previous declaration of %q+D",
7500 if (code == CLASS_IMPLEMENTATION_TYPE)
7505 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7506 if (TREE_VALUE (chain) == class_name)
7508 error ("reimplementation of class %qs",
7509 IDENTIFIER_POINTER (class_name));
7510 return error_mark_node;
7512 implemented_classes = tree_cons (NULL_TREE, class_name,
7513 implemented_classes);
7516 /* Reset for multiple classes per file. */
7519 objc_implementation_context = class;
7521 /* Lookup the interface for this implementation. */
7523 if (!(implementation_template = lookup_interface (class_name)))
7525 warning (0, "cannot find interface declaration for %qs",
7526 IDENTIFIER_POINTER (class_name));
7527 add_class (implementation_template = objc_implementation_context,
7531 /* If a super class has been specified in the implementation,
7532 insure it conforms to the one specified in the interface. */
7535 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7537 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7538 const char *const name =
7539 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7540 error ("conflicting super class name %qs",
7541 IDENTIFIER_POINTER (super_name));
7542 error ("previous declaration of %qs", name);
7545 else if (! super_name)
7547 CLASS_SUPER_NAME (objc_implementation_context)
7548 = CLASS_SUPER_NAME (implementation_template);
7552 else if (code == CLASS_INTERFACE_TYPE)
7554 if (lookup_interface (class_name))
7556 error ("duplicate interface declaration for class %qs",
7558 warning (0, "duplicate interface declaration for class %qs",
7560 IDENTIFIER_POINTER (class_name));
7562 add_class (class, class_name);
7565 CLASS_PROTOCOL_LIST (class)
7566 = lookup_and_install_protocols (protocol_list);
7569 else if (code == CATEGORY_INTERFACE_TYPE)
7571 tree class_category_is_assoc_with;
7573 /* For a category, class_name is really the name of the class that
7574 the following set of methods will be associated with. We must
7575 find the interface so that can derive the objects template. */
7577 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7579 error ("cannot find interface declaration for %qs",
7580 IDENTIFIER_POINTER (class_name));
7581 exit (FATAL_EXIT_CODE);
7584 add_category (class_category_is_assoc_with, class);
7587 CLASS_PROTOCOL_LIST (class)
7588 = lookup_and_install_protocols (protocol_list);
7591 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7593 /* Reset for multiple classes per file. */
7596 objc_implementation_context = class;
7598 /* For a category, class_name is really the name of the class that
7599 the following set of methods will be associated with. We must
7600 find the interface so that can derive the objects template. */
7602 if (!(implementation_template = lookup_interface (class_name)))
7604 error ("cannot find interface declaration for %qs",
7605 IDENTIFIER_POINTER (class_name));
7606 exit (FATAL_EXIT_CODE);
7613 continue_class (tree class)
7615 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
7616 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7618 struct imp_entry *imp_entry;
7620 /* Check consistency of the instance variables. */
7622 if (CLASS_RAW_IVARS (class))
7623 check_ivars (implementation_template, class);
7625 /* code generation */
7628 push_lang_context (lang_name_c);
7631 build_private_template (implementation_template);
7632 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7633 objc_instance_type = build_pointer_type (uprivate_record);
7635 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7637 imp_entry->next = imp_list;
7638 imp_entry->imp_context = class;
7639 imp_entry->imp_template = implementation_template;
7641 synth_forward_declarations ();
7642 imp_entry->class_decl = UOBJC_CLASS_decl;
7643 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7644 imp_entry->has_cxx_cdtors = 0;
7646 /* Append to front and increment count. */
7647 imp_list = imp_entry;
7648 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7654 pop_lang_context ();
7655 #endif /* OBJCPLUS */
7657 return get_class_ivars (implementation_template, true);
7660 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7663 push_lang_context (lang_name_c);
7664 #endif /* OBJCPLUS */
7666 build_private_template (class);
7669 pop_lang_context ();
7670 #endif /* OBJCPLUS */
7676 return error_mark_node;
7679 /* This is called once we see the "@end" in an interface/implementation. */
7682 finish_class (tree class)
7684 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7686 /* All code generation is done in finish_objc. */
7688 if (implementation_template != objc_implementation_context)
7690 /* Ensure that all method listed in the interface contain bodies. */
7691 check_methods (CLASS_CLS_METHODS (implementation_template),
7692 CLASS_CLS_METHODS (objc_implementation_context), '+');
7693 check_methods (CLASS_NST_METHODS (implementation_template),
7694 CLASS_NST_METHODS (objc_implementation_context), '-');
7696 if (CLASS_PROTOCOL_LIST (implementation_template))
7697 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7699 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7703 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7705 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
7709 /* Ensure all method listed in the interface contain bodies. */
7710 check_methods (CLASS_CLS_METHODS (category),
7711 CLASS_CLS_METHODS (objc_implementation_context), '+');
7712 check_methods (CLASS_NST_METHODS (category),
7713 CLASS_NST_METHODS (objc_implementation_context), '-');
7715 if (CLASS_PROTOCOL_LIST (category))
7716 check_protocols (CLASS_PROTOCOL_LIST (category),
7718 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7724 add_protocol (tree protocol)
7726 /* Put protocol on list in reverse order. */
7727 TREE_CHAIN (protocol) = protocol_chain;
7728 protocol_chain = protocol;
7729 return protocol_chain;
7733 lookup_protocol (tree ident)
7737 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7738 if (ident == PROTOCOL_NAME (chain))
7744 /* This function forward declares the protocols named by NAMES. If
7745 they are already declared or defined, the function has no effect. */
7748 objc_declare_protocols (tree names)
7753 if (current_namespace != global_namespace) {
7754 error ("Objective-C declarations may only appear in global scope");
7756 #endif /* OBJCPLUS */
7758 for (list = names; list; list = TREE_CHAIN (list))
7760 tree name = TREE_VALUE (list);
7762 if (lookup_protocol (name) == NULL_TREE)
7764 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7766 TYPE_LANG_SLOT_1 (protocol)
7767 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7768 PROTOCOL_NAME (protocol) = name;
7769 PROTOCOL_LIST (protocol) = NULL_TREE;
7770 add_protocol (protocol);
7771 PROTOCOL_DEFINED (protocol) = 0;
7772 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7778 start_protocol (enum tree_code code, tree name, tree list)
7783 if (current_namespace != global_namespace) {
7784 error ("Objective-C declarations may only appear in global scope");
7786 #endif /* OBJCPLUS */
7788 protocol = lookup_protocol (name);
7792 protocol = make_node (code);
7793 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7795 PROTOCOL_NAME (protocol) = name;
7796 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7797 add_protocol (protocol);
7798 PROTOCOL_DEFINED (protocol) = 1;
7799 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7801 check_protocol_recursively (protocol, list);
7803 else if (! PROTOCOL_DEFINED (protocol))
7805 PROTOCOL_DEFINED (protocol) = 1;
7806 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7808 check_protocol_recursively (protocol, list);
7812 warning (0, "duplicate declaration for protocol %qs",
7813 IDENTIFIER_POINTER (name));
7819 /* "Encode" a data type into a string, which grows in util_obstack.
7820 ??? What is the FORMAT? Someone please document this! */
7823 encode_type_qualifiers (tree declspecs)
7827 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7829 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7830 obstack_1grow (&util_obstack, 'n');
7831 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7832 obstack_1grow (&util_obstack, 'N');
7833 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7834 obstack_1grow (&util_obstack, 'o');
7835 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7836 obstack_1grow (&util_obstack, 'O');
7837 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7838 obstack_1grow (&util_obstack, 'R');
7839 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7840 obstack_1grow (&util_obstack, 'V');
7844 /* Encode a pointer type. */
7847 encode_pointer (tree type, int curtype, int format)
7849 tree pointer_to = TREE_TYPE (type);
7851 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7853 if (OBJC_TYPE_NAME (pointer_to)
7854 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7856 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7858 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7860 obstack_1grow (&util_obstack, '@');
7863 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7864 && TYPE_OBJC_INTERFACE (pointer_to))
7866 if (generating_instance_variables)
7868 obstack_1grow (&util_obstack, '@');
7869 obstack_1grow (&util_obstack, '"');
7870 obstack_grow (&util_obstack, name, strlen (name));
7871 obstack_1grow (&util_obstack, '"');
7876 obstack_1grow (&util_obstack, '@');
7880 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7882 obstack_1grow (&util_obstack, '#');
7885 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7887 obstack_1grow (&util_obstack, ':');
7892 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7893 && TYPE_MODE (pointer_to) == QImode)
7895 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7896 ? OBJC_TYPE_NAME (pointer_to)
7897 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7899 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7901 /* It appears that "r*" means "const char *" rather than
7903 if (TYPE_READONLY (pointer_to))
7904 obstack_1grow (&util_obstack, 'r');
7906 obstack_1grow (&util_obstack, '*');
7911 /* We have a type that does not get special treatment. */
7913 /* NeXT extension */
7914 obstack_1grow (&util_obstack, '^');
7915 encode_type (pointer_to, curtype, format);
7919 encode_array (tree type, int curtype, int format)
7921 tree an_int_cst = TYPE_SIZE (type);
7922 tree array_of = TREE_TYPE (type);
7925 /* An incomplete array is treated like a pointer. */
7926 if (an_int_cst == NULL)
7928 encode_pointer (type, curtype, format);
7932 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
7933 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
7935 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7936 TREE_INT_CST_LOW (an_int_cst)
7937 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
7939 obstack_grow (&util_obstack, buffer, strlen (buffer));
7940 encode_type (array_of, curtype, format);
7941 obstack_1grow (&util_obstack, ']');
7946 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7948 tree field = TYPE_FIELDS (type);
7950 for (; field; field = TREE_CHAIN (field))
7953 /* C++ static members, and things that are not field at all,
7954 should not appear in the encoding. */
7955 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7959 /* Recursively encode fields of embedded base classes. */
7960 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7961 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7963 encode_aggregate_fields (TREE_TYPE (field),
7964 pointed_to, curtype, format);
7968 if (generating_instance_variables && !pointed_to)
7970 tree fname = DECL_NAME (field);
7972 obstack_1grow (&util_obstack, '"');
7974 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7975 obstack_grow (&util_obstack,
7976 IDENTIFIER_POINTER (fname),
7977 strlen (IDENTIFIER_POINTER (fname)));
7979 obstack_1grow (&util_obstack, '"');
7982 encode_field_decl (field, curtype, format);
7987 encode_aggregate_within (tree type, int curtype, int format, int left,
7991 /* NB: aggregates that are pointed to have slightly different encoding
7992 rules in that you never encode the names of instance variables. */
7993 int ob_size = obstack_object_size (&util_obstack);
7994 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
7995 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
7996 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
7998 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7999 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
8001 /* Traverse struct aliases; it is important to get the
8002 original struct and its tag name (if any). */
8003 type = TYPE_MAIN_VARIANT (type);
8004 name = OBJC_TYPE_NAME (type);
8005 /* Open parenth/bracket. */
8006 obstack_1grow (&util_obstack, left);
8008 /* Encode the struct/union tag name, or '?' if a tag was
8009 not provided. Typedef aliases do not qualify. */
8010 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8012 /* Did this struct have a tag? */
8013 && !TYPE_WAS_ANONYMOUS (type)
8016 obstack_grow (&util_obstack,
8017 IDENTIFIER_POINTER (name),
8018 strlen (IDENTIFIER_POINTER (name)));
8020 obstack_1grow (&util_obstack, '?');
8022 /* Encode the types (and possibly names) of the inner fields,
8024 if (inline_contents)
8026 obstack_1grow (&util_obstack, '=');
8027 encode_aggregate_fields (type, pointed_to, curtype, format);
8029 /* Close parenth/bracket. */
8030 obstack_1grow (&util_obstack, right);
8034 encode_aggregate (tree type, int curtype, int format)
8036 enum tree_code code = TREE_CODE (type);
8042 encode_aggregate_within (type, curtype, format, '{', '}');
8047 encode_aggregate_within (type, curtype, format, '(', ')');
8052 obstack_1grow (&util_obstack, 'i');
8060 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8064 encode_next_bitfield (int width)
8067 sprintf (buffer, "b%d", width);
8068 obstack_grow (&util_obstack, buffer, strlen (buffer));
8071 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8073 encode_type (tree type, int curtype, int format)
8075 enum tree_code code = TREE_CODE (type);
8078 if (type == error_mark_node)
8081 if (TYPE_READONLY (type))
8082 obstack_1grow (&util_obstack, 'r');
8084 if (code == INTEGER_TYPE)
8086 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8088 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8089 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8091 if (type == long_unsigned_type_node
8092 || type == long_integer_type_node)
8093 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8095 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8097 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8100 obstack_1grow (&util_obstack, c);
8103 else if (code == REAL_TYPE)
8105 /* Floating point types. */
8106 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8108 case 32: c = 'f'; break;
8111 case 128: c = 'd'; break;
8114 obstack_1grow (&util_obstack, c);
8117 else if (code == VOID_TYPE)
8118 obstack_1grow (&util_obstack, 'v');
8120 else if (code == BOOLEAN_TYPE)
8121 obstack_1grow (&util_obstack, 'B');
8123 else if (code == ARRAY_TYPE)
8124 encode_array (type, curtype, format);
8126 else if (code == POINTER_TYPE)
8127 encode_pointer (type, curtype, format);
8129 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8130 encode_aggregate (type, curtype, format);
8132 else if (code == FUNCTION_TYPE) /* '?' */
8133 obstack_1grow (&util_obstack, '?');
8135 else if (code == COMPLEX_TYPE)
8137 obstack_1grow (&util_obstack, 'j');
8138 encode_type (TREE_TYPE (type), curtype, format);
8143 encode_gnu_bitfield (int position, tree type, int size)
8145 enum tree_code code = TREE_CODE (type);
8147 char charType = '?';
8149 if (code == INTEGER_TYPE)
8151 if (integer_zerop (TYPE_MIN_VALUE (type)))
8153 /* Unsigned integer types. */
8155 if (TYPE_MODE (type) == QImode)
8157 else if (TYPE_MODE (type) == HImode)
8159 else if (TYPE_MODE (type) == SImode)
8161 if (type == long_unsigned_type_node)
8166 else if (TYPE_MODE (type) == DImode)
8171 /* Signed integer types. */
8173 if (TYPE_MODE (type) == QImode)
8175 else if (TYPE_MODE (type) == HImode)
8177 else if (TYPE_MODE (type) == SImode)
8179 if (type == long_integer_type_node)
8185 else if (TYPE_MODE (type) == DImode)
8189 else if (code == ENUMERAL_TYPE)
8194 sprintf (buffer, "b%d%c%d", position, charType, size);
8195 obstack_grow (&util_obstack, buffer, strlen (buffer));
8199 encode_field_decl (tree field_decl, int curtype, int format)
8204 /* C++ static members, and things that are not fields at all,
8205 should not appear in the encoding. */
8206 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8210 type = TREE_TYPE (field_decl);
8212 /* Generate the bitfield typing information, if needed. Note the difference
8213 between GNU and NeXT runtimes. */
8214 if (DECL_BIT_FIELD_TYPE (field_decl))
8216 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8218 if (flag_next_runtime)
8219 encode_next_bitfield (size);
8221 encode_gnu_bitfield (int_bit_position (field_decl),
8222 DECL_BIT_FIELD_TYPE (field_decl), size);
8225 encode_type (TREE_TYPE (field_decl), curtype, format);
8228 static GTY(()) tree objc_parmlist = NULL_TREE;
8230 /* Append PARM to a list of formal parameters of a method, making a necessary
8231 array-to-pointer adjustment along the way. */
8234 objc_push_parm (tree parm)
8236 bool relayout_needed = false;
8238 if (TREE_TYPE (parm) == error_mark_node)
8240 objc_parmlist = chainon (objc_parmlist, parm);
8244 /* Decay arrays and functions into pointers. */
8245 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8247 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8248 relayout_needed = true;
8250 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8252 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8253 relayout_needed = true;
8256 if (relayout_needed)
8257 relayout_decl (parm);
8260 DECL_ARG_TYPE (parm)
8261 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8263 /* Record constancy and volatility. */
8264 c_apply_type_quals_to_decl
8265 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8266 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8267 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8269 objc_parmlist = chainon (objc_parmlist, parm);
8272 /* Retrieve the formal parameter list constructed via preceding calls to
8273 objc_push_parm(). */
8277 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8279 static struct c_arg_info *
8280 objc_get_parm_info (int have_ellipsis)
8284 tree parm_info = objc_parmlist;
8285 objc_parmlist = NULL_TREE;
8289 tree parm_info = objc_parmlist;
8290 struct c_arg_info *arg_info;
8291 /* The C front-end requires an elaborate song and dance at
8294 declare_parm_level ();
8297 tree next = TREE_CHAIN (parm_info);
8299 TREE_CHAIN (parm_info) = NULL_TREE;
8300 parm_info = pushdecl (parm_info);
8301 finish_decl (parm_info, NULL_TREE, NULL_TREE);
8304 arg_info = get_parm_info (have_ellipsis);
8306 objc_parmlist = NULL_TREE;
8311 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8312 method definitions. In the case of instance methods, we can be more
8313 specific as to the type of 'self'. */
8316 synth_self_and_ucmd_args (void)
8320 if (objc_method_context
8321 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8322 self_type = objc_instance_type;
8324 /* Really a `struct objc_class *'. However, we allow people to
8325 assign to self, which changes its type midstream. */
8326 self_type = objc_object_type;
8329 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8332 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8335 /* Transform an Objective-C method definition into a static C function
8336 definition, synthesizing the first two arguments, "self" and "_cmd",
8340 start_method_def (tree method)
8346 struct c_arg_info *parm_info;
8348 int have_ellipsis = 0;
8350 /* If we are defining a "dealloc" method in a non-root class, we
8351 will need to check if a [super dealloc] is missing, and warn if
8353 if(CLASS_SUPER_NAME (objc_implementation_context)
8354 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8355 should_call_super_dealloc = 1;
8357 should_call_super_dealloc = 0;
8359 /* Required to implement _msgSuper. */
8360 objc_method_context = method;
8361 UOBJC_SUPER_decl = NULL_TREE;
8363 /* Generate prototype declarations for arguments..."new-style". */
8364 synth_self_and_ucmd_args ();
8366 /* Generate argument declarations if a keyword_decl. */
8367 parmlist = METHOD_SEL_ARGS (method);
8370 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8372 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8373 objc_push_parm (parm);
8374 parmlist = TREE_CHAIN (parmlist);
8377 if (METHOD_ADD_ARGS (method))
8381 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8382 akey; akey = TREE_CHAIN (akey))
8384 objc_push_parm (TREE_VALUE (akey));
8387 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8391 parm_info = objc_get_parm_info (have_ellipsis);
8393 really_start_method (objc_method_context, parm_info);
8397 warn_with_method (const char *message, int mtype, tree method)
8399 /* Add a readable method name to the warning. */
8400 warning (0, "%J%s %<%c%s%>", method,
8401 message, mtype, gen_method_decl (method));
8404 /* Return 1 if TYPE1 is equivalent to TYPE2
8405 for purposes of method overloading. */
8408 objc_types_are_equivalent (tree type1, tree type2)
8413 /* Strip away indirections. */
8414 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8415 && (TREE_CODE (type1) == TREE_CODE (type2)))
8416 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8417 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8420 type1 = (TYPE_HAS_OBJC_INFO (type1)
8421 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8423 type2 = (TYPE_HAS_OBJC_INFO (type2)
8424 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8427 if (list_length (type1) == list_length (type2))
8429 for (; type2; type2 = TREE_CHAIN (type2))
8430 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8437 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8440 objc_types_share_size_and_alignment (tree type1, tree type2)
8442 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8443 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8446 /* Return 1 if PROTO1 is equivalent to PROTO2
8447 for purposes of method overloading. Ordinarily, the type signatures
8448 should match up exactly, unless STRICT is zero, in which case we
8449 shall allow differences in which the size and alignment of a type
8453 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8457 /* The following test is needed in case there are hashing
8459 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8462 /* Compare return types. */
8463 type1 = TREE_VALUE (TREE_TYPE (proto1));
8464 type2 = TREE_VALUE (TREE_TYPE (proto2));
8466 if (!objc_types_are_equivalent (type1, type2)
8467 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8470 /* Compare argument types. */
8471 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8472 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8474 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8476 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8478 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8479 TREE_VALUE (type2))))
8483 return (!type1 && !type2);
8486 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8487 this occurs. ObjC method dispatches are _not_ like C++ virtual
8488 member function dispatches, and we account for the difference here. */
8491 objc_fold_obj_type_ref (tree ref, tree known_type)
8493 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8494 tree known_type ATTRIBUTE_UNUSED)
8498 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8500 /* If the receiver does not have virtual member functions, there
8501 is nothing we can (or need to) do here. */
8505 /* Let C++ handle C++ virtual functions. */
8506 return cp_fold_obj_type_ref (ref, known_type);
8508 /* For plain ObjC, we currently do not need to do anything. */
8514 objc_start_function (tree name, tree type, tree attrs,
8518 struct c_arg_info *params
8522 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8525 DECL_ARGUMENTS (fndecl) = params;
8526 DECL_INITIAL (fndecl) = error_mark_node;
8527 DECL_EXTERNAL (fndecl) = 0;
8528 TREE_STATIC (fndecl) = 1;
8529 retrofit_lang_decl (fndecl);
8530 cplus_decl_attributes (&fndecl, attrs, 0);
8531 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8533 struct c_label_context_se *nstack_se;
8534 struct c_label_context_vm *nstack_vm;
8535 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8536 nstack_se->labels_def = NULL;
8537 nstack_se->labels_used = NULL;
8538 nstack_se->next = label_context_stack_se;
8539 label_context_stack_se = nstack_se;
8540 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8541 nstack_vm->labels_def = NULL;
8542 nstack_vm->labels_used = NULL;
8543 nstack_vm->scope = 0;
8544 nstack_vm->next = label_context_stack_vm;
8545 label_context_stack_vm = nstack_vm;
8546 current_function_returns_value = 0; /* Assume, until we see it does. */
8547 current_function_returns_null = 0;
8549 decl_attributes (&fndecl, attrs, 0);
8550 announce_function (fndecl);
8551 DECL_INITIAL (fndecl) = error_mark_node;
8552 DECL_EXTERNAL (fndecl) = 0;
8553 TREE_STATIC (fndecl) = 1;
8554 current_function_decl = pushdecl (fndecl);
8556 declare_parm_level ();
8557 DECL_RESULT (current_function_decl)
8558 = build_decl (RESULT_DECL, NULL_TREE,
8559 TREE_TYPE (TREE_TYPE (current_function_decl)));
8560 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8561 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8562 start_fname_decls ();
8563 store_parm_decls_from (params);
8566 TREE_USED (current_function_decl) = 1;
8569 /* - Generate an identifier for the function. the format is "_n_cls",
8570 where 1 <= n <= nMethods, and cls is the name the implementation we
8572 - Install the return type from the method declaration.
8573 - If we have a prototype, check for type consistency. */
8576 really_start_method (tree method,
8580 struct c_arg_info *parmlist
8584 tree ret_type, meth_type;
8586 const char *sel_name, *class_name, *cat_name;
8589 /* Synth the storage class & assemble the return type. */
8590 ret_type = TREE_VALUE (TREE_TYPE (method));
8592 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8593 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8594 cat_name = ((TREE_CODE (objc_implementation_context)
8595 == CLASS_IMPLEMENTATION_TYPE)
8597 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8600 /* Make sure this is big enough for any plausible method label. */
8601 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8602 + (cat_name ? strlen (cat_name) : 0));
8604 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8605 class_name, cat_name, sel_name, method_slot);
8607 method_id = get_identifier (buf);
8610 /* Objective-C methods cannot be overloaded, so we don't need
8611 the type encoding appended. It looks bad anyway... */
8612 push_lang_context (lang_name_c);
8616 = build_function_type (ret_type,
8617 get_arg_type_list (method, METHOD_DEF, 0));
8618 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8620 /* Set self_decl from the first argument. */
8621 self_decl = DECL_ARGUMENTS (current_function_decl);
8623 /* Suppress unused warnings. */
8624 TREE_USED (self_decl) = 1;
8625 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8627 pop_lang_context ();
8630 METHOD_DEFINITION (method) = current_function_decl;
8632 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8634 if (implementation_template != objc_implementation_context)
8637 = lookup_method_static (implementation_template,
8638 METHOD_SEL_NAME (method),
8639 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8640 | OBJC_LOOKUP_NO_SUPER));
8644 if (!comp_proto_with_proto (method, proto, 1))
8646 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
8648 warn_with_method ("conflicting types for", type, method);
8649 warn_with_method ("previous declaration of", type, proto);
8654 /* We have a method @implementation even though we did not
8655 see a corresponding @interface declaration (which is allowed
8656 by Objective-C rules). Go ahead and place the method in
8657 the @interface anyway, so that message dispatch lookups
8659 tree interface = implementation_template;
8661 if (TREE_CODE (objc_implementation_context)
8662 == CATEGORY_IMPLEMENTATION_TYPE)
8663 interface = lookup_category
8665 CLASS_SUPER_NAME (objc_implementation_context));
8668 objc_add_method (interface, copy_node (method),
8669 TREE_CODE (method) == CLASS_METHOD_DECL);
8674 static void *UOBJC_SUPER_scope = 0;
8676 /* _n_Method (id self, SEL sel, ...)
8678 struct objc_super _S;
8679 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8683 get_super_receiver (void)
8685 if (objc_method_context)
8687 tree super_expr, super_expr_list;
8689 if (!UOBJC_SUPER_decl)
8691 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8692 objc_super_template);
8693 /* This prevents `unused variable' warnings when compiling with -Wall. */
8694 TREE_USED (UOBJC_SUPER_decl) = 1;
8695 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8696 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
8697 UOBJC_SUPER_scope = objc_get_current_scope ();
8700 /* Set receiver to self. */
8701 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8702 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
8703 super_expr_list = super_expr;
8705 /* Set class to begin searching. */
8706 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8707 get_identifier ("super_class"));
8709 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8711 /* [_cls, __cls]Super are "pre-built" in
8712 synth_forward_declarations. */
8714 super_expr = build_modify_expr (super_expr, NOP_EXPR,
8715 ((TREE_CODE (objc_method_context)
8716 == INSTANCE_METHOD_DECL)
8718 : uucls_super_ref));
8722 /* We have a category. */
8724 tree super_name = CLASS_SUPER_NAME (implementation_template);
8727 /* Barf if super used in a category of Object. */
8730 error ("no super class declared in interface for %qs",
8731 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8732 return error_mark_node;
8735 if (flag_next_runtime && !flag_zero_link)
8737 super_class = objc_get_class_reference (super_name);
8738 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8739 /* If we are in a class method, we must retrieve the
8740 _metaclass_ for the current class, pointed at by
8741 the class's "isa" pointer. The following assumes that
8742 "isa" is the first ivar in a class (which it must be). */
8744 = build_indirect_ref
8745 (build_c_cast (build_pointer_type (objc_class_type),
8746 super_class), "unary *");
8750 add_class_reference (super_name);
8751 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8752 ? objc_get_class_decl : objc_get_meta_class_decl);
8753 assemble_external (super_class);
8755 = build_function_call
8759 my_build_string_pointer
8760 (IDENTIFIER_LENGTH (super_name) + 1,
8761 IDENTIFIER_POINTER (super_name))));
8765 = build_modify_expr (super_expr, NOP_EXPR,
8766 build_c_cast (TREE_TYPE (super_expr),
8770 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8772 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
8773 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8775 return super_expr_list;
8779 error ("[super ...] must appear in a method context");
8780 return error_mark_node;
8784 /* When exiting a scope, sever links to a 'super' declaration (if any)
8785 therein contained. */
8788 objc_clear_super_receiver (void)
8790 if (objc_method_context
8791 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8792 UOBJC_SUPER_decl = 0;
8793 UOBJC_SUPER_scope = 0;
8798 objc_finish_method_definition (tree fndecl)
8800 /* We cannot validly inline ObjC methods, at least not without a language
8801 extension to declare that a method need not be dynamically
8802 dispatched, so suppress all thoughts of doing so. */
8803 DECL_INLINE (fndecl) = 0;
8804 DECL_UNINLINABLE (fndecl) = 1;
8807 /* The C++ front-end will have called finish_function() for us. */
8811 METHOD_ENCODING (objc_method_context)
8812 = encode_method_prototype (objc_method_context);
8814 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8815 since the optimizer may find "may be used before set" errors. */
8816 objc_method_context = NULL_TREE;
8818 if (should_call_super_dealloc)
8819 warning (0, "method possibly missing a [super dealloc] call");
8824 lang_report_error_function (tree decl)
8826 if (objc_method_context)
8828 fprintf (stderr, "In method %qs\n",
8829 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8838 /* Given a tree DECL node, produce a printable description of it in the given
8839 buffer, overwriting the buffer. */
8842 gen_declaration (tree decl)
8848 gen_type_name_0 (TREE_TYPE (decl));
8850 if (DECL_NAME (decl))
8852 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8853 strcat (errbuf, " ");
8855 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8858 if (DECL_INITIAL (decl)
8859 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8860 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8861 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8867 /* Given a tree TYPE node, produce a printable description of it in the given
8868 buffer, overwriting the buffer. */
8871 gen_type_name_0 (tree type)
8873 tree orig = type, proto;
8875 if (TYPE_P (type) && TYPE_NAME (type))
8876 type = TYPE_NAME (type);
8877 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8879 tree inner = TREE_TYPE (type);
8881 while (TREE_CODE (inner) == ARRAY_TYPE)
8882 inner = TREE_TYPE (inner);
8884 gen_type_name_0 (inner);
8886 if (!POINTER_TYPE_P (inner))
8887 strcat (errbuf, " ");
8889 if (POINTER_TYPE_P (type))
8890 strcat (errbuf, "*");
8892 while (type != inner)
8894 strcat (errbuf, "[");
8896 if (TYPE_DOMAIN (type))
8900 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8902 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8903 strcat (errbuf, sz);
8906 strcat (errbuf, "]");
8907 type = TREE_TYPE (type);
8913 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8914 type = DECL_NAME (type);
8916 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
8917 ? IDENTIFIER_POINTER (type)
8920 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8921 if (objc_is_id (orig))
8922 orig = TREE_TYPE (orig);
8924 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8928 strcat (errbuf, " <");
8932 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8933 proto = TREE_CHAIN (proto);
8934 strcat (errbuf, proto ? ", " : ">");
8943 gen_type_name (tree type)
8947 return gen_type_name_0 (type);
8950 /* Given a method tree, put a printable description into the given
8951 buffer (overwriting) and return a pointer to the buffer. */
8954 gen_method_decl (tree method)
8958 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8959 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8960 strcat (errbuf, ")");
8961 chain = METHOD_SEL_ARGS (method);
8965 /* We have a chain of keyword_decls. */
8968 if (KEYWORD_KEY_NAME (chain))
8969 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8971 strcat (errbuf, ":(");
8972 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8973 strcat (errbuf, ")");
8975 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8976 if ((chain = TREE_CHAIN (chain)))
8977 strcat (errbuf, " ");
8981 if (METHOD_ADD_ARGS (method))
8983 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8985 /* Know we have a chain of parm_decls. */
8988 strcat (errbuf, ", ");
8989 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8990 chain = TREE_CHAIN (chain);
8993 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8994 strcat (errbuf, ", ...");
8999 /* We have a unary selector. */
9000 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
9008 /* Dump an @interface declaration of the supplied class CHAIN to the
9009 supplied file FP. Used to implement the -gen-decls option (which
9010 prints out an @interface declaration of all classes compiled in
9011 this run); potentially useful for debugging the compiler too. */
9013 dump_interface (FILE *fp, tree chain)
9015 /* FIXME: A heap overflow here whenever a method (or ivar)
9016 declaration is so long that it doesn't fit in the buffer. The
9017 code and all the related functions should be rewritten to avoid
9018 using fixed size buffers. */
9019 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9020 tree ivar_decls = CLASS_RAW_IVARS (chain);
9021 tree nst_methods = CLASS_NST_METHODS (chain);
9022 tree cls_methods = CLASS_CLS_METHODS (chain);
9024 fprintf (fp, "\n@interface %s", my_name);
9026 /* CLASS_SUPER_NAME is used to store the superclass name for
9027 classes, and the category name for categories. */
9028 if (CLASS_SUPER_NAME (chain))
9030 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9032 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9033 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9035 fprintf (fp, " (%s)\n", name);
9039 fprintf (fp, " : %s\n", name);
9045 /* FIXME - the following doesn't seem to work at the moment. */
9048 fprintf (fp, "{\n");
9051 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9052 ivar_decls = TREE_CHAIN (ivar_decls);
9055 fprintf (fp, "}\n");
9060 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9061 nst_methods = TREE_CHAIN (nst_methods);
9066 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9067 cls_methods = TREE_CHAIN (cls_methods);
9070 fprintf (fp, "@end\n");
9073 /* Demangle function for Objective-C */
9075 objc_demangle (const char *mangled)
9077 char *demangled, *cp;
9079 if (mangled[0] == '_' &&
9080 (mangled[1] == 'i' || mangled[1] == 'c') &&
9083 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9084 if (mangled[1] == 'i')
9085 *cp++ = '-'; /* for instance method */
9087 *cp++ = '+'; /* for class method */
9088 *cp++ = '['; /* opening left brace */
9089 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9090 while (*cp && *cp == '_')
9091 cp++; /* skip any initial underbars in class name */
9092 cp = strchr(cp, '_'); /* find first non-initial underbar */
9095 free(demangled); /* not mangled name */
9098 if (cp[1] == '_') /* easy case: no category name */
9100 *cp++ = ' '; /* replace two '_' with one ' ' */
9101 strcpy(cp, mangled + (cp - demangled) + 2);
9105 *cp++ = '('; /* less easy case: category name */
9106 cp = strchr(cp, '_');
9109 free(demangled); /* not mangled name */
9113 *cp++ = ' '; /* overwriting 1st char of method name... */
9114 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9116 while (*cp && *cp == '_')
9117 cp++; /* skip any initial underbars in method name */
9120 *cp = ':'; /* replace remaining '_' with ':' */
9121 *cp++ = ']'; /* closing right brace */
9122 *cp++ = 0; /* string terminator */
9126 return mangled; /* not an objc mangled name */
9130 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9132 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9138 gcc_obstack_init (&util_obstack);
9139 util_firstobj = (char *) obstack_finish (&util_obstack);
9141 errbuf = XNEWVEC (char, 1024 * 10);
9143 synth_module_prologue ();
9149 struct imp_entry *impent;
9151 /* The internally generated initializers appear to have missing braces.
9152 Don't warn about this. */
9153 int save_warn_missing_braces = warn_missing_braces;
9154 warn_missing_braces = 0;
9156 /* A missing @end may not be detected by the parser. */
9157 if (objc_implementation_context)
9159 warning (0, "%<@end%> missing in implementation context");
9160 finish_class (objc_implementation_context);
9161 objc_ivar_chain = NULL_TREE;
9162 objc_implementation_context = NULL_TREE;
9165 /* Process the static instances here because initialization of objc_symtab
9167 if (objc_static_instances)
9168 generate_static_references ();
9170 if (imp_list || class_names_chain
9171 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9172 generate_objc_symtab_decl ();
9174 for (impent = imp_list; impent; impent = impent->next)
9176 objc_implementation_context = impent->imp_context;
9177 implementation_template = impent->imp_template;
9179 UOBJC_CLASS_decl = impent->class_decl;
9180 UOBJC_METACLASS_decl = impent->meta_decl;
9182 /* Dump the @interface of each class as we compile it, if the
9183 -gen-decls option is in use. TODO: Dump the classes in the
9184 order they were found, rather than in reverse order as we
9186 if (flag_gen_declaration)
9188 dump_interface (gen_declaration_file, objc_implementation_context);
9191 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9193 /* all of the following reference the string pool... */
9194 generate_ivar_lists ();
9195 generate_dispatch_tables ();
9196 generate_shared_structures (impent->has_cxx_cdtors
9197 ? CLS_HAS_CXX_STRUCTORS
9202 generate_dispatch_tables ();
9203 generate_category (objc_implementation_context);
9207 /* If we are using an array of selectors, we must always
9208 finish up the array decl even if no selectors were used. */
9209 if (! flag_next_runtime || sel_ref_chain)
9210 build_selector_translation_table ();
9213 generate_protocols ();
9215 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9216 generate_objc_image_info ();
9218 /* Arrange for ObjC data structures to be initialized at run time. */
9219 if (objc_implementation_context || class_names_chain || objc_static_instances
9220 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9222 build_module_descriptor ();
9224 if (!flag_next_runtime)
9225 build_module_initializer_routine ();
9228 /* Dump the class references. This forces the appropriate classes
9229 to be linked into the executable image, preserving unix archive
9230 semantics. This can be removed when we move to a more dynamically
9231 linked environment. */
9233 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9235 handle_class_ref (chain);
9236 if (TREE_PURPOSE (chain))
9237 generate_classref_translation_entry (chain);
9240 for (impent = imp_list; impent; impent = impent->next)
9241 handle_impent (impent);
9248 /* Run through the selector hash tables and print a warning for any
9249 selector which has multiple methods. */
9251 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9253 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9254 check_duplicates (hsh, 0, 1);
9255 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9256 check_duplicates (hsh, 0, 1);
9260 warn_missing_braces = save_warn_missing_braces;
9263 /* Subroutines of finish_objc. */
9266 generate_classref_translation_entry (tree chain)
9268 tree expr, decl, type;
9270 decl = TREE_PURPOSE (chain);
9271 type = TREE_TYPE (decl);
9273 expr = add_objc_string (TREE_VALUE (chain), class_names);
9274 expr = convert (type, expr); /* cast! */
9276 /* The decl that is the one that we
9277 forward declared in build_class_reference. */
9278 finish_var_decl (decl, expr);
9283 handle_class_ref (tree chain)
9285 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9286 char *string = (char *) alloca (strlen (name) + 30);
9290 sprintf (string, "%sobjc_class_name_%s",
9291 (flag_next_runtime ? "." : "__"), name);
9293 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9294 if (flag_next_runtime)
9296 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9301 /* Make a decl for this name, so we can use its address in a tree. */
9302 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9303 DECL_EXTERNAL (decl) = 1;
9304 TREE_PUBLIC (decl) = 1;
9307 rest_of_decl_compilation (decl, 0, 0);
9309 /* Make a decl for the address. */
9310 sprintf (string, "%sobjc_class_ref_%s",
9311 (flag_next_runtime ? "." : "__"), name);
9312 exp = build1 (ADDR_EXPR, string_type_node, decl);
9313 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9314 DECL_INITIAL (decl) = exp;
9315 TREE_STATIC (decl) = 1;
9316 TREE_USED (decl) = 1;
9317 /* Force the output of the decl as this forces the reference of the class. */
9318 mark_decl_referenced (decl);
9321 rest_of_decl_compilation (decl, 0, 0);
9325 handle_impent (struct imp_entry *impent)
9329 objc_implementation_context = impent->imp_context;
9330 implementation_template = impent->imp_template;
9332 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9334 const char *const class_name =
9335 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9337 string = (char *) alloca (strlen (class_name) + 30);
9339 sprintf (string, "%sobjc_class_name_%s",
9340 (flag_next_runtime ? "." : "__"), class_name);
9342 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9344 const char *const class_name =
9345 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9346 const char *const class_super_name =
9347 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9349 string = (char *) alloca (strlen (class_name)
9350 + strlen (class_super_name) + 30);
9352 /* Do the same for categories. Even though no references to
9353 these symbols are generated automatically by the compiler, it
9354 gives you a handle to pull them into an archive by hand. */
9355 sprintf (string, "*%sobjc_category_name_%s_%s",
9356 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9361 #ifdef ASM_DECLARE_CLASS_REFERENCE
9362 if (flag_next_runtime)
9364 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9372 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9373 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9374 TREE_PUBLIC (decl) = 1;
9375 TREE_READONLY (decl) = 1;
9376 TREE_USED (decl) = 1;
9377 TREE_CONSTANT (decl) = 1;
9378 DECL_CONTEXT (decl) = 0;
9379 DECL_ARTIFICIAL (decl) = 1;
9380 DECL_INITIAL (decl) = init;
9381 assemble_variable (decl, 1, 0, 0);
9385 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9386 later requires that ObjC translation units participating in F&C be
9387 specially marked. The following routine accomplishes this. */
9389 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9392 generate_objc_image_info (void)
9394 tree decl, initlist;
9396 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9397 | (flag_objc_gc ? 2 : 0));
9399 decl = start_var_decl (build_array_type
9401 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9402 "_OBJC_IMAGE_INFO");
9404 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9405 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9406 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9408 finish_var_decl (decl, initlist);
9411 /* Look up ID as an instance variable. OTHER contains the result of
9412 the C or C++ lookup, which we may want to use instead. */
9415 objc_lookup_ivar (tree other, tree id)
9419 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9420 if (!objc_method_context)
9423 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9424 /* We have a message to super. */
9425 return get_super_receiver ();
9427 /* In a class method, look up an instance variable only as a last
9429 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9430 && other && other != error_mark_node)
9433 /* Look up the ivar, but do not use it if it is not accessible. */
9434 ivar = is_ivar (objc_ivar_chain, id);
9436 if (!ivar || is_private (ivar))
9439 /* In an instance method, a local variable (or parameter) may hide the
9440 instance variable. */
9441 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9442 && other && other != error_mark_node
9444 && CP_DECL_CONTEXT (other) != global_namespace)
9446 && !DECL_FILE_SCOPE_P (other))
9449 warning (0, "local declaration of %qs hides instance variable",
9450 IDENTIFIER_POINTER (id));
9455 /* At this point, we are either in an instance method with no obscuring
9456 local definitions, or in a class method with no alternate definitions
9458 return build_ivar_reference (id);
9461 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9462 needs to be done if we are calling a function through a cast. */
9465 objc_rewrite_function_call (tree function, tree params)
9467 if (TREE_CODE (function) == NOP_EXPR
9468 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9469 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9472 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9473 TREE_OPERAND (function, 0),
9474 TREE_VALUE (params), size_zero_node);
9480 /* Look for the special case of OBJC_TYPE_REF with the address of
9481 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9484 enum gimplify_status
9485 objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
9487 enum gimplify_status r0, r1;
9488 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9489 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9490 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9493 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9494 value of the OBJ_TYPE_REF, so force them to be emitted
9495 during subexpression evaluation rather than after the
9496 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9497 C to use direct rather than indirect calls when the
9498 object expression has a postincrement. */
9499 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9500 is_gimple_val, fb_rvalue);
9501 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9502 is_gimple_val, fb_rvalue);
9504 return MIN (r0, r1);
9508 return cp_gimplify_expr (expr_p, pre_p, post_p);
9510 return c_gimplify_expr (expr_p, pre_p, post_p);
9514 /* Given a CALL expression, find the function being called. The ObjC
9515 version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend. */
9518 objc_get_callee_fndecl (const_tree call_expr)
9520 tree addr = CALL_EXPR_FN (call_expr);
9521 if (TREE_CODE (addr) != OBJ_TYPE_REF)
9524 addr = OBJ_TYPE_REF_EXPR (addr);
9526 /* If the address is just `&f' for some function `f', then we know
9527 that `f' is being called. */
9528 if (TREE_CODE (addr) == ADDR_EXPR
9529 && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
9530 return TREE_OPERAND (addr, 0);
9535 #include "gt-objc-objc-act.h"