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 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
60 #include "langhooks.h"
71 #include "diagnostic.h"
73 #include "tree-iterator.h"
77 #define OBJC_VOID_AT_END void_list_node
79 /* When building Objective-C++, we are not linking against the C front-end
80 and so need to replicate the C tree-construction functions in some way. */
82 #define OBJCP_REMAP_FUNCTIONS
83 #include "objcp-decl.h"
86 /* This is the default way of generating a method name. */
87 /* I am not sure it is really correct.
88 Perhaps there's a danger that it will make name conflicts
89 if method names contain underscores. -- rms. */
90 #ifndef OBJC_GEN_METHOD_LABEL
91 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
94 sprintf ((BUF), "_%s_%s_%s_%s", \
95 ((IS_INST) ? "i" : "c"), \
97 ((CAT_NAME)? (CAT_NAME) : ""), \
99 for (temp = (BUF); *temp; temp++) \
100 if (*temp == ':') *temp = '_'; \
104 /* These need specifying. */
105 #ifndef OBJC_FORWARDING_STACK_OFFSET
106 #define OBJC_FORWARDING_STACK_OFFSET 0
109 #ifndef OBJC_FORWARDING_MIN_OFFSET
110 #define OBJC_FORWARDING_MIN_OFFSET 0
113 /* Set up for use of obstacks. */
117 /* This obstack is used to accumulate the encoding of a data type. */
118 static struct obstack util_obstack;
120 /* This points to the beginning of obstack contents, so we can free
121 the whole contents. */
124 /* The version identifies which language generation and runtime
125 the module (file) was compiled for, and is recorded in the
126 module descriptor. */
128 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
129 #define PROTOCOL_VERSION 2
131 /* (Decide if these can ever be validly changed.) */
132 #define OBJC_ENCODE_INLINE_DEFS 0
133 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
135 /*** Private Interface (procedures) ***/
137 /* Used by compile_file. */
139 static void init_objc (void);
140 static void finish_objc (void);
142 /* Code generation. */
144 static void synth_module_prologue (void);
145 static tree objc_build_constructor (tree, tree);
146 static void build_module_descriptor (void);
147 static void build_module_initializer_routine (void);
148 static tree init_module_descriptor (tree);
149 static tree build_objc_method_call (int, tree, tree, tree, tree);
150 static void generate_strings (void);
151 static tree get_proto_encoding (tree);
152 static void build_selector_translation_table (void);
153 static tree lookup_interface (tree);
154 static tree objc_add_static_instance (tree, tree);
156 static tree start_class (enum tree_code, tree, tree, tree);
157 static tree continue_class (tree);
158 static void finish_class (tree);
159 static void start_method_def (tree);
161 static void objc_start_function (tree, tree, tree, tree);
163 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
165 static tree start_protocol (enum tree_code, tree, tree);
166 static tree build_method_decl (enum tree_code, tree, tree, tree);
167 static tree objc_add_method (tree, tree, int);
168 static tree add_instance_variable (tree, int, tree);
169 static tree build_ivar_reference (tree);
170 static tree is_ivar (tree, tree);
171 static int is_private (tree);
172 static tree get_super_receiver (void);
174 static void build_objc_exception_stuff (void);
175 static void build_next_objc_exception_stuff (void);
177 static tree build_ivar_template (void);
178 static tree build_method_template (void);
179 static void build_private_template (tree);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static tree lookup_method_in_hash_lists (tree, int);
184 static void build_super_template (void);
185 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
186 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
187 static void synth_forward_declarations (void);
188 static int ivar_list_length (tree);
189 static tree get_class_ivars (tree);
190 static void generate_ivar_lists (void);
191 static void generate_dispatch_tables (void);
192 static void generate_shared_structures (void);
193 static tree generate_protocol_list (tree);
194 static void build_protocol_reference (tree);
196 static tree build_keyword_selector (tree);
197 static const char *synth_id_with_class_suffix (const char *, tree);
199 static void generate_static_references (void);
200 static int check_methods_accessible (tree, tree, int);
201 static void encode_aggregate_within (tree, int, int, int, int);
202 static const char *objc_demangle (const char *);
204 /* Hash tables to manage the global pool of method prototypes. */
206 hash *nst_method_hash_list = 0;
207 hash *cls_method_hash_list = 0;
209 static size_t hash_func (tree);
210 static void hash_init (void);
211 static void hash_enter (hash *, tree);
212 static hash hash_lookup (hash *, tree);
213 static void hash_add_attr (hash, tree);
214 static tree lookup_method (tree, tree);
215 static tree lookup_method_static (tree, tree, int);
216 static void add_method_to_hash_list (hash *, tree);
217 static tree add_class (tree);
218 static void add_category (tree, tree);
219 static inline tree lookup_category (tree, tree);
223 class_names, /* class, category, protocol, module names */
224 meth_var_names, /* method and variable names */
225 meth_var_types /* method and variable type descriptors */
228 static tree add_objc_string (tree, enum string_section);
229 static tree get_objc_string_decl (tree, enum string_section);
230 static tree build_objc_string_decl (enum string_section);
231 static tree build_selector_reference_decl (void);
232 static void build_selector_table_decl (void);
234 /* Protocol additions. */
236 static tree add_protocol (tree);
237 static tree lookup_protocol (tree);
238 static void check_protocol_recursively (tree, tree);
239 static tree lookup_and_install_protocols (tree);
243 static void encode_type_qualifiers (tree);
244 static void encode_pointer (tree, int, int);
245 static void encode_array (tree, int, int);
246 static void encode_aggregate (tree, int, int);
247 static void encode_next_bitfield (int);
248 static void encode_gnu_bitfield (int, tree, int);
249 static void encode_type (tree, int, int);
250 static void encode_field_decl (tree, int, int);
253 static void really_start_method (tree, tree);
255 static void really_start_method (tree, struct c_arg_info *);
257 static int objc_types_are_equivalent (tree, tree);
258 static int comp_proto_with_proto (tree, tree);
259 static tree get_arg_type_list (tree, int, int);
260 static void objc_push_parm (tree);
262 static tree objc_get_parm_info (int);
264 static struct c_arg_info *objc_get_parm_info (int);
266 static void synth_self_and_ucmd_args (void);
268 /* Utilities for debugging and error diagnostics. */
270 static void warn_with_method (const char *, int, tree);
271 static void error_with_ivar (const char *, tree);
272 static char *gen_type_name (tree);
273 static char *gen_type_name_0 (tree);
274 static char *gen_method_decl (tree);
275 static char *gen_declaration (tree);
276 static void dump_interface (FILE *, tree);
278 /* Everything else. */
280 static tree lookup_method_in_protocol_list (tree, tree, int);
281 static tree lookup_protocol_in_reflist (tree, tree);
282 static tree start_var_decl (tree, const char *);
283 static void finish_var_decl (tree, tree);
284 static tree create_field_decl (tree, const char *);
285 static tree setup_string_decl (void);
286 static int check_string_class_template (void);
287 static tree my_build_string (int, const char *);
288 static void build_objc_symtab_template (void);
289 static tree init_def_list (tree);
290 static tree init_objc_symtab (tree);
291 static tree build_metadata_decl (const char *, tree);
292 static void forward_declare_categories (void);
293 static void generate_objc_symtab_decl (void);
294 static tree build_selector (tree);
295 static tree build_typed_selector_reference (tree, tree);
296 static tree build_selector_reference (tree);
297 static tree build_class_reference_decl (void);
298 static void add_class_reference (tree);
299 static void build_protocol_template (void);
300 static tree build_descriptor_table_initializer (tree, tree);
301 static tree build_method_prototype_list_template (tree, int);
302 static tree build_method_prototype_template (void);
303 static tree objc_method_parm_type (tree);
304 static int objc_encoded_type_size (tree);
305 static tree encode_method_prototype (tree);
306 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
307 static void generate_method_descriptors (tree);
308 static void generate_protocol_references (tree);
309 static void generate_protocols (void);
310 static void check_ivars (tree, tree);
311 static tree build_ivar_list_template (tree, int);
312 static tree build_method_list_template (tree, int);
313 static tree build_ivar_list_initializer (tree, tree);
314 static tree generate_ivars_list (tree, const char *, int, tree);
315 static tree build_dispatch_table_initializer (tree, tree);
316 static tree generate_dispatch_table (tree, const char *, int, tree);
317 static tree build_shared_structure_initializer (tree, tree, tree, tree,
318 tree, int, tree, tree, tree);
319 static void generate_category (tree);
320 static tree adjust_type_for_id_default (tree);
321 static tree check_duplicates (hash, int, int);
322 static tree receiver_is_class_object (tree, int, int);
323 static int check_methods (tree, tree, int);
324 static int conforms_to_protocol (tree, tree);
325 static void check_protocol (tree, const char *, const char *);
326 static void check_protocols (tree, const char *, const char *);
327 static void generate_classref_translation_entry (tree);
328 static void handle_class_ref (tree);
329 static void generate_struct_by_value_array (void)
331 static void mark_referenced_methods (void);
332 static void generate_objc_image_info (void);
334 /*** Private Interface (data) ***/
336 /* Reserved tag definitions. */
338 #define OBJECT_TYPEDEF_NAME "id"
339 #define CLASS_TYPEDEF_NAME "Class"
341 #define TAG_OBJECT "objc_object"
342 #define TAG_CLASS "objc_class"
343 #define TAG_SUPER "objc_super"
344 #define TAG_SELECTOR "objc_selector"
346 #define UTAG_CLASS "_objc_class"
347 #define UTAG_IVAR "_objc_ivar"
348 #define UTAG_IVAR_LIST "_objc_ivar_list"
349 #define UTAG_METHOD "_objc_method"
350 #define UTAG_METHOD_LIST "_objc_method_list"
351 #define UTAG_CATEGORY "_objc_category"
352 #define UTAG_MODULE "_objc_module"
353 #define UTAG_SYMTAB "_objc_symtab"
354 #define UTAG_SUPER "_objc_super"
355 #define UTAG_SELECTOR "_objc_selector"
357 #define UTAG_PROTOCOL "_objc_protocol"
358 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
359 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
361 /* Note that the string object global name is only needed for the
363 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
365 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
367 static const char *TAG_GETCLASS;
368 static const char *TAG_GETMETACLASS;
369 static const char *TAG_MSGSEND;
370 static const char *TAG_MSGSENDSUPER;
371 /* The NeXT Objective-C messenger may have two extra entry points, for use
372 when returning a structure. */
373 static const char *TAG_MSGSEND_STRET;
374 static const char *TAG_MSGSENDSUPER_STRET;
375 static const char *default_constant_string_class_name;
377 /* Runtime metadata flags. */
378 #define CLS_FACTORY 0x0001L
379 #define CLS_META 0x0002L
381 #define OBJC_MODIFIER_STATIC 0x00000001
382 #define OBJC_MODIFIER_FINAL 0x00000002
383 #define OBJC_MODIFIER_PUBLIC 0x00000004
384 #define OBJC_MODIFIER_PRIVATE 0x00000008
385 #define OBJC_MODIFIER_PROTECTED 0x00000010
386 #define OBJC_MODIFIER_NATIVE 0x00000020
387 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
388 #define OBJC_MODIFIER_ABSTRACT 0x00000080
389 #define OBJC_MODIFIER_VOLATILE 0x00000100
390 #define OBJC_MODIFIER_TRANSIENT 0x00000200
391 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
393 /* NeXT-specific tags. */
395 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
396 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
397 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
398 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
399 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
400 #define TAG_EXCEPTIONMATCH "objc_exception_match"
401 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
402 #define TAG_SYNCENTER "objc_sync_enter"
403 #define TAG_SYNCEXIT "objc_sync_exit"
404 #define TAG_SETJMP "_setjmp"
405 #define UTAG_EXCDATA "_objc_exception_data"
407 /* GNU-specific tags. */
409 #define TAG_EXECCLASS "__objc_exec_class"
410 #define TAG_GNUINIT "__objc_gnu_init"
412 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
413 tree objc_global_trees[OCTI_MAX];
415 static void handle_impent (struct imp_entry *);
417 struct imp_entry *imp_list = 0;
418 int imp_count = 0; /* `@implementation' */
419 int cat_count = 0; /* `@category' */
421 enum tree_code objc_inherit_code;
422 int objc_public_flag;
424 /* Use to generate method labels. */
425 static int method_slot = 0;
429 static char *errbuf; /* Buffer for error diagnostics */
431 /* Data imported from tree.c. */
433 extern enum debug_info_type write_symbols;
435 /* Data imported from toplev.c. */
437 extern const char *dump_base_name;
439 static int flag_typed_selectors;
441 /* Store all constructed constant strings in a hash table so that
442 they get uniqued properly. */
444 struct string_descriptor GTY(())
446 /* The literal argument . */
449 /* The resulting constant string. */
453 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
455 static hashval_t string_hash (const void *);
456 static int string_eq (const void *, const void *);
458 FILE *gen_declaration_file;
460 /* Tells "encode_pointer/encode_aggregate" whether we are generating
461 type descriptors for instance variables (as opposed to methods).
462 Type descriptors for instance variables contain more information
463 than methods (for static typing and embedded structures). */
465 static int generating_instance_variables = 0;
467 /* Some platforms pass small structures through registers versus
468 through an invisible pointer. Determine at what size structure is
469 the transition point between the two possibilities. */
472 generate_struct_by_value_array (void)
475 tree field_decl, field_decl_chain;
477 int aggregate_in_mem[32];
480 /* Presumably no platform passes 32 byte structures in a register. */
481 for (i = 1; i < 32; i++)
485 /* Create an unnamed struct that has `i' character components */
486 type = start_struct (RECORD_TYPE, NULL_TREE);
488 strcpy (buffer, "c1");
489 field_decl = create_field_decl (char_type_node,
491 field_decl_chain = field_decl;
493 for (j = 1; j < i; j++)
495 sprintf (buffer, "c%d", j + 1);
496 field_decl = create_field_decl (char_type_node,
498 chainon (field_decl_chain, field_decl);
500 finish_struct (type, field_decl_chain, NULL_TREE);
502 aggregate_in_mem[i] = aggregate_value_p (type, 0);
503 if (!aggregate_in_mem[i])
507 /* We found some structures that are returned in registers instead of memory
508 so output the necessary data. */
511 for (i = 31; i >= 0; i--)
512 if (!aggregate_in_mem[i])
514 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
516 /* The first member of the structure is always 0 because we don't handle
517 structures with 0 members */
518 printf ("static int struct_forward_array[] = {\n 0");
520 for (j = 1; j <= i; j++)
521 printf (", %d", aggregate_in_mem[j]);
532 if (cxx_init () == false)
534 if (c_objc_common_init () == false)
538 #ifndef USE_MAPPED_LOCATION
539 /* Force the line number back to 0; check_newline will have
540 raised it to 1, which will make the builtin functions appear
541 not to be built in. */
545 /* If gen_declaration desired, open the output file. */
546 if (flag_gen_declaration)
548 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
549 gen_declaration_file = fopen (dumpname, "w");
550 if (gen_declaration_file == 0)
551 fatal_error ("can't open %s: %m", dumpname);
555 if (flag_next_runtime)
557 TAG_GETCLASS = "objc_getClass";
558 TAG_GETMETACLASS = "objc_getMetaClass";
559 TAG_MSGSEND = "objc_msgSend";
560 TAG_MSGSENDSUPER = "objc_msgSendSuper";
561 TAG_MSGSEND_STRET = "objc_msgSend_stret";
562 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
563 default_constant_string_class_name = "NSConstantString";
567 TAG_GETCLASS = "objc_get_class";
568 TAG_GETMETACLASS = "objc_get_meta_class";
569 TAG_MSGSEND = "objc_msg_lookup";
570 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
571 /* GNU runtime does not provide special functions to support
572 structure-returning methods. */
573 default_constant_string_class_name = "NXConstantString";
574 flag_typed_selectors = 1;
579 if (print_struct_values)
580 generate_struct_by_value_array ();
586 objc_finish_file (void)
588 mark_referenced_methods ();
591 /* We need to instantiate templates _before_ we emit ObjC metadata;
592 if we do not, some metadata (such as selectors) may go missing. */
593 instantiate_pending_templates (0);
596 /* Finalize Objective-C runtime data. No need to generate tables
597 and code if only checking syntax. */
598 if (!flag_syntax_only)
601 if (gen_declaration_file)
602 fclose (gen_declaration_file);
609 /* Return the first occurrence of a method declaration corresponding
610 to sel_name in rproto_list. Search rproto_list recursively.
611 If is_class is 0, search for instance methods, otherwise for class
614 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
620 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
622 p = TREE_VALUE (rproto);
624 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
626 if ((fnd = lookup_method (is_class
627 ? PROTOCOL_CLS_METHODS (p)
628 : PROTOCOL_NST_METHODS (p), sel_name)))
630 else if (PROTOCOL_LIST (p))
631 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
636 ; /* An identifier...if we could not find a protocol. */
647 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
651 /* Make sure the protocol is supported by the object on the rhs. */
652 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
655 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
657 p = TREE_VALUE (rproto);
659 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
664 else if (PROTOCOL_LIST (p))
665 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
674 ; /* An identifier...if we could not find a protocol. */
681 objc_start_class_interface (tree class, tree super_class, tree protos)
683 objc_interface_context
685 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
686 objc_public_flag = 0;
690 objc_start_category_interface (tree class, tree categ, tree protos)
692 objc_interface_context
693 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
695 = continue_class (objc_interface_context);
699 objc_start_protocol (tree name, tree protos)
701 objc_interface_context
702 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
706 objc_continue_interface (void)
709 = continue_class (objc_interface_context);
713 objc_finish_interface (void)
715 finish_class (objc_interface_context);
716 objc_interface_context = NULL_TREE;
720 objc_start_class_implementation (tree class, tree super_class)
722 objc_implementation_context
724 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
725 objc_public_flag = 0;
729 objc_start_category_implementation (tree class, tree categ)
731 objc_implementation_context
732 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
734 = continue_class (objc_implementation_context);
738 objc_continue_implementation (void)
741 = continue_class (objc_implementation_context);
745 objc_finish_implementation (void)
747 if (objc_implementation_context)
749 finish_class (objc_implementation_context);
750 objc_ivar_chain = NULL_TREE;
751 objc_implementation_context = NULL_TREE;
754 warning ("%<@end%> must appear in an @implementation context");
758 objc_set_visibility (int visibility)
760 objc_public_flag = visibility;
764 objc_set_method_type (enum tree_code type)
766 objc_inherit_code = (type == PLUS_EXPR
768 : INSTANCE_METHOD_DECL);
772 objc_build_method_signature (tree rettype, tree selector, tree optparms)
774 return build_method_decl (objc_inherit_code, rettype, selector, optparms);
778 objc_add_method_declaration (tree decl)
780 if (!objc_interface_context)
781 fatal_error ("method declaration not in @interface context");
783 objc_add_method (objc_interface_context,
785 objc_inherit_code == CLASS_METHOD_DECL);
789 objc_start_method_definition (tree decl)
791 if (!objc_implementation_context)
792 fatal_error ("method definition not in @implementation context");
794 objc_add_method (objc_implementation_context,
796 objc_inherit_code == CLASS_METHOD_DECL);
797 start_method_def (decl);
801 objc_add_instance_variable (tree decl)
803 (void) add_instance_variable (objc_ivar_context,
808 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
812 objc_is_reserved_word (tree ident)
814 unsigned char code = C_RID_CODE (ident);
816 return (OBJC_IS_AT_KEYWORD (code)
818 || code == RID_CLASS || code == RID_PUBLIC
819 || code == RID_PROTECTED || code == RID_PRIVATE
820 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
825 /* Return true if TYPE is 'id'. */
828 objc_is_object_id (tree type)
830 return OBJC_TYPE_NAME (type) == objc_object_id;
834 objc_is_class_id (tree type)
836 return OBJC_TYPE_NAME (type) == objc_class_id;
839 /* Return 1 if LHS and RHS are compatible types for assignment or
840 various other operations. Return 0 if they are incompatible, and
841 return -1 if we choose to not decide (because the types are really
842 just C types, not ObjC specific ones). When the operation is
843 REFLEXIVE (typically comparisons), check for compatibility in
844 either direction; when it's not (typically assignments), don't.
846 This function is called in two cases: when both lhs and rhs are
847 pointers to records (in which case we check protocols too), and
848 when both lhs and rhs are records (in which case we check class
851 Warnings about classes/protocols not implementing a protocol are
852 emitted here (multiple of those warnings might be emitted for a
853 single line!); generic warnings about incompatible assignments and
854 lacks of casts in comparisons are/must be emitted by the caller if
859 objc_comptypes (tree lhs, tree rhs, int reflexive)
861 /* New clause for protocols. */
863 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
864 manage the ObjC ones, and leave the rest to the C code. */
865 if (TREE_CODE (lhs) == POINTER_TYPE
866 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
867 && TREE_CODE (rhs) == POINTER_TYPE
868 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
870 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_UNTYPED (lhs);
871 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_UNTYPED (rhs);
875 tree lproto, lproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (lhs));
876 tree rproto, rproto_list;
879 /* <Protocol> = <Protocol> */
882 /* Class <Protocol> != id <Protocol>;
883 id <Protocol> != Class <Protocol> */
884 if (IS_ID (lhs) != IS_ID (rhs))
887 rproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs));
891 /* An assignment between objects of type 'id
892 <Protocol>'; make sure the protocol on the lhs is
893 supported by the object on the rhs. */
894 for (lproto = lproto_list; lproto;
895 lproto = TREE_CHAIN (lproto))
897 p = TREE_VALUE (lproto);
898 rproto = lookup_protocol_in_reflist (rproto_list, p);
902 ("object does not conform to the %qs protocol",
903 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
909 /* Obscure case - a comparison between two objects
910 of type 'id <Protocol>'. Check that either the
911 protocol on the lhs is supported by the object on
912 the rhs, or viceversa. */
914 /* Check if the protocol on the lhs is supported by the
915 object on the rhs. */
916 for (lproto = lproto_list; lproto;
917 lproto = TREE_CHAIN (lproto))
919 p = TREE_VALUE (lproto);
920 rproto = lookup_protocol_in_reflist (rproto_list, p);
924 /* Check failed - check if the protocol on the rhs
925 is supported by the object on the lhs. */
926 for (rproto = rproto_list; rproto;
927 rproto = TREE_CHAIN (rproto))
929 p = TREE_VALUE (rproto);
930 lproto = lookup_protocol_in_reflist (lproto_list,
935 /* This check failed too: incompatible */
945 /* <Protocol> = <class> * */
946 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
948 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
951 /* Class <Protocol> != <class> * */
955 /* Make sure the protocol is supported by the object on
957 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
959 p = TREE_VALUE (lproto);
961 rinter = lookup_interface (rname);
963 while (rinter && !rproto)
967 rproto_list = CLASS_PROTOCOL_LIST (rinter);
968 rproto = lookup_protocol_in_reflist (rproto_list, p);
969 /* If the underlying ObjC class does not have
970 the protocol we're looking for, check for "one-off"
971 protocols (e.g., `NSObject<MyProt> *foo;') attached
973 if (!rproto && TYPE_HAS_OBJC_INFO (TREE_TYPE (rhs)))
975 rproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs));
976 rproto = lookup_protocol_in_reflist (rproto_list, p);
979 /* Check for protocols adopted by categories. */
980 cat = CLASS_CATEGORY_LIST (rinter);
981 while (cat && !rproto)
983 rproto_list = CLASS_PROTOCOL_LIST (cat);
984 rproto = lookup_protocol_in_reflist (rproto_list, p);
985 cat = CLASS_CATEGORY_LIST (cat);
988 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
992 warning ("class %qs does not implement the %qs protocol",
993 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
994 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
998 /* id <Protocol> = id; Class <Protocol> = id */
999 else if (objc_is_object_id (TREE_TYPE (rhs)))
1003 /* id <Protocol> != Class; Class <Protocol> = Class */
1004 else if (objc_is_class_id (TREE_TYPE (rhs)))
1006 return IS_CLASS (lhs);
1008 /* <Protocol> = ?? : let comptypes decide. */
1011 else if (rhs_is_proto)
1013 /* <class> * = <Protocol> */
1014 if (TYPED_OBJECT (TREE_TYPE (lhs)))
1016 /* <class> * != Class <Protocol> */
1022 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
1024 tree rproto, rproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs));
1026 /* Make sure the protocol is supported by the object on
1028 for (rproto = rproto_list; rproto;
1029 rproto = TREE_CHAIN (rproto))
1031 tree p = TREE_VALUE (rproto);
1033 rinter = lookup_interface (rname);
1035 while (rinter && !lproto)
1039 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
1040 lproto = lookup_protocol_in_reflist (lproto_list, p);
1041 /* If the underlying ObjC class does not
1042 have the protocol we're looking for,
1043 check for "one-off" protocols (e.g.,
1044 `NSObject<MyProt> *foo;') attached to the
1046 if (!lproto && TYPE_HAS_OBJC_INFO (TREE_TYPE (lhs)))
1048 lproto_list = TYPE_OBJC_PROTOCOL_LIST
1050 lproto = lookup_protocol_in_reflist
1054 /* Check for protocols adopted by categories. */
1055 cat = CLASS_CATEGORY_LIST (rinter);
1056 while (cat && !lproto)
1058 lproto_list = CLASS_PROTOCOL_LIST (cat);
1059 lproto = lookup_protocol_in_reflist (lproto_list,
1061 cat = CLASS_CATEGORY_LIST (cat);
1064 rinter = lookup_interface (CLASS_SUPER_NAME
1069 warning ("class %qs does not implement the %qs protocol",
1070 IDENTIFIER_POINTER (OBJC_TYPE_NAME
1072 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1079 /* id = id <Protocol>; id = Class <Protocol> */
1080 else if (objc_is_object_id (TREE_TYPE (lhs)))
1084 /* Class != id <Protocol>; Class = Class <Protocol> */
1085 else if (objc_is_class_id (TREE_TYPE (lhs)))
1087 return IS_CLASS (rhs);
1089 /* ??? = <Protocol> : let comptypes decide */
1097 /* Attention: we shouldn't defer to comptypes here. One bad
1098 side effect would be that we might loose the REFLEXIVE
1101 lhs = TREE_TYPE (lhs);
1102 rhs = TREE_TYPE (rhs);
1106 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
1108 /* Nothing to do with ObjC - let immediately comptypes take
1109 responsibility for checking. */
1113 /* `id' = `<class> *' `<class> *' = `id': always allow it.
1115 'Object *o = [[Object alloc] init]; falls
1116 in the case <class> * = `id'.
1118 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
1119 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
1122 /* `id' = `Class', `Class' = `id' */
1124 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
1125 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
1128 /* `Class' != `<class> *' && `<class> *' != `Class'! */
1129 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
1130 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
1133 /* `<class> *' = `<class> *' */
1135 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1137 tree lname = OBJC_TYPE_NAME (lhs);
1138 tree rname = OBJC_TYPE_NAME (rhs);
1144 /* If the left hand side is a super class of the right hand side,
1146 for (inter = lookup_interface (rname); inter;
1147 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1148 if (lname == CLASS_SUPER_NAME (inter))
1151 /* Allow the reverse when reflexive. */
1153 for (inter = lookup_interface (lname); inter;
1154 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1155 if (rname == CLASS_SUPER_NAME (inter))
1161 /* Not an ObjC type - let comptypes do the check. */
1165 /* Called from finish_decl. */
1168 objc_check_decl (tree decl)
1170 tree type = TREE_TYPE (decl);
1172 if (TREE_CODE (type) != RECORD_TYPE)
1174 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1175 error ("statically allocated instance of Objective-C class %qs",
1176 IDENTIFIER_POINTER (type));
1179 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1180 either name an Objective-C class, or refer to the special 'id' or 'Class'
1181 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1184 objc_get_protocol_qualified_type (tree interface, tree protocols)
1186 /* If INTERFACE is not provided, default to 'id'. */
1187 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1188 bool is_ptr = (type != NULL_TREE);
1192 type = objc_is_class_name (interface);
1195 type = xref_tag (RECORD_TYPE, type);
1202 type = build_variant_type_copy (type);
1204 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1208 TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
1209 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1210 type = TREE_TYPE (type);
1213 /* Look up protocols and install in lang specific list. */
1214 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1215 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1217 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1218 return the pointer to the new pointee variant. */
1220 type = TYPE_POINTER_TO (type);
1222 TYPE_OBJC_INTERFACE (type)
1223 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1229 /* Check for circular dependencies in protocols. The arguments are
1230 PROTO, the protocol to check, and LIST, a list of protocol it
1234 check_protocol_recursively (tree proto, tree list)
1238 for (p = list; p; p = TREE_CHAIN (p))
1240 tree pp = TREE_VALUE (p);
1242 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1243 pp = lookup_protocol (pp);
1246 fatal_error ("protocol %qs has circular dependency",
1247 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1249 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1253 /* Look up PROTOCOLS, and return a list of those that are found.
1254 If none are found, return NULL. */
1257 lookup_and_install_protocols (tree protocols)
1260 tree return_value = NULL_TREE;
1262 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1264 tree ident = TREE_VALUE (proto);
1265 tree p = lookup_protocol (ident);
1268 error ("cannot find protocol declaration for %qs",
1269 IDENTIFIER_POINTER (ident));
1271 return_value = chainon (return_value,
1272 build_tree_list (NULL_TREE, p));
1275 return return_value;
1278 /* Create a declaration for field NAME of a given TYPE. */
1281 create_field_decl (tree type, const char *name)
1283 return build_decl (FIELD_DECL, get_identifier (name), type);
1286 /* Create a global, static declaration for variable NAME of a given TYPE. The
1287 finish_var_decl() routine will need to be called on it afterwards. */
1290 start_var_decl (tree type, const char *name)
1292 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1294 TREE_STATIC (var) = 1;
1295 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1296 DECL_IGNORED_P (var) = 1;
1297 DECL_ARTIFICIAL (var) = 1;
1298 DECL_CONTEXT (var) = NULL_TREE;
1300 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1306 /* Finish off the variable declaration created by start_var_decl(). */
1309 finish_var_decl (tree var, tree initializer)
1311 finish_decl (var, initializer, NULL_TREE);
1312 /* Ensure that the variable actually gets output. */
1313 mark_decl_referenced (var);
1314 /* Mark the decl to avoid "defined but not used" warning. */
1315 TREE_USED (var) = 1;
1318 /* Find the decl for the constant string class reference. This is only
1319 used for the NeXT runtime. */
1322 setup_string_decl (void)
1327 /* %s in format will provide room for terminating null */
1328 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1329 + strlen (constant_string_class_name);
1330 name = xmalloc (length);
1331 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1332 constant_string_class_name);
1333 constant_string_global_id = get_identifier (name);
1334 string_class_decl = lookup_name (constant_string_global_id);
1336 return string_class_decl;
1339 /* Purpose: "play" parser, creating/installing representations
1340 of the declarations that are required by Objective-C.
1344 type_spec--------->sc_spec
1345 (tree_list) (tree_list)
1348 identifier_node identifier_node */
1351 synth_module_prologue (void)
1354 enum debug_info_type save_write_symbols = write_symbols;
1355 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1357 /* Suppress outputting debug symbols, because
1358 dbxout_init hasn'r been called yet. */
1359 write_symbols = NO_DEBUG;
1360 debug_hooks = &do_nothing_debug_hooks;
1363 push_lang_context (lang_name_c); /* extern "C" */
1366 /* The following are also defined in <objc/objc.h> and friends. */
1368 objc_object_id = get_identifier (TAG_OBJECT);
1369 objc_class_id = get_identifier (TAG_CLASS);
1371 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1372 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1374 objc_object_type = build_pointer_type (objc_object_reference);
1375 objc_class_type = build_pointer_type (objc_class_reference);
1377 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1378 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1380 /* Declare the 'id' and 'Class' typedefs. */
1382 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1385 DECL_IN_SYSTEM_HEADER (type) = 1;
1386 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1389 DECL_IN_SYSTEM_HEADER (type) = 1;
1391 /* Forward-declare '@interface Protocol'. */
1393 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1394 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1395 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1398 /* Declare type of selector-objects that represent an operation name. */
1400 if (flag_next_runtime)
1401 /* `struct objc_selector *' */
1403 = build_pointer_type (xref_tag (RECORD_TYPE,
1404 get_identifier (TAG_SELECTOR)));
1406 /* `const struct objc_selector *' */
1408 = build_pointer_type
1409 (build_qualified_type (xref_tag (RECORD_TYPE,
1410 get_identifier (TAG_SELECTOR)),
1413 /* Declare receiver type used for dispatching messages to 'super'. */
1415 /* `struct objc_super *' */
1416 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1417 get_identifier (TAG_SUPER)));
1419 if (flag_next_runtime)
1421 /* NB: In order to call one of the ..._stret (struct-returning)
1422 functions, the function *MUST* first be cast to a signature that
1423 corresponds to the actual ObjC method being invoked. This is
1424 what is done by the build_objc_method_call() routine below. */
1426 /* id objc_msgSend (id, SEL, ...); */
1427 /* id objc_msgSendNonNil (id, SEL, ...); */
1428 /* id objc_msgSend_stret (id, SEL, ...); */
1429 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1431 = build_function_type (objc_object_type,
1432 tree_cons (NULL_TREE, objc_object_type,
1433 tree_cons (NULL_TREE, objc_selector_type,
1435 umsg_decl = builtin_function (TAG_MSGSEND,
1436 type, 0, NOT_BUILT_IN,
1438 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1439 type, 0, NOT_BUILT_IN,
1441 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1442 type, 0, NOT_BUILT_IN,
1444 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1445 type, 0, NOT_BUILT_IN,
1448 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1449 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1451 = build_function_type (objc_object_type,
1452 tree_cons (NULL_TREE, objc_super_type,
1453 tree_cons (NULL_TREE, objc_selector_type,
1455 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1456 type, 0, NOT_BUILT_IN,
1458 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1459 type, 0, NOT_BUILT_IN, 0,
1464 /* GNU runtime messenger entry points. */
1466 /* typedef id (*IMP)(id, SEL, ...); */
1468 = build_pointer_type
1469 (build_function_type (objc_object_type,
1470 tree_cons (NULL_TREE, objc_object_type,
1471 tree_cons (NULL_TREE, objc_selector_type,
1474 /* IMP objc_msg_lookup (id, SEL); */
1476 = build_function_type (IMP_type,
1477 tree_cons (NULL_TREE, objc_object_type,
1478 tree_cons (NULL_TREE, objc_selector_type,
1479 OBJC_VOID_AT_END)));
1480 umsg_decl = builtin_function (TAG_MSGSEND,
1481 type, 0, NOT_BUILT_IN,
1484 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1486 = build_function_type (IMP_type,
1487 tree_cons (NULL_TREE, objc_super_type,
1488 tree_cons (NULL_TREE, objc_selector_type,
1489 OBJC_VOID_AT_END)));
1490 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1491 type, 0, NOT_BUILT_IN,
1494 /* The following GNU runtime entry point is called to initialize
1497 __objc_exec_class (void *); */
1499 = build_function_type (void_type_node,
1500 tree_cons (NULL_TREE, ptr_type_node,
1502 execclass_decl = builtin_function (TAG_EXECCLASS,
1503 type, 0, NOT_BUILT_IN,
1507 /* id objc_getClass (const char *); */
1509 type = build_function_type (objc_object_type,
1510 tree_cons (NULL_TREE,
1511 const_string_type_node,
1515 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1518 /* id objc_getMetaClass (const char *); */
1520 objc_get_meta_class_decl
1521 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1523 build_class_template ();
1524 build_super_template ();
1525 build_protocol_template ();
1526 build_category_template ();
1527 build_objc_exception_stuff ();
1529 if (flag_next_runtime)
1530 build_next_objc_exception_stuff ();
1532 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1534 if (! flag_next_runtime)
1535 build_selector_table_decl ();
1537 /* Forward declare constant_string_id and constant_string_type. */
1538 if (!constant_string_class_name)
1539 constant_string_class_name = default_constant_string_class_name;
1541 constant_string_id = get_identifier (constant_string_class_name);
1542 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1544 /* Pre-build the following entities - for speed/convenience. */
1545 self_id = get_identifier ("self");
1546 ucmd_id = get_identifier ("_cmd");
1548 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1549 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1553 pop_lang_context ();
1556 write_symbols = save_write_symbols;
1557 debug_hooks = save_hooks;
1560 /* Ensure that the ivar list for NSConstantString/NXConstantString
1561 (or whatever was specified via `-fconstant-string-class')
1562 contains fields at least as large as the following three, so that
1563 the runtime can stomp on them with confidence:
1565 struct STRING_OBJECT_CLASS_NAME
1569 unsigned int length;
1573 check_string_class_template (void)
1575 tree field_decl = TYPE_FIELDS (constant_string_type);
1577 #define AT_LEAST_AS_LARGE_AS(F, T) \
1578 (F && TREE_CODE (F) == FIELD_DECL \
1579 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1580 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1582 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1585 field_decl = TREE_CHAIN (field_decl);
1586 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1589 field_decl = TREE_CHAIN (field_decl);
1590 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1592 #undef AT_LEAST_AS_LARGE_AS
1595 /* Avoid calling `check_string_class_template ()' more than once. */
1596 static GTY(()) int string_layout_checked;
1598 /* Custom build_string which sets TREE_TYPE! */
1601 my_build_string (int len, const char *str)
1603 return fix_string_type (build_string (len, str));
1608 string_hash (const void *ptr)
1610 tree str = ((struct string_descriptor *)ptr)->literal;
1611 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1612 int i, len = TREE_STRING_LENGTH (str);
1615 for (i = 0; i < len; i++)
1616 h = ((h * 613) + p[i]);
1622 string_eq (const void *ptr1, const void *ptr2)
1624 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1625 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1626 int len1 = TREE_STRING_LENGTH (str1);
1628 return (len1 == TREE_STRING_LENGTH (str2)
1629 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1633 /* Given a chain of STRING_CST's, build a static instance of
1634 NXConstantString which points at the concatenation of those
1635 strings. We place the string object in the __string_objects
1636 section of the __OBJC segment. The Objective-C runtime will
1637 initialize the isa pointers of the string objects to point at the
1638 NXConstantString class object. */
1641 objc_build_string_object (tree string)
1643 tree initlist, constructor, constant_string_class;
1646 struct string_descriptor *desc, key;
1649 /* Prep the string argument. */
1650 string = fix_string_type (string);
1651 TREE_SET_CODE (string, STRING_CST);
1652 length = TREE_STRING_LENGTH (string) - 1;
1654 /* Check whether the string class being used actually exists and has the
1655 correct ivar layout. */
1656 if (!string_layout_checked)
1658 string_layout_checked = -1;
1659 constant_string_class = lookup_interface (constant_string_id);
1661 if (!constant_string_class
1662 || !(constant_string_type
1663 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1664 error ("cannot find interface declaration for %qs",
1665 IDENTIFIER_POINTER (constant_string_id));
1666 /* The NSConstantString/NXConstantString ivar layout is now known. */
1667 else if (!check_string_class_template ())
1668 error ("interface %qs does not have valid constant string layout",
1669 IDENTIFIER_POINTER (constant_string_id));
1670 /* For the NeXT runtime, we can generate a literal reference
1671 to the string class, don't need to run a constructor. */
1672 else if (flag_next_runtime && !setup_string_decl ())
1673 error ("cannot find reference tag for class %qs",
1674 IDENTIFIER_POINTER (constant_string_id));
1677 string_layout_checked = 1; /* Success! */
1678 add_class_reference (constant_string_id);
1682 if (string_layout_checked == -1)
1683 return error_mark_node;
1685 /* Perhaps we already constructed a constant string just like this one? */
1686 key.literal = string;
1687 loc = htab_find_slot (string_htab, &key, INSERT);
1693 *loc = desc = ggc_alloc (sizeof (*desc));
1694 desc->literal = string;
1696 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1697 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1698 fields = TYPE_FIELDS (constant_string_type);
1700 = build_tree_list (fields,
1702 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1703 : build_int_cst (NULL_TREE, 0));
1704 fields = TREE_CHAIN (fields);
1705 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1707 fields = TREE_CHAIN (fields);
1708 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1710 constructor = objc_build_constructor (constant_string_type,
1711 nreverse (initlist));
1712 TREE_INVARIANT (constructor) = true;
1714 if (!flag_next_runtime)
1716 = objc_add_static_instance (constructor, constant_string_type);
1719 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1720 DECL_INITIAL (var) = constructor;
1721 TREE_STATIC (var) = 1;
1722 pushdecl_top_level (var);
1725 desc->constructor = constructor;
1728 addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
1733 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1735 static GTY(()) int num_static_inst;
1738 objc_add_static_instance (tree constructor, tree class_decl)
1743 /* Find the list of static instances for the CLASS_DECL. Create one if
1745 for (chain = &objc_static_instances;
1746 *chain && TREE_VALUE (*chain) != class_decl;
1747 chain = &TREE_CHAIN (*chain));
1750 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1751 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1754 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1755 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1756 DECL_COMMON (decl) = 1;
1757 TREE_STATIC (decl) = 1;
1758 DECL_ARTIFICIAL (decl) = 1;
1759 DECL_INITIAL (decl) = constructor;
1761 /* We may be writing something else just now.
1762 Postpone till end of input. */
1763 DECL_DEFER_OUTPUT (decl) = 1;
1764 pushdecl_top_level (decl);
1765 rest_of_decl_compilation (decl, 1, 0);
1767 /* Add the DECL to the head of this CLASS' list. */
1768 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1773 /* Build a static constant CONSTRUCTOR
1774 with type TYPE and elements ELTS. */
1777 objc_build_constructor (tree type, tree elts)
1779 tree constructor = build_constructor (type, elts);
1781 TREE_CONSTANT (constructor) = 1;
1782 TREE_STATIC (constructor) = 1;
1783 TREE_READONLY (constructor) = 1;
1786 /* Adjust for impedance mismatch. We should figure out how to build
1787 CONSTRUCTORs that consistently please both the C and C++ gods. */
1788 if (!TREE_PURPOSE (elts))
1789 TREE_TYPE (constructor) = NULL_TREE;
1790 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1796 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1798 /* Predefine the following data type:
1806 void *defs[cls_def_cnt + cat_def_cnt];
1810 build_objc_symtab_template (void)
1812 tree field_decl, field_decl_chain;
1814 objc_symtab_template
1815 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1817 /* long sel_ref_cnt; */
1818 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
1819 field_decl_chain = field_decl;
1822 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
1824 chainon (field_decl_chain, field_decl);
1826 /* short cls_def_cnt; */
1827 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
1828 chainon (field_decl_chain, field_decl);
1830 /* short cat_def_cnt; */
1831 field_decl = create_field_decl (short_integer_type_node,
1833 chainon (field_decl_chain, field_decl);
1835 if (imp_count || cat_count || !flag_next_runtime)
1837 /* void *defs[imp_count + cat_count (+ 1)]; */
1838 /* NB: The index is one less than the size of the array. */
1839 int index = imp_count + cat_count
1840 + (flag_next_runtime? -1: 0);
1841 field_decl = create_field_decl
1844 build_index_type (build_int_cst (NULL_TREE, index))),
1846 chainon (field_decl_chain, field_decl);
1849 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1852 /* Create the initial value for the `defs' field of _objc_symtab.
1853 This is a CONSTRUCTOR. */
1856 init_def_list (tree type)
1858 tree expr, initlist = NULL_TREE;
1859 struct imp_entry *impent;
1862 for (impent = imp_list; impent; impent = impent->next)
1864 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1866 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1867 initlist = tree_cons (NULL_TREE, expr, initlist);
1872 for (impent = imp_list; impent; impent = impent->next)
1874 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1876 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1877 initlist = tree_cons (NULL_TREE, expr, initlist);
1881 if (!flag_next_runtime)
1883 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1886 if (static_instances_decl)
1887 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1889 expr = build_int_cst (NULL_TREE, 0);
1891 initlist = tree_cons (NULL_TREE, expr, initlist);
1894 return objc_build_constructor (type, nreverse (initlist));
1897 /* Construct the initial value for all of _objc_symtab. */
1900 init_objc_symtab (tree type)
1904 /* sel_ref_cnt = { ..., 5, ... } */
1906 initlist = build_tree_list (NULL_TREE,
1907 build_int_cst (long_integer_type_node, 0));
1909 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1911 if (flag_next_runtime || ! sel_ref_chain)
1912 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
1915 = tree_cons (NULL_TREE,
1916 convert (build_pointer_type (objc_selector_type),
1917 build_unary_op (ADDR_EXPR,
1918 UOBJC_SELECTOR_TABLE_decl, 1)),
1921 /* cls_def_cnt = { ..., 5, ... } */
1923 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
1925 /* cat_def_cnt = { ..., 5, ... } */
1927 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
1929 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1931 if (imp_count || cat_count || !flag_next_runtime)
1934 tree field = TYPE_FIELDS (type);
1935 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1937 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1941 return objc_build_constructor (type, nreverse (initlist));
1944 /* Generate forward declarations for metadata such as
1945 'OBJC_CLASS_...'. */
1948 build_metadata_decl (const char *name, tree type)
1952 /* struct TYPE NAME_<name>; */
1953 decl = start_var_decl (type, synth_id_with_class_suffix
1955 objc_implementation_context));
1960 /* Push forward-declarations of all the categories so that
1961 init_def_list can use them in a CONSTRUCTOR. */
1964 forward_declare_categories (void)
1966 struct imp_entry *impent;
1967 tree sav = objc_implementation_context;
1969 for (impent = imp_list; impent; impent = impent->next)
1971 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1973 /* Set an invisible arg to synth_id_with_class_suffix. */
1974 objc_implementation_context = impent->imp_context;
1975 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1976 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1977 objc_category_template);
1980 objc_implementation_context = sav;
1983 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1984 and initialized appropriately. */
1987 generate_objc_symtab_decl (void)
1989 /* forward declare categories */
1991 forward_declare_categories ();
1993 build_objc_symtab_template ();
1994 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
1995 finish_var_decl (UOBJC_SYMBOLS_decl,
1996 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2000 init_module_descriptor (tree type)
2002 tree initlist, expr;
2004 /* version = { 1, ... } */
2006 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2007 initlist = build_tree_list (NULL_TREE, expr);
2009 /* size = { ..., sizeof (struct _objc_module), ... } */
2011 expr = convert (long_integer_type_node,
2012 size_in_bytes (objc_module_template));
2013 initlist = tree_cons (NULL_TREE, expr, initlist);
2015 /* name = { ..., "foo.m", ... } */
2017 expr = add_objc_string (get_identifier (input_filename), class_names);
2018 initlist = tree_cons (NULL_TREE, expr, initlist);
2020 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2022 if (UOBJC_SYMBOLS_decl)
2023 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2025 expr = build_int_cst (NULL_TREE, 0);
2026 initlist = tree_cons (NULL_TREE, expr, initlist);
2028 return objc_build_constructor (type, nreverse (initlist));
2031 /* Write out the data structures to describe Objective C classes defined.
2033 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2036 build_module_descriptor (void)
2038 tree field_decl, field_decl_chain;
2041 push_lang_context (lang_name_c); /* extern "C" */
2044 objc_module_template
2045 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2048 field_decl = create_field_decl (long_integer_type_node, "version");
2049 field_decl_chain = field_decl;
2052 field_decl = create_field_decl (long_integer_type_node, "size");
2053 chainon (field_decl_chain, field_decl);
2056 field_decl = create_field_decl (string_type_node, "name");
2057 chainon (field_decl_chain, field_decl);
2059 /* struct _objc_symtab *symtab; */
2061 = create_field_decl (build_pointer_type
2062 (xref_tag (RECORD_TYPE,
2063 get_identifier (UTAG_SYMTAB))),
2065 chainon (field_decl_chain, field_decl);
2067 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2069 /* Create an instance of "_objc_module". */
2070 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2071 finish_var_decl (UOBJC_MODULES_decl,
2072 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2075 pop_lang_context ();
2079 /* The GNU runtime requires us to provide a static initializer function
2082 static void __objc_gnu_init (void) {
2083 __objc_exec_class (&L_OBJC_MODULES);
2087 build_module_initializer_routine (void)
2092 push_lang_context (lang_name_c); /* extern "C" */
2095 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2096 objc_start_function (get_identifier (TAG_GNUINIT),
2097 build_function_type (void_type_node,
2099 NULL_TREE, objc_get_parm_info (0));
2101 body = c_begin_compound_stmt (true);
2102 add_stmt (build_function_call
2106 build_unary_op (ADDR_EXPR,
2107 UOBJC_MODULES_decl, 0))));
2108 add_stmt (c_end_compound_stmt (body, true));
2110 TREE_PUBLIC (current_function_decl) = 0;
2113 /* For Objective-C++, we will need to call __objc_gnu_init
2114 from objc_generate_static_init_call() below. */
2115 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2118 GNU_INIT_decl = current_function_decl;
2122 pop_lang_context ();
2127 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2128 to be called by the module initializer routine. */
2131 objc_static_init_needed_p (void)
2133 return (GNU_INIT_decl != NULL_TREE);
2136 /* Generate a call to the __objc_gnu_init initializer function. */
2139 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2141 add_stmt (build_stmt (EXPR_STMT,
2142 build_function_call (GNU_INIT_decl, NULL_TREE)));
2146 #endif /* OBJCPLUS */
2148 /* Return the DECL of the string IDENT in the SECTION. */
2151 get_objc_string_decl (tree ident, enum string_section section)
2155 if (section == class_names)
2156 chain = class_names_chain;
2157 else if (section == meth_var_names)
2158 chain = meth_var_names_chain;
2159 else if (section == meth_var_types)
2160 chain = meth_var_types_chain;
2164 for (; chain != 0; chain = TREE_CHAIN (chain))
2165 if (TREE_VALUE (chain) == ident)
2166 return (TREE_PURPOSE (chain));
2172 /* Output references to all statically allocated objects. Return the DECL
2173 for the array built. */
2176 generate_static_references (void)
2178 tree decls = NULL_TREE, expr = NULL_TREE;
2179 tree class_name, class, decl, initlist;
2180 tree cl_chain, in_chain, type
2181 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2182 int num_inst, num_class;
2185 if (flag_next_runtime)
2188 for (cl_chain = objc_static_instances, num_class = 0;
2189 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2191 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2192 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2194 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2195 decl = start_var_decl (type, buf);
2197 /* Output {class_name, ...}. */
2198 class = TREE_VALUE (cl_chain);
2199 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2200 initlist = build_tree_list (NULL_TREE,
2201 build_unary_op (ADDR_EXPR, class_name, 1));
2203 /* Output {..., instance, ...}. */
2204 for (in_chain = TREE_PURPOSE (cl_chain);
2205 in_chain; in_chain = TREE_CHAIN (in_chain))
2207 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2208 initlist = tree_cons (NULL_TREE, expr, initlist);
2211 /* Output {..., NULL}. */
2212 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2214 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2215 finish_var_decl (decl, expr);
2217 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2220 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2221 expr = objc_build_constructor (type, nreverse (decls));
2222 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2223 finish_var_decl (static_instances_decl, expr);
2226 /* Output all strings. */
2229 generate_strings (void)
2231 tree chain, string_expr;
2232 tree string, decl, type;
2234 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2236 string = TREE_VALUE (chain);
2237 decl = TREE_PURPOSE (chain);
2238 type = build_array_type
2241 (build_int_cst (NULL_TREE,
2242 IDENTIFIER_LENGTH (string))));
2243 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2244 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2245 IDENTIFIER_POINTER (string));
2246 finish_var_decl (decl, string_expr);
2249 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2251 string = TREE_VALUE (chain);
2252 decl = TREE_PURPOSE (chain);
2253 type = build_array_type
2256 (build_int_cst (NULL_TREE,
2257 IDENTIFIER_LENGTH (string))));
2258 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2259 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2260 IDENTIFIER_POINTER (string));
2261 finish_var_decl (decl, string_expr);
2264 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2266 string = TREE_VALUE (chain);
2267 decl = TREE_PURPOSE (chain);
2268 type = build_array_type
2271 (build_int_cst (NULL_TREE,
2272 IDENTIFIER_LENGTH (string))));
2273 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2274 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2275 IDENTIFIER_POINTER (string));
2276 finish_var_decl (decl, string_expr);
2280 static GTY(()) int selector_reference_idx;
2283 build_selector_reference_decl (void)
2288 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2289 decl = start_var_decl (objc_selector_type, buf);
2295 build_selector_table_decl (void)
2299 if (flag_typed_selectors)
2301 build_selector_template ();
2302 temp = build_array_type (objc_selector_template, NULL_TREE);
2305 temp = build_array_type (objc_selector_type, NULL_TREE);
2307 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2310 /* Just a handy wrapper for add_objc_string. */
2313 build_selector (tree ident)
2315 return convert (objc_selector_type,
2316 add_objc_string (ident, meth_var_names));
2320 build_selector_translation_table (void)
2322 tree chain, initlist = NULL_TREE;
2324 tree decl = NULL_TREE;
2326 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2330 if (warn_selector && objc_implementation_context)
2334 for (method_chain = meth_var_names_chain;
2336 method_chain = TREE_CHAIN (method_chain))
2338 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2345 warning ("%Jcreating selector for nonexistent method %qE",
2346 TREE_PURPOSE (chain), TREE_VALUE (chain));
2349 expr = build_selector (TREE_VALUE (chain));
2350 /* add one for the '\0' character */
2351 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2353 if (flag_next_runtime)
2355 decl = TREE_PURPOSE (chain);
2356 finish_var_decl (decl, expr);
2360 if (flag_typed_selectors)
2362 tree eltlist = NULL_TREE;
2363 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2364 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2365 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2366 expr = objc_build_constructor (objc_selector_template,
2367 nreverse (eltlist));
2370 initlist = tree_cons (NULL_TREE, expr, initlist);
2374 if (! flag_next_runtime)
2376 /* Cause the selector table (previously forward-declared)
2377 to be actually output. */
2378 initlist = tree_cons (NULL_TREE,
2379 flag_typed_selectors
2380 ? objc_build_constructor
2381 (objc_selector_template,
2382 tree_cons (NULL_TREE,
2383 build_int_cst (NULL_TREE, 0),
2384 tree_cons (NULL_TREE,
2385 build_int_cst (NULL_TREE, 0),
2387 : build_int_cst (NULL_TREE, 0), initlist);
2388 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2389 nreverse (initlist));
2390 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2395 get_proto_encoding (tree proto)
2400 if (! METHOD_ENCODING (proto))
2402 encoding = encode_method_prototype (proto);
2403 METHOD_ENCODING (proto) = encoding;
2406 encoding = METHOD_ENCODING (proto);
2408 return add_objc_string (encoding, meth_var_types);
2411 return build_int_cst (NULL_TREE, 0);
2414 /* sel_ref_chain is a list whose "value" fields will be instances of
2415 identifier_node that represent the selector. */
2418 build_typed_selector_reference (tree ident, tree prototype)
2420 tree *chain = &sel_ref_chain;
2426 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2427 goto return_at_index;
2430 chain = &TREE_CHAIN (*chain);
2433 *chain = tree_cons (prototype, ident, NULL_TREE);
2436 expr = build_unary_op (ADDR_EXPR,
2437 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2438 build_int_cst (NULL_TREE, index)),
2440 return convert (objc_selector_type, expr);
2444 build_selector_reference (tree ident)
2446 tree *chain = &sel_ref_chain;
2452 if (TREE_VALUE (*chain) == ident)
2453 return (flag_next_runtime
2454 ? TREE_PURPOSE (*chain)
2455 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2456 build_int_cst (NULL_TREE, index)));
2459 chain = &TREE_CHAIN (*chain);
2462 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2464 *chain = tree_cons (expr, ident, NULL_TREE);
2466 return (flag_next_runtime
2468 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2469 build_int_cst (NULL_TREE, index)));
2472 static GTY(()) int class_reference_idx;
2475 build_class_reference_decl (void)
2480 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2481 decl = start_var_decl (objc_class_type, buf);
2486 /* Create a class reference, but don't create a variable to reference
2490 add_class_reference (tree ident)
2494 if ((chain = cls_ref_chain))
2499 if (ident == TREE_VALUE (chain))
2503 chain = TREE_CHAIN (chain);
2507 /* Append to the end of the list */
2508 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2511 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2514 /* Get a class reference, creating it if necessary. Also create the
2515 reference variable. */
2518 objc_get_class_reference (tree ident)
2523 if (processing_template_decl)
2524 /* Must wait until template instantiation time. */
2525 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2526 if (TREE_CODE (ident) == TYPE_DECL)
2527 ident = DECL_NAME (ident);
2531 if (!(ident = objc_is_class_name (ident)))
2533 error ("%qs is not an Objective-C class name or alias",
2534 IDENTIFIER_POINTER (orig_ident));
2535 return error_mark_node;
2538 if (flag_next_runtime && !flag_zero_link)
2543 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2544 if (TREE_VALUE (*chain) == ident)
2546 if (! TREE_PURPOSE (*chain))
2547 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2549 return TREE_PURPOSE (*chain);
2552 decl = build_class_reference_decl ();
2553 *chain = tree_cons (decl, ident, NULL_TREE);
2560 add_class_reference (ident);
2562 params = build_tree_list (NULL_TREE,
2563 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2564 IDENTIFIER_POINTER (ident)));
2566 assemble_external (objc_get_class_decl);
2567 return build_function_call (objc_get_class_decl, params);
2571 /* For each string section we have a chain which maps identifier nodes
2572 to decls for the strings. */
2575 add_objc_string (tree ident, enum string_section section)
2579 if (section == class_names)
2580 chain = &class_names_chain;
2581 else if (section == meth_var_names)
2582 chain = &meth_var_names_chain;
2583 else if (section == meth_var_types)
2584 chain = &meth_var_types_chain;
2590 if (TREE_VALUE (*chain) == ident)
2591 return convert (string_type_node,
2592 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2594 chain = &TREE_CHAIN (*chain);
2597 decl = build_objc_string_decl (section);
2599 *chain = tree_cons (decl, ident, NULL_TREE);
2601 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2604 static GTY(()) int class_names_idx;
2605 static GTY(()) int meth_var_names_idx;
2606 static GTY(()) int meth_var_types_idx;
2609 build_objc_string_decl (enum string_section section)
2614 if (section == class_names)
2615 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2616 else if (section == meth_var_names)
2617 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2618 else if (section == meth_var_types)
2619 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2621 ident = get_identifier (buf);
2623 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2624 DECL_EXTERNAL (decl) = 1;
2625 TREE_PUBLIC (decl) = 0;
2626 TREE_USED (decl) = 1;
2627 TREE_CONSTANT (decl) = 1;
2628 DECL_CONTEXT (decl) = 0;
2629 DECL_ARTIFICIAL (decl) = 1;
2631 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2634 make_decl_rtl (decl);
2635 pushdecl_top_level (decl);
2642 objc_declare_alias (tree alias_ident, tree class_ident)
2644 tree underlying_class;
2647 if (current_namespace != global_namespace) {
2648 error ("Objective-C declarations may only appear in global scope");
2650 #endif /* OBJCPLUS */
2652 if (!(underlying_class = objc_is_class_name (class_ident)))
2653 warning ("cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2654 else if (objc_is_class_name (alias_ident))
2655 warning ("class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2657 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2661 objc_declare_class (tree ident_list)
2665 if (current_namespace != global_namespace) {
2666 error ("Objective-C declarations may only appear in global scope");
2668 #endif /* OBJCPLUS */
2670 for (list = ident_list; list; list = TREE_CHAIN (list))
2672 tree ident = TREE_VALUE (list);
2674 if (! objc_is_class_name (ident))
2676 tree record = lookup_name (ident), type = record;
2680 if (TREE_CODE (record) == TYPE_DECL)
2681 type = DECL_ORIGINAL_TYPE (record);
2683 if (!TYPE_HAS_OBJC_INFO (type)
2684 || !TYPE_OBJC_INTERFACE (type))
2686 error ("%qs redeclared as different kind of symbol",
2687 IDENTIFIER_POINTER (ident));
2688 error ("%Jprevious declaration of '%D'",
2693 record = xref_tag (RECORD_TYPE, ident);
2694 INIT_TYPE_OBJC_INFO (record);
2695 TYPE_OBJC_INTERFACE (record) = ident;
2696 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2702 objc_is_class_name (tree ident)
2706 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2707 && identifier_global_value (ident))
2708 ident = identifier_global_value (ident);
2709 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2710 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2712 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2713 ident = OBJC_TYPE_NAME (ident);
2715 if (ident && TREE_CODE (ident) == TYPE_DECL)
2716 ident = DECL_NAME (ident);
2718 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2721 if (lookup_interface (ident))
2724 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2726 if (ident == TREE_VALUE (chain))
2730 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2732 if (ident == TREE_VALUE (chain))
2733 return TREE_PURPOSE (chain);
2739 /* Check whether TYPE is either 'id' or 'Class'. */
2742 objc_is_id (tree type)
2744 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2745 && identifier_global_value (type))
2746 type = identifier_global_value (type);
2748 if (type && TREE_CODE (type) == TYPE_DECL)
2749 type = TREE_TYPE (type);
2751 /* NB: This function may be called before the ObjC front-end has
2752 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2753 return (objc_object_type && type
2754 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2759 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2760 class instance. This is needed by other parts of the compiler to
2761 handle ObjC types gracefully. */
2764 objc_is_object_ptr (tree type)
2768 type = TYPE_MAIN_VARIANT (type);
2769 if (!POINTER_TYPE_P (type))
2772 ret = objc_is_id (type);
2774 ret = objc_is_class_name (TREE_TYPE (type));
2780 lookup_interface (tree ident)
2785 if (ident && TREE_CODE (ident) == TYPE_DECL)
2786 ident = DECL_NAME (ident);
2788 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2790 if (ident == CLASS_NAME (chain))
2796 /* Implement @defs (<classname>) within struct bodies. */
2799 objc_get_class_ivars (tree class_name)
2801 tree interface = lookup_interface (class_name);
2804 return get_class_ivars (interface);
2806 error ("cannot find interface declaration for %qs",
2807 IDENTIFIER_POINTER (class_name));
2809 return error_mark_node;
2812 /* Used by: build_private_template, continue_class,
2813 and for @defs constructs. */
2816 get_class_ivars (tree interface)
2818 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
2820 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
2821 by the current class (i.e., they do not include super-class ivars).
2822 However, the CLASS_IVARS list will be side-effected by a call to
2823 finish_struct(), which will fill in field offsets. */
2824 if (!CLASS_IVARS (interface))
2825 CLASS_IVARS (interface) = ivar_chain;
2827 while (CLASS_SUPER_NAME (interface))
2829 /* Prepend super-class ivars. */
2830 interface = lookup_interface (CLASS_SUPER_NAME (interface));
2831 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
2839 objc_create_temporary_var (tree type)
2843 decl = build_decl (VAR_DECL, NULL_TREE, type);
2844 TREE_USED (decl) = 1;
2845 DECL_ARTIFICIAL (decl) = 1;
2846 DECL_IGNORED_P (decl) = 1;
2847 DECL_CONTEXT (decl) = current_function_decl;
2852 /* Exception handling constructs. We begin by having the parser do most
2853 of the work and passing us blocks. What we do next depends on whether
2854 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2855 We abstract all of this in a handful of appropriately named routines. */
2857 /* Stack of open try blocks. */
2859 struct objc_try_context
2861 struct objc_try_context *outer;
2863 /* Statements (or statement lists) as processed by the parser. */
2867 /* Some file position locations. */
2868 location_t try_locus;
2869 location_t end_try_locus;
2870 location_t end_catch_locus;
2871 location_t finally_locus;
2872 location_t end_finally_locus;
2874 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2875 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2878 /* The CATCH_EXPR of an open @catch clause. */
2881 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2887 static struct objc_try_context *cur_try_context;
2889 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2890 that represents TYPE. For Objective-C, this is just the class name. */
2891 /* ??? Isn't there a class object or some such? Is it easy to get? */
2895 objc_eh_runtime_type (tree type)
2897 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
2901 /* Initialize exception handling. */
2904 objc_init_exceptions (void)
2906 static bool done = false;
2911 if (flag_objc_sjlj_exceptions)
2913 /* On Darwin, ObjC exceptions require a sufficiently recent
2914 version of the runtime, so the user must ask for them explicitly. */
2915 if (!flag_objc_exceptions)
2916 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2917 "exception syntax");
2922 c_eh_initialized_p = true;
2923 eh_personality_libfunc
2924 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2925 ? "__gnu_objc_personality_sj0"
2926 : "__gnu_objc_personality_v0");
2927 using_eh_for_cleanups ();
2928 lang_eh_runtime_type = objc_eh_runtime_type;
2933 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2934 we'll arrange for it to be initialized (and associated with a binding)
2938 objc_build_exc_ptr (void)
2940 if (flag_objc_sjlj_exceptions)
2942 tree var = cur_try_context->caught_decl;
2945 var = objc_create_temporary_var (objc_object_type);
2946 cur_try_context->caught_decl = var;
2951 return build (EXC_PTR_EXPR, objc_object_type);
2954 /* Build "objc_exception_try_exit(&_stack)". */
2957 next_sjlj_build_try_exit (void)
2960 t = build_fold_addr_expr (cur_try_context->stack_decl);
2961 t = tree_cons (NULL, t, NULL);
2962 t = build_function_call (objc_exception_try_exit_decl, t);
2967 objc_exception_try_enter (&_stack);
2968 if (_setjmp(&_stack.buf))
2972 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2973 empty, ready for the caller to fill them in. */
2976 next_sjlj_build_enter_and_setjmp (void)
2978 tree t, enter, sj, cond;
2980 t = build_fold_addr_expr (cur_try_context->stack_decl);
2981 t = tree_cons (NULL, t, NULL);
2982 enter = build_function_call (objc_exception_try_enter_decl, t);
2984 t = build_component_ref (cur_try_context->stack_decl,
2985 get_identifier ("buf"));
2986 t = build_fold_addr_expr (t);
2987 t = convert (ptr_type_node, t);
2988 t = tree_cons (NULL, t, NULL);
2989 sj = build_function_call (objc_setjmp_decl, t);
2991 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
2992 cond = lang_hooks.truthvalue_conversion (cond);
2994 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
2998 DECL = objc_exception_extract(&_stack);
3002 next_sjlj_build_exc_extract (tree decl)
3006 t = build_fold_addr_expr (cur_try_context->stack_decl);
3007 t = tree_cons (NULL, t, NULL);
3008 t = build_function_call (objc_exception_extract_decl, t);
3009 t = convert (TREE_TYPE (decl), t);
3010 t = build (MODIFY_EXPR, void_type_node, decl, t);
3016 if (objc_exception_match(obj_get_class(TYPE), _caught)
3023 objc_exception_try_exit(&_stack);
3025 from the sequence of CATCH_EXPRs in the current try context. */
3028 next_sjlj_build_catch_list (void)
3030 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3032 tree *last = &catch_seq;
3033 bool saw_id = false;
3035 for (; !tsi_end_p (i); tsi_next (&i))
3037 tree stmt = tsi_stmt (i);
3038 tree type = CATCH_TYPES (stmt);
3039 tree body = CATCH_BODY (stmt);
3051 if (type == error_mark_node)
3052 cond = error_mark_node;
3055 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3056 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3057 args = tree_cons (NULL, t, args);
3058 t = build_function_call (objc_exception_match_decl, args);
3059 cond = lang_hooks.truthvalue_conversion (t);
3061 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3062 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3065 last = &COND_EXPR_ELSE (t);
3071 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3072 cur_try_context->caught_decl);
3073 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3074 append_to_statement_list (t, last);
3076 t = next_sjlj_build_try_exit ();
3077 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3078 append_to_statement_list (t, last);
3084 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3085 exception handling. We aim to build:
3088 struct _objc_exception_data _stack;
3089 id volatile _rethrow = 0;
3092 objc_exception_try_enter (&_stack);
3093 if (_setjmp(&_stack.buf))
3095 id _caught = objc_exception_extract(&_stack);
3096 objc_exception_try_enter (&_stack);
3097 if (_setjmp(&_stack.buf))
3098 _rethrow = objc_exception_extract(&_stack);
3108 objc_exception_try_exit(&_stack);
3111 objc_exception_throw(_rethrow);
3115 If CATCH-LIST is empty, we can omit all of the block containing
3116 "_caught" except for the setting of _rethrow. Note the use of
3117 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3118 but handles goto and other exits from the block. */
3121 next_sjlj_build_try_catch_finally (void)
3123 tree rethrow_decl, stack_decl, t;
3124 tree catch_seq, try_fin, bind;
3126 /* Create the declarations involved. */
3127 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3128 stack_decl = objc_create_temporary_var (t);
3129 cur_try_context->stack_decl = stack_decl;
3131 rethrow_decl = objc_create_temporary_var (objc_object_type);
3132 cur_try_context->rethrow_decl = rethrow_decl;
3133 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3134 TREE_CHAIN (rethrow_decl) = stack_decl;
3136 /* Build the outermost variable binding level. */
3137 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3138 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3139 TREE_SIDE_EFFECTS (bind) = 1;
3141 /* Initialize rethrow_decl. */
3142 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
3143 convert (objc_object_type, null_pointer_node));
3144 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3145 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3147 /* Build the outermost TRY_FINALLY_EXPR. */
3148 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3149 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3150 TREE_SIDE_EFFECTS (try_fin) = 1;
3151 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3153 /* Create the complete catch sequence. */
3154 if (cur_try_context->catch_list)
3156 tree caught_decl = objc_build_exc_ptr ();
3157 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3159 t = next_sjlj_build_exc_extract (caught_decl);
3160 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3162 t = next_sjlj_build_enter_and_setjmp ();
3163 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3164 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3165 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3168 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3169 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3171 /* Build the main register-and-try if statement. */
3172 t = next_sjlj_build_enter_and_setjmp ();
3173 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3174 COND_EXPR_THEN (t) = catch_seq;
3175 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3176 TREE_OPERAND (try_fin, 0) = t;
3178 /* Build the complete FINALLY statement list. */
3179 t = next_sjlj_build_try_exit ();
3180 t = build_stmt (COND_EXPR,
3181 lang_hooks.truthvalue_conversion (rethrow_decl),
3183 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3184 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3186 append_to_statement_list (cur_try_context->finally_body,
3187 &TREE_OPERAND (try_fin, 1));
3189 t = tree_cons (NULL, rethrow_decl, NULL);
3190 t = build_function_call (objc_exception_throw_decl, t);
3191 t = build_stmt (COND_EXPR,
3192 lang_hooks.truthvalue_conversion (rethrow_decl),
3194 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3195 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3200 /* Called just after parsing the @try and its associated BODY. We now
3201 must prepare for the tricky bits -- handling the catches and finally. */
3204 objc_begin_try_stmt (location_t try_locus, tree body)
3206 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3207 c->outer = cur_try_context;
3209 c->try_locus = try_locus;
3210 c->end_try_locus = input_location;
3211 cur_try_context = c;
3213 objc_init_exceptions ();
3216 /* Called just after parsing "@catch (parm)". Open a binding level,
3217 enter DECL into the binding level, and initialize it. Leave the
3218 binding level open while the body of the compound statement is parsed. */
3221 objc_begin_catch_clause (tree decl)
3223 tree compound, type, t;
3225 /* Begin a new scope that the entire catch clause will live in. */
3226 compound = c_begin_compound_stmt (true);
3228 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3229 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3230 lang_hooks.decls.pushdecl (decl);
3232 /* Since a decl is required here by syntax, don't warn if its unused. */
3233 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3234 be what the previous objc implementation did. */
3235 TREE_USED (decl) = 1;
3237 /* Verify that the type of the catch is valid. It must be a pointer
3238 to an Objective-C class, or "id" (which is catch-all). */
3239 type = TREE_TYPE (decl);
3241 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3243 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3245 error ("@catch parameter is not a known Objective-C class type");
3246 type = error_mark_node;
3248 else if (cur_try_context->catch_list)
3250 /* Examine previous @catch clauses and see if we've already
3251 caught the type in question. */
3252 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3253 for (; !tsi_end_p (i); tsi_next (&i))
3255 tree stmt = tsi_stmt (i);
3256 t = CATCH_TYPES (stmt);
3257 if (t == error_mark_node)
3259 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3261 warning ("exception of type %<%T%> will be caught",
3263 warning ("%H by earlier handler for %<%T%>",
3264 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3270 /* Record the data for the catch in the try context so that we can
3271 finalize it later. */
3272 t = build_stmt (CATCH_EXPR, type, compound);
3273 cur_try_context->current_catch = t;
3275 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3276 t = objc_build_exc_ptr ();
3277 t = convert (TREE_TYPE (decl), t);
3278 t = build (MODIFY_EXPR, void_type_node, decl, t);
3282 /* Called just after parsing the closing brace of a @catch clause. Close
3283 the open binding level, and record a CATCH_EXPR for it. */
3286 objc_finish_catch_clause (void)
3288 tree c = cur_try_context->current_catch;
3289 cur_try_context->current_catch = NULL;
3290 cur_try_context->end_catch_locus = input_location;
3292 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3293 append_to_statement_list (c, &cur_try_context->catch_list);
3296 /* Called after parsing a @finally clause and its associated BODY.
3297 Record the body for later placement. */
3300 objc_build_finally_clause (location_t finally_locus, tree body)
3302 cur_try_context->finally_body = body;
3303 cur_try_context->finally_locus = finally_locus;
3304 cur_try_context->end_finally_locus = input_location;
3307 /* Called to finalize a @try construct. */
3310 objc_finish_try_stmt (void)
3312 struct objc_try_context *c = cur_try_context;
3315 if (c->catch_list == NULL && c->finally_body == NULL)
3316 error ("%<@try%> without %<@catch%> or %<@finally%>");
3318 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3319 if (flag_objc_sjlj_exceptions)
3321 if (!cur_try_context->finally_body)
3323 cur_try_context->finally_locus = input_location;
3324 cur_try_context->end_finally_locus = input_location;
3326 stmt = next_sjlj_build_try_catch_finally ();
3330 /* Otherwise, nest the CATCH inside a FINALLY. */
3334 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3335 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3337 if (c->finally_body)
3339 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3340 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3345 cur_try_context = c->outer;
3350 objc_build_throw_stmt (tree throw_expr)
3354 objc_init_exceptions ();
3356 if (throw_expr == NULL)
3358 /* If we're not inside a @catch block, there is no "current
3359 exception" to be rethrown. */
3360 if (cur_try_context == NULL
3361 || cur_try_context->current_catch == NULL)
3363 error ("%<@throw%> (rethrow) used outside of a @catch block");
3367 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3368 value that we get from the runtime. */
3369 throw_expr = objc_build_exc_ptr ();
3372 /* A throw is just a call to the runtime throw function with the
3373 object as a parameter. */
3374 args = tree_cons (NULL, throw_expr, NULL);
3375 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3379 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3383 /* First lock the mutex. */
3384 mutex = save_expr (mutex);
3385 args = tree_cons (NULL, mutex, NULL);
3386 call = build_function_call (objc_sync_enter_decl, args);
3387 SET_EXPR_LOCATION (call, start_locus);
3390 /* Build the mutex unlock. */
3391 args = tree_cons (NULL, mutex, NULL);
3392 call = build_function_call (objc_sync_exit_decl, args);
3393 SET_EXPR_LOCATION (call, input_location);
3395 /* Put the that and the body in a TRY_FINALLY. */
3396 objc_begin_try_stmt (start_locus, body);
3397 objc_build_finally_clause (input_location, call);
3398 objc_finish_try_stmt ();
3402 /* Predefine the following data type:
3404 struct _objc_exception_data
3410 /* The following yuckiness should prevent users from having to #include
3411 <setjmp.h> in their code... */
3413 #ifdef TARGET_POWERPC
3414 /* snarfed from /usr/include/ppc/setjmp.h */
3415 #define _JBLEN (26 + 36 + 129 + 1)
3417 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3422 build_next_objc_exception_stuff (void)
3424 tree field_decl, field_decl_chain, index, temp_type;
3426 objc_exception_data_template
3427 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3429 /* int buf[_JBLEN]; */
3431 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3432 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3434 field_decl_chain = field_decl;
3436 /* void *pointers[4]; */
3438 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3439 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3441 chainon (field_decl_chain, field_decl);
3443 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3445 /* int _setjmp(...); */
3446 /* If the user includes <setjmp.h>, this shall be superseded by
3447 'int _setjmp(jmp_buf);' */
3448 temp_type = build_function_type (integer_type_node, NULL_TREE);
3450 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3452 /* id objc_exception_extract(struct _objc_exception_data *); */
3454 = build_function_type (objc_object_type,
3455 tree_cons (NULL_TREE,
3456 build_pointer_type (objc_exception_data_template),
3458 objc_exception_extract_decl
3459 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3460 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3461 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3463 = build_function_type (void_type_node,
3464 tree_cons (NULL_TREE,
3465 build_pointer_type (objc_exception_data_template),
3467 objc_exception_try_enter_decl
3468 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3469 objc_exception_try_exit_decl
3470 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3472 /* int objc_exception_match(id, id); */
3474 = build_function_type (integer_type_node,
3475 tree_cons (NULL_TREE, objc_object_type,
3476 tree_cons (NULL_TREE, objc_object_type,
3477 OBJC_VOID_AT_END)));
3478 objc_exception_match_decl
3479 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3483 build_objc_exception_stuff (void)
3485 tree noreturn_list, nothrow_list, temp_type;
3487 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3488 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3490 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3491 /* void objc_sync_enter(id); */
3492 /* void objc_sync_exit(id); */
3493 temp_type = build_function_type (void_type_node,
3494 tree_cons (NULL_TREE, objc_object_type,
3496 objc_exception_throw_decl
3497 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3499 objc_sync_enter_decl
3500 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3501 NULL, nothrow_list);
3503 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3504 NULL, nothrow_list);
3507 /* Construct a C struct corresponding to ObjC class CLASS, with the same
3510 struct <classname> {
3511 struct _objc_class *isa;
3516 build_private_template (tree class)
3518 if (!CLASS_STATIC_TEMPLATE (class))
3520 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3522 finish_struct (record, get_class_ivars (class), NULL_TREE);
3523 /* mark this record as class template - for class type checking */
3524 INIT_TYPE_OBJC_INFO (record);
3525 TYPE_OBJC_INTERFACE (record) = class;
3526 CLASS_STATIC_TEMPLATE (class) = record;
3530 /* Begin code generation for protocols... */
3532 /* struct _objc_protocol {
3533 struct _objc_class *isa;
3534 char *protocol_name;
3535 struct _objc_protocol **protocol_list;
3536 struct _objc__method_prototype_list *instance_methods;
3537 struct _objc__method_prototype_list *class_methods;
3541 build_protocol_template (void)
3543 tree field_decl, field_decl_chain;
3545 objc_protocol_template = start_struct (RECORD_TYPE,
3546 get_identifier (UTAG_PROTOCOL));
3548 /* struct _objc_class *isa; */
3549 field_decl = create_field_decl (build_pointer_type
3550 (xref_tag (RECORD_TYPE,
3551 get_identifier (UTAG_CLASS))),
3553 field_decl_chain = field_decl;
3555 /* char *protocol_name; */
3556 field_decl = create_field_decl (string_type_node, "protocol_name");
3557 chainon (field_decl_chain, field_decl);
3559 /* struct _objc_protocol **protocol_list; */
3560 field_decl = create_field_decl (build_pointer_type
3562 (objc_protocol_template)),
3564 chainon (field_decl_chain, field_decl);
3566 /* struct objc_method_list *instance_methods; */
3567 field_decl = create_field_decl (build_pointer_type
3568 (xref_tag (RECORD_TYPE,
3570 (UTAG_METHOD_PROTOTYPE_LIST))),
3571 "instance_methods");
3572 chainon (field_decl_chain, field_decl);
3574 /* struct objc_method_list *class_methods; */
3575 field_decl = create_field_decl (build_pointer_type
3576 (xref_tag (RECORD_TYPE,
3578 (UTAG_METHOD_PROTOTYPE_LIST))),
3580 chainon (field_decl_chain, field_decl);
3582 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
3586 build_descriptor_table_initializer (tree type, tree entries)
3588 tree initlist = NULL_TREE;
3592 tree eltlist = NULL_TREE;
3595 = tree_cons (NULL_TREE,
3596 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3598 = tree_cons (NULL_TREE,
3599 add_objc_string (METHOD_ENCODING (entries),
3604 = tree_cons (NULL_TREE,
3605 objc_build_constructor (type, nreverse (eltlist)),
3608 entries = TREE_CHAIN (entries);
3612 return objc_build_constructor (build_array_type (type, 0),
3613 nreverse (initlist));
3616 /* struct objc_method_prototype_list {
3618 struct objc_method_prototype {
3625 build_method_prototype_list_template (tree list_type, int size)
3627 tree objc_ivar_list_record;
3628 tree field_decl, field_decl_chain;
3630 /* Generate an unnamed struct definition. */
3632 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3634 /* int method_count; */
3635 field_decl = create_field_decl (integer_type_node, "method_count");
3636 field_decl_chain = field_decl;
3638 /* struct objc_method method_list[]; */
3639 field_decl = create_field_decl (build_array_type
3642 (build_int_cst (NULL_TREE, size - 1))),
3644 chainon (field_decl_chain, field_decl);
3646 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3648 return objc_ivar_list_record;
3652 build_method_prototype_template (void)
3655 tree field_decl, field_decl_chain;
3658 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3661 field_decl = create_field_decl (objc_selector_type, "_cmd");
3662 field_decl_chain = field_decl;
3664 /* char *method_types; */
3665 field_decl = create_field_decl (string_type_node, "method_types");
3666 chainon (field_decl_chain, field_decl);
3668 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3670 return proto_record;
3674 objc_method_parm_type (tree type)
3676 type = TREE_VALUE (TREE_TYPE (type));
3677 if (TREE_CODE (type) == TYPE_DECL)
3678 type = TREE_TYPE (type);
3679 return TYPE_MAIN_VARIANT (type);
3683 objc_encoded_type_size (tree type)
3685 int sz = int_size_in_bytes (type);
3687 /* Make all integer and enum types at least as large
3689 if (sz > 0 && INTEGRAL_TYPE_P (type))
3690 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3691 /* Treat arrays as pointers, since that's how they're
3693 else if (TREE_CODE (type) == ARRAY_TYPE)
3694 sz = int_size_in_bytes (ptr_type_node);
3699 encode_method_prototype (tree method_decl)
3706 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3707 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3709 /* Encode return type. */
3710 encode_type (objc_method_parm_type (method_decl),
3711 obstack_object_size (&util_obstack),
3712 OBJC_ENCODE_INLINE_DEFS);
3715 /* The first two arguments (self and _cmd) are pointers; account for
3717 i = int_size_in_bytes (ptr_type_node);
3718 parm_offset = 2 * i;
3719 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3720 parms = TREE_CHAIN (parms))
3722 tree type = objc_method_parm_type (parms);
3723 int sz = objc_encoded_type_size (type);
3725 /* If a type size is not known, bail out. */
3728 error ("%Jtype '%D' does not have a known size",
3730 /* Pretend that the encoding succeeded; the compilation will
3731 fail nevertheless. */
3732 goto finish_encoding;
3737 sprintf (buf, "%d@0:%d", parm_offset, i);
3738 obstack_grow (&util_obstack, buf, strlen (buf));
3740 /* Argument types. */
3741 parm_offset = 2 * i;
3742 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3743 parms = TREE_CHAIN (parms))
3745 tree type = objc_method_parm_type (parms);
3747 /* Process argument qualifiers for user supplied arguments. */
3748 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3751 encode_type (type, obstack_object_size (&util_obstack),
3752 OBJC_ENCODE_INLINE_DEFS);
3754 /* Compute offset. */
3755 sprintf (buf, "%d", parm_offset);
3756 parm_offset += objc_encoded_type_size (type);
3758 obstack_grow (&util_obstack, buf, strlen (buf));
3762 obstack_1grow (&util_obstack, '\0');
3763 result = get_identifier (obstack_finish (&util_obstack));
3764 obstack_free (&util_obstack, util_firstobj);
3769 generate_descriptor_table (tree type, const char *name, int size, tree list,
3772 tree decl, initlist;
3774 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
3776 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
3777 initlist = tree_cons (NULL_TREE, list, initlist);
3779 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
3785 generate_method_descriptors (tree protocol)
3787 tree initlist, chain, method_list_template;
3790 if (!objc_method_prototype_template)
3791 objc_method_prototype_template = build_method_prototype_template ();
3793 chain = PROTOCOL_CLS_METHODS (protocol);
3796 size = list_length (chain);
3798 method_list_template
3799 = build_method_prototype_list_template (objc_method_prototype_template,
3803 = build_descriptor_table_initializer (objc_method_prototype_template,
3806 UOBJC_CLASS_METHODS_decl
3807 = generate_descriptor_table (method_list_template,
3808 "_OBJC_PROTOCOL_CLASS_METHODS",
3809 size, initlist, protocol);
3812 UOBJC_CLASS_METHODS_decl = 0;
3814 chain = PROTOCOL_NST_METHODS (protocol);
3817 size = list_length (chain);
3819 method_list_template
3820 = build_method_prototype_list_template (objc_method_prototype_template,
3823 = build_descriptor_table_initializer (objc_method_prototype_template,
3826 UOBJC_INSTANCE_METHODS_decl
3827 = generate_descriptor_table (method_list_template,
3828 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3829 size, initlist, protocol);
3832 UOBJC_INSTANCE_METHODS_decl = 0;
3836 generate_protocol_references (tree plist)
3840 /* Forward declare protocols referenced. */
3841 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3843 tree proto = TREE_VALUE (lproto);
3845 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3846 && PROTOCOL_NAME (proto))
3848 if (! PROTOCOL_FORWARD_DECL (proto))
3849 build_protocol_reference (proto);
3851 if (PROTOCOL_LIST (proto))
3852 generate_protocol_references (PROTOCOL_LIST (proto));
3857 /* For each protocol which was referenced either from a @protocol()
3858 expression, or because a class/category implements it (then a
3859 pointer to the protocol is stored in the struct describing the
3860 class/category), we create a statically allocated instance of the
3861 Protocol class. The code is written in such a way as to generate
3862 as few Protocol objects as possible; we generate a unique Protocol
3863 instance for each protocol, and we don't generate a Protocol
3864 instance if the protocol is never referenced (either from a
3865 @protocol() or from a class/category implementation). These
3866 statically allocated objects can be referred to via the static
3867 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3869 The statically allocated Protocol objects that we generate here
3870 need to be fixed up at runtime in order to be used: the 'isa'
3871 pointer of the objects need to be set up to point to the 'Protocol'
3872 class, as known at runtime.
3874 The NeXT runtime fixes up all protocols at program startup time,
3875 before main() is entered. It uses a low-level trick to look up all
3876 those symbols, then loops on them and fixes them up.
3878 The GNU runtime as well fixes up all protocols before user code
3879 from the module is executed; it requires pointers to those symbols
3880 to be put in the objc_symtab (which is then passed as argument to
3881 the function __objc_exec_class() which the compiler sets up to be
3882 executed automatically when the module is loaded); setup of those
3883 Protocol objects happen in two ways in the GNU runtime: all
3884 Protocol objects referred to by a class or category implementation
3885 are fixed up when the class/category is loaded; all Protocol
3886 objects referred to by a @protocol() expression are added by the
3887 compiler to the list of statically allocated instances to fixup
3888 (the same list holding the statically allocated constant string
3889 objects). Because, as explained above, the compiler generates as
3890 few Protocol objects as possible, some Protocol object might end up
3891 being referenced multiple times when compiled with the GNU runtime,
3892 and end up being fixed up multiple times at runtime initialization.
3893 But that doesn't hurt, it's just a little inefficient. */
3896 generate_protocols (void)
3900 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3902 /* If a protocol was directly referenced, pull in indirect references. */
3903 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3904 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3905 generate_protocol_references (PROTOCOL_LIST (p));
3907 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3909 tree nst_methods = PROTOCOL_NST_METHODS (p);
3910 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3912 /* If protocol wasn't referenced, don't generate any code. */
3913 decl = PROTOCOL_FORWARD_DECL (p);
3918 /* Make sure we link in the Protocol class. */
3919 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3923 if (! METHOD_ENCODING (nst_methods))
3925 encoding = encode_method_prototype (nst_methods);
3926 METHOD_ENCODING (nst_methods) = encoding;
3928 nst_methods = TREE_CHAIN (nst_methods);
3933 if (! METHOD_ENCODING (cls_methods))
3935 encoding = encode_method_prototype (cls_methods);
3936 METHOD_ENCODING (cls_methods) = encoding;
3939 cls_methods = TREE_CHAIN (cls_methods);
3941 generate_method_descriptors (p);
3943 if (PROTOCOL_LIST (p))
3944 refs_decl = generate_protocol_list (p);
3948 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3949 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3952 refs_expr = convert (build_pointer_type (build_pointer_type
3953 (objc_protocol_template)),
3954 build_unary_op (ADDR_EXPR, refs_decl, 0));
3956 refs_expr = build_int_cst (NULL_TREE, 0);
3958 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3959 by generate_method_descriptors, which is called above. */
3960 initlist = build_protocol_initializer (TREE_TYPE (decl),
3961 protocol_name_expr, refs_expr,
3962 UOBJC_INSTANCE_METHODS_decl,
3963 UOBJC_CLASS_METHODS_decl);
3964 finish_var_decl (decl, initlist);
3969 build_protocol_initializer (tree type, tree protocol_name,
3970 tree protocol_list, tree instance_methods,
3973 tree initlist = NULL_TREE, expr;
3974 tree cast_type = build_pointer_type
3975 (xref_tag (RECORD_TYPE,
3976 get_identifier (UTAG_CLASS)));
3978 /* Filling the "isa" in with one allows the runtime system to
3979 detect that the version change...should remove before final release. */
3981 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
3982 initlist = tree_cons (NULL_TREE, expr, initlist);
3983 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3984 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3986 if (!instance_methods)
3987 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
3990 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3991 initlist = tree_cons (NULL_TREE, expr, initlist);
3995 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
3998 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3999 initlist = tree_cons (NULL_TREE, expr, initlist);
4002 return objc_build_constructor (type, nreverse (initlist));
4005 /* struct _objc_category {
4006 char *category_name;
4008 struct _objc_method_list *instance_methods;
4009 struct _objc_method_list *class_methods;
4010 struct _objc_protocol_list *protocols;
4014 build_category_template (void)
4016 tree field_decl, field_decl_chain;
4018 objc_category_template = start_struct (RECORD_TYPE,
4019 get_identifier (UTAG_CATEGORY));
4021 /* char *category_name; */
4022 field_decl = create_field_decl (string_type_node, "category_name");
4023 field_decl_chain = field_decl;
4025 /* char *class_name; */
4026 field_decl = create_field_decl (string_type_node, "class_name");
4027 chainon (field_decl_chain, field_decl);
4029 /* struct _objc_method_list *instance_methods; */
4030 field_decl = create_field_decl (build_pointer_type
4031 (xref_tag (RECORD_TYPE,
4033 (UTAG_METHOD_LIST))),
4034 "instance_methods");
4035 chainon (field_decl_chain, field_decl);
4037 /* struct _objc_method_list *class_methods; */
4038 field_decl = create_field_decl (build_pointer_type
4039 (xref_tag (RECORD_TYPE,
4041 (UTAG_METHOD_LIST))),
4043 chainon (field_decl_chain, field_decl);
4045 /* struct _objc_protocol **protocol_list; */
4046 field_decl = create_field_decl (build_pointer_type
4048 (objc_protocol_template)),
4050 chainon (field_decl_chain, field_decl);
4052 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4055 /* struct _objc_selector {
4061 build_selector_template (void)
4064 tree field_decl, field_decl_chain;
4066 objc_selector_template
4067 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4070 field_decl = create_field_decl (objc_selector_type, "sel_id");
4071 field_decl_chain = field_decl;
4073 /* char *sel_type; */
4074 field_decl = create_field_decl (string_type_node, "sel_type");
4075 chainon (field_decl_chain, field_decl);
4077 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4080 /* struct _objc_class {
4081 struct _objc_class *isa;
4082 struct _objc_class *super_class;
4087 struct _objc_ivar_list *ivars;
4088 struct _objc_method_list *methods;
4089 #ifdef __NEXT_RUNTIME__
4090 struct objc_cache *cache;
4092 struct sarray *dtable;
4093 struct _objc_class *subclass_list;
4094 struct _objc_class *sibling_class;
4096 struct _objc_protocol_list *protocols;
4097 #ifdef __NEXT_RUNTIME__
4100 void *gc_object_type;
4103 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4104 the NeXT/Apple runtime; still, the compiler must generate them to
4105 maintain backward binary compatibility (and to allow for future
4109 build_class_template (void)
4111 tree field_decl, field_decl_chain;
4114 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4116 /* struct _objc_class *isa; */
4117 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4119 field_decl_chain = field_decl;
4121 /* struct _objc_class *super_class; */
4122 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4124 chainon (field_decl_chain, field_decl);
4127 field_decl = create_field_decl (string_type_node, "name");
4128 chainon (field_decl_chain, field_decl);
4131 field_decl = create_field_decl (long_integer_type_node, "version");
4132 chainon (field_decl_chain, field_decl);
4135 field_decl = create_field_decl (long_integer_type_node, "info");
4136 chainon (field_decl_chain, field_decl);
4138 /* long instance_size; */
4139 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4140 chainon (field_decl_chain, field_decl);
4142 /* struct _objc_ivar_list *ivars; */
4143 field_decl = create_field_decl (build_pointer_type
4144 (xref_tag (RECORD_TYPE,
4148 chainon (field_decl_chain, field_decl);
4150 /* struct _objc_method_list *methods; */
4151 field_decl = create_field_decl (build_pointer_type
4152 (xref_tag (RECORD_TYPE,
4154 (UTAG_METHOD_LIST))),
4156 chainon (field_decl_chain, field_decl);
4158 if (flag_next_runtime)
4160 /* struct objc_cache *cache; */
4161 field_decl = create_field_decl (build_pointer_type
4162 (xref_tag (RECORD_TYPE,
4166 chainon (field_decl_chain, field_decl);
4170 /* struct sarray *dtable; */
4171 field_decl = create_field_decl (build_pointer_type
4172 (xref_tag (RECORD_TYPE,
4176 chainon (field_decl_chain, field_decl);
4178 /* struct objc_class *subclass_list; */
4179 field_decl = create_field_decl (build_pointer_type
4180 (objc_class_template),
4182 chainon (field_decl_chain, field_decl);
4184 /* struct objc_class *sibling_class; */
4185 field_decl = create_field_decl (build_pointer_type
4186 (objc_class_template),
4188 chainon (field_decl_chain, field_decl);
4191 /* struct _objc_protocol **protocol_list; */
4192 field_decl = create_field_decl (build_pointer_type
4194 (xref_tag (RECORD_TYPE,
4198 chainon (field_decl_chain, field_decl);
4200 if (flag_next_runtime)
4203 field_decl = create_field_decl (build_pointer_type (void_type_node),
4205 chainon (field_decl_chain, field_decl);
4208 /* void *gc_object_type; */
4209 field_decl = create_field_decl (build_pointer_type (void_type_node),
4211 chainon (field_decl_chain, field_decl);
4213 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4216 /* Generate appropriate forward declarations for an implementation. */
4219 synth_forward_declarations (void)
4223 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4224 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4225 objc_class_template);
4227 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4228 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4229 objc_class_template);
4231 /* Pre-build the following entities - for speed/convenience. */
4233 an_id = get_identifier ("super_class");
4234 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4235 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4239 error_with_ivar (const char *message, tree decl)
4241 error ("%J%s %qs", decl,
4242 message, gen_declaration (decl));
4247 check_ivars (tree inter, tree imp)
4249 tree intdecls = CLASS_RAW_IVARS (inter);
4250 tree impdecls = CLASS_RAW_IVARS (imp);
4257 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4258 intdecls = TREE_CHAIN (intdecls);
4260 if (intdecls == 0 && impdecls == 0)
4262 if (intdecls == 0 || impdecls == 0)
4264 error ("inconsistent instance variable specification");
4268 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4270 if (!comptypes (t1, t2)
4271 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4272 DECL_INITIAL (impdecls)))
4274 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4276 error_with_ivar ("conflicting instance variable type",
4278 error_with_ivar ("previous declaration of",
4281 else /* both the type and the name don't match */
4283 error ("inconsistent instance variable specification");
4288 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4290 error_with_ivar ("conflicting instance variable name",
4292 error_with_ivar ("previous declaration of",
4296 intdecls = TREE_CHAIN (intdecls);
4297 impdecls = TREE_CHAIN (impdecls);
4301 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4302 This needs to be done just once per compilation. */
4304 /* struct _objc_super {
4305 struct _objc_object *self;
4306 struct _objc_class *super_class;
4310 build_super_template (void)
4312 tree field_decl, field_decl_chain;
4314 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4316 /* struct _objc_object *self; */
4317 field_decl = create_field_decl (objc_object_type, "self");
4318 field_decl_chain = field_decl;
4320 /* struct _objc_class *super_class; */
4321 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4323 chainon (field_decl_chain, field_decl);
4325 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4328 /* struct _objc_ivar {
4335 build_ivar_template (void)
4337 tree objc_ivar_id, objc_ivar_record;
4338 tree field_decl, field_decl_chain;
4340 objc_ivar_id = get_identifier (UTAG_IVAR);
4341 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4343 /* char *ivar_name; */
4344 field_decl = create_field_decl (string_type_node, "ivar_name");
4345 field_decl_chain = field_decl;
4347 /* char *ivar_type; */
4348 field_decl = create_field_decl (string_type_node, "ivar_type");
4349 chainon (field_decl_chain, field_decl);
4351 /* int ivar_offset; */
4352 field_decl = create_field_decl (integer_type_node, "ivar_offset");
4353 chainon (field_decl_chain, field_decl);
4355 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4357 return objc_ivar_record;
4362 struct objc_ivar ivar_list[ivar_count];
4366 build_ivar_list_template (tree list_type, int size)
4368 tree objc_ivar_list_record;
4369 tree field_decl, field_decl_chain;
4371 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4373 /* int ivar_count; */
4374 field_decl = create_field_decl (integer_type_node, "ivar_count");
4375 field_decl_chain = field_decl;
4377 /* struct objc_ivar ivar_list[]; */
4378 field_decl = create_field_decl (build_array_type
4381 (build_int_cst (NULL_TREE, size - 1))),
4383 chainon (field_decl_chain, field_decl);
4385 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4387 return objc_ivar_list_record;
4391 struct _objc__method_prototype_list *method_next;
4393 struct objc_method method_list[method_count];
4397 build_method_list_template (tree list_type, int size)
4399 tree objc_ivar_list_record;
4400 tree field_decl, field_decl_chain;
4402 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4404 /* struct _objc__method_prototype_list *method_next; */
4405 field_decl = create_field_decl (build_pointer_type
4406 (xref_tag (RECORD_TYPE,
4408 (UTAG_METHOD_PROTOTYPE_LIST))),
4410 field_decl_chain = field_decl;
4412 /* int method_count; */
4413 field_decl = create_field_decl (integer_type_node, "method_count");
4414 chainon (field_decl_chain, field_decl);
4416 /* struct objc_method method_list[]; */
4417 field_decl = create_field_decl (build_array_type
4420 (build_int_cst (NULL_TREE, size - 1))),
4422 chainon (field_decl_chain, field_decl);
4424 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4426 return objc_ivar_list_record;
4430 build_ivar_list_initializer (tree type, tree field_decl)
4432 tree initlist = NULL_TREE;
4436 tree ivar = NULL_TREE;
4439 if (DECL_NAME (field_decl))
4440 ivar = tree_cons (NULL_TREE,
4441 add_objc_string (DECL_NAME (field_decl),
4445 /* Unnamed bit-field ivar (yuck). */
4446 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
4449 encode_field_decl (field_decl,
4450 obstack_object_size (&util_obstack),
4451 OBJC_ENCODE_DONT_INLINE_DEFS);
4453 /* Null terminate string. */
4454 obstack_1grow (&util_obstack, 0);
4458 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4461 obstack_free (&util_obstack, util_firstobj);
4464 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4465 initlist = tree_cons (NULL_TREE,
4466 objc_build_constructor (type, nreverse (ivar)),
4469 field_decl = TREE_CHAIN (field_decl);
4470 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4474 return objc_build_constructor (build_array_type (type, 0),
4475 nreverse (initlist));
4479 generate_ivars_list (tree type, const char *name, int size, tree list)
4481 tree decl, initlist;
4483 decl = start_var_decl (type, synth_id_with_class_suffix
4484 (name, objc_implementation_context));
4486 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4487 initlist = tree_cons (NULL_TREE, list, initlist);
4489 finish_var_decl (decl,
4490 objc_build_constructor (TREE_TYPE (decl),
4491 nreverse (initlist)));
4496 /* Count only the fields occurring in T. */
4498 ivar_list_length (tree t)
4502 for (; t; t = TREE_CHAIN (t))
4503 if (TREE_CODE (t) == FIELD_DECL)
4510 generate_ivar_lists (void)
4512 tree initlist, ivar_list_template, chain;
4515 generating_instance_variables = 1;
4517 if (!objc_ivar_template)
4518 objc_ivar_template = build_ivar_template ();
4520 /* Only generate class variables for the root of the inheritance
4521 hierarchy since these will be the same for every class. */
4523 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4524 && (chain = TYPE_FIELDS (objc_class_template)))
4526 size = ivar_list_length (chain);
4528 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4529 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4531 UOBJC_CLASS_VARIABLES_decl
4532 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4536 UOBJC_CLASS_VARIABLES_decl = 0;
4538 chain = CLASS_IVARS (implementation_template);
4541 size = ivar_list_length (chain);
4542 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4543 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4545 UOBJC_INSTANCE_VARIABLES_decl
4546 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4550 UOBJC_INSTANCE_VARIABLES_decl = 0;
4552 generating_instance_variables = 0;
4556 build_dispatch_table_initializer (tree type, tree entries)
4558 tree initlist = NULL_TREE;
4562 tree elemlist = NULL_TREE;
4564 elemlist = tree_cons (NULL_TREE,
4565 build_selector (METHOD_SEL_NAME (entries)),
4568 /* Generate the method encoding if we don't have one already. */
4569 if (! METHOD_ENCODING (entries))
4570 METHOD_ENCODING (entries) =
4571 encode_method_prototype (entries);
4573 elemlist = tree_cons (NULL_TREE,
4574 add_objc_string (METHOD_ENCODING (entries),
4579 = tree_cons (NULL_TREE,
4580 convert (ptr_type_node,
4581 build_unary_op (ADDR_EXPR,
4582 METHOD_DEFINITION (entries), 1)),
4585 initlist = tree_cons (NULL_TREE,
4586 objc_build_constructor (type, nreverse (elemlist)),
4589 entries = TREE_CHAIN (entries);
4593 return objc_build_constructor (build_array_type (type, 0),
4594 nreverse (initlist));
4597 /* To accomplish method prototyping without generating all kinds of
4598 inane warnings, the definition of the dispatch table entries were
4601 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4603 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4606 build_method_template (void)
4609 tree field_decl, field_decl_chain;
4611 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4614 field_decl = create_field_decl (objc_selector_type, "_cmd");
4615 field_decl_chain = field_decl;
4617 /* char *method_types; */
4618 field_decl = create_field_decl (string_type_node, "method_types");
4619 chainon (field_decl_chain, field_decl);
4622 field_decl = create_field_decl (build_pointer_type (void_type_node),
4624 chainon (field_decl_chain, field_decl);
4626 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4633 generate_dispatch_table (tree type, const char *name, int size, tree list)
4635 tree decl, initlist;
4637 decl = start_var_decl (type, synth_id_with_class_suffix
4638 (name, objc_implementation_context));
4640 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
4641 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
4642 initlist = tree_cons (NULL_TREE, list, initlist);
4644 finish_var_decl (decl,
4645 objc_build_constructor (TREE_TYPE (decl),
4646 nreverse (initlist)));
4652 mark_referenced_methods (void)
4654 struct imp_entry *impent;
4657 for (impent = imp_list; impent; impent = impent->next)
4659 chain = CLASS_CLS_METHODS (impent->imp_context);
4662 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4663 chain = TREE_CHAIN (chain);
4666 chain = CLASS_NST_METHODS (impent->imp_context);
4669 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4670 chain = TREE_CHAIN (chain);
4676 generate_dispatch_tables (void)
4678 tree initlist, chain, method_list_template;
4681 if (!objc_method_template)
4682 objc_method_template = build_method_template ();
4684 chain = CLASS_CLS_METHODS (objc_implementation_context);
4687 size = list_length (chain);
4689 method_list_template
4690 = build_method_list_template (objc_method_template, size);
4692 = build_dispatch_table_initializer (objc_method_template, chain);
4694 UOBJC_CLASS_METHODS_decl
4695 = generate_dispatch_table (method_list_template,
4696 ((TREE_CODE (objc_implementation_context)
4697 == CLASS_IMPLEMENTATION_TYPE)
4698 ? "_OBJC_CLASS_METHODS"
4699 : "_OBJC_CATEGORY_CLASS_METHODS"),
4703 UOBJC_CLASS_METHODS_decl = 0;
4705 chain = CLASS_NST_METHODS (objc_implementation_context);
4708 size = list_length (chain);
4710 method_list_template
4711 = build_method_list_template (objc_method_template, size);
4713 = build_dispatch_table_initializer (objc_method_template, chain);
4715 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4716 UOBJC_INSTANCE_METHODS_decl
4717 = generate_dispatch_table (method_list_template,
4718 "_OBJC_INSTANCE_METHODS",
4721 /* We have a category. */
4722 UOBJC_INSTANCE_METHODS_decl
4723 = generate_dispatch_table (method_list_template,
4724 "_OBJC_CATEGORY_INSTANCE_METHODS",
4728 UOBJC_INSTANCE_METHODS_decl = 0;
4732 generate_protocol_list (tree i_or_p)
4735 tree refs_decl, lproto, e, plist;
4737 const char *ref_name;
4739 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4740 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4741 plist = CLASS_PROTOCOL_LIST (i_or_p);
4742 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4743 plist = PROTOCOL_LIST (i_or_p);
4748 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4749 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4750 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4753 /* Build initializer. */
4754 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
4755 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
4756 initlist = tree_cons (NULL_TREE, e, initlist);
4758 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4760 tree pval = TREE_VALUE (lproto);
4762 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4763 && PROTOCOL_FORWARD_DECL (pval))
4765 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4766 initlist = tree_cons (NULL_TREE, e, initlist);
4770 /* static struct objc_protocol *refs[n]; */
4772 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4773 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
4774 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4775 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
4776 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4777 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
4781 refs_decl = start_var_decl
4783 (build_pointer_type (objc_protocol_template),
4784 build_index_type (build_int_cst (NULL_TREE, size + 2))),
4787 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4788 nreverse (initlist)));
4794 build_category_initializer (tree type, tree cat_name, tree class_name,
4795 tree instance_methods, tree class_methods,
4798 tree initlist = NULL_TREE, expr;
4800 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4801 initlist = tree_cons (NULL_TREE, class_name, initlist);
4803 if (!instance_methods)
4804 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4807 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4808 initlist = tree_cons (NULL_TREE, expr, initlist);
4811 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4814 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4815 initlist = tree_cons (NULL_TREE, expr, initlist);
4818 /* protocol_list = */
4820 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4823 expr = convert (build_pointer_type
4825 (objc_protocol_template)),
4826 build_unary_op (ADDR_EXPR, protocol_list, 0));
4827 initlist = tree_cons (NULL_TREE, expr, initlist);
4830 return objc_build_constructor (type, nreverse (initlist));
4833 /* struct _objc_class {
4834 struct objc_class *isa;
4835 struct objc_class *super_class;
4840 struct objc_ivar_list *ivars;
4841 struct objc_method_list *methods;
4842 if (flag_next_runtime)
4843 struct objc_cache *cache;
4845 struct sarray *dtable;
4846 struct objc_class *subclass_list;
4847 struct objc_class *sibling_class;
4849 struct objc_protocol_list *protocols;
4850 if (flag_next_runtime)
4852 void *gc_object_type;
4856 build_shared_structure_initializer (tree type, tree isa, tree super,
4857 tree name, tree size, int status,
4858 tree dispatch_table, tree ivar_list,
4861 tree initlist = NULL_TREE, expr;
4864 initlist = tree_cons (NULL_TREE, isa, initlist);
4867 initlist = tree_cons (NULL_TREE, super, initlist);
4870 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4873 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
4877 initlist = tree_cons (NULL_TREE,
4878 build_int_cst (long_integer_type_node, status),
4881 /* instance_size = */
4882 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
4885 /* objc_ivar_list = */
4887 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4890 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4891 initlist = tree_cons (NULL_TREE, expr, initlist);
4894 /* objc_method_list = */
4895 if (!dispatch_table)
4896 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4899 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4900 initlist = tree_cons (NULL_TREE, expr, initlist);
4903 if (flag_next_runtime)
4904 /* method_cache = */
4905 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4909 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4911 /* subclass_list = */
4912 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4914 /* sibling_class = */
4915 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4918 /* protocol_list = */
4919 if (! protocol_list)
4920 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4923 expr = convert (build_pointer_type
4925 (objc_protocol_template)),
4926 build_unary_op (ADDR_EXPR, protocol_list, 0));
4927 initlist = tree_cons (NULL_TREE, expr, initlist);
4930 if (flag_next_runtime)
4932 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4934 /* gc_object_type = NULL */
4935 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4937 return objc_build_constructor (type, nreverse (initlist));
4940 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
4943 lookup_category (tree class, tree cat_name)
4945 tree category = CLASS_CATEGORY_LIST (class);
4947 while (category && CLASS_SUPER_NAME (category) != cat_name)
4948 category = CLASS_CATEGORY_LIST (category);
4952 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4955 generate_category (tree cat)
4958 tree initlist, cat_name_expr, class_name_expr;
4959 tree protocol_decl, category;
4961 add_class_reference (CLASS_NAME (cat));
4962 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4964 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4966 category = lookup_category (implementation_template,
4967 CLASS_SUPER_NAME (cat));
4969 if (category && CLASS_PROTOCOL_LIST (category))
4971 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4972 protocol_decl = generate_protocol_list (category);
4977 decl = start_var_decl (objc_category_template,
4978 synth_id_with_class_suffix
4979 ("_OBJC_CATEGORY", objc_implementation_context));
4981 initlist = build_category_initializer (TREE_TYPE (decl),
4982 cat_name_expr, class_name_expr,
4983 UOBJC_INSTANCE_METHODS_decl,
4984 UOBJC_CLASS_METHODS_decl,
4987 finish_var_decl (decl, initlist);
4990 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4991 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4994 generate_shared_structures (void)
4996 tree sc_spec, decl_specs, decl;
4997 tree name_expr, super_expr, root_expr;
4998 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4999 tree cast_type, initlist, protocol_decl;
5001 my_super_id = CLASS_SUPER_NAME (implementation_template);
5004 add_class_reference (my_super_id);
5006 /* Compute "my_root_id" - this is required for code generation.
5007 the "isa" for all meta class structures points to the root of
5008 the inheritance hierarchy (e.g. "__Object")... */
5009 my_root_id = my_super_id;
5012 tree my_root_int = lookup_interface (my_root_id);
5014 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5015 my_root_id = CLASS_SUPER_NAME (my_root_int);
5022 /* No super class. */
5023 my_root_id = CLASS_NAME (implementation_template);
5025 cast_type = build_pointer_type (objc_class_template);
5026 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5029 /* Install class `isa' and `super' pointers at runtime. */
5032 super_expr = add_objc_string (my_super_id, class_names);
5033 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5036 super_expr = build_int_cst (NULL_TREE, 0);
5038 root_expr = add_objc_string (my_root_id, class_names);
5039 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5041 if (CLASS_PROTOCOL_LIST (implementation_template))
5043 generate_protocol_references
5044 (CLASS_PROTOCOL_LIST (implementation_template));
5045 protocol_decl = generate_protocol_list (implementation_template);
5050 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5052 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5053 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5055 decl = start_var_decl (objc_class_template,
5057 (DECL_NAME (UOBJC_METACLASS_decl)));
5060 = build_shared_structure_initializer
5062 root_expr, super_expr, name_expr,
5063 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5065 UOBJC_CLASS_METHODS_decl,
5066 UOBJC_CLASS_VARIABLES_decl,
5069 finish_var_decl (decl, initlist);
5071 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5073 decl = start_var_decl (objc_class_template,
5075 (DECL_NAME (UOBJC_CLASS_decl)));
5078 = build_shared_structure_initializer
5080 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5081 super_expr, name_expr,
5082 convert (integer_type_node,
5083 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5084 (implementation_template))),
5086 UOBJC_INSTANCE_METHODS_decl,
5087 UOBJC_INSTANCE_VARIABLES_decl,
5090 finish_var_decl (decl, initlist);
5095 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5097 static char string[BUFSIZE];
5099 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5100 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5102 sprintf (string, "%s_%s", preamble,
5103 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5105 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5106 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5108 /* We have a category. */
5109 const char *const class_name
5110 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5111 const char *const class_super_name
5112 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5113 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5115 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5117 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5118 sprintf (string, "%s_%s", preamble, protocol_name);
5126 /* If type is empty or only type qualifiers are present, add default
5127 type of id (otherwise grokdeclarator will default to int). */
5130 adjust_type_for_id_default (tree type)
5133 type = make_node (TREE_LIST);
5135 if (!TREE_VALUE (type))
5136 TREE_VALUE (type) = objc_object_type;
5137 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5138 && TYPED_OBJECT (TREE_VALUE (type)))
5139 error ("can not use an object as parameter to a method");
5146 selector ':' '(' typename ')' identifier
5149 Transform an Objective-C keyword argument into
5150 the C equivalent parameter declarator.
5152 In: key_name, an "identifier_node" (optional).
5153 arg_type, a "tree_list" (optional).
5154 arg_name, an "identifier_node".
5156 Note: It would be really nice to strongly type the preceding
5157 arguments in the function prototype; however, then I
5158 could not use the "accessor" macros defined in "tree.h".
5160 Out: an instance of "keyword_decl". */
5163 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5167 /* If no type is specified, default to "id". */
5168 arg_type = adjust_type_for_id_default (arg_type);
5170 keyword_decl = make_node (KEYWORD_DECL);
5172 TREE_TYPE (keyword_decl) = arg_type;
5173 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5174 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5176 return keyword_decl;
5179 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5182 build_keyword_selector (tree selector)
5185 tree key_chain, key_name;
5188 /* Scan the selector to see how much space we'll need. */
5189 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5191 if (TREE_CODE (selector) == KEYWORD_DECL)
5192 key_name = KEYWORD_KEY_NAME (key_chain);
5193 else if (TREE_CODE (selector) == TREE_LIST)
5194 key_name = TREE_PURPOSE (key_chain);
5199 len += IDENTIFIER_LENGTH (key_name) + 1;
5201 /* Just a ':' arg. */
5205 buf = (char *) alloca (len + 1);
5206 /* Start the buffer out as an empty string. */
5209 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5211 if (TREE_CODE (selector) == KEYWORD_DECL)
5212 key_name = KEYWORD_KEY_NAME (key_chain);
5213 else if (TREE_CODE (selector) == TREE_LIST)
5215 key_name = TREE_PURPOSE (key_chain);
5216 /* The keyword decl chain will later be used as a function argument
5217 chain. Unhook the selector itself so as to not confuse other
5218 parts of the compiler. */
5219 TREE_PURPOSE (key_chain) = NULL_TREE;
5225 strcat (buf, IDENTIFIER_POINTER (key_name));
5229 return get_identifier (buf);
5232 /* Used for declarations and definitions. */
5235 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5240 /* If no type is specified, default to "id". */
5241 ret_type = adjust_type_for_id_default (ret_type);
5243 method_decl = make_node (code);
5244 TREE_TYPE (method_decl) = ret_type;
5246 /* If we have a keyword selector, create an identifier_node that
5247 represents the full selector name (`:' included)... */
5248 if (TREE_CODE (selector) == KEYWORD_DECL)
5250 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5251 METHOD_SEL_ARGS (method_decl) = selector;
5252 METHOD_ADD_ARGS (method_decl) = add_args;
5256 METHOD_SEL_NAME (method_decl) = selector;
5257 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5258 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5264 #define METHOD_DEF 0
5265 #define METHOD_REF 1
5267 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5268 an argument list for method METH. CONTEXT is either METHOD_DEF or
5269 METHOD_REF, saying whether we are trying to define a method or call
5270 one. SUPERFLAG says this is for a send to super; this makes a
5271 difference for the NeXT calling sequence in which the lookup and
5272 the method call are done together. If METH is null, user-defined
5273 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5276 get_arg_type_list (tree meth, int context, int superflag)
5280 /* Receiver type. */
5281 if (flag_next_runtime && superflag)
5282 arglist = build_tree_list (NULL_TREE, objc_super_type);
5283 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5284 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5286 arglist = build_tree_list (NULL_TREE, objc_object_type);
5288 /* Selector type - will eventually change to `int'. */
5289 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5291 /* No actual method prototype given -- assume that remaining arguments
5296 /* Build a list of argument types. */
5297 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5299 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
5301 /* Decay arrays into pointers. */
5302 if (TREE_CODE (arg_type) == ARRAY_TYPE)
5303 arg_type = build_pointer_type (TREE_TYPE (arg_type));
5305 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5308 if (METHOD_ADD_ARGS (meth))
5310 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5311 akey; akey = TREE_CHAIN (akey))
5313 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
5315 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5318 if (!TREE_OVERFLOW (METHOD_ADD_ARGS (meth)))
5319 goto lack_of_ellipsis;
5324 chainon (arglist, OBJC_VOID_AT_END);
5331 check_duplicates (hash hsh, int methods, int is_class)
5333 tree meth = NULL_TREE;
5341 /* We have two or more methods with the same name but
5345 warning ("multiple %s named %<%c%s%> found",
5346 methods ? "methods" : "selectors",
5347 (is_class ? '+' : '-'),
5348 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5350 warn_with_method (methods ? "using" : "found",
5351 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5355 for (loop = hsh->list; loop; loop = loop->next)
5356 warn_with_method ("also found",
5357 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5366 /* If RECEIVER is a class reference, return the identifier node for
5367 the referenced class. RECEIVER is created by objc_get_class_reference,
5368 so we check the exact form created depending on which runtimes are
5372 receiver_is_class_object (tree receiver, int self, int super)
5374 tree chain, exp, arg;
5376 /* The receiver is 'self' or 'super' in the context of a class method. */
5377 if (objc_method_context
5378 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5381 ? CLASS_SUPER_NAME (implementation_template)
5382 : CLASS_NAME (implementation_template));
5384 if (flag_next_runtime)
5386 /* The receiver is a variable created by
5387 build_class_reference_decl. */
5388 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
5389 /* Look up the identifier. */
5390 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5391 if (TREE_PURPOSE (chain) == receiver)
5392 return TREE_VALUE (chain);
5395 /* The receiver is a function call that returns an id. Check if
5396 it is a call to objc_getClass, if so, pick up the class name. */
5397 if (TREE_CODE (receiver) == CALL_EXPR
5398 && (exp = TREE_OPERAND (receiver, 0))
5399 && TREE_CODE (exp) == ADDR_EXPR
5400 && (exp = TREE_OPERAND (exp, 0))
5401 && TREE_CODE (exp) == FUNCTION_DECL
5402 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5403 prototypes for objc_get_class(). Thankfully, they seem to share the
5404 same function type. */
5405 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5406 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5407 /* We have a call to objc_get_class/objc_getClass! */
5408 && (arg = TREE_OPERAND (receiver, 1))
5409 && TREE_CODE (arg) == TREE_LIST
5410 && (arg = TREE_VALUE (arg)))
5413 if (TREE_CODE (arg) == ADDR_EXPR
5414 && (arg = TREE_OPERAND (arg, 0))
5415 && TREE_CODE (arg) == STRING_CST)
5416 /* Finally, we have the class name. */
5417 return get_identifier (TREE_STRING_POINTER (arg));
5422 /* If we are currently building a message expr, this holds
5423 the identifier of the selector of the message. This is
5424 used when printing warnings about argument mismatches. */
5426 static tree current_objc_message_selector = 0;
5429 objc_message_selector (void)
5431 return current_objc_message_selector;
5434 /* Construct an expression for sending a message.
5435 MESS has the object to send to in TREE_PURPOSE
5436 and the argument list (including selector) in TREE_VALUE.
5438 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5439 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5442 objc_build_message_expr (tree mess)
5444 tree receiver = TREE_PURPOSE (mess);
5447 tree args = TREE_PURPOSE (TREE_VALUE (mess));
5449 tree args = TREE_VALUE (mess);
5451 tree method_params = NULL_TREE;
5453 if (TREE_CODE (receiver) == ERROR_MARK)
5454 return error_mark_node;
5456 /* Obtain the full selector name. */
5457 if (TREE_CODE (args) == IDENTIFIER_NODE)
5458 /* A unary selector. */
5460 else if (TREE_CODE (args) == TREE_LIST)
5461 sel_name = build_keyword_selector (args);
5465 /* Build the parameter list to give to the method. */
5466 if (TREE_CODE (args) == TREE_LIST)
5468 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
5471 tree chain = args, prev = NULL_TREE;
5473 /* We have a keyword selector--check for comma expressions. */
5476 tree element = TREE_VALUE (chain);
5478 /* We have a comma expression, must collapse... */
5479 if (TREE_CODE (element) == TREE_LIST)
5482 TREE_CHAIN (prev) = element;
5487 chain = TREE_CHAIN (chain);
5489 method_params = args;
5494 if (processing_template_decl)
5495 /* Must wait until template instantiation time. */
5496 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5500 return objc_finish_message_expr (receiver, sel_name, method_params);
5503 /* Look up method SEL_NAME that would be suitable for receiver
5504 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5505 nonzero), and report on any duplicates. */
5508 lookup_method_in_hash_lists (tree sel_name, int is_class)
5510 hash method_prototype = NULL;
5513 method_prototype = hash_lookup (nst_method_hash_list,
5516 if (!method_prototype)
5518 method_prototype = hash_lookup (cls_method_hash_list,
5523 return check_duplicates (method_prototype, 1, is_class);
5526 /* The 'objc_finish_message_expr' routine is called from within
5527 'objc_build_message_expr' for non-template functions. In the case of
5528 C++ template functions, it is called from 'build_expr_from_tree'
5529 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5532 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
5534 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5535 tree selector, retval, class_tree;
5536 int self, super, have_cast;
5538 /* Extract the receiver of the message, as well as its type
5539 (where the latter may take the form of a cast or be inferred
5540 from the implementation context). */
5542 while (TREE_CODE (rtype) == COMPOUND_EXPR
5543 || TREE_CODE (rtype) == MODIFY_EXPR
5544 || TREE_CODE (rtype) == NOP_EXPR
5545 || TREE_CODE (rtype) == CONVERT_EXPR
5546 || TREE_CODE (rtype) == COMPONENT_REF)
5547 rtype = TREE_OPERAND (rtype, 0);
5548 self = (rtype == self_decl);
5549 super = (rtype == UOBJC_SUPER_decl);
5550 rtype = TREE_TYPE (receiver);
5551 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5552 || (TREE_CODE (receiver) == COMPOUND_EXPR
5553 && !IS_SUPER (rtype)));
5555 /* If the receiver is a class object, retrieve the corresponding
5556 @interface, if one exists. */
5557 class_tree = receiver_is_class_object (receiver, self, super);
5559 /* Now determine the receiver type (if an explicit cast has not been
5564 rtype = lookup_interface (class_tree);
5565 /* Handle `self' and `super'. */
5568 if (!CLASS_SUPER_NAME (implementation_template))
5570 error ("no super class declared in @interface for %qs",
5571 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5572 return error_mark_node;
5574 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5577 rtype = lookup_interface (CLASS_NAME (implementation_template));
5580 /* If receiver is of type `id' or `Class' (or if the @interface for a
5581 class is not visible), we shall be satisfied with the existence of
5582 any instance or class method. */
5583 if (!rtype || objc_is_id (rtype))
5586 rtype = xref_tag (RECORD_TYPE, class_tree);
5589 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
5590 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
5591 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
5598 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
5599 in protocols themselves for the method prototype. */
5601 = lookup_method_in_protocol_list (rprotos, sel_name,
5602 class_tree != NULL_TREE);
5604 /* If messaging 'Class <Proto>' but did not find a class method
5605 prototype, search for an instance method instead, and warn
5606 about having done so. */
5607 if (!method_prototype && !rtype && class_tree != NULL_TREE)
5610 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
5612 if (method_prototype)
5613 warning ("found %<-%s%> instead of %<+%s%> in protocol(s)",
5614 IDENTIFIER_POINTER (sel_name),
5615 IDENTIFIER_POINTER (sel_name));
5621 tree orig_rtype = rtype, saved_rtype;
5623 if (TREE_CODE (rtype) == POINTER_TYPE)
5624 rtype = TREE_TYPE (rtype);
5625 /* Traverse typedef aliases */
5626 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
5627 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
5628 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
5629 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
5630 saved_rtype = rtype;
5631 if (TYPED_OBJECT (rtype))
5633 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
5634 rtype = TYPE_OBJC_INTERFACE (rtype);
5636 /* If we could not find an @interface declaration, we must have
5637 only seen a @class declaration; so, we cannot say anything
5638 more intelligent about which methods the receiver will
5640 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
5641 rtype = saved_rtype;
5642 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5643 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5645 /* We have a valid ObjC class name. Look up the method name
5646 in the published @interface for the class (and its
5649 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
5651 /* If the method was not found in the @interface, it may still
5652 exist locally as part of the @implementation. */
5653 if (!method_prototype && objc_implementation_context
5654 && CLASS_NAME (objc_implementation_context)
5655 == OBJC_TYPE_NAME (rtype))
5659 ? CLASS_CLS_METHODS (objc_implementation_context)
5660 : CLASS_NST_METHODS (objc_implementation_context)),
5663 /* If we haven't found a candidate method by now, try looking for
5664 it in the protocol list. */
5665 if (!method_prototype && rprotos)
5667 = lookup_method_in_protocol_list (rprotos, sel_name,
5668 class_tree != NULL_TREE);
5672 warning ("invalid receiver type %qs",
5673 gen_type_name (orig_rtype));
5674 /* After issuing the "invalid receiver" warning, perform method
5675 lookup as if we were messaging 'id'. */
5676 rtype = rprotos = NULL_TREE;
5681 /* For 'id' or 'Class' receivers, search in the global hash table
5682 as a last resort. For all receivers, warn if protocol searches
5684 if (!method_prototype)
5687 warning ("%<%c%s%> not found in protocol(s)",
5688 (class_tree ? '+' : '-'),
5689 IDENTIFIER_POINTER (sel_name));
5693 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
5696 if (!method_prototype)
5698 static bool warn_missing_methods = false;
5701 warning ("%qs may not respond to %<%c%s%>",
5702 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5703 (class_tree ? '+' : '-'),
5704 IDENTIFIER_POINTER (sel_name));
5705 /* If we are messaging an 'id' or 'Class' object and made it here,
5706 then we have failed to find _any_ instance or class method,
5709 warning ("no %<%c%s%> method found",
5710 (class_tree ? '+' : '-'),
5711 IDENTIFIER_POINTER (sel_name));
5713 if (!warn_missing_methods)
5715 warning ("(Messages without a matching method signature");
5716 warning ("will be assumed to return %<id%> and accept");
5717 warning ("%<...%> as arguments.)");
5718 warn_missing_methods = true;
5722 /* Save the selector name for printing error messages. */
5723 current_objc_message_selector = sel_name;
5725 /* Build the parameters list for looking up the method.
5726 These are the object itself and the selector. */
5728 if (flag_typed_selectors)
5729 selector = build_typed_selector_reference (sel_name, method_prototype);
5731 selector = build_selector_reference (sel_name);
5733 retval = build_objc_method_call (super, method_prototype,
5735 selector, method_params);
5737 current_objc_message_selector = 0;
5742 /* Build a tree expression to send OBJECT the operation SELECTOR,
5743 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5744 assuming the method has prototype METHOD_PROTOTYPE.
5745 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5746 Use METHOD_PARAMS as list of args to pass to the method.
5747 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5750 build_objc_method_call (int super_flag, tree method_prototype,
5751 tree lookup_object, tree selector,
5754 tree sender = (super_flag ? umsg_super_decl :
5755 (!flag_next_runtime || flag_nil_receivers
5757 : umsg_nonnil_decl));
5758 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
5760 /* If a prototype for the method to be called exists, then cast
5761 the sender's return type and arguments to match that of the method.
5762 Otherwise, leave sender as is. */
5765 ? TREE_VALUE (TREE_TYPE (method_prototype))
5766 : objc_object_type);
5768 = build_pointer_type
5769 (build_function_type
5772 (method_prototype, METHOD_REF, super_flag)));
5775 lookup_object = build_c_cast (rcv_p, lookup_object);
5777 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
5778 lookup_object = save_expr (lookup_object);
5780 if (flag_next_runtime)
5782 /* If we are returning a struct in memory, and the address
5783 of that memory location is passed as a hidden first
5784 argument, then change which messenger entry point this
5785 expr will call. NB: Note that sender_cast remains
5786 unchanged (it already has a struct return type). */
5787 if (!targetm.calls.struct_value_rtx (0, 0)
5788 && (TREE_CODE (ret_type) == RECORD_TYPE
5789 || TREE_CODE (ret_type) == UNION_TYPE)
5790 && targetm.calls.return_in_memory (ret_type, 0))
5791 sender = (super_flag ? umsg_super_stret_decl :
5792 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5794 method_params = tree_cons (NULL_TREE, lookup_object,
5795 tree_cons (NULL_TREE, selector,
5797 method = build_fold_addr_expr (sender);
5801 /* This is the portable (GNU) way. */
5804 /* First, call the lookup function to get a pointer to the method,
5805 then cast the pointer, then call it with the method arguments. */
5807 object = (super_flag ? self_decl : lookup_object);
5809 t = tree_cons (NULL_TREE, selector, NULL_TREE);
5810 t = tree_cons (NULL_TREE, lookup_object, t);
5811 method = build_function_call (sender, t);
5813 /* Pass the object to the method. */
5814 method_params = tree_cons (NULL_TREE, object,
5815 tree_cons (NULL_TREE, selector,
5819 /* ??? Selector is not at this point something we can use inside
5820 the compiler itself. Set it to garbage for the nonce. */
5821 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
5822 return build_function_call (t, method_params);
5826 build_protocol_reference (tree p)
5829 const char *proto_name;
5831 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
5833 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5834 decl = start_var_decl (objc_protocol_template, proto_name);
5836 PROTOCOL_FORWARD_DECL (p) = decl;
5839 /* This function is called by the parser when (and only when) a
5840 @protocol() expression is found, in order to compile it. */
5842 objc_build_protocol_expr (tree protoname)
5845 tree p = lookup_protocol (protoname);
5849 error ("cannot find protocol declaration for %qs",
5850 IDENTIFIER_POINTER (protoname));
5851 return error_mark_node;
5854 if (!PROTOCOL_FORWARD_DECL (p))
5855 build_protocol_reference (p);
5857 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5859 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5860 if we have it, rather than converting it here. */
5861 expr = convert (objc_protocol_type, expr);
5863 /* The @protocol() expression is being compiled into a pointer to a
5864 statically allocated instance of the Protocol class. To become
5865 usable at runtime, the 'isa' pointer of the instance need to be
5866 fixed up at runtime by the runtime library, to point to the
5867 actual 'Protocol' class. */
5869 /* For the GNU runtime, put the static Protocol instance in the list
5870 of statically allocated instances, so that we make sure that its
5871 'isa' pointer is fixed up at runtime by the GNU runtime library
5872 to point to the Protocol class (at runtime, when loading the
5873 module, the GNU runtime library loops on the statically allocated
5874 instances (as found in the defs field in objc_symtab) and fixups
5875 all the 'isa' pointers of those objects). */
5876 if (! flag_next_runtime)
5878 /* This type is a struct containing the fields of a Protocol
5879 object. (Cfr. objc_protocol_type instead is the type of a pointer
5880 to such a struct). */
5881 tree protocol_struct_type = xref_tag
5882 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5885 /* Look for the list of Protocol statically allocated instances
5886 to fixup at runtime. Create a new list to hold Protocol
5887 statically allocated instances, if the list is not found. At
5888 present there is only another list, holding NSConstantString
5889 static instances to be fixed up at runtime. */
5890 for (chain = &objc_static_instances;
5891 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5892 chain = &TREE_CHAIN (*chain));
5895 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5896 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
5900 /* Add this statically allocated instance to the Protocol list. */
5901 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5902 PROTOCOL_FORWARD_DECL (p),
5903 TREE_PURPOSE (*chain));
5910 /* This function is called by the parser when a @selector() expression
5911 is found, in order to compile it. It is only called by the parser
5912 and only to compile a @selector(). */
5914 objc_build_selector_expr (tree selnamelist)
5918 /* Obtain the full selector name. */
5919 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5920 /* A unary selector. */
5921 selname = selnamelist;
5922 else if (TREE_CODE (selnamelist) == TREE_LIST)
5923 selname = build_keyword_selector (selnamelist);
5927 /* If we are required to check @selector() expressions as they
5928 are found, check that the selector has been declared. */
5929 if (warn_undeclared_selector)
5931 /* Look the selector up in the list of all known class and
5932 instance methods (up to this line) to check that the selector
5936 /* First try with instance methods. */
5937 hsh = hash_lookup (nst_method_hash_list, selname);
5939 /* If not found, try with class methods. */
5942 hsh = hash_lookup (cls_method_hash_list, selname);
5945 /* If still not found, print out a warning. */
5948 warning ("undeclared selector %qs", IDENTIFIER_POINTER (selname));
5953 if (flag_typed_selectors)
5954 return build_typed_selector_reference (selname, 0);
5956 return build_selector_reference (selname);
5960 objc_build_encode_expr (tree type)
5965 encode_type (type, obstack_object_size (&util_obstack),
5966 OBJC_ENCODE_INLINE_DEFS);
5967 obstack_1grow (&util_obstack, 0); /* null terminate string */
5968 string = obstack_finish (&util_obstack);
5970 /* Synthesize a string that represents the encoded struct/union. */
5971 result = my_build_string (strlen (string) + 1, string);
5972 obstack_free (&util_obstack, util_firstobj);
5977 build_ivar_reference (tree id)
5979 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5981 /* Historically, a class method that produced objects (factory
5982 method) would assign `self' to the instance that it
5983 allocated. This would effectively turn the class method into
5984 an instance method. Following this assignment, the instance
5985 variables could be accessed. That practice, while safe,
5986 violates the simple rule that a class method should not refer
5987 to an instance variable. It's better to catch the cases
5988 where this is done unknowingly than to support the above
5990 warning ("instance variable %qs accessed in class method",
5991 IDENTIFIER_POINTER (id));
5992 self_decl = convert (objc_instance_type, self_decl); /* cast */
5995 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5998 /* Compute a hash value for a given method SEL_NAME. */
6001 hash_func (tree sel_name)
6003 const unsigned char *s
6004 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6008 h = h * 67 + *s++ - 113;
6015 nst_method_hash_list
6016 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6017 cls_method_hash_list
6018 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6020 /* Initialize the hash table used to hold the constant string objects. */
6021 string_htab = htab_create_ggc (31, string_hash,
6025 /* WARNING!!!! hash_enter is called with a method, and will peek
6026 inside to find its selector! But hash_lookup is given a selector
6027 directly, and looks for the selector that's inside the found
6028 entry's key (method) for comparison. */
6031 hash_enter (hash *hashlist, tree method)
6034 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6036 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6038 obj->next = hashlist[slot];
6041 hashlist[slot] = obj; /* append to front */
6045 hash_lookup (hash *hashlist, tree sel_name)
6049 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6053 if (sel_name == METHOD_SEL_NAME (target->key))
6056 target = target->next;
6062 hash_add_attr (hash entry, tree value)
6066 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6067 obj->next = entry->list;
6070 entry->list = obj; /* append to front */
6074 lookup_method (tree mchain, tree method)
6078 if (TREE_CODE (method) == IDENTIFIER_NODE)
6081 key = METHOD_SEL_NAME (method);
6085 if (METHOD_SEL_NAME (mchain) == key)
6088 mchain = TREE_CHAIN (mchain);
6094 lookup_method_static (tree interface, tree ident, int is_class)
6096 tree meth = NULL_TREE, root_inter = NULL_TREE;
6097 tree inter = interface;
6101 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6102 tree category = inter;
6104 /* First, look up the method in the class itself. */
6105 if ((meth = lookup_method (chain, ident)))
6108 /* Failing that, look for the method in each category of the class. */
6109 while ((category = CLASS_CATEGORY_LIST (category)))
6111 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6113 /* Check directly in each category. */
6114 if ((meth = lookup_method (chain, ident)))
6117 /* Failing that, check in each category's protocols. */
6118 if (CLASS_PROTOCOL_LIST (category))
6120 if ((meth = (lookup_method_in_protocol_list
6121 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6126 /* If not found in categories, check in protocols of the main class. */
6127 if (CLASS_PROTOCOL_LIST (inter))
6129 if ((meth = (lookup_method_in_protocol_list
6130 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6134 /* Failing that, climb up the inheritance hierarchy. */
6136 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6140 /* If no class (factory) method was found, check if an _instance_
6141 method of the same name exists in the root class. This is what
6142 the Objective-C runtime will do. If an instance method was not
6144 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6147 /* Add the method to the hash list if it doesn't contain an identical
6150 add_method_to_hash_list (hash *hash_list, tree method)
6154 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6156 /* Install on a global chain. */
6157 hash_enter (hash_list, method);
6161 /* Check types against those; if different, add to a list. */
6163 int already_there = comp_proto_with_proto (method, hsh->key);
6164 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6165 already_there |= comp_proto_with_proto (method, loop->value);
6167 hash_add_attr (hsh, method);
6172 objc_add_method (tree class, tree method, int is_class)
6176 if (!(mth = lookup_method (is_class
6177 ? CLASS_CLS_METHODS (class)
6178 : CLASS_NST_METHODS (class), method)))
6180 /* put method on list in reverse order */
6183 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6184 CLASS_CLS_METHODS (class) = method;
6188 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6189 CLASS_NST_METHODS (class) = method;
6194 /* When processing an @interface for a class or category, give hard
6195 errors on methods with identical selectors but differing argument
6196 and/or return types. We do not do this for @implementations, because
6197 C/C++ will do it for us (i.e., there will be duplicate function
6198 definition errors). */
6199 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6200 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6201 && !comp_proto_with_proto (method, mth))
6202 error ("duplicate declaration of method %<%c%s%>",
6203 is_class ? '+' : '-',
6204 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6208 add_method_to_hash_list (cls_method_hash_list, method);
6211 add_method_to_hash_list (nst_method_hash_list, method);
6213 /* Instance methods in root classes (and categories thereof)
6214 may act as class methods as a last resort. We also add
6215 instance methods listed in @protocol declarations to
6216 the class hash table, on the assumption that @protocols
6217 may be adopted by root classes or categories. */
6218 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6219 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6220 class = lookup_interface (CLASS_NAME (class));
6222 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6223 || !CLASS_SUPER_NAME (class))
6224 add_method_to_hash_list (cls_method_hash_list, method);
6231 add_class (tree class)
6233 /* Put interfaces on list in reverse order. */
6234 TREE_CHAIN (class) = interface_chain;
6235 interface_chain = class;
6236 return interface_chain;
6240 add_category (tree class, tree category)
6242 /* Put categories on list in reverse order. */
6243 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6247 warning ("duplicate interface declaration for category %<%s(%s)%>",
6248 IDENTIFIER_POINTER (CLASS_NAME (class)),
6249 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6253 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6254 CLASS_CATEGORY_LIST (class) = category;
6258 /* Called after parsing each instance variable declaration. Necessary to
6259 preserve typedefs and implement public/private...
6261 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6264 add_instance_variable (tree class, int public, tree field_decl)
6266 tree field_type = TREE_TYPE (field_decl);
6267 const char *ivar_name = DECL_NAME (field_decl)
6268 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6272 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6274 error ("illegal reference type specified for instance variable %qs",
6276 /* Return class as is without adding this ivar. */
6281 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6282 || TYPE_SIZE (field_type) == error_mark_node)
6283 /* 'type[0]' is allowed, but 'type[]' is not! */
6285 error ("instance variable %qs has unknown size", ivar_name);
6286 /* Return class as is without adding this ivar. */
6291 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6292 cannot be ivars; ditto for classes with vtables. */
6293 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6294 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6296 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6297 if(TYPE_POLYMORPHIC_P (field_type)) {
6298 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6299 error ("type %qs has virtual member functions", type_name);
6300 error ("illegal aggregate type %qs specified for instance variable %qs",
6301 type_name, ivar_name);
6302 /* Return class as is without adding this ivar. */
6305 /* user-defined constructors and destructors are not known to Obj-C and
6306 hence will not be called. This may or may not be a problem. */
6307 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6308 warning ("type %qs has a user-defined constructor", type_name);
6309 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6310 warning ("type %qs has a user-defined destructor", type_name);
6311 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6315 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6319 TREE_PUBLIC (field_decl) = 0;
6320 TREE_PRIVATE (field_decl) = 0;
6321 TREE_PROTECTED (field_decl) = 1;
6325 TREE_PUBLIC (field_decl) = 1;
6326 TREE_PRIVATE (field_decl) = 0;
6327 TREE_PROTECTED (field_decl) = 0;
6331 TREE_PUBLIC (field_decl) = 0;
6332 TREE_PRIVATE (field_decl) = 1;
6333 TREE_PROTECTED (field_decl) = 0;
6338 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
6344 is_ivar (tree decl_chain, tree ident)
6346 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6347 if (DECL_NAME (decl_chain) == ident)
6352 /* True if the ivar is private and we are not in its implementation. */
6355 is_private (tree decl)
6357 return (TREE_PRIVATE (decl)
6358 && ! is_ivar (CLASS_IVARS (implementation_template),
6362 /* We have an instance variable reference;, check to see if it is public. */
6365 objc_is_public (tree expr, tree identifier)
6367 tree basetype = TREE_TYPE (expr);
6368 enum tree_code code = TREE_CODE (basetype);
6371 if (code == RECORD_TYPE)
6373 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
6375 if (TREE_CODE (TYPE_OBJC_INTERFACE (basetype)) == IDENTIFIER_NODE)
6377 error ("cannot find interface declaration for %qs",
6378 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6382 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6384 if (TREE_PUBLIC (decl))
6387 /* Important difference between the Stepstone translator:
6388 all instance variables should be public within the context
6389 of the implementation. */
6390 if (objc_implementation_context
6391 && (((TREE_CODE (objc_implementation_context)
6392 == CLASS_IMPLEMENTATION_TYPE)
6393 || (TREE_CODE (objc_implementation_context)
6394 == CATEGORY_IMPLEMENTATION_TYPE))
6395 && (CLASS_NAME (objc_implementation_context)
6396 == OBJC_TYPE_NAME (basetype))))
6398 int private = is_private (decl);
6401 error ("instance variable %qs is declared private",
6402 IDENTIFIER_POINTER (DECL_NAME (decl)));
6406 /* The 2.95.2 compiler sometimes allowed C functions to access
6407 non-@public ivars. We will let this slide for now... */
6408 if (!objc_method_context)
6410 warning ("instance variable %qs is %s; "
6411 "this will be a hard error in the future",
6412 IDENTIFIER_POINTER (identifier),
6413 TREE_PRIVATE (decl) ? "@private" : "@protected");
6417 error ("instance variable %qs is declared %s",
6418 IDENTIFIER_POINTER (identifier),
6419 TREE_PRIVATE (decl) ? "private" : "protected");
6424 else if (objc_implementation_context && (basetype == objc_object_reference))
6426 expr = convert (uprivate_record, expr);
6427 warning ("static access to object of type %<id%>");
6434 /* Make sure all entries in CHAIN are also in LIST. */
6437 check_methods (tree chain, tree list, int mtype)
6443 if (!lookup_method (list, chain))
6447 if (TREE_CODE (objc_implementation_context)
6448 == CLASS_IMPLEMENTATION_TYPE)
6449 warning ("incomplete implementation of class %qs",
6450 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6451 else if (TREE_CODE (objc_implementation_context)
6452 == CATEGORY_IMPLEMENTATION_TYPE)
6453 warning ("incomplete implementation of category %qs",
6454 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6458 warning ("method definition for %<%c%s%> not found",
6459 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6462 chain = TREE_CHAIN (chain);
6468 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6471 conforms_to_protocol (tree class, tree protocol)
6473 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6475 tree p = CLASS_PROTOCOL_LIST (class);
6476 while (p && TREE_VALUE (p) != protocol)
6481 tree super = (CLASS_SUPER_NAME (class)
6482 ? lookup_interface (CLASS_SUPER_NAME (class))
6484 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6493 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6494 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6497 check_methods_accessible (tree chain, tree context, int mtype)
6501 tree base_context = context;
6505 context = base_context;
6509 list = CLASS_CLS_METHODS (context);
6511 list = CLASS_NST_METHODS (context);
6513 if (lookup_method (list, chain))
6516 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6517 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6518 context = (CLASS_SUPER_NAME (context)
6519 ? lookup_interface (CLASS_SUPER_NAME (context))
6522 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6523 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6524 context = (CLASS_NAME (context)
6525 ? lookup_interface (CLASS_NAME (context))
6531 if (context == NULL_TREE)
6535 if (TREE_CODE (objc_implementation_context)
6536 == CLASS_IMPLEMENTATION_TYPE)
6537 warning ("incomplete implementation of class %qs",
6539 (CLASS_NAME (objc_implementation_context)));
6540 else if (TREE_CODE (objc_implementation_context)
6541 == CATEGORY_IMPLEMENTATION_TYPE)
6542 warning ("incomplete implementation of category %qs",
6544 (CLASS_SUPER_NAME (objc_implementation_context)));
6547 warning ("method definition for %<%c%s%> not found",
6548 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6551 chain = TREE_CHAIN (chain); /* next method... */
6556 /* Check whether the current interface (accessible via
6557 'objc_implementation_context') actually implements protocol P, along
6558 with any protocols that P inherits. */
6561 check_protocol (tree p, const char *type, const char *name)
6563 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6567 /* Ensure that all protocols have bodies! */
6570 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6571 CLASS_CLS_METHODS (objc_implementation_context),
6573 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6574 CLASS_NST_METHODS (objc_implementation_context),
6579 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6580 objc_implementation_context,
6582 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6583 objc_implementation_context,
6588 warning ("%s %qs does not fully implement the %qs protocol",
6589 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6592 /* Check protocols recursively. */
6593 if (PROTOCOL_LIST (p))
6595 tree subs = PROTOCOL_LIST (p);
6597 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6601 tree sub = TREE_VALUE (subs);
6603 /* If the superclass does not conform to the protocols
6604 inherited by P, then we must! */
6605 if (!super_class || !conforms_to_protocol (super_class, sub))
6606 check_protocol (sub, type, name);
6607 subs = TREE_CHAIN (subs);
6612 /* Check whether the current interface (accessible via
6613 'objc_implementation_context') actually implements the protocols listed
6617 check_protocols (tree proto_list, const char *type, const char *name)
6619 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6621 tree p = TREE_VALUE (proto_list);
6623 check_protocol (p, type, name);
6627 /* Make sure that the class CLASS_NAME is defined
6628 CODE says which kind of thing CLASS_NAME ought to be.
6629 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6630 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6633 start_class (enum tree_code code, tree class_name, tree super_name,
6639 if (current_namespace != global_namespace) {
6640 error ("Objective-C declarations may only appear in global scope");
6642 #endif /* OBJCPLUS */
6644 if (objc_implementation_context)
6646 warning ("%<@end%> missing in implementation context");
6647 finish_class (objc_implementation_context);
6648 objc_ivar_chain = NULL_TREE;
6649 objc_implementation_context = NULL_TREE;
6652 class = make_node (code);
6653 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
6655 /* Check for existence of the super class, if one was specified. */
6656 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
6657 && super_name && !objc_is_class_name (super_name))
6659 error ("cannot find interface declaration for %qs, superclass of %qs",
6660 IDENTIFIER_POINTER (super_name),
6661 IDENTIFIER_POINTER (class_name));
6662 super_name = NULL_TREE;
6665 CLASS_NAME (class) = class_name;
6666 CLASS_SUPER_NAME (class) = super_name;
6667 CLASS_CLS_METHODS (class) = NULL_TREE;
6669 if (! objc_is_class_name (class_name)
6670 && (decl = lookup_name (class_name)))
6672 error ("%qs redeclared as different kind of symbol",
6673 IDENTIFIER_POINTER (class_name));
6674 error ("%Jprevious declaration of '%D'",
6678 if (code == CLASS_IMPLEMENTATION_TYPE)
6683 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6684 if (TREE_VALUE (chain) == class_name)
6686 error ("reimplementation of class %qs",
6687 IDENTIFIER_POINTER (class_name));
6688 return error_mark_node;
6690 implemented_classes = tree_cons (NULL_TREE, class_name,
6691 implemented_classes);
6694 /* Reset for multiple classes per file. */
6697 objc_implementation_context = class;
6699 /* Lookup the interface for this implementation. */
6701 if (!(implementation_template = lookup_interface (class_name)))
6703 warning ("cannot find interface declaration for %qs",
6704 IDENTIFIER_POINTER (class_name));
6705 add_class (implementation_template = objc_implementation_context);
6708 /* If a super class has been specified in the implementation,
6709 insure it conforms to the one specified in the interface. */
6712 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6714 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6715 const char *const name =
6716 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6717 error ("conflicting super class name %qs",
6718 IDENTIFIER_POINTER (super_name));
6719 error ("previous declaration of %qs", name);
6722 else if (! super_name)
6724 CLASS_SUPER_NAME (objc_implementation_context)
6725 = CLASS_SUPER_NAME (implementation_template);
6729 else if (code == CLASS_INTERFACE_TYPE)
6731 if (lookup_interface (class_name))
6733 error ("duplicate interface declaration for class %qs",
6735 warning ("duplicate interface declaration for class %qs",
6737 IDENTIFIER_POINTER (class_name));
6742 CLASS_PROTOCOL_LIST (class)
6743 = lookup_and_install_protocols (protocol_list);
6746 else if (code == CATEGORY_INTERFACE_TYPE)
6748 tree class_category_is_assoc_with;
6750 /* For a category, class_name is really the name of the class that
6751 the following set of methods will be associated with. We must
6752 find the interface so that can derive the objects template. */
6754 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6756 error ("cannot find interface declaration for %qs",
6757 IDENTIFIER_POINTER (class_name));
6758 exit (FATAL_EXIT_CODE);
6761 add_category (class_category_is_assoc_with, class);
6764 CLASS_PROTOCOL_LIST (class)
6765 = lookup_and_install_protocols (protocol_list);
6768 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6770 /* Reset for multiple classes per file. */
6773 objc_implementation_context = class;
6775 /* For a category, class_name is really the name of the class that
6776 the following set of methods will be associated with. We must
6777 find the interface so that can derive the objects template. */
6779 if (!(implementation_template = lookup_interface (class_name)))
6781 error ("cannot find interface declaration for %qs",
6782 IDENTIFIER_POINTER (class_name));
6783 exit (FATAL_EXIT_CODE);
6790 continue_class (tree class)
6792 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6793 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6795 struct imp_entry *imp_entry;
6798 /* Check consistency of the instance variables. */
6800 if (CLASS_RAW_IVARS (class))
6801 check_ivars (implementation_template, class);
6803 /* code generation */
6806 push_lang_context (lang_name_c);
6809 build_private_template (implementation_template);
6810 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
6811 ivar_context = TYPE_FIELDS (uprivate_record);
6812 objc_instance_type = build_pointer_type (uprivate_record);
6814 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6816 imp_entry->next = imp_list;
6817 imp_entry->imp_context = class;
6818 imp_entry->imp_template = implementation_template;
6820 synth_forward_declarations ();
6821 imp_entry->class_decl = UOBJC_CLASS_decl;
6822 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6824 /* Append to front and increment count. */
6825 imp_list = imp_entry;
6826 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6832 pop_lang_context ();
6833 #endif /* OBJCPLUS */
6835 return ivar_context;
6838 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6841 push_lang_context (lang_name_c);
6842 #endif /* OBJCPLUS */
6844 build_private_template (class);
6847 pop_lang_context ();
6848 #endif /* OBJCPLUS */
6854 return error_mark_node;
6857 /* This is called once we see the "@end" in an interface/implementation. */
6860 finish_class (tree class)
6862 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6864 /* All code generation is done in finish_objc. */
6866 if (implementation_template != objc_implementation_context)
6868 /* Ensure that all method listed in the interface contain bodies. */
6869 check_methods (CLASS_CLS_METHODS (implementation_template),
6870 CLASS_CLS_METHODS (objc_implementation_context), '+');
6871 check_methods (CLASS_NST_METHODS (implementation_template),
6872 CLASS_NST_METHODS (objc_implementation_context), '-');
6874 if (CLASS_PROTOCOL_LIST (implementation_template))
6875 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6877 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6881 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6883 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6887 /* Ensure all method listed in the interface contain bodies. */
6888 check_methods (CLASS_CLS_METHODS (category),
6889 CLASS_CLS_METHODS (objc_implementation_context), '+');
6890 check_methods (CLASS_NST_METHODS (category),
6891 CLASS_NST_METHODS (objc_implementation_context), '-');
6893 if (CLASS_PROTOCOL_LIST (category))
6894 check_protocols (CLASS_PROTOCOL_LIST (category),
6896 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6902 add_protocol (tree protocol)
6904 /* Put protocol on list in reverse order. */
6905 TREE_CHAIN (protocol) = protocol_chain;
6906 protocol_chain = protocol;
6907 return protocol_chain;
6911 lookup_protocol (tree ident)
6915 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6916 if (ident == PROTOCOL_NAME (chain))
6922 /* This function forward declares the protocols named by NAMES. If
6923 they are already declared or defined, the function has no effect. */
6926 objc_declare_protocols (tree names)
6931 if (current_namespace != global_namespace) {
6932 error ("Objective-C declarations may only appear in global scope");
6934 #endif /* OBJCPLUS */
6936 for (list = names; list; list = TREE_CHAIN (list))
6938 tree name = TREE_VALUE (list);
6940 if (lookup_protocol (name) == NULL_TREE)
6942 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6944 TYPE_LANG_SLOT_1 (protocol)
6945 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
6946 PROTOCOL_NAME (protocol) = name;
6947 PROTOCOL_LIST (protocol) = NULL_TREE;
6948 add_protocol (protocol);
6949 PROTOCOL_DEFINED (protocol) = 0;
6950 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6956 start_protocol (enum tree_code code, tree name, tree list)
6961 if (current_namespace != global_namespace) {
6962 error ("Objective-C declarations may only appear in global scope");
6964 #endif /* OBJCPLUS */
6966 protocol = lookup_protocol (name);
6970 protocol = make_node (code);
6971 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
6973 PROTOCOL_NAME (protocol) = name;
6974 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6975 add_protocol (protocol);
6976 PROTOCOL_DEFINED (protocol) = 1;
6977 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6979 check_protocol_recursively (protocol, list);
6981 else if (! PROTOCOL_DEFINED (protocol))
6983 PROTOCOL_DEFINED (protocol) = 1;
6984 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6986 check_protocol_recursively (protocol, list);
6990 warning ("duplicate declaration for protocol %qs",
6991 IDENTIFIER_POINTER (name));
6997 /* "Encode" a data type into a string, which grows in util_obstack.
6998 ??? What is the FORMAT? Someone please document this! */
7001 encode_type_qualifiers (tree declspecs)
7005 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7007 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7008 obstack_1grow (&util_obstack, 'n');
7009 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7010 obstack_1grow (&util_obstack, 'N');
7011 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7012 obstack_1grow (&util_obstack, 'o');
7013 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7014 obstack_1grow (&util_obstack, 'O');
7015 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7016 obstack_1grow (&util_obstack, 'R');
7017 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7018 obstack_1grow (&util_obstack, 'V');
7022 /* Encode a pointer type. */
7025 encode_pointer (tree type, int curtype, int format)
7027 tree pointer_to = TREE_TYPE (type);
7029 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7031 if (OBJC_TYPE_NAME (pointer_to)
7032 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7034 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7036 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7038 obstack_1grow (&util_obstack, '@');
7041 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7042 && TYPE_OBJC_INTERFACE (pointer_to))
7044 if (generating_instance_variables)
7046 obstack_1grow (&util_obstack, '@');
7047 obstack_1grow (&util_obstack, '"');
7048 obstack_grow (&util_obstack, name, strlen (name));
7049 obstack_1grow (&util_obstack, '"');
7054 obstack_1grow (&util_obstack, '@');
7058 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7060 obstack_1grow (&util_obstack, '#');
7063 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7065 obstack_1grow (&util_obstack, ':');
7070 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7071 && TYPE_MODE (pointer_to) == QImode)
7073 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7074 ? OBJC_TYPE_NAME (pointer_to)
7075 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7077 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7079 /* It appears that "r*" means "const char *" rather than
7081 if (TYPE_READONLY (pointer_to))
7082 obstack_1grow (&util_obstack, 'r');
7084 obstack_1grow (&util_obstack, '*');
7089 /* We have a type that does not get special treatment. */
7091 /* NeXT extension */
7092 obstack_1grow (&util_obstack, '^');
7093 encode_type (pointer_to, curtype, format);
7097 encode_array (tree type, int curtype, int format)
7099 tree an_int_cst = TYPE_SIZE (type);
7100 tree array_of = TREE_TYPE (type);
7103 /* An incomplete array is treated like a pointer. */
7104 if (an_int_cst == NULL)
7106 encode_pointer (type, curtype, format);
7110 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7111 (TREE_INT_CST_LOW (an_int_cst)
7112 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7114 obstack_grow (&util_obstack, buffer, strlen (buffer));
7115 encode_type (array_of, curtype, format);
7116 obstack_1grow (&util_obstack, ']');
7121 encode_aggregate_within (tree type, int curtype, int format, int left,
7125 /* NB: aggregates that are pointed to have slightly different encoding
7126 rules in that you never encode the names of instance variables. */
7128 = (obstack_object_size (&util_obstack) > 0
7129 && *(obstack_next_free (&util_obstack) - 1) == '^');
7131 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7132 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7134 /* Traverse struct aliases; it is important to get the
7135 original struct and its tag name (if any). */
7136 type = TYPE_MAIN_VARIANT (type);
7137 name = OBJC_TYPE_NAME (type);
7138 /* Open parenth/bracket. */
7139 obstack_1grow (&util_obstack, left);
7141 /* Encode the struct/union tag name, or '?' if a tag was
7142 not provided. Typedef aliases do not qualify. */
7143 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7145 /* Did this struct have a tag? */
7146 && !TYPE_WAS_ANONYMOUS (type)
7149 obstack_grow (&util_obstack,
7150 IDENTIFIER_POINTER (name),
7151 strlen (IDENTIFIER_POINTER (name)));
7153 obstack_1grow (&util_obstack, '?');
7155 /* Encode the types (and possibly names) of the inner fields,
7157 if (inline_contents)
7159 tree fields = TYPE_FIELDS (type);
7161 obstack_1grow (&util_obstack, '=');
7162 for (; fields; fields = TREE_CHAIN (fields))
7165 /* C++ static members, and things that are not fields at all,
7166 should not appear in the encoding. */
7167 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7170 if (generating_instance_variables && !pointed_to)
7172 tree fname = DECL_NAME (fields);
7174 obstack_1grow (&util_obstack, '"');
7175 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7176 obstack_grow (&util_obstack,
7177 IDENTIFIER_POINTER (fname),
7178 strlen (IDENTIFIER_POINTER (fname)));
7179 obstack_1grow (&util_obstack, '"');
7181 encode_field_decl (fields, curtype, format);
7184 /* Close parenth/bracket. */
7185 obstack_1grow (&util_obstack, right);
7189 encode_aggregate (tree type, int curtype, int format)
7191 enum tree_code code = TREE_CODE (type);
7197 encode_aggregate_within (type, curtype, format, '{', '}');
7202 encode_aggregate_within (type, curtype, format, '(', ')');
7207 obstack_1grow (&util_obstack, 'i');
7215 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7219 encode_next_bitfield (int width)
7222 sprintf (buffer, "b%d", width);
7223 obstack_grow (&util_obstack, buffer, strlen (buffer));
7226 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7228 encode_type (tree type, int curtype, int format)
7230 enum tree_code code = TREE_CODE (type);
7233 if (TYPE_READONLY (type))
7234 obstack_1grow (&util_obstack, 'r');
7236 if (code == INTEGER_TYPE)
7238 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7240 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7241 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7243 if (type == long_unsigned_type_node
7244 || type == long_integer_type_node)
7245 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7247 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7249 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7252 obstack_1grow (&util_obstack, c);
7255 else if (code == REAL_TYPE)
7257 /* Floating point types. */
7258 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7260 case 32: c = 'f'; break;
7263 case 128: c = 'd'; break;
7266 obstack_1grow (&util_obstack, c);
7269 else if (code == VOID_TYPE)
7270 obstack_1grow (&util_obstack, 'v');
7272 else if (code == BOOLEAN_TYPE)
7273 obstack_1grow (&util_obstack, 'B');
7275 else if (code == ARRAY_TYPE)
7276 encode_array (type, curtype, format);
7278 else if (code == POINTER_TYPE)
7279 encode_pointer (type, curtype, format);
7281 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7282 encode_aggregate (type, curtype, format);
7284 else if (code == FUNCTION_TYPE) /* '?' */
7285 obstack_1grow (&util_obstack, '?');
7289 encode_gnu_bitfield (int position, tree type, int size)
7291 enum tree_code code = TREE_CODE (type);
7293 char charType = '?';
7295 if (code == INTEGER_TYPE)
7297 if (integer_zerop (TYPE_MIN_VALUE (type)))
7299 /* Unsigned integer types. */
7301 if (TYPE_MODE (type) == QImode)
7303 else if (TYPE_MODE (type) == HImode)
7305 else if (TYPE_MODE (type) == SImode)
7307 if (type == long_unsigned_type_node)
7312 else if (TYPE_MODE (type) == DImode)
7317 /* Signed integer types. */
7319 if (TYPE_MODE (type) == QImode)
7321 else if (TYPE_MODE (type) == HImode)
7323 else if (TYPE_MODE (type) == SImode)
7325 if (type == long_integer_type_node)
7331 else if (TYPE_MODE (type) == DImode)
7335 else if (code == ENUMERAL_TYPE)
7340 sprintf (buffer, "b%d%c%d", position, charType, size);
7341 obstack_grow (&util_obstack, buffer, strlen (buffer));
7345 encode_field_decl (tree field_decl, int curtype, int format)
7350 /* C++ static members, and things that are not fields at all,
7351 should not appear in the encoding. */
7352 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7356 type = TREE_TYPE (field_decl);
7358 /* Generate the bitfield typing information, if needed. Note the difference
7359 between GNU and NeXT runtimes. */
7360 if (DECL_BIT_FIELD_TYPE (field_decl))
7362 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7364 if (flag_next_runtime)
7365 encode_next_bitfield (size);
7367 encode_gnu_bitfield (int_bit_position (field_decl),
7368 DECL_BIT_FIELD_TYPE (field_decl), size);
7371 encode_type (TREE_TYPE (field_decl), curtype, format);
7374 static GTY(()) tree objc_parmlist = NULL_TREE;
7376 /* Append PARM to a list of formal parameters of a method, making a necessary
7377 array-to-pointer adjustment along the way. */
7380 objc_push_parm (tree parm)
7382 /* Convert array parameters of unknown size into pointers. */
7383 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE
7384 && !TYPE_SIZE (TREE_TYPE (parm)))
7385 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
7387 objc_parmlist = chainon (objc_parmlist, parm);
7390 /* Retrieve the formal parameter list constructed via preceding calls to
7391 objc_push_parm(). */
7395 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
7397 static struct c_arg_info *
7398 objc_get_parm_info (int have_ellipsis)
7402 tree parm_info = objc_parmlist;
7403 objc_parmlist = NULL_TREE;
7407 tree parm_info = objc_parmlist;
7408 struct c_arg_info *arg_info;
7409 /* The C front-end requires an elaborate song and dance at
7412 declare_parm_level ();
7415 tree next = TREE_CHAIN (parm_info);
7417 TREE_CHAIN (parm_info) = NULL_TREE;
7418 pushdecl (parm_info);
7421 arg_info = get_parm_info (have_ellipsis);
7423 objc_parmlist = NULL_TREE;
7428 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
7429 method definitions. In the case of instance methods, we can be more
7430 specific as to the type of 'self'. */
7433 synth_self_and_ucmd_args (void)
7437 if (objc_method_context
7438 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7439 self_type = objc_instance_type;
7441 /* Really a `struct objc_class *'. However, we allow people to
7442 assign to self, which changes its type midstream. */
7443 self_type = objc_object_type;
7446 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
7449 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
7452 /* Transform an Objective-C method definition into a static C function
7453 definition, synthesizing the first two arguments, "self" and "_cmd",
7457 start_method_def (tree method)
7463 struct c_arg_info *parm_info;
7465 int have_ellipsis = 0;
7467 /* Required to implement _msgSuper. */
7468 objc_method_context = method;
7469 UOBJC_SUPER_decl = NULL_TREE;
7471 /* Generate prototype declarations for arguments..."new-style". */
7472 synth_self_and_ucmd_args ();
7474 /* Generate argument declarations if a keyword_decl. */
7475 parmlist = METHOD_SEL_ARGS (method);
7478 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
7480 /* Decay arrays into pointers. */
7481 if (TREE_CODE (type) == ARRAY_TYPE)
7482 type = build_pointer_type (TREE_TYPE (type));
7484 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
7485 objc_push_parm (parm);
7486 parmlist = TREE_CHAIN (parmlist);
7489 if (METHOD_ADD_ARGS (method))
7493 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
7494 akey; akey = TREE_CHAIN (akey))
7496 objc_push_parm (TREE_VALUE (akey));
7499 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
7503 parm_info = objc_get_parm_info (have_ellipsis);
7505 really_start_method (objc_method_context, parm_info);
7509 warn_with_method (const char *message, int mtype, tree method)
7511 /* Add a readable method name to the warning. */
7512 warning ("%J%s %<%c%s%>", method,
7513 message, mtype, gen_method_decl (method));
7516 /* Return 1 if TYPE1 is equivalent to TYPE2
7517 for purposes of method overloading. */
7520 objc_types_are_equivalent (tree type1, tree type2)
7525 /* Strip away indirections. */
7526 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
7527 && (TREE_CODE (type1) == TREE_CODE (type2)))
7528 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
7529 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7532 type1 = (TYPE_HAS_OBJC_INFO (type1)
7533 ? TYPE_OBJC_PROTOCOL_LIST (type1)
7535 type2 = (TYPE_HAS_OBJC_INFO (type2)
7536 ? TYPE_OBJC_PROTOCOL_LIST (type2)
7539 if (list_length (type1) == list_length (type2))
7541 for (; type2; type2 = TREE_CHAIN (type2))
7542 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7549 /* Return 1 if PROTO1 is equivalent to PROTO2
7550 for purposes of method overloading. */
7553 comp_proto_with_proto (tree proto1, tree proto2)
7557 /* The following test is needed in case there are hashing
7559 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7562 /* Compare return types. */
7563 type1 = TREE_VALUE (TREE_TYPE (proto1));
7564 type2 = TREE_VALUE (TREE_TYPE (proto2));
7566 if (!objc_types_are_equivalent (type1, type2))
7569 /* Compare argument types. */
7570 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7571 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7573 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7575 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7579 return (!type1 && !type2);
7582 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
7583 this occurs. ObjC method dispatches are _not_ like C++ virtual
7584 member function dispatches, and we account for the difference here. */
7587 objc_fold_obj_type_ref (tree ref, tree known_type)
7589 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
7590 tree known_type ATTRIBUTE_UNUSED)
7594 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
7596 /* If the receiver does not have virtual member functions, there
7597 is nothing we can (or need to) do here. */
7601 /* Let C++ handle C++ virtual functions. */
7602 return cp_fold_obj_type_ref (ref, known_type);
7604 /* For plain ObjC, we currently do not need to do anything. */
7610 objc_start_function (tree name, tree type, tree attrs,
7614 struct c_arg_info *params
7618 tree fndecl = build_decl (FUNCTION_DECL, name, type);
7621 DECL_ARGUMENTS (fndecl) = params;
7623 DECL_INITIAL (fndecl) = error_mark_node;
7624 DECL_EXTERNAL (fndecl) = 0;
7625 TREE_STATIC (fndecl) = 1;
7628 retrofit_lang_decl (fndecl);
7629 cplus_decl_attributes (&fndecl, attrs, 0);
7630 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
7632 decl_attributes (&fndecl, attrs, 0);
7633 announce_function (fndecl);
7634 current_function_decl = pushdecl (fndecl);
7636 declare_parm_level ();
7637 DECL_RESULT (current_function_decl)
7638 = build_decl (RESULT_DECL, NULL_TREE,
7639 TREE_TYPE (TREE_TYPE (current_function_decl)));
7640 start_fname_decls ();
7641 store_parm_decls_from (params);
7644 TREE_USED (current_function_decl) = 1;
7647 /* - Generate an identifier for the function. the format is "_n_cls",
7648 where 1 <= n <= nMethods, and cls is the name the implementation we
7650 - Install the return type from the method declaration.
7651 - If we have a prototype, check for type consistency. */
7654 really_start_method (tree method,
7658 struct c_arg_info *parmlist
7662 tree ret_type, meth_type;
7664 const char *sel_name, *class_name, *cat_name;
7667 /* Synth the storage class & assemble the return type. */
7668 ret_type = TREE_VALUE (TREE_TYPE (method));
7670 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7671 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7672 cat_name = ((TREE_CODE (objc_implementation_context)
7673 == CLASS_IMPLEMENTATION_TYPE)
7675 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7678 /* Make sure this is big enough for any plausible method label. */
7679 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7680 + (cat_name ? strlen (cat_name) : 0));
7682 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7683 class_name, cat_name, sel_name, method_slot);
7685 method_id = get_identifier (buf);
7688 /* Objective-C methods cannot be overloaded, so we don't need
7689 the type encoding appended. It looks bad anyway... */
7690 push_lang_context (lang_name_c);
7694 = build_function_type (ret_type,
7695 get_arg_type_list (method, METHOD_DEF, 0));
7696 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
7698 /* Set self_decl from the first argument. */
7699 self_decl = DECL_ARGUMENTS (current_function_decl);
7701 /* Suppress unused warnings. */
7702 TREE_USED (self_decl) = 1;
7703 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7705 pop_lang_context ();
7708 METHOD_DEFINITION (method) = current_function_decl;
7710 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7712 if (implementation_template != objc_implementation_context)
7715 = lookup_method_static (implementation_template,
7716 METHOD_SEL_NAME (method),
7717 TREE_CODE (method) == CLASS_METHOD_DECL);
7721 if (!comp_proto_with_proto (method, proto))
7723 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7725 warn_with_method ("conflicting types for", type, method);
7726 warn_with_method ("previous declaration of", type, proto);
7731 /* We have a method @implementation even though we did not
7732 see a corresponding @interface declaration (which is allowed
7733 by Objective-C rules). Go ahead and place the method in
7734 the @interface anyway, so that message dispatch lookups
7736 tree interface = implementation_template;
7738 if (TREE_CODE (objc_implementation_context)
7739 == CATEGORY_IMPLEMENTATION_TYPE)
7740 interface = lookup_category
7742 CLASS_SUPER_NAME (objc_implementation_context));
7745 objc_add_method (interface, copy_node (method),
7746 TREE_CODE (method) == CLASS_METHOD_DECL);
7751 static void *UOBJC_SUPER_scope = 0;
7753 /* _n_Method (id self, SEL sel, ...)
7755 struct objc_super _S;
7756 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7760 get_super_receiver (void)
7762 if (objc_method_context)
7764 tree super_expr, super_expr_list;
7766 if (!UOBJC_SUPER_decl)
7768 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
7769 objc_super_template);
7770 /* This prevents `unused variable' warnings when compiling with -Wall. */
7771 TREE_USED (UOBJC_SUPER_decl) = 1;
7772 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
7773 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7774 UOBJC_SUPER_scope = objc_get_current_scope ();
7777 /* Set receiver to self. */
7778 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7779 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7780 super_expr_list = super_expr;
7782 /* Set class to begin searching. */
7783 super_expr = build_component_ref (UOBJC_SUPER_decl,
7784 get_identifier ("super_class"));
7786 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7788 /* [_cls, __cls]Super are "pre-built" in
7789 synth_forward_declarations. */
7791 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7792 ((TREE_CODE (objc_method_context)
7793 == INSTANCE_METHOD_DECL)
7795 : uucls_super_ref));
7799 /* We have a category. */
7801 tree super_name = CLASS_SUPER_NAME (implementation_template);
7804 /* Barf if super used in a category of Object. */
7807 error ("no super class declared in interface for %qs",
7808 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7809 return error_mark_node;
7812 if (flag_next_runtime && !flag_zero_link)
7814 super_class = objc_get_class_reference (super_name);
7815 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7816 /* If we are in a class method, we must retrieve the
7817 _metaclass_ for the current class, pointed at by
7818 the class's "isa" pointer. The following assumes that
7819 "isa" is the first ivar in a class (which it must be). */
7821 = build_indirect_ref
7822 (build_c_cast (build_pointer_type (objc_class_type),
7823 super_class), "unary *");
7827 add_class_reference (super_name);
7828 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7829 ? objc_get_class_decl : objc_get_meta_class_decl);
7830 assemble_external (super_class);
7832 = build_function_call
7836 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7837 IDENTIFIER_POINTER (super_name))));
7841 = build_modify_expr (super_expr, NOP_EXPR,
7842 build_c_cast (TREE_TYPE (super_expr),
7846 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7848 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7849 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7851 return super_expr_list;
7855 error ("[super ...] must appear in a method context");
7856 return error_mark_node;
7860 /* When exiting a scope, sever links to a 'super' declaration (if any)
7861 therein contained. */
7864 objc_clear_super_receiver (void)
7866 if (objc_method_context
7867 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
7868 UOBJC_SUPER_decl = 0;
7869 UOBJC_SUPER_scope = 0;
7874 objc_finish_method_definition (tree fndecl)
7876 /* We cannot validly inline ObjC methods, at least not without a language
7877 extension to declare that a method need not be dynamically
7878 dispatched, so suppress all thoughts of doing so. */
7879 DECL_INLINE (fndecl) = 0;
7880 DECL_UNINLINABLE (fndecl) = 1;
7883 /* The C++ front-end will have called finish_function() for us. */
7887 METHOD_ENCODING (objc_method_context)
7888 = encode_method_prototype (objc_method_context);
7890 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7891 since the optimizer may find "may be used before set" errors. */
7892 objc_method_context = NULL_TREE;
7897 lang_report_error_function (tree decl)
7899 if (objc_method_context)
7901 fprintf (stderr, "In method %qs\n",
7902 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7911 /* Given a tree DECL node, produce a printable description of it in the given
7912 buffer, overwriting the buffer. */
7915 gen_declaration (tree decl)
7921 gen_type_name_0 (TREE_TYPE (decl));
7923 if (DECL_NAME (decl))
7925 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
7926 strcat (errbuf, " ");
7928 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
7931 if (DECL_INITIAL (decl)
7932 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
7933 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
7934 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
7940 /* Given a tree TYPE node, produce a printable description of it in the given
7941 buffer, overwriting the buffer. */
7944 gen_type_name_0 (tree type)
7946 tree orig = type, proto;
7948 if (TYPE_P (type) && TYPE_NAME (type))
7949 type = TYPE_NAME (type);
7950 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
7952 tree inner = TREE_TYPE (type);
7954 while (TREE_CODE (inner) == ARRAY_TYPE)
7955 inner = TREE_TYPE (inner);
7957 gen_type_name_0 (inner);
7959 if (!POINTER_TYPE_P (inner))
7960 strcat (errbuf, " ");
7962 if (POINTER_TYPE_P (type))
7963 strcat (errbuf, "*");
7965 while (type != inner)
7967 strcat (errbuf, "[");
7969 if (TYPE_DOMAIN (type))
7973 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
7975 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
7976 strcat (errbuf, sz);
7979 strcat (errbuf, "]");
7980 type = TREE_TYPE (type);
7986 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
7987 type = DECL_NAME (type);
7989 strcat (errbuf, IDENTIFIER_POINTER (type));
7991 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
7992 if (objc_is_id (orig))
7993 orig = TREE_TYPE (orig);
7995 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
7999 strcat (errbuf, " <");
8003 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8004 proto = TREE_CHAIN (proto);
8005 strcat (errbuf, proto ? ", " : ">");
8014 gen_type_name (tree type)
8018 return gen_type_name_0 (type);
8021 /* Given a method tree, put a printable description into the given
8022 buffer (overwriting) and return a pointer to the buffer. */
8025 gen_method_decl (tree method)
8029 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8030 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8031 strcat (errbuf, ")");
8032 chain = METHOD_SEL_ARGS (method);
8036 /* We have a chain of keyword_decls. */
8039 if (KEYWORD_KEY_NAME (chain))
8040 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8042 strcat (errbuf, ":(");
8043 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8044 strcat (errbuf, ")");
8046 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8047 if ((chain = TREE_CHAIN (chain)))
8048 strcat (errbuf, " ");
8052 if (METHOD_ADD_ARGS (method))
8054 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8056 /* Know we have a chain of parm_decls. */
8059 strcat (errbuf, ", ");
8060 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8061 chain = TREE_CHAIN (chain);
8064 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
8065 strcat (errbuf, ", ...");
8070 /* We have a unary selector. */
8071 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8079 /* Dump an @interface declaration of the supplied class CHAIN to the
8080 supplied file FP. Used to implement the -gen-decls option (which
8081 prints out an @interface declaration of all classes compiled in
8082 this run); potentially useful for debugging the compiler too. */
8084 dump_interface (FILE *fp, tree chain)
8086 /* FIXME: A heap overflow here whenever a method (or ivar)
8087 declaration is so long that it doesn't fit in the buffer. The
8088 code and all the related functions should be rewritten to avoid
8089 using fixed size buffers. */
8090 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8091 tree ivar_decls = CLASS_RAW_IVARS (chain);
8092 tree nst_methods = CLASS_NST_METHODS (chain);
8093 tree cls_methods = CLASS_CLS_METHODS (chain);
8095 fprintf (fp, "\n@interface %s", my_name);
8097 /* CLASS_SUPER_NAME is used to store the superclass name for
8098 classes, and the category name for categories. */
8099 if (CLASS_SUPER_NAME (chain))
8101 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8103 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8104 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8106 fprintf (fp, " (%s)\n", name);
8110 fprintf (fp, " : %s\n", name);
8116 /* FIXME - the following doesn't seem to work at the moment. */
8119 fprintf (fp, "{\n");
8122 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
8123 ivar_decls = TREE_CHAIN (ivar_decls);
8126 fprintf (fp, "}\n");
8131 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
8132 nst_methods = TREE_CHAIN (nst_methods);
8137 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
8138 cls_methods = TREE_CHAIN (cls_methods);
8141 fprintf (fp, "@end\n");
8144 /* Demangle function for Objective-C */
8146 objc_demangle (const char *mangled)
8148 char *demangled, *cp;
8150 if (mangled[0] == '_' &&
8151 (mangled[1] == 'i' || mangled[1] == 'c') &&
8154 cp = demangled = xmalloc(strlen(mangled) + 2);
8155 if (mangled[1] == 'i')
8156 *cp++ = '-'; /* for instance method */
8158 *cp++ = '+'; /* for class method */
8159 *cp++ = '['; /* opening left brace */
8160 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8161 while (*cp && *cp == '_')
8162 cp++; /* skip any initial underbars in class name */
8163 cp = strchr(cp, '_'); /* find first non-initial underbar */
8166 free(demangled); /* not mangled name */
8169 if (cp[1] == '_') /* easy case: no category name */
8171 *cp++ = ' '; /* replace two '_' with one ' ' */
8172 strcpy(cp, mangled + (cp - demangled) + 2);
8176 *cp++ = '('; /* less easy case: category name */
8177 cp = strchr(cp, '_');
8180 free(demangled); /* not mangled name */
8184 *cp++ = ' '; /* overwriting 1st char of method name... */
8185 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8187 while (*cp && *cp == '_')
8188 cp++; /* skip any initial underbars in method name */
8191 *cp = ':'; /* replace remaining '_' with ':' */
8192 *cp++ = ']'; /* closing right brace */
8193 *cp++ = 0; /* string terminator */
8197 return mangled; /* not an objc mangled name */
8201 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8203 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8209 gcc_obstack_init (&util_obstack);
8210 util_firstobj = (char *) obstack_finish (&util_obstack);
8212 errbuf = (char *) xmalloc (1024 * 10);
8214 synth_module_prologue ();
8220 struct imp_entry *impent;
8222 /* The internally generated initializers appear to have missing braces.
8223 Don't warn about this. */
8224 int save_warn_missing_braces = warn_missing_braces;
8225 warn_missing_braces = 0;
8227 /* A missing @end may not be detected by the parser. */
8228 if (objc_implementation_context)
8230 warning ("%<@end%> missing in implementation context");
8231 finish_class (objc_implementation_context);
8232 objc_ivar_chain = NULL_TREE;
8233 objc_implementation_context = NULL_TREE;
8236 /* Process the static instances here because initialization of objc_symtab
8238 if (objc_static_instances)
8239 generate_static_references ();
8241 if (imp_list || class_names_chain
8242 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8243 generate_objc_symtab_decl ();
8245 for (impent = imp_list; impent; impent = impent->next)
8247 objc_implementation_context = impent->imp_context;
8248 implementation_template = impent->imp_template;
8250 UOBJC_CLASS_decl = impent->class_decl;
8251 UOBJC_METACLASS_decl = impent->meta_decl;
8253 /* Dump the @interface of each class as we compile it, if the
8254 -gen-decls option is in use. TODO: Dump the classes in the
8255 order they were found, rather than in reverse order as we
8257 if (flag_gen_declaration)
8259 dump_interface (gen_declaration_file, objc_implementation_context);
8262 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8264 /* all of the following reference the string pool... */
8265 generate_ivar_lists ();
8266 generate_dispatch_tables ();
8267 generate_shared_structures ();
8271 generate_dispatch_tables ();
8272 generate_category (objc_implementation_context);
8276 /* If we are using an array of selectors, we must always
8277 finish up the array decl even if no selectors were used. */
8278 if (! flag_next_runtime || sel_ref_chain)
8279 build_selector_translation_table ();
8282 generate_protocols ();
8284 if (flag_replace_objc_classes && imp_list)
8285 generate_objc_image_info ();
8287 /* Arrange for ObjC data structures to be initialized at run time. */
8288 if (objc_implementation_context || class_names_chain || objc_static_instances
8289 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8291 build_module_descriptor ();
8293 if (!flag_next_runtime)
8294 build_module_initializer_routine ();
8297 /* Dump the class references. This forces the appropriate classes
8298 to be linked into the executable image, preserving unix archive
8299 semantics. This can be removed when we move to a more dynamically
8300 linked environment. */
8302 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8304 handle_class_ref (chain);
8305 if (TREE_PURPOSE (chain))
8306 generate_classref_translation_entry (chain);
8309 for (impent = imp_list; impent; impent = impent->next)
8310 handle_impent (impent);
8312 /* Dump the string table last. */
8314 generate_strings ();
8321 /* Run through the selector hash tables and print a warning for any
8322 selector which has multiple methods. */
8324 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8326 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8327 check_duplicates (hsh, 0, 1);
8328 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8329 check_duplicates (hsh, 0, 1);
8333 warn_missing_braces = save_warn_missing_braces;
8336 /* Subroutines of finish_objc. */
8339 generate_classref_translation_entry (tree chain)
8341 tree expr, decl, type;
8343 decl = TREE_PURPOSE (chain);
8344 type = TREE_TYPE (decl);
8346 expr = add_objc_string (TREE_VALUE (chain), class_names);
8347 expr = convert (type, expr); /* cast! */
8349 /* The decl that is the one that we
8350 forward declared in build_class_reference. */
8351 finish_var_decl (decl, expr);
8356 handle_class_ref (tree chain)
8358 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8359 char *string = (char *) alloca (strlen (name) + 30);
8363 sprintf (string, "%sobjc_class_name_%s",
8364 (flag_next_runtime ? "." : "__"), name);
8366 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8367 if (flag_next_runtime)
8369 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8374 /* Make a decl for this name, so we can use its address in a tree. */
8375 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8376 DECL_EXTERNAL (decl) = 1;
8377 TREE_PUBLIC (decl) = 1;
8380 rest_of_decl_compilation (decl, 0, 0);
8382 /* Make a decl for the address. */
8383 sprintf (string, "%sobjc_class_ref_%s",
8384 (flag_next_runtime ? "." : "__"), name);
8385 exp = build1 (ADDR_EXPR, string_type_node, decl);
8386 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8387 DECL_INITIAL (decl) = exp;
8388 TREE_STATIC (decl) = 1;
8389 TREE_USED (decl) = 1;
8392 rest_of_decl_compilation (decl, 0, 0);
8396 handle_impent (struct imp_entry *impent)
8400 objc_implementation_context = impent->imp_context;
8401 implementation_template = impent->imp_template;
8403 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8405 const char *const class_name =
8406 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8408 string = (char *) alloca (strlen (class_name) + 30);
8410 sprintf (string, "%sobjc_class_name_%s",
8411 (flag_next_runtime ? "." : "__"), class_name);
8413 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8415 const char *const class_name =
8416 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8417 const char *const class_super_name =
8418 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8420 string = (char *) alloca (strlen (class_name)
8421 + strlen (class_super_name) + 30);
8423 /* Do the same for categories. Even though no references to
8424 these symbols are generated automatically by the compiler, it
8425 gives you a handle to pull them into an archive by hand. */
8426 sprintf (string, "*%sobjc_category_name_%s_%s",
8427 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8432 #ifdef ASM_DECLARE_CLASS_REFERENCE
8433 if (flag_next_runtime)
8435 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8443 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
8444 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8445 TREE_PUBLIC (decl) = 1;
8446 TREE_READONLY (decl) = 1;
8447 TREE_USED (decl) = 1;
8448 TREE_CONSTANT (decl) = 1;
8449 DECL_CONTEXT (decl) = 0;
8450 DECL_ARTIFICIAL (decl) = 1;
8451 DECL_INITIAL (decl) = init;
8452 assemble_variable (decl, 1, 0, 0);
8456 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
8457 later requires that ObjC translation units participating in F&C be
8458 specially marked. The following routine accomplishes this. */
8460 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
8463 generate_objc_image_info (void)
8465 tree decl, initlist;
8467 decl = start_var_decl (build_array_type
8469 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
8470 "_OBJC_IMAGE_INFO");
8472 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
8473 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 1), initlist);
8474 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
8476 finish_var_decl (decl, initlist);
8479 /* Look up ID as an instance variable. OTHER contains the result of
8480 the C or C++ lookup, which we may want to use instead. */
8483 objc_lookup_ivar (tree other, tree id)
8487 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
8488 if (!objc_method_context)
8491 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
8492 /* We have a message to super. */
8493 return get_super_receiver ();
8495 /* In a class method, look up an instance variable only as a last
8497 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
8498 && other && other != error_mark_node)
8501 /* Look up the ivar, but do not use it if it is not accessible. */
8502 ivar = is_ivar (objc_ivar_chain, id);
8504 if (!ivar || is_private (ivar))
8507 /* In an instance method, a local variable (or parameter) may hide the
8508 instance variable. */
8509 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8510 && other && other != error_mark_node && !DECL_FILE_SCOPE_P (other))
8512 warning ("local declaration of %qs hides instance variable",
8513 IDENTIFIER_POINTER (id));
8518 /* At this point, we are either in an instance method with no obscuring
8519 local definitions, or in a class method with no alternate definitions
8521 return build_ivar_reference (id);
8524 #include "gt-objc-objc-act.h"